Logo Search packages:      
Sourcecode: kazehakase version File versions

kz-mozembed.cpp

// -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-

//
//  Copyright (C) 2002-2003 Hiroyuki Ikezoe
//  Copyright (C) 2003 Takuro Ashie
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2, or (at your option)
//  any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//

#include "kz-mozembed.h"

#include <string.h>
#include <math.h>
#include <gtkmozembed.h>
#include <gtkmozembed_internal.h>
#include <glib/gi18n.h>

#include "kazehakase.h"
#include "kz-window.h"
#include "kz-mozwrapper.h"
#include "kz-mozprogresslistener.h"
#include "kz-mozthumbnailcreator.h"
#include "kz-mozutils.h"
#include "gobject-utils.h"
#include "mozilla.h"
#include "mozilla-prefs.h"
#include "bookmarks/kz-bookmark.h"
#if USE_MIGEMO
#include "migemo.h"
#endif
#include "utils.h"
#include "estsearch.h"

#include <nsCOMPtr.h>
#include <nsIDOMDocument.h>
#include <nsIDocumentViewer.h>
#include <nsIWebBrowser.h>
#include <nsIDOMMouseEvent.h>
#include <dom/nsIDOMKeyEvent.h>
#include <dom/nsIDOMNSHTMLElement.h>  
#include <nsIDOMHTMLElement.h>  
#include <nsIDOMHTMLDocument.h>  
#include <nsIDOMHTMLTextAreaElement.h>  
#include <nsIDOMNamedNodeMap.h>
#include <nsIDOMDocumentRange.h>
#include <nsIDOMDocumentFragment.h>
#include <nsIDOMText.h>
#include <webbrowserpersist/nsIWebBrowserPersist.h>
#include <nsIWebBrowserFind.h>
#include <nsIFind.h>
#include <dom/nsIDOMNSDocument.h>
#include <dom/nsIDOMNSEvent.h>
#include <nsIDOMNodeList.h>
#include <nsIDOMWindow.h>
#include <nsISelection.h>
#include <nsIDOMRange.h>
#include <nsIDOMWindow.h>
#include <nsISelection.h>
#include <nsISHistory.h>
#include <nsIHistoryEntry.h>
#include <nsISHEntry.h>
#include <nsISHistoryInternal.h>
#include <nsIWebNavigation.h>
#include <nsCWebBrowserPersist.h>
#include <widget/nsIBaseWindow.h>
#include <nsIWebPageDescriptor.h>
#include <nsICommandManager.h>
#include <nsTime.h>
#include <nsICaret.h>
#include <nsRect.h>
#define MOZILLA_STRICT_API
#include <nsEmbedString.h>
#undef MOZILLA_STRICT_API
#include <nsIServiceManager.h>
#include <nsIInterfaceRequestorUtils.h>
#include <nsMemory.h>
#include <nsILocalFile.h>
#include <nsIDOM3Node.h>

#define N_LINKS 6

static gchar *nav_names[N_LINKS] =
{
 "NEXT", "PREV", "INDEX", "CONTENTS", "START", "ALTERNATE"
};

struct _KzMozEmbedPriv
{
      KzMozWrapper *wrapper;
      gint size_inited;
      gint cur_requests;
      gint total_requests;
      
      gboolean lock;

      /* for navigation link */
      gchar *nav_links[N_LINKS];

#ifdef USE_MIGEMO
      gchar *migemo_keyword;
#endif
      gchar *last_highlight;
      gchar *first_url;
};

static void kz_moz_embed_class_init    (KzMozEmbedClass *klass);
static void kz_moz_embed_init          (KzMozEmbed  *kzembed);
static void kz_moz_embed_destroy       (GtkObject   *object);
static void kz_moz_embed_finalize      (GObject     *object);
static void kz_moz_embed_realize       (GtkWidget   *widget);
static void kz_moz_embed_unrealize     (GtkWidget   *widget);
static void kz_moz_embed_size_allocate (GtkWidget   *widget,
                              GtkAllocation *allocation);
static void kz_moz_embed_destroy_brsr  (GtkMozEmbed *embed);
static void kz_moz_embed_link_message  (GtkMozEmbed *embed);
static void kz_moz_embed_js_status     (GtkMozEmbed *embed);
static void kz_moz_embed_title         (GtkMozEmbed *embed);
static void kz_moz_embed_location      (GtkMozEmbed *embed);
static void kz_moz_embed_net_start     (GtkMozEmbed *embed);
static void kz_moz_embed_new_window    (GtkMozEmbed *embed,
                              GtkMozEmbed **newembed,
                              guint        chromemask);
static gint kz_moz_embed_open_uri      (GtkMozEmbed *embed,
                              const char  *uri);
static void kz_moz_embed_size_to       (GtkMozEmbed *embed,
                              gint         width,
                              gint         height);
static void kz_moz_embed_visibility    (GtkMozEmbed *embed,
                              gboolean     visibility);
static void kz_moz_embed_net_stop      (GtkMozEmbed *embed);
static void kz_moz_embed_net_state_all (GtkMozEmbed *embed,
                              const char  *aURI,
                              gint         state,
                              guint        status);
#if 0
static void kz_moz_embed_security_change (GtkMozEmbed *embed,
                                gpointer     request,
                                guint        state);
#endif
static void kz_moz_embed_navigation_link_free(KzMozEmbed *kzembed);

static gint kz_moz_embed_dom_key_down        (GtkMozEmbed *embed, gpointer event);
static gint kz_moz_embed_dom_key_up          (GtkMozEmbed *embed, gpointer event);
static gint kz_moz_embed_dom_key_press       (GtkMozEmbed *embed, gpointer event);
static gint kz_moz_embed_dom_mouse_down      (GtkMozEmbed *embed, gpointer event);
static gint kz_moz_embed_dom_mouse_up        (GtkMozEmbed *embed, gpointer event);
static gint kz_moz_embed_dom_mouse_click     (GtkMozEmbed *embed, gpointer event);
static gint kz_moz_embed_dom_mouse_dbl_click (GtkMozEmbed *embed, gpointer event);
static gint kz_moz_embed_dom_mouse_over      (GtkMozEmbed *embed, gpointer event);

static glong     mozilla_set_event_context  (KzMozEmbed *kzembed,
                                   nsIDOMEventTarget *target,
                                   KzEmbedEvent *info);

static gchar      *mozilla_store_history_file (KzMozEmbed *kzembed);

static void         kz_moz_embed_load_url              (KzEmbed      *kzembed,
                                          const gchar  *url);
static void         kz_moz_embed_view_source           (KzEmbed      *kzembed,
                                          const gchar  *url);

static gboolean     kz_moz_embed_is_loading            (KzEmbed      *kzembed);

static const gchar *kz_moz_embed_get_title             (KzEmbed      *kzembed);
static const gchar *kz_moz_embed_get_location          (KzEmbed      *kzembed);
static gchar       *kz_moz_embed_ensure_title          (KzEmbed      *kzembed);
static gchar       *kz_moz_embed_get_link_message      (KzEmbed      *kzembed);

static gdouble      kz_moz_embed_get_progress          (KzEmbed      *kzembed);

static gboolean     kz_moz_embed_can_cut_selection     (KzEmbed      *kzembed);
static gboolean     kz_moz_embed_can_copy_selection    (KzEmbed      *kzembed);
static gboolean     kz_moz_embed_can_paste             (KzEmbed      *kzembed);
static void         kz_moz_embed_cut_selection         (KzEmbed      *kzembed);
static void         kz_moz_embed_copy_selection        (KzEmbed      *kzembed);
static void         kz_moz_embed_paste                 (KzEmbed      *kzembed);
static void         kz_moz_embed_select_all            (KzEmbed      *kzembed);

static gchar       *kz_moz_embed_get_selection_string  (KzEmbed      *kzembed);

static gboolean     kz_moz_embed_find                  (KzEmbed      *kzembed,
                                          const char   *keyword,
                                          gboolean      backward);
static gboolean     kz_moz_embed_incremental_search    (KzEmbed      *kzembed,
                                          const char   *keyword,
                                          gboolean      backward);

static gboolean     kz_moz_embed_selection_is_collapsed(KzEmbed      *kzembed);

static gboolean     kz_moz_embed_get_links             (KzEmbed      *kzembed,
                                          GList       **list,
                                          gboolean      selected_only);

static void         kz_moz_embed_copy_page             (KzEmbed      *kzembed,
                                          KzEmbed      *dkzembed);
static gboolean     kz_moz_embed_shistory_copy         (KzEmbed      *source,
                                          KzEmbed      *dest,
                                          gboolean      back_history,
                                          gboolean      forward_history,
                                          gboolean      set_current);
static gboolean     kz_moz_embed_shistory_get_pos      (KzEmbed      *kzembed,
                                          int          *pos,
                                          int          *count);
static void         kz_moz_embed_shistory_get_nth      (KzEmbed      *kzembed, 
                                          int           nth,
                                          gboolean      is_relative,
                                          char        **aUrl,
                                          char        **aTitle);

static void         kz_moz_embed_reload                (KzEmbed      *kzembed,
                                          gint32        flags);
static void         kz_moz_embed_stop_load             (KzEmbed      *kzembed);
static void         kz_moz_embed_go_back               (KzEmbed      *kzembed);
static void         kz_moz_embed_go_forward            (KzEmbed      *kzembed);

static gboolean     kz_moz_embed_can_go_back           (KzEmbed      *kzembed);
static gboolean     kz_moz_embed_can_go_forward        (KzEmbed      *kzembed);
static gboolean     kz_moz_embed_can_go_nav_link       (KzEmbed      *kzembed,
                                          KzEmbedNavLink link);
static void         kz_moz_embed_go_nav_link           (KzEmbed      *kzembed,
                                          KzEmbedNavLink link);
static void         kz_moz_embed_set_nav_link          (KzEmbed      *kzembed,
                                          const gchar  *name,
                                          const gchar  *link);
static void         kz_moz_embed_go_history_index      (KzEmbed      *kzembed,
                                          gint          index);

static void         kz_moz_embed_do_command            (KzEmbed      *kzembed,
                                          const char   *command);
static gboolean     kz_moz_embed_can_do_command        (KzEmbed      *kzembed,
                                          const char   *command);

static gboolean     kz_moz_embed_get_lock              (KzEmbed      *kzembed);
static void         kz_moz_embed_set_lock              (KzEmbed      *kzembed,
                                          gboolean      lock);

static gchar       *kz_moz_embed_get_body_text         (KzEmbed      *kzembed);
#if 0
static gchar       *kz_moz_embed_get_selection_source  (KzEmbed      *kzembed);
#endif
static void         kz_moz_embed_set_encoding          (KzEmbed      *kzembed,
                                          const char   *encoding);
static void         kz_moz_embed_get_encoding          (KzEmbed      *kzembed,
                                          char        **encoding,
                                          gboolean     *forced);
static void         kz_moz_embed_print                 (KzEmbed      *kzembed);
static void         kz_moz_embed_print_preview         (KzEmbed      *kzembed);
static GList       *kz_moz_embed_get_printer_list      (KzEmbed      *kzembed);
static void         kz_moz_embed_create_thumbnail      (KzEmbed      *kzembed);


static gboolean     kz_moz_embed_save_with_content     (KzEmbed      *kzembed,
                                          const char   *rawfilename);

static gboolean     kz_moz_embed_set_text_into_textarea(KzEmbed      *kzembed,
                                          gpointer      element,
                                          const gchar  *text);
static gchar       *kz_moz_embed_get_text_from_textarea(KzEmbed      *kzembed,
                                          gpointer      element);


static void         kz_moz_embed_zoom_set              (KzEmbed      *kzembed, 
                                          int           zoom, 
                                          gboolean      reflow);
static int          kz_moz_embed_zoom_get              (KzEmbed      *kzembed);
static void         kz_moz_embed_set_text_size         (KzEmbed      *kzembed, 
                                          int           zoom, 
                                          gboolean      reflow);
static int          kz_moz_embed_get_text_size         (KzEmbed      *kzembed);

static gchar       *kz_moz_embed_get_html_with_contents
                                    (KzEmbed      *kzembed,
                                     const gchar  *storedir);

static void      kz_moz_embed_set_history           (KzEmbed      *kzembed,
                                           KzBookmark   *history);
static void      kz_moz_embed_get_history           (KzEmbed      *kzembed,
                                           KzBookmark   *history);
static guint           kz_moz_embed_get_last_modified     (KzEmbed      *kzembed);


#if 0
static void         kz_moz_embed_set_edit_mode         (KzEmbed      *kzembed);
static void         kz_moz_embed_set_view_mode         (KzEmbed      *kzembed);
#endif
static void         kz_moz_embed_fine_scroll            (KzEmbed      *kzembed,
                                           int           horiz, 
                                           int           vert);
static void      kz_moz_embed_page_up           (KzEmbed      *kzembed);
static void      kz_moz_embed_page_down         (KzEmbed      *kzembed);

