HTMLエディタでの改行がIEとFirefoxで異なる

HTMLエディタでの改行がIEとFirefoxで異なる

- Tatsuya Shirai の投稿
返信数: 12

実はこの問題も前々から少し気になっていたのですが....

HTMLエディタ(htmlarea)を用いて文章の入力を行う際に,FirefoxとIEとではエンターキーを押した場合の改行の入り方が違います.例えば,以下はFirefoxで入力した場合です.

文章1
文章2
文章3

そしてこれがIEを用いた場合です.

文章1

文章2

文章3

このようにIEの場合は段落変えになります.Shiftキーを押しながら改行を行えば,

文章1
文章2
文章3

のように密着させることも可能ですが,一つの段落だけを選んでインデントを加えても,

文章1
文章2
文章3

全ての文章ブロックが一塊になっているため一緒にインデントされます.

Firefoxですと,

文章1
文章2
文章3

このように一部だけインデントを付けることが可能です.

タグエディタ画面(<>)を使ってソースを見てみると,きっとのその違いが分かるとは思うのですが,どちらでも同じように入力できるようにするにはどうしたら良いのでしょうか.

個人的にはFirefoxによる改行,の挙動が好ましい.既にこの問題に対して対策を施した方がいらっしゃるならば御報告お願いします.
Tatsuya Shirai への返信

Re: HTMLエディタでの改行がIEとFirefoxで異なる

- Tatsuya Shirai の投稿
Firefoxの場合は改行した場合は単純に,<br/>で改行されるのが, IEだと,<p>文章</p>で括られていますね.

IEでShiftキーを押して改行した場合は,全体を<p>と</p>で囲って,中は<br/>で改行されています.

ちなみに不勉強で申し訳ないのですが,<br>はよく使うのですが,<br/>は<br>とどう違うのでしょうか?
Tatsuya Shirai への返信

Re: HTMLエディタでの改行がIEとFirefoxで異なる

- Haruhiko Okumura の投稿
へぇっ,おもしろいですね。気づきませんでした。

<br> はHTML,<br />はXHTMLの書き方です。XHTMLは終了タグを省略できず,brのように終了タグがないものは<br />と書くルールになっています。
Tatsuya Shirai への返信

Re: HTMLエディタでの改行がIEとFirefoxで異なる

- Yuichi Saotome の投稿
信州大学の五月女です.

便乗して質問させてください.
この現象は私も前から調べているのですが,解決法が分からずに放置しています.

関連するかわかりませんが,IE,Firefoxかかわらず,<p>タグが入ったり入らなかったりしませんか?
トピックのラベル等を新しく編集するたびに<p>タグ入ったり入らなかったりします.
<p>タグが入ってると改行されて,入ってないと改行されないので,混在していると見づらくなってしまうんですよね.
htmleditorの実装を見てみましたが,再現性が分からずこちらも放置しています.

Yuichi Saotome への返信

Re: HTMLエディタでの改行がIEとFirefoxで異なる

- Tatsuya Shirai の投稿
いやぁ,ソースリストを読んで何がどうなっているのか頑張って調べてみようと思ったのですが,全く分かりませんね.

この問題はちょっと手に余る感じです.

----

<br>と<br/>の違いの説明ありがとうございました.

Tatsuya Shirai への返信

Re: HTMLエディタでの改行がIEとFirefoxで異なる

- Yuichi Saotome の投稿
Shirai先生でも分かりませんでしたか悲しい

これらの問題は,大きな実害は無いので余裕が出るまで放置ですね.

ご返答ありがとうございました.
Tatsuya Shirai への返信

Re: HTMLエディタでの改行がIEとFirefoxで異なる

- Tatsuya Shirai の投稿

IE7を使用するとHTMLエディタがハングアップすると,池田先生より指摘がありましたので,私のIE6もIE7にアップデートし,さらにできるだけFirefoxの代わりにIE7を使うようにしました.しかし,そうすると,本件が非常に気になって仕方がありません.

そこで少しだけ調べてみました.

やはりよく分からないのですが....取っ掛かりはmoodle/lib/editor/htmlarea/htmlarea.html中のHTMLArea.prototype._editorEvent = function(ev)にありそうです.このメソッドは,HTMLareaを生成する初期化用の関数,HTMLArea.prototype.generate = function ()の中で,

    HTMLArea._addEvents
          (doc, ["keydown", "keypress", "mousedown", "mouseup", "drag"],
          function (event) {
              return editor._editorEvent(HTMLArea.is_ie ? editor._iframe.contentWindow.event : event);
          });

