out->media_flags = data.media_flags();
out->spellcheck_enabled = data.spellcheck_enabled();
out->is_editable = data.is_editable();
+#if BUILDFLAG(IS_EFL)
+ out->is_text_node = data.is_text_node();
+#endif
out->writing_direction_default = data.writing_direction_default();
out->writing_direction_left_to_right = data.writing_direction_left_to_right();
out->writing_direction_right_to_left = data.writing_direction_right_to_left();
params.misspelled_word = data.misspelled_word;
params.spellcheck_enabled = data.is_spell_checking_enabled;
params.is_editable = data.is_editable;
+#if BUILDFLAG(IS_EFL)
+ params.is_text_node = data.is_text_node;
+#endif
params.writing_direction_default = data.writing_direction_default;
params.writing_direction_left_to_right = data.writing_direction_left_to_right;
params.writing_direction_right_to_left = data.writing_direction_right_to_left;
dictionary_suggestions = other.dictionary_suggestions;
spellcheck_enabled = other.spellcheck_enabled;
is_editable = other.is_editable;
+#if BUILDFLAG(IS_EFL)
+ is_text_node = other.is_text_node;
+#endif
writing_direction_default = other.writing_direction_default;
writing_direction_left_to_right = other.writing_direction_left_to_right;
writing_direction_right_to_left = other.writing_direction_right_to_left;
// Whether context is editable.
bool is_editable;
+#if BUILDFLAG(IS_EFL)
+ bool is_text_node;
+#endif
+
// If this node is an input field, the type of that field.
blink::mojom::ContextMenuDataInputFieldType input_field_type;
media_flags(kMediaNone),
is_spell_checking_enabled(false),
is_editable(false),
+#if BUILDFLAG(IS_EFL)
+ is_text_node(false),
+#endif
writing_direction_default(kCheckableMenuItemDisabled),
writing_direction_left_to_right(kCheckableMenuItemEnabled),
writing_direction_right_to_left(kCheckableMenuItemEnabled),
return r.is_editable;
}
+#if BUILDFLAG(IS_EFL)
+ static bool is_text_node(const blink::UntrustworthyContextMenuParams& r) {
+ return r.is_text_node;
+ }
+#endif
+
static int writing_direction_default(
const blink::UntrustworthyContextMenuParams& r) {
return r.writing_direction_default;
// Whether context is editable.
bool is_editable;
+#if BUILDFLAG(IS_EFL)
+ // Whether node context menu was invoked on is a text node.
+ bool is_text_node;
+#endif
+
// Writing direction menu items.
int writing_direction_default;
int writing_direction_left_to_right;
// Whether context is editable.
bool is_editable;
+ // Whether element is text
+ [EnableIf=is_efl]
+ bool is_text_node;
+
// Writing direction menu items.
int32 writing_direction_default;
int32 writing_direction_left_to_right;
}
}
+#if BUILDFLAG(IS_EFL)
+ data.is_text_node = result.InnerNode()->IsTextNode();
+#endif
+
if (result.IsContentEditable()) {
data.is_editable = true;
SpellChecker& spell_checker = selected_frame->GetSpellChecker();
static_library("android_content_detection") {
set_sources_assignment_filter([])
sources = [
+ "//content/renderer/android/disambiguation_popup_helper.cc",
+ "//content/renderer/android/disambiguation_popup_helper.h",
"//content/renderer/android/renderer_date_time_picker.cc",
"//content/renderer/android/renderer_date_time_picker.h",
]
static_cast<RWHVAuraOffscreenHelperEfl*>(data);
thiz->FocusRWHVA();
+ if (IsMobileProfile() && thiz->GetSelectionController()) {
+ thiz->GetSelectionController()->ShowHandleAndContextMenuIfRequired();
+ }
+
if (!thiz->on_focus_in_callback_.is_null())
thiz->on_focus_in_callback_.Run();
}
if (focused_window)
focused_window->LostFocus();
+ if (IsMobileProfile() && thiz->GetSelectionController()) {
+ thiz->GetSelectionController()->HideHandleAndContextMenu();
+ }
+
if (!thiz->on_focus_out_callback_.is_null())
thiz->on_focus_out_callback_.Run();
}
}
}
+void RWHVAuraOffscreenHelperEfl::MoveCaret(const gfx::Point& point) {
+ if (auto* delegate = rwhv_aura_->host()->delegate()) {
+ delegate->MoveCaret(gfx::Point(point.x() / device_scale_factor_,
+ point.y() / device_scale_factor_));
+ }
+}
+
+void RWHVAuraOffscreenHelperEfl::SelectClosestWord(
+ const gfx::Point& touch_point) {
+ int view_x, view_y;
+ EvasToBlinkCords(touch_point.x(), touch_point.y(), &view_x, &view_y);
+
+#if !defined(EWK_BRINGUP) // FIXME: m67 bringup
+ // FIXME: The SelectClosestWord function was removed by
+ // commit 9720a4494c8bcd24d1f496feec5cfac7582103d2 in s-chromium
+ // It will be fixed by webview team.
+ // FIXME: http://suprem.sec.samsung.net/jira/browse/TWF-2122
+ Send(new ViewMsg_SelectClosestWord(host_->GetRoutingID(), view_x, view_y));
+#endif // EWK_BRINGUP
+}
+
+bool RWHVAuraOffscreenHelperEfl::HasSelectableText() {
+ // If the last character of textarea is '\n', We can assume an extra '\n'.
+ // Actually when you insert line break by ENTER key, '\n\n' is stored in
+ // textarea. And If you press delete key, only a '\n' character will be stored
+ // although there is no visible and selectable character in textarea. That's
+ // why we should check whether selection_text contains only one line break.
+ // Bug: http://suprem.sec.samsung.net/jira/browse/TSAM-2230
+ //
+ // Please see below commit for more information.
+ // https://codereview.chromium.org/1785603002
+ std::u16string selection_text = rwhv_aura_->GetSelectedText();
+ return !selection_text.empty() &&
+ base::UTF16ToUTF8(selection_text).compare("\n") != 0;
+}
+
void RWHVAuraOffscreenHelperEfl::FocusedNodeChanged(
bool editable
#if BUILDFLAG(IS_TIZEN_TV)
bool IsFocusedNodeContentEditable() const { return is_content_editable_; }
+ void MoveCaret(const gfx::Point& point);
+ void SelectClosestWord(const gfx::Point& touch_point);
+ bool HasSelectableText();
+
private:
static void OnParentViewResize(void* data, Evas*, Evas_Object*, void*);
static void EvasObjectImagePixelsGetCallback(void*, Evas_Object*);
#include "selection_box_efl.h"
#include "base/trace_event/trace_event.h"
+#include "content/browser/renderer_host/render_widget_host_view_aura.h"
namespace content {
-SelectionBoxEfl::SelectionBoxEfl(Evas_Object* parent_view)
- : status_(false),
- is_anchor_first_(false),
- context_params_(new ContextMenuParams()),
- parent_view_(parent_view) {
- context_params_->has_image_contents = false;
+SelectionBoxEfl::SelectionBoxEfl(RenderWidgetHostViewAura* rwhva)
+ : status_(false),
+ is_anchor_first_(false),
+ context_params_(new ContextMenuParams()),
+ rwhva_(rwhva) {
+ context_params_->has_image_contents = false;
}
+SelectionBoxEfl::~SelectionBoxEfl() = default;
+
void SelectionBoxEfl::UpdateSelectStringData(const std::u16string& text) {
context_params_->selection_text = text;
}
left_rect_ = left_rect;
right_rect_ = right_rect;
- // Display point of context Menu
- Evas_Coord x, y;
- evas_object_geometry_get(parent_view_, &x, &y, 0, 0);
//context params suppose to be global - related to evas not the web view
- ret |= (context_params_->x != (left_rect_.x() + x));
- ret |= (context_params_->y != (left_rect_.y() + y));
- context_params_->x = left_rect_.x() + x;
- context_params_->y = left_rect_.y() + y;
+ gfx::Rect view_bounds = rwhva_->offscreen_helper()->GetViewBoundsInPix();
+ ret |= (context_params_->x != (left_rect_.x() + (view_bounds.x())));
+ ret |= (context_params_->y != (left_rect_.y() + view_bounds.y()));
+ context_params_->x = left_rect_.x() + view_bounds.x();
+ context_params_->y = left_rect_.y() + view_bounds.y();
return ret;
}
}
void SelectionBoxEfl::SetStatus(bool enable) {
- bool invokeCbAtEnd = status_ != enable;
+ bool invoke_cb_at_end = status_ != enable;
status_ = enable;
// invoke CB only if mode actually changed
- if (invokeCbAtEnd && parent_view_)
- evas_object_smart_callback_call(parent_view_, "textselection,mode", &status_);
+ if (invoke_cb_at_end && rwhva_->offscreen_helper()->ewk_view())
+ evas_object_smart_callback_call(rwhva_->offscreen_helper()->ewk_view(),
+ "textselection,mode", &status_);
}
}
namespace content {
+class RenderWidgetHostViewAura;
// Hold the data related to drwaing the selection handlers
// and context menu. Also stores all the data required for selection
// controlling
class SelectionBoxEfl {
public:
- SelectionBoxEfl(Evas_Object* parent_view);
+ explicit SelectionBoxEfl(RenderWidgetHostViewAura* rwhva);
+ ~SelectionBoxEfl();
+
+ SelectionBoxEfl(const SelectionBoxEfl&) = delete;
+ SelectionBoxEfl& operator=(const SelectionBoxEfl&) = delete;
void SetStatus(bool enable);
bool GetStatus() const { return status_; }
// Contains the menu item data for which context needs to be populated
std::unique_ptr<ContextMenuParams> context_params_;
- Evas_Object* parent_view_;
+ RenderWidgetHostViewAura* rwhva_;
};
}
#include "selection_controller_efl.h"
-#include <Edje.h>
+#include <Elementary.h>
#include "base/trace_event/trace_event.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_contents/web_contents_impl_efl.h"
#include "content/public/browser/context_menu_params.h"
return line_offset;
}
-SelectionControllerEfl::SelectionControllerEfl(Evas_Object* parent_view, WebContents& web_contents)
- : parent_view_(parent_view),
- controls_temporarily_hidden_(false),
- selection_change_reason_(Reason::Irrelevant),
- long_mouse_press_(false),
- selection_data_(new SelectionBoxEfl(parent_view)),
- start_handle_(new SelectionHandleEfl(*this, SelectionHandleEfl::HANDLE_TYPE_LEFT, parent_view)),
- end_handle_(new SelectionHandleEfl(*this, SelectionHandleEfl::HANDLE_TYPE_RIGHT, parent_view)),
- input_handle_(new SelectionHandleEfl(*this, SelectionHandleEfl::HANDLE_TYPE_INPUT, parent_view)),
- magnifier_(new SelectionMagnifierEfl(this, web_contents)),
- is_selection_visible_(false),
- handle_being_dragged_(false),
- selection_on_empty_form_control_(false),
- web_contents_(web_contents),
- selection_mode_(None) {
- evas_object_event_callback_add(parent_view_, EVAS_CALLBACK_MOVE, &EvasParentViewMoveCallback, this);
+content::WebContents* SelectionControllerEfl::web_contents() const {
+ return rwhva_->offscreen_helper()->GetWebContents();
+}
+
+SelectionControllerEfl::SelectionControllerEfl(RenderWidgetHostViewAura* rwhva)
+ : rwhva_(rwhva),
+ selection_data_(new SelectionBoxEfl(rwhva)),
+ start_handle_(
+ new SelectionHandleEfl(*this, SelectionHandleEfl::HANDLE_TYPE_LEFT)),
+ end_handle_(
+ new SelectionHandleEfl(*this, SelectionHandleEfl::HANDLE_TYPE_RIGHT)),
+ input_handle_(
+ new SelectionHandleEfl(*this, SelectionHandleEfl::HANDLE_TYPE_INPUT)),
+ magnifier_(new SelectionMagnifierEfl(this)),
+ selection_mode_(None) {
+ evas_object_event_callback_add(rwhva_->offscreen_helper()->content_image(),
+ EVAS_CALLBACK_MOVE,
+ &EvasParentViewMoveCallback, this);
#if BUILDFLAG(IS_TIZEN)
vconf_notify_key_changed(VCONFKEY_LANGSET, PlatformLanguageChanged, this);
#endif
}
SelectionControllerEfl::~SelectionControllerEfl() {
+ if (ecore_events_filter_)
+ ecore_event_filter_del(ecore_events_filter_);
if (GetSelectionStatus())
ClearSelectionViaEWebView();
HideHandleAndContextMenu();
- evas_object_event_callback_del(parent_view_, EVAS_CALLBACK_MOVE, &EvasParentViewMoveCallback);
+ evas_object_event_callback_del(rwhva_->offscreen_helper()->content_image(),
+ EVAS_CALLBACK_MOVE,
+ &EvasParentViewMoveCallback);
}
void SelectionControllerEfl::SetSelectionStatus(bool enable) {
"controls are hidden:", value);
if (controls_temporarily_hidden_ == value)
return;
-#if !defined(USE_AURA)
- RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(
- web_contents_.GetRenderWidgetHostView());
- CHECK(rwhv);
// Make sure to show selection controls only when no finger
// is left touching the screen.
- if (!value && rwhv->PointerStatePointerCount())
+ if (!value && rwhva_->event_handler()->pointer_state().GetPointerCount())
return;
-#endif
controls_temporarily_hidden_ = value;
if (value) {
Clear();
truncated_end = gfx::ToEnclosingRect(
gfx::ConvertRectToPixels(truncated_end, device_scale_factor));
+ if (handle_being_dragged_ &&
+ dragging_handle_->Type() != SelectionHandleEfl::HANDLE_TYPE_INPUT) {
+ dragging_handle_->MoveObject(selection_data_->GetIsAnchorFirst()
+ ? truncated_end.bottom_right()
+ : truncated_start.bottom_left());
+ }
+
bool finger_down = handle_being_dragged_ || long_mouse_press_;
bool show = (selection_change_reason_ != Reason::Irrelevant) && !finger_down;
UpdateSelectionDataAndShow(
truncated_start, truncated_end, show);
selection_change_reason_ = Reason::Irrelevant;
+
+ // In case of the selected text contains only line break and no other
+ // characters, we should use caret selection mode.
+ if (GetSelectionEditable() && !handle_being_dragged_ &&
+ rwhva_->GetSelectedText() == (u"\n")) {
+ rwhva_->offscreen_helper()->MoveCaret(
+ selection_data_->GetLeftRect().origin());
+ is_caret_mode_forced_ = true;
+ }
}
void SelectionControllerEfl::OnTextInputStateChanged() {
-#if !defined(USE_AURA)
- RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(
- web_contents_.GetRenderWidgetHostView());
- CHECK(rwhv);
// In order to confirm if a long press gesture is ongoing,
// we just needed to check "long_mouse_press_".
// However, when long press happens on a link or image,
// although finger is still down.
// To compensate this, add an extra check asking from the engine
// if a finger is still touching down.
- bool is_touch_down = rwhv->PointerStatePointerCount() > 0;
+ bool is_touch_down =
+ rwhva_->event_handler()->pointer_state().GetPointerCount() > 0;
// If on an editable field and in caret selection mode, only
// show the large handle if:
// handling "tap" gesture.
bool finger_down = handle_being_dragged_ || long_mouse_press_ || is_touch_down;
- if (GetSelectionEditable() && !finger_down && !controls_temporarily_hidden_ &&
+ if (GetSelectionEditable() && GetCaretSelectionStatus() && !finger_down &&
+ !controls_temporarily_hidden_ &&
selection_change_reason_ == Reason::Irrelevant) {
HideHandleAndContextMenu();
ClearSelection();
}
-#endif
}
void SelectionControllerEfl::UpdateSelectionData(const std::u16string& text) {
}
bool SelectionControllerEfl::ClearSelectionViaEWebView() {
- if (!GetSelectionStatus() || !web_contents_.GetRenderViewHost() ||
- web_contents_.IsBeingDestroyed()) {
+ if (!GetSelectionStatus() || !web_contents()->GetRenderViewHost() ||
+ web_contents()->IsBeingDestroyed()) {
return false;
}
- // RenderWidgetHostImpl* rwhi = static_cast<RenderWidgetHostImpl*>(
- // web_contents_.GetRenderViewHost()->GetWidget());
- // rwhi->ExecuteEditCommand("Unselect", "");
-
RenderWidgetHostDelegate* host_delegate =
- RenderWidgetHostImpl::From(web_contents_.GetRenderViewHost()->GetWidget())
+ RenderWidgetHostImpl::From(
+ web_contents()->GetRenderViewHost()->GetWidget())
->delegate();
if (host_delegate) {
host_delegate->ExecuteEditCommand("Unselect", absl::nullopt);
selection_mode_ = mode;
}
+void SelectionControllerEfl::ToggleCaretAfterSelection() {
+ if (!GetCaretSelectionStatus() && GetSelectionEditable()) {
+ rwhva_->offscreen_helper()->MoveCaret(
+ selection_data_->GetRightRect().origin());
+ ClearSelection();
+ }
+}
+
void SelectionControllerEfl::DetermineSelectionMode(
const gfx::Rect& left_rect,
const gfx::Rect& right_rect) {
return;
}
- bool is_any_handle_visible = start_selection_.visible() ||
- end_selection_.visible();
+ bool is_selection_range_visible =
+ start_selection_.visible() || end_selection_.visible();
// Is in edit field and no text is selected. show only single handle
if (selection_data_->IsInEditField() && left == right) {
CHECK(start_selection_ == end_selection_);
- if (GetCaretSelectionStatus() && is_any_handle_visible) {
+ if (GetCaretSelectionStatus() && is_selection_range_visible) {
gfx::Rect left = selection_data_->GetLeftRect();
input_handle_->SetBasePosition(gfx::Point(left.x(), left.y()));
input_handle_->Move(left.bottom_right());
start_handle_->Hide();
end_handle_->Hide();
- bool show_context_menu = is_any_handle_visible &&
- effective_reason != Reason::ScrollOrZoomGestureEnded &&
- effective_reason != Reason::Tap &&
- effective_reason != Reason::Irrelevant;
+ bool show_context_menu =
+ IsAnyHandleVisible() &&
+ effective_reason != Reason::ScrollOrZoomGestureEnded &&
+ effective_reason != Reason::Tap &&
+ effective_reason != Reason::Irrelevant;
if (!handle_being_dragged_ && show_context_menu)
ShowContextMenu();
// Do not show the context menu during selection extend and
// offscreen selection.
if (!handle_being_dragged_ && effective_reason != Reason::Irrelevant &&
- is_any_handle_visible)
+ IsAnyHandleVisible()) {
ShowContextMenu();
+ }
}
void SelectionControllerEfl::ShowContextMenu() {
input_handle_->Hide();
}
-void SelectionControllerEfl::HandleDragBeginNotification(SelectionHandleEfl* handle) {
+Eina_Bool SelectionControllerEfl::EcoreEventFilterCallback(void* user_data,
+ void* /*loop_data*/,
+ int type,
+ void* event_info) {
+ if (type == ECORE_EVENT_MOUSE_MOVE) {
+ auto controller = static_cast<SelectionControllerEfl*>(user_data);
+ if (!controller || !controller->dragged_handle_)
+ return ECORE_CALLBACK_PASS_ON;
+
+ auto event = static_cast<Ecore_Event_Mouse_Move*>(event_info);
+ controller->dragged_handle_->UpdatePosition(gfx::Point(event->x, event->y));
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+void SelectionControllerEfl::HandleDragBeginNotification(
+ SelectionHandleEfl* handle) {
+ selection_change_reason_ = Reason::HandleDragged;
+ dragged_handle_ = handle;
+ ecore_events_filter_ =
+ ecore_event_filter_add(nullptr, EcoreEventFilterCallback, nullptr, this);
+
+ if (!ecore_events_filter_) {
+ LOG(ERROR) << __PRETTY_FUNCTION__
+ << " : Unable to create ecore events filter";
+ }
+
// Hide context menu on mouse down
CancelContextMenu(0);
handle_being_dragged_ = true;
Evas_Coord x, y;
- evas_object_geometry_get(parent_view_, &x, &y, 0, 0);
+ evas_object_geometry_get(rwhva_->offscreen_helper()->content_image(), &x, &y,
+ 0, 0);
gfx::Point magnifier_point(
handle->GetBasePosition().x() + x,
handle->GetBasePosition().y() + y);
base += base_offset;
extent += extent_offset;
- WebContentsImpl* wci = static_cast<WebContentsImpl*>(&web_contents_);
+ WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents());
wci->SelectRange(gfx::ToFlooredPoint(base), gfx::ToFlooredPoint(extent));
}
void SelectionControllerEfl::HandleDragUpdateNotification(SelectionHandleEfl* handle) {
+ if (!rwhva_)
+ return;
// FIXME : Check the text Direction later
- Evas_Coord x, y;
- evas_object_geometry_get(parent_view_, &x, &y, 0, 0);
+ gfx::Rect view_bounds = rwhva_->offscreen_helper()->GetViewBoundsInPix();
selection_change_reason_ = Reason::HandleDragged;
gfx::Point magnifier_point;
- magnifier_point.set_x(handle->GetBasePosition().x() + x);
- magnifier_point.set_y(handle->GetBasePosition().y() + y);
+ magnifier_point.set_x(handle->GetBasePosition().x() + view_bounds.x());
+ magnifier_point.set_y(handle->GetBasePosition().y() + view_bounds.y());
magnifier_->UpdateLocation(magnifier_point);
magnifier_->Move(magnifier_point);
switch (handle->Type()) {
-#if !defined(USE_AURA)
case SelectionHandleEfl::HANDLE_TYPE_INPUT: {
- RenderWidgetHostViewEfl* rwhv =
- static_cast<RenderWidgetHostViewEfl*>(web_contents_.GetRenderWidgetHostView());
- if (rwhv)
- rwhv->MoveCaret(handle->GetBasePosition());
+ rwhva_->offscreen_helper()->MoveCaret(handle->GetBasePosition());
return;
}
-#endif
case SelectionHandleEfl::HANDLE_TYPE_LEFT:
case SelectionHandleEfl::HANDLE_TYPE_RIGHT: {
float device_scale_factor =
: ComputeLineOffsetFromBottom(end_selection_);
extent += line_offset;
- WebContentsImpl* wci = static_cast<WebContentsImpl*>(&web_contents_);
+ WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents());
wci->MoveRangeSelectionExtent(gfx::ToFlooredPoint(extent));
return;
}
}
void SelectionControllerEfl::HandleDragEndNotification() {
+ dragged_handle_ = nullptr;
+
+ if (ecore_events_filter_)
+ ecore_event_filter_del(ecore_events_filter_);
+ ecore_events_filter_ = nullptr;
+
selection_change_reason_ = Reason::Irrelevant;
magnifier_->Hide();
start_handle_->SetBasePosition(selection_data_->GetLeftRect().bottom_left());
}
}
-void SelectionControllerEfl::HandlePostponedGesture(int x, int y, ui::EventType type) {
+void SelectionControllerEfl::HandlePostponedGesture(int x,
+ int y,
+ ui::EventType type) {
DVLOG(0) << "HandlePostponedGesture :: " << type;
#if !defined(USE_AURA)
RenderWidgetHostViewEfl* rwhv =
#endif
SetSelectionStatus(true);
SetSelectionEditable(true);
+ if (selection_mode_ == None)
+ SetSelectionMode(Caret);
HandleLongPressEventPrivate(touch_point);
return true;
- } else if (params.link_url.is_empty() && params.src_url.is_empty()
-#if !defined(EWK_BRINGUP) // FIXME: m67 bringup
- && params.is_text_node) {
-#else
- ) {
-#endif
+ } else if (params.link_url.is_empty() && params.src_url.is_empty() &&
+ params.is_text_node ||
+ !params.selection_text.empty()) {
// If user is long pressing on a content with
// -webkit-user-select: none, we should bail and not enter
// selection neither show magnigier class or context menu.
return true;
}
-void SelectionControllerEfl::HandleLongPressEventPrivate(const gfx::Point& touch_point) {
+void SelectionControllerEfl::HandleLongPressEventPrivate(
+ const gfx::Point& touch_point) {
Clear();
- Evas_Coord x, y;
- evas_object_geometry_get(parent_view_, &x, &y, 0, 0);
- magnifier_->HandleLongPress(gfx::Point(touch_point.x() + x,
- touch_point.y() + y));
+ gfx::Rect view_bounds = rwhva_->offscreen_helper()->GetViewBoundsInPix();
+ magnifier_->HandleLongPress(gfx::Point(touch_point.x() + view_bounds.x(),
+ touch_point.y() + view_bounds.y()));
}
void SelectionControllerEfl::HandleLongPressMoveEvent(const gfx::Point& touch_point) {
-#if !defined(USE_AURA)
- RenderWidgetHostViewEfl* rwhv =
- static_cast<RenderWidgetHostViewEfl*>(web_contents_.GetRenderWidgetHostView());
- Clear();
- selection_change_reason_ = Reason::LongPressMoved;
- if (selection_data_->IsInEditField()) {
- Evas_Coord x, y;
- evas_object_geometry_get(parent_view_, &x, &y, 0, 0);
- if (rwhv)
- rwhv->MoveCaret(gfx::Point(touch_point.x() - x, touch_point.y() - y));
- } else{
- if (rwhv)
- rwhv->SelectClosestWord(touch_point);
- }
-#endif
+ if (rwhva_)
+ rwhva_->offscreen_helper()->SelectClosestWord(touch_point);
}
void SelectionControllerEfl::HandleLongPressEndEvent() {
}
void SelectionControllerEfl::PostHandleTapGesture(bool is_content_editable) {
- HideHandleAndContextMenu();
if (is_content_editable) {
DVLOG(1) << "PostHandleTapGesture :: Editable";
SetSelectionStatus(true);
SetSelectionEditable(true);
selection_change_reason_ = Reason::Tap;
} else {
- ClearSelectionViaEWebView();
SetSelectionEditable(false);
}
}
void SelectionControllerEfl::ClearSelection() {
TRACE_EVENT0("selection,efl", __PRETTY_FUNCTION__);
Clear();
+ CancelContextMenu(0);
SetSelectionStatus(false);
SetSelectionEditable(false);
SetSelectionMode(None);
int handleHeight, webViewX, webViewY, webViewWidth, webViewHeight;
gfx::Rect imeRect;
edje_object_part_geometry_get(input_handle_->evas_object(), "handle", 0, 0, 0, &handleHeight);
- evas_object_geometry_get(GetParentView(), &webViewX, &webViewY, &webViewWidth, &webViewHeight);
+ evas_object_geometry_get(rwhva_->offscreen_helper()->content_image(),
+ &webViewX, &webViewY, &webViewWidth, &webViewHeight);
gfx::Rect viewportRect = gfx::Rect(webViewX, webViewY, webViewWidth, webViewHeight);
#if !defined(USE_AURA)
RenderWidgetHostViewEfl* rwhv =
return;
}
+gfx::Rect SelectionControllerEfl::GetVisibleViewportRect() const {
+ if (custom_visible_view_rect_.IsEmpty())
+ return rwhva_->offscreen_helper()->GetViewBoundsInPix();
+
+ return gfx::IntersectRects(rwhva_->offscreen_helper()->GetViewBoundsInPix(),
+ custom_visible_view_rect_);
+}
+
bool SelectionControllerEfl::TextSelectionDown(int x, int y) {
/*
* According to webkit-efl textSelectionDown is used on long press gesture, we already
#include <libintl.h>
namespace content {
+class RenderWidgetHostViewAura;
class WebContents;
class WebContentsImpl;
};
public:
- explicit SelectionControllerEfl(Evas_Object* parent_view, WebContents& web_contents);
+ explicit SelectionControllerEfl(RenderWidgetHostViewAura* rwhva);
~SelectionControllerEfl();
+ SelectionControllerEfl(const SelectionControllerEfl&) = delete;
+ SelectionControllerEfl& operator=(const SelectionControllerEfl&) = delete;
+
// Functions that handle long press, long press move and release
bool HandleLongPressEvent(const gfx::Point& touch_point,
const content::ContextMenuParams& params);
// Clears the selection and hides context menu and handles
void ClearSelection();
bool ClearSelectionViaEWebView();
- Evas_Object* GetParentView() const { return parent_view_; }
void HideHandles();
void HideHandleAndContextMenu();
bool IsAnyHandleVisible() const;
LongPressEnded,
Tap,
RequestedByContextMenu,
+ CaretModeForced,
Irrelevant,
};
void SetWaitsForRendererSelectionChanges(
void HandlePostponedGesture(int x, int y, ui::EventType type);
void HandleGesture(blink::WebGestureEvent& event);
+ gfx::Rect GetVisibleViewportRect() const;
+
+ bool IsCaretModeForced() const { return is_caret_mode_forced_; }
+ void SetCustomVisibleViewRect(const gfx::Rect& custom_visible_view_rect) {
+ custom_visible_view_rect_ = custom_visible_view_rect;
+ }
+
+ void ToggleCaretAfterSelection();
+ void ShowHandleAndContextMenuIfRequired(
+ Reason explicit_reason = Reason::Irrelevant);
+
+ RenderWidgetHostViewAura* rwhva() const { return rwhva_; }
+ content::WebContents* web_contents() const;
+
private:
enum SelectionMode {
None = 0,
void HandleLongPressEventPrivate(const gfx::Point& touch_point);
- void ShowHandleAndContextMenuIfRequired(Reason explicit_reason = Reason::Irrelevant);
-
void Clear();
bool IsSelectionValid(const gfx::Rect& left_rect, const gfx::Rect& right_rect);
void ShowContextMenu();
void CancelContextMenu(int request_id);
- static void EvasParentViewMoveCallback(void *data, Evas *e, Evas_Object *obj, void *event_info)
- { reinterpret_cast<SelectionControllerEfl*>(data)->OnParentParentViewMove(); }
+ static void EvasParentViewMoveCallback(void* data,
+ Evas* e,
+ Evas_Object* obj,
+ void* event_info) {
+ reinterpret_cast<SelectionControllerEfl*>(data)->OnParentParentViewMove();
+ }
#if BUILDFLAG(IS_TIZEN)
static void PlatformLanguageChanged(keynode_t* keynode, void* data);
void OnParentParentViewMove();
- Evas_Object* parent_view_;
+ static Eina_Bool EcoreEventFilterCallback(void* user_data,
+ void* loop_data,
+ int type,
+ void* event_info);
+
// Is required to send back selction points and range extenstion co-ordinates
+ RenderWidgetHostViewAura* rwhva_;
// Saves state so that selection controls are temporarily hidden due
// to scrolling or zooming.
- bool controls_temporarily_hidden_;
+ bool controls_temporarily_hidden_ = false;
// Cache the reason of why browser has requested a text selection
// change to the renderer. At the next composited selection update
// the cache is handled and reset.
- Reason selection_change_reason_;
+ Reason selection_change_reason_ = Reason::Irrelevant;
- // Saves state so that handlers and context menu is not shown when seletion change event occurs.
- bool long_mouse_press_;
+ // Saves state so that handlers and context menu is not shown when seletion
+ // change event occurs.
+ bool long_mouse_press_ = false;
// Saves the data that are required to draw handle and context menu
std::unique_ptr<SelectionBoxEfl> selection_data_;
// Helper pointer to the stationary handle (during dragging).
SelectionHandleEfl* stationary_handle_;
- bool is_selection_visible_;
+ gfx::Rect custom_visible_view_rect_;
+
+ bool is_selection_visible_ = false;
+
+ bool handle_being_dragged_ = false;
- bool handle_being_dragged_;
+ bool is_caret_mode_forced_ = false;
+ bool selection_on_empty_form_control_ = false;
- bool selection_on_empty_form_control_;
+ Ecore_Event_Filter* ecore_events_filter_ = nullptr;
- WebContents& web_contents_;
+ SelectionHandleEfl* dragged_handle_ = nullptr;
enum SelectionMode selection_mode_;
gfx::SelectionBound start_selection_;
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/trace_event/trace_event.h"
+#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/selection/selection_controller_efl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/paths_efl.h"
namespace content {
}
}
-SelectionHandleEfl::SelectionHandleEfl(SelectionControllerEfl& controller, HandleType type, Evas_Object* parent)
- : controller_(controller),
- pressed_(false),
- is_top_(false),
- handle_type_(type) {
-
- Evas* evas = evas_object_evas_get(parent);
+SelectionHandleEfl::SelectionHandleEfl(SelectionControllerEfl& controller,
+ HandleType type)
+ : controller_(controller),
+ pressed_(false),
+ is_top_(false),
+ handle_type_(type) {
+ Evas* evas = evas_object_evas_get(
+ controller_.rwhva()->offscreen_helper()->content_image());
handle_ = edje_object_add(evas);
base::FilePath edj_dir;
edje_object_signal_emit(handle_, "edje,focus,in", "edje");
edje_object_signal_emit(handle_, "elm,state,bottom", "elm");
- evas_object_smart_member_add(handle_, parent);
+ Evas_Object* main_layout_ =
+ static_cast<WebContentsImpl*>(
+ controller_.rwhva()->offscreen_helper()->GetWebContents())
+ ->GetEflNativeView();
+ Evas_Object* smart_parent = evas_object_smart_parent_get(main_layout_);
+ evas_object_smart_member_add(handle_, smart_parent);
evas_object_propagate_events_set(handle_, false);
evas_object_event_callback_add(handle_, EVAS_CALLBACK_MOUSE_DOWN, OnMouseDown, this);
SelectionHandleEfl::~SelectionHandleEfl() {
evas_object_event_callback_del(handle_, EVAS_CALLBACK_MOUSE_DOWN, OnMouseDown);
evas_object_event_callback_del(handle_, EVAS_CALLBACK_MOUSE_UP, OnMouseUp);
+ evas_object_smart_member_del(handle_);
evas_object_del(handle_);
}
void SelectionHandleEfl::Show() {
evas_object_show(handle_);
+ evas_object_raise(handle_);
}
void SelectionHandleEfl::Hide() {
}
bool SelectionHandleEfl::IsVisible() const {
- return evas_object_visible_get(handle_);
+ int handle_x, handle_y;
+ evas_object_geometry_get(handle_, &handle_x, &handle_y, nullptr, nullptr);
+
+ auto view_rect = controller_.GetVisibleViewportRect();
+
+ return evas_object_visible_get(handle_) &&
+ view_rect.Contains(handle_x, handle_y);
}
void SelectionHandleEfl::Move(const gfx::Point& point) {
- if (!pressed_) {
+ if (!pressed_)
ChangeObjectDirection(CalculateDirection(point));
- }
if (handle_type_ == HANDLE_TYPE_INPUT)
MoveInputHandle(point);
Evas_Event_Mouse_Down* event = static_cast<Evas_Event_Mouse_Down*>(event_info);
SelectionHandleEfl* handle = static_cast<SelectionHandleEfl*>(data);
handle->pressed_ = true;
- evas_object_event_callback_add(handle->handle_, EVAS_CALLBACK_MOUSE_MOVE,
- OnMouseMove, handle);
//Save the diff_point between touch point and base point of the handle
handle->diff_point_.SetPoint(event->canvas.x - handle->base_point_.x(),
event->canvas.y - handle->base_point_.y());
- Evas_Coord x, y;
- evas_object_geometry_get(handle->evas_object(), &x, &y, 0, 0);
- handle->handle_position_at_touch_down_ = gfx::Point(x, y);
- handle->touch_down_position_ = gfx::Point(event->canvas.x, event->canvas.y);
-
handle->controller_.HandleDragBeginNotification(handle);
}
-void SelectionHandleEfl::OnMouseMove(void* data, Evas*, Evas_Object*, void* event_info) {
- Evas_Event_Mouse_Move* event = static_cast<Evas_Event_Mouse_Move*>(event_info);
- SelectionHandleEfl* handle = static_cast<SelectionHandleEfl*>(data);
- handle->current_touch_point_.SetPoint(event->cur.canvas.x, event->cur.canvas.y);
- ecore_job_add(UpdateMouseMove, handle);
+void SelectionHandleEfl::UpdatePosition(const gfx::Point& position) {
+ current_touch_point_ = position;
+ ecore_job_add(UpdateMouseMove, this);
}
void SelectionHandleEfl::OnMouseUp(void* data, Evas*, Evas_Object*, void* /* event_info */) {
SelectionHandleEfl* handle = static_cast<SelectionHandleEfl*>(data);
handle->pressed_ = false;
- evas_object_event_callback_del(handle->handle_, EVAS_CALLBACK_MOUSE_MOVE, OnMouseMove);
-
handle->controller_.HandleDragEndNotification();
}
int delta_y = handle->current_touch_point_.y() - handle->diff_point_.y();
handle->base_point_.SetPoint(delta_x, delta_y);
- gfx::Vector2d diff = handle->current_touch_point_ - handle->touch_down_position_;
- if (handle->handle_type_ != HANDLE_TYPE_INPUT) {
- // We call MoveObject with evas coordinates relative to
- // the webview canvas. So we need to ignore the parent
- // view offset calculation.
- handle->MoveObject(handle->handle_position_at_touch_down_ + diff,
- true /*ignore_parent_view_offset*/);
- }
-
handle->controller_.HandleDragUpdateNotification(handle);
}
SelectionHandleEfl::HandleDirection SelectionHandleEfl::CalculateDirection(
const gfx::Point& point) const {
- bool reverse_horizontally = false, reverse_vertically = false;
- Evas_Coord x, y, deviceWidth, deviceHeight;
+ bool reverse_horizontally = false, reverse_vertically = false;
int handleHeight;
-
edje_object_part_geometry_get(handle_, "handle", 0, 0, 0, &handleHeight);
- evas_object_geometry_get(controller_.GetParentView(),
- &x, &y, &deviceWidth, &deviceHeight);
- gfx::Point conv_point(point.x() + x, point.y() + y);
- gfx::Rect reverse_direction_rect = gfx::Rect(x + kReverseMargin,
- y, deviceWidth - 2 * kReverseMargin, deviceHeight - handleHeight);
+ auto visible_viewport_rect = controller_.GetVisibleViewportRect();
+ gfx::Point conv_point(point.x() + visible_viewport_rect.x(),
+ point.y() + visible_viewport_rect.y());
+
+ gfx::Rect reverse_direction_rect = gfx::Rect(
+ visible_viewport_rect.x() + kReverseMargin, visible_viewport_rect.y(),
+ visible_viewport_rect.width() - 2 * kReverseMargin,
+ visible_viewport_rect.height() - handleHeight);
if (!reverse_direction_rect.Contains(conv_point)) {
if (conv_point.x() <= reverse_direction_rect.x() ||
}
if (handle_type_ != HANDLE_TYPE_INPUT) {
- if (reverse_vertically) {
- if (reverse_horizontally) {
- return DirectionTopReverse;
- } else {
- return DirectionBottomReverse;
- }
- } else {
- if (reverse_horizontally) {
- return DirectionTopNormal;
- } else {
- return DirectionBottomNormal;
- }
- }
+ if (reverse_vertically) {
+ if (reverse_horizontally)
+ return DirectionTopReverse;
+ else
+ return DirectionBottomReverse;
+ } else {
+ if (reverse_horizontally)
+ return DirectionTopNormal;
+ else
+ return DirectionBottomNormal;
+ }
} else {
// Input handle can only be rotated horizontally
- if (reverse_horizontally) {
+ if (reverse_horizontally)
return DirectionTopNormal;
- } else {
+ else
return DirectionBottomNormal;
- }
}
NOTREACHED();
+ return DirectionBottomNormal;
}
void SelectionHandleEfl::ChangeObjectDirection(HandleDirection direction) {
else
edje_object_signal_emit(handle_, "elm,state,top,reversed", "elm");
break;
- }
+ }
switch (handle_type_) {
case HANDLE_TYPE_LEFT:
- evas_object_smart_callback_call(controller_.GetParentView(),
- "selection,handle,left,direction", &direction);
+ evas_object_smart_callback_call(
+ controller_.rwhva()->offscreen_helper()->ewk_view(),
+ "selection,handle,left,direction", &direction);
break;
case HANDLE_TYPE_RIGHT:
- evas_object_smart_callback_call(controller_.GetParentView(),
- "selection,handle,right,direction", &direction);
+ evas_object_smart_callback_call(
+ controller_.rwhva()->offscreen_helper()->ewk_view(),
+ "selection,handle,right,direction", &direction);
break;
case HANDLE_TYPE_INPUT:
- evas_object_smart_callback_call(controller_.GetParentView(),
- "selection,handle,large,direction", &direction);
+ evas_object_smart_callback_call(
+ controller_.rwhva()->offscreen_helper()->ewk_view(),
+ "selection,handle,large,direction", &direction);
break;
}
}
}
void SelectionHandleEfl::MoveObject(const gfx::Point& point, bool ignore_parent_view_offset) {
- Evas_Coord x = 0, y = 0;
- if (!ignore_parent_view_offset)
- evas_object_geometry_get(controller_.GetParentView(), &x, &y,
- 0, 0);
-
- if (handle_type_ == HANDLE_TYPE_INPUT && IsTop()) {
- evas_object_move(handle_, point.x() + x,
- point.y() + y - controller_.GetLeftRect().height());
- } else {
- evas_object_move(handle_, point.x() + x, point.y() + y);
+ gfx::Rect view_bounds =
+ controller_.rwhva()->offscreen_helper()->GetViewBoundsInPix();
+ int handle_x = point.x() + view_bounds.x();
+ int handle_y = point.y() + view_bounds.y();
+
+ if (IsTop()) {
+ if (handle_type_ == HANDLE_TYPE_RIGHT)
+ handle_y -= controller_.GetRightRect().height();
+ else
+ handle_y -= controller_.GetLeftRect().height();
+ }
+
+ // Prevent selection handles from moving out of visible webview.
+ if (handle_type_ != HANDLE_TYPE_INPUT) {
+ const gfx::Rect& viewport_rect = controller_.GetVisibleViewportRect();
+ int viewport_rect_x = viewport_rect.x();
+ int viewport_rect_y = viewport_rect.y();
+ int viewport_rect_w = viewport_rect.width();
+ int viewport_rect_h = viewport_rect.height();
+
+ if (handle_y < viewport_rect_y)
+ handle_y = viewport_rect_y;
+ else if (handle_y > viewport_rect_h + viewport_rect_y)
+ handle_y = viewport_rect_h + viewport_rect_y;
+
+ if (handle_x < viewport_rect_x)
+ handle_x = viewport_rect_x;
+ else if (handle_x > viewport_rect_w + viewport_rect_x)
+ handle_x = viewport_rect_w + viewport_rect_x;
}
+
+ evas_object_move(handle_, handle_x, handle_y);
}
} // namespace content
DirectionNone,
};
- SelectionHandleEfl(SelectionControllerEfl& controller, HandleType type, Evas_Object* parent);
+ SelectionHandleEfl(SelectionControllerEfl& controller, HandleType type);
~SelectionHandleEfl();
void Show();
void Hide();
HandleType Type() const { return handle_type_; }
+ void UpdatePosition(const gfx::Point& position);
+ void MoveObject(const gfx::Point& point,
+ bool ignore_parent_view_offset = false);
+
private:
static void OnMouseDown(void* data, Evas*, Evas_Object*, void* event_info);
- static void OnMouseMove(void* data, Evas*, Evas_Object*, void* event_info);
static void OnMouseUp(void* data, Evas*, Evas_Object*, void* event_info);
static void UpdateMouseMove(void* data);
HandleDirection CalculateDirection(const gfx::Point&) const;
void ChangeObjectDirection(HandleDirection direction);
gfx::Rect GetSelectionRect() const;
- void MoveObject(const gfx::Point& point, bool ignore_parent_view_offset = false);
// This point is one which will be used during extending selection
// it is in web view coordinates
// This save the gap between the touch point and base point when OnMouseDown is called
gfx::Point diff_point_;
- // Saves the original handle position at the time it started
- // being dragged.
- gfx::Point handle_position_at_touch_down_;
-
- // Saves the original touch down position when a handle is grabbed.
- // It is later used to calculate the movement offset.
- gfx::Point touch_down_position_;
-
// Parent to send back mouse events
SelectionControllerEfl& controller_;
#include "base/files/file_path.h"
#include "base/path_service.h"
+#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/selection/selection_controller_efl.h"
#include "content/common/paths_efl.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/web_contents.h"
namespace content {
const float kZoomScale = 0.66;
SelectionMagnifierEfl::SelectionMagnifierEfl(
- content::SelectionControllerEfl* controller,
- content::WebContents& web_contents)
- : controller_(controller),
- web_contents_(web_contents),
- content_image_(0),
- shown_(false) {
- Evas_Object* top_widget = static_cast<Evas_Object*>(controller->
- GetParentView());
-
+ content::SelectionControllerEfl* controller)
+ : controller_(controller), content_image_(0), shown_(false) {
base::FilePath edj_dir;
base::FilePath magnifier_edj;
base::PathService::Get(PathsEfl::EDJE_RESOURCE_DIR, &edj_dir);
magnifier_edj = edj_dir.Append(FILE_PATH_LITERAL("Magnifier.edj"));
- container_ = elm_layout_add(top_widget);
+ container_ =
+ elm_layout_add(controller_->rwhva()->offscreen_helper()->content_image());
elm_layout_file_set(container_, magnifier_edj.AsUTF8Unsafe().c_str(), "magnifier");
edje_object_part_geometry_get(elm_layout_edje_get(container_), "bg", 0, 0, &width_, &height_);
}
}
void SelectionMagnifierEfl::HandleLongPress(const gfx::Point& touch_point) {
- evas_object_event_callback_add(controller_->GetParentView(),
- EVAS_CALLBACK_MOUSE_MOVE,
- OnAnimatorMove,
- this);
- evas_object_event_callback_add(controller_->GetParentView(),
- EVAS_CALLBACK_MOUSE_UP,
- OnAnimatorUp,
- this);
+ evas_object_event_callback_add(
+ controller_->rwhva()->offscreen_helper()->content_image(),
+ EVAS_CALLBACK_MOUSE_MOVE, OnAnimatorMove, this);
+ evas_object_event_callback_add(
+ controller_->rwhva()->offscreen_helper()->content_image(),
+ EVAS_CALLBACK_MOUSE_UP, OnAnimatorUp, this);
// Call OnAnimatorMove here, so that the magnifier widget
// gets properly placed. Other calls to it are expected to
// happen as a react to finger/mouse movements.
}
void SelectionMagnifierEfl::DisconnectCallbacks() {
- evas_object_event_callback_del(controller_->GetParentView(),
- EVAS_CALLBACK_MOUSE_MOVE,
- OnAnimatorMove);
- evas_object_event_callback_del(controller_->GetParentView(),
- EVAS_CALLBACK_MOUSE_UP,
- OnAnimatorUp);
+ evas_object_event_callback_del(
+ controller_->rwhva()->offscreen_helper()->content_image(),
+ EVAS_CALLBACK_MOUSE_MOVE, OnAnimatorMove);
+ evas_object_event_callback_del(
+ controller_->rwhva()->offscreen_helper()->content_image(),
+ EVAS_CALLBACK_MOUSE_UP, OnAnimatorUp);
}
void SelectionMagnifierEfl::OnAnimatorMove(void* data, Evas*, Evas_Object*, void*) {
void SelectionMagnifierEfl::OnAnimatorMove() {
Evas_Coord_Point point;
- evas_pointer_canvas_xy_get(evas_object_evas_get(controller_->GetParentView()),
- &point.x,
- &point.y);
+ evas_pointer_canvas_xy_get(
+ evas_object_evas_get(
+ controller_->rwhva()->offscreen_helper()->content_image()),
+ &point.x, &point.y);
gfx::Point display_point(point.x, point.y);
controller_->HandleLongPressMoveEvent(display_point);
UpdateLocation(display_point);
void SelectionMagnifierEfl::UpdateLocation(const gfx::Point& location) {
int device_x, device_y, device_width, device_height;
- evas_object_geometry_get(controller_->GetParentView(),
- &device_x,
- &device_y,
- &device_width,
- &device_height);
+ evas_object_geometry_get(
+ controller_->rwhva()->offscreen_helper()->content_image(), &device_x,
+ &device_y, &device_width, &device_height);
int zoomedWidth = width_ * kZoomScale;
int zoomedHeight = height_ * kZoomScale;
void SelectionMagnifierEfl::Move(const gfx::Point& location) {
int device_x, device_y, device_width, device_height;
- evas_object_geometry_get(controller_->GetParentView(),
- &device_x,
- &device_y,
- &device_width,
- &device_height);
+ evas_object_geometry_get(
+ controller_->rwhva()->offscreen_helper()->content_image(), &device_x,
+ &device_y, &device_width, &device_height);
int magnifier_x = location.x();
int magnifier_y = location.y() - height_ - kHeightOffset;
if (rwhv)
rwhv->set_magnifier(true);
#endif
- if (controller_->GetParentView())
- evas_object_smart_callback_call(controller_->GetParentView(), "magnifier,show", NULL);
+ if (controller_->rwhva()->offscreen_helper()->ewk_view()) {
+ evas_object_smart_callback_call(
+ controller_->rwhva()->offscreen_helper()->ewk_view(), "magnifier,show",
+ nullptr);
+ }
}
void SelectionMagnifierEfl::Hide() {
if (rwhv)
rwhv->set_magnifier(false);
#endif
- if (controller_->GetParentView())
- evas_object_smart_callback_call(controller_->GetParentView(), "magnifier,hide", NULL);
+ if (controller_->rwhva()->offscreen_helper()->ewk_view()) {
+ evas_object_smart_callback_call(
+ controller_->rwhva()->offscreen_helper()->ewk_view(), "magnifier,hide",
+ nullptr);
+ }
}
}
namespace content {
class SelectionControllerEfl;
-class WebContents;
class SelectionMagnifierEfl {
public:
- SelectionMagnifierEfl(content::SelectionControllerEfl* controller,
- WebContents& web_contents);
+ SelectionMagnifierEfl(content::SelectionControllerEfl* controller);
~SelectionMagnifierEfl();
void HandleLongPress(const gfx::Point& touch_point);
// Parent to send back mouse events
SelectionControllerEfl* controller_;
- WebContents& web_contents_;
-
// Magnifier
Evas_Object* container_;
rel2 { relative: 1.0 1.0; }
}
}
+ part {
+ name: "autofill_popup";
+ type: SWALLOW;
+ scale: 1;
+ description {
+ state: "default" 0.0;
+ visible: 1;
+ fixed: 1 1;
+ align: 0.0 0.0;
+ rel1 { relative: 0.0 0.0; to:"content";}
+ rel2 { relative: 1.0 1.0; to:"content";}
+ }
+ }
+ part {
+ name: "context_menu_popup";
+ type: SWALLOW;
+ scale: 1;
+ description {
+ state: "default" 0.0;
+ visible: 1;
+ fixed: 1 1;
+ align: 0.0 0.0;
+ rel1 { relative: 0.0 0.0; to:"content";}
+ rel2 { relative: 1.0 1.0; to:"content";}
+ }
+ }
}
}
}
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/ui/popup_item_ids.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/paths_efl.h"
#include "eweb_view.h"
#include "tizen/system_info.h"
autofill_list_(nullptr),
password_popup_(nullptr),
selected_line_(-1) {
- Evas_Object* widgetWin_ = elm_object_top_widget_get(
- elm_object_parent_widget_get(view->evas_object()));
- if (!widgetWin_)
- widgetWin_ = view->evas_object();
- autofill_popup_ = elm_layout_add(widgetWin_);
+ auto native_view =
+ static_cast<content::WebContentsImpl*>(&(webview_->web_contents()))
+ ->GetEflNativeView();
+
if (!autofill_popup_)
return;
+ auto smart_parent = evas_object_smart_parent_get(native_view);
+ if (!smart_parent) {
+ LOG(ERROR) << "Unable to get smart parent from native view";
+ evas_object_del(autofill_popup_);
+ autofill_popup_ = nullptr;
+ return;
+ }
+ evas_object_smart_member_add(autofill_popup_, smart_parent);
+ elm_object_part_content_set(smart_parent, "autofill_popup", autofill_popup_);
base::FilePath edj_dir;
base::FilePath autofill_edj;
base::PathService::Get(PathsEfl::EDJE_RESOURCE_DIR, &edj_dir);
AutofillPopupViewEfl::~AutofillPopupViewEfl()
{
- if (autofill_popup_)
+ if (autofill_popup_) {
+ evas_object_smart_member_del(autofill_popup_);
evas_object_del(autofill_popup_);
+ }
if (password_popup_)
evas_object_del(password_popup_);
}
class RectF;
}
+namespace content {
+class WebContentsImpl;
+}
+
namespace autofill {
class AutofillPopupViewEfl {
#include "base/strings/utf_string_conversions.h"
#include "browser_context_efl.h"
#include "common/web_contents_utils.h"
+#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/selection/selection_controller_efl.h"
#include "content/common/paths_efl.h"
#include "content/public/browser/browser_thread.h"
params_.link_url.spec(),
params_.link_url.spec());
}
-#if !defined(EWK_BRINGUP)
- RenderWidgetHostViewEfl* rwhv = static_cast<RenderWidgetHostViewEfl*>(web_contents_.GetRenderWidgetHostView());
+ RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
+ web_contents_.GetRenderWidgetHostView());
if ((params_.media_type != ContextMenuDataMediaType::kImage &&
!params_.selection_text.empty()) ||
- (params_.is_editable && (rwhv && !rwhv->IsLastAvailableTextEmpty()))) {
+ (params_.is_editable &&
+ (rwhva && rwhva->offscreen_helper()->HasSelectableText()))) {
AddItemToProposedList(EWK_CONTEXT_MENU_ITEM_TYPE_ACTION, EWK_CONTEXT_MENU_ITEM_TAG_SELECT_WORD,
std::string(dgettext("WebKit", "IDS_WEBVIEW_OPT_SELECT_ABB")));
AddItemToProposedList(EWK_CONTEXT_MENU_ITEM_TYPE_ACTION, EWK_CONTEXT_MENU_ITEM_TAG_SELECT_ALL,
std::string(dgettext("WebKit", "IDS_WEBVIEW_OPT_SELECT_ALL_ABB")));
}
+#if !defined(EWK_BRINGUP)
if (params_.is_draggable) {
AddItemToProposedList(EWK_CONTEXT_MENU_ITEM_TYPE_ACTION, EWK_CONTEXT_MENU_ITEM_TAG_DRAG,
std::string(dgettext("WebKit", "IDS_WEBVIEW_OPT_DRAG_AND_DROP")));
if (!popup_)
return false;
+ auto smart_parent = evas_object_smart_parent_get(native_view_);
+ if (!smart_parent) {
+ LOG(ERROR) << "Unable to get smart parent from native view";
+ evas_object_del(popup_);
+ popup_ = nullptr;
+ return false;
+ }
+ evas_object_smart_member_add(popup_, smart_parent);
+ elm_object_part_content_set(smart_parent, "context_menu_popup", popup_);
evas_object_data_set(popup_, "ContextMenuContollerEfl", this);
void ContextMenuControllerEfl::ContextMenuHWBackKey(void* data, Evas_Object* obj,
void* event_info) {
- ContextMenuControllerEfl* menu_controller = static_cast<ContextMenuControllerEfl*>(data);
+ auto menu_controller = static_cast<ContextMenuControllerEfl*>(data);
if (menu_controller) {
+ auto selection_controller =
+ menu_controller->webview_->GetSelectionController();
+
+ if (selection_controller)
+ selection_controller->ToggleCaretAfterSelection();
+
menu_controller->HideContextMenu();
evas_object_data_del(obj, "ContextEfl");
}
}
web_contents_.Focus();
} else {
+ evas_object_smart_callback_add(popup_, "block,clicked",
+ BlockClickedCallback, this);
+ }
+
#if BUILDFLAG(IS_TIZEN)
eext_object_event_callback_add(popup_, EEXT_CALLBACK_BACK, ContextMenuHWBackKey, this);
// Workaround. After context menu shows up, there is "unfocused" event fired.
// evas_object_smart_callback_add(popup_, "unfocused", ContextMenuHWBackKey, this);
evas_object_focus_set(popup_, EINA_TRUE);
#endif
- evas_object_smart_callback_add(popup_, "block,clicked", BlockClickedCallback, this);
- }
- evas_object_show(popup_);
- return true;
+ evas_object_show(popup_);
+ evas_object_raise(popup_);
+ return true;
}
void ContextMenuControllerEfl::HideSelectionHandle() {
void ContextMenuControllerEfl::HideContextMenu() {
if (popup_) {
+ evas_object_event_callback_del(popup_, EVAS_CALLBACK_RESIZE,
+ ContextMenuPopupResize);
evas_object_del(popup_);
- popup_ = NULL;
+ popup_ = nullptr;
}
_context_menu_resized = false;
- if (menu_items_) {
+ if (IsMobileProfile()) {
+#if !defined(EWK_BRINGUP)
+ context_menu_status_ = HIDDEN;
+#endif
+ } else if (menu_items_) {
void* data;
EINA_LIST_FREE(menu_items_, data) {
_Ewk_Context_Menu_Item *item = static_cast<_Ewk_Context_Menu_Item*> (data);
delete item;
}
- menu_items_ = NULL;
+ menu_items_ = nullptr;
}
}
-
void ContextMenuControllerEfl::SetPopupSize(int width, int height) {
if (save_fail_dialog_)
save_fail_dialog_->SetPopupSize(width, height);
if (popup_) {
evas_object_data_set(popup_, "ContextMenuContollerEfl", 0);
+ evas_object_smart_member_del(popup_);
evas_object_del(popup_);
popup_ = 0;
}
static const char* kRendererCrashedHTMLMessage =
"<html><body><h1>Renderer process has crashed!</h1></body></html>";
+// "visible,content,changed" is an email-app specific signal which informs
+// that the web view is only partially visible.
+static const char* kVisibleContentChangedSignalName = "visible,content,changed";
+
inline void SetDefaultStringIfNull(const char*& variable,
const char* default_string) {
if (!variable) {
view->SetFocus(EINA_FALSE);
}
+void EWebView::VisibleContentChangedCallback(void* user_data,
+ Evas_Object* /*object*/,
+ void* event_info) {
+ auto view = static_cast<EWebView*>(user_data);
+ auto rect = static_cast<Eina_Rectangle*>(event_info);
+ view->GetSelectionController()->SetCustomVisibleViewRect(
+ gfx::Rect(rect->x, rect->y, rect->w, rect->h));
+}
+
EWebView::EWebView(Ewk_Context* context, Evas_Object* object)
: context_(context),
evas_object_(object),
y_delta_(0.0),
is_initialized_(false) {
if (evas_object_) {
- evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_IN,
- OnViewFocusIn, this);
- evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
- OnViewFocusOut, this);
+ evas_object_smart_callback_add(evas_object_,
+ kVisibleContentChangedSignalName,
+ VisibleContentChangedCallback, this);
+
+ evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_IN,
+ OnViewFocusIn, this);
+ evas_object_event_callback_add(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
+ OnViewFocusOut, this);
}
}
OnViewFocusIn);
evas_object_event_callback_del(evas_object_, EVAS_CALLBACK_FOCUS_OUT,
OnViewFocusOut);
+ evas_object_smart_callback_del(evas_object_,
+ kVisibleContentChangedSignalName,
+ VisibleContentChangedCallback);
}
}
}
void EWebView::MoveCaret(const gfx::Point& point) {
-#if !defined(USE_AURA)
- if (rwhv())
- rwhv()->MoveCaret(point);
-#endif
+ if (rwhva())
+ rwhva()->offscreen_helper()->MoveCaret(point);
}
SelectionControllerEfl* EWebView::GetSelectionController() const {
void EWebView::EvasToBlinkCords(int x, int y, int* view_x, int* view_y) {
DCHECK(display::Screen::GetScreen());
- Evas_Coord tmpX, tmpY;
- evas_object_geometry_get(evas_object_, &tmpX, &tmpY, NULL, NULL);
+ if (!rwhva())
+ return;
+
+ gfx::Rect view_bounds = rwhva()->offscreen_helper()->GetViewBoundsInPix();
if (view_x) {
- *view_x = x - tmpX;
+ *view_x = x - view_bounds.x();
*view_x /=
display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
}
if (view_y) {
- *view_y = y - tmpY;
+ *view_y = y - view_bounds.y();
*view_y /=
display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
}
static void OnViewFocusIn(void* data, Evas*, Evas_Object*, void*);
static void OnViewFocusOut(void* data, Evas*, Evas_Object*, void*);
+ static void VisibleContentChangedCallback(void* user_data,
+ Evas_Object* object,
+ void* event_info);
scoped_refptr<WebViewEvasEventHandler> evas_event_handler_;
scoped_refptr<Ewk_Context> context_;