static gboolean        kz_moz_embed_get_allow_javascript    (KzEmbed      *kzembed);
static void      kz_moz_embed_set_allow_javascript    (KzEmbed      *kzembed,
                                           gboolean      allow);
static gboolean        kz_moz_embed_get_allow_images  (KzEmbed      *kzembed);
static void      kz_moz_embed_set_allow_images  (KzEmbed      *kzembed,
                                           gboolean      allow);

static GtkMozEmbedClass *parent_class = NULL;

static void
kz_moz_embed_iface_init (KzEmbedIFace *iface)
{
      iface->load_url               = kz_moz_embed_load_url;
      iface->view_source            = kz_moz_embed_view_source;
      iface->is_loading             = kz_moz_embed_is_loading;
      iface->get_title              = kz_moz_embed_get_title;
      iface->get_location           = kz_moz_embed_get_location;
      iface->ensure_title           = kz_moz_embed_ensure_title;
      iface->get_link_message       = kz_moz_embed_get_link_message;
      iface->get_progress           = kz_moz_embed_get_progress;
      iface->can_cut_selection      = kz_moz_embed_can_cut_selection;
      iface->can_copy_selection     = kz_moz_embed_can_copy_selection;
      iface->can_paste              = kz_moz_embed_can_paste;
      iface->cut_selection          = kz_moz_embed_cut_selection;
      iface->copy_selection         = kz_moz_embed_copy_selection;
      iface->paste                  = kz_moz_embed_paste;
      iface->select_all             = kz_moz_embed_select_all;
      iface->get_selection_string   = kz_moz_embed_get_selection_string;
      iface->find                   = kz_moz_embed_find;
      iface->incremental_search     = kz_moz_embed_incremental_search;
      iface->selection_is_collapsed = kz_moz_embed_selection_is_collapsed;
      iface->get_links              = kz_moz_embed_get_links;
      iface->copy_page              = kz_moz_embed_copy_page;
      iface->shistory_copy          = kz_moz_embed_shistory_copy;
      iface->shistory_get_pos       = kz_moz_embed_shistory_get_pos;
      iface->shistory_get_nth       = kz_moz_embed_shistory_get_nth;
      iface->reload                 = kz_moz_embed_reload;
      iface->stop_load              = kz_moz_embed_stop_load;
      iface->go_back                = kz_moz_embed_go_back;
      iface->go_forward             = kz_moz_embed_go_forward;
      iface->can_go_back            = kz_moz_embed_can_go_back;
      iface->can_go_forward         = kz_moz_embed_can_go_forward;
      iface->can_go_nav_link        = kz_moz_embed_can_go_nav_link;
      iface->go_nav_link            = kz_moz_embed_go_nav_link;
      iface->set_nav_link           = kz_moz_embed_set_nav_link;
      iface->go_history_index       = kz_moz_embed_go_history_index;
      iface->do_command             = kz_moz_embed_do_command;
      iface->can_do_command         = kz_moz_embed_can_do_command;
      iface->get_lock               = kz_moz_embed_get_lock;
      iface->set_lock               = kz_moz_embed_set_lock;
      iface->get_body_text          = kz_moz_embed_get_body_text;
#if 0
      iface->get_selection_source   = kz_moz_embed_get_selection_source;
#endif
      iface->set_encoding           = kz_moz_embed_set_encoding;
      iface->get_encoding           = kz_moz_embed_get_encoding;
      iface->print                  = kz_moz_embed_print;
      iface->print_preview          = kz_moz_embed_print_preview;
      iface->get_printer_list       = kz_moz_embed_get_printer_list;
      iface->create_thumbnail       = kz_moz_embed_create_thumbnail;
      iface->save_with_content      = kz_moz_embed_save_with_content;
      iface->set_text_into_textarea = kz_moz_embed_set_text_into_textarea;
      iface->get_text_from_textarea = kz_moz_embed_get_text_from_textarea;
      iface->zoom_set               = kz_moz_embed_zoom_set;
      iface->zoom_get               = kz_moz_embed_zoom_get;
      iface->set_text_size          = kz_moz_embed_set_text_size;
      iface->get_text_size          = kz_moz_embed_get_text_size;
      iface->get_html_with_contents = kz_moz_embed_get_html_with_contents;
      iface->set_history            = kz_moz_embed_set_history;
      iface->get_history            = kz_moz_embed_get_history;
      iface->get_last_modified      = kz_moz_embed_get_last_modified;
      iface->fine_scroll            = kz_moz_embed_fine_scroll;
      iface->page_up                = kz_moz_embed_page_up;
      iface->page_down              = kz_moz_embed_page_down;
      iface->get_allow_javascript   = kz_moz_embed_get_allow_javascript;
      iface->set_allow_javascript   = kz_moz_embed_set_allow_javascript;
      iface->get_allow_images       = kz_moz_embed_get_allow_images;
      iface->set_allow_images       = kz_moz_embed_set_allow_images;
#if 0
      iface->set_edit_mode          = set_edit_mode;
      iface->set_view_mode          = set_view_mode;
#endif
      iface->link_message        = NULL;
      iface->js_status           = NULL;
      iface->location            = NULL;
      iface->title               = NULL;
      iface->progress            = NULL;
      iface->net_start           = NULL;
      iface->net_stop            = NULL;
      iface->new_window          = NULL;
      iface->open_uri            = NULL;
      iface->size_to             = NULL;
      iface->dom_key_down        = NULL;
      iface->dom_key_press       = NULL;
      iface->dom_key_up          = NULL;
      iface->dom_mouse_down      = NULL;
      iface->dom_mouse_up        = NULL;
      iface->dom_mouse_click     = NULL;
      iface->dom_mouse_dbl_click = NULL;
      iface->dom_mouse_over      = NULL;
      iface->dom_mouse_out       = NULL;
      iface->security_change     = NULL;
      iface->status_change       = NULL;
}

KZ_OBJECT_GET_TYPE_IFACE(kz_moz_embed, "KzMozEmbed", KzMozEmbed,
                   kz_moz_embed_class_init, kz_moz_embed_init,
                   GTK_TYPE_MOZ_EMBED,
                   kz_moz_embed_iface_init, KZ_TYPE_EMBED)


static void
kz_moz_embed_class_init (KzMozEmbedClass *klass)
{
      GObjectClass *gobject_class;
      GtkObjectClass *object_class;
      GtkWidgetClass *widget_class;
      GtkMozEmbedClass *moz_embed_class;

      parent_class    = (GtkMozEmbedClass *) g_type_class_peek_parent (klass);

      gobject_class   = (GObjectClass *) klass;
      object_class    = (GtkObjectClass *) klass;
      widget_class    = (GtkWidgetClass *) klass;
      moz_embed_class = (GtkMozEmbedClass *) klass;

      // GObject
      gobject_class->finalize = kz_moz_embed_finalize;

      // GtkObject signals
      object_class->destroy = kz_moz_embed_destroy;
 
      // widget class
      widget_class->realize         = kz_moz_embed_realize;
      widget_class->unrealize       = kz_moz_embed_unrealize;
      widget_class->size_allocate   = kz_moz_embed_size_allocate;
 
      // GtkMozEmbedSignals
      moz_embed_class->net_state_all   = kz_moz_embed_net_state_all;
#if 0
      moz_embed_class->security_change     = kz_moz_embed_security_change;
      moz_embed_class->dom_mouse_over      = kz_moz_embed_dom_mouse_over;
      moz_embed_class->dom_mouse_out       = kz_moz_embed_dom_mouse_out;
      moz_embed_class->net_state           = kz_moz_embed_net_state;
      moz_embed_class->progress            = kz_moz_embed_progress;
      moz_embed_class->progress_all        = kz_moz_embed_progress_all;
#endif
      moz_embed_class->destroy_brsr        = kz_moz_embed_destroy_brsr;

      moz_embed_class->link_message        = kz_moz_embed_link_message;
      moz_embed_class->js_status           = kz_moz_embed_js_status;
      moz_embed_class->title               = kz_moz_embed_title;
      moz_embed_class->location            = kz_moz_embed_location;
      moz_embed_class->net_start           = kz_moz_embed_net_start;
      moz_embed_class->net_stop            = kz_moz_embed_net_stop;
      moz_embed_class->new_window          = kz_moz_embed_new_window;
      moz_embed_class->open_uri            = kz_moz_embed_open_uri;
      moz_embed_class->size_to             = kz_moz_embed_size_to;
      moz_embed_class->visibility          = kz_moz_embed_visibility;
      moz_embed_class->dom_key_press       = kz_moz_embed_dom_key_press;
      moz_embed_class->dom_key_down        = kz_moz_embed_dom_key_down;
      moz_embed_class->dom_key_up          = kz_moz_embed_dom_key_up;
      moz_embed_class->dom_mouse_down      = kz_moz_embed_dom_mouse_down;
      moz_embed_class->dom_mouse_up        = kz_moz_embed_dom_mouse_up;
      moz_embed_class->dom_mouse_click     = kz_moz_embed_dom_mouse_click;
      moz_embed_class->dom_mouse_dbl_click = kz_moz_embed_dom_mouse_dbl_click;
      moz_embed_class->dom_mouse_over      = kz_moz_embed_dom_mouse_over;

}

static void
kz_moz_embed_init (KzMozEmbed *kzembed)
{
      gint i;
      // widgets
      kzembed->popup_window          = NULL;

      // status
      kzembed->location              = NULL;
      kzembed->title                 = NULL;
      kzembed->load_started          = 0;
      kzembed->load_percent          = 0;
      kzembed->bytes_loaded          = 0;
      kzembed->max_bytes_loaded      = 0;
      kzembed->is_loading            = FALSE;
      kzembed->load_status_message   = NULL;

      // priv
      kzembed->priv = g_new0(KzMozEmbedPriv, 1);
      kzembed->priv->wrapper        = NULL;
      kzembed->priv->size_inited    = FALSE;
      kzembed->priv->total_requests = 0;
      kzembed->priv->cur_requests   = 0;
      
      for (i =0; i < N_LINKS; i++)
      {
            kzembed->priv->nav_links[i] = NULL;
      }
#ifdef USE_MIGEMO
      kzembed->priv->migemo_keyword = NULL;
#endif
      kzembed->priv->last_highlight = NULL;
      kzembed->priv->first_url      = NULL;
      kz_moz_embed_load_url(KZ_EMBED(kzembed), "about:blank");
}

GtkWidget *
kz_moz_embed_new (const gchar *url)
{
      KzMozEmbed *kzembed = KZ_MOZ_EMBED(g_object_new(KZ_TYPE_MOZ_EMBED, NULL));

#if 0
      //
      // set the chrome type so it's stored in the object
      //
      g_moz_embed_set_chrome_mask(GTK_MOZ_EMBED(kzembed->mozembed),
                            actualChromeMask);
#endif
      
      // To use the gesture in empty tab, 
      // After "about:balnk" was loaded, the first url start to load.  
      if (url)
            kzembed->priv->first_url = g_strdup(url);
      //kz_moz_embed_load_url(KZ_EMBED(kzembed), url);

      return GTK_WIDGET(kzembed);
}

static void
kz_moz_embed_destroy (GtkObject *object)
{
      KzMozEmbed *kzembed = KZ_MOZ_EMBED(object);

      if (kzembed->location)
            g_free(kzembed->location);
      kzembed->location = NULL;
      
      if (kzembed->title)
            g_free(kzembed->title);
      kzembed->title = NULL;

      if (kzembed->priv->first_url)
            g_free(kzembed->priv->first_url);
      kzembed->priv->first_url = NULL;

      if (GTK_OBJECT_CLASS(parent_class)->destroy)
            GTK_OBJECT_CLASS(parent_class)->destroy(object);
}


KZ_OBJECT_FINALIZE (kz_moz_embed, KzMozEmbed)


static void
kz_moz_embed_realize (GtkWidget *widget)
{
      gboolean java = TRUE;
      if (GTK_WIDGET_CLASS(parent_class)->realize)
            GTK_WIDGET_CLASS(parent_class)->realize(widget);

      KzMozEmbed *kzembed = KZ_MOZ_EMBED(widget);

      if (!kzembed->priv->wrapper)
      {
            kzembed->priv->wrapper = new KzMozWrapper();
            nsresult rv = kzembed->priv->wrapper->Init(kzembed);
            if (NS_FAILED(rv))
            {
                  g_error("KzMozEmbed: Faild to init KzMozWrapper!");
            }
            else
            {
            }
      }
      KZ_CONF_GET("Global", "use_javascript", java, BOOL);
      kz_moz_embed_set_allow_javascript(KZ_EMBED(kzembed), java);
}