で割り付けられているようです.何らかのキー操作やマウス操作が行われたら呼び出されるようです.

HTMLArea.prototype._editorEvent()の最後の方に,コメントコメントアウトされている,

/*
  else if (keyEvent) {
        // other keys here
        switch (ev.keyCode) {
            case 13: // KEY enter
            // if (HTMLArea.is_ie) {
            this.insertHTML("<br />");
            HTMLArea._stopEvent(ev);
            // }
            break;
        }
    }
 */

を生かして,以下のようにすると改行で<br />入力されるようになります.

//  /*
    if (keyEvent) {
        // other keys here
        switch (ev.keyCode) {
            case 13: // KEY enter
            if (HTMLArea.is_ie) {
            this.insertHTML("<br />");
            HTMLArea._stopEvent(ev);
            }
            break;
        }
    }
//  */

もちろん,これでは問題は全く解決されません.このままですと文章全体が一つの段落として<P>と</P>で囲まれてしまうため,それこそインデントを付けると文全てがインデントしてしまいます.


いま気付いたのですが,IEで入力を行うと,例えば上記ソースコードのように,半角スペースが統合されずに残ります.インデントで頭を下げないでも.
   ちなみに
       文章中に
          半角スペースでインデント風にしてみました.

このような書き込みを今度はFirefoxで編集しようとすると,空白は全て取り除かれてしまいます.

上記段落はタグで見てみると,


<p>いま気付いたのですが,IEで入力を行うと,例えば上記ソースコードのように,半角スペースが統合されずに残ります.インデントで頭を下げないでも.<br />   ちなみに<br />       文章中に<br />          半角スペースでインデント風にしてみました.</p>

このとおり.(半角<は全角に変更しています)

IEとIE以外で挙動が激しく異なるようです.困りましたねぇ.

Tatsuya Shirai への返信

Re: HTMLエディタでの改行がIEとFirefoxで異なる

- Tatsuya Shirai の投稿

ところどころに,

        if (HTMLArea.is_ie) {
            range.pasteHTML(sChar);
        } else {
            // insert the table
            editor.insertHTML(sChar);
        }

のようなコードがあります.IEならばpasteHTML()というrangeオブジェクト(IEのJavascriptの方言?)を使用し,IE以外ではinsertHTML()という独自の関数を用いています.きっとrangeオブジェクトの方が楽で便利なのでしょう.

多分,これらが影響しているのでしょうねぇ.では,IEでもeditor.insertHTML()を使用すれば良いと思うのですが,何か問題でもあるのでしょうか...先の改造(コメントアウトされていたIE用のコード)にもinsertHTML()が含まれて居ますので,IEでも実行可能だと思います.

Tatsuya Shirai への返信

Re: HTMLエディタでの改行がIEとFirefoxで異なる

- Tatsuya Shirai の投稿

 if (HTMLArea.is_ie) {
            this.insertHTML("<br />");
            HTMLArea._stopEvent(ev);
            }
を有効にすると,Firefoxに近い挙動になりますね.ただ,<P>と</P>で囲まれてしまう問題をどう解決するか.

HTMLソースモードで入力すると,<P> </P>で囲まれないことは分かりました.WYSWYGモードに戻しても大丈夫です.ところがインデントボタンを押すと,やはり全体が<P>と</P>で囲まれてしまいます.

これを抑制できればFirefoxとIEで同じような入力になりそうです.さらにIEの場合,(無改造で)文章中の半角スペースが保存されるという機能もオマケで付いてきます.

ただ,indentを押すと,どのような仕組みで<P>と</P>で文章全体が囲まれてしまうのか,が,依然として不明です.

Tatsuya Shirai への返信

Re: HTMLエディタでの改行がIEとFirefoxで異なる

- Tatsuya Shirai の投稿

 インデントやSmileアイコンの挿入といったHTMLareaのコマンドはHTMLArea.prototype.execCommand = function(cmdID, UI, param)でまとめて処理しています.
 cmdIDはコマンドの種類を表すアルファベット小文字の文字列で,例えば"hilitecolor"や"unlink"など.いま例に挙げたのはHTMLarea内に実装された独自の命令で,それ以外の"indent"や"outdent"などのJavascriptで実行できるリッチテキスト編集用のコマンドは,
 Switch (cmdID)のdefalut:で,default: this._doc.execCommand(cmdID, UI, param);のように,投げています.doc.execCommand()は各ブラウザのJavascriptが実行するようです.つまりIEやFirefoxで動作が異なる可能性があります.

