Fossil SCM
/chat: a potential fix to stop *some* builds of Firefox from pasting formatted content into the edit field. (Some builds, same version, do not do so.)
Commit
498bc071cafc366cee2b193b487d00a37b135e71fef94ca865c18f5c2128deb8
Parent
3fa1f2429b8a3eb…
1 file changed
+26
-17
+26
-17
| --- src/fossil.page.chat.js | ||
| +++ src/fossil.page.chat.js | ||
| @@ -579,14 +579,16 @@ | ||
| 579 | 579 | D.addClassBriefly(e, a, 0, cb); |
| 580 | 580 | } |
| 581 | 581 | return this; |
| 582 | 582 | } |
| 583 | 583 | }; |
| 584 | - if(!D.attr(cs.e.inputField,'contenteditable','plaintext-only').isContentEditable){ | |
| 585 | - /* Only the Chrome family supports contenteditable=plaintext-only, | |
| 586 | - but Chrome is the only engine for which we need this flag: */ | |
| 587 | - D.attr(cs.e.inputField,'contenteditable','true'); | |
| 584 | + if(D.attr(cs.e.inputField,'contenteditable','plaintext-only').isContentEditable){ | |
| 585 | + cs.$browserHasPlaintextOnly = true; | |
| 586 | + }else{ | |
| 587 | + /* Only the Chrome family supports contenteditable=plaintext-only */ | |
| 588 | + cs.$browserHasPlaintextOnly = false; | |
| 589 | + D.attr(cs.e.inputField,'contenteditable','true'); | |
| 588 | 590 | } |
| 589 | 591 | cs.animate.$disabled = true; |
| 590 | 592 | F.fetch.beforesend = ()=>cs.ajaxStart(); |
| 591 | 593 | F.fetch.aftersend = ()=>cs.ajaxEnd(); |
| 592 | 594 | cs.pageTitleOrig = cs.e.pageTitle.innerText; |
| @@ -1143,23 +1145,30 @@ | ||
| 1143 | 1145 | return false; |
| 1144 | 1146 | } |
| 1145 | 1147 | /* else continue propagating */ |
| 1146 | 1148 | }; |
| 1147 | 1149 | document.addEventListener('paste', pasteListener, true); |
| 1148 | - if(0){ | |
| 1149 | - const onPastePlainText = function(ev){ | |
| 1150 | - var pastedText = undefined; | |
| 1151 | - if (window.clipboardData && window.clipboardData.getData) { // IE | |
| 1152 | - pastedText = window.clipboardData.getData('Text'); | |
| 1153 | - }else if (ev.clipboardData && ev.clipboardData.getData) { | |
| 1154 | - pastedText = ev.clipboardData.getData('text/plain'); | |
| 1155 | - } | |
| 1156 | - ev.target.textContent += pastedText; | |
| 1157 | - ev.preventDefault(); | |
| 1158 | - return false; | |
| 1159 | - }; | |
| 1160 | - Chat.e.inputField.addEventListener('paste', onPastePlainText, false); | |
| 1150 | + if(window.Selection && window.Range && !Chat.$browserHasPlaintextOnly){ | |
| 1151 | + /* Acrobatics to keep *some* installations of Firefox | |
| 1152 | + from pasting formatting into contenteditable fields. | |
| 1153 | + This also works on Chrome, but chrome has the | |
| 1154 | + contenteditable=plaintext-only property which does this | |
| 1155 | + for us. */ | |
| 1156 | + Chat.inputElement().addEventListener( | |
| 1157 | + 'paste', | |
| 1158 | + function(ev){ | |
| 1159 | + if (ev.clipboardData && ev.clipboardData.getData) { | |
| 1160 | + const pastedText = ev.clipboardData.getData('text/plain'); | |
| 1161 | + const selection = window.getSelection(); | |
| 1162 | + if (!selection.rangeCount) return false; | |
| 1163 | + selection.deleteFromDocument(/*remove selected content*/); | |
| 1164 | + selection.getRangeAt(0).insertNode(document.createTextNode(pastedText)); | |
| 1165 | + selection.collapseToEnd(/*deselect pasted text and set cursor at the end*/); | |
| 1166 | + ev.preventDefault(); | |
| 1167 | + return false; | |
| 1168 | + } | |
| 1169 | + }, false); | |
| 1161 | 1170 | } |
| 1162 | 1171 | const noDragDropEvents = function(ev){ |
| 1163 | 1172 | /* contenteditable tries to do its own thing with dropped data, |
| 1164 | 1173 | which is not compatible with how we use it, so... */ |
| 1165 | 1174 | ev.dataTransfer.effectAllowed = 'none'; |
| 1166 | 1175 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -579,14 +579,16 @@ | |
| 579 | D.addClassBriefly(e, a, 0, cb); |
| 580 | } |
| 581 | return this; |
| 582 | } |
| 583 | }; |
| 584 | if(!D.attr(cs.e.inputField,'contenteditable','plaintext-only').isContentEditable){ |
| 585 | /* Only the Chrome family supports contenteditable=plaintext-only, |
| 586 | but Chrome is the only engine for which we need this flag: */ |
| 587 | D.attr(cs.e.inputField,'contenteditable','true'); |
| 588 | } |
| 589 | cs.animate.$disabled = true; |
| 590 | F.fetch.beforesend = ()=>cs.ajaxStart(); |
| 591 | F.fetch.aftersend = ()=>cs.ajaxEnd(); |
| 592 | cs.pageTitleOrig = cs.e.pageTitle.innerText; |
| @@ -1143,23 +1145,30 @@ | |
| 1143 | return false; |
| 1144 | } |
| 1145 | /* else continue propagating */ |
| 1146 | }; |
| 1147 | document.addEventListener('paste', pasteListener, true); |
| 1148 | if(0){ |
| 1149 | const onPastePlainText = function(ev){ |
| 1150 | var pastedText = undefined; |
| 1151 | if (window.clipboardData && window.clipboardData.getData) { // IE |
| 1152 | pastedText = window.clipboardData.getData('Text'); |
| 1153 | }else if (ev.clipboardData && ev.clipboardData.getData) { |
| 1154 | pastedText = ev.clipboardData.getData('text/plain'); |
| 1155 | } |
| 1156 | ev.target.textContent += pastedText; |
| 1157 | ev.preventDefault(); |
| 1158 | return false; |
| 1159 | }; |
| 1160 | Chat.e.inputField.addEventListener('paste', onPastePlainText, false); |
| 1161 | } |
| 1162 | const noDragDropEvents = function(ev){ |
| 1163 | /* contenteditable tries to do its own thing with dropped data, |
| 1164 | which is not compatible with how we use it, so... */ |
| 1165 | ev.dataTransfer.effectAllowed = 'none'; |
| 1166 |
| --- src/fossil.page.chat.js | |
| +++ src/fossil.page.chat.js | |
| @@ -579,14 +579,16 @@ | |
| 579 | D.addClassBriefly(e, a, 0, cb); |
| 580 | } |
| 581 | return this; |
| 582 | } |
| 583 | }; |
| 584 | if(D.attr(cs.e.inputField,'contenteditable','plaintext-only').isContentEditable){ |
| 585 | cs.$browserHasPlaintextOnly = true; |
| 586 | }else{ |
| 587 | /* Only the Chrome family supports contenteditable=plaintext-only */ |
| 588 | cs.$browserHasPlaintextOnly = false; |
| 589 | D.attr(cs.e.inputField,'contenteditable','true'); |
| 590 | } |
| 591 | cs.animate.$disabled = true; |
| 592 | F.fetch.beforesend = ()=>cs.ajaxStart(); |
| 593 | F.fetch.aftersend = ()=>cs.ajaxEnd(); |
| 594 | cs.pageTitleOrig = cs.e.pageTitle.innerText; |
| @@ -1143,23 +1145,30 @@ | |
| 1145 | return false; |
| 1146 | } |
| 1147 | /* else continue propagating */ |
| 1148 | }; |
| 1149 | document.addEventListener('paste', pasteListener, true); |
| 1150 | if(window.Selection && window.Range && !Chat.$browserHasPlaintextOnly){ |
| 1151 | /* Acrobatics to keep *some* installations of Firefox |
| 1152 | from pasting formatting into contenteditable fields. |
| 1153 | This also works on Chrome, but chrome has the |
| 1154 | contenteditable=plaintext-only property which does this |
| 1155 | for us. */ |
| 1156 | Chat.inputElement().addEventListener( |
| 1157 | 'paste', |
| 1158 | function(ev){ |
| 1159 | if (ev.clipboardData && ev.clipboardData.getData) { |
| 1160 | const pastedText = ev.clipboardData.getData('text/plain'); |
| 1161 | const selection = window.getSelection(); |
| 1162 | if (!selection.rangeCount) return false; |
| 1163 | selection.deleteFromDocument(/*remove selected content*/); |
| 1164 | selection.getRangeAt(0).insertNode(document.createTextNode(pastedText)); |
| 1165 | selection.collapseToEnd(/*deselect pasted text and set cursor at the end*/); |
| 1166 | ev.preventDefault(); |
| 1167 | return false; |
| 1168 | } |
| 1169 | }, false); |
| 1170 | } |
| 1171 | const noDragDropEvents = function(ev){ |
| 1172 | /* contenteditable tries to do its own thing with dropped data, |
| 1173 | which is not compatible with how we use it, so... */ |
| 1174 | ev.dataTransfer.effectAllowed = 'none'; |
| 1175 |