static void
kz_moz_embed_unrealize (GtkWidget *widget)
{
      KzMozEmbed *kzembed = KZ_MOZ_EMBED(widget);

      kzembed->priv->size_inited = FALSE;

      if (kzembed->priv->wrapper)
      {
            kzembed->priv->wrapper->Destroy();
            delete kzembed->priv->wrapper;
            kzembed->priv->wrapper = NULL;
      }
      
      kz_moz_embed_navigation_link_free(kzembed);
      
      if (GTK_WIDGET_CLASS(parent_class)->unrealize)
            GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
}


static void
kz_moz_embed_navigation_link_free(KzMozEmbed *kzembed)
{     
      gint i;
      
      for (i =0; i < N_LINKS; i++)
      {
            if (kzembed->priv->nav_links[i])
            {
                  g_free(kzembed->priv->nav_links[i]);
                  kzembed->priv->nav_links[i] = NULL;
            }
      }
#ifdef USE_MIGEMO
      if (kzembed->priv->migemo_keyword)
            g_free(kzembed->priv->migemo_keyword);
      kzembed->priv->migemo_keyword =NULL;
#endif
      if (kzembed->priv->last_highlight)
            g_free(kzembed->priv->last_highlight);
      kzembed->priv->last_highlight = NULL;
}


static void
kz_moz_embed_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
{
      KzMozEmbed *kzembed = KZ_MOZ_EMBED(widget);

      g_return_if_fail(GTK_IS_WIDGET(widget));

      if (!GTK_WIDGET_REALIZED(widget)) return;

      if (!kzembed->priv->size_inited) 
      {
            // for preventing invalid scroll position 
            // when new tab background opens with anchor (html#xx)  
            nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(kzembed->priv->wrapper->mWebBrowser);
            baseWindow->SetPositionAndSize(0, 0,
                                     allocation->width,
                                     allocation->height,
                                     PR_FALSE);
      }
      if (!GTK_WIDGET_MAPPED(widget))
            return;
      
      if (GTK_WIDGET_CLASS(parent_class)->size_allocate)
            GTK_WIDGET_CLASS(parent_class)->size_allocate(widget, allocation);

      kzembed->priv->size_inited = TRUE;
}


static void
kz_moz_embed_load_url (KzEmbed *kzembed, const gchar *url)
{
      gchar *start_page = NULL;

      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);

      if (url && *url)
      {
            start_page = g_strdup(url);
      }
      else
      {
            start_page = g_strdup("about:blank");
      }

      if (!mozembed->priv->first_url &&
          kz_moz_embed_get_lock(kzembed))
      {
            GtkMozEmbed *newembed = NULL;
            g_signal_emit_by_name(kzembed, 
                              "new-window",
                              &newembed, 0);
            gtk_moz_embed_load_url(newembed, start_page);
            return;
      }
      else
            gtk_moz_embed_load_url(GTK_MOZ_EMBED(kzembed), start_page);
      
      if (mozembed->location)
            g_free(mozembed->location);
      mozembed->location = start_page;
}


static void
kz_moz_embed_view_source (KzEmbed *kzembed, const gchar *url)
{
      KzMozWrapper *wrapper = KZ_MOZ_EMBED(kzembed)->priv->wrapper;
      nsresult rv;

        nsCOMPtr<nsISupports> pageDescriptor;
        rv = wrapper->GetPageDescriptor(getter_AddRefs(pageDescriptor));
        if (!pageDescriptor || NS_FAILED(rv)) return;

        rv = wrapper->LoadDocument(pageDescriptor, 
                           nsIWebPageDescriptor::DISPLAY_AS_SOURCE);
      if (NS_FAILED(rv)) return;

      // set history explicitly
      nsCOMPtr<nsISHistory> sHistory;
      rv = wrapper->GetSHistory(getter_AddRefs(sHistory));
      if (NS_FAILED(rv) || !sHistory) return;

      nsCOMPtr<nsISHistoryInternal> sHistoryInternal;
      sHistoryInternal = do_QueryInterface(sHistory);

      gchar *uri = g_strdup_printf("view-source:%s", url);

      nsCOMPtr<nsISHEntry> entry;
      entry = do_CreateInstance(NS_SHENTRY_CONTRACTID);

      nsCOMPtr<nsIURI> aURI;
      NewURI(getter_AddRefs(aURI), uri);
      /* FIXME! set correct contentType */
      nsEmbedCString contentType;
      entry->Create(aURI,
                  nsnull,
                  nsnull,
                  nsnull,
                  nsnull,
                  nsnull,
                  nsEmbedCString(""));
      sHistoryInternal->AddEntry(entry, PR_TRUE);
      g_free(uri);
}


static gboolean
kz_moz_embed_is_loading (KzEmbed *kzembed)
{
      return KZ_IS_MOZ_EMBED(kzembed)
            ? KZ_MOZ_EMBED(kzembed)->is_loading
            : FALSE;
}


static const gchar *
kz_moz_embed_get_title (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), NULL);
      return KZ_MOZ_EMBED(kzembed)->title;
}

static gchar *
kz_moz_embed_ensure_title (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), NULL);

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);

      if (mozembed->title && *mozembed->title)
            return g_strdup(mozembed->title);

      if (mozembed->location && *mozembed->location)
      {
            if (kz_moz_embed_is_loading(kzembed))
            {
                  return g_strdup_printf(_("Loading %s ..."),
                                     mozembed->location);
            }
            else
            {
                  return g_strdup(mozembed->location);
            }
      }
      else
      {
            if (kz_moz_embed_is_loading(kzembed))
                  return g_strdup(_("Loading..."));
      }

      return g_strdup(_("No title"));
}

static gchar * 
kz_moz_embed_get_link_message (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_MOZ_EMBED(kzembed), NULL);

      gchar *message;

      message = gtk_moz_embed_get_link_message(GTK_MOZ_EMBED(kzembed));

      return message;
}


static gdouble
kz_moz_embed_get_progress (KzEmbed *kzembed)
{
      gdouble progress;

      g_return_val_if_fail(KZ_MOZ_EMBED(kzembed), 0.0);

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);

      if (mozembed->priv->total_requests <= 0 ||
          mozembed->priv->cur_requests <= 0)
      {
            return 0.0;
      }

      progress = (gdouble) mozembed->priv->cur_requests
            / (gdouble) mozembed->priv->total_requests;

      if (progress > 1.0)
            return 1.0;

      return progress;
}


static const gchar *
kz_moz_embed_get_location (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), NULL);

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);

      if (mozembed->location != NULL &&
          !strncmp(mozembed->location, "about:blank", 11))
      {
            return "";
      }

      return mozembed->location;
}

static void
kz_moz_embed_destroy_brsr (GtkMozEmbed *embed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(embed));

      gtk_widget_destroy(GTK_WIDGET(embed));
}


static void
kz_moz_embed_link_message (GtkMozEmbed *embed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(embed));

      g_signal_emit_by_name(embed, "kz-link-message");

      if (parent_class->link_message)
            parent_class->link_message(embed);
}

static void
kz_moz_embed_js_status (GtkMozEmbed *embed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(embed));

      g_signal_emit_by_name(embed, "kz-js-status");

      if (parent_class->js_status)
            parent_class->js_status(embed);
}

static void
kz_moz_embed_title (GtkMozEmbed *embed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(embed));

      KzMozEmbed *kzembed = KZ_MOZ_EMBED(embed);

      g_free(kzembed->title);

      kzembed->title = gtk_moz_embed_get_title(embed);

      g_signal_emit_by_name(embed, "kz-title");

      if (parent_class->title)
            parent_class->title(embed);
}

static void
kz_moz_embed_location (GtkMozEmbed *embed)
{
      KzMozEmbed *kzembed = KZ_MOZ_EMBED(embed);

      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      
      if (kzembed->priv->first_url)
      {
            gchar *tmp = g_strdup(kzembed->priv->first_url);
            g_free(kzembed->priv->first_url);
            kzembed->priv->first_url = NULL;

            kz_moz_embed_load_url(KZ_EMBED(kzembed),
                              tmp);
            g_free(tmp);

            return;
      }
      if (kzembed->location)
            g_free(kzembed->location);
      kzembed->location = gtk_moz_embed_get_location(embed);

      g_signal_emit_by_name(embed, "kz-location");

      if (parent_class->location)
            parent_class->location(embed);
}


static void
kz_moz_embed_net_start (GtkMozEmbed *embed)
{
      KzMozEmbed *kzembed = KZ_MOZ_EMBED(embed);

      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      if (kzembed->priv->first_url)
            return;

      kzembed->is_loading = TRUE;
      g_signal_emit_by_name(embed, "kz-net-start");

      if (parent_class->net_start)
            parent_class->net_start(embed);
}

static void
net_stop_proccess (KzMozEmbed *kzembed)
{
      gboolean create_thumbnail = FALSE, store_cache = TRUE;
      KZ_CONF_GET("Global", "create_thumbnail", create_thumbnail, BOOL);
      KZ_CONF_GET("History", "store_cache", store_cache, BOOL);

      gchar *cache = g_strconcat("file://", g_get_home_dir(),
                           HISTORY_DIR, NULL);
      const gchar *location = kz_moz_embed_get_location(KZ_EMBED(kzembed));
      if (location && 
          (g_str_has_prefix(location, "http:") || 
           g_str_has_prefix(location, "https:") || 
           g_str_has_prefix(location, "history-search:") || 
           g_str_has_prefix(location, "file:")) &&
          !g_str_has_prefix(location, cache))
      {
            //get the last modification time
            nsCOMPtr<nsIDOMDocument> domDoc;
            kzembed->priv->wrapper->GetMainDomDocument(getter_AddRefs(domDoc));
            nsCOMPtr<nsIDOMNSDocument> doc = do_QueryInterface(domDoc);
            nsEmbedString value;
            doc->GetLastModified(value);

            nsEmbedCString cValue;
            NS_UTF16ToCString(value,
                          NS_CSTRING_ENCODING_UTF8, cValue);
            nsTime lm (cValue.get(), PR_TRUE);
            GTime last_modified;
            LL_DIV(last_modified,
                   NS_STATIC_CAST(PRTime, lm), PR_USEC_PER_SEC);

            nsCOMPtr<nsIURI> inURI;
            nsEmbedCString sURI;
            nsresult rv;

            rv = kzembed->priv->wrapper->GetDocumentUrl(sURI);
            const gchar *uri = sURI.get();
                  rv = NewURI(getter_AddRefs(inURI), uri);

            if (create_thumbnail && 
                (!last_modified || (thumbnail_get_last_modified(uri) < last_modified)))
            {
                  kz_moz_embed_create_thumbnail(KZ_EMBED(kzembed));
            }
            
            if (store_cache && exists_estindex &&
                (!last_modified || (history_get_last_modified(uri) < last_modified)) &&
                !g_str_has_prefix(location, "history-search:"))
            {
                  gchar *filename;
                  filename = mozilla_store_history_file(kzembed);
                  if (filename)
                        g_idle_add(estsearch_update_index, filename);
            }
      }
      
      g_free(cache);
}

static void
kz_moz_embed_net_stop (GtkMozEmbed *embed)
{
      KzMozEmbed *kzembed = KZ_MOZ_EMBED(embed);

      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      kzembed->is_loading = FALSE;

      if (parent_class->net_stop)
            parent_class->net_stop(embed);

      /* First free previous link */
      kz_moz_embed_navigation_link_free(kzembed);

      net_stop_proccess(kzembed);

      g_signal_emit_by_name(embed, "kz-net-stop");
}

static void
kz_moz_embed_net_state_all (GtkMozEmbed *embed, const char *aURI,
                      gint state, guint status)
{
      KzMozEmbed *kzembed = KZ_MOZ_EMBED(embed);

      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      if (state & GTK_MOZ_EMBED_FLAG_IS_NETWORK)
      {
            kzembed->priv->total_requests = 0;
            kzembed->priv->cur_requests = 0;
#if 0
                if (state & GTK_MOZ_EMBED_FLAG_START)
                {
            }
                else if (state & EMBED_STATE_STOP)
                {
                        kzembed->priv->total_requests = 0;
                        kzembed->priv->cur_requests = 0;
            } 
#endif
      }
        if (state & GTK_MOZ_EMBED_FLAG_IS_REQUEST)
        {
                if (state & GTK_MOZ_EMBED_FLAG_START)
                        kzembed->priv->total_requests ++;
                else if (state & GTK_MOZ_EMBED_FLAG_STOP)
                        kzembed->priv->cur_requests ++;
        }

      g_signal_emit_by_name(embed, "kz-progress");

      if (parent_class->net_state_all)
            parent_class->net_state_all(embed, aURI, state, status);
}

static void 
cb_embed_destroy_browser (GtkMozEmbed *embed, GtkWidget *transient_window)
{
      gtk_widget_destroy(GTK_WIDGET(transient_window));
}

