iPhone Safariが勝手に改行!?シャドウコンテンツとは

iPhone Safariが勝手に改行!?シャドウコンテンツとは

どうも、さむらいです。

今回は、iPhone Safariが勝手にタグやらDOMやら追加してしまうシャドウコンテンツ(Shadow contents / Shadow DOM)についてです。

当社 ASP サービスのフォームアシストではカーソル自動移動機能というものがございましてね。郵便番号が 3 桁と 4 桁で分かれているようなフォームの場合、3 桁入力欄で3 桁を入力すると、4 桁入力欄に自動でカーソル移動してくれます。便利ですね。ええとっても。

そんな便利機能に真っ向から戦いを挑むあいつ(あれ、デジャヴ?)

前回の記事で、ここで出てきたフォームアシストの天敵は jQuery だったのですが、今回は違います。天下の Apple 様が提供する iPhone Safari です。

どうゆうことなのか。

カーソルの移動先フォームで入力した文字がちょっと縦にづれる…

イメージしづらいですよね。そんなときは画面イメージ。

image09

こんな感じ。みたことありませんか?

これ、再現方法は簡単で

1.移動先フォーム(上の図でいうと「6」が入力されている)に予め何か入力し、それをすべて削除する。
2.移動元フォーム(上の図でいうと「129」が入力されている)から、JSでカーソル移動する。

たったこれだけ。でもこの状態になると、maxlength を移動先フォームに指定している場合、入力可能文字数が減ります。なぜなのか?

それは・・・

何故か改行が入っている・・・

iPhone Safari は Mac にライトニングケーブルを繋げたあと、Mac 上の Safari から開発者コンソールを開くことで、iPhone の Safari で開いている Web ページの状態を確認する機能があります。

この機能を使って移動先フォームの中に何が入っているのかを見てみたらば・・

image07

うむ。なんの変哲もないエレメントだ。

だがしかし、よーっく見てみると、エレメントの左側に三角アイコンがあるぞ。なんだこれは。ということでクリックしてみる。

image06

Σ(; ゚Д゚)ウハッ 

シャ、シャドウコンテンツ!?

混迷を極める思考の中、恐る恐る三角をクリックして開いてみると、中身はこんな感じになっていました。

image01

なんすかこれ、div タグに編集可能領域属性がついていて、その中に改行が入ってるじゃん・・。

100 歩譲って、ああ Safari の input タグは div タグの editable 属性を追加して編集できるようにしているんですね、と理解できなくもないけど、改行を入れた覚えはない。どこから来たお前は。どこから来たんですかあなたは。

これはもしや・・・

バグじゃないですかこれは。Safari にバグがあります!Apple の Safari には文字を削除した時にシャドウコンテンツに≷br>が残るというバグがありますよ!!

と、縦にづれる理由がわかって一安心したさむらい。しかし悲劇はこれで終わらなかった。

そもそものフォームアシストの機能が・・・!?

カーソル自動移動機能の実際の処理ロジックはとっても簡単で、

1.移動先のエレメント.focus();
2.移動先のエレメント.select();

これだけ(嘘です、結構割愛してます)

プログラムを追いかけて上記の記述まで追いついた時に、 .select() でそもそも改行も含めて選択されるはずじゃ・・と思いネットを調べたら

iPhone Safari には .select() 関数にバグがあり、文字をすべて選択できない

これはもしや・・

バグじゃないですかこれは!Safari にバグがあります!Apple の Safari には .select() 関数で文字を選択できないというバグがありますよ!!

どうすんのよー!なんて思っていたら、同じ事象にぶちあたった人が解決方法も書いてくれてました。

フォーム.selectionStart = 0
フォーム.selectionEnd = 文字数

この 2 行を書くだけで改行も含めたすべての文字を選択できます。
さむらいがこの結論にいたる頃には、もうすぐ日付が変わろうとしていました・・・。

2013年の記事で指摘されていて直ってないということは、仕様なんでしょうかねー?

【参考】iPhoneのSafari(Mobile Safari)のselect()は、代わりにselectionStart, selectEndを使わなければいけない

わかったこと

iPhone Safari はシャドウコンテンツなる独自の構造を持っている。

Safari の input type=”tel” ( textも?) 項目で削除キーを押すとなぞの改行が残る。
(文字数分しか削除キーを押さなかった場合)

Safari の.select() 関数では最初の文字を選択できない。

他にもいろいろありそうだけど、シャドウコンテンツについてはネットにはほとんど文献がなくて、Apple の開発者向けサイトにちょっと記述があるだけでした。

https://developer.apple.com/library/mac/documentation/AppleApplications/Conceptual/Safari_Developer_Guide/ResourcesandtheDOM/ResourcesandtheDOM.html

これを見ると Webkit が自動的にシャドウコンテンツ( Shadow DOM? )を作り出す、みたいな書き方をしてるけど、Chrome はそんなことないし。単なるブラウザ実装なのかな。

もうほんとに、ブラウザとかどれか一つに統一してくれないかなー・・・この際 Mictosoft Edge でもいいからさー!世の中のASPサービスはブラウザが一つになるだけで、ものすっごく進化すると思うよー!ほんとにー!

ってことで、ではまた。

コメント