function hostNinja() {
if [[ $SKIP_NINJA == 0 ]]; then
- TARGETS="chromium-efl efl_webprocess chromium-ewk efl_webview_app"
+ TARGETS="chromium-efl efl_webprocess chromium-ewk efl_webview_app ubrowser"
if [[ $BUILD_EWK_UNITTESTS == 1 ]]; then
TARGETS="$TARGETS ewk_unittests"
fi
]},
'includes': [
- 'unittest/ewk-tests.gypi'
+ 'unittest/ewk-tests.gypi',
+ 'ubrowser/ubrowser.gypi',
],
'targets': [{
--- /dev/null
+// Copyright 2014 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 "browser.h"
+
+#include <assert.h>
+#include <ewk_context.h>
+
+#include "logger.h"
+
+static std::string kHomePage = "http://www.google.com";
+static int kDefaultMobileWindowWidth = 360;
+static int kDefaultMobileWindowHeight = 640;
+static int kDefaultDesktopWindowWidth = 1600;
+static int kDefaultDesktopWindowHeight = 900;
+static int kToolboxWindowWidth = 640;
+static int kToolboxWindowHeight = 400;
+
+Window* Browser::selected_window_;
+
+Browser::Browser(bool desktop)
+ : toolbox_window_(NULL)
+ , window_list_(NULL)
+ , desktop_(desktop)
+ , inspector_started_(false) {
+
+ log_info("UI type: %s", desktop_ ? "desktop" : "mobile");
+ if (desktop_)
+ return;
+
+ toolbox_window_ = elm_win_util_standard_add(
+ "ubrowser-toolbox", "uBrowser ToolBox");
+
+ evas_object_resize(toolbox_window_,
+ kToolboxWindowWidth, kToolboxWindowHeight);
+ elm_win_autodel_set(toolbox_window_, EINA_TRUE);
+
+ Evas_Object* box = elm_box_add(toolbox_window_);
+ evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_win_resize_object_add(toolbox_window_, box);
+ evas_object_show(box);
+
+ window_list_ = elm_list_add(toolbox_window_);
+ evas_object_size_hint_weight_set(window_list_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(window_list_, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ elm_box_pack_end(box, window_list_);
+ evas_object_show(window_list_);
+
+ Evas_Object* bbox = elm_box_add(toolbox_window_);
+ elm_box_horizontal_set(bbox, EINA_TRUE);
+ evas_object_size_hint_weight_set(bbox, EVAS_HINT_EXPAND, 0);
+ evas_object_size_hint_align_set(bbox, EVAS_HINT_FILL, 0);
+ elm_box_pack_end(box, bbox);
+ evas_object_show(bbox);
+
+ AddButton(bbox, "New Window", "add", NULL, OnNewWindowRequest);
+
+ if (elm_win_wm_rotation_supported_get(toolbox_window_)) {
+ static const int rots[] = {0, 90, 270};
+ elm_win_wm_rotation_available_rotations_set(
+ toolbox_window_, rots, (sizeof(rots) / sizeof(int)));
+ }
+
+ evas_object_smart_callback_add(toolbox_window_, "delete,request",
+ &Browser::OnToolboxWindowDelRequest, this);
+
+ evas_object_show(toolbox_window_);
+}
+
+Browser::~Browser() {
+ assert(window_map_.empty());
+ Ewk_Context* ctx = ewk_context_default_get();
+ if (inspector_started_)
+ ewk_context_inspector_server_stop(ctx);
+}
+
+Window& Browser::CreateWindow() {
+ WindowMapData data;
+ memset(&data, 0, sizeof(data));
+
+ if (desktop_)
+ data.window = new Window(*this, kDefaultDesktopWindowWidth,
+ kDefaultDesktopWindowHeight);
+ else
+ data.window = new Window(*this, kDefaultMobileWindowWidth,
+ kDefaultMobileWindowHeight);
+
+ if (toolbox_window_) {
+ Evas_Object* pb = elm_progressbar_add(toolbox_window_);
+ elm_object_style_set(pb, "wheel");
+ elm_progressbar_pulse_set(pb, EINA_TRUE);
+ evas_object_size_hint_align_set(pb, EVAS_HINT_FILL, 0);
+ evas_object_size_hint_weight_set(pb, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ data.loading_indicator = pb;
+ data.list_elm = elm_list_item_append(window_list_,
+ "New Window", pb, CreateControlButtons(window_list_),
+ &Browser::OnWindowElementClicked, data.window);
+ }
+
+ window_map_[data.window->Id()] = data;
+
+ if (window_list_)
+ elm_list_go(window_list_);
+
+ log_trace("%s: %x", __PRETTY_FUNCTION__, data.window->Id());
+
+ return *data.window;
+}
+
+void Browser::ShowInspectorWindow() {
+ Ewk_Context* ctx = ewk_context_default_get();
+ unsigned int port = ewk_context_inspector_server_start(ctx, 0);
+ assert(port != 0);
+ char url[1024];
+ snprintf(url, sizeof(url), "http://localhost:%u/", port);
+ Window& win = CreateWindow();
+ win.EnableMouseEvents(true);
+ win.EnableTouchEvents(false);
+ win.LoadURL(url);
+ inspector_started_ = true;
+}
+
+void Browser::ActivateToolboxWindow() {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ assert(toolbox_window_);
+ elm_win_activate(toolbox_window_);
+}
+
+void Browser::OnWindowDestroyed(Window::IdType id) {
+ log_trace("%s: %x", __PRETTY_FUNCTION__, id);
+ assert(window_map_.find(id) != window_map_.end());
+ if (window_map_[id].list_elm)
+ elm_object_item_del(window_map_[id].list_elm);
+ if (window_map_[id].window == selected_window_)
+ selected_window_ = NULL;
+ if (window_list_)
+ elm_list_go(window_list_);
+ window_map_.erase(id);
+}
+
+void Browser::OnWindowTitleChanged(Window::IdType id, const char* title) {
+ if (toolbox_window_)
+ elm_object_item_part_text_set(window_map_[id].list_elm, "default", title);
+}
+
+void Browser::OnWindowLoadStarted(Window::IdType id) {
+ assert(window_map_.find(id) != window_map_.end());
+ elm_progressbar_pulse(window_map_[id].loading_indicator, EINA_TRUE);
+}
+
+void Browser::OnWindowLoadFinished(Window::IdType id) {
+ assert(window_map_.find(id) != window_map_.end());
+ elm_progressbar_pulse(window_map_[id].loading_indicator, EINA_FALSE);
+}
+
+void Browser::AddButton(Evas_Object* parent, const char* label,
+ const char* icon, const char* tooltip, Evas_Smart_Cb cb) {
+ Evas_Object *bt = elm_button_add(parent);
+ evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0.5);
+ if (label)
+ elm_object_text_set(bt, label);
+ if (tooltip)
+ elm_object_tooltip_text_set(bt, tooltip);
+ if (icon) {
+ Evas_Object* icon_elm = elm_icon_add(bt);
+ elm_icon_standard_set(icon_elm, icon);
+ elm_object_part_content_set(bt, "icon", icon_elm);
+ }
+ evas_object_smart_callback_add(bt, "clicked", cb, this);
+ elm_box_pack_end(parent, bt);
+ evas_object_show(bt);
+}
+
+Evas_Object* Browser::CreateControlButtons(Evas_Object* parent) {
+ Evas_Object* box = elm_box_add(parent);
+ elm_box_horizontal_set(box, EINA_TRUE);
+ evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ AddButton(box, NULL, "close", "Close", &Browser::OnWindowClose);
+ evas_object_show(box);
+ return box;
+}
+
+void Browser::OnToolboxWindowDelRequest(void* data, Evas_Object*, void*) {
+ Browser* thiz = static_cast<Browser*>(data);
+ WindowMap::iterator it = thiz->window_map_.begin();
+ while (!thiz->window_map_.empty())
+ thiz->window_map_.begin()->second.window->Close();
+ thiz->toolbox_window_ = NULL;
+}
+
+void Browser::OnWindowElementClicked(void *data, Evas_Object*, void*) {
+ selected_window_ = static_cast<Window*>(data);
+ selected_window_->Activate();
+}
+
+void Browser::OnWindowClose(void *data, Evas_Object*, void*) {
+ assert(selected_window_);
+ selected_window_->Close();
+ selected_window_ = NULL;
+}
+
+void Browser::OnNewWindowRequest(void *data, Evas_Object*, void*) {
+ Browser *thiz = static_cast<Browser*>(data);
+ Window& win = thiz->CreateWindow();
+ win.LoadURL(kHomePage);
+}
--- /dev/null
+// Copyright 2014 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 _BROWSER_H_
+#define _BROWSER_H_
+
+#include <map>
+#include <Ecore_Evas.h>
+#include <Elementary.h>
+
+#include "window.h"
+
+class Browser {
+ public:
+ Browser(bool desktop);
+ ~Browser();
+
+ Window& CreateWindow();
+ void ShowInspectorWindow();
+ void ActivateToolboxWindow();
+ bool IsDesktop() const { return desktop_; }
+
+ void OnWindowDestroyed(Window::IdType id);
+ void OnWindowURLChanged(Window::IdType id, const char*);
+ void OnWindowTitleChanged(Window::IdType id, const char*);
+ void OnWindowLoadStarted(Window::IdType id);
+ void OnWindowLoadFinished(Window::IdType id);
+
+ private:
+ void AddButton(Evas_Object*, const char*, const char*,
+ const char*, Evas_Smart_Cb);
+ Evas_Object* CreateControlButtons(Evas_Object*);
+
+ static void OnToolboxWindowDelRequest(void*, Evas_Object*, void*);
+ static void OnWindowElementClicked(void *data, Evas_Object*, void*);
+ static void OnWindowClose(void *data, Evas_Object*, void*);
+ static void OnNewWindowRequest(void *data, Evas_Object*, void*);
+
+ typedef struct _WindowMapData {
+ Window* window;
+ Elm_Object_Item* list_elm;
+ Evas_Object* loading_indicator;
+ } WindowMapData;
+
+ typedef std::map<Window::IdType, WindowMapData> WindowMap;
+
+ WindowMap window_map_;
+ static Window* selected_window_;
+
+ Evas_Object* toolbox_window_;
+ Evas_Object* window_list_;
+
+ bool desktop_;
+ bool inspector_started_;
+};
+
+#endif // _BROWSER_H_
--- /dev/null
+/*-
+ * Copyright (c) 2013 Peter Tworek
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "logger.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/* Format headers used by logger */
+#define INFO_FORMAT "\e[1;32m[INFO]\e[00m %s"
+#define INFO_FORMAT_NC "[INFO] %s"
+#define WARN_FORMAT "\e[1;33m[WARN]\e[00m %s"
+#define WARN_FORMAT_NC "[WARN] %s"
+#define ERROR_FORMAT "\e[1;31m[ERROR]\e[00m %s"
+#define ERROR_FORMAT_NC "[ERROR] %s"
+#define DEBUG_FORMAT "\e[1;36m[DEBUG]\e[00m %s"
+#define DEBUG_FORMAT_NC "[DEBUG] %s"
+#define TRACE_FORMAT "\e[1;36m[TRACE]\e[00m %s"
+#define TRACE_FORMAT_NC "[TRACE] %s"
+
+int logger_use_color = 1;
+int logger_show_trace = 0;
+
+static char *
+_make_format(MESSAGE_TYPE type, int add_newline, const char *fmt) {
+ char* msg_fmt = NULL;
+ const char* fmt_hdr = NULL;
+ int fmt_len = 0;
+
+ switch (type) {
+ case INFO:
+ fmt_hdr = logger_use_color ? INFO_FORMAT : INFO_FORMAT_NC;
+ break;
+ case WARNING:
+ fmt_hdr = logger_use_color ? WARN_FORMAT : WARN_FORMAT_NC;
+ break;
+ case ERROR:
+ fmt_hdr = logger_use_color ? ERROR_FORMAT : ERROR_FORMAT_NC;
+ break;
+ case DEBUG:
+ fmt_hdr = logger_use_color ? DEBUG_FORMAT : DEBUG_FORMAT_NC;
+ break;
+ case TRACE:
+ fmt_hdr = logger_use_color ? TRACE_FORMAT : TRACE_FORMAT_NC;
+ break;
+ default:
+ fmt_hdr = "[UNKNOWN] %s";
+ break;
+ }
+
+ fmt_len = strlen(fmt_hdr) + strlen(fmt);
+ msg_fmt = (char *) malloc(fmt_len);
+ if (msg_fmt == NULL) {
+ return NULL;
+ }
+ sprintf(msg_fmt, fmt_hdr, fmt);
+
+ if (add_newline) {
+ msg_fmt[fmt_len - 2] = '\n';
+ msg_fmt[fmt_len - 1] = '\0';
+ }
+
+ return msg_fmt;
+}
+
+void
+log_message(MESSAGE_TYPE type, int add_newline, const char *fmt, ...) {
+ char *msg_fmt = NULL;
+ va_list list;
+
+ if (!logger_show_trace && type == TRACE) {
+ return;
+ }
+
+ msg_fmt = _make_format(type, add_newline, fmt);
+
+ va_start(list, fmt);
+
+ if (msg_fmt == NULL) {
+ vfprintf(stderr, fmt, list);
+ }
+
+ if (type == ERROR) {
+ vfprintf(stderr, msg_fmt, list);
+ } else {
+ vfprintf(stdout, msg_fmt, list);
+ }
+ va_end(list);
+
+ free(msg_fmt);
+}
+
+void
+vlog_message(MESSAGE_TYPE type, int add_newline, const char *fmt, va_list vl) {
+ char *msg_fmt = NULL;
+
+ if (!logger_show_trace && type == TRACE) {
+ return;
+ }
+
+ msg_fmt = _make_format(type, add_newline, fmt);
+
+ if (msg_fmt == NULL) {
+ vfprintf(stderr, fmt, vl);
+ }
+
+ if (type == ERROR) {
+ vfprintf(stderr, msg_fmt, vl);
+ } else {
+ vfprintf(stdout, msg_fmt, vl);
+ }
+
+ free(msg_fmt);
+}
--- /dev/null
+/*-
+ * Copyright (c) 2013 Peter Tworek
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LOGGER_H
+#define LOGGER_H
+
+#include <stdarg.h>
+
+extern "C" {
+
+/* Supported message types.*/
+typedef enum {
+ INFO,
+ WARNING,
+ ERROR,
+ DEBUG,
+ TRACE,
+} MESSAGE_TYPE;
+
+extern int logger_use_color;
+extern int logger_show_trace;
+
+/**
+ * Main logging routine. Should not be used directly.
+ * Please use log_<type> macros.
+ */
+void
+log_message(MESSAGE_TYPE type, int add_newline, const char* format, ...);
+
+/**
+ * Logging function similar to log_message, but taking va_list as last argument.
+ * Useful when integration with external logging subsystems.
+ */
+void
+vlog_message(MESSAGE_TYPE type, int add_newline, const char *fmt, va_list vl);
+
+/* Logging macros. */
+#define log_info(format, args...) log_message(INFO, 1, format, ## args)
+#define log_warning(format, args...) log_message(WARNING, 1, format, ## args)
+#define log_error(format, args...) log_message(ERROR, 1, format, ## args)
+#define log_debug(format, args...) log_message(DEBUG, 1, format, ## args)
+#define log_trace(format, args...) log_message(TRACE, 1, format, ## args)
+
+#endif /* LOGGER_H */
+
+}
--- /dev/null
+// Copyright 2014 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 <ewk_main.h>
+#include <Elementary.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <vector>
+#if defined(OS_TIZEN)
+#include <app.h>
+#endif // OS_TIZEN
+
+#include "browser.h"
+#include "logger.h"
+
+extern int logger_show_trace;
+extern int logger_use_color;
+#if defined(OS_TIZEN)
+int desktop_ui = 0;
+#else
+int desktop_ui = 1;
+#endif
+
+typedef struct app_data {
+ std::vector<std::string> urls;
+ Browser* browser;
+ bool ewk_initialized;
+} AppData;
+
+void show_help_and_exit(const char* app_name) {
+ printf("Usage: %s [OPTION]... [URL]...\n\n", app_name);
+ printf("Available options:\n");
+ printf(" -v, --verbose Print verbose application logs\n");
+ printf(" -n, --no-color Don't use colors in application logs\n");
+ printf(" -d, --desktop Run application UI in desktop mode\n");
+ printf(" -m, --mobile Run application UI in mobile mode\n");
+ printf(" -h, --help Show this help message\n");
+ exit(0);
+}
+
+void parse_options(int argc, char** argv) {
+ int show_help = 0;
+ int c;
+
+ while (1) {
+ static struct option long_options[] = {
+ {"verbose", no_argument, &logger_show_trace, 1},
+ {"no-color", no_argument, &logger_use_color, 0},
+ {"desktop", no_argument, &desktop_ui, 1},
+ {"mobile", no_argument, &desktop_ui, 0},
+ {"help", no_argument, &show_help, 1},
+ {0, 0, 0, 0}
+ };
+
+ int option_index = 0;
+ c = getopt_long (argc, argv, "vndmh", long_options, &option_index);
+
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'v':
+ logger_show_trace = 1;
+ break;
+ case 'n':
+ logger_use_color = 0;
+ break;
+ case 'd':
+ desktop_ui = 1;
+ break;
+ case 'm':
+ desktop_ui = 0;
+ break;
+ case 'h':
+ show_help = 1;
+ break;
+ default:
+ // Ignore EFL or chromium specific options,
+ // ewk_set_arguments should handle them
+ continue;
+ }
+ }
+
+ if (show_help)
+ show_help_and_exit(argv[0]);
+}
+
+static bool app_create(void *data) {
+ AppData* app_data = static_cast<AppData*>(data);
+
+ if (!ewk_init())
+ return false;
+
+ elm_config_preferred_engine_set("opengl_x11");
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+
+ app_data->browser = new Browser(desktop_ui);
+ std::vector<std::string>::iterator it = app_data->urls.begin();
+ for (;it != app_data->urls.end(); ++it)
+ app_data->browser->CreateWindow().LoadURL(*it);
+ app_data->urls.clear();
+ app_data->ewk_initialized = true;
+ return true;
+}
+
+static void app_terminate(void* data) {
+ AppData* app_data = static_cast<AppData*>(data);
+ if (app_data->browser)
+ delete app_data->browser;
+ if (app_data->ewk_initialized)
+ ewk_shutdown();
+}
+
+#if defined(OS_TIZEN) && defined(TIZEN_APP)
+static void app_pause(void* data) {
+ log_debug("Tizen uBrowser pause");
+}
+
+static void app_resume(void* data) {
+ log_debug("Tizen uBrowser resume");
+}
+#endif // OS_TIZEN
+
+int main(int argc, char** argv) {
+ AppData data;
+ memset(&data, 0, sizeof(data));
+
+ for (int i = 1; i < argc; ++i)
+ if (argv[i][0] != '-')
+ data.urls.push_back(std::string(argv[i]));
+
+ if (data.urls.empty())
+ data.urls.push_back("http://www.google.com");
+
+ ewk_set_arguments(argc, argv);
+ elm_init(argc, argv);
+ parse_options(argc, argv);
+
+ int ret = 0;
+// Enable the section below once ubrowser is ready
+// to replace mini_browser. For the code below to work
+// proper manifest needs to be added to the rpm package
+#if defined(OS_TIZEN) && defined(TIZEN_APP)
+ app_event_callback_s ops;
+ memset(&ops, 0, sizeof(ops));
+ ops.create = app_create;
+ ops.terminate = app_terminate;
+ ops.pause = app_pause;
+ ops.resume = app_resume;
+
+ ret = app_efl_main(&argc, &argv, &ops, &data);
+#else
+ if (!app_create(&data))
+ return EXIT_FAILURE;
+
+ elm_run();
+
+ app_terminate(&data);
+#endif
+
+ return ret;
+}
--- /dev/null
+{
+ 'targets': [{
+ 'target_name': 'ubrowser',
+ 'type': 'executable',
+ 'dependencies': [
+ 'chromium-ewk',
+ ],
+ 'defines': [
+ # Uncomment once uBrowser replaces mini_browser and it's xml
+ # manifest is shipped in the rpm package
+ #'TIZEN_APP=1',
+ ],
+ 'include_dirs': [
+ '.',
+ '../efl_integration/public',
+ ],
+ 'sources': [
+ 'browser.cc',
+ 'browser.h',
+ 'logger.cc',
+ 'logger.h',
+ 'main.cc',
+ 'window.cc',
+ 'window.h',
+ 'window_ui.h',
+ 'window_ui.cc',
+ ],
+ 'copies': [{
+ 'destination': '<(PRODUCT_DIR)',
+ 'files': [ 'ubrowser.sh', ],
+ }],
+ 'conditions': [
+ ['building_for_tizen==1', {
+ 'cflags': [
+ '<!@(pkg-config --cflags capi-appfw-application)',
+ ],
+ 'link_settings': {
+ 'ldflags': [
+ '<!@(pkg-config --libs-only-L --libs-only-other capi-appfw-application)',
+ ],
+ 'libraries': [
+ '<!@(pkg-config --libs-only-l capi-appfw-application)',
+ ]
+ },
+ }],
+ ],
+ }],
+}
--- /dev/null
+#!/bin/sh
+
+SCRIPTDIR=$(cd $(dirname $0); pwd -P)
+OUT_DIR=$(echo $SCRIPTDIR | grep -Po "(?<=/)out\..*?(?=/)")
+BUILD_MODE=Release
+
+. $SCRIPTDIR/../../build/common.sh
+
+_LIBDIR=lib
+if [ "$(getHostArch)" == "x64" ]; then
+ _LIBDIR=lib64
+fi
+
+if echo $SCRIPTDIR | grep -q "Debug/efl_webview_app"; then
+ BUILD_MODE=Debug
+fi
+
+CHROMIUM_EFL_LIBDIR=$(cd $SCRIPTDIR/lib; pwd -P)
+CHROMIUM_EFL_DEPENDENCIES_LIBDIR=$(cd $SCRIPTDIR/../Dependencies/Root/$_LIBDIR; pwd -P)
+
+export LD_LIBRARY_PATH=$CHROMIUM_EFL_DEPENDENCIES_LIBDIR:$CHROMIUM_EFL_LIBDIR:${LD_LIBRARY_PATH}
+echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}"
+
+export ELM_ACCEL=hw
+
+exec ${SCRIPTDIR}/ubrowser "$@"
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns="http://tizen.org/ns/packages" package="chromium-efl" version="40.2214.0.47">
+ <label>uBrowser application for chromium-efl package</label>
+ <author href="www.samsung.com" email="p.tworek@samsung.com">SRPOL</author>
+ <description>Small reference browser application for chromium-efl port</description>
+ <ui-application appid="org.tizen.ubrowser" exec="/usr/bin/ubrowser" nodisplay="false" multiple="false" type="capp" taskmanage="true">
+ <icon>/opt/share/icons/ubrowser.png</icon>
+ <label>uBrowser</label>
+ <label xml:lang="en-us">uBrowser</label>
+ </ui-application>
+</manifest>
--- /dev/null
+// Copyright 2014 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 "window.h"
+
+#include <assert.h>
+#include <ewk_view.h>
+#include <ewk_console_message.h>
+#include <ewk_policy_decision.h>
+#include <Elementary.h>
+
+#include "browser.h"
+#include "logger.h"
+#include "window_ui.h"
+
+Window::Window(Browser& browser, int width, int height)
+ : browser_(browser) {
+ window_ = elm_win_util_standard_add(
+ "ubrowser", "uBrowser");
+ evas_object_resize(window_, width, height);
+ elm_win_autodel_set(window_, EINA_TRUE);
+
+ Evas_Object* conform = elm_conformant_add(window_);
+ evas_object_size_hint_weight_set(conform,
+ EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_win_resize_object_add(window_, conform);
+ evas_object_show(conform);
+
+ Evas_Object *box = elm_box_add(window_);
+ elm_object_content_set(conform, box);
+ evas_object_show(box);
+
+ ui_ = new WindowUI(*this, browser_);
+
+ elm_box_pack_end(box, ui_->GetURLBar());
+ evas_object_show(ui_->GetURLBar());
+
+ web_view_elm_host_ = elm_bg_add(window_);
+ evas_object_size_hint_align_set(
+ web_view_elm_host_, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(
+ web_view_elm_host_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_object_focus_allow_set(web_view_elm_host_, EINA_TRUE);
+ elm_box_pack_end(box, web_view_elm_host_);
+ evas_object_show(web_view_elm_host_);
+
+ elm_box_pack_end(box, ui_->GetNavBar());
+ evas_object_show(ui_->GetNavBar());
+
+ elm_object_focus_set(web_view_elm_host_, EINA_TRUE);
+ evas_object_smart_callback_add(web_view_elm_host_, "focused",
+ &Window::OnHostFocusedIn, this);
+ evas_object_smart_callback_add(web_view_elm_host_, "unfocused",
+ &Window::OnHostFocusedOut, this);
+
+ Evas* evas = evas_object_evas_get(window_);
+ web_view_ = ewk_view_add(evas);
+ evas_object_resize(web_view_, width, height);
+ elm_object_part_content_set(web_view_elm_host_, "overlay", web_view_);
+
+ evas_object_smart_callback_add(web_view_, "title,changed",
+ &Window::OnTitleChanged, this);
+ evas_object_smart_callback_add(web_view_, "url,changed",
+ &Window::OnURLChanged, this);
+ evas_object_smart_callback_add(web_view_, "load,progress,started",
+ &Window::OnLoadStarted, this);
+ evas_object_smart_callback_add(web_view_, "load,progress,finished",
+ &Window::OnLoadFinished, this);
+ evas_object_smart_callback_add(web_view_, "create,window",
+ &Window::OnNewWindowRequest, this);
+ evas_object_smart_callback_add(web_view_, "console,message",
+ &Window::OnConsoleMessage, NULL);
+ evas_object_smart_callback_add(web_view_, "policy,newwindow,decide",
+ &Window::OnNewWindowPolicyDecide, NULL);
+ evas_object_smart_callback_add(window_, "delete,request",
+ &Window::OnWindowDelRequest, this);
+ evas_object_smart_callback_add(window_, "back,forward,lsit,changed",
+ &Window::OnBackForwardListChanged, this);
+
+ if (elm_win_wm_rotation_supported_get(window_)) {
+ static const int rots[] = {0, 90, 270};
+ elm_win_wm_rotation_available_rotations_set(
+ window_, rots, (sizeof(rots) / sizeof(int)));
+ evas_object_smart_callback_add(window_, "wm,rotation,changed",
+ &Window::OnOrientationChanged, this);
+ }
+
+ evas_object_show(window_);
+}
+
+Window::~Window() {
+ assert(!window_);
+ delete ui_;
+}
+
+void Window::LoadURL(std::string url) {
+ const static std::string http = "http";
+ const static std::string about = "about:";
+ if (url.compare(0, 1, "/") == 0) {
+ url = "file://" + url;
+ } else if (url.compare(0, http.length(), http) != 0 &&
+ url.compare(0, about.length(), about) != 0) {
+ url = "http://" + url;
+ }
+ log_info("Loading URL: %s", url.c_str());
+ ewk_view_url_set(web_view_, url.c_str());
+ ui_->OnURLChanged(url.c_str());
+}
+
+const char* Window::GetURL() const {
+ return ewk_view_url_get(web_view_);
+}
+
+void Window::Activate() {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ elm_win_activate(window_);
+}
+
+void Window::Close() {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ evas_object_del(window_);
+ browser_.OnWindowDestroyed(Id());
+ window_ = NULL;
+}
+
+void Window::Show() {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ evas_object_show(window_);
+}
+
+void Window::Hide() {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ evas_object_hide(window_);
+}
+
+void Window::Back() {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ ewk_view_back(web_view_);
+}
+
+void Window::Forward() {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ ewk_view_forward(web_view_);
+}
+
+void Window::Reload() {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ ewk_view_reload(web_view_);
+}
+
+void Window::Stop() {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ ewk_view_stop(web_view_);
+}
+
+void Window::SetUserAgent(const char* new_ua) {
+ log_trace("%s: %s", __PRETTY_FUNCTION__, new_ua);
+ ewk_view_user_agent_set(web_view_, new_ua);
+}
+
+const char* Window::GetUserAgent() const {
+ return ewk_view_user_agent_get(web_view_);
+}
+
+void Window::FakeRotate() {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ int x, y, width, height;
+ evas_object_geometry_get(window_, &x, &y, &width, &height);
+ evas_object_move(window_, x, y);
+ evas_object_resize(window_, height, width);
+ if (width > height)
+ ewk_view_orientation_send(web_view_, 0);
+ else
+ ewk_view_orientation_send(web_view_, 90);
+}
+
+void Window::Resize(int width, int height) {
+ int x, y;
+ log_trace("%s: %dx%d", __PRETTY_FUNCTION__, width, height);
+ evas_object_geometry_get(window_, &x, &y, 0, 0);
+ evas_object_move(window_, x, y);
+ evas_object_resize(window_, width, height);
+ ewk_view_orientation_send(web_view_, 0);
+}
+
+void Window::EnableTouchEvents(bool enable) {
+ log_trace("%s: %d", __PRETTY_FUNCTION__, enable);
+ ewk_view_touch_events_enabled_set(web_view_, enable);
+}
+
+void Window::EnableMouseEvents(bool enable) {
+ log_trace("%s: %d", __PRETTY_FUNCTION__, enable);
+ ewk_view_mouse_events_enabled_set(web_view_, enable);
+}
+
+double Window::GetScale() const {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ return ewk_view_scale_get(web_view_);
+}
+
+void Window::SetScale(double scale) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ ewk_view_scale_set(web_view_, scale, 0, 0);
+}
+
+Window::IdType Window::Id() const {
+ return window_;
+}
+
+void Window::OnHostFocusedIn(void* data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ Window* thiz = static_cast<Window*>(data);
+ evas_object_focus_set(thiz->web_view_, EINA_TRUE);
+}
+
+void Window::OnHostFocusedOut(void* data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ Window* thiz = static_cast<Window*>(data);
+ evas_object_focus_set(thiz->web_view_, EINA_FALSE);
+}
+
+void Window::OnWindowDelRequest(void* data, Evas_Object*, void*) {
+ Window* thiz = static_cast<Window*>(data);
+ thiz->browser_.OnWindowDestroyed(thiz->Id());
+}
+
+void Window::OnNewWindowRequest(void *data, Evas_Object*, void* out_view) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ Window* thiz = static_cast<Window*>(data);
+ Window& new_window = thiz->browser_.CreateWindow();
+ *static_cast<Evas_Object**>(out_view) = new_window.web_view_;
+}
+
+void Window::OnTitleChanged(void *data, Evas_Object *obj, void *arg) {
+ Window* thiz = static_cast<Window*>(data);
+ elm_win_title_set(thiz->window_, static_cast<char*>(arg));
+ log_trace("%s: %s", __PRETTY_FUNCTION__, static_cast<char*>(arg));
+ thiz->browser_.OnWindowTitleChanged(thiz->Id(), static_cast<char *>(arg));
+}
+
+void Window::OnURLChanged(void *data, Evas_Object *obj, void *arg) {
+ Window* thiz = static_cast<Window*>(data);
+ log_trace("%s: %s", __PRETTY_FUNCTION__, static_cast<char*>(arg));
+ elm_win_title_set(thiz->window_, static_cast<char*>(arg));
+ thiz->ui_->OnURLChanged(static_cast<char*>(arg));
+}
+
+void Window::OnLoadStarted(void* data, Evas_Object*, void*) {
+ Window* thiz = static_cast<Window*>(data);
+ log_trace("%s", __PRETTY_FUNCTION__);
+ thiz->browser_.OnWindowLoadStarted(thiz->Id());
+ thiz->ui_->OnLoadingStarted();
+}
+
+void Window::OnLoadFinished(void* data, Evas_Object*, void*) {
+ Window* thiz = static_cast<Window*>(data);
+ log_trace("%s", __PRETTY_FUNCTION__);
+ thiz->browser_.OnWindowLoadFinished(thiz->Id());
+ thiz->ui_->OnLoadingFinished();
+}
+
+void Window::OnConsoleMessage(void*, Evas_Object*, void* event_info) {
+ Ewk_Console_Message* msg = static_cast<Ewk_Console_Message*>(event_info);
+
+ MESSAGE_TYPE type;
+ switch (ewk_console_message_level_get(msg)) {
+ case EWK_CONSOLE_MESSAGE_LEVEL_ERROR:
+ type = ERROR;
+ break;
+ case EWK_CONSOLE_MESSAGE_LEVEL_WARNING:
+ type = WARNING;
+ break;
+ case EWK_CONSOLE_MESSAGE_LEVEL_DEBUG:
+ type = DEBUG;
+ break;
+ default:
+ type = INFO;
+ }
+
+ log_message(type, true, "[JS Console] [%s:%d] %s",
+ ewk_console_message_source_get(msg),
+ ewk_console_message_line_get(msg),
+ ewk_console_message_text_get(msg));
+}
+
+void Window::OnOrientationChanged(void* data, Evas_Object *obj, void* event) {
+ Window* thiz = static_cast<Window*>(data);
+ log_trace("%s", __PRETTY_FUNCTION__);
+
+ int rotation = elm_win_rotation_get(thiz->window_);
+ // ewk_view_orientation_send expects angles: 0, 90, -90, 180.
+ if (rotation == 270)
+ rotation = -90;
+ ewk_view_orientation_send(thiz->web_view_, rotation);
+}
+
+void Window::OnNewWindowPolicyDecide(void*, Evas_Object*, void* policy) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ Ewk_Policy_Decision *policy_decision = static_cast<Ewk_Policy_Decision*>(policy);
+ const char* url = ewk_policy_decision_url_get(policy_decision);
+ log_info("Allowing new window for: %s", url);
+ ewk_policy_decision_use(policy_decision);
+}
+
+void Window::OnBackForwardListChanged(void* data, Evas_Object*, void* policy) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ Window* thiz = static_cast<Window*>(data);
+ thiz->ui_->EnableBackButton(ewk_view_back_possible(thiz->web_view_));
+ thiz->ui_->EnableForwardButton(ewk_view_forward_possible(thiz->web_view_));
+}
--- /dev/null
+// Copyright 2014 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 _WINDOW_H_
+#define _WINDOW_H_
+
+#include <string>
+#include <Ecore_Evas.h>
+
+class Browser;
+class WindowUI;
+
+class Window {
+ public:
+ typedef void* IdType;
+
+ Window(Browser&, int width, int height);
+ ~Window();
+
+ Evas_Object* GetEvasObject() const { return window_; };
+
+ void LoadURL(std::string url);
+ const char* GetURL() const;
+ void Activate();
+ void Close();
+ void Show();
+ void Hide();
+ void Back();
+ void Forward();
+ void Reload();
+ void Stop();
+ void SetUserAgent(const char* new_ua);
+ const char* GetUserAgent() const;
+ void FakeRotate();
+ void Resize(int width, int height);
+ void EnableTouchEvents(bool);
+ void EnableMouseEvents(bool);
+ double GetScale() const;
+ void SetScale(double);
+
+ IdType Id() const;
+
+ private:
+ static void OnHostFocusedIn(void* data, Evas_Object*, void*);
+ static void OnHostFocusedOut(void* data, Evas_Object*, void*);
+ static void OnWindowDelRequest(void* data, Evas_Object*, void*);
+ static void OnNewWindowRequest(void *data, Evas_Object*, void*);
+ static void OnTitleChanged(void*, Evas_Object*, void*);
+ static void OnURLChanged(void*, Evas_Object*, void*);
+ static void OnLoadStarted(void*, Evas_Object*, void*);
+ static void OnLoadFinished(void*, Evas_Object*, void*);
+ static void OnConsoleMessage(void*, Evas_Object*, void*);
+ static void OnOrientationChanged(void*, Evas_Object*, void*);
+ static void OnNewWindowPolicyDecide(void*, Evas_Object*, void*);
+ static void OnBackForwardListChanged(void*, Evas_Object*, void*);
+
+ Browser& browser_;
+ WindowUI* ui_;
+ Evas_Object* window_;
+ Evas_Object* web_view_;
+ Evas_Object* web_view_elm_host_;
+};
+
+#endif // _WINDOW_H_
--- /dev/null
+// Copyright 2014 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 "window_ui.h"
+
+#include <assert.h>
+#include <Elementary.h>
+#include <ewk_context.h>
+
+#include "browser.h"
+#include "logger.h"
+#include "window.h"
+
+namespace {
+static std::string kDefaultNewWindowURL = "http://www.google.com";
+static double kMinViewScale = 1;
+static double kMaxViewScale = 4;
+static double kViewScaleDelta = 0.1;
+}
+
+WindowUI::WindowUI(Window& window, Browser& browser)
+ : window_(window)
+ , browser_(browser)
+ , is_loading_(false) {
+ navbar_ = elm_box_add(window_.GetEvasObject());
+ elm_box_horizontal_set(navbar_, EINA_TRUE);
+ elm_box_homogeneous_set(navbar_, EINA_TRUE);
+ evas_object_size_hint_weight_set(navbar_, EVAS_HINT_EXPAND, 0.0f);
+ evas_object_size_hint_align_set(navbar_, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ AddButton(navbar_, "file", "New Window", &WindowUI::OnCreateWindow);
+ back_button_ = AddButton(navbar_, "arrow_left", "Back", &WindowUI::OnBack);
+ forward_button_ = AddButton(navbar_, "arrow_right", "Forward",
+ &WindowUI::OnForward);
+ stop_reload_button_ = AddButton(navbar_, "refresh", "Reload",
+ &WindowUI::OnStopOrReload);
+ AddButton(navbar_, "arrow_up", "More Actions",
+ &WindowUI::OnShowExtraActionsMenu);
+
+ urlbar_ = elm_box_add(window_.GetEvasObject());
+ elm_box_horizontal_set(urlbar_, EINA_TRUE);
+ evas_object_size_hint_weight_set(urlbar_, EVAS_HINT_EXPAND, 0.0f);
+ evas_object_size_hint_align_set(urlbar_, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ progress_bar_ = elm_progressbar_add(window_.GetEvasObject());
+ elm_object_style_set(progress_bar_, "wheel");
+ elm_progressbar_pulse_set(progress_bar_, EINA_TRUE);
+ elm_progressbar_pulse(progress_bar_, EINA_FALSE);
+ elm_box_pack_end(urlbar_, progress_bar_);
+ evas_object_show(progress_bar_);
+
+ url_entry_ = elm_entry_add(urlbar_);
+ elm_entry_single_line_set(url_entry_, EINA_TRUE);
+ elm_entry_scrollable_set(url_entry_, EINA_TRUE);
+ elm_entry_input_panel_layout_set(url_entry_, ELM_INPUT_PANEL_LAYOUT_URL);
+ evas_object_size_hint_weight_set(url_entry_, EVAS_HINT_EXPAND, 1.0f);
+ evas_object_size_hint_align_set(url_entry_, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_smart_callback_add(url_entry_, "activated", OnURLEntered, this);
+ elm_box_pack_end(urlbar_, url_entry_);
+ evas_object_show(url_entry_);
+
+ Evas_Object* separator = elm_separator_add(urlbar_);
+ elm_separator_horizontal_set(separator, EINA_TRUE);
+ elm_box_pack_end(urlbar_, separator);
+ evas_object_show(separator);
+
+ // FIXME: Uncomment once "back,forward,lsit,changed" EWK callback works
+ //EnableBackButton(false);
+ //EnableForwardButton(false);
+
+ extra_actions_menu_ = CreateExtraActionsMenu(window_.GetEvasObject());
+}
+
+void WindowUI::OnURLChanged(const char* url) {
+ log_trace("%s: %s", __PRETTY_FUNCTION__, url);
+ elm_object_text_set(url_entry_, url);
+}
+
+void WindowUI::OnLoadingStarted() {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ elm_progressbar_pulse(progress_bar_, EINA_TRUE);
+ Evas_Object* icon = elm_object_part_content_get(stop_reload_button_, "icon");
+ elm_icon_standard_set(icon, "close");
+ if (browser_.IsDesktop())
+ elm_object_text_set(stop_reload_button_, "Stop");
+ is_loading_ = true;
+}
+
+void WindowUI::OnLoadingFinished() {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ elm_progressbar_pulse(progress_bar_, EINA_FALSE);
+ Evas_Object* icon = elm_object_part_content_get(stop_reload_button_, "icon");
+ elm_icon_standard_set(icon, "refresh");
+ if (browser_.IsDesktop())
+ elm_object_text_set(stop_reload_button_, "Reload");
+ is_loading_ = false;
+}
+
+void WindowUI::EnableBackButton(bool enable) {
+ elm_object_disabled_set(back_button_, !enable);
+}
+
+void WindowUI::EnableForwardButton(bool enable) {
+ elm_object_disabled_set(forward_button_, !enable);
+}
+
+Evas_Object* WindowUI::AddButton(Evas_Object* parent,
+ const char* icon, const char* label, Evas_Smart_Cb cb) {
+ Evas_Object *bt = elm_button_add(parent);
+ evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0.5);
+ if (label && browser_.IsDesktop())
+ elm_object_text_set(bt, label);
+ if (icon) {
+ Evas_Object* icon_elm = elm_icon_add(bt);
+ elm_icon_standard_set(icon_elm, icon);
+ elm_object_part_content_set(bt, "icon", icon_elm);
+ }
+ evas_object_smart_callback_add(bt, "clicked", cb, this);
+ elm_box_pack_end(parent, bt);
+ evas_object_show(bt);
+
+ return bt;
+}
+
+Evas_Object* WindowUI::CreateExtraActionsMenu(Evas_Object* parent) {
+ Evas_Object* menu = elm_menu_add(parent);
+ elm_menu_item_add(menu, NULL, NULL,
+ "Override User Agent String", &WindowUI::OnUAOverride, this);
+
+ if (browser_.IsDesktop()) {
+ elm_menu_item_add(menu, NULL, NULL,
+ "Show Web Inspector", &WindowUI::OnInspectorShow, this);
+ elm_menu_item_add(menu, NULL, NULL, "Simulate screen rotation",
+ &WindowUI::OnRotate, this);
+
+ Elm_Object_Item* resize = elm_menu_item_add(menu, NULL, NULL, "Resize",
+ NULL, NULL);
+ elm_menu_item_add(menu, resize, NULL, "360x640",
+ &WindowUI::OnResize, new std::pair<const char*, WindowUI*>("360x640", this));
+ elm_menu_item_add(menu, resize, NULL, "800x600",
+ &WindowUI::OnResize, new std::pair<const char*, WindowUI*>("800x600", this));
+ elm_menu_item_add(menu, resize, NULL, "1024x768",
+ &WindowUI::OnResize, new std::pair<const char*, WindowUI*>("1024x768", this));
+ elm_menu_item_add(menu, resize, NULL, "1280x720",
+ &WindowUI::OnResize, new std::pair<const char*, WindowUI*>("1280x720", this));
+ }
+
+ Elm_Object_Item* input = elm_menu_item_add(menu, NULL, NULL, "Input event type",
+ NULL, NULL);
+ elm_menu_item_add(menu, input, NULL, "Mouse",
+ &WindowUI::OnSelectMouseInput, this);
+ elm_menu_item_add(menu, input, NULL, "Touch",
+ &WindowUI::OnSelectTouchInput, this);
+
+#if defined(OS_TIZEN)
+ // Techincally those functions change page scale factor, not zoom in/out.
+ // The code was borrowed from mini_browser app. On desktop support for
+ // page scale factor is disabled so don't show the options.
+ elm_menu_item_add(menu, NULL, NULL,
+ "Zoom in", &WindowUI::OnZoomIn, this);
+ elm_menu_item_add(menu, NULL, NULL,
+ "Zoom out", &WindowUI::OnZoomOut, this);
+#endif // OS_TIZEN
+
+ return menu;
+}
+
+namespace {
+static void _ClosePopup(void *data, Evas_Object*, void*) {
+ Evas_Object* popup = static_cast<Evas_Object*>(data);
+ evas_object_del(popup);
+}
+}
+
+void WindowUI::ShowTextEntryPopup(const char* title,
+ const char* initial_content, Evas_Smart_Cb cb) {
+ Evas_Object* popup = elm_popup_add(window_.GetEvasObject());
+ elm_object_part_text_set(popup, "title,text", title);
+ elm_popup_orient_set(popup, ELM_POPUP_ORIENT_CENTER);
+
+ log_trace("%s: (%s, %s)", __PRETTY_FUNCTION__, title, initial_content);
+
+ Evas_Object* entry = elm_entry_add(popup);
+ elm_entry_single_line_set(entry, EINA_TRUE);
+ elm_entry_scrollable_set(entry, EINA_TRUE);
+ elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_URL);
+ evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, 0.0f);
+ evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_smart_callback_add(entry, "activated", cb,
+ new std::pair<Evas_Object*, WindowUI*>(entry, this));
+
+ elm_object_part_content_set(popup, "default", entry);
+ if (initial_content) {
+ elm_object_text_set(entry, initial_content);
+ elm_entry_cursor_end_set(entry);
+ }
+
+ Evas_Object* btn = elm_button_add(popup);
+ elm_object_text_set(btn, "OK");
+ evas_object_smart_callback_add(btn, "clicked", cb,
+ new std::pair<Evas_Object*, WindowUI*>(entry, this));
+ elm_object_part_content_set(popup, "button1", btn);
+
+ btn = elm_button_add(popup);
+ elm_object_text_set(btn, "Cancel");
+ evas_object_smart_callback_add(btn, "clicked", _ClosePopup, popup);
+ elm_object_part_content_set(popup, "button2", btn);
+
+ evas_object_show(popup);
+}
+
+void WindowUI::OnCreateWindow(void *data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ WindowUI *thiz = static_cast<WindowUI*>(data);;
+ if (thiz->browser_.IsDesktop()) {
+ thiz->browser_.CreateWindow().LoadURL(kDefaultNewWindowURL);
+ } else {
+ thiz->browser_.ActivateToolboxWindow();
+ }
+}
+
+void WindowUI::OnBack(void *data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ static_cast<WindowUI*>(data)->window_.Back();
+}
+
+void WindowUI::OnForward(void *data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ static_cast<WindowUI*>(data)->window_.Forward();
+}
+
+void WindowUI::OnStopOrReload(void *data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ WindowUI* thiz = static_cast<WindowUI*>(data);
+ if (thiz->is_loading_)
+ thiz->window_.Stop();
+ else
+ thiz->window_.Reload();
+}
+
+void WindowUI::OnShowExtraActionsMenu(void *data, Evas_Object* obj, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ WindowUI* thiz = static_cast<WindowUI*>(data);
+ int x, y;
+ evas_object_geometry_get(obj, &x, &y, 0, 0);
+ elm_menu_move(thiz->extra_actions_menu_, x, y);
+ evas_object_show(thiz->extra_actions_menu_);
+}
+
+void WindowUI::OnURLEntered(void *data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ WindowUI* thiz = static_cast<WindowUI*>(data);
+ thiz->window_.LoadURL(elm_object_text_get(thiz->url_entry_));
+ elm_object_focus_set(thiz->url_entry_, EINA_FALSE);
+}
+
+void WindowUI::OnUAOverride(void* data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ WindowUI *thiz = static_cast<WindowUI*>(data);
+ const char* ua = thiz->window_.GetUserAgent();
+ thiz->ShowTextEntryPopup("User Agent Override", ua,
+ &WindowUI::OnUAOverrideEntered);
+}
+
+void WindowUI::OnUAOverrideEntered(void* data, Evas_Object*, void*) {
+ std::pair<Evas_Object*, WindowUI*>* p =
+ static_cast<std::pair<Evas_Object*, WindowUI*>*>(data);
+ p->second->window_.SetUserAgent(elm_object_text_get(p->first));
+ Evas_Object* content = elm_object_parent_widget_get(p->first);
+ Evas_Object* popup = elm_object_parent_widget_get(content);
+ popup = elm_object_parent_widget_get(popup);
+ evas_object_del(popup);
+ delete p;
+}
+
+void WindowUI::OnInspectorShow(void* data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ static_cast<WindowUI*>(data)->browser_.ShowInspectorWindow();
+}
+
+void WindowUI::OnRotate(void* data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ static_cast<WindowUI*>(data)->window_.FakeRotate();
+}
+
+void WindowUI::OnResize(void* data, Evas_Object*, void*) {
+ std::pair<const char*, WindowUI*>* pr =
+ static_cast<std::pair<const char*, WindowUI*>*>(data);
+ int width, height;
+ sscanf(pr->first, "%dx%d", &width, &height);
+ log_trace("%s %dx%d", __PRETTY_FUNCTION__, width, height);
+ pr->second->window_.Resize(width, height);
+}
+
+void WindowUI::OnSelectMouseInput(void* data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ WindowUI *thiz = static_cast<WindowUI*>(data);
+ thiz->window_.EnableTouchEvents(false);
+ thiz->window_.EnableMouseEvents(true);
+}
+
+void WindowUI::OnSelectTouchInput(void* data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ WindowUI *thiz = static_cast<WindowUI*>(data);
+ thiz->window_.EnableTouchEvents(true);
+ thiz->window_.EnableMouseEvents(false);
+}
+
+namespace {
+inline void _change_zoom(Window& win, double delta) {
+ double scale = win.GetScale();
+ if (scale >= kMinViewScale && scale < kMaxViewScale) {
+ scale += delta;
+ win.SetScale(scale);
+ }
+}
+}
+
+void WindowUI::OnZoomIn(void* data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ WindowUI *thiz = static_cast<WindowUI*>(data);
+ _change_zoom(thiz->window_, kViewScaleDelta);
+}
+
+void WindowUI::OnZoomOut(void* data, Evas_Object*, void*) {
+ log_trace("%s", __PRETTY_FUNCTION__);
+ WindowUI *thiz = static_cast<WindowUI*>(data);
+ _change_zoom(thiz->window_, -kViewScaleDelta);
+}
--- /dev/null
+// Copyright 2014 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 _WINDOW_UI_H_
+#define _WINDOW_UI_H_
+
+#include <Evas.h>
+
+class Window;
+class Browser;
+
+class WindowUI {
+ public:
+ WindowUI(Window&, Browser&);
+
+ Evas_Object* GetNavBar() const { return navbar_; }
+ Evas_Object* GetURLBar() const { return urlbar_; }
+
+ void OnURLChanged(const char* url);
+ void OnLoadingStarted();
+ void OnLoadingFinished();
+
+ void EnableBackButton(bool);
+ void EnableForwardButton(bool);
+
+ private:
+ Evas_Object* AddButton(Evas_Object*, const char*,
+ const char*, Evas_Smart_Cb);
+ Evas_Object* CreateExtraActionsMenu(Evas_Object*);
+ void ShowTextEntryPopup(const char* title,
+ const char* initial_content, Evas_Smart_Cb);
+
+ // Nav bar callbacks
+ static void OnCreateWindow(void *data, Evas_Object*, void*);
+ static void OnBack(void *data, Evas_Object*, void*);
+ static void OnForward(void *data, Evas_Object*, void*);
+ static void OnStopOrReload(void *data, Evas_Object*, void*);
+ static void OnShowExtraActionsMenu(void *data, Evas_Object*, void*);
+
+ // URL bar callbacks
+ static void OnURLEntered(void *data, Evas_Object*, void*);
+
+ // Extra actions callbacks
+ static void OnUAOverride(void* data, Evas_Object*, void*);
+ static void OnUAOverrideEntered(void* data, Evas_Object*, void*);
+ static void OnInspectorShow(void* data, Evas_Object*, void*);
+ static void OnRotate(void* data, Evas_Object*, void*);
+ static void OnResize(void* data, Evas_Object*, void*);
+ static void OnSelectMouseInput(void* data, Evas_Object*, void*);
+ static void OnSelectTouchInput(void* data, Evas_Object*, void*);
+ static void OnZoomIn(void* data, Evas_Object*, void*);
+ static void OnZoomOut(void* data, Evas_Object*, void*);
+
+ Window& window_;
+ Browser& browser_;
+ Evas_Object* navbar_;
+ Evas_Object* urlbar_;
+ Evas_Object* url_entry_;
+ Evas_Object* extra_actions_menu_;
+ Evas_Object* stop_reload_button_;
+ Evas_Object* progress_bar_;
+ Evas_Object* forward_button_;
+ Evas_Object* back_button_;
+
+ bool is_loading_;
+};
+
+#endif // _WINDOW_UI_H_
<filesystem path="/opt/share/icons/mini-browser.png" label="_" />
<filesystem path="/usr/bin/efl_webview_app" label="chromium-efl" exec_label="chromium-efl"/>
<filesystem path="/usr/bin/mini_browser" label="chromium-efl" exec_label="chromium-efl"/>
+ <filesystem path="/usr/bin/ubrowser" label="chromium-efl" exec_label="chromium-efl"/>
</assign>
</manifest>
%if 0%{?build_ewk_unittests}
ewk_unittests \
%endif
- chromium-efl efl_webprocess chromium-ewk efl_webview_app mini_browser
+ chromium-efl efl_webprocess chromium-ewk efl_webview_app mini_browser ubrowser
%if 0%{?_enable_unittests}
ninja %{_smp_mflags} -C"%{OUTPUT_FOLDER}" angle_unittests env_chromium_unittests cacheinvalidation_unittests \
install -m 0755 "%{OUTPUT_FOLDER}"/efl_webview_app "%{buildroot}"%{_bindir}
install -m 0755 "%{OUTPUT_FOLDER}"/mini_browser "%{buildroot}"%{_bindir}
+install -m 0755 "%{OUTPUT_FOLDER}"/ubrowser "%{buildroot}"%{_bindir}
install -m 0644 "%{OUTPUT_FOLDER}"/pkgconfig/*.pc "%{buildroot}"%{_libdir}/pkgconfig/
install -m 0644 ewk/efl_integration/public/*.h "%{buildroot}"%{_includedir}/chromium-ewk/
%{CHROMIUM_DATA_DIR}/themes/*.edj
%{_bindir}/efl_webview_app
%{_bindir}/mini_browser
+%{_bindir}/ubrowser
/opt/share/packages/chromium-efl.xml
/opt/share/icons/mini-browser.png
%{CHROMIUM_DATA_DIR}/locale/*