static void
kz_moz_embed_new_window (GtkMozEmbed *embed, GtkMozEmbed **newEmbed,
                   guint chromemask)
{
      if ((chromemask & GTK_MOZ_EMBED_FLAG_OPENASCHROME) != 0)
      {
            /* FIXME! this is ad hoc. */
            GtkWidget *newWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);

            gtk_window_set_transient_for(GTK_WINDOW(newWindow),
                                   GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(embed))));
            *newEmbed = GTK_MOZ_EMBED(kz_moz_embed_new(NULL));
            g_signal_connect(*newEmbed,"destroy",
                         G_CALLBACK(cb_embed_destroy_browser),
                         newWindow);
            gtk_container_add(GTK_CONTAINER(newWindow),
                          GTK_WIDGET(*newEmbed));
      }
      else
      {
            g_signal_emit_by_name(embed, "kz-new-window", newEmbed);
      }
}

static gint
kz_moz_embed_open_uri (GtkMozEmbed *embed, const char *uri)
{
      gint ret = FALSE;

      g_signal_emit_by_name(embed, "kz-open-uri", uri, &ret);

      if (parent_class->open_uri)
            ret = parent_class->open_uri(embed, uri);

#if 0
      if (!strncmp(uri, "mailto:", 7))
      {
            return TRUE;
      }
#endif

      return ret;
}

static void
kz_moz_embed_size_to (GtkMozEmbed *embed, gint width, gint height)
{
      gtk_widget_set_size_request(GTK_WIDGET(embed), width, height);
      gtk_widget_queue_resize(GTK_WIDGET(embed));

      g_signal_emit_by_name(embed, "kz-size-to", width, height);
}

static gint
kz_moz_embed_dom_key_down (GtkMozEmbed *embed, gpointer event)
{
      KzEmbedEventKey *kzevent;
      gint ret = FALSE;

      kz_moz_embed_get_key_event_info(KZ_MOZ_EMBED(embed), event, &kzevent);
      g_signal_emit_by_name(embed, "kz-dom-key-down",
                        kzevent, &ret);
      kz_embed_event_free((KzEmbedEvent *) kzevent);

      return ret;
}

static gint
kz_moz_embed_dom_key_up (GtkMozEmbed *embed, gpointer event)
{
      KzEmbedEventKey *kzevent;
      gint ret = FALSE;

      kz_moz_embed_get_key_event_info(KZ_MOZ_EMBED(embed), event, &kzevent);
      g_signal_emit_by_name(embed, "kz-dom-key-up",
                        kzevent, &ret);
      kz_embed_event_free((KzEmbedEvent *) kzevent);

      return ret;
}

static gint
kz_moz_embed_dom_key_press (GtkMozEmbed *embed, gpointer event)
{
      KzEmbedEventKey *kzevent;
      gint ret = FALSE;

      kz_moz_embed_get_key_event_info(KZ_MOZ_EMBED(embed), event, &kzevent);
      g_signal_emit_by_name(embed, "kz-dom-key-press",
                        kzevent, &ret);
      kz_embed_event_free((KzEmbedEvent *) kzevent);

      return ret;
}

static gint
kz_moz_embed_dom_mouse_down (GtkMozEmbed *embed, gpointer event)
{
      KzEmbedEventMouse *kzevent;
      gint ret = FALSE;

      kz_moz_embed_get_mouse_event_info(KZ_MOZ_EMBED(embed), event, &kzevent);

      g_signal_emit_by_name(embed, "kz-dom-mouse-down",
                        kzevent, &ret);
      kz_embed_event_free((KzEmbedEvent *) kzevent);

      return ret;
}

static
gint kz_moz_embed_dom_mouse_up (GtkMozEmbed *embed, gpointer event)
{
      KzEmbedEventMouse *kzevent;
      gint ret = FALSE;

      kz_moz_embed_get_mouse_event_info(KZ_MOZ_EMBED(embed), event, &kzevent);
      g_signal_emit_by_name(embed, "kz-dom-mouse-up",
                        kzevent, &ret);
      kz_embed_event_free((KzEmbedEvent *) kzevent);

      return ret;
}

static gint
kz_moz_embed_dom_mouse_click (GtkMozEmbed *embed, gpointer event)
{
      KzEmbedEventMouse *kzevent;
      gint ret = FALSE;

      kz_moz_embed_get_mouse_event_info(KZ_MOZ_EMBED(embed), event, &kzevent);
      g_signal_emit_by_name(embed, "kz-dom-mouse-click",
                        kzevent, &ret);
      kz_embed_event_free((KzEmbedEvent *) kzevent);

      return ret;
}

static gint
kz_moz_embed_dom_mouse_dbl_click (GtkMozEmbed *embed, gpointer event)
{
      KzEmbedEventMouse *kzevent;
      gint ret = FALSE;

      kz_moz_embed_get_mouse_event_info(KZ_MOZ_EMBED(embed), event, &kzevent);
      g_signal_emit_by_name(embed, "kz-dom-mouse-dbl-click",
                        kzevent, &ret);
      kz_embed_event_free((KzEmbedEvent *) kzevent);

      return ret;
}

static
gint kz_moz_embed_dom_mouse_over (GtkMozEmbed *embed, gpointer event)
{
      KzEmbedEventMouse *kzevent;
      gint ret = FALSE;

      kz_moz_embed_get_mouse_event_info(KZ_MOZ_EMBED(embed), event, &kzevent);
      g_signal_emit_by_name(embed, "kz-dom-mouse-over",
                        kzevent, &ret);
      kz_embed_event_free((KzEmbedEvent *) kzevent);

      return ret;
}

static void
kz_moz_embed_visibility (GtkMozEmbed *embed, gboolean visibility)
{
      GtkWidget *parent = NULL;

      parent = gtk_widget_get_parent(GTK_WIDGET(embed));
      g_return_if_fail(parent != NULL);
      
      if (visibility) 
      {
            gtk_widget_show(GTK_WIDGET(embed));
            gtk_widget_show(parent);
      }
      else
      {
            gtk_widget_hide(GTK_WIDGET(embed));
            gtk_widget_hide(parent);
      }
}

#if 0
static void
kz_moz_embed_security_change (GtkMozEmbed *embed,
                        gpointer request,
                        guint state)
{
      if (parent_class->security_change)
            parent_class->security_change(embed, request, state);
}
#endif

static gboolean
kz_moz_embed_can_cut_selection (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);

      if (!KZ_MOZ_EMBED(kzembed)->priv->wrapper) return TRUE;

      PRBool retval;
      nsresult rv = KZ_MOZ_EMBED(kzembed)->priv->wrapper->CanCutSelection(&retval);

      if (NS_FAILED(rv)) return FALSE;

      return retval;
}

static gboolean
kz_moz_embed_can_copy_selection (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);

      if (!KZ_MOZ_EMBED(kzembed)->priv->wrapper) return TRUE;

      PRBool retval;
      nsresult rv = KZ_MOZ_EMBED(kzembed)->priv->wrapper->CanCopySelection(&retval);

      if (NS_FAILED(rv)) return FALSE;

      return retval;
}

static gboolean
kz_moz_embed_can_paste (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);

      if (!KZ_MOZ_EMBED(kzembed)->priv->wrapper) return TRUE;

      PRBool retval;
      nsresult rv = KZ_MOZ_EMBED(kzembed)->priv->wrapper->CanPaste(&retval);

      if (NS_FAILED(rv)) return FALSE;

      return retval;
}

static void
kz_moz_embed_cut_selection (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      g_return_if_fail(KZ_MOZ_EMBED(kzembed)->priv->wrapper);

      KZ_MOZ_EMBED(kzembed)->priv->wrapper->CutSelection();
}

static void
kz_moz_embed_copy_selection (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      g_return_if_fail(KZ_MOZ_EMBED(kzembed)->priv->wrapper);

      KZ_MOZ_EMBED(kzembed)->priv->wrapper->CopySelection();
}

static void
kz_moz_embed_paste (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      g_return_if_fail(KZ_MOZ_EMBED(kzembed)->priv->wrapper);

      KZ_MOZ_EMBED(kzembed)->priv->wrapper->Paste();
}

static void
kz_moz_embed_select_all (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      g_return_if_fail(KZ_MOZ_EMBED(kzembed)->priv->wrapper);

      KzMozWrapper *wrapper = KZ_MOZ_EMBED(kzembed)->priv->wrapper;

      wrapper->SelectAll();
}

static gchar *
kz_moz_embed_get_selection_string(KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), NULL);

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      if (!mozembed->priv->wrapper) return NULL;

      nsresult rv;

      nsCOMPtr<nsISelection> selection;
      rv = mozembed->priv->wrapper->GetSelection(getter_AddRefs(selection));
      if (!selection) return NULL;

      PRUnichar *string;
      rv = selection->ToString(&string);
      
      nsEmbedCString str;
      NS_UTF16ToCString(nsEmbedString(string),
                    NS_CSTRING_ENCODING_UTF8, str);

      return g_strdup (str.get());
}

static gchar *
kz_moz_embed_get_html_with_contents (KzEmbed *kzembed, const gchar *storedir)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), NULL);

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      if (!mozembed->priv->wrapper) return NULL;

      nsresult rv;

      nsCOMPtr<nsISelection> selection;
      rv = mozembed->priv->wrapper->GetSelection(getter_AddRefs(selection));
      if (!selection) return NULL;

      nsEmbedString string;
      rv = mozembed->priv->wrapper->GetHtmlWithContents(selection, 
                                            storedir,
                                            string);
      if (NS_FAILED(rv)) return NULL;

      nsEmbedCString str;
      NS_UTF16ToCString(nsEmbedString(string),
                    NS_CSTRING_ENCODING_UTF8, str);
      return g_strdup(str.get());
}
#if 0
static gchar *
kz_moz_embed_get_selection_source(KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), NULL);

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      if (!mozembed->priv->wrapper) return NULL;

      nsresult rv;

      nsCOMPtr<nsISelection> selection;
      rv = mozembed->priv->wrapper->GetSelection(getter_AddRefs(selection));
      if (!selection) return NULL;

      nsAutoString string;
      rv = mozembed->priv->wrapper->GetSelectionSource(selection, PR_TRUE, string);
      if (NS_FAILED(rv)) return NULL;

      return g_strdup(NS_ConvertUCS2toUTF8(string).get());
}
#endif

#if USE_MIGEMO
static gboolean
kz_moz_embed_get_body_string(KzMozEmbed *mozembed, gchar **body_string,
                       gboolean backward, gboolean whole)
{
      nsEmbedString text;
      nsresult rv;

      if (whole)
            rv = mozembed->priv->wrapper->GetBodyString(text);
      else
            rv = mozembed->priv->wrapper->GetStringSelection(text, backward);
      if (NS_FAILED(rv))
            return FALSE;
      
      nsEmbedCString str;
      NS_UTF16ToCString(text,
                    NS_CSTRING_ENCODING_UTF8, str);
      *body_string = g_strdup(str.get());
      return TRUE;
}

static void
set_migemo_keyword(KzMozEmbed *mozembed, const char *keyword,
               gchar *body_string, gboolean backward)
{
      g_free(mozembed->priv->migemo_keyword);
      mozembed->priv->migemo_keyword =
            migemo_get_matched_text(body_string, keyword, backward);
}
#endif

static gboolean
kz_moz_embed_unhighlight_word (KzEmbed *kzembed, const char *word)
{
      if (!KZ_MOZ_EMBED(kzembed)->priv->wrapper) return FALSE;

      KzMozWrapper *wrapper = KZ_MOZ_EMBED(kzembed)->priv->wrapper;

      nsresult rv;
      nsCOMPtr<nsIFind> finder;
      finder = do_CreateInstance("@mozilla.org/embedcomp/rangefind;1", &rv);

      if (NS_FAILED(rv)) return FALSE;

      nsEmbedString string;
      NS_CStringToUTF16(nsEmbedCString(word),
                    NS_CSTRING_ENCODING_UTF8, string);
      const PRUnichar *u_word;
      NS_StringGetData(string, &u_word);
      
      nsCOMPtr<nsIDOMDocument> domDoc;
            rv = wrapper->GetMainDomDocument(getter_AddRefs(domDoc));
        if (NS_FAILED(rv) || !domDoc) return FALSE;
      
      nsCOMPtr<nsIDOMDocumentRange> docRange = do_QueryInterface(domDoc);
      if (!docRange) return FALSE;

      nsCOMPtr<nsIDOMRange> searchRange;
      nsCOMPtr<nsIDOMRange> startRange;
      nsCOMPtr<nsIDOMRange> endRange;
      rv = wrapper->SetHighlightRange(getter_AddRefs(searchRange),
                              getter_AddRefs(startRange),
                              getter_AddRefs(endRange));
      nsCOMPtr<nsIDOMRange> retRange;

      while (finder->Find(u_word, searchRange, startRange, endRange, getter_AddRefs(retRange)) == NS_OK)
      {
            if (!retRange) break;

            nsCOMPtr<nsIDOMNode> startContainer;
            retRange->GetStartContainer(getter_AddRefs(startContainer));

            nsCOMPtr<nsIDOMNode> elm;
            startContainer->GetParentNode(getter_AddRefs(elm));

            char *attr = NULL;
            wrapper->GetAttributeFromNode(elm, "id", &attr);
            if (elm && attr && !g_ascii_strcasecmp(attr, "kazehakase-search"))
            {
                  nsCOMPtr<nsIDOMDocumentFragment> flag;
                  nsCOMPtr<nsIDOMNode> next;
                  nsCOMPtr<nsIDOMNode> parent;

                  domDoc->CreateDocumentFragment(getter_AddRefs(flag));
                  nsCOMPtr<nsIDOMNode> flagNode;
                  flagNode = do_QueryInterface(flag);

                  elm->GetNextSibling(getter_AddRefs(next));
                  elm->GetParentNode(getter_AddRefs(parent));

                  nsCOMPtr<nsIDOMNode> child;
                  while (elm->GetFirstChild(getter_AddRefs(child)) == NS_OK)
                  {
                        if (!child) break;
                        nsCOMPtr<nsIDOMNode> newNode;
                        flagNode->AppendChild(child, getter_AddRefs(newNode));
                  }

                  docRange->CreateRange(getter_AddRefs(startRange));
                  startRange->SetStartAfter(elm);

                  nsCOMPtr<nsIDOMNode> tmp;
                  parent->RemoveChild(elm, getter_AddRefs(tmp));
                  parent->InsertBefore(flagNode, next, getter_AddRefs(tmp));
            }
            else
            {
                  nsCOMPtr<nsIDOMNode> endContainer;
                  retRange->GetEndContainer(getter_AddRefs(endContainer));
                  PRInt32 endOffset;
                  retRange->GetEndOffset(&endOffset);
                  docRange->CreateRange(getter_AddRefs(startRange));
                  startRange->SetStart(endContainer, endOffset);
            }
            startRange->Collapse(PR_TRUE);
      }

      return TRUE;
}


