From: v-saha Date: Fri, 17 Feb 2023 12:34:31 +0000 (+0530) Subject: [M108 Migration] Selection & Context menu controller. X-Git-Tag: submit/tizen/20230305.160307~33 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F15%2F288515%2F4;p=platform%2Fframework%2Fweb%2Fchromium-efl.git [M108 Migration] Selection & Context menu controller. This change migrates below fixes related to context menu/text selection. 1. Uses GetSelectedText in RWHVA. 2. Avoid hiding context menu during potrait to landscape and vice versa. 3. Do not restore context popup when in caret mode. Reference: https://review.tizen.org/gerrit/282457 Change-Id: Iadc9cb3c5bb9948b867c24ba825e658260908a8c Signed-off-by: v-saha --- diff --git a/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.cc b/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.cc index efca84b..225550c 100644 --- a/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.cc +++ b/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.cc @@ -137,9 +137,8 @@ bool SelectionControllerEfl::GetCaretSelectionStatus() const { return selection_mode_ == SelectionMode::CARET; } -void SelectionControllerEfl::SetControlsTemporarilyHidden( - bool value, - bool from_custom_scroll_callback) { +void SelectionControllerEfl::SetControlsTemporarilyHidden(bool value, + bool set_forcefully) { TRACE_EVENT1("selection,efl", __PRETTY_FUNCTION__, "controls are hidden:", value); if (controls_temporarily_hidden_ == value) @@ -147,7 +146,7 @@ void SelectionControllerEfl::SetControlsTemporarilyHidden( // Make sure to show selection controls only when no finger // is left touching the screen. if (!value && rwhva_->event_handler()->pointer_state().GetPointerCount() && - !from_custom_scroll_callback) { + !set_forcefully) { return; } controls_temporarily_hidden_ = value; @@ -164,13 +163,14 @@ void SelectionControllerEfl::SetIsAnchorFirst(bool value) { } void SelectionControllerEfl::TriggerOnSelectionChange() { + triggered_selection_change_ = true; OnSelectionChanged(start_selection_, end_selection_); } void SelectionControllerEfl::OnSelectionChanged( const gfx::SelectionBound& start, const gfx::SelectionBound& end) { if (start_selection_ == start && end_selection_ == end && - selection_change_reason_ != Reason::RequestedByContextMenu) + !triggered_selection_change_) return; if (selection_change_reason_ != Reason::HandleDragged) @@ -202,11 +202,12 @@ void SelectionControllerEfl::OnSelectionChanged( bool show = (selection_change_reason_ != Reason::Irrelevant) && !finger_down; UpdateSelectionDataAndShow( truncated_start, truncated_end, show); + triggered_selection_change_ = false; 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_ && + if (GetSelectionEditable() && !handle_being_dragged_ && rwhva_ && rwhva_->GetSelectedText() == (u"\n")) { rwhva_->offscreen_helper()->MoveCaret( selection_data_->GetLeftRect().origin()); @@ -238,6 +239,11 @@ void SelectionControllerEfl::OnTextInputStateChanged() { HideHandleAndContextMenu(); ClearSelection(); } + + if (selection_change_reason_ == Reason::CaretModeForced) { + is_caret_mode_forced_ = false; + selection_change_reason_ = Reason::Irrelevant; + } } void SelectionControllerEfl::UpdateSelectionData(const std::u16string& text) { @@ -308,10 +314,8 @@ bool SelectionControllerEfl::UpdateSelectionDataAndShow( return false; } - if (selection_changed || - selection_change_reason_ == Reason::RequestedByContextMenu) { + if (selection_changed || triggered_selection_change_) ShowHandleAndContextMenuIfRequired(); - } return true; } @@ -389,6 +393,11 @@ void SelectionControllerEfl::ShowHandleAndContextMenuIfRequired( selection_change_reason_ = saved_reason; ShowContextMenu(); } + + // In order to keep selection controlls showing up, + // Reason::CaretModeForced should be used as a reason of selection change. + if (is_caret_mode_forced_) + selection_change_reason_ = Reason::CaretModeForced; return; } input_handle_->Hide(); @@ -709,7 +718,6 @@ void SelectionControllerEfl::HandlePostponedGesture(int x, bool SelectionControllerEfl::HandleLongPressEvent( const gfx::Point& touch_point, const content::ContextMenuParams& params) { - if (params.is_editable) { // If one long press on an empty form, do not enter selection mode. // Instead, context menu will be shown if needed for clipboard actions. diff --git a/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.h b/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.h index b41234c..c687da4 100644 --- a/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.h +++ b/tizen_src/chromium_impl/content/browser/selection/selection_controller_efl.h @@ -86,8 +86,7 @@ class CONTENT_EXPORT SelectionControllerEfl { void HideHandleAndContextMenu(); bool IsAnyHandleVisible() const; - void SetControlsTemporarilyHidden(bool hidden, - bool from_custom_scroll_callback = false); + void SetControlsTemporarilyHidden(bool hidden, bool set_forcefully = false); gfx::Rect GetLeftRect() const; gfx::Rect GetRightRect() const; @@ -240,6 +239,7 @@ class CONTENT_EXPORT SelectionControllerEfl { enum ContextMenuStatus context_menu_status_ = ContextMenuStatus::NONE; enum SelectionMode selection_mode_ = SelectionMode::NONE; + bool triggered_selection_change_ = false; gfx::SelectionBound start_selection_; gfx::SelectionBound end_selection_; }; diff --git a/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc b/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc index 0590549..838a328 100644 --- a/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc +++ b/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc @@ -225,24 +225,66 @@ void ContextMenuControllerEfl::GetProposedContextMenu() { params_.link_url.spec(), params_.link_url.spec()); } - RenderWidgetHostViewAura* rwhva = static_cast( - web_contents_.GetRenderWidgetHostView()); - if ((params_.media_type != ContextMenuDataMediaType::kImage && - !params_.selection_text.empty()) || - (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 BUILDFLAG(IS_TIZEN) - if (!params_.is_editable && !params_.selection_text.empty()) { - // TODO: IDS_WEBVIEW_OPT_SHARE should be added for all po files. - AddItemToProposedList(EWK_CONTEXT_MENU_ITEM_TYPE_ACTION, - EWK_CONTEXT_MENU_ITEM_TAG_SHARE, - dgettext("WebKit", "IDS_WEBVIEW_OPT_SHARE")); + if (params_.is_editable) { + RenderWidgetHostViewAura* rwhva = static_cast( + web_contents_.GetRenderWidgetHostView()); + const SelectionControllerEfl* controller = + webview_->GetSelectionController(); + bool should_add_select_and_select_all = + (!controller) ? true : !controller->IsCaretModeForced(); + + if (rwhva && rwhva->offscreen_helper()->HasSelectableText() && + should_add_select_and_select_all) { + if (params_.selection_text.empty() && + params_.input_field_type != + blink::mojom::ContextMenuDataInputFieldType::kPassword) { + AddItemToProposedList( + EWK_CONTEXT_MENU_ITEM_TYPE_ACTION, + EWK_CONTEXT_MENU_ITEM_TAG_SELECT_WORD, + std::string(dgettext("WebKit", "IDS_WEBVIEW_OPT_SELECT_ABB"))); + } + + // This is a tricky way to check if everything in the editable field is + // selected, because there is no other known way. + // + // * params_.selection_text contains selected text + // * rwhva->GetSelectedText() contains selected + // text and some text around selection + // + // If both strings are the same length, it means that the selection has + // no more text around it, so everything is already selected. + // + // There is also one more issue with this hack: if the last character of + // textarea is '\n', there will be additional '\n' reported in selection + // with surrounding characters, which isn't reported in selection text + // from params_. This means that lengths aren't equal, so normal length + // check won't work. + // + // To work around this, we assume that everything is already selected if + // selection with surroundings is one character longer than selection, + // and that last character is '\n'. + size_t surroundings_length = rwhva->GetSelectedText().length(); + size_t selection_length = params_.selection_text.length(); + char16_t surroundings_last_char = + rwhva->GetSelectedText()[surroundings_length - 1]; + + if (surroundings_length != selection_length && + !(surroundings_length == selection_length + 1 && + surroundings_last_char == '\n')) { + AddItemToProposedList( + EWK_CONTEXT_MENU_ITEM_TYPE_ACTION, + EWK_CONTEXT_MENU_ITEM_TAG_SELECT_ALL, + std::string(dgettext("WebKit", "IDS_WEBVIEW_OPT_SELECT_ALL_ABB"))); + } + } + } else { + if (params_.media_type != ContextMenuDataMediaType::kImage && + is_text_selection_) { + AddItemToProposedList( + EWK_CONTEXT_MENU_ITEM_TYPE_ACTION, + EWK_CONTEXT_MENU_ITEM_TAG_SELECT_ALL, + std::string(dgettext("WebKit", "IDS_WEBVIEW_OPT_SELECT_ALL_ABB"))); } -#endif } #if BUILDFLAG(IS_TIZEN) if (IsMobileProfile() && params_.is_draggable && @@ -437,8 +479,10 @@ Eina_Bool ContextMenuControllerEfl::RestoreTimerCallback(void* data) { menu_controller->webview_->GetSelectionController(); if (menu_controller->popup_ && selection_controller && - selection_controller->GetSelectionStatus()) + selection_controller->GetSelectionStatus() && + !selection_controller->IsCaretMode()) { evas_object_show(menu_controller->popup_); + } menu_controller->restore_timer_ = nullptr; diff --git a/tizen_src/ewk/efl_integration/web_contents_view_delegate_ewk.cc b/tizen_src/ewk/efl_integration/web_contents_view_delegate_ewk.cc index f4433aa..e3b770e 100644 --- a/tizen_src/ewk/efl_integration/web_contents_view_delegate_ewk.cc +++ b/tizen_src/ewk/efl_integration/web_contents_view_delegate_ewk.cc @@ -19,7 +19,7 @@ WebContentsViewDelegateEwk::WebContentsViewDelegateEwk(EWebView* wv) void WebContentsViewDelegateEwk::ShowContextMenu( content::RenderFrameHost& render_frame_host, const content::ContextMenuParams& params) { - if (params.source_type == ui::MENU_SOURCE_TOUCH) { + if (params.source_type == ui::MENU_SOURCE_LONG_PRESS) { CHECK(web_view_->TouchEventsEnabled()); web_view_->HandleLongPressGesture(params); } else {