From 062b83aa082b7cc81fdeca586e66fe98a5753015 Mon Sep 17 00:00:00 2001 From: liwei Date: Thu, 3 Mar 2022 15:24:01 +0800 Subject: [PATCH] [M94 Migration] Refactor JavaScriptModalDialog for EWK and WRT JavaScriptModalDialog implementation is pretty much the same both EWK and WRT. - WRTJavaScriptModalDialog and JavaScriptModalDialogEfl This patch will refactor 2 almost identical classes by common code and be able to improve maintainability. Reference: https://review.tizen.org/gerrit/248006/ And for compile, upload some logic from https://review.tizen.org/gerrit/267646/. Change-Id: I10ce6e4e2de9575d869c33d6089cc5694c94a83a Signed-off-by: liwei --- .../content/browser/browser_efl.gni | 2 + .../javascript_modal_dialog.cc | 499 ++++++++++++++++++ .../javascript_modal_dialog.h | 93 ++++ .../chromium_impl/content/common/paths_efl.h | 1 + .../browser/javascript_dialog_manager_efl.cc | 12 +- .../browser/javascript_modal_dialog_efl.cc | 433 ++------------- .../browser/javascript_modal_dialog_efl.h | 52 +- .../context_menu_controller_efl.cc | 4 +- 8 files changed, 654 insertions(+), 442 deletions(-) create mode 100644 tizen_src/chromium_impl/content/browser/javascript_dialog/javascript_modal_dialog.cc create mode 100644 tizen_src/chromium_impl/content/browser/javascript_dialog/javascript_modal_dialog.h diff --git a/tizen_src/chromium_impl/content/browser/browser_efl.gni b/tizen_src/chromium_impl/content/browser/browser_efl.gni index b463e0d6f1de..c15aebee6c90 100644 --- a/tizen_src/chromium_impl/content/browser/browser_efl.gni +++ b/tizen_src/chromium_impl/content/browser/browser_efl.gni @@ -72,6 +72,8 @@ external_content_browser_efl_sources = [ "//tizen_src/chromium_impl/content/browser/compositor/evasgl_delegated_frame_host.h", "//tizen_src/chromium_impl/content/browser/compositor/evasgl_output_surface.cc", "//tizen_src/chromium_impl/content/browser/compositor/evasgl_output_surface.h", + "//tizen_src/chromium_impl/content/browser/javascript_dialog/javascript_modal_dialog.cc", + "//tizen_src/chromium_impl/content/browser/javascript_dialog/javascript_modal_dialog.h", "//tizen_src/chromium_impl/content/browser/media/capture/mouse_cursor_overlay_controller_efl.cc", "//tizen_src/chromium_impl/content/browser/public/browser/web_contents_efl_delegate.h", "//tizen_src/chromium_impl/content/browser/public/browser/web_contents_view_efl_delegate.h", diff --git a/tizen_src/chromium_impl/content/browser/javascript_dialog/javascript_modal_dialog.cc b/tizen_src/chromium_impl/content/browser/javascript_dialog/javascript_modal_dialog.cc new file mode 100644 index 000000000000..4e294765b8e7 --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/javascript_dialog/javascript_modal_dialog.cc @@ -0,0 +1,499 @@ +// Copyright 2020 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "javascript_modal_dialog.h" + +#include + +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "base/strings/utf_string_conversions.h" +#include "content/common/paths_efl.h" +#include "content/public/browser/web_contents.h" +#include "tizen_src/chromium_impl/tizen/system_info.h" +#include "ui/display/device_display_info_efl.h" +#include "url/gurl.h" + +#if defined(OS_TIZEN) +#include +#endif + +namespace content { + +namespace { + +static void PromptEnterKeyDownCallback(void*, Evas_Object* obj, void*) { + elm_entry_input_panel_hide(obj); +} + +} // namespace + +// static +JavaScriptModalDialog* JavaScriptModalDialog::CreateDialogAndShow( + content::WebContents* web_contents, + Type type, + const std::u16string& message_text, + const std::u16string& default_prompt_text, + content::JavaScriptDialogManager::DialogClosedCallback callback, + Evas_Object* parent) { + JavaScriptModalDialog* dialog = new JavaScriptModalDialog( + web_contents, type, message_text, default_prompt_text, + std::move(callback), parent); + if (!dialog->ShowJavaScriptDialog()) { + LOG(ERROR) << "Could not create javascript dialog."; + delete dialog; + dialog = nullptr; + } + return dialog; +} + +JavaScriptModalDialog::JavaScriptModalDialog( + content::WebContents* web_contents, + Type type, + const std::u16string& message_text, + const std::u16string& default_prompt_text, + content::JavaScriptDialogManager::DialogClosedCallback callback, + Evas_Object* evas_object) + : window_(nullptr), + conformant_(nullptr), + popup_(nullptr), + prompt_entry_(nullptr), + parent_(elm_object_parent_widget_get(evas_object)), + is_callback_processed_(false), + is_showing_(false), + web_contents_(web_contents), + type_(type), + message_text_(message_text), + default_prompt_text_(default_prompt_text), + close_callback_(std::move(callback)), + prompt_entry_changed_callback_(nullptr) {} + +JavaScriptModalDialog::~JavaScriptModalDialog() { + Close(); +} + +bool JavaScriptModalDialog::ShowJavaScriptDialog() { + if (!parent_) + return false; + + Evas_Object* top_window = elm_object_top_widget_get(parent_); + + if (IsMobileProfile() || IsTvProfile()) + popup_ = CreatePopupOnNewWindow(top_window); + else + popup_ = CreatePopup(top_window); + + if (!popup_) + return false; + + if (IsWearableProfile()) + elm_object_style_set(popup_, "circle"); + + switch (type_) { + case PROMPT: + if (!CreatePromptLayout()) + return false; + break; + case NAVIGATION: + if (!CreateNavigationLayout()) + return false; + break; + case ALERT: + if (!CreateAlertLayout()) + return false; + break; + case CONFIRM: + if (!CreateConfirmLayout()) + return false; + break; + } + +#if defined(OS_TIZEN) + eext_object_event_callback_add(popup_, EEXT_CALLBACK_BACK, + CancelButtonCallback, this); +#endif + + evas_object_focus_set(popup_, true); + evas_object_show(popup_); + + is_showing_ = true; + + return true; +} + +Evas_Object* JavaScriptModalDialog::CreatePopup(Evas_Object* window) { + if (!window) + return nullptr; + + conformant_ = elm_conformant_add(window); + if (!conformant_) + return nullptr; + + evas_object_size_hint_weight_set(conformant_, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + elm_win_resize_object_add(window, conformant_); + evas_object_show(conformant_); + Evas_Object* layout = elm_layout_add(conformant_); + if (!layout) + return nullptr; + + elm_layout_theme_set(layout, "layout", "application", "default"); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(layout); + + elm_object_content_set(conformant_, layout); + + return elm_popup_add(layout); +} + +Evas_Object* JavaScriptModalDialog::CreatePopupOnNewWindow( + Evas_Object* top_window) { + if (!top_window) + return nullptr; + + window_ = elm_win_add(top_window, "JavaScriptModalDialog", ELM_WIN_BASIC); + if (!window_) + return nullptr; + + elm_win_alpha_set(window_, EINA_TRUE); + + if (elm_win_indicator_mode_get(top_window) == ELM_WIN_INDICATOR_SHOW) + elm_win_indicator_mode_set(window_, ELM_WIN_INDICATOR_SHOW); + + if (elm_win_indicator_opacity_get(top_window) == + ELM_WIN_INDICATOR_TRANSPARENT) + elm_win_indicator_opacity_set(window_, ELM_WIN_INDICATOR_TRANSPARENT); + + if (elm_win_wm_rotation_supported_get(top_window)) { + int rots[] = {0, 90, 180, 270}; + elm_win_wm_rotation_available_rotations_set(window_, rots, 4); + } + + display::DeviceDisplayInfoEfl display_info; + evas_object_resize(window_, display_info.GetDisplayWidth(), + display_info.GetDisplayHeight()); + + Evas_Object* popup = CreatePopup(window_); + elm_win_conformant_set(window_, EINA_TRUE); + evas_object_show(window_); + + return popup; +} + +bool JavaScriptModalDialog::CreatePromptLayout() { + Evas_Object* layout = elm_layout_add(popup_); + if (!layout) + return false; + if (IsWearableProfile()) { + elm_layout_theme_set(layout, "layout", "popup", "content/circle/buttons2"); + if (message_text_.c_str()) { + elm_object_part_text_set(layout, "elm.text.title", + base::UTF16ToUTF8(message_text_).c_str()); + } + } else { + if (message_text_.c_str()) { + elm_object_part_text_set(popup_, "title,text", + base::UTF16ToUTF8(message_text_).c_str()); + } + + elm_layout_file_set(layout, GetEdjPath().c_str(), "prompt"); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + } + + prompt_entry_ = elm_entry_add(popup_); + if (!prompt_entry_) + return false; + + if (prompt_entry_changed_callback_) { + Ecore_IMF_Context* imf_context = static_cast( + elm_entry_imf_context_get(prompt_entry_)); + ecore_imf_context_input_panel_event_callback_add( + imf_context, ECORE_IMF_INPUT_PANEL_STATE_EVENT, + prompt_entry_changed_callback_, prompt_entry_); + } + elm_entry_single_line_set(prompt_entry_, EINA_TRUE); + elm_entry_input_panel_return_key_type_set( + prompt_entry_, ELM_INPUT_PANEL_RETURN_KEY_TYPE_DONE); + evas_object_smart_callback_add(prompt_entry_, "activated", + PromptEnterKeyDownCallback, this); + elm_object_text_set(prompt_entry_, + base::UTF16ToUTF8(default_prompt_text_).c_str()); + elm_entry_scrollable_set(prompt_entry_, EINA_TRUE); + elm_entry_cursor_end_set(prompt_entry_); + + if (IsWearableProfile()) + elm_object_part_content_set(layout, "elm.swallow.content", prompt_entry_); + else + elm_object_part_content_set(layout, "prompt_container", prompt_entry_); + + elm_object_content_set(popup_, layout); + Evas_Object* cancel_btn = AddButton("IDS_WEBVIEW_BUTTON_CANCEL_ABB4", + "button1", CancelButtonCallback); + Evas_Object* ok_btn = + AddButton("IDS_WEBVIEW_BUTTON_OK_ABB4", "button2", OkButtonCallback); + if (!cancel_btn || !ok_btn) + return false; + + evas_object_focus_set(ok_btn, true); + return true; +} + +bool JavaScriptModalDialog::CreateNavigationLayout() { + if (message_text_.c_str()) { + elm_object_part_text_set(popup_, "title,text", + base::UTF16ToUTF8(message_text_).c_str()); + } + + std::string question(dgettext("WebKit", "IDS_WEBVIEW_POP_LEAVE_THIS_PAGE_Q")); + std::string message; + if (default_prompt_text_.c_str()) { + message = std::string(base::UTF16ToUTF8(default_prompt_text_).c_str()) + + ("\n") + question; + } else { + message = question; + } + if (IsWearableProfile() && + !AddCircleLayout(message, "content/circle/buttons2")) { + return false; + } else if (!message_text_.empty()) { + // Use GetPopupMessage() to modify the message_text_ + elm_object_text_set( + popup_, GetPopupMessage(base::UTF16ToUTF8(message_text_)).c_str()); + } + Evas_Object* cancel_btn = + AddButton("IDS_WEBVIEW_BUTTON_STAY", "button1", CancelButtonCallback); + Evas_Object* ok_btn = + AddButton("IDS_WEBVIEW_BUTTON_LEAVE", "button2", OkButtonCallback); + if (!cancel_btn || !ok_btn) + return false; + + evas_object_focus_set(ok_btn, true); + + return true; +} + +bool JavaScriptModalDialog::CreateAlertLayout() { + elm_object_part_text_set(popup_, "title,text", GetTitle().c_str()); + if (IsWearableProfile() && !AddCircleLayout(base::UTF16ToUTF8(message_text_), + "content/circle/buttons1")) + return false; + if (!message_text_.empty()) { + // Use GetPopupMessage() to modify the message_text_ + elm_object_text_set( + popup_, GetPopupMessage(base::UTF16ToUTF8(message_text_)).c_str()); + } + + Evas_Object* ok_btn = + AddButton("IDS_WEBVIEW_BUTTON_OK_ABB4", "button1", OkButtonCallback); + if (!ok_btn) + return false; + + evas_object_focus_set(ok_btn, true); + return true; +} + +bool JavaScriptModalDialog::CreateConfirmLayout() { + elm_object_part_text_set(popup_, "title,text", GetTitle().c_str()); + if (IsWearableProfile() && !AddCircleLayout(base::UTF16ToUTF8(message_text_), + "content/circle/buttons2")) + return false; + if (!message_text_.empty()) { + // Use GetPopupMessage() to modify the message_text_ + elm_object_text_set( + popup_, GetPopupMessage(base::UTF16ToUTF8(message_text_)).c_str()); + } + Evas_Object* cancel_btn = AddButton("IDS_WEBVIEW_BUTTON_CANCEL_ABB4", + "button1", CancelButtonCallback); + Evas_Object* ok_btn = + AddButton("IDS_WEBVIEW_BUTTON_OK_ABB4", "button2", OkButtonCallback); + if (!cancel_btn || !ok_btn) + return false; + + evas_object_focus_set(ok_btn, true); + + return true; +} + +std::string JavaScriptModalDialog::GetTitle() { + const GURL& url = web_contents_->GetVisibleURL(); + std::string text; + if (url.SchemeIsFile() || url.is_empty()) { + if (web_contents_->GetMainFrame()) + text = base::UTF16ToUTF8(web_contents_->GetTitle()); + } else + text = url.possibly_invalid_spec(); + + std::string title = + dgettext("WebKit", "IDS_WEBVIEW_HEADER_MESSAGE_FROM_PS_M_WEBSITE"); + + const std::string replaceStr("%s"); + size_t pos = title.find(replaceStr); + if (pos != std::string::npos) + title.replace(pos, replaceStr.length(), text); + + return title; +} + +std::string JavaScriptModalDialog::GetPopupMessage(const std::string& str) { + if (str.empty()) + return str; + // Replace new line with break in the string + std::string message = std::string(elm_entry_utf8_to_markup(str.c_str())); + base::ReplaceChars(message, "\n", "
", &message); + +#if !defined(OS_TIZEN_TV_PRODUCT) + if (!IsWearableProfile()) + message = "" + message + ""; +#endif + + return message; +} + +std::string JavaScriptModalDialog::GetEdjPath() { + base::FilePath edj_dir; + base::PathService::Get(PathsEfl::EDJE_RESOURCE_DIR, &edj_dir); + return edj_dir.Append(FILE_PATH_LITERAL("JavaScriptPopup.edj")) + .AsUTF8Unsafe(); +} + +// static +void JavaScriptModalDialog::CancelButtonCallback(void* data, + Evas_Object* obj, + void* event_info) { + JavaScriptModalDialog* dialog = static_cast(data); + + std::move(dialog->close_callback_).Run(false, std::u16string()); + evas_object_del(dialog->popup_); + dialog->CloseAndNotify(); +} + +// static +void JavaScriptModalDialog::OkButtonCallback(void* data, + Evas_Object* obj, + void* event_info) { + JavaScriptModalDialog* dialog = static_cast(data); + if (dialog->type_ == PROMPT && dialog->prompt_entry_) { + std::move(dialog->close_callback_) + .Run(true, + base::UTF8ToUTF16(elm_entry_entry_get(dialog->prompt_entry_))); + } else { + std::move(dialog->close_callback_).Run(true, std::u16string()); + } + dialog->CloseAndNotify(); +} + +void JavaScriptModalDialog::Close() { + if (!is_callback_processed_) + std::move(close_callback_).Run(false, std::u16string()); + + if ((IsMobileProfile() || IsTvProfile()) && window_) { + evas_object_del(window_); + window_ = nullptr; + conformant_ = nullptr; + } else if (conformant_) { + evas_object_del(conformant_); + conformant_ = nullptr; + } + + popup_ = nullptr; + prompt_entry_ = nullptr; + + is_showing_ = false; +} + +void JavaScriptModalDialog::SetPopupSize(int width, int height) { + if (!popup_) + return; + + evas_object_resize(popup_, width, height); + evas_object_move(popup_, 0, 0); +} + +Evas_Object* JavaScriptModalDialog::AddButton(const std::string& text, + const std::string& part, + Evas_Smart_Cb callback) { + Evas_Object* btn = elm_button_add(popup_); + if (!btn) + return nullptr; + if (IsWearableProfile()) { + Evas_Object* img; + if (type_ == ALERT) { + elm_object_style_set(btn, "bottom"); + img = AddButtonIcon(btn, "popup_btn_ok.png"); + } else if (part.compare("button1") == 0) { + elm_object_style_set(btn, "popup/circle/left"); + img = AddButtonIcon(btn, "popup_btn_cancel.png"); + } else { + elm_object_style_set(btn, "popup/circle/right"); + img = AddButtonIcon(btn, "popup_btn_ok.png"); + } + + if (!img) + return nullptr; + } else { + elm_object_style_set(btn, "popup"); + elm_object_domain_translatable_part_text_set(btn, nullptr, "WebKit", + text.c_str()); + } + elm_object_part_content_set(popup_, part.c_str(), btn); + evas_object_smart_callback_add(btn, "clicked", callback, this); + return btn; +} + +Evas_Object* JavaScriptModalDialog::AddButtonIcon(Evas_Object* btn, + const std::string& img) { + if (!IsWearableProfile()) + return nullptr; + + Evas_Object* icon = elm_image_add(btn); + if (!icon) + return nullptr; + + base::FilePath img_dir; + base::PathService::Get(PathsEfl::IMAGE_RESOURCE_DIR, &img_dir); + std::string file_path = img_dir.Append(FILE_PATH_LITERAL(img)).AsUTF8Unsafe(); + if (!elm_image_file_set(icon, file_path.c_str(), nullptr)) + return nullptr; + + evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_part_content_set(btn, "elm.swallow.content", icon); + evas_object_show(icon); + return icon; +} + +bool JavaScriptModalDialog::AddCircleLayout(const std::string& title, + const std::string& theme) { + if (!IsWearableProfile()) + return false; + + Evas_Object* layout = elm_layout_add(popup_); + if (!layout) + return false; + + elm_layout_theme_set(layout, "layout", "popup", theme.c_str()); + + if (!title.empty()) { + elm_object_part_text_set(layout, "elm.text", + GetPopupMessage(title).c_str()); + } + + elm_object_content_set(popup_, layout); + + return true; +} + +void JavaScriptModalDialog::SetPopupClosedCallback( + PopupClosedCallback& callback) { + popup_closed_callback_ = std::move(callback); +} + +void JavaScriptModalDialog::CloseAndNotify() { + is_callback_processed_ = true; + Close(); + if (popup_closed_callback_) + std::move(popup_closed_callback_).Run(); +} + +} // namespace content diff --git a/tizen_src/chromium_impl/content/browser/javascript_dialog/javascript_modal_dialog.h b/tizen_src/chromium_impl/content/browser/javascript_dialog/javascript_modal_dialog.h new file mode 100644 index 000000000000..dcfd8d3d72ed --- /dev/null +++ b/tizen_src/chromium_impl/content/browser/javascript_dialog/javascript_modal_dialog.h @@ -0,0 +1,93 @@ +// Copyright 2020 Samsung Electronics. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_JAVASCRIPT_MODAL_DIALOG_H_ +#define CONTENT_BROWSER_JAVASCRIPT_MODAL_DIALOG_H_ + +#include +#include +#include + +#include "base/callback.h" +#include "content/public/browser/javascript_dialog_manager.h" + +namespace content { + +class JavaScriptModalDialog { + public: + typedef void (*PromptEntryChangedCallback)(void*, Ecore_IMF_Context*, int); + typedef base::OnceCallback PopupClosedCallback; + enum Type { ALERT, CONFIRM, NAVIGATION, PROMPT }; + static JavaScriptModalDialog* CreateDialogAndShow( + content::WebContents* web_contents, + Type type, + const std::u16string& message_text, + const std::u16string& default_prompt_text, + content::JavaScriptDialogManager::DialogClosedCallback callback, + Evas_Object* parent); + JavaScriptModalDialog( + content::WebContents* web_contents, + Type type, + const std::u16string& message_text, + const std::u16string& default_prompt_text, + content::JavaScriptDialogManager::DialogClosedCallback callback, + Evas_Object* parent); + virtual ~JavaScriptModalDialog(); + + bool IsShowing() { return is_showing_; } + void SetPopupSize(int width, int height); + void SetParentEvasObject(Evas_Object* parent) { parent_ = parent; } + void SetPromptEntryChangedCallback(PromptEntryChangedCallback callback) { + prompt_entry_changed_callback_ = callback; + } + void SetPopupClosedCallback(PopupClosedCallback& callback); + bool ShowJavaScriptDialog(); + + private: + static void CancelButtonCallback(void* data, + Evas_Object* obj, + void* event_info); + static void OkButtonCallback(void* data, Evas_Object* obj, void* event_info); + + void Close(); + void CloseAndNotify(); + + bool AddCircleLayout(const std::string& title, const std::string& theme); + bool CreatePromptLayout(); + bool CreateAlertLayout(); + bool CreateConfirmLayout(); + bool CreateNavigationLayout(); + + Evas_Object* AddButton(const std::string& text, + const std::string& part, + Evas_Smart_Cb callback); + Evas_Object* AddButtonIcon(Evas_Object* btn, const std::string& img); + Evas_Object* CreatePopup(Evas_Object* window); + Evas_Object* CreatePopupOnNewWindow(Evas_Object* top_window); + + std::string GetEdjPath(); + std::string GetPopupMessage(const std::string&); + std::string GetTitle(); + + Evas_Object* window_; + Evas_Object* conformant_; + Evas_Object* popup_; + Evas_Object* prompt_entry_; + Evas_Object* parent_; + + bool is_callback_processed_; + bool is_showing_; + + content::WebContents* web_contents_; + Type type_; + std::u16string message_text_; + std::u16string default_prompt_text_; + content::JavaScriptDialogManager::DialogClosedCallback close_callback_; + PromptEntryChangedCallback prompt_entry_changed_callback_; + PopupClosedCallback popup_closed_callback_; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_JAVASCRIPT_MODAL_DIALOG_H_ diff --git a/tizen_src/chromium_impl/content/common/paths_efl.h b/tizen_src/chromium_impl/content/common/paths_efl.h index 5a4c3b2a0310..b162d262df46 100644 --- a/tizen_src/chromium_impl/content/common/paths_efl.h +++ b/tizen_src/chromium_impl/content/common/paths_efl.h @@ -12,6 +12,7 @@ namespace PathsEfl { enum { PATH_START = 2000, EDJE_RESOURCE_DIR, + IMAGE_RESOURCE_DIR, WEB_DATABASE_DIR, DIR_USER_DATA, DIR_DATA_PATH, diff --git a/tizen_src/ewk/efl_integration/browser/javascript_dialog_manager_efl.cc b/tizen_src/ewk/efl_integration/browser/javascript_dialog_manager_efl.cc index 859d525748ff..b11690a2febf 100644 --- a/tizen_src/ewk/efl_integration/browser/javascript_dialog_manager_efl.cc +++ b/tizen_src/ewk/efl_integration/browser/javascript_dialog_manager_efl.cc @@ -121,9 +121,9 @@ void JavaScriptDialogManagerEfl::RunJavaScriptDialog( } } - dialog_.reset(JavaScriptModalDialogEfl::CreateDialog( + dialog_.reset(JavaScriptModalDialogEfl::CreateDialogAndShow( web_contents, type, message_text, default_prompt_text, - std::move(callback))); + std::move(dialog_closed_callback_))); } void JavaScriptDialogManagerEfl::SetAlertCallback( @@ -156,7 +156,7 @@ void JavaScriptDialogManagerEfl::ExecuteDialogClosedCallBack( std::move(dialog_closed_callback_) .Run(result, base::UTF8ToUTF16(prompt_data)); if (dialog_) { - dialog_->close(); + dialog_.reset(nullptr); } } @@ -176,11 +176,11 @@ void JavaScriptDialogManagerEfl::RunBeforeUnloadDialog( EWebView* wv = WebViewFromWebContents(web_contents); wv->SmartCallback().call(0); - dialog_.reset(JavaScriptModalDialogEfl::CreateDialog( + dialog_.reset(JavaScriptModalDialogEfl::CreateDialogAndShow( web_contents, JavaScriptModalDialogEfl::NAVIGATION, base::UTF8ToUTF16( - std::string(dgettext("WebKit", "IDS_WEBVIEW_BEFOREUNLOAD_MESSAGE"))), - std::u16string(), std::move(callback))); + std::string(dgettext("WebKit", "IDS_WEBVIEW_POP_LEAVE_THIS_PAGE_Q"))), + std::u16string(), std::move(dialog_closed_callback_))); } bool JavaScriptDialogManagerEfl::HandleJavaScriptDialog( diff --git a/tizen_src/ewk/efl_integration/browser/javascript_modal_dialog_efl.cc b/tizen_src/ewk/efl_integration/browser/javascript_modal_dialog_efl.cc index cd9ae7090578..127dff104859 100644 --- a/tizen_src/ewk/efl_integration/browser/javascript_modal_dialog_efl.cc +++ b/tizen_src/ewk/efl_integration/browser/javascript_modal_dialog_efl.cc @@ -3,34 +3,26 @@ // found in the LICENSE file. #include "javascript_modal_dialog_efl.h" -#include "base/files/file_path.h" -#include "base/path_service.h" -#include "base/strings/utf_string_conversions.h" + +#include "base/callback.h" #include "common/web_contents_utils.h" -#include "content/common/paths_efl.h" #include "eweb_view.h" -#ifdef OS_TIZEN -#include -#endif +/* LCOV_EXCL_START */ +static void PromptEntryChanged(void* data, Ecore_IMF_Context* ctx, int value) { + if (value != ECORE_IMF_INPUT_PANEL_STATE_HIDE) + return; -using web_contents_utils::WebViewFromWebContents; + Evas_Object* entry = static_cast(data); + if (entry) + elm_object_focus_set(entry, EINA_FALSE); +} -//static -JavaScriptModalDialogEfl* JavaScriptModalDialogEfl::CreateDialog( - content::WebContents* web_contents, - Type type, - const std::u16string& message_text, - const std::u16string& default_prompt_text, - content::JavaScriptDialogManager::DialogClosedCallback callback) { - JavaScriptModalDialogEfl* dialog = - new JavaScriptModalDialogEfl(web_contents, type, message_text, - default_prompt_text, std::move(callback)); - if (!dialog->ShowJavaScriptDialog()) { - delete dialog; - dialog = NULL; +static void PopupReplyWaitFinish(EWebView* eweb_view) { + if (eweb_view) { + eweb_view->SmartCallback().call( + nullptr); } - return dialog; } JavaScriptModalDialogEfl::JavaScriptModalDialogEfl( @@ -38,372 +30,35 @@ JavaScriptModalDialogEfl::JavaScriptModalDialogEfl( Type type, const std::u16string& message_text, const std::u16string& default_prompt_text, - content::JavaScriptDialogManager::DialogClosedCallback callback) - : callback_(std::move(callback)), - label_(false), - type_(type), - message_text_(message_text), - default_prompt_text_(default_prompt_text), - web_view_(web_contents_utils::WebViewFromWebContents(web_contents)), - prompt_entry_(NULL), - ok_button_(NULL), - cancel_button_(NULL), - imfContext(NULL) {} - -static void promptEntryChanged(void* data, Ecore_IMF_Context* ctx, int value) { - if (value == ECORE_IMF_INPUT_PANEL_STATE_HIDE) { - Evas_Object* entry = static_cast(data); - if(entry) - elm_object_focus_set(entry, EINA_FALSE); - } -} - -static void promptEnterKeyDownCallback(void* data, Evas_Object* obj, void* eventInfo) { - elm_entry_input_panel_hide(obj); -} - -bool JavaScriptModalDialogEfl::ShowJavaScriptDialog() { - Evas_Object* parent = elm_object_top_widget_get( - elm_object_parent_widget_get(web_view_->evas_object())); - if (!parent) - parent = web_view_->evas_object(); - - Evas_Object* conformant = elm_conformant_add(parent); - if (!conformant) - return 0; - - evas_object_size_hint_weight_set(conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_win_resize_object_add(parent, conformant); - evas_object_show(conformant); - - Evas_Object* layout_ = elm_layout_add(conformant); - if (!layout_) - return 0; - - elm_layout_theme_set(layout_, "layout", "application", "default"); - evas_object_size_hint_weight_set(layout_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_show(layout_); - - elm_object_content_set(conformant, layout_); - - popup_ = elm_popup_add(layout_); - - if (!popup_) - return false; - - if (type_ == PROMPT) { - if (message_text_.c_str()) - elm_object_part_text_set(popup_, "title,text", - base::UTF16ToUTF8(message_text_).c_str()); - - base::FilePath edj_dir; - base::FilePath javaScriptPopup_edj; - base::PathService::Get(PathsEfl::EDJE_RESOURCE_DIR, &edj_dir); - javaScriptPopup_edj = edj_dir.Append(FILE_PATH_LITERAL("JavaScriptPopup.edj")); - - Evas_Object* layout = elm_layout_add(popup_); - elm_layout_file_set(layout, javaScriptPopup_edj.AsUTF8Unsafe().c_str(), "prompt"); - evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - - prompt_entry_ = elm_entry_add(popup_); - - imfContext = static_cast(elm_entry_imf_context_get(prompt_entry_)); - ecore_imf_context_input_panel_event_callback_add(imfContext, ECORE_IMF_INPUT_PANEL_STATE_EVENT, promptEntryChanged, prompt_entry_); - elm_entry_single_line_set(prompt_entry_, EINA_TRUE); - elm_entry_input_panel_return_key_type_set(prompt_entry_, ELM_INPUT_PANEL_RETURN_KEY_TYPE_DONE ); - evas_object_smart_callback_add(prompt_entry_, "activated", promptEnterKeyDownCallback, this); - elm_object_text_set(prompt_entry_, - base::UTF16ToUTF8(default_prompt_text_).c_str()); - elm_entry_scrollable_set(prompt_entry_, EINA_TRUE); - elm_entry_cursor_end_set(prompt_entry_); - - elm_object_part_content_set(layout, "prompt_container", prompt_entry_); - elm_object_content_set(popup_, layout); - - cancel_button_ = elm_button_add(popup_); - elm_object_style_set(cancel_button_, "popup"); - elm_object_text_set(cancel_button_, dgettext("sys_string", "IDS_COM_SK_CANCEL")); - elm_object_part_content_set(popup_, "button1", cancel_button_); - evas_object_smart_callback_add(cancel_button_, "clicked", CancelButtonHandlerForPrompt, this); - - ok_button_ = elm_button_add(popup_); - elm_object_style_set(ok_button_, "popup"); - elm_object_text_set(ok_button_, dgettext("sys_string", "IDS_COM_SK_OK")); - elm_object_part_content_set(popup_, "button2", ok_button_); - evas_object_focus_set(ok_button_, true); - evas_object_smart_callback_add(ok_button_, "clicked", OkButtonHandlerForPrompt, this); - - } else if (type_ == NAVIGATION) { - if (message_text_.c_str()) - elm_object_part_text_set(popup_, "title,text", - base::UTF16ToUTF8(message_text_).c_str()); - - std::string question(dgettext("WebKit", "IDS_WEBVIEW_POP_LEAVE_THIS_PAGE_Q")); - - std::string message; - if (default_prompt_text_.c_str()) - message = std::string(base::UTF16ToUTF8(default_prompt_text_).c_str()) + - ("\n") + question; - else - message = question; - - setLabelText(message.c_str()); - - cancel_button_ = elm_button_add(popup_); - elm_object_style_set(cancel_button_, "popup"); - elm_object_text_set(cancel_button_, dgettext("WebKit", "IDS_WEBVIEW_BUTTON_LEAVE")); - elm_object_part_content_set(popup_, "button1", cancel_button_); - evas_object_smart_callback_add(cancel_button_, "clicked", OkButtonHandlerForPrompt, this); - - ok_button_ = elm_button_add(popup_); - elm_object_style_set(ok_button_, "popup"); - elm_object_text_set(ok_button_, dgettext("WebKit", "IDS_WEBVIEW_BUTTON_STAY")); - elm_object_part_content_set(popup_, "button2", ok_button_); - evas_object_smart_callback_add(ok_button_, "clicked", CancelButtonHandlerForPrompt, this); - } else if (type_ == ALERT) { - if (message_text_.c_str()) { - elm_object_part_text_set(popup_, "title,text", dgettext("WebKit", - "IDS_WEBVIEW_POP_JAVASCRIPT_ALERT")); - } - - if (!setLabelText(base::UTF16ToUTF8(message_text_).c_str())) - return false; - - ok_button_ = elm_button_add(popup_); - elm_object_style_set(ok_button_, "popup"); - elm_object_text_set(ok_button_, dgettext("sys_string", "IDS_COM_SK_OK")); - elm_object_part_content_set(popup_, "button1", ok_button_); - - evas_object_smart_callback_add(ok_button_, "clicked", OkButtonHandlerForAlert, this); - } else if (type_ == CONFIRM) { - if (message_text_.c_str()) { - elm_object_part_text_set(popup_, "title,text", dgettext("WebKit", - "IDS_WEBVIEW_POP_JAVASCRIPT")); - } - - if (!setLabelText(base::UTF16ToUTF8(message_text_).c_str())) - return false; - - cancel_button_ = elm_button_add(popup_); - elm_object_style_set(cancel_button_, "popup"); - elm_object_text_set(cancel_button_, dgettext("sys_string", "IDS_COM_SK_CANCEL")); - elm_object_part_content_set(popup_, "button1", cancel_button_); - evas_object_smart_callback_add(cancel_button_, "clicked", CancelButtonHandlerForConfirm, this); - - ok_button_ = elm_button_add(popup_); - elm_object_style_set(ok_button_, "popup"); - elm_object_text_set(ok_button_, dgettext("sys_string", "IDS_COM_SK_OK")); - elm_object_part_content_set(popup_, "button2", ok_button_); - evas_object_smart_callback_add(ok_button_, "clicked", OkButtonHandlerForConfirm, this); - } - -#if defined(OS_TIZEN) - if (type_ == PROMPT || type_ == NAVIGATION) - eext_object_event_callback_add(popup_, EEXT_CALLBACK_BACK, CancelButtonHandlerForPrompt, this); - else if (type_ == ALERT) - eext_object_event_callback_add(popup_, EEXT_CALLBACK_BACK, CancelButtonHandlerForAlert, this); - else - eext_object_event_callback_add(popup_, EEXT_CALLBACK_BACK, CancelButtonHandlerForConfirm, this); -#endif - evas_object_event_callback_add(popup_, EVAS_CALLBACK_KEY_UP, KeyUpCallback, this); - evas_object_focus_set(popup_, true); - evas_object_show(popup_); - - int width = 0, height = 0; - const Ecore_Evas* ee = ecore_evas_ecore_evas_get(web_view_->GetEvas()); - ecore_evas_screen_geometry_get(ee, nullptr, nullptr, &width, &height); - evas_object_resize(popup_, width, height); - evas_object_move(popup_, 0, 0); - return true; -} - -bool JavaScriptModalDialogEfl::setLabelText(const char* message) { - if (!message) - return false; - - popupMessage_ = ("") + - std::string(elm_entry_utf8_to_markup(message)) + (""); - base::ReplaceChars(popupMessage_, "\n", "
", &popupMessage_); - - // Create label and put text to it. In case of resizing it will be reused in scroller. - Evas_Object* label = elm_label_add(popup_); - elm_label_line_wrap_set(label, ELM_WRAP_MIXED); - elm_object_text_set(label, popupMessage_.c_str()); - evas_object_show(label); - evas_object_event_callback_add(popup_, EVAS_CALLBACK_RESIZE, javascriptPopupResizeCallback, (void*)this); - elm_object_part_content_set(popup_, "default", label); - label_ = true; - - return true; -} - -void JavaScriptModalDialogEfl::javascriptPopupResizeCallback(void *data, Evas *e, Evas_Object *obj, void *event_info) { - if (!obj) - return; - - int popupHeight; - int width = 0, height = 0; -#if defined(USE_WAYLAND) -#if TIZEN_VERSION_AT_LEAST(5, 0, 0) - Ecore_Wl2_Display* wl2_display = ecore_wl2_connected_display_get(NULL); - ecore_wl2_display_screen_size_get(wl2_display, &width, &height); -#else - ecore_wl_screen_size_get(&width, &height); -#endif // TIZEN_VERSION_AT_LEAST(5, 0, 0) -#else - ecore_x_window_size_get(ecore_x_window_root_first_get(), &width, &height); -#endif - evas_object_geometry_get(obj, 0, 0, 0, &popupHeight); - - JavaScriptModalDialogEfl* popup = static_cast(data); - - if (!popup) - return; - - // Put label with displayed text to scroller in this case. - if (popupHeight > (height / 2)) { - Evas_Object* content = elm_object_part_content_get( - popup->popup_, "default"); - if (!content) - return; - - if (!popup->label_) - return; - - popup->label_ = false; - // Get label with text and remove it from content of popup. - Evas_Object* label = elm_object_part_content_unset( - popup->popup_, "default"); - - if (!label) - return; - - // Create scrollable layout. - Evas_Object* layout = elm_layout_add(popup->popup_); - - base::FilePath edj_dir; - base::FilePath javaScriptPopup_edj; - base::PathService::Get(PathsEfl::EDJE_RESOURCE_DIR, &edj_dir); - javaScriptPopup_edj = edj_dir.Append( - FILE_PATH_LITERAL("JavaScriptPopup.edj")); - - elm_layout_file_set( - layout, javaScriptPopup_edj.AsUTF8Unsafe().c_str(), "scroll"); - evas_object_show(layout); - evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); - - Evas_Object* scroller = elm_scroller_add(layout); - elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE); - elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO); - - evas_object_show(scroller); - elm_object_part_content_set(layout, "scroll_container", scroller); - - evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_object_content_set(scroller, label); - elm_object_part_content_set(popup->popup_, "default", layout); - } -} - -void JavaScriptModalDialogEfl::OkButtonHandlerForAlert(void *data, Evas_Object *obj, void *event_info) { - JavaScriptModalDialogEfl* dialog = (JavaScriptModalDialogEfl*)data; - - std::move(dialog->callback_).Run(true, std::u16string()); - evas_object_del(dialog->popup_); - dialog->close(); - - dialog->web_view_->SmartCallback().call(0); -} - -void JavaScriptModalDialogEfl::CancelButtonHandlerForAlert(void *data, Evas_Object *obj, void *event_info) { - JavaScriptModalDialogEfl* dialog = (JavaScriptModalDialogEfl*)data; - - std::move(dialog->callback_).Run(false, std::u16string()); - evas_object_del(dialog->popup_); - dialog->close(); - - dialog->web_view_->SmartCallback().call(0); -} - -void JavaScriptModalDialogEfl::OkButtonHandlerForConfirm(void *data, Evas_Object *obj, void *event_info) { - JavaScriptModalDialogEfl* dialog = (JavaScriptModalDialogEfl*)data; - - std::move(dialog->callback_).Run(true, std::u16string()); - evas_object_del(dialog->popup_); - dialog->close(); - - dialog->web_view_->SmartCallback().call(0); -} - -void JavaScriptModalDialogEfl::CancelButtonHandlerForConfirm(void *data, Evas_Object *obj, void *event_info) { - JavaScriptModalDialogEfl* dialog = (JavaScriptModalDialogEfl*)data; - - std::move(dialog->callback_).Run(false, std::u16string()); - evas_object_del(dialog->popup_); - dialog->close(); - - dialog->web_view_->SmartCallback().call(0); -} - -void JavaScriptModalDialogEfl::OkButtonHandlerForPrompt(void *data, Evas_Object *obj, void *event_info) { - JavaScriptModalDialogEfl* dialog = (JavaScriptModalDialogEfl*)data; - - std::string prompt_data; - if (dialog->prompt_entry_) - prompt_data = elm_entry_entry_get(dialog->prompt_entry_); - - std::move(dialog->callback_).Run(true, base::UTF8ToUTF16(prompt_data)); - evas_object_del(dialog->popup_); - dialog->close(); - - dialog->web_view_->SmartCallback().call(0); -} - -void JavaScriptModalDialogEfl::CancelButtonHandlerForPrompt(void *data, Evas_Object *obj, void *event_info) { - JavaScriptModalDialogEfl* dialog = (JavaScriptModalDialogEfl*)data; - - std::move(dialog->callback_).Run(false, std::u16string()); - evas_object_del(dialog->popup_); - dialog->close(); - - dialog->web_view_->SmartCallback().call(0); -} - -// General key up callback for all platforms designed to handle keyboard HW Back key -void JavaScriptModalDialogEfl::KeyUpCallback(void *data, Evas *e, Evas_Object *obj, void *event_info) { - Evas_Event_Key_Up* key_struct = static_cast(event_info); - if (!web_contents_utils::MapsToHWBackKey(key_struct->keyname)) - return; - - JavaScriptModalDialogEfl* dialog = static_cast(data); - - if (dialog->type_ == PROMPT || dialog->type_ == NAVIGATION) - CancelButtonHandlerForPrompt(data, obj, event_info); - else if (dialog->type_ == ALERT) - CancelButtonHandlerForAlert(data, obj, event_info); - else - CancelButtonHandlerForConfirm(data, obj, event_info); -} - -void JavaScriptModalDialogEfl::close() { - if(popup_) { - evas_object_del(popup_); - popup_ = 0; + content::JavaScriptDialogManager::DialogClosedCallback& callback) + : JavaScriptModalDialog(web_contents, + type, + message_text, + default_prompt_text, + std::move(callback), + nullptr) {} + +// static +JavaScriptModalDialogEfl* JavaScriptModalDialogEfl::CreateDialogAndShow( + content::WebContents* web_contents, + Type type, + const std::u16string& message_text, + const std::u16string& default_prompt_text, + content::JavaScriptDialogManager::DialogClosedCallback callback) { + auto* eweb_view = web_contents_utils::WebViewFromWebContents(web_contents); + auto* dialog = new JavaScriptModalDialogEfl(web_contents, type, message_text, + default_prompt_text, callback); + dialog->SetPromptEntryChangedCallback(PromptEntryChanged); + dialog->SetParentEvasObject(eweb_view->evas_object()); + + base::OnceCallback once_callback = + base::BindOnce(&PopupReplyWaitFinish, eweb_view); + dialog->SetPopupClosedCallback(once_callback); + if (!dialog->ShowJavaScriptDialog()) { + LOG(ERROR) << "Could not create javascript dialog."; + delete dialog; + dialog = nullptr; } - prompt_entry_ = 0; - imfContext = 0; -} - -void JavaScriptModalDialogEfl::SetPopupSize(int width, int height) { - if (!popup_) - return; - - evas_object_resize(popup_, width, height); - evas_object_move(popup_, 0, 0); -} - -JavaScriptModalDialogEfl::~JavaScriptModalDialogEfl() { - close(); + return dialog; } +/* LCOV_EXCL_STOP */ diff --git a/tizen_src/ewk/efl_integration/browser/javascript_modal_dialog_efl.h b/tizen_src/ewk/efl_integration/browser/javascript_modal_dialog_efl.h index 2f016b552d8c..701513e66f31 100644 --- a/tizen_src/ewk/efl_integration/browser/javascript_modal_dialog_efl.h +++ b/tizen_src/ewk/efl_integration/browser/javascript_modal_dialog_efl.h @@ -5,71 +5,33 @@ #ifndef JAVA_SCRIPT_MODAL_DIALOG_EFL_H_ #define JAVA_SCRIPT_MODAL_DIALOG_EFL_H_ -#include "content/public/browser/javascript_dialog_manager.h" #include -#include -#include -#include "base/callback.h" -#include "ecore_x_wayland_wrapper.h" +#include "content/browser/javascript_dialog/javascript_modal_dialog.h" -class EWebView; +// to avoid build errors +#include "ecore_x_wayland_wrapper.h" namespace content { class WebContentsDelegateEfl; } -class JavaScriptModalDialogEfl { +class JavaScriptModalDialogEfl : public content::JavaScriptModalDialog { public: - enum Type { - ALERT, - CONFIRM, - NAVIGATION, - PROMPT - }; - - virtual ~JavaScriptModalDialogEfl(); - static void OkButtonHandlerForAlert(void *data, Evas_Object *obj, void *event_info); - static void CancelButtonHandlerForAlert(void *data, Evas_Object *obj, void *event_info); - static void OkButtonHandlerForConfirm(void *data, Evas_Object *obj, void *event_info); - static void CancelButtonHandlerForConfirm(void *data, Evas_Object *obj, void *event_info); - static void OkButtonHandlerForPrompt(void *data, Evas_Object *obj, void *event_info); - static void CancelButtonHandlerForPrompt(void *data, Evas_Object *obj, void *event_info); - static void javascriptPopupResizeCallback(void *data, Evas *e, Evas_Object *obj, void *event_info); - static JavaScriptModalDialogEfl* CreateDialog( + static JavaScriptModalDialogEfl* CreateDialogAndShow( content::WebContents* web_contents, Type type, const std::u16string& message_text, const std::u16string& default_prompt_text, content::JavaScriptDialogManager::DialogClosedCallback callback); - static void KeyUpCallback(void *data, Evas *e, Evas_Object *obj, void *event_info); - bool ShowJavaScriptDialog(); - Evas_Object* popupAdd(); - bool setLabelText(const char* message); - void close(); - void SetPopupSize(int width, int height); - Evas_Object* popup_; - - private: JavaScriptModalDialogEfl( content::WebContents* web_contents, Type type, const std::u16string& message_text, const std::u16string& default_prompt_text, - content::JavaScriptDialogManager::DialogClosedCallback callback); - - content::JavaScriptDialogManager::DialogClosedCallback callback_; - bool label_; - Type type_; - std::u16string message_text_; - std::u16string default_prompt_text_; - EWebView* web_view_; - Evas_Object* prompt_entry_; - Evas_Object* ok_button_; - Evas_Object* cancel_button_; - std::string popupMessage_; - Ecore_IMF_Context* imfContext; + content::JavaScriptDialogManager::DialogClosedCallback& callback); + ~JavaScriptModalDialogEfl() = default; // LCOV_EXCL_LINE }; #endif /* JAVA_SCRIPT_MODAL_DIALOG_EFL_H_ */ 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 275d7fe19f24..d943f6e8e487 100644 --- a/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc +++ b/tizen_src/ewk/efl_integration/context_menu_controller_efl.cc @@ -528,7 +528,7 @@ void ContextMenuControllerEfl::OnDiskDownload( download::DownloadItem* item, download::DownloadInterruptReason interrupt_reason) { if (!item) { - save_fail_dialog_.reset(JavaScriptModalDialogEfl::CreateDialog( + save_fail_dialog_.reset(JavaScriptModalDialogEfl::CreateDialogAndShow( &web_contents_, JavaScriptModalDialogEfl::ALERT, base::UTF8ToUTF16( std::string(dgettext("WebKit", "IDS_WEBVIEW_POP_FAIL"))), @@ -554,7 +554,7 @@ void ContextMenuControllerEfl::OnDownloadUpdated( clipboard_download_items_.erase(download); } if (disk_download_items_.find(download) != disk_download_items_.end()) { - file_saved_dialog_.reset(JavaScriptModalDialogEfl::CreateDialog( + file_saved_dialog_.reset(JavaScriptModalDialogEfl::CreateDialogAndShow( &web_contents_, JavaScriptModalDialogEfl::ALERT, base::UTF8ToUTF16( std::string(dgettext("WebKit", "IDS_WEBVIEW_POP_SAVED"))), -- 2.34.1