// this function is drawn upon 
//   toolkit/components/typeaheadfind/content/findBar.js in firefox-1.0+.
static gboolean
kz_moz_embed_highlight_word (KzEmbed *kzembed, const char *word)
{
      if (KZ_MOZ_EMBED(kzembed)->priv->last_highlight)
      {
            if (!strcmp(KZ_MOZ_EMBED(kzembed)->priv->last_highlight, word))
                  return TRUE;
            kz_moz_embed_unhighlight_word (kzembed, KZ_MOZ_EMBED(kzembed)->priv->last_highlight);
            g_free(KZ_MOZ_EMBED(kzembed)->priv->last_highlight);
      }
      
      KZ_MOZ_EMBED(kzembed)->priv->last_highlight = g_strdup(word);

      nsresult rv;
      nsCOMPtr<nsIFind> finder;
      finder = do_CreateInstance("@mozilla.org/embedcomp/rangefind;1", &rv);

      if (NS_FAILED(rv)) return FALSE;

      nsEmbedString string;
      NS_CStringToUTF16(nsEmbedCString(word),
                    NS_CSTRING_ENCODING_UTF8, string);
      const PRUnichar *u_word;
      NS_StringGetData(string, &u_word);
      
      nsCOMPtr<nsIDOMDocument> domDoc;
            rv = KZ_MOZ_EMBED(kzembed)->priv->wrapper->GetMainDomDocument(getter_AddRefs(domDoc));
        if (NS_FAILED(rv) || !domDoc) return FALSE;


      nsCOMPtr<nsIDOMRange> searchRange;
      nsCOMPtr<nsIDOMRange> startRange;
      nsCOMPtr<nsIDOMRange> endRange;
      rv = KZ_MOZ_EMBED(kzembed)->priv->wrapper->SetHighlightRange(getter_AddRefs(searchRange),
                                                     getter_AddRefs(startRange),
                                                     getter_AddRefs(endRange));

      const PRUnichar span[]          = { 's', 'p', 'a', 'n' ,'\0' };
      const PRUnichar style[]         = { 's', 't', 'y', 'l' ,'e', '\0' };
      const PRUnichar u_color[]       = { 's', 'p', 'a', 'n' ,'\0' };
      const PRUnichar id[]            = { 'i', 'd', '\0' };
      const PRUnichar sc[]            = { ';', '\0' };
      const PRUnichar bg_color[]      = { 'b', 'a', 'c', 'k' ,'g', 'r', 
                                  'o', 'u', 'n', 'd', '-', 'c',
                                  'o', 'l', 'o', 'r', ':', '\0' };
      const PRUnichar kazehakase_id[] = { 'k', 'a', 'z', 'e' ,'h', 'a', 
                                  'k', 'a', 's', 'e', '-', 's',
                                  'e', 'a', 'r', 'c', 'h', '\0' };

      nsEmbedCString cColor("#ffff00");
      nsEmbedString uColor;
      NS_CStringToUTF16(cColor, NS_CSTRING_ENCODING_UTF8, uColor);
      nsEmbedString color(bg_color);
      color += uColor;
      color += sc;
      nsCOMPtr<nsIDOMElement> baseElm;
      domDoc->CreateElement(nsEmbedString(span), getter_AddRefs(baseElm));
      baseElm->SetAttribute(nsEmbedString(style), color);
      baseElm->SetAttribute(nsEmbedString(id), nsEmbedString(kazehakase_id));
      nsCOMPtr<nsIDOMNode> baseNode = do_QueryInterface(baseElm);

      nsCOMPtr<nsIDOMRange> retRange;

      while (finder->Find(u_word, searchRange, startRange, endRange, getter_AddRefs(retRange)) == NS_OK)
      {
            if (!retRange) break;

            nsCOMPtr<nsIDOMNode> node;
            baseNode->CloneNode(PR_TRUE, getter_AddRefs(node));

            nsCOMPtr<nsIDOMNode> startContainer;
            retRange->GetStartContainer(getter_AddRefs(startContainer));

            PRInt32 startOffset, endOffset;
            retRange->GetStartOffset(&startOffset);
            retRange->GetEndOffset(&endOffset);

            nsCOMPtr<nsIDOMDocumentFragment> flag;
            retRange->ExtractContents(getter_AddRefs(flag));
            if (!flag) continue;

            nsCOMPtr<nsIDOMNode> flagNode;
            flagNode = do_QueryInterface(flag);

            nsCOMPtr<nsIDOMText> text;
            text = do_QueryInterface(startContainer);

            nsCOMPtr<nsIDOMText> before;
            text->SplitText(startOffset, getter_AddRefs(before));
            nsCOMPtr<nsIDOMNode> beforeNode;
            beforeNode = do_QueryInterface(before);
            
            nsCOMPtr<nsIDOMNode> parent;
            beforeNode->GetParentNode(getter_AddRefs(parent));

            nsCOMPtr<nsIDOMNode> newNode;
            node->AppendChild(flagNode, getter_AddRefs(newNode));
            nsCOMPtr<nsIDOMNode> newParent;
            parent->InsertBefore(node, beforeNode, getter_AddRefs(newParent));

            nsCOMPtr<nsIDOMDocument> doc;
            node->GetOwnerDocument(getter_AddRefs(doc));
            nsCOMPtr<nsIDOMDocumentRange> range;
            range = do_QueryInterface(doc);

            range->CreateRange(getter_AddRefs(startRange));

            nsCOMPtr<nsIDOMNodeList> list;
            node->GetChildNodes(getter_AddRefs(list));

            PRUint32 length;
            list->GetLength(&length);
            startRange->SetStart(node, length);
            startRange->SetEnd(node, length);
      }

      return TRUE;
}

  
static gboolean
kz_moz_embed_find (KzEmbed *kzembed, const char *keyword,
               gboolean backward)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);
      g_return_val_if_fail(keyword, FALSE);

      nsCOMPtr<nsIWebBrowser> web;
      gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(kzembed),
                              getter_AddRefs(web));
      if (!web) return FALSE;

      nsresult rv;
      nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(web));
#if USE_MIGEMO
      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      gboolean use_migemo;
      KZ_CONF_GET("Global", "use_migemo", use_migemo, BOOL);

      nsEmbedString str;
      if (use_migemo)
      {
            gchar *body_string;

            if (!kz_moz_embed_get_body_string(mozembed, &body_string,
                                      backward, FALSE))
                  goto START_SEARCH;
            set_migemo_keyword(mozembed, keyword, body_string, backward);

            if (!mozembed->priv->migemo_keyword)
            {
                  g_free(body_string);
                  if (!kz_moz_embed_get_body_string(mozembed,
                                            &body_string,
                                            backward,
                                            TRUE))
                        goto START_SEARCH;
                  set_migemo_keyword(mozembed, keyword,
                                 body_string, backward);
            }
            
            if (mozembed->priv->migemo_keyword)
            {
                  NS_CStringToUTF16(nsEmbedCString(mozembed->priv->migemo_keyword),
                                NS_CSTRING_ENCODING_UTF8, str);
            }
            else
            {
                  NS_CStringToUTF16(nsEmbedCString(keyword),
                                NS_CSTRING_ENCODING_UTF8, str);
            }
            g_free(body_string);
      }
      else
      {
            NS_CStringToUTF16(nsEmbedCString(keyword),
                          NS_CSTRING_ENCODING_UTF8, str);
      }
      finder->SetSearchString(str.get());
START_SEARCH:
#else 
      nsEmbedString str;
      NS_CStringToUTF16(nsEmbedCString(keyword),
                    NS_CSTRING_ENCODING_UTF8, str);
      finder->SetSearchString(str.get());
#endif
      finder->SetFindBackwards(backward);
      finder->SetWrapFind(TRUE);
      finder->SetEntireWord(TRUE);
      finder->SetSearchFrames(TRUE);
      finder->SetMatchCase(FALSE);
      PRBool did_find;
      rv = finder->FindNext(&did_find);

      return NS_SUCCEEDED(rv) && did_find ? TRUE : FALSE;
}

static gboolean
kz_moz_embed_incremental_search (KzEmbed *kzembed, const char *keyword,
                         gboolean backward)
{
      nsresult rv;
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);
      g_return_val_if_fail(keyword, FALSE);

      if (strlen(keyword) == 0)
            return FALSE;

      nsCOMPtr<nsIWebBrowser> web;
      gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(kzembed),
                              getter_AddRefs(web));
      if (!web) return FALSE;

      nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(web));
#if USE_MIGEMO
      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      gboolean use_migemo;
      KZ_CONF_GET("Global", "use_migemo", use_migemo, BOOL);

      nsCOMPtr<nsISelection> selection;
      rv = mozembed->priv->wrapper->GetSelection(getter_AddRefs(selection));
      if (!selection) return FALSE;

      selection->RemoveAllRanges();

      nsEmbedString str;
      if (use_migemo)
      {
            gchar *body_string;

            if (!kz_moz_embed_get_body_string(mozembed, &body_string,
                                      backward, TRUE))
                  goto START_SEARCH;
            set_migemo_keyword(mozembed, keyword, body_string, backward);

            if (mozembed->priv->migemo_keyword) 
            {
                  NS_CStringToUTF16(nsEmbedCString(mozembed->priv->migemo_keyword),
                                NS_CSTRING_ENCODING_UTF8, str);
            }
            else 
            {
                  NS_CStringToUTF16(nsEmbedCString(keyword),
                                NS_CSTRING_ENCODING_UTF8, str);
            }
            g_free(body_string);
      }
      else
      {
            NS_CStringToUTF16(nsEmbedCString(keyword),
                          NS_CSTRING_ENCODING_UTF8, str);
      }
      finder->SetSearchString(str.get());
START_SEARCH:
#else
      nsEmbedString str;
      NS_CStringToUTF16(nsEmbedCString(keyword),
                    NS_CSTRING_ENCODING_UTF8, str);
      finder->SetSearchString(str.get());
#endif
      finder->SetFindBackwards(backward);
      finder->SetWrapFind(TRUE);
      finder->SetEntireWord(TRUE);
      finder->SetSearchFrames(TRUE);
      finder->SetMatchCase(FALSE);
      PRBool did_find;
      rv = finder->FindNext(&did_find);

      // highlight search word
      
      gboolean use_highlight = FALSE;
      KZ_CONF_GET("Global", "use_highlight", use_highlight, BOOL);
      if (use_highlight)
      {
            if (NS_SUCCEEDED(rv))
            {
                  nsEmbedCString c_str;
                  NS_UTF16ToCString(str, NS_CSTRING_ENCODING_UTF8, c_str);
                  kz_moz_embed_highlight_word(kzembed, c_str.get());
            }
      }

      return NS_SUCCEEDED(rv) && did_find ? TRUE : FALSE;
}

static gboolean
kz_moz_embed_selection_is_collapsed (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), TRUE);

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      if (!mozembed->priv->wrapper) return TRUE;

      nsresult rv;

      nsCOMPtr<nsISelection> selection;
      rv = mozembed->priv->wrapper->GetSelection(getter_AddRefs(selection));
      if (!selection) return TRUE;

      PRBool collapsed;
      rv = selection->GetIsCollapsed(&collapsed);
      if (NS_FAILED(rv)) return TRUE;

      return collapsed;
}


