20
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

RubyでChrome Extensionを作れるフレームワーク、"unloosen"を使ってContent Sctiptを作成した

Last updated at Posted at 2023-05-14

これは何

RubyKaigi 2023でunloosen(Ruby + wasmでChrome Extentionを作るためのフレームワーク)についての発表がありました。

RubyKaigi 2023での発表の詳細は下記です。

こちらの内容が面白く、実際に触ってみたという内容になります。
作ったサンプルは↓になります。

unloosenについては既に紹介記事が書かれている為、詳しい内容はそちらをご覧いただければと思います。

何を作ったか

マークダウンにURLなどを貼るとき、[Title](URL) <- こちらのフォーマットで貼りたい時が多々あります。
h1タグ(ページのタイトル)と URLを取得して、[Title](URL)のフォーマットでクリップボードにコピーするボタンをChrome Extentionで追加するChrome Extentionを作成しました。

作成したサンプルのコードはこちらになります。

manifest.json
{
  "manifest_version": 3,
  "name": "unloosen-sample",
  "description": "unloosen-sample",
  "version": "0.0.1",
  "content_scripts": [
    {
      "matches": [
        "http://www.example.com/"
      ],
      "js": [
        "node_modules/unloosen-ruby-loader/dist/entry/loader-content-script.esm.js"
      ]
    }
  ],
  "content_security_policy": {
    "extention_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'"
  },
  "web_accessible_resources": [
    {
      "resources": [
        "*",
        "node_modules/unloosen-ruby-loader/dist/*"
      ],
      "matches": [
        "<all_urls>"
      ]
    }
  ]
}
unloosen.config.json
{
  "application": "app.rb",
  "ruby.wasm": "./node_modules/unloosen-ruby-loader/dist/ruby.wasm",
  "content-script-entry": "./node_modules/unloosen-ruby-loader/dist/entry/module-content-script.esm.js",
  "remote-require": false
}
app.rb
require 'unloosen'

content_script site: 'www.example.com' do
  h1_content = document.querySelector("h1")
  url = window.location.href.inspect[1...-1]
  clip_text = "[#{h1_content.textContent}](#{url})"

  # Create input element
  input = document.createElement("input")
  input.type = "text"
  input.style = "position: absolute; left: -1000px; top: -1000px;"
  input.value = clip_text

  # Create button element
  button = document.createElement("button")
  button.textContent = "Copy [title](url)"

  button.addEventListener("click") do
    input.select()
    # 非推奨の書き方だが、HTTPではnavigator.clipboardが使えない、試しで書いているので、これで進めている...
    document.execCommand("copy")
    puts "Copied!"
  end

  flagment = document.createDocumentFragment()
  flagment.appendChild(input)
  flagment.appendChild(button)

  h1_content.appendChild(flagment)
end

長々となってしまっていますが、やっていることは、下記です。

  • h1要素と、URLを取得
  • 追加するinput要素、button要素の作成してDOMを追加する

実装をしていて気づいたことをあげます。

  • unloosenがRuby wasmでjsを取り扱う部分をラップしてくれている

document.querySelector("h1") と記載している箇所、普通にRuby + wasmで書く場合は、JS.global[:document].querySelector("h1")と書く必要があります。
unloosenが扱いやすいよう、aliasを用意しているため、コードのようにシンプルに書くことができています。(Ref)

使ってみて

  • unloosenがRuby + wasm、Chrome Extentionの気になるところをサポートしてくれていると感じた
    • シンプルに記述ができる
    • Chrome Extentionを作る際にJavaScriptをほぼ触らず、Rubyで作っていくことができるのは、とても面白いなと感じます。
  • 開発の体験の良さ
    • Extentionを読み込んだ後、コードの変更した際Extentionのリロードの必要がなく、ブラウザを読み込み直すだけで反映がされるので、シンプルにtry & errorを試せるのが良いなと思いました。
      • コンパイル、bundleを必要としない今のシンプルな構成、Rubyだからこその利点を感じました。

ruby.wasm、unloosen共にドキュメントがまだまだ少ないところではありますが、これからruby.wasmを触ってみたい、RubyでChrome拡張作るのに興味がある方に、ぜひ一度触ってみることをお勧めしたいです。

20
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?