Improve paste handling of formatted data

This commit is contained in:
Scott Nonnenberg 2023-05-17 09:58:32 -07:00 committed by GitHub
parent 73f4374e1e
commit f42192fb5a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 127 additions and 39 deletions
patches
ts
quill
formatting
signal-clipboard
util/lint

76
patches/quill+1.3.7.patch Normal file
View file

@ -0,0 +1,76 @@
diff --git a/node_modules/quill/dist/quill.js b/node_modules/quill/dist/quill.js
index 811b3d0..c8c4892 100644
--- a/node_modules/quill/dist/quill.js
+++ b/node_modules/quill/dist/quill.js
@@ -8917,9 +8917,9 @@ var Clipboard = function (_Module) {
var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this, quill, options));
_this.quill.root.addEventListener('paste', _this.onPaste.bind(_this));
- _this.container = _this.quill.addContainer('ql-clipboard');
- _this.container.setAttribute('contenteditable', true);
- _this.container.setAttribute('tabindex', -1);
+ // _this.container = _this.quill.addContainer('ql-clipboard');
+ // _this.container.setAttribute('contenteditable', true);
+ // _this.container.setAttribute('tabindex', -1);
_this.matchers = [];
CLIPBOARD_CONFIG.concat(_this.options.matchers).forEach(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
@@ -8941,15 +8941,18 @@ var Clipboard = function (_Module) {
key: 'convert',
value: function convert(html) {
if (typeof html === 'string') {
- this.container.innerHTML = html.replace(/\>\r?\n +\</g, '><'); // Remove spaces between tags
+ // this.container.innerHTML = html.replace(/\>\r?\n +\</g, '><'); // Remove spaces between tags
+ var parser = new DOMParser();
+ var htmlNoSpaces = html.replace(/\>\r?\n +\</g, '><'); // Remove spaces between tags
+ this.container = parser.parseFromString(htmlNoSpaces, "text/html").body;
return this.convert();
}
var formats = this.quill.getFormat(this.quill.selection.savedRange.index);
- if (formats[_code2.default.blotName]) {
- var text = this.container.innerText;
- this.container.innerHTML = '';
- return new _quillDelta2.default().insert(text, _defineProperty({}, _code2.default.blotName, formats[_code2.default.blotName]));
- }
+ // if (formats[_code2.default.blotName]) {
+ // var text = this.container.innerText;
+ // this.container.innerHTML = '';
+ // return new _quillDelta2.default().insert(text, _defineProperty({}, _code2.default.blotName, formats[_code2.default.blotName]));
+ // }
var _prepareMatching = this.prepareMatching(),
_prepareMatching2 = _slicedToArray(_prepareMatching, 2),
@@ -8962,7 +8965,8 @@ var Clipboard = function (_Module) {
delta = delta.compose(new _quillDelta2.default().retain(delta.length() - 1).delete(1));
}
debug.log('convert', this.container.innerHTML, delta);
- this.container.innerHTML = '';
+ // this.container.innerHTML = '';
+ this.container = null;
return delta;
}
}, {
@@ -9056,9 +9060,10 @@ function applyFormat(delta, format, value) {
}
function computeStyle(node) {
- if (node.nodeType !== Node.ELEMENT_NODE) return {};
- var DOM_KEY = '__ql-computed-style';
- return node[DOM_KEY] || (node[DOM_KEY] = window.getComputedStyle(node));
+ // if (node.nodeType !== Node.ELEMENT_NODE) return {};
+ // var DOM_KEY = '__ql-computed-style';
+ // return node[DOM_KEY] || (node[DOM_KEY] = window.getComputedStyle(node));
+ return node.style;
}
function deltaEndsWith(delta, text) {
@@ -9074,7 +9079,8 @@ function deltaEndsWith(delta, text) {
function isLine(node) {
if (node.childNodes.length === 0) return false; // Exclude embed blocks
var style = computeStyle(node);
- return ['block', 'list-item'].indexOf(style.display) > -1;
+ // return ['block', 'list-item'].indexOf(style.display) > -1;
+ return ['block', 'list-item'].indexOf(style.display) > -1 || node.nodeName === 'DIV' || node.nodeName === 'P';
}
function traverse(node, elementMatchers, textMatchers) {

View file

@ -181,6 +181,16 @@ export class FormattingMenu {
return;
}
// Note: we special-case single \n ops because Quill doesn't apply formatting to them
const contents = this.quill.getContents(
quillSelection.index,
quillSelection.length
);
if (contents.length() === 1 && contents.ops[0].insert === '\n') {
this.scheduleRemoval();
return;
}
// a virtual reference to the text we are trying to format
this.cancelRemoval();
this.referenceElement = {
@ -251,6 +261,11 @@ export class FormattingMenu {
const contents = this.quill.getContents(selection.index, selection.length);
// Note: we special-case single \n ops because Quill doesn't apply formatting to them
if (contents.length() === 1 && contents.ops[0].insert === '\n') {
this.scheduleRemoval();
return false;
}
return contents.ops.every(
op => op.attributes?.[style] || op.insert === '\n'
);

View file

@ -34,6 +34,9 @@ export class SignalClipboard {
}
onCapturePaste(event: ClipboardEvent): void {
event.preventDefault();
event.stopPropagation();
if (event.clipboardData == null) {
return;
}
@ -62,13 +65,12 @@ export class SignalClipboard {
setTimeout(() => {
const delta = new Delta()
.retain(selection.index)
.delete(selection.length)
.concat(clipboardDelta);
this.quill.updateContents(delta, 'user');
this.quill.setSelection(delta.length(), 0, 'silent');
this.quill.scrollingContainer.scrollTop = scrollTop;
}, 1);
}
event.preventDefault();
}
}

View file

@ -1078,6 +1078,20 @@
"updated": "2020-10-13T18:36:57.012Z",
"reasonDetail": "necessary for quill"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.core.js",
"line": " this.container.innerHTML = html.replace(/\\>\\r?\\n +\\</g, '><'); // Remove spaces between tags",
"reasonCategory": "notExercisedByOurApp",
"updated": "2023-05-17T16:29:59.196Z"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.core.js",
"line": " this.container.innerHTML = '';",
"reasonCategory": "notExercisedByOurApp",
"updated": "2023-05-17T16:29:59.196Z"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.core.js",
@ -1094,22 +1108,6 @@
"updated": "2020-10-13T18:36:57.012Z",
"reasonDetail": "necessary for quill"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.core.js",
"line": " this.container.innerHTML = html.replace(/\\>\\r?\\n +\\</g, '><'); // Remove spaces between tags",
"reasonCategory": "usageTrusted",
"updated": "2020-10-13T18:36:57.012Z",
"reasonDetail": "necessary for quill"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.core.js",
"line": " this.container.innerHTML = '';",
"reasonCategory": "usageTrusted",
"updated": "2020-10-13T18:36:57.012Z",
"reasonDetail": "necessary for quill"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.core.js",
@ -1129,15 +1127,28 @@
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.js",
"line": " var html = this.container.innerHTML.trim();",
"reasonCategory": "usageTrusted",
"updated": "2020-10-13T18:36:57.012Z",
"reasonDetail": "necessary for quill"
"line": " // this.container.innerHTML = html.replace(/\\>\\r?\\n +\\</g, '><'); // Remove spaces between tags",
"reasonCategory": "falseMatch",
"updated": "2023-05-17T01:41:49.734Z"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.js",
"line": " this.container.innerHTML = '';",
"line": " // this.container.innerHTML = '';",
"reasonCategory": "falseMatch",
"updated": "2023-05-17T01:41:49.734Z"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.js",
"line": " // this.container.innerHTML = '';",
"reasonCategory": "falseMatch",
"updated": "2023-05-17T01:41:49.734Z"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.js",
"line": " var html = this.container.innerHTML.trim();",
"reasonCategory": "usageTrusted",
"updated": "2020-10-13T18:36:57.012Z",
"reasonDetail": "necessary for quill"
@ -1174,14 +1185,6 @@
"updated": "2020-10-13T18:36:57.012Z",
"reasonDetail": "necessary for quill"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.js",
"line": " this.container.innerHTML = html.replace(/\\>\\r?\\n +\\</g, '><'); // Remove spaces between tags",
"reasonCategory": "usageTrusted",
"updated": "2020-10-13T18:36:57.012Z",
"reasonDetail": "necessary for quill"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.js",
@ -1198,14 +1201,6 @@
"updated": "2020-10-13T18:36:57.012Z",
"reasonDetail": "necessary for quill"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.js",
"line": " this.container.innerHTML = '';",
"reasonCategory": "usageTrusted",
"updated": "2020-10-13T18:36:57.012Z",
"reasonDetail": "necessary for quill"
},
{
"rule": "DOM-innerHTML",
"path": "node_modules/quill/dist/quill.js",