static gboolean
kz_moz_embed_get_links (KzEmbed *kzembed, GList **list,
                  gboolean selected_only)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);
      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      g_return_val_if_fail(mozembed->priv->wrapper, FALSE);
      g_return_val_if_fail(list, FALSE);

      // get selection
      nsresult rv;
      nsCOMPtr<nsISelection> selection;
      rv = mozembed->priv->wrapper->GetSelection(getter_AddRefs(selection));
      if (NS_FAILED(rv)) return FALSE;

      // get all anchor nodes in the document.
      nsCOMPtr<nsIDOMDocument> mainDoc;
        rv = mozembed->priv->wrapper->GetMainDomDocument(getter_AddRefs(mainDoc));
        if (NS_FAILED(rv) || !mainDoc) return FALSE;

        // get main DOMWindow
      nsCOMPtr<nsIDOMWindow> mainDOMWindow;
      rv = mozembed->priv->wrapper->GetDOMWindow(getter_AddRefs(mainDOMWindow));
      if (NS_FAILED(rv)) return FALSE;

      rv = mozembed->priv->wrapper->GetLinksFromWindow(mainDOMWindow,
                                           list,
                                           selection,
                                           selected_only);

      return NS_FAILED(rv) ? FALSE : TRUE;
}


glong
kz_moz_embed_get_key_event_info(KzMozEmbed *kzembed, gpointer event,
                        KzEmbedEventKey **info_ret)
{
      KzEmbedEventKey *info;
      info = (KzEmbedEventKey *) kz_embed_event_new(KZ_EMBED_EVENT_KEY);
      *info_ret = info;

      nsresult result;

      nsIDOMKeyEvent *aKeyEvent = (nsIDOMKeyEvent*) event;

      nsCOMPtr<nsIDOMEventTarget> OriginalTarget;

      nsCOMPtr<nsIDOMNSEvent> aEvent = do_QueryInterface(aKeyEvent);
      if (!aEvent) return KZ_CONTEXT_NONE;

      PRUint32 code;
      aKeyEvent->GetKeyCode(&code);
      code = info->key;

      aKeyEvent->GetCharCode(&code);
      code = info->char_code;

      PRBool mod_key;
      info->modifier = 0;
      aKeyEvent->GetAltKey(&mod_key);
        if (mod_key) info->modifier |= KZ_ALT_KEY;

      aKeyEvent->GetShiftKey(&mod_key);
        if (mod_key) info->modifier |= KZ_SHIFT_KEY;

      aKeyEvent->GetMetaKey(&mod_key);
        if (mod_key) info->modifier |= KZ_META_KEY;

      aKeyEvent->GetCtrlKey(&mod_key);
        if (mod_key) info->modifier |= KZ_CTRL_KEY;

      result = aEvent->GetOriginalTarget(getter_AddRefs(OriginalTarget));

      if (NS_FAILED(result) || !OriginalTarget) return KZ_CONTEXT_NONE;

      nsCOMPtr<nsIDOMNode> OriginalNode = do_QueryInterface(OriginalTarget);
      if (!OriginalNode) return KZ_CONTEXT_NONE;

      nsEmbedString nodename;
      OriginalNode->GetNodeName(nodename);

      nsEmbedCString cNodename;
      NS_UTF16ToCString(nodename, NS_CSTRING_ENCODING_UTF8, cNodename);

      if (!g_ascii_strcasecmp(cNodename.get(), "xul:thumb") ||
          !g_ascii_strcasecmp(cNodename.get(), "xul:slider"))
      {
                  return KZ_CONTEXT_NONE;
      }

      nsCOMPtr<nsIDOMEventTarget> target;
      result = aKeyEvent->GetTarget(getter_AddRefs(target));
      if (NS_FAILED(result) || !target) return KZ_CONTEXT_NONE;

      return mozilla_set_event_context(kzembed, target, (KzEmbedEvent *) info);
}


glong
kz_moz_embed_get_mouse_event_info(KzMozEmbed *kzembed, gpointer event,
                          KzEmbedEventMouse **info_ret)
{
      KzEmbedEventMouse *info;
      info = (KzEmbedEventMouse *) kz_embed_event_new(KZ_EMBED_EVENT_MOUSE);
      *info_ret = info;

      nsresult result;

      nsIDOMMouseEvent *aMouseEvent = (nsIDOMMouseEvent*)event;

      nsCOMPtr<nsIDOMEventTarget> OriginalTarget;

      nsCOMPtr<nsIDOMNSEvent> aEvent = do_QueryInterface(aMouseEvent);
      if (!aEvent) return KZ_CONTEXT_NONE;

      PRUint16 button;
      aMouseEvent->GetButton(&button);
      info->button = button;

      PRBool mod_key;
      info->modifier = 0;
      aMouseEvent->GetAltKey(&mod_key);
        if (mod_key) info->modifier |= KZ_ALT_KEY;

      aMouseEvent->GetShiftKey(&mod_key);
        if (mod_key) info->modifier |= KZ_SHIFT_KEY;

      aMouseEvent->GetMetaKey(&mod_key);
        if (mod_key) info->modifier |= KZ_META_KEY;

      aMouseEvent->GetCtrlKey(&mod_key);
        if (mod_key) info->modifier |= KZ_CTRL_KEY;

      PRInt32 pos;
      aMouseEvent->GetClientX(&pos);
      info->x = pos;
      aMouseEvent->GetClientY(&pos);
      info->y = pos;

      result = aEvent->GetOriginalTarget(getter_AddRefs(OriginalTarget));

      if (NS_FAILED(result) || !OriginalTarget) return KZ_CONTEXT_NONE;

      nsCOMPtr<nsIDOMNode> OriginalNode = do_QueryInterface(OriginalTarget);
      if (!OriginalNode) return KZ_CONTEXT_NONE;

      nsEmbedString nodename;
      OriginalNode->GetNodeName(nodename);

      nsEmbedCString cNodename;
      NS_UTF16ToCString(nodename, NS_CSTRING_ENCODING_UTF8, cNodename);

      if (!g_ascii_strcasecmp(cNodename.get(), "xul:thumb") ||
          !g_ascii_strcasecmp(cNodename.get(), "xul:slider"))
      {
                  return KZ_CONTEXT_NONE;
      }

      nsCOMPtr<nsIDOMEventTarget> target;
      result = aMouseEvent->GetTarget(getter_AddRefs(target));
      if (NS_FAILED(result) || !target) return KZ_CONTEXT_NONE;

      return mozilla_set_event_context(kzembed, target, (KzEmbedEvent *) info);
}


static glong
mozilla_set_event_context (KzMozEmbed *kzembed,
                     nsIDOMEventTarget *target,
                     KzEmbedEvent *info)
{
      nsresult result;
      KzMozWrapper *wrapper = kzembed->priv->wrapper;

      g_return_val_if_fail(kzembed->priv->wrapper, KZ_CONTEXT_NONE);

      nsCOMPtr<nsIDOMNode> node = do_QueryInterface(target);
      if (!node) return KZ_CONTEXT_NONE;

      nsCOMPtr<nsIDOMDocument> domDoc;
      result = node->GetOwnerDocument(getter_AddRefs(domDoc));
      if (!NS_SUCCEEDED (result) || !domDoc) return KZ_CONTEXT_NONE;

      nsCOMPtr<nsIDOM3Node> domnode = do_QueryInterface(domDoc);
      if(!domnode) return KZ_CONTEXT_NONE;

      nsCOMPtr<nsIDOMNSDocument> nsDoc = do_QueryInterface(domDoc);
      if (!nsDoc) return KZ_CONTEXT_NONE;

      nsEmbedString spec;
      domnode->GetBaseURI(spec);

      nsEmbedCString cSpec;
      NS_UTF16ToCString(spec,
                    NS_CSTRING_ENCODING_UTF8, cSpec);

      nsCOMPtr<nsIURI> baseURI;
      NewURI(getter_AddRefs(baseURI), cSpec.get());
      if (!baseURI) return KZ_CONTEXT_NONE;

      nsEmbedString mime;
      nsDoc->GetContentType(mime);

      nsEmbedCString cMime;
      NS_UTF16ToCString(mime, NS_CSTRING_ENCODING_UTF8, cMime);
      if (!g_ascii_strcasecmp(cMime.get(), "text/xul"))  return KZ_CONTEXT_NONE;

      PRUint32 flags = KZ_CONTEXT_NONE;

      // check framed page
      nsCOMPtr<nsIDOMDocument> mainDocument;
      result = kzembed->priv->wrapper->GetMainDomDocument (getter_AddRefs(mainDocument));
      if (domDoc != mainDocument)
      {
            flags |= KZ_CONTEXT_FRAME;
            nsEmbedCString url;
            baseURI->GetSpec(url);        
            info->frame_src = g_strdup(url.get());
      }
      
      // check whether the node is in the selection or not
      nsCOMPtr<nsISelection> selection;
      result = kzembed->priv->wrapper->GetSelection(getter_AddRefs(selection));
      if (selection)
      {
            PRBool contains;
            selection->ContainsNode(node, PR_TRUE, &contains);
            if (contains)
                  flags |= KZ_CONTEXT_SELECTION;
      }

      // Get other context
      nsCOMPtr<nsIDOMHTMLElement> element;

      do {
            PRUint16 type;
            node->GetNodeType(&type);

            element = do_QueryInterface(node);
            if (element)
            {
                  nsEmbedString uTag;
                  element->GetLocalName(uTag);

                  nsEmbedCString utf8_tag;
                  NS_UTF16ToCString(uTag, NS_CSTRING_ENCODING_UTF8, utf8_tag);

                  if (!g_ascii_strcasecmp(utf8_tag.get(), "input"))
                  {
                        flags |= KZ_CONTEXT_INPUT;
                  }
                  else if (!g_ascii_strcasecmp(utf8_tag.get(), "textarea"))
                  {
                        flags |= KZ_CONTEXT_INPUT | KZ_CONTEXT_TEXTAREA;
                        info->element = (void*)element;
                  }
                  else if (!g_ascii_strcasecmp(utf8_tag.get(), "img"))
                  {
                        flags |= KZ_CONTEXT_IMAGE;

                        char *src = NULL;
                        wrapper->GetAttributeFromNode(node, "src", &src);
                        if (!src)  return KZ_CONTEXT_NONE;

                        nsEmbedCString srca;
                        srca = nsEmbedCString(src);

                        nsEmbedCString srcc,imgc;
                        
                        srcc = nsEmbedCString(src);

                        result = baseURI->Resolve(srcc, imgc);
                        g_free(src);

                        info->img = g_strdup(imgc.get());

                        if (!info->img) return KZ_CONTEXT_NONE;
                  }
                  else
                  {
                        flags |= KZ_CONTEXT_OTHER;
                  }

                  nsCOMPtr<nsIDOMNamedNodeMap> attributes;
                  node->GetAttributes(getter_AddRefs(attributes));
                  if (attributes)
                  {
                        nsCOMPtr<nsIDOMNode> hrefNode;
                        nsEmbedString href;

                        NS_CStringToUTF16(nsEmbedCString("href"),
                                      NS_CSTRING_ENCODING_UTF8,
                                      href);
                        attributes->GetNamedItem(href, getter_AddRefs(hrefNode));
                        if (hrefNode)
                        {
                              gchar *link;
                              flags |= KZ_CONTEXT_LINK;

                              wrapper->GetLinkAndTitleFromNode(domDoc,
                                                 node,
                                                 &link,
                                                 &info->linktext);
                              if (!link)
                              {
                                    g_free(info->linktext);
                                    return KZ_CONTEXT_NONE;
                              }
                              if (!strncasecmp(link, "mailto:", 7))
                                    info->link = g_strdup(link+7); 
                              else 
                                    info->link = g_strdup(link);
                              g_free(link);
                              break;
                        }
                  }
            }

            nsCOMPtr<nsIDOMNode> parentNode;
            node->GetParentNode(getter_AddRefs(parentNode));

            if (!parentNode)
            {
                  node = nsnull;
                  flags |= KZ_CONTEXT_DOCUMENT;
                  break;
            }
            node = parentNode;
      } while (node);

      info->context = flags;

      return flags;
}

static gchar *
kz_moz_embed_get_up_location(KzMozEmbed *kzembed)
{
      const gchar *location;
      gchar *up_location = NULL;
      gchar *pos, *dummy;
      int len; 

      location = kz_moz_embed_get_location(KZ_EMBED(kzembed));
      if (!location)
            return NULL;

      len = strlen(location);
      if (location[len - 1] == '/')
            dummy = g_strndup(location, len - 1);
      else 
            dummy = g_strndup(location, len);
      pos =  strrchr(dummy, '/');
      if (pos)
            up_location = g_strndup(dummy, pos - dummy + 1);
      g_free(dummy);
      return up_location;
}

