wiki:GtkAPIProposal

Version 4 (modified by Kimmo Kinnunen, 15 years ago) (diff)

--

Heres some thoughts if you are thinking about Gtk -style API for Webkit which would run on top of Gdk/Gtk+ or similar environment. I'm not sure what desired for WebkitGdk, since the port's name is Gdk and not Gtk+. Nevertheless, since the code seems to have dependency to Gtk+, I'll ramble anyway.

I created webkit-gtk api for gtk-webcore. It's copied from WebKit's WebView API, translated to GObject -like API using same conventions that all the Gtk+ and GNOME applications use. Currently the main classes are:

  • WebkitView (which corresponds to WebView), the main view which can show web pages. This is a GtkWidget you can put to the application layout
  • WebkitFrame (corresponds to WebFrame), class representing a frame in a web page. WebView has one main frame, and main frame can have multiple child frames.
  • WebkitUIDelegate, WebkitResourceLoadDelegate, WebkitFrameLoadDelegate: hooks into various processes the engine does

The main assumptions in this api are as follows:

  • if a library targets gtk applications, it needs to have gtk api that feels native. This means C, this means GObject system and this means Gtk coding standards *for the API*
  • if a library implementation is based on Webkit, it should reflect webits implementation. Trying to swim against the current (ie. doing things differently than Obj-C Webkit) is just asking for trouble. And WebView is a good API.

These are actually written and in use in gtk-webcore's NRCit public API. This component corresponds what would be WebkitGdk, public API for developers using the WebkitGdk component.

http://gtk-webcore.svn.sourceforge.net/viewvc/gtk-webcore/trunk/NRCit/src/webkit-gtk/webkit-view.h?revision=92&view=markup 92

http://gtk-webcore.svn.sourceforge.net/viewvc/gtk-webcore/trunk/NRCit/src/webkit-gtk/webkit-frame.h?revision=92&view=markup 92

http://gtk-webcore.svn.sourceforge.net/viewvc/gtk-webcore/trunk/NRCit/src/webkit-gtk/webkit-ui-delegate.h?revision=92&view=markup 92

The overall API can be found from following URL:

http://gtk-webcore.svn.sourceforge.net/viewvc/gtk-webcore/trunk/NRCit/src/webkit-gtk/

The header files would apply directly to the Webkit TOT Gdk work. The implementatation (.c and .cc files) of said interface is specific to gtk-webcore. My rationale to implement this in gtk-webcore was twofold:

  • Replace the old webi -api (pasted below, btw, by somebody else)
  • When WebKitGdk would have enough features, developers using gtk-webcore could move directly to WebkitGdk

