Bessere Rückgängigmachen-Unterstützung beim Einfügen von formatiertem Text hinzufügen

Derzeit funktioniert in Discourse das Einfügen von reinem Text in den Composer über die übliche Browserfunktion mit Strg+Z nicht, da dieser Vorgang den eingefügten Text rückgängig macht und entfernt. Wenn Sie jedoch formatierten Text einfügen, wie diesen Fettdruck, funktioniert die Rückgängig-Funktion nicht. Ebenso können Links, die über Text eingefügt werden, um diesen zu verlinken, nicht rückgängig gemacht werden, ebenso wenig wie Markdown, das über Tastenkombinationen wie Strg+B oder beim Hinzufügen von Formatierungen über die Werkzeugleistenoptionen des Composers eingefügt wird. Idealerweise sollte so viel wie möglich davon dem Rückgängig-Stapel hinzugefügt werden, damit Strg+Z wie erwartet funktioniert.

Ich gebe Ihnen eine Beschreibung dessen, was mir ziemlich oft passiert.

  1. Ich kopiere Text von einer anderen Website, der zufällig ein Link, fett, eine Überschrift usw. ist. (Manchmal wird diese Tatsache registriert, manchmal nicht.)
  2. Ich gehe zu Discourse, um diesen Text in meinen bereits teilweise geschriebenen Beitrag einzufügen.
  3. Ich drücke Strg+V, wodurch der formatierte Text eingefügt wird.
  4. Ich erkenne meinen Fehler und drücke Strg+Z, was nichts bewirkt.
  5. Ich entferne manuell den formatierten Text, den ich versehentlich eingefügt habe. (Meistens ist es die verlinkte Version, die ich versehentlich eingefügt habe, also nicht so, dass ich nur ein # oder etwas Ähnliches entfernen muss.)
  6. Ich drücke Strg+Umschalt+V, was ich von Anfang an hätte tun sollen, um den unformatierten Text einzufügen.

Offensichtlich handelt es sich hierbei teilweise um Benutzerfehler, und wenn ich mich nicht irre, sind es nur zwei Schritte (von anderer Website kopieren, als einfacher Text in Discourse einfügen). Aber wenn ich mich irre (was oft vorkommt, da ich es gewohnt bin, einfach Strg+V zu drücken, da die meisten Websites keine formatierten Einfügungen vornehmen), wäre es schön, wenn ich Zeit sparen könnte, indem Strg+Z normal funktioniert.

4 „Gefällt mir“

Dies ist im Allgemeinen ein natives Browserverhalten und nichts, was Discourse tut. Versuchen Sie, es mit einem einfachen Textfeld in HTML zu testen.

Okay, standardmäßig funktioniert Rückgängigmachen nicht, wenn Sie JavaScript verwenden, um eine Eingabe zu ändern. Aber ich habe gegoogelt und festgestellt, dass document.execCommand Text einfügen kann, während er dem Rückgängig-Stapel hinzugefügt wird.

Wenn Sie zum Beispiel document.getElementById('myInput').value = 'asd' und dann Strg+Z ausführen, wird dies nicht rückgängig gemacht.

Wenn Sie jedoch document.execCommand('insertText', false, 'asd') ausführen, während sich der Cursor an der gewünschten Stelle befindet (was er basierend auf dem aktuellen Discourse-Workflow tun sollte), wird der Text ordnungsgemäß eingefügt und Strg+Z entfernt den hinzugefügten Text wie erwartet.

Grundsätzlich frage ich mich, ob document.execCommand (oder ein anderer Prozess, wenn ein anderer Ansatz als besser erachtet wird) verwendet werden kann, um dem Rückgängig-Stapel etwas hinzuzufügen, damit Strg+Z in diesen Fällen funktioniert.

3 „Gefällt mir“

Nein — wir haben diese Unterstützung vor Jahren absichtlich aus Discourse entfernt, um die native Rückgängig-Funktion der Textfelder des Browsers so zu nutzen, wie sie auf allen Standardwebsites funktionieren sollte.

Ich glaube, ich verstehe etwas nicht. Was genau bedeutet „die native Rückgängig-Funktion des Browsers für Textfelder nutzen“? Soweit ich weiß, funktioniert Rückgängig für formatierten Text in Discourse überhaupt nicht. Meinen Sie also, dass das Nichtfunktionieren von Rückgängig das Standardverhalten von Websites ist?

Der Grund für meine Verwirrung ist, dass mir keine einzige Website einfällt (außer Dingen wie Microsoft Word, wo Rückgängig funktioniert), die formatiertes Einfügen unterstützt, außer Discourse. Daher habe ich nichts, womit ich Discourse vergleichen könnte, um zu sehen, was „Standard“ ist. Wenn Sie mir ein paar Websites zum Vergleich nennen könnten, wäre das sehr hilfreich.

2 „Gefällt mir“

Siehe

Klicken Sie auf Try it yourself, geben Sie dann Text in das Textfeld ein, warten Sie kurz und drücken Sie dann Strg+z, um Ihre Aktionen rückgängig zu machen. Hier ist eine Demo. Zuerst klicken wir auf die Schaltfläche Try it yourself, was dazu führt, dass ein HTML-<textarea> im Browser angezeigt wird.

Ich gebe Text in das Textfeld ein. Wie Sie auf dem Screenshot sehen können, habe ich Folgendes eingegeben:

ICH HABE GERADE DIESEN TEXT EINGEGEBEN JUUUHUUU!

Nachdem ich nun getippt habe, drücke ich Strg+z, um meine Eingabe rückgängig zu machen, und sehe Folgendes:

Beachten Sie, dass der Text in seinen vorherigen Zustand zurückgekehrt ist und dies zu 100 % vom Browser selbst gehandhabt wurde, ohne jeglichen JavaScript-Code.

Mein Verständnis ist, dass @seanblue fragt, ob wir die Browser-APIs, die wir bei der Bearbeitung des Textbereichs verwenden, ändern können, um dem Browser einen besseren Hinweis zu geben, damit er die Rückgängig-Funktion besser handhaben kann. Dies würde also nur für Tastenkombinationen und Symbolleisten, Uploads und Ähnliches gelten.

Ich bin nicht dagegen, hier Dinge zu optimieren, aber ich befürchte, dass einige dieser APIs viel Sorgfalt erfordern werden, es besteht sicherlich das Risiko von Regressionen.

Ich bin nicht gegen Experimente hier, vielleicht wenn die Community einige PRs einreichen möchte, um uns zu zeigen, wie es gemacht wird.

7 „Gefällt mir“

Wir könnten das hier definitiv besser machen. Viele unserer Symbolleistenschaltflächen und das Verhalten von „Fancy Paste“ setzen den Wert des Textbereichs direkt in JavaScript. Dies zerstört die native Rückgängig-/Wiederherstellungsverlauf des Browsers vollständig.

Stattdessen sollten wir immer, wenn wir programmatische Änderungen am Textbereich vornehmen, document.execCommand verwenden (wie von @seanblue erwähnt). Auf diese Weise interpretiert der Browser dies genauso wie eine Benutzeraktion und fügt es sauber in den Rückgängig-/Wiederherstellungsverlauf ein.

Der Befehl insertText, den Sie verwenden können, um Text programmgesteuert an der Cursorposition zu ersetzen und dabei den Rückgängig-Puffer (Bearbeitungshistorie) in einfachen textarea- und input-Elementen beizubehalten.

10 „Gefällt mir“

Aber dieses Textfeld verarbeitet keine formatierten Text, worauf ich mich beziehe. Ich weiß, dass Browser das Rückgängigmachen von normal getipptem und eingefügtem Text verarbeiten. Mein Punkt ist, dass Discourse das Rückgängigmachen von eingefügtem formatiertem Text nicht verarbeitet. Befolgen Sie diese Schritte, um zu sehen, worauf ich mich beziehe.

Öffnen Sie zuerst den Discourse-Komponisten:

Kopieren Sie nun den folgenden Text und fügen Sie ihn in den Komponisten ein: this is a test

Drücken Sie nun Strg+Z, und der eingefügte Text wird entfernt. Dies ist identisch mit dem Verhalten, das Sie in Ihrem Beitrag gezeigt haben.

Kopieren Sie nun stattdessen den folgenden Text und fügen Sie ihn in den Komponisten ein: this is a great test
Beachten Sie, dass er mit dem Markdown zum Kursivieren von “great” eingefügt wird.

Drücken Sie nun Strg+Z und Sie werden feststellen, dass der eingefügte Text immer noch vorhanden ist. Darauf beziehe ich mich.


Das stimmt. Ich schlage nicht vor, das Rückgängigmachen selbst in JavaScript zu handhaben. Ich schlage vor, dass Sie, wenn Sie den Textbereich bearbeiten, den Browser darauf aufmerksam machen, damit er die Änderung selbst rückgängig machen kann, wenn der Benutzer Strg+Z drückt.

Was es wert ist, 99 % meiner Frustration wären gelöst, wenn Strg+Z nach dem Einfügen von formatiertem Text funktionieren würde. Wäre es ideal, wenn jede einzelne Operation mit Strg+Z rückgängig gemacht werden könnte? Sicher. Aber die meisten anderen Operationen können durch Wiederholung der ursprünglichen Operation rückgängig gemacht werden (z. B. kann Strg+B sowohl Markdown für Fettdruck hinzufügen als auch entfernen). Aber beim Einfügen besteht das Potenzial, eine beträchtliche Menge unerwarteten Markdown einzufügen, einschließlich Überschriften, Links und sogar Tabellen, weshalb es so wichtig ist, dass das Rückgängigmachen in diesem Fall funktioniert.

Wenn wir den Umfang auf die Handhabung des Rückgängigmachens beim Einfügen von formatiertem Text beschränken und andere Tastenkombinationen, Symbolleistenschaltflächen usw. ignorieren würden, würde dies das Risiko ausreichend reduzieren, um es zu versuchen?

9 „Gefällt mir“

Ich verstehe; zwischen deiner und Davids Erklärung verstehe ich den Unterschied. Ich benutze diese Schaltflächen im Editor meistens nie. Ich tippe Dinge in das Textfeld mit der Tastatur meines Computers (entweder physisch oder auf dem Bildschirm), und das wird vom Browser nahtlos gehandhabt.

6 „Gefällt mir“

Das ist verständlich. Ich neige auch dazu, das Markdown anstelle der Schaltflächen der Symbolleiste dafür zu tippen, sodass dieser Aspekt für mich keine wirkliche Rolle spielt. Ich habe die Symbolleisten-Sachen nur im OP erwähnt, um darauf hinzuweisen, dass es nicht nur beim Einfügen von formatiertem Text passiert. Die Möglichkeit, die Aktionen der Symbolleiste rückgängig zu machen, ist nicht besonders wichtig, da der Benutzer diese Aktionen absichtlich ausführt. Aber beim Einfügen ist die Formatierung oft zufällig und unerwartet, daher wäre es sehr praktisch, diese rückgängig machen zu können.

6 „Gefällt mir“

Ich wollte mich nur noch einmal dazu melden und sehen, wie wahrscheinlich es ist, dass dies in absehbarer Zeit bearbeitet wird.

3 „Gefällt mir“

Noch nicht geplant, aber ja, es scheint den Zweck zu erfüllen. Ich denke, wir sollten unsere Implementierung sowohl für die Symbolleiste als auch für Dinge wie STRG-B-Verknüpfungen und Erwähnungen ändern.

Es ist jedoch eine ziemlich tiefgreifende Änderung, ich würde sagen, es würde etwa 1-3 Wochen Arbeit dauern, um das alles zu integrieren. Es gibt viel zu tun:

  • Bilder ausschneiden und einfügen
  • Uploads
  • Fett / Kursiv
  • Links
  • @Erwähnungen
  • #Autocomplete

Ich unterstütze diese Änderung, bin mir aber nicht sicher, wann wir sie planen können … Ich denke, ich bin damit einverstanden, sie für unsere nächste Veröffentlichung einzuplanen. Gibt es Einwände, @codinghorror?

Ich mag es, dass Sie STRG-Z bis zu einem leeren Feld zurückverfolgen können, anstatt nur bei Ihrer ersten Erwähnung, Ihrem ersten Link usw. blockiert zu werden.

8 „Gefällt mir“

Eine schöne Sache ist, dass es (meiner Meinung nach) vernünftigerweise inkrementell erfolgen kann, anstatt alles auf einmal veröffentlichen zu müssen. Offensichtlich weiß ich nicht, ob das aus technischer Sicht der Fall sein wird, aber aus Benutzersicht denke ich, dass es in Ordnung wäre. Einige logische Trennungen könnten sein:

  • Einfügen von Text, der formatiert wird, einschließlich Dingen wie Fett, Bildern und Links
  • Vervollständigen von Erwähnungen, Kategorien/Tags, Emoji
  • Tastenkombinationen wie Strg+B für Fett
  • Symbolleistenaktionen wie Fett, Details ausblenden, Spoiler verwischen usw.

Ich habe das Gefühl, dass jede dieser Gruppen einzeln erledigt werden könnte, ohne die Benutzer zu verwirren, und persönlich wäre das die Reihenfolge, in der ich sie implementieren würde.

8 „Gefällt mir“

Ich plane diese Arbeit für unsere nächste Veröffentlichung ein. Das bedeutet, dass wir dies in den nächsten sechs Monaten oder so bereinigen werden. Es wird nicht über Nacht geschehen, aber wir werden hier Fortschritte machen.

8 „Gefällt mir“

Da es nun vier Monate her ist, wollte ich nachfragen, wie es damit vorangeht. :slight_smile:

2 „Gefällt mir“

Ja, ich verstehe Sie vollkommen, aber das wird noch eine Weile dauern.

Es ist irgendwie zu einem kompletten Refactoring des Komponisten eskaliert. Unser langfristiger Plan ist es, eine andere Abstraktionsschicht für den Komponisten zu unterstützen, der jetzt SUPER fest daran gebunden ist, immer ein TEXTAREA-Element zu sein.

Der erste Schritt zur Entblockung ist die Unterstützung eines contenteditable-Komponisten, der wie unser aktuelles Textfeld aussieht und sich auch so verhält.

Ich sehe nicht, dass wir mit diesem Projekt in den nächsten 3 Monaten beginnen, da wir 3 andere sehr große Projekte davor haben, aber ich sehe definitiv, dass wir dieses Jahr mit diesem Projekt beginnen werden.

2 „Gefällt mir“

Keine Sorge, ich habe nur nach einem Update gesucht.

Wow, von contenteditable habe ich bis jetzt noch nie etwas gehört. Würden Sie mir vielleicht eine kurze technische Erklärung geben, warum diese Änderung notwendig/wünschenswert ist? Wenn nicht, ist das in Ordnung, ich bin nur neugierig.

Es ist etwas kompliziert, aber wir möchten uns mit Rich-Editoren experimentell auseinandersetzen. Dies würde dies ermöglichen.

Der Grund, warum diese Arbeit auf dem kritischen Pfad liegt, ist, dass unsere gesamten Interna stark an eine bestimmte Implementierung (TEXTAREA) gekoppelt sind. Wir haben keine einzige Funktion, um mit dem Komponisten zu interagieren, es ist eher wie das Ausschneiden und Einfügen von 20 verschiedenen Implementierungen.

Was wir tun möchten, ist eine kleine „Skelett“-Komponente zu haben, die besagt:

  • So wählen Sie Text aus
  • So fügen Sie Text ein

Und so weiter … dann können wir das Skelett als Contenteditable oder eine Undo-freundliche Implementierung von TEXTAREA neu implementieren.

Allerdings muss viel Code verschoben werden, um dies zu ermöglichen.

2 „Gefällt mir“

Ich konnte hier ein wenig Fortschritt erzielen:

Dies ist bei weitem nicht so umfassend wie die langfristige Arbeit, die @sam beschrieben hat. Aber ich denke, es sollte kurzfristig helfen. Dies sollte die Rückgängig-Historie beim Einfügen von Rich-Text, beim Zitieren und bei der Verwendung von (den meisten) Composer-Schaltflächen/Tastenkombinationen beibehalten.

Es ist jetzt auf Meta live – meldet euch, wenn ihr Probleme bemerkt.

3 „Gefällt mir“