static void
kz_moz_embed_reload (KzEmbed *kzembed, gint32 flags)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      gtk_moz_embed_reload(GTK_MOZ_EMBED(kzembed), flags);
}


static void
kz_moz_embed_stop_load (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      gtk_moz_embed_stop_load(GTK_MOZ_EMBED(kzembed));
}


static void
kz_moz_embed_go_back (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      gtk_moz_embed_go_back(GTK_MOZ_EMBED(kzembed));
}


static void
kz_moz_embed_go_up (KzEmbed *kzembed)
{
      gchar *location;
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      location = kz_moz_embed_get_up_location(KZ_MOZ_EMBED(kzembed));
      kz_moz_embed_load_url(kzembed, location);
      g_free(location);
}

static void
kz_moz_embed_go_forward (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      gtk_moz_embed_go_forward(GTK_MOZ_EMBED(kzembed));
}


static gboolean
kz_moz_embed_can_go_back (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);
      return gtk_moz_embed_can_go_back(GTK_MOZ_EMBED(kzembed));
}

static gboolean
kz_moz_embed_can_go_forward (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);
      return gtk_moz_embed_can_go_forward(GTK_MOZ_EMBED(kzembed));
}

static gboolean
kz_moz_embed_can_go_up (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);

      gboolean ret;
      gchar *location;

      location = kz_moz_embed_get_up_location(KZ_MOZ_EMBED(kzembed));

      if (!location)
            return FALSE;

      /* stupid! */
      if (strcmp(location, "http://") &&
          strcmp(location, "ftp://")  &&
          strcmp(location, "file://"))
            ret = TRUE;
      else
            ret = FALSE;
      g_free(location);

      return ret;
}

static gboolean
kz_moz_embed_can_go_nav_link (KzEmbed *kzembed,
                        KzEmbedNavLink link)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);

      return (KZ_MOZ_EMBED(kzembed)->priv->nav_links[link]) ? TRUE : FALSE;
}

static void
kz_moz_embed_go_nav_link (KzEmbed *kzembed,
                    KzEmbedNavLink link)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      g_return_if_fail(KZ_MOZ_EMBED(kzembed)->priv->nav_links[link]);

      kz_moz_embed_load_url(kzembed,
                        KZ_MOZ_EMBED(kzembed)->priv->nav_links[link]);
}

static void
kz_moz_embed_set_nav_link (KzEmbed *kzembed,
                     const gchar *name,
                     const gchar *link)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      g_return_if_fail(name);
      g_return_if_fail(link);

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      
      for (int j = 0; j < N_LINKS; j++)
      {
            if (!strcasecmp(name, nav_names[j]))
            {
                  if (mozembed->priv->nav_links[j])
                        g_free(mozembed->priv->nav_links[j]);
                  mozembed->priv->nav_links[j] = g_strdup(link);
                  break;
            }
      }
}


static void
kz_moz_embed_go_history_index (KzEmbed *kzembed, gint index)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      
      KzMozWrapper *wrapper = KZ_MOZ_EMBED(kzembed)->priv->wrapper;
      g_return_if_fail(wrapper);
      
      wrapper->GoHistoryIndex(index);
}

static void
kz_moz_embed_copy_page (KzEmbed *kzembed, KzEmbed *dkzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      g_return_if_fail(KZ_IS_MOZ_EMBED(dkzembed));

      KzMozWrapper *dWrapper = KZ_MOZ_EMBED(dkzembed)->priv->wrapper;;
      KzMozWrapper *sWrapper = KZ_MOZ_EMBED(kzembed)->priv->wrapper;;

        nsresult rv;

        nsCOMPtr<nsISupports> pageDescriptor;
        rv = sWrapper->GetPageDescriptor(getter_AddRefs(pageDescriptor));
        if (!pageDescriptor || NS_FAILED(rv)) return;

        rv = dWrapper->LoadDocument(pageDescriptor, 
                            nsIWebPageDescriptor::DISPLAY_NORMAL);
}


static gboolean
kz_moz_embed_shistory_copy (KzEmbed *source,
                      KzEmbed *dest,
                      gboolean back_history,
                      gboolean forward_history,
                      gboolean set_current)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(source), FALSE);
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(dest), FALSE);

      nsresult rv;
      KzMozWrapper *s_wrapper = KZ_MOZ_EMBED(source)->priv->wrapper;
      KzMozWrapper *d_wrapper = KZ_MOZ_EMBED(dest)->priv->wrapper;
      
      rv = s_wrapper->CopyHistoryTo (d_wrapper, back_history, forward_history, set_current);

      return NS_SUCCEEDED(rv) ? TRUE : FALSE;
}


/* picked from galeon-1.3.11a */
static gboolean
kz_moz_embed_shistory_get_pos (KzEmbed *kzembed,
                         int *pos, int *count)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);

      KzMozWrapper *wrapper = KZ_MOZ_EMBED(kzembed)->priv->wrapper;
      nsresult rv;
      int total, index;

      rv = wrapper->GetSHInfo (&total, &index);

      *pos = index;
      *count = total;

      return NS_SUCCEEDED(rv) ? TRUE : FALSE;
}

/* picked from galeon-1.3.11a */
static void
kz_moz_embed_shistory_get_nth (KzEmbed *kzembed, 
                         int nth,
                         gboolean is_relative,
                         char **aUrl,
                         char **aTitle)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      KzMozWrapper *wrapper = mozembed->priv->wrapper;
      nsresult rv;

      if (is_relative)
      {
            int pos, count;
            if(kz_moz_embed_shistory_get_pos(kzembed, &pos, &count))
                  pos += nth;
            else
                  return;
            nth = pos;
      }
      
        nsEmbedCString url;
        rv = wrapper->GetSHUrlAtIndex(nth, url);

        *aUrl = (NS_SUCCEEDED (rv) && url.Length()) ? g_strdup(url.get()) : NULL;

      PRUnichar *title;
      rv = wrapper->GetSHTitleAtIndex(nth, &title);

      nsEmbedCString str;
      NS_UTF16ToCString(nsEmbedString(title),
                    NS_CSTRING_ENCODING_UTF8, str);
      *aTitle = g_strdup (str.get());
      nsMemory::Free(title);
}


static gboolean
kz_moz_embed_get_lock (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);
      return KZ_MOZ_EMBED(kzembed)->priv->lock;
}


static void
kz_moz_embed_set_lock (KzEmbed *kzembed, gboolean lock)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      KZ_MOZ_EMBED(kzembed)->priv->lock = lock;
}


static gchar *
kz_moz_embed_get_body_text(KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);
      g_return_val_if_fail(KZ_MOZ_EMBED(kzembed)->priv->wrapper, FALSE);

      nsEmbedString text;
      KZ_MOZ_EMBED(kzembed)->priv->wrapper->GetBodyString(text);

      nsEmbedCString cText;
      NS_UTF16ToCString(text,
                    NS_CSTRING_ENCODING_UTF8, cText);
      return g_strdup(cText.get());
}


static void
kz_moz_embed_set_encoding (KzEmbed *kzembed, const char *encoding)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      g_return_if_fail(KZ_MOZ_EMBED(kzembed)->priv->wrapper);

      KZ_MOZ_EMBED(kzembed)->priv->wrapper->ForceEncoding(encoding);
}

static void
kz_moz_embed_get_encoding (KzEmbed *kzembed, char **encoding, gboolean *forced)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      g_return_if_fail(KZ_MOZ_EMBED(kzembed)->priv->wrapper);

      KZ_MOZ_EMBED(kzembed)->priv->wrapper->GetEncoding(encoding, *forced);
}

static gboolean 
kz_moz_embed_save_with_content (KzEmbed *kzembed, const char *rawfilename)
{
      nsresult rv;
      KzMozWrapper *wrapper = NULL;
      PRUint32 persistFlags = 0;

      nsCOMPtr<nsIWebBrowserPersist> bpersist = 
            do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID);
      if (!bpersist) return FALSE;

      nsCOMPtr<nsIURI> linkURI;
      linkURI = nsnull;

      nsEmbedCString filename(rawfilename);
        nsCOMPtr<nsILocalFile> file;
            NS_NewNativeLocalFile(filename, PR_TRUE, getter_AddRefs(file)); 
        if (!file) return FALSE;

      nsCOMPtr<nsILocalFile> path;
      char *datapath;
      datapath = g_strconcat (rawfilename, ".content", NULL);

      nsEmbedString DataPath;
      NS_CStringToUTF16(nsEmbedCString(datapath),
                    NS_CSTRING_ENCODING_UTF8, DataPath);
      NS_NewLocalFile(DataPath, PR_TRUE, getter_AddRefs(path));
      g_free (datapath);

      wrapper = KZ_MOZ_EMBED(kzembed)->priv->wrapper;
      g_return_val_if_fail (wrapper != NULL, FALSE);  

      persistFlags = nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;

      size_t len = strlen(rawfilename);
      if((rawfilename[len-1] == 'z' && rawfilename[len-2] == 'g') ||
         (rawfilename[len-1] == 'Z' && rawfilename[len-2] == 'G'))
      {
                persistFlags |= nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION;
      }

      persistFlags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE;
      bpersist->SetPersistFlags (persistFlags);

      g_return_val_if_fail (wrapper != NULL, FALSE);

      nsCOMPtr<nsIDOMDocument> DOMDocument;

      rv = wrapper->GetMainDomDocument (getter_AddRefs(DOMDocument));
      if (NS_FAILED(rv) || !DOMDocument) return FALSE;

      nsCOMPtr<nsIURI> inURI;
      nsEmbedCString sURI;

      rv = wrapper->GetDocumentUrl(sURI);
            rv = NewURI(getter_AddRefs(inURI), sURI.get());

      // FIXME! Use ProgressListener. 
      // KzMozProgressListener *aProgress = new KzMozProgressListener ();
      // aProgress->Init(inURI, path, 
      //          nsnull, nsnull, 0, bpersist);

      rv = bpersist->SaveDocument (DOMDocument, file, path, nsnull, 0, 0);
      if (NS_FAILED(rv)) return FALSE;

      return TRUE;
}


static void
kz_moz_embed_print (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozWrapper *wrapper = KZ_MOZ_EMBED(kzembed)->priv->wrapper;
      g_return_if_fail (wrapper != NULL);

      wrapper->Print();
}


static void
kz_moz_embed_print_preview (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozWrapper *wrapper = KZ_MOZ_EMBED(kzembed)->priv->wrapper;
      g_return_if_fail (wrapper != NULL);
      
      wrapper->PrintPreview();
}


static GList *
kz_moz_embed_get_printer_list (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), NULL);

      KzMozWrapper *wrapper = KZ_MOZ_EMBED(kzembed)->priv->wrapper;
      g_return_val_if_fail (wrapper != NULL, NULL);
      
      GList *list = NULL;
      wrapper->GetPrinterList(&list);

      return list;
}


static gchar *
kz_moz_embed_get_text_from_textarea (KzEmbed *kzembed,
                             gpointer element)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), NULL);

      nsIDOMHTMLElement *htmlElement = (nsIDOMHTMLElement*)element;

      nsCOMPtr<nsIDOMHTMLTextAreaElement> tElement = do_QueryInterface(htmlElement);

      g_return_val_if_fail(tElement, NULL);

      nsEmbedString string;
      tElement->GetValue(string);

      nsEmbedCString cString;
      NS_UTF16ToCString(string,
                    NS_CSTRING_ENCODING_UTF8, cString);

      return g_strdup(cString.get());
}


static gboolean
kz_moz_embed_set_text_into_textarea (KzEmbed *kzembed,
                             gpointer element,
                             const gchar *text)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);

      nsIDOMHTMLElement *htmlElement = (nsIDOMHTMLElement*)element;

      nsCOMPtr<nsIDOMHTMLTextAreaElement> tElement = do_QueryInterface(htmlElement);

      if (!tElement) return FALSE;

      nsEmbedString string;
      NS_CStringToUTF16(nsEmbedCString(text),
                    NS_CSTRING_ENCODING_UTF8, string);
      tElement->SetValue(string);

      return TRUE;
}


