ゆるめ

ゆるめなのは公開範囲です。

Mastodon の投稿欄をブックマークレットでいじるコツ

Mastodon には react が使われているため、度々それ由来の罠にはまることがあります。投稿欄の文言を変更する操作なんかがそれです。そのままだと変更できたように見えて実はできていない状態になってしまいます。

{
	const tootArea = document.querySelector('.compose-form textarea');
	const replacedText = tootArea.value.replace(/$/, ' #ハッシュタグ'); // 例として末尾にタグ付け 
	Object.getOwnPropertyDescriptor(Object.getPrototypeOf(tootArea), 'value').set.call(tootArea, replacedText);
	tootArea.dispatchEvent(new Event('input', { bubbles: true }));
}

解決策としては上記のような書き方をすると変更できるようになります。

参考までに以下のブックマークレットを参照してください。
[?]絵文字の隙間詰め - Hatena::Let
[?]となっているのは Hatena::Let の不具合で絵文字が消え去った名残で、はじめは[🐘]と書かれていました。

本当は過去五年の間にやたらめったら生み出したブックマークレットやユーザスクリプトを紹介したいのですが、なんなら他の方が生み出した資産も紹介したいのですが、私含め皆様 v4.0 に向けた対応や動作確認や放置等の作業の真っ最中で、タイミングが悪いので、本日は取り急ぎ要件のみということで。

きごるふ(記号プログラミング + コードゴルフ)


始まりは orumin さん*1のトゥートが読めなかったので、書けるトゥートを何気なくぶつけたあたりです。以下使用環境および言語は Firefox 67.0b18 の Web コンソールにばちばち打ち込んだ JavaScript だと思ってください。



そこへ id:unarist さんがこちらのコードを括弧だらけにした上、戻り値も括弧だったら面白いんじゃないか的発想で乗ってきました。

({[[]](){[]}}[[]]())

これは、ES2015 からオブジェクトの中で関数を書く時に { 関数名 () {} } のような省略形で書けるようになった*2のと、{ "": 0 } のように空文字列でもプロパティを作れること、そしてブラケット表記法で書かれたプロパティは文字列に変換されること*3と、[] を文字列化すると ""(空文字列)になることのコンボで成り立っています。

しかし、アロー関数で簡潔文体*4を使った時以外は、関数内で明示的に return を書かないと戻り値が発生しないので、せっかく書いた [] が無駄になってしまっています。


記号だけで return 付きの関数を 500 字以内で記述するのは直感的に無理そうな気がするという旨の発言が以下です。

過去に何度か Mastodon 1 トゥート(500字)プログラミングで遊んでいて、記号のみで文字列を出力した際に骨が折れたなという記憶に基づいて発言しました。実際は記号であれば何でもいいゆるい縛りだったので、変数を使いまくって八文字の出力を達成していました。

ちなみに何らかの括弧(実質 [] 固定ですが)を返すコードは、括弧のみ縛りをしなければ、私が書いたものにちょっと手を入れて

({[[]]:()=>([])})[[]]()

で達成できます。なんなら

(()=>([]))()

でもいいし、ぶっちゃけ

[]

が一番短いのですが、今回は括弧でこさえた関数の戻り値も括弧だったら面白いねというテーマなので、括弧を返す関数を括弧で構築していきます。可能であれば 1トゥート 500字以内に収めたいですが、直感が無理だと言っているのでその辺はそこまでこだわりきらないことにして、なるたけ近づける、程度でいきます。

本当は元のコードのように純粋な括弧縛りでいきたかったのですが、どうしても + は使わざるを得なかったので、そこだけ勘弁してください。

参考にした記事[]()+= の六文字縛りで、特にゴルフ要素なくのびのびと記述していて、[](){}<>+ で 500字以内が目標という今回のレギュレーションとは少し違っていたので、自分で工夫を凝らす必要がある場面がいくつかあり、楽しかったです。


まず骨組みとして

(function(){}['constructor'])('return[]')()

というものを組み、"constructor""return[]" という文字列を記号で置き換え、function(){} もそれに相当する何かに置き換えていくという方向になりました。

これは記号のみで JavaScript を書く際に現状ほぼ必ず通る道なのですが、Function("return[]") のような書き方で作り出した文字列をコードとして実行することができる(eval 相当)ため、そして 任意の関数.constructor を参照すると Function になっているため、まずは "constructor" という文字列の獲得を目指すのです。

ちなみに 任意のオブジェクト(数値でも文字列でもなんでも).constructor が関数になっているため、任意の何か.constructor.constructor が組めれば eval を得たも同然になります。今回はゴルフも兼ねているのでそちらは使いませんでしたが、同じ文字列で一気に問題を解決していく様はとても爽快ですね。

あと、細かいことですが、"return[]" のように括弧類で始まる式を構文に書く際にはスペースが省略できる場合があるので、とりあえず削ってみて実行してみると良いかもしれません。for(i of[]) なども過去にゴルフで使いました。


置き換えるにあたって、はじめに "文字列"[添字] で使う文字を切り出していく際の添字用数字を捻出しました。以下が今のところ最短です。

+[] // 0
++[[]][+[]] // 1
++[++[[]][+[]]][+[]] // 2
++[++[++[[]][+[]]][+[]]][+[]] // 3
++[++[[]][+[]]][+[]]<<++[[]][+[]] // 4
++[++[++[[]][+[]]][+[]]<<++[[]][+[]]][+[]] // 5
++[++[++[[]][+[]]][+[]]][+[]]<<++[[]][+[]] // 6
++[++[++[[]][+[]]][+[]]][+[]]<<++[++[[]][+[]]][+[]] // 12

"[object Object]" の "c" を参照する際、一つ目の "c"(5) より二つ目の "c"(12) を参照した方が 3<<2 で短くなるのではと試してみましたが、5 の方が文字数が少なくなったので実際は使っていません。


それから、文字列の素材を用意しました。

{}+[] // "[object Object]"
[][[]]+[] // "undefined"
(+[]+[]>[])+[] // "true"
([]>[])+[] // "false"
{[[]](){}}[[]]+[] // "[[]](){}" (function)

これはコピペして実行するとエラーになる({} がオブジェクトのくくりではなくブロックのくくりとして解釈されるため、文法エラーになる)ので、試したい場合は適宜 () を補って実行してください。


これらを組み合わせて、以下の文字を生成しました。

((+[]+[]>[])+[])[+[]] // "t"
((+[]+[]>[])+[])[++[[]][+[]]] // "r"
(([]>[])+[])[++[++[++[[]][+[]]][+[]]][+[]]] // "s"
({}+[])[+[]] // "["
({}+[])[++[[]][+[]]] // "o"
({}+[])[++[++[++[[]][+[]]][+[]]<<++[[]][+[]]][+[]]] // "c"
({}+[])[++[++[[]][+[]]][+[]]<<++[[]][+[]]] // "e"
([][[]]+[])[++[++[++[[]][+[]]][+[]]][+[]]] // "e"
([][[]]+[])[+[]] // "u"
([][[]]+[])[++[[]][+[]]] // "n"
({[[]](){}}[[]]+[])[++[++[[]][+[]]][+[]]] // "]"

これもスクラッチパッドにそのまま貼り付けるとエラーが起きるので、行末に ; を補うか、一行ずつコンソールに入力して実行する形にしてください。

最初は "[object Object]" の方から "]"(14)を取ってこようかと思っていたのですが、14 という数字が半端なく、そして果てしないので、関数を一つ作ってそれを文字列化させ、そこに関数名として含まれる "]"(2)を取ってくる方向に変えました。

function(){} はたった今 "]" の取り出しに使った {[[]](){}}[[]] をもう一度そのまま使うことにしました。元のコードからだいぶ変わり果ててしまったコードの中で、元のコードの根幹がこうして別の形で現れてくるのは、なかなかにドラマチックですね。


これらを組み合わせてできたのが以下のコードです。

({[[]](){}}[[]][({}+[])[++[++[++[[]][+[]]][+[]]<<++[[]][+[]]][+[]]]+({}+[])[++[[]][+[]]]+([][[]]+[])[++[[]][+[]]]+(([]>[])+[])[++[++[++[[]][+[]]][+[]]][+[]]]+((+[]+[]>[])+[])[+[]]+((+[]+[]>[])+[])[++[[]][+[]]]+([][[]]+[])[+[]]+({}+[])[++[++[++[[]][+[]]][+[]]<<++[[]][+[]]][+[]]]+((+[]+[]>[])+[])[+[]]+({}+[])[++[[]][+[]]]+((+[]+[]>[])+[])[++[[]][+[]]]])(((+[]+[]>[])+[])[++[[]][+[]]]+({}+[])[++[++[[]][+[]]][+[]]<<++[[]][+[]]]+((+[]+[]>[])+[])[+[]]+([][[]]+[])[+[]]+((+[]+[]>[])+[])[++[[]][+[]]]+([][[]]+[])[++[[]][+[]]]+({}+[])[+[]]+({[[]](){}}[[]]+[])[++[++[[]][+[]]][+[]]])()

実行結果は [] になります。今試しに Google Chrome でも実行してみましたが、想定した実行結果になりました。


残念ながらというかやはりというか、578文字から縮められず、1 トゥート内には収まりきらなかったのですが、最初に Mastodon で出した 739文字のコード(

({[[]](){}}[[]][({}+[])[++[++[++[+[]][+[]]][+[]]<<++[+[]][+[]]][+[]]]+({}+[])[++[+[]][+[]]]+([][[]]+[])[++[+[]][+[]]]+[([]>[])+[]][+[]][++[++[++[+[]][+[]]][+[]]][+[]]]+({}+[])[++[++[++[+[]][+[]]][+[]]][+[]]<<++[+[]][+[]]]+[(++[+[]][+[]]>[])+[]][+[]][++[+[]][+[]]]+([][[]]+[])[+[]]+({}+[])[++[++[++[+[]][+[]]][+[]]<<++[+[]][+[]]][+[]]]+({}+[])[++[++[++[+[]][+[]]][+[]]][+[]]<<++[+[]][+[]]]+({}+[])[++[+[]][+[]]]+[(++[+[]][+[]]>[])+[]][+[]][++[+[]][+[]]]])([(++[+[]][+[]]>[])+[]][+[]][++[+[]][+[]]]+({}+[])[++[++[+[]][+[]]][+[]]<<++[+[]][+[]]]+({}+[])[++[++[++[+[]][+[]]][+[]]][+[]]<<++[+[]][+[]]]+([][[]]+[])[+[]]+[(++[+[]][+[]]>[])+[]][+[]][++[+[]][+[]]]+([][[]]+[])[++[+[]][+[]]]+({}+[])[+[]]+({[[]](){}}[[]]+[])[++[++[+[]][+[]]][+[]]])()

)から 161文字削れて、個人的には大分健闘したなと思ったので、こうしてブログ記事として仕上げて出すことにしました。

もしこのレギュレーションで 500字まで削れましたらご一報ください。Mastodon の方で紹介したいと思います。

ぐー🏠⛳

ライトニングトークというものを生で見たことがないのですが、その状態を逆手に取って、何も知らないまま想像でライトニングトークを語ったらおもしろいのではないかとふと思い立って、トークしました。

f:id:pacochi:20190321072815j:plain:w400
Google Home でいかに短く指示を伝えるかという話です。

前述の通り音が出ますのでご注意ください。

音声をつけたら好きなタイミングでクリックができなくなってしまったので、元のスライドも公開しておきます。

これがもう総合的にとてもとても難しくて、さらっとネタを用意してスライド書いて過不足なくスピーチする皆様がいかにすごかったかをしみじみ実感しました。

後から思ったのですが、短くするコツなんかも入れた方が良かったかもしれませんね。ここで補足しておくと、「亭主関白になりきる」みたいな感じでしょうか。

追記: 音声付きスライドを投稿していたニコナレがサービス終了したので、YouTube に移しました。

私だけはてなブログにスターがつけられなくなった原因と対処法

Mastodon ブーム以来ずっとそちらの方にいたのですが、ここ最近観測範囲で書かれる Advent Calendar のはてなブログ利用率が高く、一周してはてなに戻ってきた感じがあります。

戻ってきたのはいいのですが、SSL 化の影響か、はてなブログの記事にスターがつけられなくなっていて、とても不便を感じました。

f:id:pacochi:20181216235751p:plain
ログインしているのにログインしていないと言われる

また、サードパーティー Cookie を有効にしているのですが、上部のバーでも無効になっていますと言われてしまいました。

f:id:pacochi:20181216235937p:plain
サードパーティー Cookie が無効になっていますが出る

他の方は難なくスターをつけているので、私の側で何か余計なことをしているのかなと思い、その線で検証していきました。

原因は、Ghostery の「強化された追跡防止」という機能によってその辺の情報がせき止められていたことによるものでした。

f:id:pacochi:20181217000341p:plain
盾マークが強化された追跡防止、六件ブロックされている

盾マークをクリックして灰色にしてからリロードすると、上部のバーもはてなスターも復活しました。

信頼するサイトに入れるほどすべてのはてなブログを信頼している訳ではないので、スターをつける時だけ盾を外してつけようかと思っています。