Providing a handler to adjust cursor position on quote space click
authorAlexander Ebert <ebert@woltlab.com>
Sat, 17 Jan 2015 15:28:30 +0000 (16:28 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Sat, 17 Jan 2015 15:28:30 +0000 (16:28 +0100)
If you click on the margin created by quotes, browsers redirect the caret inside the quote. This can make it impossible to get the caret in front of/after it if there are no siblings. Even though you can use the arrow keys to navigate there, this is rather unknown to users and does not solve the issue on mobile devices.

This change attempts to detect clicks into the margin by comparing the offsets with the click position, ultimately moving the caret where the user excepts it to be.

wcfsetup/install/files/js/3rdParty/redactor/plugins/wmonkeypatch.js

index a470d4cfa5700acd13032238c83e7ee71cfc0c3a..90624c945fecfa95c59a5840b53527fda1fe8e69 100644 (file)
@@ -103,6 +103,48 @@ RedactorPlugins.wmonkeypatch = function() {
                                        this.wutil.saveSelection();
                                }
                        }).bind(this));
+                       
+                       var $setCaretBeforeOrAfter = (function(event, blockquote) {
+                               var $offset = $(blockquote).offset();
+                               if (event.pageY <= $offset.top) {
+                                       // set caret before
+                                       if (blockquote.previousElementSibling && blockquote.previousElementSibling.tagName === 'P') {
+                                               this.caret.setEnd(blockquote.previousElementSibling);
+                                       }
+                                       else {
+                                               this.wutil.setCaretBefore(blockquote);
+                                       }
+                               }
+                               else {
+                                       if (blockquote.nextElementSibling && blockquote.nextElementSibling.tagName === 'P') {
+                                               this.caret.setEnd(blockquote.nextElementSibling);
+                                       }
+                                       else {
+                                               this.wutil.setCaretAfter(blockquote);
+                                       }
+                               }
+                       }).bind(this);
+                       
+                       this.$editor.on('click.wmonkeypatch', (function(event) {
+                               if (event.target === this.$editor[0]) {
+                                       var $range = (window.getSelection().rangeCount) ? window.getSelection().getRangeAt(0) : null;
+                                       if ($range !== null && $range.collapsed) {
+                                               // clicking on the margin created by <blockquote> will direct the cursor inside the quote
+                                               var $current = $range.startContainer;
+                                               while ($current !== null && $current !== this.$editor[0]) {
+                                                       if ($current.nodeType === Node.ELEMENT_NODE) {
+                                                               if ($current.tagName === 'BLOCKQUOTE') {
+                                                                       $setCaretBeforeOrAfter(event, $current);
+                                                                       
+                                                                       return false;
+                                                               }
+                                                       }
+                                                       
+                                                       $current = $current.parentElement;
+                                               }
+                                       }
+                               }
+                       }).bind(this));
                },
                
                /**