(Mozzila)
http://www.mozilla-japan.org/editor/midas-spec.html

(IE)
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/vbafpw10/html/fpmthexecCommand.asp

http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/Vbafpd11/html/fpmthexecCommand.asp

で,実際に動作が異なるのでしょう.

例えばindentする場合,Firefoxではカーソルのある行,あるいは選択されている複数行を<div style="margin-left: 40px;">で囲むことでindentを実現している.

それに対してIEのJavascriptでは,カーソルのあるブロックを<blockquote dir="ltr" style="margin-right: 0px">で囲む.もしカーソルのあるブロックが<p></p>で括られていなければ全体を<p></p>で囲む.

右寄せする場合,Firefoxならば,<div style="text-align: right;">で囲むのに対して,IEではカーソルのあるブロックを<p align="right">で囲む.もし<p></p>で括られていなければ全体を<p></p>で囲む.

このように同じexecCommand()に対して実装がブラウザによって異なること,特にIEでは<p></p>を自動挿入する機能が行単位(あるいは選択された行単位)ではない点に今回の問題はあります.

HTMLArea.prototype.execCommand = function(cmdID, UI, param)のswitch (cmdID)に対して,独自のcase "indent"を追加することで,互換性の違いを吸収することもできるのかも知れません.ちょっといまの私には手に余る感じです...不可能ではないと思うのですが.


リンクを解除する"unlink"は,

HTMLArea.prototype._removelink = function() {
    var editor = this;
    link = this.getParentElement();
    editor.selectNodeContents(link);

    this._doc.execCommand("unlink", false, null);
    this.focusEditor();
};
という関数を使用しています.多分,カーソルのあるブロックを抽出する機能をもっているのではないでしょうか.この関数を参考にすればもしかしたら実装できるかも?

なお,ノードという考えをよく理解できていないのだが,IE, Firefoxではかなり異なるらしい.この辺りも関わっていそう.実際,上記コードを流用してindentモドキの実装を試みたところ,IEではカーソルの存在する行ではなく全文がノードとしてselectされてしまった.多分,Firefoxではカーソルのある一行(<br/>まで)をselectしてくれるのでしょうね.(unlinkの場合は<a>と</a>で囲まれているので,IEでもFirefoxでもこれを一つのノードと解釈してくれる,ということかな)

http://www.techdego.com/2007/01/dom.php

Tatsuya Shirai への返信

Re: HTMLエディタでの改行がIEとFirefoxで異なる

- Tatsuya Shirai の投稿

 一人で長々と申し訳ありません.

 IEとFirefoxのHTMLエディタ(HTMLarea)での挙動の違いについて以下にまとめます.

1.改行時の挙動の違い

 IEで改行を行うと,文章は一つの段落として<p></p>で囲まれる.Shift+エンターキーで改行(<br />)を行った複数行の文章があったとしても,それは一つの文章になる.したがって,Shift+エンターキーで改行した文章の一部をインデントしたり,センタリングしたりといった装飾は行えない.なによりも,エンターキーを押すたびに,前の行との間に1行分の隙間が行間に生じてしまう.
 Firefoxで改行を行うと,単純にその箇所に<br />が挿入されるだけである.したがって前の行との間に隙間は生じないし,好きな行だけを選んでインデントやセンタリングが可能である.

