フォーマットされたテキストを挿入する際の、より良いアンドゥサポートを追加

現在 Discourse では、コンポーザーにプレーンテキストを貼り付けると、通常のブラウザの動作である Ctrl+Z でその貼り付けを取り消し、貼り付けられたテキストを削除できます。しかし、この太字のような書式設定されたテキストを貼り付けた場合、取り消しは機能しません。同様に、テキストの上にリンクを貼り付けてリンク化した場合も取り消すことはできません。ショートカット Ctrl+B で挿入されるマークダウンや、コンポーザーのツールバーオプションから書式を追加した場合も同様です。理想的には、これらのほとんどが取り消しスタックに追加され、Ctrl+Z が正常に機能するようにしたいです。

私が頻繁に経験する状況を説明します。

  1. 他のウェブサイトから、リンク、太字、ヘッダーなどの書式設定がされたテキストをコピーします。(時々この事実が認識され、時々認識されないことがあります。)
  2. Discourse に移動し、すでに部分的に書かれている投稿にこのテキストを貼り付けます。
  3. Ctrl+V を押すと、書式設定されたテキストが挿入されます。
  4. 間違いに気づき、Ctrl+Z を押しますが、何も起こりません。
  5. 間違って挿入した書式設定されたテキストを手動で削除します。(ほとんどの場合、間違って貼り付けたのはリンクされたバージョンであり、単に「#」などを削除するだけではありません。
  6. 最初にやるべきだった Ctrl+Shift+V を押して、書式設定されていないテキストを貼り付けます。

明らかにこれは部分的にユーザーエラーですが、私が間違えなければ(他のウェブサイトからコピーして Discourse にプレーンテキストとして貼り付けるだけなので、わずか2ステップです)、間違った場合(ほとんどのウェブサイトは書式付きの貼り付けを行わないため、私は Ctrl+V を押すことに慣れています)、Ctrl+Z が通常通り機能すれば、時間を節約できるでしょう。

「いいね!」 4

これは通常、ブラウザのネイティブな動作であり、Discourse が行っていることではありません。HTML のプレーンテキストボックスでテストしてみてください。

JavaScript を使用してインプットを直接変更する場合、デフォルトでは元に戻す機能が機能しません。しかし、調べたところ、document.execCommand を使用すると、元に戻すスタックに追加しながらテキストを挿入できることがわかりました。

たとえば、document.getElementById('myInput').value = 'asd' を実行してから Ctrl+Z を押しても、元に戻りません。

しかし、カーソルが目的の位置にある状態で document.execCommand('insertText', false, 'asd') を実行すると(現在の Discourse のワークフローに基づけばそうなるはずです)、テキストは正しく挿入され、Ctrl+Z で期待どおりに追加されたテキストを削除できます。

基本的に、document.execCommand(または別の方法がより良いと見なされる場合は他のプロセス)を使用して元に戻すスタックに追加し、これらのケースで Ctrl+Z が機能するようにできるかどうかを知りたいです。

「いいね!」 3

いいえ — ブラウザのネイティブのテキストボックスの元に戻す処理が、すべての標準的なウェブサイトで機能するように、数年前に意図的にDiscourseからそのサポートを削除しました。

「ブラウザのネイティブなテキストボックスの元に戻す処理を、標準的なウェブサイトで機能するようにする」とは具体的にどういう意味でしょうか? 私が知る限り、Discourse では書式付きテキストの元に戻す機能はまったく機能しませんが、元に戻す機能が機能しないことが標準的なウェブサイトの動作だということでしょうか?

混乱している理由は、Discourse 以外で書式付き貼り付けをサポートしているウェブサイト(元に戻す機能が機能する Microsoft Word のようなものを除いて)を思いつかないからです。そのため、Discourse と比較して「標準」が何であるかを確認するための比較対象がありません。比較のためのウェブサイトをいくつか教えていただけると大変助かります。

「いいね!」 2

参照してください

Try it yourself をクリックしてから、テキストボックスにテキストを入力し、一時停止してから Ctrl+Z を押して操作を元に戻します。デモはこちらです。まず Try it yourself ボタンをクリックすると、ブラウザに HTML の <textarea> が表示されます。

テキストボックスにテキストを入力します。スクリーンショットでわかるように、次のように入力しました。

I JUST TYPED THIS TEXT YAYYYY!

入力後、Ctrl+Z を押して入力を元に戻すと、次のようになります。

テキストは以前の状態に戻り、これは 100% ブラウザ自体によって処理され、JavaScript コードは一切関与していないことに注意してください。

私の理解では、@seanblue は、ブラウザが undo をより適切に処理できるように、textarea を操作する際に使用するブラウザ API を変更できるかどうかを尋ねています。したがって、これはキーボード ショートカット、ツールバー、アップロードなどにのみ適用されます。

ここで調整することに反対しているわけではありませんが、これらの API の一部には細心の注意が必要であり、確実にリグレッションのリスクがあることを懸念しています。

ここでの実験に反対しているわけではありません。コミュニティが、やり方を示すためにプルリクエストを送信したい場合は、おそらく可能です。

「いいね!」 7

もっと改善できる点があります。ツールバーのボタンや貼り付けの動作の多くは、JavaScriptで直接テキストエリアの値を設定しています。これにより、ブラウザのネイティブな元に戻す/やり直し履歴が完全に壊れてしまいます。

代わりに、テキストエリアをプログラムで変更する際には、document.execCommand を使用すべきです(@seanblue が言及したように)。そうすれば、ブラウザはユーザーのアクションと同じように解釈し、元に戻す/やり直し履歴にきれいに挿入します。

insertText コマンド。これは、プレーンな textarea および input 要素で、カーソルの位置のテキストをプログラムで置き換え、元に戻すバッファ(編集履歴)を保持するために使用できます。

「いいね!」 10

しかし、そのテキストボックスは書式付きテキストを処理できないため、私が話していることとは異なります。ブラウザが通常の入力テキストや貼り付けたテキストの元に戻す操作を処理することはわかっています。私の言いたいのは、Discourse は書式付きテキストの貼り付け操作の元に戻す操作を処理できないということです。私が言っていることを確認するには、次の手順に従ってください。

まず、Discourse のコンポーザーを開きます。

次に、次のテキストをコピーしてコンポーザーに貼り付けます: this is a test

次に Ctrl+Z を押すと、貼り付けたテキストが削除されます。これは、投稿で示した動作とまったく同じです。

今度は次のテキストをコピーしてコンポーザーに貼り付けます: this is a great test
「great」をイタリックにするためのマークダウンとともに貼り付けられることに注意してください。

次に Ctrl+Z を押すと、貼り付けたテキストがまだ残っていることに注意してください。これが私が話していたことです。


その通りです。JavaScript で元に戻す操作を自分で処理することを提案しているのではありません。テキストエリアを操作する際に、ユーザーが Ctrl+Z を押したときにブラウザが変更を元に戻せるようにブラウザに通知することを提案しています。

参考までに、書式付きテキストを貼り付けた後に Ctrl+Z が機能すれば、私のフラストレーションの 99% は解消されます。すべての操作を Ctrl+Z で元に戻せることが理想的でしょうか?確かに。しかし、ほとんどの他の操作は、元の操作を繰り返すことで元に戻すことができます(たとえば、Ctrl+B を行うと、太字のマークダウンを追加したり削除したりできます)。しかし、貼り付けの場合、ヘッダー、リンク、さらにはテーブルなど、予期しないマークダウンが大量に含まれる可能性があるため、その場合に元に戻す操作が機能することが非常に重要です。

スコープを書式付きテキストの貼り付けの元に戻す操作のみを処理し、他のショートカット、ツールバーボタンなどを無視するように狭めた場合、リスクは十分に軽減されて試す価値があるでしょうか?

「いいね!」 9

なるほど、あなたと@davidさんの説明で区別が分かりました。エディタのこれらのボタンは、ほとんど使ったことがありません。テキストボックスには、コンピューターのキーボード(物理または画面上)を使って入力しており、これはブラウザによってシームレスに処理されます。

「いいね!」 6

それは理解できます。私もツールバーのボタンではなく、マークダウンを直接入力する傾向があるので、その点は私にとって問題ではありません。ツールバーの件は、フォーマットされたテキストを貼り付けたときだけ起こるわけではないことを指摘するために、OPで言及しただけです。ツールバーのアクションを元に戻せることは、ユーザーが意図的にそれらのアクションを実行しているので、それほど重要ではありません。しかし、貼り付けの場合、フォーマットはしばしば偶発的で予期しないものなので、それを元に戻せると非常に便利でしょう。

「いいね!」 6

こちらについてフォローアップし、近い将来に作業が行われる可能性について確認したいと思います。

「いいね!」 3

まだスケジュールされていませんが、はい、うまくいきそうです。ツールバーと CTRL-B ショートカットやメンションのようなものの両方で、実装を変更すべきだと思います。

ただし、これはかなり大変な変更で、すべてを組み込むには 1~3 週間かかると言えます。多くの領域があります。

  • 画像のコピー&ペースト
  • アップロード
  • 太字 / 斜体
  • リンク
  • @メンション
  • #オートコンプリート

この変更は支持しますが、いつスケジュールできるか確信がありません… 次のリリースに組み込んでも構いませんが、何か異論はありますか @codinghorror

最初のメンション、リンクなどでブロックされるのではなく、CTRL-Z で空のボックスまで戻れるようになるのは良いと思います。

「いいね!」 8

良い点は、(私の意見では)すべてを一度にリリースする必要はなく、段階的に合理的に行うことができることです。もちろん、技術的な観点からそうなるかどうかはわかりませんが、ユーザーの観点からは問題ないと思います。論理的な分離は次のようになるかもしれません。

  • 太字、画像、リンクなどの書式設定されたテキストの貼り付け
  • メンション、カテゴリ/タグ、絵文字の自動補完
  • 太字のCtrl+Bなどのキーボードショートカット
  • 太字、詳細の非表示、スポイラーのぼかしなどのツールバーアクション

これらの各グループは、ユーザーを混乱させることなく個別に完了できると感じており、個人的にはその順序で実装します。

「いいね!」 8

この作業は次回のリリースに組み込みます。つまり、今後約6か月かけてクリーンアップを進めます。一朝一夕にはいきませんが、進捗はあります。

「いいね!」 8

4ヶ月経ったので、進捗状況を確認したかったのです。:slight_smile:

「いいね!」 2

ええ、おっしゃることはよくわかります。しかし、もう少し時間がかかりそうです。

コンポーザーの完全なリファクタリングが必要な状況にまで発展してしまいました。長期的な計画としては、コンポーザーに別の抽象化レイヤーをサポートすることですが、現在は常にTEXTAREA要素であることが非常に強く結びついています。

最初にブロッカーを解除する動きは、現在のテキストエリアのように見え、動作するcontenteditableコンポーザーをサポートすることです。

このプロジェクトは、他に3つの非常に大きなプロジェクトが控えているため、開始まであと3ヶ月はかかると見ていますが、今年中にはこのプロジェクトに着手できると考えています。

「いいね!」 2

心配いりません、アップデートを確認したかっただけです。

わあ、contenteditable については今まで聞いたこともありませんでした。この変更が必要/望ましい理由について、簡単な技術的な説明を共有していただけますか?もし無理なら結構ですが、ただ興味があっただけです。

少し複雑ですが、リッチエディタの世界に実験的に参入したいと考えています。これがそれを可能にします。

この作業がクリティカルパスにある理由は、私たちの内部全体が特定の(TEXTAREA)実装に強く結びついているためです。コンポーザーと連携する単一の関数がなく、むしろ20個の異なる実装をコピー&ペーストしているような状態です。

やりたいことは、次のような小さな「スケルトン」コンポーネントを持つことです。

  • テキストを選択する方法
  • テキストを挿入する方法

など…その後、コンテンツ編集可能またはundoフレンドリーなTEXTAREAの実装としてスケルトンを再実装できます。

ただし、これを可能にするためには、多くのコードを移動させる必要があります。

「いいね!」 2

ここで少し進歩がありました。

これは、@sam が説明した長期的な作業ほど包括的なものではありません。しかし、短期的な助けになると思います。これにより、リッチテキストの貼り付け、引用、および(ほとんどの)コンポーザーボタン/キーボードショートカットの使用時に、元に戻す履歴が保持されるはずです。

これは現在Metaで公開されています。問題に気づいたらお知らせください。

「いいね!」 3