夢語るだけのREADME。
- node:
18.12.1
npm ci
npm run build:production:firefox
npm run output:firefox
cd dist/web-ext-artifacts
npm ci
npm run build:production:chrome
npm run output:chrome
cd dist/web-ext-artifacts
- ブラウザ拡張機能
- Fx だけでいい
- ページの翻訳処理を行う
- 特定のページに対するパターン定義を取り込んで翻訳する
- 翻訳者がしんどい
- ユーザーは自然に読める
- 公式で日本語訳ページを作る企業あんまないでしょ
- 英語至上主義感がつらい
- いろんな言語も対応できたら誰かが幸せになる(設定ファイルがあればね!)
- 原文を自分で読んでも翻訳サイト使っても機微が分からん
- 翻訳先言語の多数の目があれば、とは思いつつ誰が訳すねんっていうね
manifest.json | package.json | その他 |
---|---|---|
name |
- | locale: ext_name |
short_name |
name |
ローカライズしない想定。 HTTP-HEADER: X-Extension としても使用される |
version |
version |
|
description |
description |
locale: ext_description |
- 基本的に package.json データを元に manifest.json を組み立てる
- 項目が重複するものは package.json を正として楽ちん管理したい
- バージョンアップ時は
version
だけ変えて運用したい
npm scripts
の*-env
系スクリプトはプロジェクトディレクトリ直下の.npmrc
の環境変数を使用する。- 注意 前提をいきなり覆すが、 Chrome を実行する場合
PTD_CHROME_APPLICATION
の設定は必須となる
- 注意 前提をいきなり覆すが、 Chrome を実行する場合
.npmrc
を使用する場合、正しいパス・設定が行われている前提となる- Windows で動かすことが前提となっていることに注意
# npm scripts: *-env 系の環境を設定
# 変数名の先頭に PTD_ を付与すること
# Firefox 設定
# プロファイルディレクトリ
PTD_FIREFOX_PROFILE_DIRECTORY=X:\fx
# Chrome 設定
# アプリパス
PTD_CHROME_APPLICATION=C:\Program Files\Google\Chrome\Application\chrome.exe
# プロファイルディレクトリ
PTD_CHROME_PROFILE_DIRECTORY=X:\ch
{
// 名前
"name": "example trans",
// バージョン
"version": "YYYY-MM-DD/x.xx.xxx",
// 対象ドメイン
"hosts": [
"example.com",
"www.example.com"
],
// 設定情報
"information": {
"website": "https://",
"repository": "https://",
"document": "https://"
},
// 優先度 0: 通常, 低 < 0 < 高
"priority": 0,
// 変換先言語
"language": "ja",
"watch": {
"window": [
// window 監視対象イベント
],
"document": [
// document 監視対象イベント
"pjax:end",
],
},
// パス
"path": {
// 対象パス(正規表現)
"^/$": {
// パスにクエリ部分を含めるか
"with_search": true,
// セレクタに対する処理
"query": [
// ID 指定
{
"selector": {
// 該当する <meta name=* content=*> に全条件を満たす場合にセレクタが使用される。
"meta": {
// 判定方法
// partial: 部分一致
// forward: 前方一致
// backward: 後方一致
// perfect: 完全一致
// regex: 正規表現
// not_empty: `content` が空でない
// ignore: パターンを無視(`content` を見ない)
"mode": "partial",
// 大文字小文字を区別するか
"ignore_case": true,
// パターン
"pattern": "pattern",
},
// セレクタ種別
// normal: 通常
// common: 共通
"mode": "normal",
"value": "#id",
// テキストノードの指定。 childNodes の #text だけを集計した 1 基底の番号: <span>[1]<br />[2]<br />[3]</span>
// 負数を指定した場合は全テキストノードが対象となる(matchesによる制御を想定)
// `-1` を指定すれば一致時点で後続終了、`-2`(負数-1未満) を指定した場合はすべて処理。
"node": 3,
// セレクタを全要素に適用するか
"all": false,
},
// 対象要素の (Element/Text).textContent
"text": {
"filter": {
// 改行をどう扱うか
// join: 半角スペース1つに置き換える
// raw: そのまま
"line_break": "join",
// 改行以外のホワイトスペースの扱い
// join: 半角スペース1つに置き換える
// raw: そのまま
"white_space": "",
// トリムを実施するか
"trim": true,
},
// 条件
"matches": [
{
// 判定方法
// partial: 部分一致
// forward: 前方一致
// backward: 後方一致
// perfect: 完全一致
// regex: 正規表現 (?<NAME>) 使用可能
"mode": "partial",
// 大文字小文字を区別するか
"ignore_case": true,
// パターン
"pattern": "pattern",
"replace": {
// 置き換え方法
// normal: 通常
// common: 共通
"mode": "normal",
// 条件が正規表現の場合で指定がある場合 `(?<NAME>)` を `$<NAME>` で使用可能
"value": "text",
// 条件が正規表現の場合にキャプチャグループ名に対する置き換え文字列を指定(未指定・一致しない場合にもと文字列)
"regex": {
// キャプチャグループ名
"NAME": {
// キャプチャした文字列に対する置き換え
"A": "aaa",
"B": "bbb",
}
}
}
}
],
// 置き換え(matches に該当しない場合)
"replace": {
"mode": "normal",
"value": "text",
}
},
// 対象要素の属性
"attributes": {
// 属性名
"attribute-name": {
// 属性値
}
}
},
{
"selector": {
"value": "html .class > child + next child[data-custom='xxx'] input",
}
// 置き換え処理
},
{
// 共通セレクタの使用
"selector": {
"mode": "common",
"value": "common-nav-logout",
},
"text": {
"replace": {
// 共通テキストの使用
"mode": "common",
"value": "common-nav-logout"
}
}
}
],
// 共通クエリの使用
"import": [
"common-query"
]
}
},
// 共通設定
"common": {
// 共通セレクタ設定
"selector": {
"common-nav-logout": "nav a.logout",
},
// 共通テキスト設定
"text": {
"common-nav-logout": "ログアウト",
},
// 共通クエリ設定
"query": {
"common-query": {
"selector": {
},
"text": {
}
}
}
}
}