Skip to content

Commit

Permalink
handle nested list paste, closes #906
Browse files Browse the repository at this point in the history
  • Loading branch information
jhchen committed Apr 17, 2017
1 parent c7ad430 commit 643f65a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
26 changes: 23 additions & 3 deletions modules/clipboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ const DOM_KEY = '__ql-matcher';

const CLIPBOARD_CONFIG = [
[Node.TEXT_NODE, matchText],
[Node.TEXT_NODE, matchNewline],
['br', matchBreak],
[Node.ELEMENT_NODE, matchNewline],
[Node.ELEMENT_NODE, matchBlot],
[Node.ELEMENT_NODE, matchSpacing],
[Node.ELEMENT_NODE, matchAttributor],
[Node.ELEMENT_NODE, matchStyles],
['li', matchIndent],
['b', matchAlias.bind(matchAlias, 'bold')],
['i', matchAlias.bind(matchAlias, 'italic')],
['style', matchIgnore]
Expand Down Expand Up @@ -69,7 +71,7 @@ class Clipboard extends Module {

convert(html) {
if (typeof html === 'string') {
this.container.innerHTML = html;
this.container.innerHTML = html.replace(/\>\r?\n +\</g, '><'); // Remove spaces between tags
}
let [elementMatchers, textMatchers] = this.prepareMatching();
let delta = traverse(this.container, elementMatchers, textMatchers);
Expand Down Expand Up @@ -240,9 +242,27 @@ function matchIgnore() {
return new Delta();
}

function matchIndent(node, delta) {
let match = Parchment.query(node);
if (match == null || match.blotName !== 'list-item' || !deltaEndsWith(delta, '\n')) {
return delta;
}
let indent = -1, parent = node.parentNode;
while (!parent.classList.contains('ql-clipboard')) {
if ((Parchment.query(parent) || {}).blotName === 'list') {
indent += 1;
}
parent = parent.parentNode;
}
if (indent <= 0) return delta;
return delta.compose(new Delta().retain(delta.length() - 1).retain(1, { indent: indent}));
}

function matchNewline(node, delta) {
if (isLine(node) && !deltaEndsWith(delta, '\n')) {
delta.insert('\n');
if (!deltaEndsWith(delta, '\n')) {
if (isLine(node) || (delta.length() > 0 && node.nextSibling && isLine(node.nextSibling))) {
delta.insert('\n');
}
}
return delta;
}
Expand Down
15 changes: 14 additions & 1 deletion test/unit/modules/clipboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('Clipboard', function() {

it('whitespace', function() {
let html =
'<div> 0 </div> <div> <div> 1 2 <span> 3 </span> 4 </div> </div>' +
'<div> 0 </div><div> <div> 1 2 <span> 3 </span> 4 </div> </div>' +
'<div><span>5 </span><span>6 </span><span> 7</span><span> 8</span></div>';
let delta = this.clipboard.convert(html);
expect(delta).toEqual(new Delta().insert('0\n1 2 3 4\n5 6 7 8'));
Expand Down Expand Up @@ -78,6 +78,11 @@ describe('Clipboard', function() {
expect(delta).toEqual(new Delta().insert('0\n1\n2\n3\n\n4\n\n5'));
});

it('mixed inline and block', function() {
let delta = this.clipboard.convert('<div>One<div>Two</div></div>');
expect(delta).toEqual(new Delta().insert('One\nTwo'));
});

it('alias', function() {
let delta = this.clipboard.convert('<b>Bold</b><i>Italic</i>');
expect(delta).toEqual(new Delta().insert('Bold', { bold: true }).insert('Italic', { italic: true }));
Expand All @@ -95,6 +100,14 @@ describe('Clipboard', function() {
.insert('Alpha\n', { list: 'ordered', indent: 1 }));
});

it('html nested list', function() {
let delta = this.clipboard.convert('<ol><li>One<ol><li>Alpha</li><li>Beta</li></ol></li></ol>');
expect(delta).toEqual(new Delta().insert('One\nAlpha', { list: 'ordered' })
.insert('\n', { list: 'ordered', indent: 1 })
.insert('Beta', { list: 'ordered' })
.insert('\n', { list: 'ordered', indent: 1 }));
});

it('embeds', function() {
let delta = this.clipboard.convert('<div>01<img src="/assets/favicon.png" height="200" width="300">34</div>');
let expected = new Delta()
Expand Down

0 comments on commit 643f65a

Please sign in to comment.