更新: CSSでこれを処理することは驚くほど単純でオーバーヘッドが少ないですが、ブレークが発生する場所を制御することはできません。気にしない場合や、データが自然に途切れることなく英数字の実行が長い場合は問題ありません。長いファイルパス、URL、電話番号がたくさんありましたが、いずれも他の場所よりも中断した方がはるかに良い場所があります。
私たちの解決策は、最初に正規表現の置換を使用して、空白ではない15文字(たとえば)ごとに、または改行を希望する特殊文字の後にゼロ幅のスペース(​)を配置することでした。次に、別の置換を行って、これらの特殊文字の後に幅ゼロのスペースを置きます。
ゼロ幅のスペースは画面に表示されないので便利です。データに重要なハイフンがあるため、恥ずかしがり屋のハイフンは表示時に混乱しました。ブラウザーからテキストをコピーする場合、ゼロ幅スペースも含まれません。
現在使用している特殊なブレーク文字は、ピリオド、スラッシュ、バックスラッシュ、コンマ、アンダースコア、@、|、およびハイフンです。ハイフンの後に改行を促すために何もする必要はないと思いますが、Firefox(少なくとも3.6および4)は、数字(電話番号など)で囲まれたハイフンだけでは改行しません。
また、使用可能なレイアウトスペースに基づいて、人工的な区切りの間の文字数を制御したいと考えました。つまり、長い中断のない実行に一致する正規表現は動的である必要がありました。これはよく呼ばれ、パフォーマンス上の理由から同じ同一の正規表現を何度も作成したくなかったため、正規表現とそのフラグをキーにした単純な正規表現キャッシュを使用しました。
これがコードです。あなたはおそらくユーティリティパッケージの関数に名前空間を付けるでしょう:
makeWrappable = function(str, position)
{
if (!str)
return '';
position = position || 15; // default to breaking after 15 chars
// matches every requested number of chars that's not whitespace or one of the special chars defined below
var longRunsRegex = cachedRegex('([^\\s\\.\/\\,_@\\|-]{' + position + '})(?=[^\\s\\.\/\\,_@\\|-])', 'g');
return str
.replace(longRunsRegex, '$1​') // put a zero-width space every requested number of chars that's not whitespace or a special char
.replace(makeWrappable.SPECIAL_CHARS_REGEX, '$1​'); // and one after special chars we want to allow breaking after
};
makeWrappable.SPECIAL_CHARS_REGEX = /([\.\/\\,_@\|-])/g; // period, forward slash, backslash, comma, underscore, @, |, hyphen
cachedRegex = function(reString, reFlags)
{
var key = reString + (reFlags ? ':::' + reFlags : '');
if (!cachedRegex.cache[key])
cachedRegex.cache[key] = new RegExp(reString, reFlags);
return cachedRegex.cache[key];
};
cachedRegex.cache = {};
このようなテスト:
makeWrappable('12345678901234567890 12345678901234567890 1234567890/1234567890')
更新2:少なくとも一部の状況では、実際には幅がゼロのスペースがコピーされたテキストに含まれているように見えますが、それらを表示することはできません。明らかに、非表示の文字を含むテキストをコピーするように人々を促すことは、他のプログラムやシステムに入力したようなデータを持っていることを招待することであり、問題を引き起こす可能性があります。たとえば、それがデータベースで終わる場合、それに対する検索は失敗する可能性があり、このような検索文字列も失敗する可能性があります。矢印キーを使用してこのようなデータ間を移動するには、(正しく)見えない文字を移動するために追加のキーを押す必要があります。ユーザーが気づいたら、少し奇妙です。
クローズドシステムでは、入力時にその文字をフィルタリングして自分を保護できますが、他のプログラムやシステムには役立ちません。
このテクニックはうまく機能しますが、改行の原因となるキャラクターの最良の選択が何であるかはわかりません。
更新3:この特性がデータに含まれることは、もはや理論的な可能性ではなく、観察された問題です。画面からコピーされたデータをユーザーが送信すると、データベースに保存され、検索が中断され、物事が奇妙にソートされます。
私たちは2つのことをしました:
- このアプリのすべてのデータソースのすべてのテーブルのすべての列からそれらを削除するユーティリティを書きました。
- 標準の文字列入力プロセッサにそれを削除するためのフィルタリングが追加されたため、コードがそれを認識するまでに削除されます。
これはテクニック自体と同じようにうまく機能しますが、注意書きです。
更新4:これに供給されるデータがHTMLエスケープされる可能性があるコンテキストでこれを使用しています。適切な状況下では、HTMLエンティティの中央にゼロ幅のスペースを挿入でき、ファンキーな結果が得られます。
修正は、次のように、中断しない文字のリストにアンパサンドを追加することでした。
var longRunsRegex = cachedRegex('([^&\\s\\.\/\\,_@\\|-]{' + position + '})(?=[^&\\s\\.\/\\,_@\\|-])', 'g');