2.空白文字などが自動的に消去される/されない

 IEは(行頭も含めて)入力された文章を<p></p>で囲むため,入力された半角空白も正しく入力されたまま出力される.それに対してFirefoxなどはベタにHTML文章に文字が埋め込まれるため,後処理などによって重複する半角空白等は正規化されて消去される.たとえば空白スペースでインデントされたソースリストをコピー&ペーストした場合,IEから入力した場合はイメージ通りに出力されるが,Firefoxなどから入力した場合は連続する複数の空白文字(半角スペース,全角スペース)は1個の半角スペースに置き換えられ,出力時には行頭の半角スペースは無視されるため空白文字で字下げしたインデントは全て消えてしまう.したがって明示的にインデントを指示する必要がある.


 2の問題を考えると,実はIEのように改行までに入力された文章を一つの段落として<p></p>で囲むのは正しいのではないかと考えるようになりました.IE以外のブラウザで,キー入力された文章を<p></p>で囲まないまま,HTMLに埋め込んでいる方が無責任であるような気がします.

 ではこの問題をどのように改善すべきかと言うと,単純にパラグラフ(段落)間のマージンをゼロにするだけで良いのではないでしょうか.CSSで<p></p>のマージンを変更できるらしい,ことまでは調べて分かってきたのですが,まだ実験は行っていません.心配なのは,HTMLエディタで入力しているときはパラグラフ間のマージンがゼロで,Shift+エンターキーで改行しても,単に改行しても,見た目は変わらないように行間が密着して改行できるようになったとしても,フォーラムを表示する際には,また行間が開いてしまうのではないか.あるいは画面全体の表示に影響を与えてしまわないかなどなど. 


参考URL
http://www.asahi-net.or.jp/~wq6k-yn/para.html  


htmlarea.php中でスタイルを指定している箇所を修正することで,パラグラフ前後の行間をゼロにすることができました.入力時は小さなエディタでもフルスクリーンエディタでも行間はゼロにできました.でも,これはあくまで入力時の対策であって,当然ながらフォーラムで表示する際には行間が開いてしまいます...
Tatsuya Shirai への返信

Re: HTMLエディタでの改行がIEとFirefoxで異なる

- Tatsuya Shirai の投稿

 いままではHTMLエディタでの文字入力に関して,Firefoxの使用が好ましいという立場で居ましたが,今後はIEを薦める立場に変更しました.

 IEだと,

 文章1
 文章2
 文章3

のようにShift+改行で入力した3行の途中の文章2だけをインデントしたり,センタリングできないという点を問題視し,改善方法を探ってきました.そもそものスタートは,上記仕様ではソースリストのインデントが表現できないではないか,というつもりでした.
 ところが実際には,Firefox等では正規化されて消去されてしまう文頭の空白文字がIEから入力した場合は(<p></p>で囲まれているため)入力したまま出力可能である,つまりソースリストのインデントが空白文字で可能であることが判明しました.インデントが空白文字で入力されているソースリストならば,テキストエディタからCopy&Pasteするだけで良い.これは書き込む側だけでなく,読み出しを行う側もブラウザ上でコピーしてテキストエディタにペーストするだけで良いというメリットがある.

 確かに
              ここだけセンターリング(実際には空白で字下げしています)
といった書き方をしたいこともあるでしょうし,

  1. 箇条書きをする際に
  2. 必ず前の段落との間に
  3. 空行が入るのもイヤではあります.

 この辺りのクセに慣れれば,それほど気になりません.

#気になっていたのは私だけかも知れませんね赤面

 どちらかと言うと,IE以外のブラウザの方をIEの出力に合わせるべきなのかも知れない,とまで考えるようになりました.フォーラムの書き込みなら良いのですが,Wikiの場合には色々な人が色々なブラウザで編集を行います.その際に,IEとIE以外の異なったブラウザで処理を行った際に,予期せぬ副作用が発生しないかが,少しだけ心配です(多分,大丈夫).

 したがって,「IEでのHTMLエディタの挙動が変」という立場での意見はこれで一時中断します.ただ,皆さんの考えはとても気になりますので,IEとIE以外での挙動の違いについて何か御意見のある方は,是非とも返信お願いします.

#ここ暫くはIE7で書き込みを行っていますが,池田先生の仰るようなIEのハングアップは発生していませんねぇ.WindowsXP SP2です.

Tatsuya Shirai への返信

Re: HTMLエディタでの改行がIEとFirefoxで異なる

- Tatsuya Shirai の投稿

 HTMLareaで同じ現象に気付いている人が他にも居ました.

http://nlogn.ath.cx/archives/000328.html
(Mozilla での不可解な動作)

 この方の判断は私と同じですが,それに対して,「二重改行だ」とか,「<p>で括られて変」といった書き込みがいくつかあります.私も人のことは言えませんが...解釈は人によって違いますね.

 どこかにFirefoxでもIEと同じように改行すると<p>で括られ,Shift+改行すると<br />が挿入される,という改造を成功させた方がいらしたら御紹介お願いします.