module WebExtension
Overview
According to architecture of WebKit2GTK, JavaScript code runs in a separeted process called Render Process.
That's why extending JavaScript can not be done in the same process which manages the WebView.
Instead WebKit2GTK proposes a new way to extend JavaScript with native code called WebExtension.
A WebExtension is a shared library which will be loaded at runtime by Render Process.
This module provides some simple macros to reduce redundant works in making a webExtension.
The following code shows an simple example which provides a JS function. It reads given file on filesystem.
require "alizarin"
include WebExtension
initialize_extension do
  # code inside this block will be executed when this Web Extension is loaded by Render Process
  func = function params do
    if params.size != 1
      JSCFunction.raise "#{params.size} parameter(s) provided, expect 1"
      undefined
    else
      path = params.first.to_s
      File.read(path) rescue nil # Return content of file at *path*, otherwise return JS's null
    end
  end
  JSCContext.set_value("read_file", func)
end
Builds shared library:
$ crystal build --single-module --link-flags="-shared -fpic" -o <output-path> <source-file>
NOTE  The shared library should be placed in the directory provided with WebView#extension_dir=
In main process (which manages an instance of WebView), opens WebInspector's console and types:
read_file("/a-file-located-some-where")
See more:
Defined in:
components/web_extension.crcomponents/web_extension/IPC.cr
components/web_extension/annotations.cr
Class Method Summary
- 
        .eval(js : String)
        
          
Evaluates js and gets the result back.
 - 
        .uuid
        
          
Gets UUID hex string of the
WebViewwhich loads this extension 
Macro Summary
- 
        function(arg_name)
        
          
This macro initializes an anonymous JavaScript function.
 - 
        initialize_extension
        
          
Entry point of a Web Extension shared library
 - 
        new(constructor, *args)
        
          
JavaScript's
newoperator, returnsJSCPrimative | JSCFunction | JSCObject - 
        register_class(type)
        
          
Exposes a Crystal's Class so it can be used in JavaScript
 - 
        undefined
        
          
JavaScript
undefined 
Class Method Detail
Macro Detail
This macro initializes an anonymous JavaScript function.
func = function p do
  puts typeof(p) # => Array(JSCFunction|JSCObject|JSCPrimative)
  # Developers can return anything as long as it has method to_jsc() : JSC::JSValue
  if p.size != 0
    JSCPrimative.new true
  else
    false
  else
  # return type is (JSCPrimative|Bool), it's ok because both JSCPrimative and Bool have method to_jsc()
end
        JavaScript's new operator, returns JSCPrimative | JSCFunction | JSCObject
include WebExtension
promise = JSCContext.get_value("Promise")
new Promise, function p {
  resolve = p.first.as(JSCFunction)
  spawn do
    1000.times{ sleep 0.1 }
    resolve.call true
  end
}
        Exposes a Crystal's Class so it can be used in JavaScript
Example:
- webextension.cr:
 
class File
  def initialize(p : [] of (JSCFunction | JSCObject | JSCPrimative))
    super(p.first.to_s)
  end
  @[JSCInstanceMethod]
  def content(p)
    self.seek(0)
    self.gets_to_end
  end
end
JSCContext.set_value "File", WebExtension.register_class(File)
- index.js
 
var content = new File("./LICENSE").content();
See more at JSCInstanceMethod.