static gchar *
mozilla_store_history_file(KzMozEmbed *kzembed)
{
      nsresult rv;

      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), NULL);

      KzMozWrapper *wrapper = kzembed->priv->wrapper;
      g_return_val_if_fail (wrapper != NULL, NULL);

      PRUint32 persistFlags = 0;
      
      nsCOMPtr<nsIWebBrowserPersist> bpersist = 
            do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID);
      if (!bpersist) return NULL;

      persistFlags = nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;

      persistFlags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
      bpersist->SetPersistFlags (persistFlags);

      nsCOMPtr<nsIURI> inURI;
      nsEmbedCString sURI;

      rv = wrapper->GetDocumentUrl(sURI);
            rv = NewURI(getter_AddRefs(inURI), sURI.get());

      gchar *dir, *filename;

      filename = create_filename_with_path_from_uri(sURI.get());
            
      dir = g_build_filename(g_get_home_dir(),
                         HISTORY_DIR,
                         filename,
                         NULL);
      g_free(filename);

      nsCOMPtr<nsILocalFile> localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
      rv = localFile->InitWithNativePath(nsEmbedCString(dir));

      if (NS_FAILED(rv))
            return NULL;

      PRBool exists;
      localFile->Exists(&exists);
      if (!exists)
      {
            rv = localFile->Create(nsIFile::NORMAL_FILE_TYPE, 0600);
            if (NS_FAILED(rv))
                  return NULL;
      }

      nsCOMPtr<nsISupports> pageDescriptor;

      wrapper->GetPageDescriptor(getter_AddRefs(pageDescriptor));
      
      rv = bpersist->SaveURI (inURI, pageDescriptor, nsnull,
                        nsnull, nsnull, localFile);
      
      return dir;
}


#if 1 /* FIXME! */
static KzMozThumbnailCreator *
kz_window_create_thumbnail_creator (KzWindow *kz)
{
      KzMozThumbnailCreator *creator;

      creator     = KZ_MOZ_THUMBNAIL_CREATOR(g_object_get_data(G_OBJECT(kz),
                                               "KzMozEmbed::ThumbnailCreator"));
      if (!creator)
      {
            creator = kz_moz_thumbnail_creator_new();
            gtk_widget_set_size_request(GTK_WIDGET(creator), 0, 0);
            gtk_widget_show(GTK_WIDGET(creator));

            gtk_box_pack_start(GTK_BOX(kz->statusbar_area),
                           GTK_WIDGET(creator),
                           FALSE, FALSE, 0);
            g_object_set_data(G_OBJECT(kz), 
                          "KzMozEmbed::ThumbnailCreator", 
                          creator);
      }

      return creator;
}
#endif /* FIXME! */
static void
kz_moz_embed_create_thumbnail (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      KzMozWrapper *wrapper = NULL;
      wrapper = mozembed->priv->wrapper;
      g_return_if_fail (wrapper != NULL);

      nsresult rv;
      int total, index;
      rv = wrapper->GetSHInfo (&total, &index);

      nsCOMPtr<nsIHistoryEntry> he;
      rv = wrapper->GetHistoryEntry(index, getter_AddRefs(he));
      if (NS_FAILED(rv)) return;

      GtkWidget *window = gtk_widget_get_toplevel(GTK_WIDGET(kzembed));

      if (!KZ_IS_WINDOW(window)) return;

      KzWindow *kz = KZ_WINDOW(window);

      gboolean create_thumbnail = FALSE;
      KZ_CONF_GET("Global", "create_thumbnail", create_thumbnail, BOOL);
      if (create_thumbnail)
      {
            KzMozThumbnailCreator *creator;
            creator = kz_window_create_thumbnail_creator(kz);
            kz_moz_thumbnail_creator_append_queue(creator, he);
      }
}


void
kz_moz_embed_do_command (KzEmbed *kzembed, const char *command)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      nsCOMPtr<nsICommandManager> commandManager;
      commandManager = do_GetInterface(mozembed->priv->wrapper->mWebBrowser);
      if (!commandManager) return;
      
      commandManager->DoCommand(command, nsnull, nsnull);

}

static gboolean
kz_moz_embed_can_do_command (KzEmbed *kzembed, const char *command)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);
      
      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      nsCOMPtr<nsICommandManager> commandManager;
      commandManager = do_GetInterface(mozembed->priv->wrapper->mWebBrowser);
      if (!commandManager) return FALSE;
      
      PRBool enabled;
      commandManager->IsCommandEnabled(command, nsnull, &enabled);

      return (enabled == PR_TRUE);
}

static void
kz_moz_embed_zoom_set (KzEmbed *kzembed, int zoom, gboolean reflow)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozWrapper *wrapper = KZ_MOZ_EMBED(kzembed)->priv->wrapper;

      wrapper->SetImageZoom ((float)(zoom) / 100);
            
      kz_moz_embed_set_text_size(kzembed, zoom, reflow);
}

static int
kz_moz_embed_zoom_get (KzEmbed *kzembed)
{
      return kz_moz_embed_get_text_size(kzembed);
}


static void
kz_moz_embed_set_text_size (KzEmbed *kzembed,  int zoom, gboolean reflow)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozWrapper *wrapper = KZ_MOZ_EMBED(kzembed)->priv->wrapper;

      wrapper->SetZoom ((float)(zoom) / 100, reflow);
}

static int 
kz_moz_embed_get_text_size (KzEmbed *kzembed)
{
      float f;
      int zoom;

      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), 100);

      KzMozWrapper *wrapper = KZ_MOZ_EMBED(kzembed)->priv->wrapper;

      if (!wrapper) return 100;

      nsresult result = wrapper->GetZoom (&f);
      if (NS_FAILED (result)) return 100;

      zoom = (int) rint (f * 100);

      return zoom;
}

static void
kz_moz_embed_set_history (KzEmbed *kzembed, KzBookmark *history)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      g_return_if_fail(KZ_IS_BOOKMARK(history));

      if (!kz_bookmark_is_folder(history)) return;

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      KzMozWrapper *wrapper = mozembed->priv->wrapper;
      if (!wrapper) return;

      nsCOMPtr<nsISHistory> sHistory;
      nsresult rv = wrapper->GetSHistory(getter_AddRefs(sHistory));
      if (NS_FAILED(rv) || !sHistory) return;

      nsCOMPtr<nsISHistoryInternal> sHistoryInternal;
      sHistoryInternal = do_QueryInterface(sHistory);

      PRInt32 n;
      sHistory->GetCount(&n);
      sHistory->PurgeHistory(n);

      GList *children, *node;
      children = kz_bookmark_get_children(history);
      for (node = children; node; node = g_list_next (node))
      {
            KzBookmark *child = KZ_BOOKMARK(node->data);
            const gchar *title, *uri;

            title = kz_bookmark_get_title(child);
            uri   = kz_bookmark_get_link(child);

            nsCOMPtr<nsISHEntry> entry;
            entry = do_CreateInstance(NS_SHENTRY_CONTRACTID);

            nsCOMPtr<nsIURI> aURI;
            NewURI(getter_AddRefs(aURI), uri);        
            /* FIXME! set correct contentType */
            nsEmbedCString contentType;
            entry->Create(aURI,
                        nsnull,
                        nsnull,
                        nsnull,
                        nsnull,
                        nsnull,
                        nsEmbedCString(""));
            sHistoryInternal->AddEntry(entry, PR_TRUE);
      }
      g_list_free(children);

      /* set current */
      gint cur = kz_bookmark_get_current(history);
      kz_moz_embed_go_history_index(kzembed, cur);
}

static void
kz_moz_embed_get_history (KzEmbed *kzembed, KzBookmark *history)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));
      g_return_if_fail(KZ_IS_BOOKMARK(history));

      if (!kz_bookmark_is_folder(history)) return;

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      KzMozWrapper *wrapper = mozembed->priv->wrapper;
      if (!wrapper) return;

      nsCOMPtr<nsISHistory> sHistory;
      nsresult rv = wrapper->GetSHistory(getter_AddRefs(sHistory));

      if (NS_FAILED(rv) || !sHistory) return;

      GList *children, *tab;
      children = kz_bookmark_get_children(history);
      tab = children;

      PRInt32 count;
      sHistory->GetCount(&count);

      PRInt32 index;
      sHistory->GetIndex(&index);
      for (PRInt32 i = 0; i < count; i++)
      {
            gchar *title, *uri;
            KzBookmark *bookmark = NULL;
            
            kz_moz_embed_shistory_get_nth (kzembed,
                                     i, FALSE,
                                     &uri,
                                     &title);
            if (tab)
            {
                  bookmark = KZ_BOOKMARK(tab->data);
                  tab = g_list_next(tab);
            }

            /* if there's no children of bookmarks, create a new bookmark */
            if (!bookmark)
            {
                  bookmark = kz_bookmark_new_with_attrs(title, uri, NULL);
                  kz_bookmark_append(history, bookmark);
                  g_object_unref(bookmark);
            }
            else if (!strcmp(uri, kz_bookmark_get_link(bookmark)))
            {
                  continue;
            }
            else
            {
                  kz_bookmark_set_link(bookmark, uri);
                  kz_bookmark_set_title(bookmark, title);
                  kz_bookmark_set_last_visited(bookmark, 0);
            }

            if (title)
                  g_free(title);
            if (uri)
                  g_free(uri);
      }

      if (tab)
            tab = g_list_last(tab);
      GList *prev;

      while (tab)
      {
            KzBookmark *child = KZ_BOOKMARK(tab->data);
            prev = g_list_previous(tab);
            kz_bookmark_remove (history, child);
            tab = prev;
      }

      if (children)
            g_list_free(children);

      kz_bookmark_set_current(history, (gint)index);
}


static guint
kz_moz_embed_get_last_modified (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), 0);

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);

      if (!mozembed->priv->wrapper) return 0;

      nsresult result;

      nsCOMPtr<nsIDOMDocument> DOMDocument;

      result = mozembed->priv->wrapper->GetDocument (getter_AddRefs(DOMDocument));
      if (NS_FAILED(result) || !DOMDocument) return 0;

      nsCOMPtr<nsIDOMNSDocument> doc = do_QueryInterface(DOMDocument);
      if(!doc) return 0;
      
      nsEmbedString value;

      doc->GetLastModified(value);

      guint mod_time = 0;
      nsEmbedCString cValue;
      NS_UTF16ToCString(value,
                    NS_CSTRING_ENCODING_UTF8, cValue);
      nsTime last_modified (cValue.get(), PR_TRUE);
      LL_DIV (mod_time,
            NS_STATIC_CAST(PRTime, last_modified), PR_USEC_PER_SEC);
      return mod_time;
}


#if 0
static void
kz_moz_embed_set_edit_mode (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);

      nsCOMPtr<nsIDOMWindow> domWindow;
      mozembed->priv->wrapper->GetDOMWindow(getter_AddRefs(domWindow));
      
      nsCOMPtr<nsIEditingSession> edit;
      edit = do_GetInterface(mozembed->priv->wrapper->mWebBrowser);
      if (edit)
      {
            edit->MakeWindowEditable(domWindow, "html", PR_FALSE);
      }
}

static void
kz_moz_embed_set_view_mode (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      
      nsCOMPtr<nsIDOMWindow> domWindow;
      mozembed->priv->wrapper->GetDOMWindow(getter_AddRefs(domWindow));
      
      nsCOMPtr<nsIEditingSession> edit;
      edit = do_GetInterface(mozembed->priv->wrapper->mWebBrowser);
      if (edit)
      {
            edit->TearDownEditorOnWindow(domWindow);
      }
}
#endif

static void
kz_moz_embed_fine_scroll (KzEmbed *kzembed,
                    int horiz, int vert)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      KzMozWrapper *wrapper = mozembed->priv->wrapper;

      if (!wrapper) return;

      wrapper->FineScroll (horiz, vert);
}

static void
kz_moz_embed_page_up (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      KzMozWrapper *wrapper = mozembed->priv->wrapper;

      if (!wrapper) return;
      
      wrapper->PageUp();
}

static void
kz_moz_embed_page_down (KzEmbed *kzembed)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      KzMozWrapper *wrapper = mozembed->priv->wrapper;

      if (!wrapper) return;
      
      wrapper->PageDown();
}

static gboolean
kz_moz_embed_get_allow_javascript (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      KzMozWrapper *wrapper = mozembed->priv->wrapper;

      if (!wrapper) return FALSE;

      PRBool allow;
      wrapper->GetAllowJavascript(&allow);

      return allow ? TRUE : FALSE;
}

static void
kz_moz_embed_set_allow_javascript (KzEmbed *kzembed, gboolean allow)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      KzMozWrapper *wrapper = mozembed->priv->wrapper;

      if (!wrapper) return;
      
      wrapper->SetAllowJavascript(allow);
}

static gboolean
kz_moz_embed_get_allow_images (KzEmbed *kzembed)
{
      g_return_val_if_fail(KZ_IS_MOZ_EMBED(kzembed), FALSE);

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      KzMozWrapper *wrapper = mozembed->priv->wrapper;

      if (!wrapper) return FALSE;

      PRBool allow;
      wrapper->GetAllowImages(&allow);

      return allow ? TRUE : FALSE;
}

static void
kz_moz_embed_set_allow_images (KzEmbed *kzembed, gboolean allow)
{
      g_return_if_fail(KZ_IS_MOZ_EMBED(kzembed));

      KzMozEmbed *mozembed = KZ_MOZ_EMBED(kzembed);
      KzMozWrapper *wrapper = mozembed->priv->wrapper;

      if (!wrapper) return;
      
      wrapper->SetAllowImages(allow);
}


Generated by  Doxygen 1.6.0   Back to index