1 module webkit2webextension.WebExtension; 2 3 private import gio.AsyncResultIF; 4 private import gio.Cancellable; 5 private import glib.ErrorG; 6 private import glib.GException; 7 private import gobject.ObjectG; 8 private import gobject.Signals; 9 private import std.algorithm; 10 private import webkit2webextension.UserMessage; 11 private import webkit2webextension.WebPage; 12 private import webkit2webextension.c.functions; 13 public import webkit2webextension.c.types; 14 15 16 /** 17 * WebKitWebExtension is a loadable module for the WebProcess. It allows you to execute code in the 18 * WebProcess and being able to use the DOM API, to change any request or to inject custom 19 * JavaScript code, for example. 20 * 21 * To create a WebKitWebExtension you should write a module with an initialization function that could 22 * be either webkit_web_extension_initialize() with prototype #WebKitWebExtensionInitializeFunction or 23 * webkit_web_extension_initialize_with_user_data() with prototype #WebKitWebExtensionInitializeWithUserDataFunction. 24 * This function has to be public and it has to use the #G_MODULE_EXPORT macro. It is called when the 25 * web process is initialized. 26 * 27 * <informalexample><programlisting> 28 * static void 29 * web_page_created_callback (WebKitWebExtension *extension, 30 * WebKitWebPage *web_page, 31 * gpointer user_data) 32 * { 33 * g_print ("Page %d created for %s\n", 34 * webkit_web_page_get_id (web_page), 35 * webkit_web_page_get_uri (web_page)); 36 * } 37 * 38 * G_MODULE_EXPORT void 39 * webkit_web_extension_initialize (WebKitWebExtension *extension) 40 * { 41 * g_signal_connect (extension, "page-created", 42 * G_CALLBACK (web_page_created_callback), 43 * NULL); 44 * } 45 * </programlisting></informalexample> 46 * 47 * The previous piece of code shows a trivial example of an extension that notifies when 48 * a #WebKitWebPage is created. 49 * 50 * WebKit has to know where it can find the created WebKitWebExtension. To do so you 51 * should use the webkit_web_context_set_web_extensions_directory() function. The signal 52 * #WebKitWebContext::initialize-web-extensions is the recommended place to call it. 53 * 54 * To provide the initialization data used by the webkit_web_extension_initialize_with_user_data() 55 * function, you have to call webkit_web_context_set_web_extensions_initialization_user_data() with 56 * the desired data as parameter. You can see an example of this in the following piece of code: 57 * 58 * <informalexample><programlisting> 59 * #define WEB_EXTENSIONS_DIRECTORY /<!-- -->* ... *<!-- -->/ 60 * 61 * static void 62 * initialize_web_extensions (WebKitWebContext *context, 63 * gpointer user_data) 64 * { 65 * /<!-- -->* Web Extensions get a different ID for each Web Process *<!-- -->/ 66 * static guint32 unique_id = 0; 67 * 68 * webkit_web_context_set_web_extensions_directory ( 69 * context, WEB_EXTENSIONS_DIRECTORY); 70 * webkit_web_context_set_web_extensions_initialization_user_data ( 71 * context, g_variant_new_uint32 (unique_id++)); 72 * } 73 * 74 * int main (int argc, char **argv) 75 * { 76 * g_signal_connect (webkit_web_context_get_default (), 77 * "initialize-web-extensions", 78 * G_CALLBACK (initialize_web_extensions), 79 * NULL); 80 * 81 * GtkWidget *view = webkit_web_view_new (); 82 * 83 * /<!-- -->* ... *<!-- -->/ 84 * } 85 * </programlisting></informalexample> 86 */ 87 public class WebExtension : ObjectG 88 { 89 /** the main Gtk struct */ 90 protected WebKitWebExtension* webKitWebExtension; 91 92 /** Get the main Gtk struct */ 93 public WebKitWebExtension* getWebExtensionStruct(bool transferOwnership = false) 94 { 95 if (transferOwnership) 96 ownedRef = false; 97 return webKitWebExtension; 98 } 99 100 /** the main Gtk struct as a void* */ 101 protected override void* getStruct() 102 { 103 return cast(void*)webKitWebExtension; 104 } 105 106 /** 107 * Sets our main struct and passes it to the parent class. 108 */ 109 public this (WebKitWebExtension* webKitWebExtension, bool ownedRef = false) 110 { 111 this.webKitWebExtension = webKitWebExtension; 112 super(cast(GObject*)webKitWebExtension, ownedRef); 113 } 114 115 116 /** */ 117 public static GType getType() 118 { 119 return webkit_web_extension_get_type(); 120 } 121 122 /** 123 * Get the web page of the given @page_id. 124 * 125 * Params: 126 * pageId = the identifier of the #WebKitWebPage to get 127 * 128 * Returns: the #WebKitWebPage for the given @page_id, or %NULL if the 129 * identifier doesn't correspond to an existing web page. 130 */ 131 public WebPage getPage(ulong pageId) 132 { 133 auto __p = webkit_web_extension_get_page(webKitWebExtension, pageId); 134 135 if(__p is null) 136 { 137 return null; 138 } 139 140 return ObjectG.getDObject!(WebPage)(cast(WebKitWebPage*) __p); 141 } 142 143 /** 144 * Send @message to the #WebKitWebContext corresponding to @extension. If @message is floating, it's consumed. 145 * 146 * If you don't expect any reply, or you simply want to ignore it, you can pass %NULL as @calback. 147 * When the operation is finished, @callback will be called. You can then call 148 * webkit_web_extension_send_message_to_context_finish() to get the message reply. 149 * 150 * Params: 151 * message = a #WebKitUserMessage 152 * cancellable = a #GCancellable or %NULL to ignore 153 * callback = (nullable): A #GAsyncReadyCallback to call when the request is satisfied or %NULL 154 * userData = the data to pass to callback function 155 * 156 * Since: 2.28 157 */ 158 public void sendMessageToContext(UserMessage message, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 159 { 160 webkit_web_extension_send_message_to_context(webKitWebExtension, (message is null) ? null : message.getUserMessageStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 161 } 162 163 /** 164 * Finish an asynchronous operation started with webkit_web_extension_send_message_to_context(). 165 * 166 * Params: 167 * result = a #GAsyncResult 168 * 169 * Returns: a #WebKitUserMessage with the reply or %NULL in case of error. 170 * 171 * Since: 2.28 172 * 173 * Throws: GException on failure. 174 */ 175 public UserMessage sendMessageToContextFinish(AsyncResultIF result) 176 { 177 GError* err = null; 178 179 auto __p = webkit_web_extension_send_message_to_context_finish(webKitWebExtension, (result is null) ? null : result.getAsyncResultStruct(), &err); 180 181 if (err !is null) 182 { 183 throw new GException( new ErrorG(err) ); 184 } 185 186 if(__p is null) 187 { 188 return null; 189 } 190 191 return ObjectG.getDObject!(UserMessage)(cast(WebKitUserMessage*) __p, true); 192 } 193 194 /** 195 * This signal is emitted when a new #WebKitWebPage is created in 196 * the Web Process. 197 * 198 * Params: 199 * webPage = the #WebKitWebPage created 200 */ 201 gulong addOnPageCreated(void delegate(WebPage, WebExtension) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 202 { 203 return Signals.connect(this, "page-created", dlg, connectFlags ^ ConnectFlags.SWAPPED); 204 } 205 206 /** 207 * This signal is emitted when a #WebKitUserMessage is received from the 208 * #WebKitWebContext corresponding to @extension. Messages sent by #WebKitWebContext 209 * are always broadcasted to all #WebKitWebExtension<!-- -->s and they can't be 210 * replied to. Calling webkit_user_message_send_reply() will do nothing. 211 * 212 * Params: 213 * message = the #WebKitUserMessage received 214 * 215 * Since: 2.28 216 */ 217 gulong addOnUserMessageReceived(void delegate(UserMessage, WebExtension) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 218 { 219 return Signals.connect(this, "user-message-received", dlg, connectFlags ^ ConnectFlags.SWAPPED); 220 } 221 }