@slite/quill-delta-markdown
Advanced tools
Comparing version 0.0.3 to 0.0.4
{ | ||
"name": "@slite/quill-delta-markdown", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"public": true, | ||
@@ -5,0 +5,0 @@ "description": "To and from Markdown and Quill delta", |
@@ -60,56 +60,75 @@ var _ = require('lodash'); | ||
embed: { | ||
image: function(src, attributes) { | ||
this.append('![]('+src+')'); | ||
} | ||
image: function(src, attributes) { | ||
this.append('![]('+src+')'); | ||
} | ||
}, | ||
inline: { | ||
italic: function() { | ||
return ['_', '_']; | ||
}, | ||
bold: function() { | ||
return ['*', '*']; | ||
}, | ||
code: function() { | ||
return ['`', '`']; | ||
}, | ||
link: function(href) { | ||
return ['[', ']('+href+')']; | ||
italic: function() { | ||
return ['*', '*']; | ||
}, | ||
bold: function() { | ||
return ['**', '**']; | ||
}, | ||
code: function() { | ||
return ['`', '`']; | ||
}, | ||
underline: function() { | ||
return ['__', '__']; | ||
}, | ||
strikethrough: function() { | ||
return ['~~', '~~']; | ||
}, | ||
entity: function(attributes) { | ||
switch (attributes.type) { | ||
case 'LINK': | ||
return [`[`, `](${attributes.data.url})`] | ||
default: | ||
return ['', ''] | ||
} | ||
} | ||
}, | ||
block: { | ||
'header-one': function() { | ||
this.open = '# ' +this.open; | ||
'header-one': function() { | ||
this.open = '# ' + this.open | ||
}, | ||
'header-two': function() { | ||
this.open = '## ' + this.open | ||
}, | ||
blockquote: function() { | ||
this.open = '> '+this.open | ||
}, | ||
'code-block': function() { | ||
this.open = "```\n" + this.open | ||
this.close = this.close + "```\n" | ||
}, | ||
'todo-block': function({ data }) { | ||
this.open = ( data.checked ? '- [x] ' : '- [ ] ') + this.open | ||
}, | ||
'unordered-list-item': { | ||
group: function() { | ||
return new node(['', "\n"]) | ||
}, | ||
'header-two': function(header) { | ||
this.open = '## ' +this.open; | ||
line: function(type, group) { | ||
this.open = '- '+this.open | ||
} | ||
}, | ||
'ordered-list-item': { | ||
group: function() { | ||
return new node(['', "\n"]) | ||
}, | ||
blockquote: function(header) { | ||
this.open = '> '+this.open; | ||
}, | ||
'code-block': function(header) { | ||
this.open = "```\n"+this.open; | ||
this.close = this.close+"```\n"; | ||
}, | ||
'unordered-list-item': { | ||
group: function() { | ||
return new node(['', "\n"]) | ||
}, | ||
line: function(type, group) { | ||
this.open = '- '+this.open; | ||
} | ||
}, | ||
'ordered-list-item': { | ||
group: function() { | ||
return new node(['', "\n"]) | ||
}, | ||
line: function(type, group) { | ||
group.count = group.count || 0; | ||
var count = ++group.count; | ||
this.open = count+'. '+this.open; | ||
} | ||
line: function(type, group) { | ||
group.count = group.count || 0 | ||
var count = ++group.count | ||
this.open = count +'. ' + this.open | ||
} | ||
} | ||
}, | ||
'separator': function() { | ||
this.open = '---' + this.open | ||
}, | ||
'image': function({ data }) { | ||
this.open = `![](${data.url})` | ||
} | ||
} | ||
}; | ||
@@ -122,5 +141,5 @@ | ||
function newLine() { | ||
el = line = new node(["", "\n"]); | ||
root.append(line); | ||
activeInline = {}; | ||
el = line = new node(["", "\n"]); | ||
root.append(line); | ||
activeInline = {}; | ||
} | ||
@@ -152,3 +171,2 @@ newLine(); | ||
var fn = format.block[op.attributes.type]; | ||
console.log('Block found', { fn }); | ||
if (typeof fn == 'object') { | ||
@@ -175,3 +193,3 @@ if (group && group.type != k) { | ||
fn.call(line, op.attributes[k], group); | ||
fn.call(line, op.attributes, group); | ||
newLine(); | ||
@@ -259,8 +277,8 @@ break; | ||
function isLinifyable(attrs) { | ||
for (var k in attrs) { | ||
if (k === 'type' && format.block[attrs.type]) { | ||
return true; | ||
} | ||
for (var k in attrs) { | ||
if (k === 'type' && format.block[attrs.type]) { | ||
return true | ||
} | ||
return false; | ||
} | ||
return false | ||
} |
var render = require('../src/fromDelta'), | ||
expect = require('chai').expect; | ||
expect = require('chai').expect; | ||
describe('fromDelta', function() { | ||
it('renders inline format', function() { | ||
it('renders inline format', function() { | ||
expect(render([ | ||
{ | ||
"insert": "Hi " | ||
}, | ||
{ | ||
"attributes": { | ||
"bold": true | ||
}, | ||
"insert": "mom" | ||
} | ||
])) | ||
.to.equal('Hi *mom*\n'); | ||
expect(render([ | ||
{ | ||
"insert": "Hi " | ||
}, | ||
{ | ||
"attributes": { | ||
"bold": true | ||
}, | ||
"insert": "mom" | ||
} | ||
])) | ||
.to.equal('Hi **mom**\n'); | ||
}); | ||
}); | ||
it('renders embed format', function() { | ||
it('renders embed format', function() { | ||
expect(render([ | ||
{ | ||
"insert": "LOOK AT THE KITTEN!\n" | ||
}, | ||
{ | ||
"insert": { | ||
"image": "https://placekitten.com/g/200/300" | ||
}, | ||
} | ||
])) | ||
.to.equal('LOOK AT THE KITTEN!\n![](https://placekitten.com/g/200/300)\n'); | ||
expect(render([ | ||
{ | ||
"insert": "LOOK AT THE KITTEN!\n" | ||
}, | ||
{ | ||
"insert": "\n", | ||
"attributes": { | ||
"type": "image", | ||
"data": { | ||
"url": "https://placekitten.com/g/200/300", | ||
} | ||
}, | ||
} | ||
])) | ||
.to.equal('LOOK AT THE KITTEN!\n![](https://placekitten.com/g/200/300)\n'); | ||
}); | ||
}); | ||
it('renders block format', function() { | ||
it('renders block format', function() { | ||
expect(render([ | ||
{ | ||
"insert": "Headline" | ||
}, | ||
{ | ||
"attributes": { | ||
"type": "header-one" | ||
}, | ||
"insert": "\n" | ||
} | ||
])) | ||
.to.equal('# Headline\n'); | ||
}); | ||
expect(render([ | ||
{ | ||
"insert": "Headline" | ||
}, | ||
{ | ||
"attributes": { | ||
"type": "header-one" | ||
}, | ||
"insert": "\n" | ||
} | ||
])) | ||
.to.equal('# Headline\n'); | ||
}); | ||
it('renders lists with inline formats correctly', function() { | ||
it('renders lists with inline formats correctly', function() { | ||
expect(render([ | ||
{ | ||
"attributes": { | ||
"italic": true | ||
}, | ||
"insert": "Glenn v. Brumby" | ||
}, | ||
{ | ||
"insert": ", 663 F.3d 1312 (11th Cir. 2011)" | ||
}, | ||
{ | ||
"attributes": { | ||
"list": 'ordered' | ||
}, | ||
"insert": "\n" | ||
}, | ||
{ | ||
"attributes": { | ||
"italic": true | ||
}, | ||
"insert": "Barnes v. City of Cincinnati" | ||
}, | ||
{ | ||
"insert": ", 401 F.3d 729 (6th Cir. 2005)" | ||
}, | ||
{ | ||
"attributes": { | ||
"list": 'ordered' | ||
}, | ||
"insert": "\n" | ||
} | ||
])) | ||
.to.equal('1. *Glenn v. Brumby*, 663 F.3d 1312 (11th Cir. 2011)\n2. *Barnes v. City of Cincinnati*, 401 F.3d 729 (6th Cir. 2005)\n'); | ||
expect(render([ | ||
{ | ||
"attributes": { | ||
"italic": true | ||
}, | ||
"insert": "Glenn v. Brumby" | ||
}, | ||
{ | ||
"insert": ", 663 F.3d 1312 (11th Cir. 2011)" | ||
}, | ||
{ | ||
"attributes": { | ||
"type": 'ordered-list-item' | ||
}, | ||
"insert": "\n" | ||
}, | ||
{ | ||
"attributes": { | ||
"italic": true | ||
}, | ||
"insert": "Barnes v. City of Cincinnati" | ||
}, | ||
{ | ||
"insert": ", 401 F.3d 729 (6th Cir. 2005)" | ||
}, | ||
{ | ||
"attributes": { | ||
"type": 'ordered-list-item' | ||
}, | ||
"insert": "\n" | ||
} | ||
])) | ||
.to.equal('1. *Glenn v. Brumby*, 663 F.3d 1312 (11th Cir. 2011)\n2. *Barnes v. City of Cincinnati*, 401 F.3d 729 (6th Cir. 2005)\n'); | ||
}); | ||
}); | ||
it('renders adjacent lists correctly', function() { | ||
it('renders adjacent lists correctly', function() { | ||
expect(render([ | ||
{ | ||
"insert": "Item 1" | ||
}, | ||
{ | ||
"insert": "\n", | ||
"attributes": { | ||
"list": 'ordered' | ||
} | ||
}, | ||
{ | ||
"insert": "Item 2" | ||
}, | ||
{ | ||
"insert": "\n", | ||
"attributes": { | ||
"list": 'ordered' | ||
} | ||
}, | ||
{ | ||
"insert": "Item 3" | ||
}, | ||
{ | ||
"insert": "\n", | ||
"attributes": { | ||
"list": 'ordered' | ||
} | ||
}, | ||
{ | ||
"insert": "Intervening paragraph\nItem 4" | ||
}, | ||
{ | ||
"insert": "\n", | ||
"attributes": { | ||
"list": 'ordered' | ||
} | ||
}, | ||
{ | ||
"insert": "Item 5" | ||
}, | ||
{ | ||
"insert": "\n", | ||
"attributes": { | ||
"list": 'ordered' | ||
} | ||
}, | ||
{ | ||
"insert": "Item 6" | ||
}, | ||
{ | ||
"insert": "\n", | ||
"attributes": { | ||
"list": 'ordered' | ||
} | ||
} | ||
])) | ||
.to.equal('1. Item 1\n2. Item 2\n3. Item 3\n\nIntervening paragraph\n1. Item 4\n2. Item 5\n3. Item 6\n'); | ||
expect(render([ | ||
{ | ||
"insert": "Item 1" | ||
}, | ||
{ | ||
"insert": "\n", | ||
"attributes": { | ||
"type": 'ordered-list-item' | ||
} | ||
}, | ||
{ | ||
"insert": "Item 2" | ||
}, | ||
{ | ||
"insert": "\n", | ||
"attributes": { | ||
"type": 'ordered-list-item' | ||
} | ||
}, | ||
{ | ||
"insert": "Item 3" | ||
}, | ||
{ | ||
"insert": "\n", | ||
"attributes": { | ||
"type": 'ordered-list-item' | ||
} | ||
}, | ||
{ | ||
"insert": "Intervening paragraph\nItem 4" | ||
}, | ||
{ | ||
"insert": "\n", | ||
"attributes": { | ||
"type": 'ordered-list-item' | ||
} | ||
}, | ||
{ | ||
"insert": "Item 5" | ||
}, | ||
{ | ||
"insert": "\n", | ||
"attributes": { | ||
"type": 'ordered-list-item' | ||
} | ||
}, | ||
{ | ||
"insert": "Item 6" | ||
}, | ||
{ | ||
"insert": "\n", | ||
"attributes": { | ||
"type": 'ordered-list-item' | ||
} | ||
} | ||
])) | ||
.to.equal('1. Item 1\n2. Item 2\n3. Item 3\n\nIntervening paragraph\n1. Item 4\n2. Item 5\n3. Item 6\n'); | ||
}); | ||
}); | ||
it('renders adjacent inline formats correctly', function() { | ||
expect(render([ | ||
{ | ||
"attributes" : { | ||
"italic" : true | ||
}, | ||
"insert" : "Italics! " | ||
}, | ||
{ | ||
"attributes": { | ||
"italic": true, | ||
"link": "http://example.com" | ||
}, | ||
"insert": "Italic link" | ||
}, | ||
{ | ||
"attributes": { | ||
"link": "http://example.com" | ||
}, | ||
"insert": " regular link" | ||
} | ||
it('renders adjacent inline formats correctly', function() { | ||
expect(render([ | ||
{ | ||
"attributes" : { | ||
"italic" : true | ||
}, | ||
"insert" : "Italics! " | ||
}, | ||
{ | ||
"attributes": { | ||
"italic": true, | ||
"entity": { | ||
"type": "LINK", | ||
"data": { | ||
"url": "http://example.com" | ||
} | ||
} | ||
}, | ||
"insert": "Italic link" | ||
}, | ||
{ | ||
"attributes": { | ||
"entity": { | ||
"type": "LINK", | ||
"data": { | ||
"url": "http://example.com" | ||
} | ||
} | ||
}, | ||
"insert": " regular link" | ||
} | ||
])) | ||
.to.equal('*Italics! [Italic link](http://example.com)*[ regular link](http://example.com)'+"\n"); | ||
}); | ||
])) | ||
.to.equal('*Italics! [Italic link](http://example.com)*[ regular link](http://example.com)'+"\n"); | ||
}) | ||
it('handles embed inserts with inline styles', function() { | ||
expect(render([ | ||
{ | ||
"insert": { | ||
"image": "https://placekitten.com/g/200/300", | ||
}, | ||
"attributes": { | ||
"link": "http://example.com" | ||
}, | ||
} | ||
])) | ||
.to.equal('[![](https://placekitten.com/g/200/300)](http://example.com)'+"\n"); | ||
}); | ||
/* | ||
it('is XSS safe in regular text', function() { | ||
expect(render([ | ||
{ | ||
"insert": '<img src=x onerror="doBadThings()">' | ||
} | ||
])) | ||
.to.equal('<p><img src=x onerror="doBadThings()"></p>'); | ||
}); | ||
it('render an inline link', function () { | ||
expect(render([ | ||
{ | ||
"insert" : "Go to Google", | ||
"attributes": { | ||
"entity": { | ||
"type": "LINK", | ||
"data": { | ||
"url": "https://www.google.fr", | ||
} | ||
} | ||
} | ||
} | ||
])) | ||
.to.equal( | ||
'[Go to Google](https://www.google.fr)' + "\n" | ||
) | ||
}) | ||
it('is XSS safe in images', function() { | ||
expect(render([ | ||
{ | ||
"insert": { | ||
"image": '"><img src=x onerror="doBadThings()">' | ||
}, | ||
} | ||
])) | ||
.to.equal('<p></p><p><img src=""><img src=x onerror="doBadThings()">"></p><p></p>'); | ||
});*/ | ||
}); | ||
it('renders todo block', function() { | ||
expect(render([ | ||
{ | ||
"insert" : "First todo" | ||
}, | ||
{ | ||
"attributes": { | ||
"type": "todo-block", | ||
"data": { | ||
"checked": false, | ||
} | ||
}, | ||
"insert": "\n" | ||
}, | ||
{ | ||
"insert" : "Second todo" | ||
}, | ||
{ | ||
"attributes": { | ||
"type": "todo-block", | ||
"data": { | ||
"checked": true, | ||
} | ||
}, | ||
"insert": "\n" | ||
}, | ||
])) | ||
.to.equal( | ||
'- [ ] First todo' + "\n" + | ||
'- [x] Second todo' + "\n" | ||
) | ||
}) | ||
it('renders a separator block', function() { | ||
expect(render([ | ||
{ | ||
"insert" : "Before\n" | ||
}, | ||
{ | ||
"attributes": { | ||
"type": "separator", | ||
}, | ||
"insert": "\n" | ||
}, | ||
{ | ||
"insert" : "After\n" | ||
}, | ||
])) | ||
.to.equal( | ||
'Before' + "\n" + | ||
'---' + "\n" + | ||
'After' + "\n" | ||
) | ||
}) | ||
}) |
@@ -32,21 +32,2 @@ import chai, {expect} from 'chai'; | ||
it('converts text with image', () => { | ||
const input = 'Hello ![world](url)'; | ||
const expected = [{ insert: 'Hello '}, { insert: { "image": 'url' }, attributes: { alt: 'world' } }, { insert: "\n" }]; | ||
var result = toDelta(input); | ||
expect(result).to.deep.equal(expected); | ||
}); | ||
it('converts text with image with title', () => { | ||
const input = 'Hello ![world](url "title")'; | ||
const expected = [{ insert: 'Hello '}, { insert: { "image": 'url' }, attributes: { alt: 'world', title: 'title' } }, { insert: "\n" }]; | ||
var result = toDelta(input); | ||
expect(result).to.deep.equal(expected); | ||
}); | ||
it('converts multi paragraphs', () => { | ||
@@ -53,0 +34,0 @@ const input = "line 1\n\nline 2\n"; |
30875
910