2024/11/14 Solomonの教科書のページめくりをユーザ側で自動化
Solomonの教科書ページめくりが面倒
アクセスした時点で、すべての行が表示されてほしい
PDFなどの一般的な形式に変換することをいったんゴールとしてみる?
形式A
https://scrapbox.io/files/67360ccd30d4fbd8e5883948.png
この形式では、各行が<p></p>要素で表現されている
1行目にはtext1、2行目にはtext2、...というクラスが振られている
デフォルトではdisplay: hidden
JavaScriptで、次へボタンを押したときにdisplay: blockを付けている
この形式のページに対してすべての行を一気に表示するスクリプトは
code:all_open.js
for (const text of document.querySelectorAll("class^=text")) text.style.display = "block";
ただしiframe内で動作させる必要がある
iframe内にContent Scriptを読み込むにはall_framesを指定する
形式B
libのprototypeにいくつか使えそうなものが入っている
Sourceを見れば分かるが、画面右下の再生ボタンはplaybuttonと呼ばれている
画面がクリックされるとfl_MouseClickHandlerが呼ばれる
fl_MouseClickHandlerの動作について
parent.cnsという値を、別のどこかで代入している?
1. parent.main.text(文字列)のparent.ct文字目を取得
2. その文字を名前として持つparentのプロパティにアクセスする
3. そのプロパティのplayメソッドを呼び出す
subが存在する場合は同様のことをする
mainを1段階進めると、subも1段階進む
parent.main.textへのイテレーションが * (アニメーション指定文字列の終端を表す)に達したタイミングで、subの遷移も終了する
this.parent.main.text
例'abcdefghiBj*end'
これを元にcnmを計算
this.parent.sub.text
例'AAAAAAAAAAAA'
cnsを計算
cnsやcnmの計算はそのまま拡張機能でやってあげれば良いかな。。t6o_o6t.icon
試行錯誤
initialize関数の定義が見当たらないので、CreateJSが提供する関数だろうか
各要素を表すコンストラクタ関数のprototypeはnew cjs.MovieCrip()に書き換えられているので..
各関数を、適切なthisをbindしたうえで呼び出せばよいか...?
そもそもClickイベントを発行しても何も起きないのは...?
発行したイベントX座標、Y座標が不適切?
HTML側に書かれたhandleComplete関数が、canvas変数のセットなどを行ったあとにnew lib._0003()を呼び出している
newを用いてコンストラクタ関数を呼び出したとき、thisは新しく生成されたプレーンなオブジェクトにバインドされる
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/new#解説
したがって、lib._0003の中で参照されているthisは、exportRoot変数と同一である
そのなかでplaybotton = new lib.bot()が呼ばれている
したがって、lib.bot内で参照されているthisは、exportRoot.playbottonからアクセスできるはずだ
注:playbottonはおそらく開発者の誤字である
自動めくりを実現できそう!
exportRoot.aなどの関数が開発者ツールのConsoleから呼び出せることが分かった
code:all_open_2.js
const match = exportRoot.main.text.match(/(.*)\*?end$/)1;
const subText = exportRoot.sub.text;
if (match) {
Array.from(match).forEach((c, i) => {
exportRootc?.play?.();
exportRoot[subTexti]?.play?.();
});
}
左側にフローチャートが表示されることがあるのだが、このスクリプトでは自動めくりができない
sub.textはAAAA...となっている。つまり、同じ要素に対して繰り返しplayを呼び出すことで、フローチャートのアニメーションが再生されている
mainの方は、要素が異なっていたので独立してアニメーションを再生できた
こちらでできることとしては、適切なタイミングでplayを呼び出し続ける...?
使えそうなもの
MovieClip.framerate
フレームレートを高速にしてplayし続ける?
MovieClip.goToAndStop
アニメーション名またはフレーム番号を指定できる?
アニメーション名とは?
フレーム番号を指定すればアニメーションをスキップできるのか?
MovieClip.startPosition
こっちのほうが簡単?
gotoAndStop(9999)で出来た。
code:all_open_3.js
const match = exportRoot.main.text.match(/(.*)\*?end$/)1;
const subText = exportRoot.sub.text;
if (match) {
Array.from(match).forEach((c, i) => {
exportRootc?.gotoAndStop?.(Number.MAX_SAFE_INTEGER);
exportRoot[subTexti]?.gotoAndStop?.(Number.MAX_SAFE_INTEGER);
});
}
あとはChrome拡張機能に組み込めば完了
if (exportRoot) { ... }で囲えばOK?
exportRootが定義されていないというエラーが出たので不適切。
代わりにtypeofがundefinedかどうかで未定義か確認することにした
https://qiita.com/DecoratedKnight/items/b368bc774d7d7ec0c888
iframeでだけ動作するようにしたい
https://stackoverflow.com/questions/326069/how-to-identify-if-a-webpage-is-being-loaded-inside-an-iframe-or-directly-into-t
完了
https://github.com/coolwind0202/solomonseek