Above API is not complete copy of WebView in the sense that it is not complete. Rather you should view it as good bare minimum set of classes, functions and conventions to publish before you can write working browser and still not hack into the core of the engine (meaning using webkit or webcore code directly.

Note that when I write here WebkitGdk, I don't mean I want to push WebkitGdk port towards Gtk+ dependencies, Gtk+ style APIs or anything. I just mean that *if* the project aims to be a web content rendering engine for Gtk+ environment, then this kind of API will be needed, and going with WebView is a good alternative.

-- Kimmo Kinnunen, Kompo in #webkit


/* Private structure type */
typedef struct WebiPrivate_ WebiPrivate;

/*
 * Main object structure
 */
typedef struct Webi_ Webi;

struct Webi_ {
  GtkBin __parent__;
  /*< private >*/
  WebiPrivate *_priv;
};

/** Structure used to set device type. */
typedef enum {
  WEBI_DEVICE_TYPE_SCREEN,
  WEBI_DEVICE_TYPE_HANDHELD,
  WEBI_DEVICE_TYPE_PRINTER
} WebiDeviceType;

/** Rendering engine settings structure
 *  Rendering engine settings structure.
 */

typedef struct WebiSettings_ WebiSettings;
struct WebiSettings_ {
  gboolean javascript_enabled;
  gboolean java_enabled;
  gboolean plugins_enabled;
  gboolean autoload_images;
  gfloat minimum_font_size;
  gfloat default_font_size;
  gfloat default_fixed_font_size;
  const gchar* default_text_encoding;
  const gchar* serif_font_family;
  const gchar* sans_serif_font_family;
  const gchar* fixed_font_family;
  const gchar* standard_font_family;
  const gchar* cursive_font_family;
  const gchar* fantasy_font_family;
  const gchar* user_agent_string;

  /** Full url (including port) of the proxy to use. If NULL, empty (""), */
  const gchar* http_proxy;

  /** Rendering Mode */
  const WebiDeviceType device_type;
};

typedef struct WebiLoadStatus_ WebiLoadStatus;

/** Type of the status message. */
typedef enum  {
	/** Report start loading a resource */
	WEBI_LOADING_START,
	/** Report progress in loading a resource */
	WEBI_LOADING,
	/** Report a successful resource load */
	WEBI_LOADING_COMPLETE,
	/** Report an error in resource loading. */
	WEBI_LOADING_ERROR
} WebiStatus;

/** Status message. */
struct WebiLoadStatus_ {
  /** Status of the loading process. */
  WebiStatus status;

  /** Number of files to download */
  guint files;

  /** Number of files received with Content-Length set*/
  guint filesWithSize;

  /** Number of files received */
  guint ready;

  /** Bytes available for resource. */
  guint size;

  /** Bytes received from resource. */
  guint received;

  /** Total size of the resources including those that didn't have
      Content-Length set. */
  guint totalSize;

  /** Bytes received total. */
  guint totalReceived;

  /** Error code. */
  gint statusCode;
};



typedef struct WebiPromptArgs_ WebiPromptArgs;


/** Type of message prompt if message prompt was an alert (ok button), confirm (yes/no) or input (textfield, ok, cancel).
 */
typedef enum {
	/** alert (ok button)*/
	WEBI_ALERT,
	/**confirm (yes/no)*/
	WEBI_CONFIRM,
	/**or input (textfield, ok, cancel) */
	WEBI_INPUT
} WebiPromptType;

/** Structure used to pass arguments of javascript prompt messages
 */
struct WebiPromptArgs_
{
  /*<public>*/

  /** Flag specifying if message prompt was an alert (ok button), confirm (yes/no) or
   *  input (textfield, ok, cancel). */
  WebiPromptType type;

  /** The prompt message*/
  const gchar* msg;

  /**  default input text.
   *  if type == WEBI_INPUT contains default input text to be shown in input field */
  const gchar* default_input;

  /**  text entered in the prompt textfield
   *   should be set if type == WEBI_INPUT
   *  string will be deallocated by signaller with g_free().
   *  ie. there's an ownership change. */
  gchar* out_input;

  /** flag specifying if the button pressed was ok or cancel, yes or no
   * \TRUE means ok or yes
   * \FALSE means cancel or no
   */
  gboolean out_ok_pressed;
};

typedef struct WebiAuthArgs_ WebiAuthArgs;

/** Structure used to pass arguments of javascript prompt messages
 */
struct WebiAuthArgs_
{
  /*< public >*/
  /** realm of authentication */
  const gchar* realm;

  /** Out parameter containing username from user.
   *  string will be deallocated by caller with g_free().
   *  ie. there's an ownership change.*/
  gchar* out_username;

  /** Out parameter containing password from user.
   *  string will be deallocated by caller with g_free()
   *  ie. there's an ownership change. */

  gchar* out_password;

  /** flag specifying if the button pressed was ok or cancel
   * \TRUE means ok
   * \FALSE otherwise  */
  gboolean out_ok_pressed;
};

typedef struct WebiCookie_ WebiCookie;

/** Structure used to pass arguments of javascript prompt messages
 */
struct WebiCookie_
{
  /*<public>*/

  /** Whole cookie */
  const gchar* cookie;

  /** Cookie name */
  const gchar* name;

  /** Cookie value */
  const gchar* value;

  /* Cookie comment */
  const gchar* comment;

  /* Cookie domain */
  const gchar* domain;

  /* Cookie TTL */
  const gchar* maxAge;

  /* Cookie path */
  const gchar* path;

  /* Is cookie secure? */
  gboolean secure;

  /* Cookie-specification version. */
  gint version;

  /** Out argument - user accepted the cookie. */
  gboolean out_accept_cookie;
};

typedef struct WebiWindowProperties_ WebiWindowProperties;

/** Structure used to pass arguments of javascript prompt messages
 */
struct WebiWindowProperties_
{
  /*<public>*/
  /* Are toolbars wisible. */
  gboolean toolbarsVisible;

  /* is status bar visible. */
  gboolean statusBarVisible;

  /* are scroll bars visible. */
  gboolean scrollbarsVisible;

  /* Is window resizable. */
  gboolean isResizable;
};

/** Structure used to get and set window size and content rectangle size. */
typedef enum {
  WEBI_CONTENT_SIZE,
  WEBI_WINDOW_SIZE
} WebiWindowSize;

/*
 * Class definition
 */
typedef struct WebiClass_ WebiClass;
struct WebiClass_ {
  GtkBinClass __parent__;

  /*signals*/


  /** Location change indication signal.
   * use \webi_get_location() to get the url string
   * @emited when current page changes.
   * @param self the engine which sent the signal
   */
  void (* location) (Webi * self);

  /** Title change indication signal.
   * use \webi_get_title() to get the title string
   * @emited when title of current page changes.
   * @param self the engine which sent the signal
   */
  void (* title) (Webi * self);

  /** Load start indication signal.
   * @emited when page loading is started
   * @param self the engine which sent the signal
   */
  void (* load_start) (Webi * self);

  /** Load start indication signal.
   * @emited when page loading is stopped.
   * @emited on error
   * @param self the engine which sent the signal
   */
  void (* load_stop) (Webi * self);

  /** Set cookie indication signal.
   * @emited when a cookie is received from network
   * @param self the engine which sent the signal
   * @param cookie The actual cookie received.
   * @return \FALSE if don't allow cookie to be set
   *         \TRUE if cookie should be set
   */
  gboolean (* set_cookie) (Webi * self, WebiCookie * cookie);

  /** javascript status change indication signal
   * use \webi_get_status_text() to get the status string
   *
   * @emited when javascript status changes.
   * @param self the engine which sent the signal
   */
  void (* status_text) (Webi * self);

  /** Page load status change indication signal
   *
   * @emited when page load status changes.
   * @param self the engine which sent the signal
   * @param status status of the engine.
   */
  void (* status) (Webi * self, WebiLoadStatus * status);

  /** javascript prompt and alert request signal
   * must be synchronous
   * @emited when javascript generates an alert
   * @emited when javascript generates an prompt
   *
   * @param self the engine which sent the signal
   * @param args used to pass information between browser and engine (in and out)
   *        see #WebiPromptAgs
   */
  void (* req_js_prompt) (Webi *self, WebiPromptArgs* args);

  /** HTTP Auth
   * must be synchronous
   * @emited when javascript generates an alert
   * @emited when javascript generates an prompt
   *
   * @param self the engine which sent the signal
   * @param args used to pass information between browser and engine (in and out)
   *        see #WebiPromptAgs
   */
  void (* req_auth_prompt) (Webi *self, WebiAuthArgs* args);

  /** javascript/html new window request signal
   * must be synchronous
   *
   * @emited when javascript requests to create a new window
   * @emited when html link contains target="_blank" -attribute   *
   * @param self the engine which sent the signal
   * @param url the URL string loading by newengine.
   * @return newengine The new engine of the new window
   *        or \NULL if new window creation is not allowed
   */
  Webi * (* req_new_window) (Webi *self, const gchar *url);

  void (* show_window) (Webi *self, WebiWindowProperties* features);
  void (* close_window) (Webi *self);

  void (* set_window_properties) (Webi *self, WebiWindowProperties* features);
  void (* get_window_size) (Webi *self, WebiWindowSize * type, GtkAllocation * size);
  void (* set_window_size) (Webi *self, WebiWindowSize * type, GtkRequisition * size);


  /** Set device type signal
   * must be synchronous
   *
   * @emited when user wants to change device type used in rendering and
   *         style sheet selection
   * @param self the engine which sent the signal
   * @param newDeviceType The new device type of current window
   */
  void (* set_device_type) (Webi *self, WebiDeviceType type);

  /** Get device type signal
   * must be synchronous
   *
   * @emited when user wants to change device type used in rendering and
   *         style sheet selection
   * @param self the engine which sent the signal
   * @param newDeviceType The new device type of current window
   */
  WebiDeviceType (* get_device_type) (Webi *self);

  void (* mouse_over) (Webi *self, const gchar* link_title, const gchar* link_label, const gchar* link_url, const gchar* link_target);

  /** selection change signal*/
  void (* selection) (Webi *self);
#if 0
  /* not implemented at the moment */
  void (* req_file_attach) (Webi *self);
  void (* file_upload_finished) (Webi *self);
  void (* file_upload_finished) (Webi *self);
#endif

};


/*
 * Public methods
 */


/** Returns GObject type for KHTML html renderer class
 * Returns GObject type for KHTML html renderer class.
 *
 * @return type for KHTML html renderer class
 */
GType webi_get_type ();


/** Creates new html rendering engine
 * Creates new html rendering engine widget. To be able to view web pages,
 * add returned widget to a container and show the container.
 *
 * @return html rendering engine widget
 */
GtkWidget * webi_new ();

/** Starts loading of a new url
 * Starts loading of a new url. Loading is asynchronous.
 *
 * @emit "load-start" signal on start
 * @emit "load-stop"  signal when loading stops, ie. succesfully loaded page, or error
 * @param self the engine to use
 * @param url the url to load
 */
void webi_load_url (Webi * self, const gchar * url);

/** Reloads current url
 * reloads current url
 */
void webi_refresh (Webi * self);

/** Cancels the load currently in progress, if any
 * Cancels the load currently in progress, if any.
 * @emit "load-stop"
 *
 * @param self the engine to use
 */
void webi_stop_load (Webi * self);

/** Checks the browsing history position relative to the beginning of the history
 * Checks if the engine is at the beginning of browsing history.
 * @return \TRUE if browsing history has previous elements
 *         \FALSE otherwise
 */
gboolean webi_can_go_back (Webi * self);


/** Checks the browsing history position relative to the end of the history
 * Checks if the engine is at the end of browsing history.
 * @return \TRUE if browsing history has successive elements
 *         \FALSE otherwise
 */
gboolean webi_can_go_forward (Webi * self);

/** Directs browser engine to the previous url in the browsing history
 * Directs browser engine to the previous url in the browsing history.
 * @emit "load-start" see \webi_load_url
 * @emit "load-stop" see \webi_load_url
 */
void webi_go_back (Webi * self);

/** Directs browser engine to the next url in the browsing history
 * Directs browser engine to the next url in the browsing history.
 *
 * @emit "load-start" see \webi_load_url
 * @emit "load-stop" see \webi_load_url
 */
void webi_go_forward (Webi * self);

/** Returns the url of the currently loaded page
 * Returns the url of the currently loaded page.
 * The string contains the full url used, including
 * the protocol. It can be absolute or relative.
 * The string must not be freed (const).
 *
 * @return  the url string of the currently loaded page.
 */
const gchar* webi_get_location (Webi * self);

/** Returns the title of the currently loaded page
 * Returns the title of the currently loaded page.
 * If the page contains a frameset, title is the title of the
 * frameset.
 *
 * @return the title of the currently loaded page.
 */
const gchar* webi_get_title (Webi * self);

/** Returns a status string set by javascript
 * Returns a string that javascript has set to be used
 * usually in the statusbar of the browser.
 *
 * @return javascript status string
 */
const gchar* webi_get_status_text (Webi * self);

/** Returns internal representation of the engine
 * Returns internal representation of the engine.
 * Can be used in C++ code. Exposes the public NRCore api
 * to the user. This may be needed if certain functionality
 * is not implemented in C interface.
 * usage not recommended
 * Used with:
 * OSBB::Bridge* engine = 0;
 * Webi* khtml_engine = webi_new();
 * engine = static_cast<OSB::Bridge*>(webi_get_internal (engine));
 *
 */
void* webi_get_internal (Webi * self);

/** Sets the settings of the rendering engine
 * Sets the settings of the rendering engine.
 *
 */
void webi_set_settings (Webi * self, const WebiSettings* settings);

/**  Prints the internal render tree of the engine.
 *
 * Can be used in C++ debug code. This
 * usage not recommended
 */
const gchar* webi_render_tree (Webi * self);

/** Toggles the emission of internal constructed load status messages
 * Sets the emission of internal constructed load status messages
 * Signalö emitted is status-text
 *
 * @param flag \TRUE if you want to receive internal status messages
 for loading
 \FALSE if not
*/
void webi_set_emit_internal_status (Webi * self, gboolean flag);


/** Sets the device type used for current window.
 *
 * @param self the engine which sent the signal
 * @param newDeviceType The new device type of current window
 */
void webi_set_device_type (Webi * self, WebiDeviceType device);

/** Gets the device type used for current window.
 *
 * @param self the engine which sent the signal
 * @param newDeviceType The new device type of current window
 */
WebiDeviceType webi_get_device_type (Webi * self);


void webi_set_group (Webi* self, const gchar* group);

const gchar* webi_get_group (Webi* self);

void webi_set_text_multiplier (Webi* self, gfloat multiplier);
gfloat webi_get_text_multiplier (Webi* self);

gboolean webi_find (Webi* self, const gchar* text, gboolean case_sensitive, gboolean dir_down);

/** Gets the active selection.
 * The returned string must be freed with g_free()
 * Returns "" if selection is not active
 */
gchar* webi_get_current_selection_as_text(Webi* self);

/** Gets the engine user agent string.
 * The returned string can be used to construct browser-specific
 * user-agent strings
 */
const gchar* webi_get_engine_user_agent_string ();

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif