ブックマークレット作ってたらくだらない仕様にハマったのでメモ。
記事タイトル「javascript:スキームで%(余剰)使ったらハマった件」と
どっちにしようか迷ったがブックマークレット~の方がわかりやすいかな、と。
(大晦日に投下する今年最後の記事がこれっていうね。 ある意味私らしいといえば私らしい。)
例えば以下のコードがある。
function getHours12h() { var nd = new Date(), AA = nd.getHours() < 12 ? "午前" : "午後", gg = nd.getHours() % 12; alert(AA + gg + "時"); }
現在時刻を取得し、12h表示で現在の時間をアラートするだけ。
まずはこのまま実行してみる。
<a href="#" onclick="getHours12h()">getHours12h()</a>
普通に実行できる。
次に、圧縮ツールに投下しインデント・空白・改行を削除、
関数名を削除し無名間数に丸めて実行してみる。
(function(){var nd=new Date(),AA=nd.getHours()<12?'午前':'午後',gg=nd.getHours()%12;alert(AA+gg+'時');})();
<a href="#" onclick="(function(){var nd=new Date(),AA=nd.getHours()<12?'午前':'午後',gg=nd.getHours()%12;alert(AA+gg+'時');})();">getHours12h (無名ver)</a>
ここまでは宜しい。問題は次。
↑のコードをjavascript:スキームで実行してみる。
<a href="javascript:(function(){var nd=new Date(),AA=nd.getHours()<12?'午前':'午後',gg=nd.getHours()%12;alert(AA+gg+'時');})();">getHours12h (javascriptスキーム)</a>
エラーになる。
- IE11
- Firefox
- Chrome
- Opera (Presto)
原因
記事タイトル見たらわかると思うが
原因はgetHours()%12;
←この部分。
%12が余剰演算ではなくパーセントエンコーディングとして解釈されてしまっている。
http://ja.wikipedia.org/wiki/%E3%83%91%E3%83%BC%E3%82%BB%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0
どうすりゃいいの
余剰演算子の%と数字(今回は12)の間に手動で半角スペースを入れる。
<a href="javascript:(function(){var nd=new Date(),AA=nd.getHours()<12?'午前':'午後',gg=nd.getHours()% 12;alert(AA+gg+'時');})();">getHours12h (%修正)</a>
半角スペースの部分はパーセントエンコードされても問題ない。
つまり、getHours()%%2012;
のようになっても問題なく実行できる。
(%%2012なんてパッと見じゃ何の処理なのかわからんよね…)
こんなくっだらない罠に気づくのに数十分食われた自分が悔しい。
パーセントエンコード考えた奴と余剰演算子パーセントにした奴ぶっ飛ばしてえ。
ってか、この件ggっても一切情報がない。
余剰計算自体滅多に使われるもんじゃないけど
さすがに1人くらいは記事にしててもいいのでは…
余談
Operaのデバッガ便利すぎてやばい。
エラーの原因がパーセントエンコード誤解釈だと気づけたのは
OperaのコンソールがU+0012と表示してくれたから。
IEも何文字目が該当箇所なのか地味に書いてある。
それに比べFirefoxやChromeのデバッガは何なんだ。
Illegal Characterとか言われてもどこだかわかんねーっつーの。
…ところで、16進数での12(ASCII 0x12)って一体何の文字なんだ?
ってことでggったら、どうやら Device Control 2 という制御文字らしい。
C0 and C1 control codes - Wikipedia, the free encyclopedia
http://en.wikipedia.org/wiki/Device_Control_2