Quellcode durchsuchen

ComposeArea: Replace whitespace when pasting

Unfortunately, setting `white-space: pre-wrap` on the compose area
results in a behavioral change in the way child nodes are managed in
Chromium. This breaks some tests.

Replacing spaces with escape sequences when pasting is ugly, but seems
to work.
Danilo Bargen vor 6 Jahren
Ursprung
Commit
f46bc8c69e
4 geänderte Dateien mit 23 neuen und 4 gelöschten Zeilen
  1. 9 2
      src/directives/compose_area.ts
  2. 9 0
      src/helpers.ts
  3. 0 1
      src/sass/sections/_compose_area.scss
  4. 5 1
      tests/ts/helpers.ts

+ 9 - 2
src/directives/compose_area.ts

@@ -15,7 +15,7 @@
  * along with Threema Web. If not, see <http://www.gnu.org/licenses/>.
  */
 
-import {extractText, isActionTrigger, logAdapter} from '../helpers';
+import {extractText, isActionTrigger, logAdapter, replaceWhitespace} from '../helpers';
 import {BrowserService} from '../services/browser';
 import {StringService} from '../services/string';
 import {TimeoutService} from '../services/timeout';
@@ -436,7 +436,14 @@ export default [
                         const escaped = escapeHtml(text);
 
                         // Apply filters (emojify, convert newline, etc)
-                        const formatted = nlToBr(mentionify(emojify(escaped, true, false, scope.emojiImagePath)), true);
+                        const formatted = replaceWhitespace(
+                            nlToBr(
+                                mentionify(
+                                    emojify(escaped, true, false, scope.emojiImagePath),
+                                ),
+                                true,
+                            ),
+                        );
 
                         // Insert resulting HTML
                         document.execCommand('insertHTML', false, formatted);

+ 9 - 0
src/helpers.ts

@@ -442,3 +442,12 @@ export function extractText(targetNode: HTMLElement, logWarning: (msg: string) =
     visitChildNodes(targetNode);
     return trim ? text.trim() : text;
 }
+
+/**
+ * Replace spaces with `&nbsp;` and tabs with `&nbsp;&nbsp;`.
+ */
+export function replaceWhitespace(text: string): string {
+    return text
+        .replace(/ /g, '&nbsp;')
+        .replace(/\t/, '&nbsp;&nbsp;');
+}

+ 0 - 1
src/sass/sections/_compose_area.scss

@@ -40,7 +40,6 @@ compose-area {
                     max-height: calc(1.3em * 5);
                     min-height: 22px;
                     cursor: text;
-                    white-space: pre-wrap;
 
                     img.e1 {
                         vertical-align: middle;

+ 5 - 1
tests/ts/helpers.ts

@@ -17,11 +17,15 @@
  * along with Threema Web. If not, see <http://www.gnu.org/licenses/>.
  */
 
-import {u8aToHex} from '../../src/helpers';
+import {replaceWhitespace, u8aToHex} from '../../src/helpers';
 
 describe('Helpers', () => {
     it('u8aToHex', function() {
         const arr = Uint8Array.of(1, 2, 4, 8, 254, 255);
         expect(u8aToHex(arr)).toEqual('01020408feff');
     });
+
+    it('replaceWhitespace', function() {
+        expect(replaceWhitespace('	Hello wor  ld')).toEqual('&nbsp;&nbsp;Hello&nbsp;wor&nbsp;&nbsp;ld');
+    });
 });