kazehakase 

File Info

Rev. 3819
Size 90,074 bytes
Time 2009-09-04 09:02:15
Author ikezoe
Log Message

* src/kz-embed.[ch]: Remove get_lock and set_lock interfaces. These are implemented
in kz-web.c.
* src/kz-web.c: Fix crash when kz-new-window signal is received.

Content

   1: // -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
   2: 
   3: //
   4: //  Copyright (C) 2007 Hiroyuki Ikezoe
   5: //
   6: //  This program is free software; you can redistribute it and/or modify
   7: //  it under the terms of the GNU General Public License as published by
   8: //  the Free Software Foundation; either version 2, or (at your option)
   9: //  any later version.
  10: //
  11: //  This program is distributed in the hope that it will be useful,
  12: //  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13: //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14: //  GNU General Public License for more details.
  15: //
  16: //  You should have received a copy of the GNU General Public License
  17: //  along with this program; if not, write to the Free Software
  18: //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19: //
  20: 
  21: #include "kz-module-impl.h"
  22: 
  23: #define MOZILLA_CLIENT
  24: 
  25: #include "kz-embed-prefs.h"
  26: #include "kz-gecko-single.h"
  27: 
  28: #include <string.h>
  29: #include <math.h>
  30: #include <gtkmozembed.h>
  31: #include <gtkmozembed_internal.h>
  32: #include <glib/gi18n.h>
  33: #include <glib/gstdio.h>
  34: #include <sys/stat.h>
  35: 
  36: #include "kazehakase.h"
  37: #include "kz-window.h"
  38: #include "kz-mozwrapper.h"
  39: #include "kz-mozprogresslistener.h"
  40: #include "kz-mozutils.h"
  41: #include "mozilla.h"
  42: #include "mozilla-prefs.h"
  43: #include "bookmarks/kz-bookmark.h"
  44: #if USE_MIGEMO
  45: #  include "kz-migemo.h"
  46: #endif
  47: #include "kz-history-utils.h"
  48: #include "utils.h"
  49: 
  50: #include "kz-search.h"
  51: 
  52: #include <nsCOMPtr.h>
  53: #include <nsIDOMDocument.h>
  54: #include <nsIDocumentViewer.h>
  55: #include <nsIWebBrowser.h>
  56: #include <nsIDOMMouseEvent.h>
  57: #include <nsIDOMKeyEvent.h>
  58: #include <nsIDOMNSHTMLElement.h>
  59: #include <nsIDOMHTMLElement.h>
  60: #include <nsIDOMHTMLDocument.h>
  61: #include <nsIDOMHTMLTextAreaElement.h>
  62: #include <nsIDOMNamedNodeMap.h>
  63: #include <nsIDOMDocumentRange.h>
  64: #include <nsIDOMDocumentFragment.h>
  65: #include <nsIDOMSerializer.h>
  66: #include <nsIDOMText.h>
  67: #include <nsIWebBrowserPersist.h>
  68: #include <nsIWebBrowserFind.h>
  69: #include <nsIFind.h>
  70: #include <nsIDOMNSDocument.h>
  71: #include <nsIDOMNSEvent.h>
  72: #include <nsIDOMNodeList.h>
  73: #include <nsIDOMWindow.h>
  74: #include <nsIDOMEventTarget.h>
  75: #include <nsISelection.h>
  76: #include <nsIDOMRange.h>
  77: #include <nsIDOMWindow.h>
  78: #include <nsISelection.h>
  79: #include <nsISHistory.h>
  80: #include <nsIHistoryEntry.h>
  81: #include <nsISHEntry.h>
  82: #include <nsISHistoryInternal.h>
  83: #include <nsIWebNavigation.h>
  84: #include <nsCWebBrowserPersist.h>
  85: #include <nsIBaseWindow.h>
  86: #include <nsIWebPageDescriptor.h>
  87: #include <nsICommandManager.h>
  88: #include <nsTime.h>
  89: #include <nsRect.h>
  90: #define MOZILLA_STRICT_API
  91: #include <nsEmbedString.h>
  92: #undef MOZILLA_STRICT_API
  93: #include <nsIServiceManager.h>
  94: #include <nsIInterfaceRequestorUtils.h>
  95: #include <nsMemory.h>
  96: #include <nsILocalFile.h>
  97: #include <nsIDOM3Node.h>
  98: #include <nsIPrefService.h>
  99: #include <nsIFontEnumerator.h>
 100: #include <nsISimpleEnumerator.h>
 101: #include <nsMemory.h>
 102: #include <nsServiceManagerUtils.h>
 103: 
 104: /* GTK_CHECK_CAST is masked by GTK_DISABLE_DEPRECATED in gtk+-2.14 */
 105: #ifndef GTK_CHECK_CAST
 106: #undef GTK_MOZ_EMBED
 107: #define GTK_MOZ_EMBED(obj)      (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_MOZ_EMBED, GtkMozEmbed))
 108: #endif
 109: 
 110: #define KZ_GECKO_EMBED_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), KZ_TYPE_GECKO_EMBED, KzGeckoEmbedPrivate))
 111: 
 112: enum {
 113:         PROP_0,
 114:         PROP_LOCATION
 115: };
 116: 
 117: typedef struct _KzGeckoEmbedPrivate     KzGeckoEmbedPrivate;
 118: struct _KzGeckoEmbedPrivate
 119: {
 120:         KzMozWrapper *wrapper;
 121:         gint size_inited;
 122:         gint cur_requests;
 123:         gint total_requests;
 124: 
 125:         /* location and title */
 126:         gchar *location;
 127:         gchar *title;
 128: 
 129:         gint load_started; /* count of currently active connections */
 130:         gint load_percent;
 131:         gint bytes_loaded;
 132:         gint max_bytes_loaded;
 133:         gboolean  is_loading;
 134:         const gchar *load_status_message;
 135: 
 136:         /* for navigation link */
 137:         GList *nav_links[KZ_EMBED_LINK_GUARD];
 138: 
 139: #ifdef USE_MIGEMO
 140:         gchar *migemo_keyword;
 141: #endif
 142:         gchar *last_highlight;
 143: };
 144: 
 145: typedef struct _KzGeckoEmbedClass       KzGeckoEmbedClass;
 146: struct _KzGeckoEmbedClass
 147: {
 148:         GtkMozEmbedClass parent_class;
 149: };
 150: 
 151: static GType kz_type_gecko_embed = 0;
 152: static GtkMozEmbedClass *kz_gecko_embed_parent_class;
 153: 
 154: static GtkWidget *kz_gecko_embed_new     (void);
 155: 
 156: static void kz_gecko_embed_iface_init    (KzEmbedIFace *iface);
 157: 
 158: static void kz_gecko_embed_realize       (GtkWidget   *widget);
 159: static void kz_gecko_embed_unrealize     (GtkWidget   *widget);
 160: static void kz_gecko_embed_size_allocate (GtkWidget   *widget,
 161:                                           GtkAllocation *allocation);
 162: static void kz_gecko_embed_destroy_brsr  (GtkMozEmbed *embed);
 163: static void kz_gecko_embed_link_message  (GtkMozEmbed *embed);
 164: static void kz_gecko_embed_js_status     (GtkMozEmbed *embed);
 165: static void kz_gecko_embed_title         (GtkMozEmbed *embed);
 166: static void kz_gecko_embed_location      (GtkMozEmbed *embed);
 167: static void kz_gecko_embed_net_start     (GtkMozEmbed *embed);
 168: static void kz_gecko_embed_new_window    (GtkMozEmbed *embed,
 169:                                           GtkMozEmbed **newembed,
 170:                                           guint        chromemask);
 171: static gint kz_gecko_embed_open_uri      (GtkMozEmbed *embed,
 172:                                           const char  *uri);
 173: static void kz_gecko_embed_size_to       (GtkMozEmbed *embed,
 174:                                           gint         width,
 175:                                           gint         height);
 176: static void kz_gecko_embed_visibility    (GtkMozEmbed *embed,
 177:                                           gboolean     visibility);
 178: static void kz_gecko_embed_net_stop      (GtkMozEmbed *embed);
 179: static void kz_gecko_embed_net_state_all (GtkMozEmbed *embed,
 180:                                           const char  *aURI,
 181:                                           gint         state,
 182:                                           guint        status);
 183: #if 0
 184: static void kz_gecko_embed_security_change (GtkMozEmbed *embed,
 185:                                             gpointer     request,
 186:                                             guint        state);
 187: #endif
 188: static gboolean kz_gecko_embed_dom_key_down        (GtkMozEmbed *embed, gpointer event);
 189: static gboolean kz_gecko_embed_dom_key_up          (GtkMozEmbed *embed, gpointer event);
 190: static gboolean kz_gecko_embed_dom_key_press       (GtkMozEmbed *embed, gpointer event);
 191: static gboolean kz_gecko_embed_dom_mouse_down      (GtkMozEmbed *embed, gpointer event);
 192: static gboolean kz_gecko_embed_dom_mouse_up        (GtkMozEmbed *embed, gpointer event);
 193: static gboolean kz_gecko_embed_dom_mouse_click     (GtkMozEmbed *embed, gpointer event);
 194: static gboolean kz_gecko_embed_dom_mouse_dbl_click (GtkMozEmbed *embed, gpointer event);
 195: static gboolean kz_gecko_embed_dom_mouse_over      (GtkMozEmbed *embed, gpointer event);
 196: 
 197: 
 198: static void  kz_gecko_embed_navigation_link_free(KzGeckoEmbed *kzembed);
 199: static glong kz_gecko_embed_get_key_event_info  (KzGeckoEmbed *kzembed,
 200:                                                  gpointer      event,
 201:                                                  KzEmbedEventKey **info_ret);
 202: static glong kz_gecko_embed_get_mouse_event_info(KzGeckoEmbed *kzembed,
 203:                                                  gpointer      event,
 204:                                                  KzEmbedEventMouse **info_ret);
 205: static glong kz_gecko_embed_set_event_context   (KzGeckoEmbed *kzembed,
 206:                                                  nsIDOMEventTarget *target,
 207:                                                  KzEmbedEvent *info);
 208: static gchar *kz_gecko_embed_store_history_file (KzGeckoEmbed *kzembed);
 209: 
 210: static void         load_uri              (KzEmbed      *kzembed,
 211:                                            const gchar  *url);
 212: static void         view_source           (KzEmbed      *kzembed,
 213:                                            const gchar  *url);
 214: static void         view_current_page_source_in_new
 215:                                           (KzEmbed      *kzembed,
 216:                                            KzEmbed      *new_embed);
 217: static gboolean     is_loading            (KzEmbed      *kzembed);
 218: static const gchar *get_title             (KzEmbed      *kzembed);
 219: static const gchar *get_location          (KzEmbed      *kzembed);
 220: static gdouble      get_progress          (KzEmbed      *kzembed);
 221: static gboolean     can_cut_selection     (KzEmbed      *kzembed);
 222: static gboolean     can_copy_selection    (KzEmbed      *kzembed);
 223: static gboolean     can_paste             (KzEmbed      *kzembed);
 224: static void         cut_selection         (KzEmbed      *kzembed);
 225: static void         copy_selection        (KzEmbed      *kzembed);
 226: static void         paste                 (KzEmbed      *kzembed);
 227: static void         select_all            (KzEmbed      *kzembed);
 228: static gchar       *get_selection_string  (KzEmbed      *kzembed);
 229: static gboolean     find                  (KzEmbed      *kzembed,
 230:                                            const char   *keyword,
 231:                                            gboolean      backward);
 232: static gboolean     incremental_search    (KzEmbed      *kzembed,
 233:                                            const char   *keyword,
 234:                                            gboolean      backward);
 235: static gboolean     selection_is_collapsed(KzEmbed      *kzembed);
 236: static gboolean     get_links             (KzEmbed      *kzembed,
 237:                                            GList       **list,
 238:                                            gboolean      selected_only);
 239: static gboolean     get_dest_anchors      (KzEmbed      *kzembed,
 240:                                            GList       **list);
 241: static void         copy_page             (KzEmbed      *src_embed,
 242:                                            KzEmbed      *dest_embed);
 243: static gboolean     shistory_get_pos      (KzEmbed      *kzembed,
 244:                                            int          *pos,
 245:                                            int          *count);
 246: static void         shistory_get_nth      (KzEmbed      *kzembed, 
 247:                                            int           nth,
 248:                                            gboolean      is_relative,
 249:                                            char        **aUrl,
 250:                                            char        **aTitle);
 251: static void         reload                (KzEmbed      *kzembed,
 252:                                            KzEmbedReloadFlag flags);
 253: static void         stop_load             (KzEmbed      *kzembed);
 254: static void         go_back               (KzEmbed      *kzembed);
 255: static void         go_forward            (KzEmbed      *kzembed);
 256: static gboolean     can_go_back           (KzEmbed      *kzembed);
 257: static gboolean     can_go_forward        (KzEmbed      *kzembed);
 258: static gboolean     can_go_nav_link       (KzEmbed      *kzembed,
 259:                                            KzEmbedNavLink link);
 260: static void         go_nav_link           (KzEmbed      *kzembed,
 261:                                            KzEmbedNavLink link);
 262: static void         append_nav_link       (KzEmbed      *kzembed,
 263:                                            KzEmbedNavLink link,
 264:                                            KzNavi       *navi);
 265: static void         set_nth_nav_link      (KzEmbed      *kzembed,
 266:                                            KzEmbedNavLink link,
 267:                                            KzNavi       *navi,
 268:                                            guint         n);
 269: static KzNavi      *get_nth_nav_link      (KzEmbed      *kzembed,
 270:                                            KzEmbedNavLink link,
 271:                                            guint         n);
 272: static GList       *get_nav_links         (KzEmbed      *kzembed,
 273:                                            KzEmbedNavLink link);
 274: static void         go_history_index      (KzEmbed      *kzembed,
 275:                                            gint          index);
 276: static gchar       *get_body_text         (KzEmbed      *kzembed);
 277: static void         set_encoding          (KzEmbed      *kzembed,
 278:                                            const char   *encoding);
 279: static void         get_encoding          (KzEmbed      *kzembed,
 280:                                            char        **encoding,
 281:                                            gboolean     *forced);
 282: static void         print                 (KzEmbed      *kzembed);
 283: static void         print_preview         (KzEmbed      *kzembed);
 284: static GList       *get_printer_list      (KzEmbed      *kzembed);
 285: static void         create_thumbnail      (KzEmbed      *kzembed,
 286:                                            EggPixbufThumbnailSize size);
 287: static gboolean     save_with_content     (KzEmbed      *kzembed,
 288:                                            const char   *rawfilename);
 289: static gboolean     set_text_into_textarea(KzEmbed      *kzembed,
 290:                                            gpointer      element,
 291:                                            const gchar  *text);
 292: static gchar       *get_text_from_textarea(KzEmbed      *kzembed,
 293:                                            gpointer      element);
 294: static void         zoom                  (KzEmbed      *kzembed, 
 295:                                            gdouble       zoom);
 296: static gdouble      get_zoom_ratio        (KzEmbed      *kzembed);
 297: static void         set_text_size         (KzEmbed      *kzembed, 
 298:                                            gdouble       zoom);
 299: static gdouble      get_text_size         (KzEmbed      *kzembed);
 300: 
 301: static gchar       *get_html_with_contents(KzEmbed      *kzembed,
 302:                                            const gchar  *storedir);
 303: static void         set_history           (KzEmbed      *kzembed,
 304:                                            const GList  *history,
 305:                                            guint         current_position);
 306: static void         get_history           (KzEmbed      *kzembed,
 307:                                            GList       **history,
 308:                                            guint        *current_position);
 309: static guint        get_last_modified     (KzEmbed      *kzembed);
 310: static void         fine_scroll           (KzEmbed      *kzembed,
 311:                                            int           horiz, 
 312:                                            int           vert);
 313: static void         page_up               (KzEmbed      *kzembed);
 314: static void         page_down             (KzEmbed      *kzembed);
 315: 
 316: static gboolean     get_allow_javascript  (KzEmbed      *kzembed);
 317: static void         set_allow_javascript  (KzEmbed      *kzembed,
 318:                                            gboolean      allow);
 319: static gboolean     get_allow_images      (KzEmbed      *kzembed);
 320: static void         set_allow_images      (KzEmbed      *kzembed,
 321:                                            gboolean      allow);
 322: static void         show_page_certificate (KzEmbed      *kzembed);
 323: 
 324: /* KzEmbedPrefs interfaces */
 325: static void          kz_gecko_embed_prefs_iface_init      (KzEmbedPrefsIFace *iface);
 326: static gboolean      kz_gecko_embed_prefs_init            (KzEmbedPrefs *embed_prefs);
 327: static gboolean      kz_gecko_embed_prefs_get_font_list   (KzEmbedPrefs *embed_prefs,
 328:                                                            const gchar  *lang_group,
 329:                                                            const gchar  *font_type,
 330:                                                            GList      **font_list,
 331:                                                            GList      **all_font_list,
 332:                                                            gchar       **default_font);
 333: 
 334: static gboolean      kz_gecko_embed_prefs_get_passwords    (KzEmbedPrefs *embed_prefs,
 335:                                                             GList **passwords);
 336: static gboolean      kz_gecko_embed_prefs_remove_passwords (KzEmbedPrefs *embed_prefs,
 337:                                                             GList *passwords);
 338: 
 339: /* KzGeckoEmbed Class */
 340: static void   kz_gecko_embed_class_init (KzGeckoEmbedClass *klass);
 341: static void   kz_gecko_embed_init       (KzGeckoEmbed *embed);
 342: 
 343: static GObject *constructor  (GType type,
 344:                               guint n_props,
 345:                               GObjectConstructParam *props);
 346: 
 347: static void     dispose      (GObject      *object);
 348: static void     set_property (GObject      *object,
 349:                               guint         prop_id,
 350:                               const GValue *value,
 351:                               GParamSpec   *pspec);
 352: static void     get_property (GObject      *object,
 353:                               guint         prop_id,
 354:                               GValue       *value,
 355:                               GParamSpec   *pspec);
 356: void
 357: kz_gecko_embed_register_type (GTypeModule *module)
 358: {
 359:         static const GTypeInfo kz_gecko_embed_info =
 360:         {
 361:                 sizeof (KzGeckoEmbedClass),
 362:                 NULL,           /* base_init */
 363:                 NULL,           /* base_finalize */
 364:                 (GClassInitFunc) kz_gecko_embed_class_init,
 365:                 NULL,           /* class_finalize */
 366:                 NULL,           /* class_data */
 367:                 sizeof (KzGeckoEmbed),
 368:                 0,              /* n_preallocs */
 369:                 (GInstanceInitFunc) kz_gecko_embed_init,
 370:         };
 371: 
 372:         const GInterfaceInfo kz_embed_info =
 373:         {
 374:                 (GInterfaceInitFunc) kz_gecko_embed_iface_init,
 375:                 NULL,
 376:                 NULL
 377:         };
 378: 
 379:         const GInterfaceInfo kz_embed_prefs_info =
 380:         {
 381:                 (GInterfaceInitFunc) kz_gecko_embed_prefs_iface_init,
 382:                 NULL,
 383:                 NULL
 384:         };
 385: 
 386:         kz_type_gecko_embed = g_type_module_register_type(module,
 387:                                                           GTK_TYPE_MOZ_EMBED,
 388:                                                           "KzGeckoEmbed",
 389:                                                           &kz_gecko_embed_info,
 390:                                                           (GTypeFlags)0);
 391: 
 392:         g_type_module_add_interface(module,
 393:                                     KZ_TYPE_GECKO_EMBED,
 394:                                     KZ_TYPE_EMBED,
 395:                                     &kz_embed_info);
 396: 
 397:         g_type_module_add_interface(module,
 398:                                     KZ_TYPE_GECKO_EMBED,
 399:                                     KZ_TYPE_EMBED_PREFS,
 400:                                     &kz_embed_prefs_info);
 401: }
 402: 
 403: GType
 404: kz_gecko_embed_get_type (void)
 405: {
 406:        return kz_type_gecko_embed;
 407: }
 408: 
 409: static void
 410: kz_gecko_embed_iface_init (KzEmbedIFace *iface)
 411: {
 412:         iface->load_uri               = load_uri;
 413:         iface->view_source            = view_source;
 414:         iface->view_current_page_source_in_new
 415:                                       = view_current_page_source_in_new;
 416:         iface->is_loading             = is_loading;
 417:         iface->get_title              = get_title;
 418:         iface->get_location           = get_location;
 419:         iface->get_progress           = get_progress;
 420:         iface->can_cut_selection      = can_cut_selection;
 421:         iface->can_copy_selection     = can_copy_selection;
 422:         iface->can_paste              = can_paste;
 423:         iface->cut_selection          = cut_selection;
 424:         iface->copy_selection         = copy_selection;
 425:         iface->paste                  = paste;
 426:         iface->select_all             = select_all;
 427:         iface->get_selection_string   = get_selection_string;
 428:         iface->find                   = find;
 429:         iface->incremental_search     = incremental_search;
 430:         iface->selection_is_collapsed = selection_is_collapsed;
 431:         iface->get_links              = get_links;
 432:         iface->get_dest_anchors       = get_dest_anchors;
 433:         iface->copy_page              = copy_page;
 434:         iface->shistory_get_pos       = shistory_get_pos;
 435:         iface->shistory_get_nth       = shistory_get_nth;
 436:         iface->reload                 = reload;
 437:         iface->stop_load              = stop_load;
 438:         iface->go_back                = go_back;
 439:         iface->go_forward             = go_forward;
 440:         iface->can_go_back            = can_go_back;
 441:         iface->can_go_forward         = can_go_forward;
 442:         iface->can_go_nav_link        = can_go_nav_link;
 443:         iface->go_nav_link            = go_nav_link;
 444:         iface->append_nav_link        = append_nav_link;
 445:         iface->set_nav_link           = NULL;
 446:         iface->set_nth_nav_link       = set_nth_nav_link;
 447:         iface->get_nav_link           = NULL;
 448:         iface->get_nth_nav_link       = get_nth_nav_link;
 449:         iface->get_nav_links          = get_nav_links;
 450:         iface->go_history_index       = go_history_index;
 451:         iface->get_body_text          = get_body_text;
 452:         iface->set_encoding           = set_encoding;
 453:         iface->get_encoding           = get_encoding;
 454:         iface->print                  = print;
 455:         iface->print_preview          = print_preview;
 456:         iface->get_printer_list       = get_printer_list;
 457:         iface->create_thumbnail       = create_thumbnail;
 458:         iface->save_with_content      = save_with_content;
 459:         iface->set_text_into_textarea = set_text_into_textarea;
 460:         iface->get_text_from_textarea = get_text_from_textarea;
 461:         iface->zoom                   = zoom;
 462:         iface->get_zoom_ratio         = get_zoom_ratio;
 463:         iface->set_text_size          = set_text_size;
 464:         iface->get_text_size          = get_text_size;
 465:         iface->get_html_with_contents = get_html_with_contents;
 466:         iface->set_history            = set_history;
 467:         iface->get_history            = get_history;
 468:         iface->get_last_modified      = get_last_modified;
 469:         iface->fine_scroll            = fine_scroll;
 470:         iface->page_up                = page_up;
 471:         iface->page_down              = page_down;
 472:         iface->get_allow_javascript   = get_allow_javascript;
 473:         iface->set_allow_javascript   = set_allow_javascript;
 474:         iface->get_allow_images       = get_allow_images;
 475:         iface->set_allow_images       = set_allow_images;
 476:         iface->show_page_certificate  = show_page_certificate;
 477: }
 478: 
 479: static void
 480: kz_gecko_embed_prefs_iface_init (KzEmbedPrefsIFace *iface)
 481: {
 482:         iface->init             = kz_gecko_embed_prefs_init;
 483:         iface->get_font_list    = kz_gecko_embed_prefs_get_font_list;
 484:         iface->get_passwords    = kz_gecko_embed_prefs_get_passwords;
 485:         iface->remove_passwords = kz_gecko_embed_prefs_remove_passwords;
 486: }
 487: 
 488: static void
 489: kz_gecko_embed_class_init (KzGeckoEmbedClass *klass)
 490: {
 491:         GObjectClass *gobject_class;
 492:         GtkWidgetClass *widget_class;
 493:         GtkMozEmbedClass *moz_embed_class;
 494: 
 495:         kz_gecko_embed_parent_class = (GtkMozEmbedClass *)g_type_class_peek_parent (klass);
 496: 
 497:         gobject_class   = G_OBJECT_CLASS(klass);
 498:         widget_class    = GTK_WIDGET_CLASS(klass);
 499:         moz_embed_class = GTK_MOZ_EMBED_CLASS(klass);
 500: 
 501:         gobject_class->constructor  = constructor;
 502:         gobject_class->dispose      = dispose;
 503:         gobject_class->set_property = set_property;
 504:         gobject_class->get_property = get_property;
 505: 
 506:         // widget class
 507:         widget_class->realize         = kz_gecko_embed_realize;
 508:         widget_class->unrealize       = kz_gecko_embed_unrealize;
 509:         widget_class->size_allocate   = kz_gecko_embed_size_allocate;
 510:  
 511:         // GtkMozEmbedSignals
 512:         moz_embed_class->net_state_all   = kz_gecko_embed_net_state_all;
 513: #if 0
 514:         moz_embed_class->security_change     = kz_gecko_embed_security_change;
 515:         moz_embed_class->dom_mouse_out       = kz_gecko_embed_dom_mouse_out;
 516:         moz_embed_class->net_state           = kz_gecko_embed_net_state;
 517:         moz_embed_class->progress            = kz_gecko_embed_progress;
 518:         moz_embed_class->progress_all        = kz_gecko_embed_progress_all;
 519: #endif
 520:         moz_embed_class->destroy_brsr        = kz_gecko_embed_destroy_brsr;
 521: 
 522:         moz_embed_class->link_message        = kz_gecko_embed_link_message;
 523:         moz_embed_class->js_status           = kz_gecko_embed_js_status;
 524:         moz_embed_class->title               = kz_gecko_embed_title;
 525:         moz_embed_class->location            = kz_gecko_embed_location;
 526:         moz_embed_class->net_start           = kz_gecko_embed_net_start;
 527:         moz_embed_class->net_stop            = kz_gecko_embed_net_stop;
 528:         moz_embed_class->new_window          = kz_gecko_embed_new_window;
 529:         moz_embed_class->open_uri            = kz_gecko_embed_open_uri;
 530:         moz_embed_class->size_to             = kz_gecko_embed_size_to;
 531:         moz_embed_class->visibility          = kz_gecko_embed_visibility;
 532:         moz_embed_class->dom_key_press       = kz_gecko_embed_dom_key_press;
 533:         moz_embed_class->dom_key_down        = kz_gecko_embed_dom_key_down;
 534:         moz_embed_class->dom_key_up          = kz_gecko_embed_dom_key_up;
 535:         moz_embed_class->dom_mouse_down      = kz_gecko_embed_dom_mouse_down;
 536:         moz_embed_class->dom_mouse_up        = kz_gecko_embed_dom_mouse_up;
 537:         moz_embed_class->dom_mouse_click     = kz_gecko_embed_dom_mouse_click;
 538:         moz_embed_class->dom_mouse_dbl_click = kz_gecko_embed_dom_mouse_dbl_click;
 539:         moz_embed_class->dom_mouse_over      = kz_gecko_embed_dom_mouse_over;
 540: 
 541:         g_object_class_install_property
 542:                 (gobject_class,
 543:                  PROP_LOCATION,
 544:                  g_param_spec_string(
 545:                          "location",
 546:                          _("The URL"),
 547:                          _("The current URL"),
 548:                          NULL,
 549:                          (GParamFlags) G_PARAM_READWRITE));
 550:         g_type_class_add_private(gobject_class, sizeof(KzGeckoEmbedPrivate));
 551: }
 552: 
 553: static void
 554: kz_gecko_embed_init (KzGeckoEmbed *kzembed)
 555: {
 556:         gint i;
 557:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
 558: 
 559:         priv->location              = NULL;
 560:         priv->title                 = NULL;
 561:         priv->load_started          = 0;
 562:         priv->load_percent          = 0;
 563:         priv->bytes_loaded          = 0;
 564:         priv->max_bytes_loaded      = 0;
 565:         priv->is_loading            = FALSE;
 566:         priv->load_status_message   = NULL;
 567:         priv->wrapper               = NULL;
 568:         priv->size_inited           = FALSE;
 569:         priv->total_requests        = 0;
 570:         priv->cur_requests          = 0;
 571: 
 572:         for (i = 0; i < KZ_EMBED_LINK_GUARD; i++)
 573:         {
 574:                 priv->nav_links[i] = NULL;
 575:         }
 576: #ifdef USE_MIGEMO
 577:         priv->migemo_keyword = NULL;
 578: #endif
 579:         priv->last_highlight = NULL;
 580: 
 581:         load_uri(KZ_EMBED(kzembed), "about:blank");
 582: }
 583: 
 584: static GObject*
 585: constructor (GType                  type,
 586:              guint                  n_props,
 587:              GObjectConstructParam *props)
 588: {
 589:         GObject *object;
 590:         GObjectClass *klass = G_OBJECT_CLASS(kz_gecko_embed_parent_class);
 591: 
 592:         object = klass->constructor(type, n_props, props);
 593:         
 594:         return object;
 595: }
 596: 
 597: 
 598: static void
 599: dispose (GObject *object)
 600: {
 601:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (object);
 602: 
 603:         if (priv->location)
 604:                 g_free(priv->location);
 605:         priv->location = NULL;
 606:         
 607:         if (priv->title)
 608:                 g_free(priv->title);
 609:         priv->title = NULL;
 610: 
 611:         if (G_OBJECT_CLASS (kz_gecko_embed_parent_class)->dispose)
 612:                 G_OBJECT_CLASS (kz_gecko_embed_parent_class)->dispose(object);
 613: }
 614: 
 615: 
 616: static void
 617: set_property (GObject         *object,
 618:               guint            prop_id,
 619:               const GValue    *value,
 620:               GParamSpec      *pspec)
 621: {
 622:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (object);
 623:         switch (prop_id)
 624:         {
 625:         case PROP_LOCATION:
 626:                 priv->location = g_value_dup_string(value);
 627:                 break;
 628:         default:
 629:                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 630:                 break;
 631:         }
 632: }
 633: 
 634: 
 635: static void
 636: get_property (GObject         *object,
 637:               guint            prop_id,
 638:               GValue          *value,
 639:               GParamSpec      *pspec)
 640: {
 641:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (object);
 642: 
 643:         switch (prop_id)
 644:         {
 645:         case PROP_LOCATION:
 646:                 g_value_set_string(value, priv->location);
 647:                 break;
 648:         default:
 649:                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 650:                 break;
 651:         }
 652: }
 653: 
 654: 
 655: GtkWidget *
 656: kz_gecko_embed_new (void)
 657: {
 658:         return GTK_WIDGET(g_object_new(KZ_TYPE_GECKO_EMBED,
 659:                                        NULL));
 660: 
 661: }
 662: 
 663: static void
 664: kz_gecko_embed_realize (GtkWidget *widget)
 665: {
 666:         gboolean java = TRUE;
 667:         if (GTK_WIDGET_CLASS(kz_gecko_embed_parent_class)->realize)
 668:                 GTK_WIDGET_CLASS(kz_gecko_embed_parent_class)->realize(widget);
 669: 
 670:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE(widget);
 671: 
 672:         if (!priv->wrapper)
 673:         {
 674:                 priv->wrapper = new KzMozWrapper();
 675:                 nsresult rv = priv->wrapper->Init(KZ_GECKO_EMBED(widget));
 676:                 if (NS_FAILED(rv))
 677:                 {
 678:                         g_error("KzGeckoEmbed: Faild to init KzMozWrapper!");
 679:                 }
 680:                 else
 681:                 {
 682:                 }
 683:         }
 684:         KZ_CONF_GET("Global", "use_javascript", java, BOOL);
 685:         set_allow_javascript(KZ_EMBED(widget), java);
 686: }
 687: 
 688: 
 689: static void
 690: kz_gecko_embed_unrealize (GtkWidget *widget)
 691: {
 692:         KzGeckoEmbed *kzembed = KZ_GECKO_EMBED(widget);
 693: 
 694:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
 695:         priv->size_inited = FALSE;
 696: 
 697:         kz_gecko_embed_navigation_link_free(kzembed);
 698:         
 699:         if (GTK_WIDGET_CLASS(kz_gecko_embed_parent_class)->unrealize)
 700:                 GTK_WIDGET_CLASS(kz_gecko_embed_parent_class)->unrealize(widget);
 701: 
 702:         if (priv->wrapper)
 703:         {
 704:                 priv->wrapper->Destroy();
 705:                 delete priv->wrapper;
 706:                 priv->wrapper = NULL;
 707:         }
 708:         
 709: }
 710: 
 711: 
 712: static void
 713: kz_gecko_embed_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
 714: {
 715:         g_return_if_fail(GTK_IS_WIDGET(widget));
 716: 
 717:         if (!GTK_WIDGET_REALIZED(widget)) return;
 718: 
 719:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE(widget);
 720:         if (!priv->size_inited) 
 721:         {
 722:                 // for preventing invalid scroll position 
 723:                 // when new tab background opens with anchor (html#xx)  
 724:                 nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(priv->wrapper->mWebBrowser);
 725:                 baseWindow->SetPositionAndSize(0, 0,
 726:                                                allocation->width,
 727:                                                allocation->height,
 728:                                                PR_FALSE);
 729:         }
 730:         if (!GTK_WIDGET_MAPPED(widget))
 731:                 return;
 732:         
 733:         if (GTK_WIDGET_CLASS(kz_gecko_embed_parent_class)->size_allocate)
 734:                 GTK_WIDGET_CLASS(kz_gecko_embed_parent_class)->size_allocate(widget, allocation);
 735: 
 736:         priv->size_inited = TRUE;
 737: }
 738: 
 739: 
 740: static void
 741: load_uri (KzEmbed *kzembed, const gchar *url)
 742: {
 743:         gchar *start_page = NULL;
 744: 
 745:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
 746: 
 747:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
 748: 
 749:         if (url && *url)
 750:         {
 751:                 start_page = g_strdup(url);
 752:         }
 753:         else
 754:         {
 755:                 start_page = g_strdup("about:blank");
 756:         }
 757: 
 758:         gtk_moz_embed_load_url(GTK_MOZ_EMBED(kzembed), start_page);
 759: 
 760:         if (priv->location)
 761:                 g_free(priv->location);
 762:         priv->location = start_page;
 763: }
 764: 
 765: 
 766: static void
 767: view_source (KzEmbed *kzembed, const gchar *url)
 768: {
 769:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
 770:         KzMozWrapper *wrapper = priv->wrapper;
 771:         nsresult rv;
 772: 
 773:         nsCOMPtr<nsISupports> pageDescriptor;
 774:         rv = wrapper->GetPageDescriptor(getter_AddRefs(pageDescriptor));
 775:         if (!pageDescriptor || NS_FAILED(rv)) return;
 776: 
 777:         rv = wrapper->LoadDocument(pageDescriptor, 
 778:                                    nsIWebPageDescriptor::DISPLAY_AS_SOURCE);
 779:         if (NS_FAILED(rv)) return;
 780: 
 781:         // set history explicitly
 782:         nsCOMPtr<nsISHistory> sHistory;
 783:         rv = wrapper->GetSHistory(getter_AddRefs(sHistory));
 784:         if (NS_FAILED(rv) || !sHistory) return;
 785: 
 786:         nsCOMPtr<nsISHistoryInternal> sHistoryInternal;
 787:         sHistoryInternal = do_QueryInterface(sHistory);
 788: 
 789:         gchar *uri = g_strdup_printf("view-source:%s", url);
 790: 
 791:         nsCOMPtr<nsISHEntry> entry;
 792:         entry = do_CreateInstance(NS_SHENTRY_CONTRACTID);
 793: 
 794:         nsCOMPtr<nsIURI> aURI;
 795:         NewURI(getter_AddRefs(aURI), uri);
 796:         /* FIXME! set correct contentType */
 797:         nsEmbedCString contentType;
 798:         entry->SetURI(aURI);
 799:         sHistoryInternal->AddEntry(entry, PR_TRUE);
 800:         g_free(uri);
 801: }
 802: 
 803: 
 804: static gboolean
 805: is_loading (KzEmbed *kzembed)
 806: {
 807:         return KZ_IS_GECKO_EMBED(kzembed)
 808:                 ? KZ_GECKO_EMBED_GET_PRIVATE(kzembed)->is_loading
 809:                 : FALSE;
 810: }
 811: 
 812: 
 813: static const gchar *
 814: get_title (KzEmbed *kzembed)
 815: {
 816:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
 817:         return KZ_GECKO_EMBED_GET_PRIVATE(kzembed)->title;
 818: }
 819: 
 820: static gdouble
 821: get_progress (KzEmbed *kzembed)
 822: {
 823:         gdouble progress;
 824: 
 825:         g_return_val_if_fail(KZ_GECKO_EMBED(kzembed), 0.0);
 826: 
 827:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
 828:         if (priv->total_requests <= 0 ||
 829:             priv->cur_requests <= 0)
 830:         {
 831:                 return 0.0;
 832:         }
 833: 
 834:         progress = (gdouble) priv->cur_requests
 835:                 / (gdouble) priv->total_requests;
 836: 
 837:         return (progress > 1.0) ? 1.0 : progress;
 838: }
 839: 
 840: 
 841: static const gchar *
 842: get_location (KzEmbed *kzembed)
 843: {
 844:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
 845: 
 846:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
 847: 
 848:         if (priv->location != NULL &&
 849:             !strncmp(priv->location, "about:blank", 11))
 850:         {
 851:                 return "";
 852:         }
 853: 
 854:         return priv->location;
 855: }
 856: 
 857: static void
 858: kz_gecko_embed_destroy_brsr (GtkMozEmbed *embed)
 859: {
 860:         g_return_if_fail(KZ_IS_GECKO_EMBED(embed));
 861: 
 862:         gtk_widget_destroy(GTK_WIDGET(embed));
 863: }
 864: 
 865: 
 866: static void
 867: kz_gecko_embed_link_message (GtkMozEmbed *embed)
 868: {
 869:         g_return_if_fail(KZ_IS_GECKO_EMBED(embed));
 870: 
 871:         gchar *link_message = gtk_moz_embed_get_link_message(GTK_MOZ_EMBED(embed));
 872:         g_signal_emit_by_name(embed, "kz-link-message", link_message);
 873:         g_free(link_message);
 874: 
 875:         if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->link_message)
 876:                 ((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->link_message(embed);
 877: }
 878: 
 879: static void
 880: kz_gecko_embed_js_status (GtkMozEmbed *embed)
 881: {
 882:         g_return_if_fail(KZ_IS_GECKO_EMBED(embed));
 883: 
 884:         g_signal_emit_by_name(embed, "kz-js-status");
 885: 
 886:         if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->js_status)
 887:                 ((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->js_status(embed);
 888: }
 889: 
 890: static void
 891: kz_gecko_embed_title (GtkMozEmbed *embed)
 892: {
 893:         g_return_if_fail(KZ_IS_GECKO_EMBED(embed));
 894: 
 895:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE(embed);
 896: 
 897:         g_free(priv->title);
 898: 
 899:         priv->title = gtk_moz_embed_get_title(embed);
 900: 
 901:         g_signal_emit_by_name(embed, "kz-title", priv->title);
 902: 
 903:         if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->title)
 904:                 ((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->title(embed);
 905: }
 906: 
 907: static void
 908: kz_gecko_embed_location (GtkMozEmbed *embed)
 909: {
 910:         g_return_if_fail(KZ_IS_GECKO_EMBED(embed));
 911: 
 912:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE(embed);
 913: 
 914:         if (priv->location)
 915:                 g_free(priv->location);
 916:         priv->location = gtk_moz_embed_get_location(embed);
 917: 
 918:         g_signal_emit_by_name(embed, "kz-location", priv->location);
 919: 
 920:         if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->location)
 921:                 ((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->location(embed);
 922: }
 923: 
 924: 
 925: static void
 926: kz_gecko_embed_net_start (GtkMozEmbed *embed)
 927: {
 928:         KzGeckoEmbed *kzembed = KZ_GECKO_EMBED(embed);
 929: 
 930:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
 931: 
 932:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
 933: 
 934:         priv->is_loading = TRUE;
 935: 
 936:         /* First free previous link */
 937:         kz_gecko_embed_navigation_link_free(kzembed);
 938: 
 939:         g_signal_emit_by_name(embed, "kz-net-start");
 940: 
 941:         if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->net_start)
 942:                 ((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->net_start(embed);
 943: }
 944: 
 945: static void
 946: net_stop_proccess (KzGeckoEmbed *kzembed)
 947: {
 948:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
 949: 
 950:         if (!priv->wrapper) return;
 951:         
 952:         gchar *cache = g_strconcat("file://", KZ_GET_HISTORY_DIR, NULL);
 953:         const gchar *location = get_location(KZ_EMBED(kzembed));
 954:         if (location && 
 955:             (g_str_has_prefix(location, "http:") || 
 956:              g_str_has_prefix(location, "https:") || 
 957:              g_str_has_prefix(location, "history-search:") || 
 958:              g_str_has_prefix(location, "file:")) &&
 959:             !g_str_has_prefix(location, cache))
 960:         {
 961:                 //get the last modification time
 962:                 nsCOMPtr<nsIDOMDocument> domDoc;
 963:                 priv->wrapper->GetMainDomDocument(getter_AddRefs(domDoc));
 964:                 nsCOMPtr<nsIDOMNSDocument> doc = do_QueryInterface(domDoc);
 965:                 nsEmbedString value;
 966:                 doc->GetLastModified(value);
 967: 
 968:                 nsEmbedCString cValue;
 969:                 NS_UTF16ToCString(value,
 970:                                   NS_CSTRING_ENCODING_UTF8, cValue);
 971:                 nsTime lm (cValue.get(), PR_TRUE);
 972:                 GTime last_modified = (PRTime)lm / PR_USEC_PER_SEC;
 973: 
 974:                 nsCOMPtr<nsIURI> inURI;
 975:                 nsEmbedCString sURI;
 976:                 nsresult rv;
 977: 
 978:                 rv = priv->wrapper->GetDocumentUrl(sURI);
 979:                 const gchar *uri = sURI.get();
 980:                 rv = NewURI(getter_AddRefs(inURI), uri);
 981: 
 982:                 if ((!last_modified || (history_get_last_modified(uri) < last_modified)) &&
 983:                     !g_str_has_prefix(location, "history-search:"))
 984:                 {
 985:                         gboolean store_cache;
 986:                         KZ_CONF_GET("History", "store_cache", store_cache, BOOL);
 987:                         if (store_cache)
 988:                         {
 989:                                 gchar *filename;
 990:                                 filename = kz_gecko_embed_store_history_file(kzembed);
 991:                                 if (filename)
 992:                                         g_free(filename);
 993:                         }
 994: 
 995:                         if (KZ_GET_SEARCH)
 996:                         {
 997:                                 const gchar *title = get_title(KZ_EMBED(kzembed));
 998:         
 999:                                 nsCOMPtr<nsIDOMNode> node = do_QueryInterface(domDoc);
1000:                                 nsCOMPtr<nsIDOMSerializer> serializer;
1001:                                 serializer = do_CreateInstance(NS_XMLSERIALIZER_CONTRACTID, &rv);
1002:                                 if (serializer)
1003:                                 {
1004:                                         serializer->SerializeToString(node, value);
1005:                                         NS_UTF16ToCString (value, NS_CSTRING_ENCODING_UTF8, cValue);
1006:                                 }
1007:                                 kz_search_register_document(KZ_GET_SEARCH, uri, title, cValue.get(), last_modified);
1008: #ifdef WITH_ANTHY_TRAINER
1009:                                 KzSearch *search = kz_search_new("anthy-trainer");
1010:                                 if (search)
1011:                                 {
1012:                                         kz_search_register_document(search, uri, title, cValue.get(), last_modified);
1013:                                         g_object_unref(search);
1014:                                 }
1015: #endif
1016:                         }
1017:                 }
1018:         }
1019:         
1020:         g_free(cache);
1021: }
1022: 
1023: static void
1024: kz_gecko_embed_net_stop (GtkMozEmbed *embed)
1025: {
1026:         g_return_if_fail(KZ_IS_GECKO_EMBED(embed));
1027: 
1028:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (embed);
1029:         priv->is_loading = FALSE;
1030: 
1031:         if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->net_stop)
1032:                 ((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->net_stop(embed);
1033: 
1034:         net_stop_proccess(KZ_GECKO_EMBED(embed));
1035: 
1036:         g_signal_emit_by_name(embed, "kz-net-stop");
1037: }
1038: 
1039: static void
1040: kz_gecko_embed_net_state_all (GtkMozEmbed *embed, const char *aURI,
1041:                             gint state, guint status)
1042: {
1043:         KzGeckoEmbed *kzembed = KZ_GECKO_EMBED(embed);
1044: 
1045:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
1046: 
1047:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1048:         if (state & GTK_MOZ_EMBED_FLAG_IS_NETWORK)
1049:         {
1050:                 priv->total_requests = 0;
1051:                 priv->cur_requests = 0;
1052: #if 0
1053:                 if (state & GTK_MOZ_EMBED_FLAG_START)
1054:                 {
1055:                 }
1056:                 else if (state & EMBED_STATE_STOP)
1057:                 {
1058:                         priv->total_requests = 0;
1059:                         priv->cur_requests = 0;
1060:                 } 
1061: #endif
1062:         }
1063:         if (state & GTK_MOZ_EMBED_FLAG_IS_REQUEST)
1064:         {
1065:                 if (state & GTK_MOZ_EMBED_FLAG_START)
1066:                         priv->total_requests++;
1067:                 else if (state & GTK_MOZ_EMBED_FLAG_STOP)
1068:                         priv->cur_requests++;
1069:         }
1070: 
1071:         gdouble ratio = get_progress(KZ_EMBED(embed));
1072:         g_signal_emit_by_name(embed, "kz-progress", ratio);
1073: 
1074:         if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->net_state_all)
1075:                 ((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->net_state_all(embed, aURI, state, status);
1076: }
1077: 
1078: static void 
1079: cb_embed_destroy_browser (GtkMozEmbed *embed, GtkWidget *transient_window)
1080: {
1081:         gtk_widget_destroy(GTK_WIDGET(transient_window));
1082: }
1083: 
1084: static void
1085: kz_gecko_embed_new_window (GtkMozEmbed *embed, GtkMozEmbed **newEmbed,
1086:                            guint chromemask)
1087: {
1088:         if ((chromemask & GTK_MOZ_EMBED_FLAG_OPENASCHROME) != 0)
1089:         {
1090:                 /* FIXME! this is ad hoc. */
1091:                 GtkWidget *newWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1092: 
1093:                 gtk_window_set_transient_for(GTK_WINDOW(newWindow),
1094:                                              GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(embed))));
1095:                 *newEmbed = GTK_MOZ_EMBED(kz_gecko_embed_new());
1096:                 g_signal_connect(*newEmbed,"destroy",
1097:                                  G_CALLBACK(cb_embed_destroy_browser),
1098:                                  newWindow);
1099:                 gtk_container_add(GTK_CONTAINER(newWindow),
1100:                                   GTK_WIDGET(*newEmbed));
1101:                 gtk_widget_show(newWindow);
1102:         }
1103:         else
1104:         {
1105:                 g_signal_emit_by_name(embed, "kz-new-window", newEmbed);
1106:         }
1107: }
1108: 
1109: static gint
1110: kz_gecko_embed_open_uri (GtkMozEmbed *embed, const char *uri)
1111: {
1112:         gint ret = FALSE;
1113: 
1114:         g_signal_emit_by_name(embed, "kz-open-uri", uri, &ret);
1115: 
1116:         if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->open_uri)
1117:                 ret = ((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->open_uri(embed, uri);
1118: 
1119: #if 0
1120:         if (!strncmp(uri, "mailto:", 7))
1121:         {
1122:                 return TRUE;
1123:         }
1124: #endif
1125: 
1126:         return ret;
1127: }
1128: 
1129: static void
1130: kz_gecko_embed_size_to (GtkMozEmbed *embed, gint width, gint height)
1131: {
1132:         gtk_widget_set_size_request(GTK_WIDGET(embed), width, height);
1133:         gtk_widget_queue_resize(GTK_WIDGET(embed));
1134: 
1135:         g_signal_emit_by_name(embed, "kz-size-to", width, height);
1136: }
1137: 
1138: static gint
1139: kz_gecko_embed_dom_key_down (GtkMozEmbed *embed, gpointer event)
1140: {
1141:         KzEmbedEventKey *kzevent;
1142:         gint ret = FALSE;
1143: 
1144:         kz_gecko_embed_get_key_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
1145:         g_signal_emit_by_name(embed, "kz-dom-key-down",
1146:                               kzevent, &ret);
1147:         kz_embed_event_free((KzEmbedEvent *) kzevent);
1148: 
1149:         return ret;
1150: }
1151: 
1152: static gint
1153: kz_gecko_embed_dom_key_up (GtkMozEmbed *embed, gpointer event)
1154: {
1155:         KzEmbedEventKey *kzevent;
1156:         gint ret = FALSE;
1157: 
1158:         kz_gecko_embed_get_key_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
1159:         g_signal_emit_by_name(embed, "kz-dom-key-up",
1160:                               kzevent, &ret);
1161:         kz_embed_event_free((KzEmbedEvent *) kzevent);
1162: 
1163:         return ret;
1164: }
1165: 
1166: static gint
1167: kz_gecko_embed_dom_key_press (GtkMozEmbed *embed, gpointer event)
1168: {
1169:         KzEmbedEventKey *kzevent;
1170:         gint ret = FALSE;
1171: 
1172:         kz_gecko_embed_get_key_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
1173:         g_signal_emit_by_name(embed, "kz-dom-key-press",
1174:                               kzevent, &ret);
1175:         kz_embed_event_free((KzEmbedEvent *) kzevent);
1176: 
1177:         return ret;
1178: }
1179: 
1180: static gboolean
1181: kz_gecko_embed_dom_mouse_down (GtkMozEmbed *embed, gpointer event)
1182: {
1183:         KzEmbedEventMouse *kzevent;
1184:         gboolean ret = FALSE;
1185: 
1186:         kz_gecko_embed_get_mouse_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
1187: 
1188:         g_signal_emit_by_name(embed, "kz-dom-mouse-down",
1189:                               kzevent, &ret);
1190:         kz_embed_event_free((KzEmbedEvent *) kzevent);
1191: 
1192:         return ret;
1193: }
1194: 
1195: static gboolean
1196: kz_gecko_embed_dom_mouse_up (GtkMozEmbed *embed, gpointer event)
1197: {
1198:         KzEmbedEventMouse *kzevent;
1199:         gboolean ret = FALSE;
1200: 
1201:         kz_gecko_embed_get_mouse_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
1202:         g_signal_emit_by_name(embed, "kz-dom-mouse-up",
1203:                               kzevent, &ret);
1204:         kz_embed_event_free((KzEmbedEvent *) kzevent);
1205: 
1206:         return ret;
1207: }
1208: 
1209: static gboolean
1210: kz_gecko_embed_dom_mouse_click (GtkMozEmbed *embed, gpointer event)
1211: {
1212:         KzEmbedEventMouse *kzevent;
1213:         gboolean ret = FALSE;
1214: 
1215:         kz_gecko_embed_get_mouse_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
1216:         g_signal_emit_by_name(embed, "kz-dom-mouse-click",
1217:                               kzevent, &ret);
1218:         kz_embed_event_free((KzEmbedEvent *) kzevent);
1219: 
1220:         return ret;
1221: }
1222: 
1223: static gboolean
1224: kz_gecko_embed_dom_mouse_dbl_click (GtkMozEmbed *embed, gpointer event)
1225: {
1226:         KzEmbedEventMouse *kzevent;
1227:         gboolean ret = FALSE;
1228: 
1229:         kz_gecko_embed_get_mouse_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
1230:         g_signal_emit_by_name(embed, "kz-dom-mouse-dbl-click",
1231:                               kzevent, &ret);
1232:         kz_embed_event_free((KzEmbedEvent *) kzevent);
1233: 
1234:         return ret;
1235: }
1236: 
1237: static
1238: gboolean kz_gecko_embed_dom_mouse_over (GtkMozEmbed *embed, gpointer event)
1239: {
1240:         KzEmbedEventMouse *kzevent;
1241:         gboolean ret = FALSE;
1242: 
1243:         kz_gecko_embed_get_mouse_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
1244:         g_signal_emit_by_name(embed, "kz-dom-mouse-over",
1245:                               kzevent, &ret);
1246:         kz_embed_event_free((KzEmbedEvent *) kzevent);
1247: 
1248:         return ret;
1249: }
1250: 
1251: static void
1252: kz_gecko_embed_visibility (GtkMozEmbed *embed, gboolean visibility)
1253: {
1254:         GtkWidget *parent = NULL;
1255: 
1256:         parent = gtk_widget_get_parent(GTK_WIDGET(embed));
1257:         g_return_if_fail(parent != NULL);
1258:         
1259:         g_object_set(embed, "visible", visibility, NULL);
1260:         g_object_set(parent, "visible", visibility, NULL);
1261: }
1262: 
1263: #if 0
1264: static void
1265: kz_gecko_embed_security_change (GtkMozEmbed *embed,
1266:                               gpointer request,
1267:                               guint state)
1268: {
1269:         if (kz_gecko_embed_parent_class->security_change)
1270:                 kz_gecko_embed_parent_class->security_change(embed, request, state);
1271: }
1272: #endif
1273: 
1274: static gboolean
1275: can_cut_selection (KzEmbed *kzembed)
1276: {
1277:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
1278: 
1279:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1280:         if (!priv->wrapper) return TRUE;
1281: 
1282:         PRBool retval;
1283:         nsresult rv = priv->wrapper->CanCutSelection(&retval);
1284: 
1285:         if (NS_FAILED(rv)) return FALSE;
1286: 
1287:         return retval;
1288: }
1289: 
1290: static gboolean
1291: can_copy_selection (KzEmbed *kzembed)
1292: {
1293:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
1294: 
1295:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1296:         if (!priv->wrapper) return TRUE;
1297: 
1298:         PRBool retval;
1299:         nsresult rv = priv->wrapper->CanCopySelection(&retval);
1300: 
1301:         if (NS_FAILED(rv)) return FALSE;
1302: 
1303:         return retval;
1304: }
1305: 
1306: static gboolean
1307: can_paste (KzEmbed *kzembed)
1308: {
1309:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
1310: 
1311:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1312:         if (!priv->wrapper) return TRUE;
1313: 
1314:         PRBool retval;
1315:         nsresult rv = priv->wrapper->CanPaste(&retval);
1316: 
1317:         if (NS_FAILED(rv)) return FALSE;
1318: 
1319:         return retval;
1320: }
1321: 
1322: static void
1323: cut_selection (KzEmbed *kzembed)
1324: {
1325:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
1326:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1327:         g_return_if_fail(priv->wrapper);
1328: 
1329:         priv->wrapper->CutSelection();
1330: }
1331: 
1332: static void
1333: copy_selection (KzEmbed *kzembed)
1334: {
1335:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
1336:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1337:         g_return_if_fail(priv->wrapper);
1338: 
1339:         priv->wrapper->CopySelection();
1340: }
1341: 
1342: static void
1343: paste (KzEmbed *kzembed)
1344: {
1345:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
1346:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1347:         g_return_if_fail(priv->wrapper);
1348: 
1349:         priv->wrapper->Paste();
1350: }
1351: 
1352: static void
1353: select_all (KzEmbed *kzembed)
1354: {
1355:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
1356:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1357:         g_return_if_fail(priv->wrapper);
1358: 
1359:         priv->wrapper->SelectAll();
1360: }
1361: 
1362: static gchar *
1363: get_selection_string(KzEmbed *kzembed)
1364: {
1365:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
1366: 
1367:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1368:         if (!priv->wrapper) return NULL;
1369: 
1370:         nsresult rv;
1371: 
1372:         nsCOMPtr<nsISelection> selection;
1373:         rv = priv->wrapper->GetSelection(getter_AddRefs(selection));
1374:         if (!selection) return NULL;
1375: 
1376:         PRUnichar *string;
1377:         rv = selection->ToString(&string);
1378:         
1379:         nsEmbedCString str;
1380:         NS_UTF16ToCString(nsEmbedString(string),
1381:                           NS_CSTRING_ENCODING_UTF8, str);
1382: 
1383:         return g_strdup (str.get());
1384: }
1385: 
1386: static gchar *
1387: get_html_with_contents (KzEmbed *kzembed, const gchar *storedir)
1388: {
1389:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
1390: 
1391:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1392:         if (!priv->wrapper) return NULL;
1393: 
1394:         nsresult rv;
1395: 
1396:         nsCOMPtr<nsISelection> selection;
1397:         rv = priv->wrapper->GetSelection(getter_AddRefs(selection));
1398:         if (!selection) return NULL;
1399: 
1400:         nsEmbedString string;
1401:         rv = priv->wrapper->GetHtmlWithContents(selection, 
1402:                                                 storedir,
1403:                                                 string);
1404:         if (NS_FAILED(rv)) return NULL;
1405: 
1406:         nsEmbedCString str;
1407:         NS_UTF16ToCString(nsEmbedString(string),
1408:                           NS_CSTRING_ENCODING_UTF8, str);
1409:         return g_strdup(str.get());
1410: }
1411: 
1412: #if USE_MIGEMO
1413: static gboolean
1414: kz_gecko_embed_get_body_string(KzGeckoEmbed *mozembed, gchar **body_string,
1415:                              gboolean backward, gboolean whole)
1416: {
1417:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (mozembed);
1418:         nsEmbedString text;
1419:         nsresult rv;
1420: 
1421:         if (whole)
1422:                 rv = priv->wrapper->GetBodyString(text);
1423:         else
1424:                 rv = priv->wrapper->GetStringSelection(text, backward);
1425:         if (NS_FAILED(rv))
1426:                 return FALSE;
1427:         
1428:         nsEmbedCString str;
1429:         NS_UTF16ToCString(text,
1430:                           NS_CSTRING_ENCODING_UTF8, str);
1431:         *body_string = g_strdup(str.get());
1432:         return TRUE;
1433: }
1434: 
1435: static void
1436: set_migemo_keyword(KzGeckoEmbed *mozembed, const char *keyword,
1437:                    gchar *body_string, gboolean backward)
1438: {
1439:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (mozembed);
1440:         g_free(priv->migemo_keyword);
1441:         priv->migemo_keyword =
1442:                 kz_migemo_get_matched_text(KZ_GET_MIGEMO, body_string,
1443:                                            keyword, backward);
1444: }
1445: #endif
1446: 
1447: static gboolean
1448: kz_gecko_embed_unhighlight_word (KzEmbed *kzembed, const char *word)
1449: {
1450:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1451:         if (!priv->wrapper) return FALSE;
1452: 
1453:         KzMozWrapper *wrapper = priv->wrapper;
1454: 
1455:         nsresult rv;
1456:         nsCOMPtr<nsIFind> finder;
1457:         finder = do_CreateInstance("@mozilla.org/embedcomp/rangefind;1", &rv);
1458: 
1459:         if (NS_FAILED(rv)) return FALSE;
1460: 
1461:         nsEmbedString string;
1462:         NS_CStringToUTF16(nsEmbedCString(word),
1463:                           NS_CSTRING_ENCODING_UTF8, string);
1464:         const PRUnichar *u_word;
1465:         NS_StringGetData(string, &u_word);
1466:         
1467:         nsCOMPtr<nsIDOMDocument> domDoc;
1468:         rv = wrapper->GetMainDomDocument(getter_AddRefs(domDoc));
1469:         if (NS_FAILED(rv) || !domDoc) return FALSE;
1470:         
1471:         nsCOMPtr<nsIDOMDocumentRange> docRange = do_QueryInterface(domDoc);
1472:         if (!docRange) return FALSE;
1473: 
1474:         nsCOMPtr<nsIDOMRange> searchRange;
1475:         nsCOMPtr<nsIDOMRange> startRange;
1476:         nsCOMPtr<nsIDOMRange> endRange;
1477:         rv = wrapper->SetHighlightRange(getter_AddRefs(searchRange),
1478:                                         getter_AddRefs(startRange),
1479:                                         getter_AddRefs(endRange));
1480:         nsCOMPtr<nsIDOMRange> retRange;
1481: 
1482:         while (finder->Find(u_word, searchRange, startRange, endRange, getter_AddRefs(retRange)) == NS_OK)
1483:         {
1484:                 if (!retRange) break;
1485: 
1486:                 nsCOMPtr<nsIDOMNode> startContainer;
1487:                 retRange->GetStartContainer(getter_AddRefs(startContainer));
1488: 
1489:                 nsCOMPtr<nsIDOMNode> elm;
1490:                 startContainer->GetParentNode(getter_AddRefs(elm));
1491: 
1492:                 char *attr = NULL;
1493:                 wrapper->GetAttributeFromNode(elm, "id", &attr);
1494:                 if (elm && attr && !g_ascii_strcasecmp(attr, "kazehakase-search"))
1495:                 {
1496:                         nsCOMPtr<nsIDOMDocumentFragment> flag;
1497:                         nsCOMPtr<nsIDOMNode> next;
1498:                         nsCOMPtr<nsIDOMNode> parent;
1499: 
1500:                         domDoc->CreateDocumentFragment(getter_AddRefs(flag));
1501:                         nsCOMPtr<nsIDOMNode> flagNode;
1502:                         flagNode = do_QueryInterface(flag);
1503: 
1504:                         elm->GetNextSibling(getter_AddRefs(next));
1505:                         elm->GetParentNode(getter_AddRefs(parent));
1506: 
1507:                         nsCOMPtr<nsIDOMNode> child;
1508:                         while (elm->GetFirstChild(getter_AddRefs(child)) == NS_OK)
1509:                         {
1510:                                 if (!child) break;
1511:                                 nsCOMPtr<nsIDOMNode> newNode;
1512:                                 flagNode->AppendChild(child, getter_AddRefs(newNode));
1513:                         }
1514: 
1515:                         docRange->CreateRange(getter_AddRefs(startRange));
1516:                         startRange->SetStartAfter(elm);
1517: 
1518:                         nsCOMPtr<nsIDOMNode> tmp;
1519:                         parent->RemoveChild(elm, getter_AddRefs(tmp));
1520:                         parent->InsertBefore(flagNode, next, getter_AddRefs(tmp));
1521:                 }
1522:                 else
1523:                 {
1524:                         nsCOMPtr<nsIDOMNode> endContainer;
1525:                         retRange->GetEndContainer(getter_AddRefs(endContainer));
1526:                         PRInt32 endOffset;
1527:                         retRange->GetEndOffset(&endOffset);
1528:                         docRange->CreateRange(getter_AddRefs(startRange));
1529:                         startRange->SetStart(endContainer, endOffset);
1530:                 }
1531:                 startRange->Collapse(PR_TRUE);
1532:         }
1533: 
1534:         return TRUE;
1535: }
1536: 
1537: 
1538: // this function is drawn upon 
1539: //   toolkit/components/typeaheadfind/content/findBar.js in firefox-1.0+.
1540: static gboolean
1541: kz_gecko_embed_highlight_word (KzEmbed *kzembed, const char *word)
1542: {
1543:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1544:         if (priv->last_highlight)
1545:         {
1546:                 if (!strcmp(priv->last_highlight, word))
1547:                         return TRUE;
1548:                 kz_gecko_embed_unhighlight_word (kzembed, priv->last_highlight);
1549:                 g_free(priv->last_highlight);
1550:         }
1551:         
1552:         priv->last_highlight = g_strdup(word);
1553: 
1554:         nsresult rv;
1555:         nsCOMPtr<nsIFind> finder;
1556:         finder = do_CreateInstance("@mozilla.org/embedcomp/rangefind;1", &rv);
1557: 
1558:         if (NS_FAILED(rv)) return FALSE;
1559: 
1560:         nsEmbedString string;
1561:         NS_CStringToUTF16(nsEmbedCString(word),
1562:                           NS_CSTRING_ENCODING_UTF8, string);
1563:         const PRUnichar *u_word;
1564:         NS_StringGetData(string, &u_word);
1565:         
1566:         nsCOMPtr<nsIDOMDocument> domDoc;
1567:         rv = priv->wrapper->GetMainDomDocument(getter_AddRefs(domDoc));
1568:         if (NS_FAILED(rv) || !domDoc) return FALSE;
1569: 
1570: 
1571:         nsCOMPtr<nsIDOMRange> searchRange;
1572:         nsCOMPtr<nsIDOMRange> startRange;
1573:         nsCOMPtr<nsIDOMRange> endRange;
1574:         rv = priv->wrapper->SetHighlightRange(getter_AddRefs(searchRange),
1575:                                                              getter_AddRefs(startRange),
1576:                                                              getter_AddRefs(endRange));
1577: 
1578:         const PRUnichar span[]          = { 's', 'p', 'a', 'n' ,'\0' };
1579:         const PRUnichar style[]         = { 's', 't', 'y', 'l' ,'e', '\0' };
1580:         const PRUnichar id[]            = { 'i', 'd', '\0' };
1581:         const PRUnichar sc[]            = { ';', '\0' };
1582:         const PRUnichar bg_color[]      = { 'b', 'a', 'c', 'k' ,'g', 'r', 
1583:                                             'o', 'u', 'n', 'd', '-', 'c',
1584:                                             'o', 'l', 'o', 'r', ':', '\0' };
1585:         const PRUnichar kazehakase_id[] = { 'k', 'a', 'z', 'e' ,'h', 'a', 
1586:                                             'k', 'a', 's', 'e', '-', 's',
1587:                                             'e', 'a', 'r', 'c', 'h', '\0' };
1588: 
1589:         nsEmbedCString cColor("#ffff00");
1590:         nsEmbedString uColor;
1591:         NS_CStringToUTF16(cColor, NS_CSTRING_ENCODING_UTF8, uColor);
1592:         nsEmbedString color(bg_color);
1593:         color += uColor;
1594:         color += sc;
1595:         nsCOMPtr<nsIDOMElement> baseElm;
1596:         domDoc->CreateElement(nsEmbedString(span), getter_AddRefs(baseElm));
1597:         baseElm->SetAttribute(nsEmbedString(style), color);
1598:         baseElm->SetAttribute(nsEmbedString(id), nsEmbedString(kazehakase_id));
1599:         nsCOMPtr<nsIDOMNode> baseNode = do_QueryInterface(baseElm);
1600: 
1601:         nsCOMPtr<nsIDOMRange> retRange;
1602: 
1603:         while (finder->Find(u_word, searchRange, startRange, endRange, getter_AddRefs(retRange)) == NS_OK)
1604:         {
1605:                 if (!retRange) break;
1606: 
1607:                 nsCOMPtr<nsIDOMNode> node;
1608:                 baseNode->CloneNode(PR_TRUE, getter_AddRefs(node));
1609: 
1610:                 nsCOMPtr<nsIDOMNode> startContainer;
1611:                 retRange->GetStartContainer(getter_AddRefs(startContainer));
1612: 
1613:                 PRInt32 startOffset, endOffset;
1614:                 retRange->GetStartOffset(&startOffset);
1615:                 retRange->GetEndOffset(&endOffset);
1616: 
1617:                 nsCOMPtr<nsIDOMDocumentFragment> flag;
1618:                 retRange->ExtractContents(getter_AddRefs(flag));
1619:                 if (!flag) continue;
1620: 
1621:                 nsCOMPtr<nsIDOMNode> flagNode;
1622:                 flagNode = do_QueryInterface(flag);
1623: 
1624:                 nsCOMPtr<nsIDOMText> text;
1625:                 text = do_QueryInterface(startContainer);
1626: 
1627:                 nsCOMPtr<nsIDOMText> before;
1628:                 text->SplitText(startOffset, getter_AddRefs(before));
1629:                 nsCOMPtr<nsIDOMNode> beforeNode;
1630:                 beforeNode = do_QueryInterface(before);
1631:                 
1632:                 nsCOMPtr<nsIDOMNode> parent;
1633:                 beforeNode->GetParentNode(getter_AddRefs(parent));
1634: 
1635:                 nsCOMPtr<nsIDOMNode> newNode;
1636:                 node->AppendChild(flagNode, getter_AddRefs(newNode));
1637:                 nsCOMPtr<nsIDOMNode> newParent;
1638:                 parent->InsertBefore(node, beforeNode, getter_AddRefs(newParent));
1639: 
1640:                 nsCOMPtr<nsIDOMDocument> doc;
1641:                 node->GetOwnerDocument(getter_AddRefs(doc));
1642:                 nsCOMPtr<nsIDOMDocumentRange> range;
1643:                 range = do_QueryInterface(doc);
1644: 
1645:                 range->CreateRange(getter_AddRefs(startRange));
1646: 
1647:                 nsCOMPtr<nsIDOMNodeList> list;
1648:                 node->GetChildNodes(getter_AddRefs(list));
1649: 
1650:                 PRUint32 length;
1651:                 list->GetLength(&length);
1652:                 startRange->SetStart(node, length);
1653:                 startRange->SetEnd(node, length);
1654:         }
1655: 
1656:         return TRUE;
1657: }
1658: 
1659:   
1660: static gboolean
1661: find (KzEmbed *kzembed, const char *keyword, gboolean backward)
1662: {
1663:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
1664:         g_return_val_if_fail(keyword, FALSE);
1665: 
1666:         nsCOMPtr<nsIWebBrowser> web;
1667:         gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(kzembed),
1668:                                         getter_AddRefs(web));
1669:         if (!web) return FALSE;
1670: 
1671: 
1672:         nsresult rv;
1673:         nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(web));
1674: #if USE_MIGEMO
1675:         KzGeckoEmbed *mozembed = KZ_GECKO_EMBED(kzembed);
1676:         gboolean use_migemo;
1677:         KZ_CONF_GET("Global", "use_migemo", use_migemo, BOOL);
1678: 
1679:         nsEmbedString str;
1680:         if (use_migemo)
1681:         {
1682:                 gchar *body_string;
1683:                 KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1684: 
1685:                 if (!kz_gecko_embed_get_body_string(mozembed, &body_string,
1686:                                                   backward, FALSE))
1687:                         goto START_SEARCH;
1688:                 set_migemo_keyword(mozembed, keyword, body_string, backward);
1689: 
1690:                 if (!priv->migemo_keyword)
1691:                 {
1692:                         g_free(body_string);
1693:                         if (!kz_gecko_embed_get_body_string(mozembed,
1694:                                                           &body_string,
1695:                                                           backward,
1696:                                                           TRUE))
1697:                                 goto START_SEARCH;
1698:                         set_migemo_keyword(mozembed, keyword,
1699:                                            body_string, backward);
1700:                 }
1701:                 
1702:                 if (priv->migemo_keyword)
1703:                 {
1704:                         NS_CStringToUTF16(nsEmbedCString(priv->migemo_keyword),
1705:                                           NS_CSTRING_ENCODING_UTF8, str);
1706:                 }
1707:                 else
1708:                 {
1709:                         NS_CStringToUTF16(nsEmbedCString(keyword),
1710:                                           NS_CSTRING_ENCODING_UTF8, str);
1711:                 }
1712:                 g_free(body_string);
1713:         }
1714:         else
1715:         {
1716:                 NS_CStringToUTF16(nsEmbedCString(keyword),
1717:                                   NS_CSTRING_ENCODING_UTF8, str);
1718:         }
1719:         finder->SetSearchString(str.get());
1720: START_SEARCH:
1721: #else   
1722:         nsEmbedString str;
1723:         NS_CStringToUTF16(nsEmbedCString(keyword),
1724:                           NS_CSTRING_ENCODING_UTF8, str);
1725:         finder->SetSearchString(str.get());
1726: #endif
1727:         finder->SetFindBackwards(backward);
1728:         finder->SetWrapFind(TRUE);
1729:         finder->SetEntireWord(TRUE);
1730:         finder->SetSearchFrames(TRUE);
1731:         finder->SetMatchCase(FALSE);
1732:         PRBool did_find;
1733:         rv = finder->FindNext(&did_find);
1734: 
1735:         return NS_SUCCEEDED(rv) && did_find ? TRUE : FALSE;
1736: }
1737: 
1738: static gboolean
1739: incremental_search (KzEmbed *kzembed, const char *keyword, gboolean backward)
1740: {
1741:         nsresult rv;
1742:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
1743:         g_return_val_if_fail(keyword, FALSE);
1744: 
1745:         if (strlen(keyword) == 0)
1746:                 return FALSE;
1747: 
1748:         nsCOMPtr<nsIWebBrowser> web;
1749:         gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(kzembed),
1750:                                         getter_AddRefs(web));
1751:         if (!web) return FALSE;
1752: 
1753:         nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(web));
1754: #if USE_MIGEMO
1755:         KzGeckoEmbed *mozembed = KZ_GECKO_EMBED(kzembed);
1756:         gboolean use_migemo;
1757:         KZ_CONF_GET("Global", "use_migemo", use_migemo, BOOL);
1758: 
1759:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1760:         nsCOMPtr<nsISelection> selection;
1761:         rv = priv->wrapper->GetSelection(getter_AddRefs(selection));
1762:         if (!selection) return FALSE;
1763: 
1764:         selection->RemoveAllRanges();
1765: 
1766:         nsEmbedString str;
1767:         if (use_migemo)
1768:         {
1769:                 gchar *body_string;
1770: 
1771:                 if (!kz_gecko_embed_get_body_string(mozembed, &body_string,
1772:                                                   backward, TRUE))
1773:                         goto START_SEARCH;
1774:                 set_migemo_keyword(mozembed, keyword, body_string, backward);
1775: 
1776:                 if (priv->migemo_keyword) 
1777:                 {
1778:                         NS_CStringToUTF16(nsEmbedCString(priv->migemo_keyword),
1779:                                           NS_CSTRING_ENCODING_UTF8, str);
1780:                 }
1781:                 else 
1782:                 {
1783:                         NS_CStringToUTF16(nsEmbedCString(keyword),
1784:                                           NS_CSTRING_ENCODING_UTF8, str);
1785:                 }
1786:                 g_free(body_string);
1787:         }
1788:         else
1789:         {
1790:                 NS_CStringToUTF16(nsEmbedCString(keyword),
1791:                                   NS_CSTRING_ENCODING_UTF8, str);
1792:         }
1793:         finder->SetSearchString(str.get());
1794: START_SEARCH:
1795: #else
1796:         nsEmbedString str;
1797:         NS_CStringToUTF16(nsEmbedCString(keyword),
1798:                           NS_CSTRING_ENCODING_UTF8, str);
1799:         finder->SetSearchString(str.get());
1800: #endif
1801:         finder->SetFindBackwards(backward);
1802:         finder->SetWrapFind(TRUE);
1803:         finder->SetEntireWord(TRUE);
1804:         finder->SetSearchFrames(TRUE);
1805:         finder->SetMatchCase(FALSE);
1806:         PRBool did_find;
1807:         rv = finder->FindNext(&did_find);
1808: 
1809:         // highlight search word
1810:         
1811:         gboolean use_highlight = FALSE;
1812:         KZ_CONF_GET("Global", "use_highlight", use_highlight, BOOL);
1813:         if (use_highlight)
1814:         {
1815:                 if (NS_SUCCEEDED(rv))
1816:                 {
1817:                         nsEmbedCString c_str;
1818:                         NS_UTF16ToCString(str, NS_CSTRING_ENCODING_UTF8, c_str);
1819:                         kz_gecko_embed_highlight_word(kzembed, c_str.get());
1820:                 }
1821:         }
1822: 
1823:         return NS_SUCCEEDED(rv) && did_find ? TRUE : FALSE;
1824: }
1825: 
1826: static gboolean
1827: selection_is_collapsed (KzEmbed *kzembed)
1828: {
1829:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), TRUE);
1830: 
1831:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1832:         if (!priv->wrapper) return TRUE;
1833: 
1834:         nsresult rv;
1835: 
1836:         nsCOMPtr<nsISelection> selection;
1837:         rv = priv->wrapper->GetSelection(getter_AddRefs(selection));
1838:         if (!selection) return TRUE;
1839: 
1840:         PRBool collapsed;
1841:         rv = selection->GetIsCollapsed(&collapsed);
1842:         if (NS_FAILED(rv)) return TRUE;
1843: 
1844:         return collapsed;
1845: }
1846: 
1847: 
1848: static gboolean
1849: get_links (KzEmbed *kzembed, GList **list, gboolean selected_only)
1850: {
1851:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
1852:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1853:         g_return_val_if_fail(priv->wrapper, FALSE);
1854:         g_return_val_if_fail(list, FALSE);
1855: 
1856:         // get selection
1857:         nsresult rv;
1858:         nsCOMPtr<nsISelection> selection;
1859:         rv = priv->wrapper->GetSelection(getter_AddRefs(selection));
1860:         if (NS_FAILED(rv)) return FALSE;
1861: 
1862:         // get all anchor nodes in the document.
1863:         nsCOMPtr<nsIDOMDocument> mainDoc;
1864:         rv = priv->wrapper->GetMainDomDocument(getter_AddRefs(mainDoc));
1865:         if (NS_FAILED(rv) || !mainDoc) return FALSE;
1866: 
1867:         // get main DOMWindow
1868:         nsCOMPtr<nsIDOMWindow> mainDOMWindow;
1869:         rv = priv->wrapper->GetDOMWindow(getter_AddRefs(mainDOMWindow));
1870:         if (NS_FAILED(rv)) return FALSE;
1871: 
1872:         rv = priv->wrapper->GetLinksFromWindow(mainDOMWindow,
1873:                                                          list,
1874:                                                          selection,
1875:                                                          selected_only);
1876: 
1877:         return NS_FAILED(rv) ? FALSE : TRUE;
1878: }
1879: 
1880: 
1881: static gboolean
1882: get_dest_anchors (KzEmbed *kzembed, GList **list)
1883: {
1884:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
1885:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
1886:         g_return_val_if_fail(priv->wrapper, FALSE);
1887:         g_return_val_if_fail(list, FALSE);
1888: 
1889:         // get all anchor nodes in the document.
1890:         nsCOMPtr<nsIDOMDocument> mainDoc;
1891:         nsresult rv = priv->wrapper->GetMainDomDocument(getter_AddRefs(mainDoc));
1892:         if (NS_FAILED(rv) || !mainDoc) return FALSE;
1893: 
1894:         // get main DOMWindow
1895:         nsCOMPtr<nsIDOMWindow> mainDOMWindow;
1896:         rv = priv->wrapper->GetDOMWindow(getter_AddRefs(mainDOMWindow));
1897:         if (NS_FAILED(rv)) return FALSE;
1898: 
1899:         rv = priv->wrapper->GetDestAnchorsFromWindow(mainDOMWindow,
1900:                                                      list);
1901: 
1902:         return NS_FAILED(rv) ? FALSE : TRUE;
1903: }
1904: 
1905: 
1906: glong
1907: kz_gecko_embed_get_key_event_info(KzGeckoEmbed *kzembed, gpointer event,
1908:                                 KzEmbedEventKey **info_ret)
1909: {
1910:         KzEmbedEventKey *info;
1911:         info = (KzEmbedEventKey *) kz_embed_event_new(KZ_EMBED_EVENT_KEY);
1912:         *info_ret = info;
1913: 
1914:         nsresult result;
1915: 
1916:         nsIDOMKeyEvent *aKeyEvent = (nsIDOMKeyEvent*) event;
1917: 
1918:         nsCOMPtr<nsIDOMEventTarget> OriginalTarget;
1919: 
1920:         nsCOMPtr<nsIDOMNSEvent> aEvent = do_QueryInterface(aKeyEvent);
1921:         if (!aEvent) return KZ_CONTEXT_NONE;
1922: 
1923:         PRUint32 code;
1924:         aKeyEvent->GetKeyCode(&code);
1925:         info->key = code;
1926: 
1927:         aKeyEvent->GetCharCode(&code);
1928:         info->char_code = code;
1929: 
1930:         PRBool mod_key;
1931:         info->modifier = 0;
1932:         aKeyEvent->GetAltKey(&mod_key);
1933:         if (mod_key) info->modifier |= KZ_ALT_KEY;
1934: 
1935:         aKeyEvent->GetShiftKey(&mod_key);
1936:         if (mod_key) info->modifier |= KZ_SHIFT_KEY;
1937: 
1938:         aKeyEvent->GetMetaKey(&mod_key);
1939:         if (mod_key) info->modifier |= KZ_META_KEY;
1940: 
1941:         aKeyEvent->GetCtrlKey(&mod_key);
1942:         if (mod_key) info->modifier |= KZ_CTRL_KEY;
1943: 
1944:         result = aEvent->GetOriginalTarget(getter_AddRefs(OriginalTarget));
1945: 
1946:         if (NS_FAILED(result) || !OriginalTarget) return KZ_CONTEXT_NONE;
1947: 
1948:         nsCOMPtr<nsIDOMNode> OriginalNode = do_QueryInterface(OriginalTarget);
1949:         if (!OriginalNode) return KZ_CONTEXT_NONE;
1950: 
1951:         nsEmbedString nodename;
1952:         OriginalNode->GetNodeName(nodename);
1953: 
1954:         nsEmbedCString cNodename;
1955:         NS_UTF16ToCString(nodename, NS_CSTRING_ENCODING_UTF8, cNodename);
1956: 
1957:         if (!g_ascii_strcasecmp(cNodename.get(), "xul:thumb") ||
1958:             !g_ascii_strcasecmp(cNodename.get(), "xul:slider"))
1959:         {
1960:                 return KZ_CONTEXT_NONE;
1961:         }
1962: 
1963:         nsCOMPtr<nsIDOMEventTarget> target;
1964:         result = aKeyEvent->GetTarget(getter_AddRefs(target));
1965:         if (NS_FAILED(result) || !target) return KZ_CONTEXT_NONE;
1966: 
1967:         return kz_gecko_embed_set_event_context(kzembed, target, (KzEmbedEvent *) info);
1968: }
1969: 
1970: 
1971: glong
1972: kz_gecko_embed_get_mouse_event_info(KzGeckoEmbed *kzembed, gpointer event,
1973:                                   KzEmbedEventMouse **info_ret)
1974: {
1975:         KzEmbedEventMouse *info;
1976:         info = (KzEmbedEventMouse *) kz_embed_event_new(KZ_EMBED_EVENT_MOUSE);
1977:         *info_ret = info;
1978: 
1979:         nsresult result;
1980: 
1981:         nsIDOMMouseEvent *aMouseEvent = (nsIDOMMouseEvent*)event;
1982: 
1983:         nsCOMPtr<nsIDOMEventTarget> OriginalTarget;
1984: 
1985:         nsCOMPtr<nsIDOMNSEvent> aEvent = do_QueryInterface(aMouseEvent);
1986:         if (!aEvent) return KZ_CONTEXT_NONE;
1987: 
1988:         PRUint16 button;
1989:         aMouseEvent->GetButton(&button);
1990:         info->button = button;
1991: 
1992:         PRBool mod_key;
1993:         info->modifier = 0;
1994:         aMouseEvent->GetAltKey(&mod_key);
1995:         if (mod_key) info->modifier |= KZ_ALT_KEY;
1996: 
1997:         aMouseEvent->GetShiftKey(&mod_key);
1998:         if (mod_key) info->modifier |= KZ_SHIFT_KEY;
1999: 
2000:         aMouseEvent->GetMetaKey(&mod_key);
2001:         if (mod_key) info->modifier |= KZ_META_KEY;
2002: 
2003:         aMouseEvent->GetCtrlKey(&mod_key);
2004:         if (mod_key) info->modifier |= KZ_CTRL_KEY;
2005: 
2006:         PRInt32 pos;
2007:         aMouseEvent->GetClientX(&pos);
2008:         info->x = pos;
2009:         aMouseEvent->GetClientY(&pos);
2010:         info->y = pos;
2011: 
2012:         result = aEvent->GetOriginalTarget(getter_AddRefs(OriginalTarget));
2013: 
2014:         if (NS_FAILED(result) || !OriginalTarget) return KZ_CONTEXT_NONE;
2015: 
2016:         nsCOMPtr<nsIDOMNode> OriginalNode = do_QueryInterface(OriginalTarget);
2017:         if (!OriginalNode) return KZ_CONTEXT_NONE;
2018: 
2019:         nsEmbedString nodename;
2020:         OriginalNode->GetNodeName(nodename);
2021: 
2022:         nsEmbedCString cNodename;
2023:         NS_UTF16ToCString(nodename, NS_CSTRING_ENCODING_UTF8, cNodename);
2024: 
2025:         if (!g_ascii_strcasecmp(cNodename.get(), "xul:thumb") ||
2026:             !g_ascii_strcasecmp(cNodename.get(), "xul:slider"))
2027:         {
2028:                 return KZ_CONTEXT_NONE;
2029:         }
2030: 
2031:         nsCOMPtr<nsIDOMEventTarget> target;
2032:         result = aMouseEvent->GetTarget(getter_AddRefs(target));
2033:         if (NS_FAILED(result) || !target) return KZ_CONTEXT_NONE;
2034: 
2035:         return kz_gecko_embed_set_event_context(kzembed, target, (KzEmbedEvent *) info);
2036: }
2037: 
2038: 
2039: static glong
2040: kz_gecko_embed_set_event_context (KzGeckoEmbed *kzembed,
2041:                                   nsIDOMEventTarget *target,
2042:                                   KzEmbedEvent *info)
2043: {
2044:         nsresult result;
2045:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2046:         KzMozWrapper *wrapper = priv->wrapper;
2047: 
2048:         g_return_val_if_fail(priv->wrapper, KZ_CONTEXT_NONE);
2049: 
2050:         nsCOMPtr<nsIDOMNode> node = do_QueryInterface(target);
2051:         if (!node) return KZ_CONTEXT_NONE;
2052: 
2053:         nsCOMPtr<nsIDOMDocument> domDoc;
2054:         result = node->GetOwnerDocument(getter_AddRefs(domDoc));
2055:         if (!NS_SUCCEEDED (result) || !domDoc) return KZ_CONTEXT_NONE;
2056: 
2057:         nsCOMPtr<nsIDOM3Node> domnode = do_QueryInterface(domDoc);
2058:         if(!domnode) return KZ_CONTEXT_NONE;
2059: 
2060:         nsCOMPtr<nsIDOMNSDocument> nsDoc = do_QueryInterface(domDoc);
2061:         if (!nsDoc) return KZ_CONTEXT_NONE;
2062: 
2063:         nsEmbedString spec;
2064:         domnode->GetBaseURI(spec);
2065: 
2066:         nsEmbedCString cSpec;
2067:         NS_UTF16ToCString(spec,
2068:                           NS_CSTRING_ENCODING_UTF8, cSpec);
2069: 
2070:         nsCOMPtr<nsIURI> baseURI;
2071:         NewURI(getter_AddRefs(baseURI), cSpec.get());
2072:         if (!baseURI) return KZ_CONTEXT_NONE;
2073: 
2074:         nsEmbedString mime;
2075:         nsDoc->GetContentType(mime);
2076: 
2077:         nsEmbedCString cMime;
2078:         NS_UTF16ToCString(mime, NS_CSTRING_ENCODING_UTF8, cMime);
2079:         if (!g_ascii_strcasecmp(cMime.get(), "text/xul"))  return KZ_CONTEXT_NONE;
2080: 
2081:         PRUint32 flags = KZ_CONTEXT_NONE;
2082: 
2083:         // check framed page
2084:         nsCOMPtr<nsIDOMDocument> mainDocument;
2085:         result = priv->wrapper->GetMainDomDocument (getter_AddRefs(mainDocument));
2086:         if (domDoc != mainDocument)
2087:         {
2088:                 flags |= KZ_CONTEXT_FRAME;
2089:                 nsEmbedCString url;
2090:                 baseURI->GetSpec(url);          
2091:                 info->frame_src = g_strdup(url.get());
2092:         }
2093:         
2094:         // check whether the node is in the selection or not
2095:         nsCOMPtr<nsISelection> selection;
2096:         result = priv->wrapper->GetSelection(getter_AddRefs(selection));
2097:         if (selection)
2098:         {
2099:                 PRBool contains;
2100:                 selection->ContainsNode(node, PR_TRUE, &contains);
2101:                 if (contains)
2102:                         flags |= KZ_CONTEXT_SELECTION;
2103:         }
2104: 
2105:         // Get other context
2106:         nsCOMPtr<nsIDOMHTMLElement> element;
2107: 
2108:         do {
2109:                 PRUint16 type;
2110:                 node->GetNodeType(&type);
2111: 
2112:                 element = do_QueryInterface(node);
2113:                 if (element)
2114:                 {
2115:                         nsEmbedString uTag;
2116:                         element->GetLocalName(uTag);
2117: 
2118:                         nsEmbedCString utf8_tag;
2119:                         NS_UTF16ToCString(uTag, NS_CSTRING_ENCODING_UTF8, utf8_tag);
2120: 
2121:                         if (!g_ascii_strcasecmp(utf8_tag.get(), "input"))
2122:                         {
2123:                                 flags |= KZ_CONTEXT_INPUT;
2124:                         }
2125:                         else if (!g_ascii_strcasecmp(utf8_tag.get(), "textarea"))
2126:                         {
2127:                                 flags |= KZ_CONTEXT_INPUT | KZ_CONTEXT_TEXTAREA;
2128:                                 info->element = (void*)element;
2129:                         }
2130:                         else if (!g_ascii_strcasecmp(utf8_tag.get(), "img"))
2131:                         {
2132:                                 flags |= KZ_CONTEXT_IMAGE;
2133: 
2134:                                 char *src = NULL;
2135:                                 wrapper->GetAttributeFromNode(node, "src", &src);
2136:                                 if (!src)  return KZ_CONTEXT_NONE;
2137: 
2138:                                 nsEmbedCString srca;
2139:                                 srca = nsEmbedCString(src);
2140: 
2141:                                 nsEmbedCString srcc,imgc;
2142:                                 
2143:                                 srcc = nsEmbedCString(src);
2144: 
2145:                                 result = baseURI->Resolve(srcc, imgc);
2146:                                 g_free(src);
2147: 
2148:                                 info->img = g_strdup(imgc.get());
2149: 
2150:                                 if (!info->img) return KZ_CONTEXT_NONE;
2151:                         }
2152:                         else
2153:                         {
2154:                                 flags |= KZ_CONTEXT_OTHER;
2155:                         }
2156: 
2157:                         nsCOMPtr<nsIDOMNamedNodeMap> attributes;
2158:                         node->GetAttributes(getter_AddRefs(attributes));
2159:                         if (attributes)
2160:                         {
2161:                                 nsCOMPtr<nsIDOMNode> hrefNode;
2162:                                 nsEmbedString href;
2163: 
2164:                                 NS_CStringToUTF16(nsEmbedCString("href"),
2165:                                                   NS_CSTRING_ENCODING_UTF8,
2166:                                                   href);
2167:                                 attributes->GetNamedItem(href, getter_AddRefs(hrefNode));
2168:                                 if (hrefNode)
2169:                                 {
2170:                                         gchar *link;
2171:                                         flags |= KZ_CONTEXT_LINK;
2172: 
2173:                                         wrapper->GetLinkAndTitleFromNode(domDoc,
2174:                                                                  node,
2175:                                                                  &link,
2176:                                                                  &info->linktext);
2177:                                         if (!link)
2178:                                         {
2179:                                                 g_free(info->linktext);
2180:                                                 return KZ_CONTEXT_NONE;
2181:                                         }
2182:                                         if (!strncasecmp(link, "mailto:", 7))
2183:                                                 info->link = g_strdup(link+7); 
2184:                                         else 
2185:                                                 info->link = g_strdup(link);
2186:                                         g_free(link);
2187:                                         break;
2188:                                 }
2189:                         }
2190:                 }
2191: 
2192:                 nsCOMPtr<nsIDOMNode> parentNode;
2193:                 node->GetParentNode(getter_AddRefs(parentNode));
2194: 
2195:                 if (!parentNode)
2196:                 {
2197:                         node = nsnull;
2198:                         flags |= KZ_CONTEXT_DOCUMENT;
2199:                         break;
2200:                 }
2201:                 node = parentNode;
2202:         } while (node);
2203: 
2204:         info->context = flags;
2205: 
2206:         return flags;
2207: }
2208: 
2209: static void
2210: reload (KzEmbed *kzembed, KzEmbedReloadFlag flags)
2211: {
2212:         gint32 moz_flags;
2213:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2214: 
2215:         switch (flags) {
2216:           case KZ_EMBED_RELOAD_NORMAL:
2217:             moz_flags = GTK_MOZ_EMBED_FLAG_RELOADNORMAL;
2218:             break;
2219:           case KZ_EMBED_RELOAD_BYPASS_CACHE:
2220:             moz_flags = GTK_MOZ_EMBED_FLAG_RELOADBYPASSCACHE;
2221:             break;
2222:           case KZ_EMBED_RELOAD_BYPASS_PROXY:
2223:             moz_flags = GTK_MOZ_EMBED_FLAG_RELOADBYPASSPROXY;
2224:             break;
2225:           case KZ_EMBED_RELOAD_BYPASS_PROXY_AND_CACHE:
2226:             moz_flags = GTK_MOZ_EMBED_FLAG_RELOADBYPASSPROXYANDCACHE;
2227:             break;
2228:           case KZ_EMBED_RELOAD_CHARSET_CHANGE:
2229:             moz_flags = GTK_MOZ_EMBED_FLAG_RELOADCHARSETCHANGE;
2230:             break;
2231:           default:
2232:             moz_flags = GTK_MOZ_EMBED_FLAG_RELOADNORMAL;
2233:             break;
2234:         }
2235: 
2236:         gtk_moz_embed_reload(GTK_MOZ_EMBED(kzembed), moz_flags);
2237: }
2238: 
2239: 
2240: static void
2241: stop_load (KzEmbed *kzembed)
2242: {
2243:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2244:         gtk_moz_embed_stop_load(GTK_MOZ_EMBED(kzembed));
2245: }
2246: 
2247: 
2248: static void
2249: go_back (KzEmbed *kzembed)
2250: {
2251:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2252:         gtk_moz_embed_go_back(GTK_MOZ_EMBED(kzembed));
2253: }
2254: 
2255: 
2256: static void
2257: go_forward (KzEmbed *kzembed)
2258: {
2259:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2260:         gtk_moz_embed_go_forward(GTK_MOZ_EMBED(kzembed));
2261: }
2262: 
2263: 
2264: static gboolean
2265: can_go_back (KzEmbed *kzembed)
2266: {
2267:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
2268:         return gtk_moz_embed_can_go_back(GTK_MOZ_EMBED(kzembed));
2269: }
2270: 
2271: static gboolean
2272: can_go_forward (KzEmbed *kzembed)
2273: {
2274:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
2275:         return gtk_moz_embed_can_go_forward(GTK_MOZ_EMBED(kzembed));
2276: }
2277: 
2278: static gboolean
2279: can_go_nav_link (KzEmbed *kzembed, KzEmbedNavLink link)
2280: {
2281:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
2282: 
2283:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2284:         KzNavi *navi = KZ_NAVI(g_list_nth_data(priv->nav_links[link], 0));
2285:         return (navi && navi->uri) ? TRUE : FALSE;
2286: }
2287: 
2288: static void
2289: go_nav_link (KzEmbed *kzembed, KzEmbedNavLink link)
2290: {
2291:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2292: 
2293:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2294:         KzNavi *navi = KZ_NAVI(g_list_nth_data(priv->nav_links[link], 0));
2295:         g_return_if_fail(navi);
2296: 
2297:         kz_embed_load_uri(kzembed, navi->uri);
2298: }
2299: 
2300: 
2301: static void
2302: append_nav_link (KzEmbed *kzembed,
2303:                  KzEmbedNavLink link,
2304:                  KzNavi *navi)
2305: {
2306:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2307:         g_return_if_fail(link < KZ_EMBED_LINK_GUARD);
2308:         g_return_if_fail(navi);
2309: 
2310:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2311: 
2312:         priv->nav_links[link] = g_list_append(priv->nav_links[link],
2313:                                               g_object_ref(navi));
2314: }
2315: 
2316: static void
2317: set_nth_nav_link (KzEmbed *kzembed,
2318:                   KzEmbedNavLink link,
2319:                   KzNavi *navi,
2320:                   guint n)
2321: {
2322:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2323:         g_return_if_fail(link < KZ_EMBED_LINK_GUARD);
2324:         g_return_if_fail(navi);
2325: 
2326:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2327:         guint len = g_list_length(priv->nav_links[link]);
2328:         GList *nth_nav_link;
2329: 
2330:         if (n >= len)
2331:         {
2332:                 guint i;
2333:                 for (i = len; i < n; i++)
2334:                 {
2335:                         priv->nav_links[link] =
2336:                                 g_list_append(priv->nav_links[link], NULL);
2337:                 }
2338:         }
2339:         
2340:         nth_nav_link = g_list_nth(priv->nav_links[link], n);
2341:         if (nth_nav_link->data)
2342:                 g_object_unref(nth_nav_link->data);
2343:         nth_nav_link->data = g_object_ref(navi);
2344: }
2345: 
2346: 
2347: static KzNavi *
2348: get_nth_nav_link (KzEmbed *kzembed, KzEmbedNavLink link, guint n)
2349: {
2350:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
2351: 
2352:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE(kzembed);
2353: 
2354:         return KZ_NAVI(g_list_nth_data(priv->nav_links[link], n));
2355: }
2356: 
2357: 
2358: static GList *
2359: get_nav_links (KzEmbed *kzembed, KzEmbedNavLink link)
2360: {
2361:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
2362: 
2363:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE(kzembed);
2364: 
2365:         return priv->nav_links[link];
2366: }
2367: 
2368: 
2369: static void
2370: go_history_index (KzEmbed *kzembed, gint index)
2371: {
2372:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2373:         
2374:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2375:         g_return_if_fail(priv->wrapper);
2376:         
2377:         priv->wrapper->GoHistoryIndex(index);
2378: }
2379: 
2380: static void
2381: copy_page (KzEmbed *src_embed, KzEmbed *dest_embed)
2382: {
2383:         g_return_if_fail(KZ_IS_GECKO_EMBED(src_embed));
2384:         g_return_if_fail(KZ_IS_GECKO_EMBED(dest_embed));
2385: 
2386:         KzMozWrapper *dWrapper = KZ_GECKO_EMBED_GET_PRIVATE(dest_embed)->wrapper;;
2387:         KzMozWrapper *sWrapper = KZ_GECKO_EMBED_GET_PRIVATE(src_embed)->wrapper;;
2388: 
2389:         nsresult rv;
2390: 
2391:         nsCOMPtr<nsISupports> pageDescriptor;
2392:         rv = sWrapper->GetPageDescriptor(getter_AddRefs(pageDescriptor));
2393:         if (!pageDescriptor || NS_FAILED(rv)) return;
2394:         rv = dWrapper->LoadDocument(pageDescriptor,
2395:                                     nsIWebPageDescriptor::DISPLAY_NORMAL);
2396: 
2397:         rv = sWrapper->CopyHistoryTo(dWrapper, TRUE, TRUE, TRUE);
2398: }
2399: 
2400: static void
2401: view_current_page_source_in_new (KzEmbed *kzembed, KzEmbed *new_embed)
2402: {
2403:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2404:         g_return_if_fail(KZ_IS_GECKO_EMBED(new_embed));
2405: 
2406:         KzMozWrapper *nWrapper = KZ_GECKO_EMBED_GET_PRIVATE(new_embed)->wrapper;;
2407:         KzMozWrapper *sWrapper = KZ_GECKO_EMBED_GET_PRIVATE(kzembed)->wrapper;;
2408: 
2409:         nsresult rv;
2410: 
2411:         nsCOMPtr<nsISupports> pageDescriptor;
2412:         rv = sWrapper->GetPageDescriptor(getter_AddRefs(pageDescriptor));
2413:         if (!pageDescriptor || NS_FAILED(rv)) return;
2414: 
2415:         rv = nWrapper->LoadDocument(pageDescriptor,
2416:                                     nsIWebPageDescriptor::DISPLAY_AS_SOURCE);
2417: }
2418: 
2419: /* picked from galeon-1.3.11a */
2420: static gboolean
2421: shistory_get_pos (KzEmbed *kzembed, int *pos, int *count)
2422: {
2423:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
2424: 
2425:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2426:         nsresult rv;
2427:         int total, index;
2428: 
2429:         rv = priv->wrapper->GetSHInfo (&total, &index);
2430: 
2431:         *pos = index;
2432:         *count = total;
2433: 
2434:         return NS_SUCCEEDED(rv) ? TRUE : FALSE;
2435: }
2436: 
2437: /* picked from galeon-1.3.11a */
2438: static void
2439: shistory_get_nth (KzEmbed *kzembed, 
2440:                   int nth,
2441:                   gboolean is_relative,
2442:                   char **aUrl,
2443:                   char **aTitle)
2444: {
2445:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2446: 
2447:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2448:         KzMozWrapper *wrapper = priv->wrapper;
2449:         nsresult rv;
2450: 
2451:         if (is_relative)
2452:         {
2453:                 int pos, count;
2454:                 if (shistory_get_pos(kzembed, &pos, &count))
2455:                         pos += nth;
2456:                 else
2457:                         return;
2458:                 nth = pos;
2459:         }
2460:         
2461:         nsEmbedCString url;
2462:         rv = wrapper->GetSHUrlAtIndex(nth, url);
2463: 
2464:         *aUrl = (NS_SUCCEEDED (rv) && url.Length()) ? g_strdup(url.get()) : NULL;
2465: 
2466:         PRUnichar *title = NULL;
2467:         rv = wrapper->GetSHTitleAtIndex(nth, &title);
2468: 
2469:         nsEmbedCString str;
2470:         NS_UTF16ToCString(nsEmbedString(title),
2471:                           NS_CSTRING_ENCODING_UTF8, str);
2472:         *aTitle = g_strdup (str.get());
2473:         nsMemory::Free(title);
2474: }
2475: 
2476: 
2477: static gchar *
2478: get_body_text(KzEmbed *kzembed)
2479: {
2480:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
2481: 
2482:         nsEmbedString text;
2483:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2484:         g_return_val_if_fail(priv->wrapper, FALSE);
2485:         priv->wrapper->GetBodyString(text);
2486: 
2487:         nsEmbedCString cText;
2488:         NS_UTF16ToCString(text,
2489:                           NS_CSTRING_ENCODING_UTF8, cText);
2490:         return g_strdup(cText.get());
2491: }
2492: 
2493: 
2494: static void
2495: set_encoding (KzEmbed *kzembed, const char *encoding)
2496: {
2497:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2498: 
2499:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2500:         g_return_if_fail(priv->wrapper);
2501:         priv->wrapper->ForceEncoding(encoding);
2502: }
2503: 
2504: static void
2505: get_encoding (KzEmbed *kzembed, char **encoding, gboolean *forced)
2506: {
2507:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2508: 
2509:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2510:         g_return_if_fail(priv->wrapper);
2511:         priv->wrapper->GetEncoding(encoding, *forced);
2512: }
2513: 
2514: static gboolean 
2515: save_with_content (KzEmbed *kzembed, const char *rawfilename)
2516: {
2517:         nsresult rv;
2518:         KzMozWrapper *wrapper = NULL;
2519:         PRUint32 persistFlags = 0;
2520: 
2521:         nsCOMPtr<nsIWebBrowserPersist> bpersist = 
2522:                 do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID);
2523:         if (!bpersist) return FALSE;
2524: 
2525:         nsCOMPtr<nsIURI> linkURI;
2526:         linkURI = nsnull;
2527: 
2528:         nsEmbedCString filename(rawfilename);
2529:         nsCOMPtr<nsILocalFile> file;
2530:         NS_NewNativeLocalFile(filename, PR_TRUE, getter_AddRefs(file)); 
2531:         if (!file) return FALSE;
2532: 
2533:         nsCOMPtr<nsILocalFile> path;
2534:         char *datapath;
2535:         datapath = g_strconcat (rawfilename, ".content", NULL);
2536: 
2537:         nsEmbedString DataPath;
2538:         NS_CStringToUTF16(nsEmbedCString(datapath),
2539:                           NS_CSTRING_ENCODING_UTF8, DataPath);
2540:         NS_NewLocalFile(DataPath, PR_TRUE, getter_AddRefs(path));
2541:         g_free (datapath);
2542: 
2543:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2544:         wrapper = priv->wrapper;
2545:         g_return_val_if_fail (wrapper != NULL, FALSE);  
2546: 
2547:         persistFlags = nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
2548: 
2549:         size_t len = strlen(rawfilename);
2550:         if((rawfilename[len-1] == 'z' && rawfilename[len-2] == 'g') ||
2551:            (rawfilename[len-1] == 'Z' && rawfilename[len-2] == 'G'))
2552:         {
2553:                 persistFlags |= nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION;
2554:         }
2555: 
2556:         persistFlags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE;
2557:         bpersist->SetPersistFlags (persistFlags);
2558: 
2559:         nsCOMPtr<nsIDOMDocument> DOMDocument;
2560: 
2561:         rv = wrapper->GetMainDomDocument (getter_AddRefs(DOMDocument));
2562:         if (NS_FAILED(rv) || !DOMDocument) return FALSE;
2563: 
2564:         nsCOMPtr<nsIURI> inURI;
2565:         nsEmbedCString sURI;
2566: 
2567:         rv = wrapper->GetDocumentUrl(sURI);
2568:         rv = NewURI(getter_AddRefs(inURI), sURI.get());
2569: 
2570:         // FIXME! Use ProgressListener. 
2571:         // KzMozProgressListener *aProgress = new KzMozProgressListener ();
2572:         // aProgress->Init(inURI, path, 
2573:         //              nsnull, nsnull, 0, bpersist);
2574: 
2575:         rv = bpersist->SaveDocument (DOMDocument, file, path, nsnull, 0, 0);
2576:         if (NS_FAILED(rv)) return FALSE;
2577: 
2578:         return TRUE;
2579: }
2580: 
2581: 
2582: static void
2583: print (KzEmbed *kzembed)
2584: {
2585:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2586: 
2587:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2588:         g_return_if_fail (priv->wrapper != NULL);
2589: 
2590:         priv->wrapper->Print();
2591: }
2592: 
2593: 
2594: static void
2595: print_preview (KzEmbed *kzembed)
2596: {
2597:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2598: 
2599:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2600:         g_return_if_fail (priv->wrapper != NULL);
2601:         
2602:         priv->wrapper->PrintPreview();
2603: }
2604: 
2605: 
2606: static GList *
2607: get_printer_list (KzEmbed *kzembed)
2608: {
2609:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
2610: 
2611:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2612:         g_return_val_if_fail (priv->wrapper != NULL, NULL);
2613:         
2614:         GList *list = NULL;
2615:         priv->wrapper->GetPrinterList(&list);
2616: 
2617:         return list;
2618: }
2619: 
2620: 
2621: static gchar *
2622: get_text_from_textarea (KzEmbed *kzembed, gpointer element)
2623: {
2624:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
2625: 
2626:         nsIDOMHTMLElement *htmlElement = (nsIDOMHTMLElement*)element;
2627: 
2628:         nsCOMPtr<nsIDOMHTMLTextAreaElement> tElement = do_QueryInterface(htmlElement);
2629: 
2630:         g_return_val_if_fail(tElement, NULL);
2631: 
2632:         nsEmbedString string;
2633:         tElement->GetValue(string);
2634: 
2635:         nsEmbedCString cString;
2636:         NS_UTF16ToCString(string,
2637:                           NS_CSTRING_ENCODING_UTF8, cString);
2638: 
2639:         return g_strdup(cString.get());
2640: }
2641: 
2642: 
2643: static gboolean
2644: set_text_into_textarea (KzEmbed *kzembed, gpointer element, const gchar *text)
2645: {
2646:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
2647: 
2648:         nsIDOMHTMLElement *htmlElement = (nsIDOMHTMLElement*)element;
2649: 
2650:         nsCOMPtr<nsIDOMHTMLTextAreaElement> tElement = do_QueryInterface(htmlElement);
2651: 
2652:         if (!tElement) return FALSE;
2653: 
2654:         nsEmbedString string;
2655:         NS_CStringToUTF16(nsEmbedCString(text),
2656:                           NS_CSTRING_ENCODING_UTF8, string);
2657:         tElement->SetValue(string);
2658: 
2659:         return TRUE;
2660: }
2661: 
2662: 
2663: static gchar *
2664: kz_gecko_embed_store_history_file(KzGeckoEmbed *kzembed)
2665: {
2666:         nsresult rv;
2667: 
2668:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
2669:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2670: 
2671:         KzMozWrapper *wrapper = priv->wrapper;
2672:         g_return_val_if_fail (wrapper != NULL, NULL);
2673: 
2674:         PRUint32 persistFlags = 0;
2675:         
2676:         nsCOMPtr<nsIWebBrowserPersist> bpersist = 
2677:                 do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID);
2678:         if (!bpersist) return NULL;
2679: 
2680:         persistFlags = nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
2681: 
2682:         persistFlags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
2683:         bpersist->SetPersistFlags (persistFlags);
2684: 
2685:         nsCOMPtr<nsIURI> inURI;
2686:         nsEmbedCString sURI;
2687: 
2688:         rv = wrapper->GetDocumentUrl(sURI);
2689:         rv = NewURI(getter_AddRefs(inURI), sURI.get());
2690: 
2691:         gchar *filename, *history_filename;
2692: 
2693:         filename = create_filename_with_path_from_uri(sURI.get());
2694:         history_filename = g_build_filename(KZ_GET_HISTORY_DIR,
2695:                                             filename,
2696:                                             NULL);
2697:         g_free(filename);
2698: 
2699:         nsCOMPtr<nsILocalFile> localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
2700:         rv = localFile->InitWithNativePath(nsEmbedCString(history_filename));
2701: 
2702:         if (NS_FAILED(rv))
2703:                 return NULL;
2704: 
2705:         PRBool exists;
2706:         localFile->Exists(&exists);
2707:         if (!exists)
2708:         {
2709:                 rv = localFile->Create(nsIFile::NORMAL_FILE_TYPE, 0600);
2710:                 if (NS_FAILED(rv))
2711:                         return NULL;
2712:         }
2713: 
2714:         nsCOMPtr<nsISupports> pageDescriptor;
2715: 
2716:         wrapper->GetPageDescriptor(getter_AddRefs(pageDescriptor));
2717:         
2718:         rv = bpersist->SaveURI (inURI, pageDescriptor, nsnull,
2719:                                 nsnull, nsnull, localFile);
2720: 
2721:         kz_history_append_time_stamp(history_filename);
2722: 
2723:         return history_filename;
2724: }
2725: 
2726: 
2727: static void
2728: create_thumbnail (KzEmbed *kzembed, EggPixbufThumbnailSize size)
2729: {
2730:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2731: 
2732:         const gchar *uri;
2733: 
2734:         uri = kz_embed_get_location(kzembed);
2735: 
2736:         if (!uri)
2737:                 return;
2738: 
2739:         if (uri[0] == '\0')
2740:                 return;
2741: 
2742:         guint last_modified = get_last_modified(kzembed);
2743:         if (last_modified == 0)
2744:         {
2745:                 GTimeVal now;
2746:                 g_get_current_time(&now);
2747:                 last_modified = now.tv_sec;
2748:         }
2749: 
2750:         GdkDrawable *window;
2751:         gint width, height;
2752:         GdkPixbuf *pixbuf, *thumbnail;
2753: 
2754:         window = GTK_WIDGET(kzembed)->window;
2755:         if (!gdk_window_is_viewable(window))
2756:                 return;
2757: 
2758:         gdk_drawable_get_size(window, &width, &height);
2759:         pixbuf = gdk_pixbuf_get_from_drawable(NULL,
2760:                                               window,
2761:                                               NULL,
2762:                                               0, 0, 0, 0,
2763:                                               width, height);
2764:         if (!pixbuf)
2765:                 return;
2766: 
2767:         thumbnail = gdk_pixbuf_scale_simple(pixbuf,
2768:                                             size, size,
2769:                                             GDK_INTERP_HYPER);
2770:         g_object_unref(pixbuf);
2771: 
2772:         if (!thumbnail)
2773:                 return;
2774: 
2775:         KZ_CREATE_THUMBNAIL(thumbnail, uri, last_modified, size);
2776: 
2777:         g_object_unref(thumbnail);
2778: }
2779: 
2780: 
2781: static void
2782: zoom (KzEmbed *kzembed, gdouble zoom)
2783: {
2784:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2785: 
2786:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2787: 
2788:         priv->wrapper->SetImageZoom(zoom);
2789:                 
2790:         set_text_size(kzembed, zoom);
2791: }
2792: 
2793: static gdouble
2794: get_zoom_ratio (KzEmbed *kzembed)
2795: {
2796:         return get_text_size(kzembed);
2797: }
2798: 
2799: 
2800: static void
2801: set_text_size (KzEmbed *kzembed, gdouble zoom)
2802: {
2803:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2804: 
2805:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2806: 
2807:         priv->wrapper->SetZoom(zoom, TRUE);
2808: }
2809: 
2810: static gdouble 
2811: get_text_size (KzEmbed *kzembed)
2812: {
2813:         float f;
2814:         gdouble zoom;
2815: 
2816:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), 100);
2817: 
2818:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2819: 
2820:         if (!priv->wrapper) return 100;
2821: 
2822:         nsresult result = priv->wrapper->GetZoom (&f);
2823:         if (NS_FAILED (result)) return 100;
2824: 
2825:         zoom = (gdouble)f;
2826: 
2827:         return zoom;
2828: }
2829: 
2830: static void
2831: set_history (KzEmbed *kzembed, const GList *history, guint current_position)
2832: {
2833:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2834: 
2835:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2836:         if (!priv->wrapper) return;
2837: 
2838:         nsCOMPtr<nsISHistory> sHistory;
2839:         nsresult rv = priv->wrapper->GetSHistory(getter_AddRefs(sHistory));
2840:         if (NS_FAILED(rv) || !sHistory) return;
2841: 
2842:         nsCOMPtr<nsISHistoryInternal> sHistoryInternal;
2843:         sHistoryInternal = do_QueryInterface(sHistory);
2844: 
2845:         PRInt32 n;
2846:         sHistory->GetCount(&n);
2847:         sHistory->PurgeHistory(n);
2848: 
2849:         GList *node;
2850:         for (node = g_list_first((GList*)history); node; node = g_list_next(node))
2851:         {
2852:                 KzSite *site= (KzSite*)node->data;
2853: 
2854:                 nsCOMPtr<nsISHEntry> entry;
2855:                 entry = do_CreateInstance(NS_SHENTRY_CONTRACTID);
2856: 
2857:                 nsCOMPtr<nsIURI> aURI;
2858:                 NewURI(getter_AddRefs(aURI), site->uri);                
2859:                 /* FIXME! set correct contentType */
2860:                 nsEmbedCString contentType;
2861:                 entry->SetURI(aURI);
2862:                 sHistoryInternal->AddEntry(entry, PR_TRUE);
2863:         }
2864: 
2865:         /* set current */
2866:         go_history_index(kzembed, current_position);
2867: }
2868: 
2869: static void
2870: get_history (KzEmbed *kzembed, GList **history, guint *current_position)
2871: {
2872:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2873: 
2874:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2875:         if (!priv->wrapper) return;
2876: 
2877:         nsCOMPtr<nsISHistory> sHistory;
2878:         nsresult rv = priv->wrapper->GetSHistory(getter_AddRefs(sHistory));
2879: 
2880:         if (NS_FAILED(rv) || !sHistory) return;
2881: 
2882:         PRInt32 count;
2883:         sHistory->GetCount(&count);
2884: 
2885:         PRInt32 index;
2886:         sHistory->GetIndex(&index);
2887:         for (PRInt32 i = 0; i < count; i++)
2888:         {
2889:                 gchar *title = NULL, *uri = NULL;
2890:                 
2891:                 shistory_get_nth(kzembed, i, FALSE, &uri, &title);
2892:                 KzSite *site = kz_site_new(title, uri);
2893:                 *history = g_list_append(*history, site);
2894:                 g_free(title);
2895:                 g_free(uri);
2896:         }
2897:         *current_position = index;
2898: }
2899: 
2900: 
2901: static guint
2902: get_last_modified (KzEmbed *kzembed)
2903: {
2904:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), 0);
2905: 
2906:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2907: 
2908:         if (!priv->wrapper) return 0;
2909: 
2910:         nsresult result;
2911: 
2912:         nsCOMPtr<nsIDOMDocument> DOMDocument;
2913: 
2914:         result = priv->wrapper->GetDocument (getter_AddRefs(DOMDocument));
2915:         if (NS_FAILED(result) || !DOMDocument) return 0;
2916: 
2917:         nsCOMPtr<nsIDOMNSDocument> doc = do_QueryInterface(DOMDocument);
2918:         if(!doc) return 0;
2919:         
2920:         nsEmbedString value;
2921: 
2922:         doc->GetLastModified(value);
2923: 
2924:         nsEmbedCString cValue;
2925:         NS_UTF16ToCString(value,
2926:                           NS_CSTRING_ENCODING_UTF8, cValue);
2927:         nsTime last_modified (cValue.get(), PR_FALSE);
2928:         return (PRTime)last_modified / PR_USEC_PER_SEC;
2929: }
2930: 
2931: 
2932: static void
2933: fine_scroll (KzEmbed *kzembed, int horiz, int vert)
2934: {
2935:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2936: 
2937:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2938: 
2939:         if (!priv->wrapper) return;
2940: 
2941:         priv->wrapper->FineScroll (horiz, vert);
2942: }
2943: 
2944: static void
2945: page_up (KzEmbed *kzembed)
2946: {
2947:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2948: 
2949:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2950: 
2951:         if (!priv->wrapper) return;
2952:         
2953:         priv->wrapper->PageUp();
2954: }
2955: 
2956: static void
2957: page_down (KzEmbed *kzembed)
2958: {
2959:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2960: 
2961:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2962: 
2963:         if (!priv->wrapper) return;
2964:         
2965:         priv->wrapper->PageDown();
2966: }
2967: 
2968: static gboolean
2969: get_allow_javascript (KzEmbed *kzembed)
2970: {
2971:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
2972: 
2973:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2974: 
2975:         if (!priv->wrapper) return FALSE;
2976: 
2977:         PRBool allow;
2978:         priv->wrapper->GetAllowJavascript(&allow);
2979: 
2980:         return allow ? TRUE : FALSE;
2981: }
2982: 
2983: static void
2984: set_allow_javascript (KzEmbed *kzembed, gboolean allow)
2985: {
2986:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
2987: 
2988:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
2989: 
2990:         if (!priv->wrapper) return;
2991:         
2992:         priv->wrapper->SetAllowJavascript(allow);
2993: }
2994: 
2995: static gboolean
2996: get_allow_images (KzEmbed *kzembed)
2997: {
2998:         g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
2999: 
3000:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
3001: 
3002:         if (!priv->wrapper) return FALSE;
3003: 
3004:         PRBool allow;
3005:         priv->wrapper->GetAllowImages(&allow);
3006: 
3007:         return allow ? TRUE : FALSE;
3008: }
3009: 
3010: static void
3011: set_allow_images (KzEmbed *kzembed, gboolean allow)
3012: {
3013:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
3014: 
3015:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
3016: 
3017:         if (!priv->wrapper) return;
3018:         
3019:         priv->wrapper->SetAllowImages(allow);
3020: }
3021: 
3022: static void
3023: show_page_certificate (KzEmbed       *kzembed)
3024: {
3025:         g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
3026: 
3027:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
3028: 
3029:         if (!priv->wrapper) return;
3030: 
3031:         priv->wrapper->ShowPageCertificate();
3032: 
3033: }
3034: 
3035: static void
3036: nav_link_elem_free(gpointer object, gpointer unused)
3037: {
3038:         if (object)
3039:                 g_object_unref(object);
3040: }
3041: 
3042: static void
3043: kz_gecko_embed_navigation_link_free(KzGeckoEmbed *kzembed)
3044: {
3045:         gint i;
3046:         KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE(kzembed);
3047: 
3048:         for (i = 0; i < KZ_EMBED_LINK_GUARD; i++)
3049:         {
3050:                 if (priv->nav_links[i])
3051:                 {
3052:                         g_list_foreach(priv->nav_links[i], nav_link_elem_free, NULL);
3053:                         g_list_free(priv->nav_links[i]);
3054:                         priv->nav_links[i] = NULL;
3055:                 }
3056:         }
3057: #ifdef USE_MIGEMO
3058:         if (priv->migemo_keyword)
3059:                 g_free(priv->migemo_keyword);
3060:         priv->migemo_keyword =NULL;
3061: #endif
3062:         if (priv->last_highlight)
3063:                 g_free(priv->last_highlight);
3064:         priv->last_highlight = NULL;
3065: }
3066: 
3067: static gboolean
3068: kz_gecko_embed_prefs_init (KzEmbedPrefs *embed_prefs)
3069: {
3070:         gchar *full_path;
3071: 
3072:         full_path = g_build_filename(g_get_home_dir(), 
3073:                                      "."PACKAGE,
3074:                                      "mozilla",
3075:                                      NULL);
3076:         gtk_moz_embed_set_profile_path(full_path, "kazehakase");
3077: 
3078:         g_free(full_path);
3079: 
3080:         return TRUE;
3081: }
3082: 
3083: 
3084: //
3085: //  Picked from Epiphany-0.7.0 (embed/mozilla/mozilla-embed-single.cpp).
3086: //  Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
3087: //
3088: static gboolean
3089: kz_gecko_embed_prefs_get_font_list (KzEmbedPrefs *embed_prefs,
3090:                                     const gchar  *lang_group,
3091:                                     const gchar  *font_type,
3092:                                     GList      **font_list,
3093:                                     GList      **all_font_list,
3094:                                     gchar       **default_font)
3095: 
3096: {
3097:         nsresult rv;
3098:         PRUint32 count;
3099:         PRUnichar **fontArray;
3100: 
3101:         nsCOMPtr<nsIFontEnumerator> mozFontEnumerator;
3102:         mozFontEnumerator = do_CreateInstance("@mozilla.org/gfx/fontenumerator;1");
3103:         NS_ENSURE_TRUE (mozFontEnumerator, FALSE);
3104: 
3105:         // get the language proper fonts
3106:         rv = mozFontEnumerator->EnumerateFonts(lang_group, font_type,
3107:                                                &count, &fontArray);
3108:         NS_ENSURE_SUCCESS (rv, FALSE);
3109: 
3110:         if (font_list)
3111:         {
3112:                 GList *list = NULL;
3113:                 for (PRUint32 i = 0; i < count; i++)
3114:                 {
3115:                         char *gFontString;
3116: 
3117:                         nsEmbedCString tmp;
3118:                         NS_UTF16ToCString(nsEmbedString(fontArray[i]),
3119:                                           NS_CSTRING_ENCODING_UTF8, tmp);
3120:                         gFontString = g_strdup(tmp.get());
3121:                         list = g_list_prepend(list, gFontString);
3122:                         nsMemory::Free (fontArray[i]);
3123:                 }
3124:                 *font_list = g_list_reverse(list);
3125:         }
3126:         nsMemory::Free (fontArray);
3127: 
3128:         // get all fonts
3129:         rv = mozFontEnumerator->EnumerateAllFonts(&count, &fontArray);
3130:         NS_ENSURE_SUCCESS (rv, FALSE);
3131: 
3132:         if (font_list)
3133:         {
3134:                 GList *list = NULL;
3135:                 for (PRUint32 i = 0; i < count; i++)
3136:                 {
3137:                         char *gFontString;
3138: 
3139:                         nsEmbedCString tmp;
3140:                         NS_UTF16ToCString(nsEmbedString(fontArray[i]),
3141:                                           NS_CSTRING_ENCODING_UTF8, tmp);
3142:                         if (!g_list_find_custom(*font_list, tmp.get(),
3143:                                                 (GCompareFunc)strcmp))
3144:                         {
3145:                                 gFontString = g_strdup(tmp.get());
3146:                                 list = g_list_prepend(list, gFontString);
3147:                                 nsMemory::Free (fontArray[i]);
3148:                         }
3149:                 }
3150:                 *all_font_list = g_list_reverse(list);
3151:         }
3152:         nsMemory::Free (fontArray);
3153: 
3154:         if (default_font != NULL)
3155:         {
3156:                 char key[255];
3157:                 char *value = NULL;
3158:                 nsCOMPtr<nsIPrefService> prefService;
3159: 
3160:                 prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
3161:                 g_return_val_if_fail(prefService != NULL, FALSE);
3162:         
3163:                 nsCOMPtr<nsIPrefBranch> pref;
3164:                 prefService->GetBranch("", getter_AddRefs(pref));
3165:                 g_return_val_if_fail(pref != NULL, FALSE);
3166: 
3167:                 g_snprintf(key, sizeof(key), "font.name.%s.%s",
3168:                            font_type, lang_group);
3169:                 
3170:                 pref->GetCharPref(key, &value);
3171:                 *default_font = g_strdup(value);
3172:                 nsMemory::Free(value);
3173:         }
3174: 
3175:         return TRUE;
3176: }
3177: 
3178: #include <nsIPasswordManager.h>
3179: #include <nsCPasswordManager.h>
3180: #ifdef HAVE_NSIPASSWORD_H
3181: #include <nsIPassword.h>
3182: #else
3183: #include <nsILoginManager.h>
3184: #include <nsILoginInfo.h>
3185: #endif
3186: #include <nsIIDNService.h>
3187: #include "kz-password-manager-dialog.h"
3188: 
3189: static gboolean
3190: kz_gecko_embed_prefs_get_passwords (KzEmbedPrefs *embed_prefs, GList **passwords)
3191: {
3192:         nsresult result = NS_ERROR_FAILURE;
3193: 
3194: #ifdef HAVE_NSIPASSWORD_H
3195:         nsCOMPtr<nsIPasswordManager> passwordManager =
3196:                 do_GetService(NS_PASSWORDMANAGER_CONTRACTID);
3197:         nsCOMPtr<nsISimpleEnumerator> passwordEnumerator;
3198:         result = passwordManager->GetEnumerator(getter_AddRefs(passwordEnumerator));
3199:         if (NS_FAILED(result)) return FALSE; 
3200: 
3201:         PRBool enumResult;
3202:         for (passwordEnumerator->HasMoreElements(&enumResult) ;
3203:              enumResult == PR_TRUE ;
3204:              passwordEnumerator->HasMoreElements(&enumResult))
3205:         {
3206:                 nsCOMPtr<nsIPassword> nsPassword;
3207:                 result = passwordEnumerator->GetNext 
3208:                                         (getter_AddRefs(nsPassword));
3209:                 if (NS_FAILED(result)) return FALSE;
3210: 
3211:                 PasswordInfo *p = g_new0(PasswordInfo, 1);
3212: 
3213:                 nsEmbedCString transfer;
3214:                 nsPassword->GetHost(transfer);
3215:                 p->host = g_strdup(transfer.get());
3216: 
3217:                 nsEmbedString unicodeName;
3218:                 nsPassword->GetUser(unicodeName);
3219: 
3220:                 nsEmbedCString userName;
3221:                 NS_UTF16ToCString(unicodeName,
3222:                                   NS_CSTRING_ENCODING_UTF8, userName);
3223:                 p->username = g_strdup(userName.get());
3224: 
3225:                 *passwords = g_list_prepend(*passwords, p);
3226:         }       
3227: #else
3228:         nsCOMPtr<nsILoginManager> loginManager =
3229:                 do_GetService(NS_LOGINMANAGER_CONTRACTID);      
3230:         PRUint32 count;
3231:         nsILoginInfo **logins;
3232:         loginManager->GetAllLogins(&count, &logins);
3233:         for (PRUint32 i = 0; i < count; i++)
3234:         {
3235:                 nsEmbedString hostName, userName;
3236:                 nsEmbedCString cHostName, cUserName;
3237:                 logins[i]->GetUsername(userName);
3238:                 logins[i]->GetHostname(hostName);
3239:                 NS_UTF16ToCString(userName,
3240:                                   NS_CSTRING_ENCODING_UTF8, cUserName);
3241:                 NS_UTF16ToCString(hostName,
3242:                                   NS_CSTRING_ENCODING_UTF8, cHostName);
3243:                 PasswordInfo *p = g_new0(PasswordInfo, 1);
3244:                 p->host = g_strdup(cUserName.get());
3245:                 p->username = g_strdup(cHostName.get());
3246: 
3247:                 *passwords = g_list_prepend(*passwords, p);
3248:         }
3249: #endif
3250:         *passwords = g_list_reverse(*passwords);
3251: 
3252:         return TRUE;
3253: }
3254: 
3255: static gboolean
3256: kz_gecko_embed_prefs_remove_passwords (KzEmbedPrefs *embed_prefs, GList *passwords)
3257: {
3258:         nsresult result = NS_ERROR_FAILURE;
3259:         nsCOMPtr<nsIPasswordManager> passwordManager =
3260:                         do_GetService(NS_PASSWORDMANAGER_CONTRACTID);
3261: 
3262:         nsCOMPtr<nsIIDNService> idnService
3263:                 (do_GetService ("@mozilla.org/network/idn-service;1"));
3264: 
3265: 
3266:         for (GList *l = passwords; l != NULL; l = l->next)
3267:         {
3268:                 PasswordInfo *p = (PasswordInfo *)l->data;
3269:                 nsresult rv;
3270:                 nsEmbedCString host;
3271:                 rv = idnService->ConvertUTF8toACE (nsEmbedCString(p->host), host);
3272:                 
3273:                 nsEmbedString userName;
3274:                 NS_CStringToUTF16(nsEmbedCString(p->username), 
3275:                                   NS_CSTRING_ENCODING_UTF8, userName);
3276:                 
3277:                 result = passwordManager->RemoveUser(host, userName);
3278:                 if (NS_FAILED(result)) return FALSE;
3279:         }
3280:         
3281:         return TRUE;
3282: }
3283: 
旧リポジトリブラウザで表示