written 0.2.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.babelrc +3 -0
- data/.gitignore +2 -0
- data/.ruby-version +1 -0
- data/README.md +18 -8
- data/Rakefile +1 -0
- data/compile-coffee.js +14 -0
- data/lib/written/app/assets/javascripts/written/attachments/image.coffee +4 -4
- data/lib/written/app/assets/javascripts/written/core/content.coffee +18 -29
- data/lib/written/app/assets/javascripts/written/core/cursor.coffee +8 -7
- data/lib/written/app/assets/javascripts/written/core/document.coffee +9 -8
- data/lib/written/app/assets/javascripts/written/core/{extensions/string.coffee → html.coffee} +3 -2
- data/lib/written/app/assets/javascripts/written/core/parsers.coffee +179 -0
- data/lib/written/app/assets/javascripts/written/parsers/block/code.coffee +11 -28
- data/lib/written/app/assets/javascripts/written/parsers/block/heading.coffee +37 -39
- data/lib/written/app/assets/javascripts/written/parsers/block/image.coffee +15 -39
- data/lib/written/app/assets/javascripts/written/parsers/block/olist.coffee +23 -20
- data/lib/written/app/assets/javascripts/written/parsers/block/paragraph.coffee +14 -34
- data/lib/written/app/assets/javascripts/written/parsers/block/quote.coffee +19 -38
- data/lib/written/app/assets/javascripts/written/parsers/block/ulist.coffee +20 -18
- data/lib/written/app/assets/javascripts/written/parsers/inline/bold.coffee +23 -0
- data/lib/written/app/assets/javascripts/written/parsers/inline/code.coffee +8 -27
- data/lib/written/app/assets/javascripts/written/parsers/inline/italic.coffee +8 -28
- data/lib/written/app/assets/javascripts/written/parsers/inline/link.coffee +8 -27
- data/lib/written/app/assets/stylesheets/written.scss +4 -0
- data/lib/written/version.rb +1 -1
- data/package.json +25 -0
- data/test/javascript/parsers/block/code.js +58 -0
- data/test/javascript/parsers/block/header.js +40 -0
- data/test/javascript/parsers/block/image.js +39 -0
- data/test/javascript/parsers/block/olist.js +41 -0
- data/test/javascript/parsers/block/paragraph.js +42 -0
- data/test/javascript/parsers/block/quote.js +41 -0
- data/test/javascript/parsers/block/ulist.js +40 -0
- data/test/javascript/parsers/inline/code.js +41 -0
- data/test/javascript/parsers/inline/italic.js +42 -0
- data/test/javascript/parsers/inline/link.js +42 -0
- data/test/javascript/parsers/inline/strong.js +41 -0
- data/test/server/app/assets/javascripts/application.coffee +8 -9
- data/test/server/app/assets/javascripts/secret.coffee +6 -0
- data/test/server/app/views/posts/show.html.erb +4 -4
- metadata +21 -12
- data/lib/written/app/assets/javascripts/written/parsers/inline/strong.coffee +0 -43
- data/lib/written/app/assets/javascripts/written/parsers/parsers.coffee +0 -95
- data/test/javascript/assertions/assert.coffee +0 -3
- data/test/javascript/polyfills.coffee +0 -2
- data/test/javascript/polyfills/HTMLULListElement.coffee +0 -0
- data/test/javascript/polyfills/Text.coffee +0 -0
- data/test/javascript/runner.coffee +0 -46
- data/test/javascript/tests/initialization.coffee +0 -16
- data/test/javascript/tests/parsing.coffee +0 -9
@@ -0,0 +1,40 @@
|
|
1
|
+
let struct = undefined;
|
2
|
+
|
3
|
+
window.Written = {
|
4
|
+
Parsers: {
|
5
|
+
Block: {},
|
6
|
+
register: function(s) {
|
7
|
+
if (struct == undefined) {
|
8
|
+
struct = s
|
9
|
+
}
|
10
|
+
}
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
require('../../../../lib/written/app/assets/javascripts/written/core/html')
|
15
|
+
require('../../../../lib/written/app/assets/javascripts/written/parsers/block/heading')
|
16
|
+
|
17
|
+
describe('header', () => {
|
18
|
+
it('detects a match', () => {
|
19
|
+
let match = struct.rule.exec('# Hello World')
|
20
|
+
expect(match).not.toBeNull()
|
21
|
+
})
|
22
|
+
|
23
|
+
it('returns the content for the editor', () => {
|
24
|
+
let match = struct.rule.exec('# Hello World!')
|
25
|
+
let html = Written.toHTML('<h1># Hello World!</h1>')
|
26
|
+
|
27
|
+
let parser = new struct.parser(match)
|
28
|
+
parser.content = [parser.innerText()]
|
29
|
+
expect(parser.toEditor().outerHTML).toBe(html.outerHTML)
|
30
|
+
})
|
31
|
+
|
32
|
+
it('HTML content should not include the markdown syntax', () => {
|
33
|
+
let match = struct.rule.exec('# Hello World!')
|
34
|
+
let html = Written.toHTML('<h1>Hello World!</h1>')
|
35
|
+
|
36
|
+
let parser = new struct.parser(match)
|
37
|
+
parser.content = [parser.innerText()]
|
38
|
+
expect(parser.toHTML().outerHTML).toBe(html.outerHTML)
|
39
|
+
})
|
40
|
+
})
|
@@ -0,0 +1,39 @@
|
|
1
|
+
let struct = undefined;
|
2
|
+
|
3
|
+
window.Written = {
|
4
|
+
Parsers: {
|
5
|
+
Block: {},
|
6
|
+
register: function(s) {
|
7
|
+
struct = s
|
8
|
+
}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
require('../../../../lib/written/app/assets/javascripts/written/core/html')
|
13
|
+
require('../../../../lib/written/app/assets/javascripts/written/parsers/block/image')
|
14
|
+
|
15
|
+
describe('image', () => {
|
16
|
+
it('detects a match', () => {
|
17
|
+
let match = struct.rule.exec('![an](img)')
|
18
|
+
expect(match).not.toBeNull()
|
19
|
+
})
|
20
|
+
|
21
|
+
it('returns the content for the editor', () => {
|
22
|
+
let match = struct.rule.exec('![an](img)')
|
23
|
+
let html = Written.toHTML('<figure><div contenteditable=false><img src="img" /></div><figcaption>![an](img)</figcaption></figure>')
|
24
|
+
|
25
|
+
let parser = new struct.parser(match)
|
26
|
+
parser.content = [parser.innerText()]
|
27
|
+
expect(parser.toEditor().outerHTML).toBe(html.outerHTML)
|
28
|
+
})
|
29
|
+
|
30
|
+
it('HTML content should not include the markdown syntax', () => {
|
31
|
+
let match = struct.rule.exec('![an](img)')
|
32
|
+
let html = Written.toHTML('<figure><img src="img" /><figcaption>an</figcaption></figure>')
|
33
|
+
|
34
|
+
let parser = new struct.parser(match)
|
35
|
+
parser.content = [parser.innerText()]
|
36
|
+
expect(parser.toHTML().outerHTML).toBe(html.outerHTML)
|
37
|
+
})
|
38
|
+
})
|
39
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
let struct = undefined;
|
2
|
+
|
3
|
+
window.Written = {
|
4
|
+
Parsers: {
|
5
|
+
Block: {},
|
6
|
+
register: function(s) {
|
7
|
+
struct = s
|
8
|
+
}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
require('../../../../lib/written/app/assets/javascripts/written/core/html')
|
13
|
+
require('../../../../lib/written/app/assets/javascripts/written/parsers/block/olist')
|
14
|
+
|
15
|
+
describe('olist', () => {
|
16
|
+
it('detects a match', () => {
|
17
|
+
let match = struct.rule.exec('1. a list')
|
18
|
+
expect(match).not.toBeNull()
|
19
|
+
})
|
20
|
+
|
21
|
+
it('returns the content for the editor', () => {
|
22
|
+
let match = struct.rule.exec('1. a list')
|
23
|
+
let html = Written.toHTML('<ol><li>1. a list</li></ol>')
|
24
|
+
|
25
|
+
let parser = new struct.parser(match)
|
26
|
+
parser.content = [parser.innerText()]
|
27
|
+
expect(parser.toEditor().outerHTML).toBe(html.outerHTML)
|
28
|
+
})
|
29
|
+
|
30
|
+
it('HTML content should not include the markdown syntax', () => {
|
31
|
+
let match = struct.rule.exec('1. a list')
|
32
|
+
let html = Written.toHTML('<ol><li>a list</li></ol>')
|
33
|
+
|
34
|
+
let parser = new struct.parser(match)
|
35
|
+
parser.content = [parser.innerText()]
|
36
|
+
expect(parser.toHTML().outerHTML).toBe(html.outerHTML)
|
37
|
+
})
|
38
|
+
})
|
39
|
+
|
40
|
+
|
41
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
let struct = undefined;
|
2
|
+
|
3
|
+
window.Written = {
|
4
|
+
Parsers: {
|
5
|
+
Block: {},
|
6
|
+
register: function(s) {
|
7
|
+
struct = s
|
8
|
+
}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
require('../../../../lib/written/app/assets/javascripts/written/core/html')
|
13
|
+
require('../../../../lib/written/app/assets/javascripts/written/parsers/block/paragraph')
|
14
|
+
|
15
|
+
describe('paragraph', () => {
|
16
|
+
it('detects a match', () => {
|
17
|
+
let match = struct.rule.exec('Anything, really.')
|
18
|
+
expect(match).not.toBeNull()
|
19
|
+
})
|
20
|
+
|
21
|
+
it('returns the content for the editor', () => {
|
22
|
+
let match = struct.rule.exec('Anything, really.')
|
23
|
+
let html = Written.toHTML('<p>Anything, really.</p>')
|
24
|
+
|
25
|
+
let parser = new struct.parser(match)
|
26
|
+
parser.content = [parser.innerText()]
|
27
|
+
expect(parser.toEditor().outerHTML).toBe(html.outerHTML)
|
28
|
+
})
|
29
|
+
|
30
|
+
it('HTML content should not include the markdown syntax', () => {
|
31
|
+
let match = struct.rule.exec('Anything, really.')
|
32
|
+
let html = Written.toHTML('<p>Anything, really.</p>')
|
33
|
+
|
34
|
+
let parser = new struct.parser(match)
|
35
|
+
parser.content = [parser.innerText()]
|
36
|
+
expect(parser.toHTML().outerHTML).toBe(html.outerHTML)
|
37
|
+
})
|
38
|
+
})
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
let struct = undefined;
|
2
|
+
|
3
|
+
window.Written = {
|
4
|
+
Parsers: {
|
5
|
+
Block: {},
|
6
|
+
register: function(s) {
|
7
|
+
struct = s
|
8
|
+
}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
require('../../../../lib/written/app/assets/javascripts/written/core/html')
|
13
|
+
require('../../../../lib/written/app/assets/javascripts/written/parsers/block/quote')
|
14
|
+
|
15
|
+
describe('quote', () => {
|
16
|
+
it('detects a match', () => {
|
17
|
+
let match = struct.rule.exec('> a quote')
|
18
|
+
expect(match).not.toBeNull()
|
19
|
+
})
|
20
|
+
|
21
|
+
it('returns the content for the editor', () => {
|
22
|
+
let match = struct.rule.exec('> a quote')
|
23
|
+
let html = Written.toHTML('<blockquote><p>> a quote</p></blockquote>')
|
24
|
+
|
25
|
+
let parser = new struct.parser(match)
|
26
|
+
parser.content = [parser.innerText()]
|
27
|
+
expect(parser.toEditor().outerHTML).toBe(html.outerHTML)
|
28
|
+
})
|
29
|
+
|
30
|
+
it('HTML content should not include the markdown syntax', () => {
|
31
|
+
let match = struct.rule.exec('> a quote')
|
32
|
+
let html = Written.toHTML('<blockquote><p>a quote</p></blockquote>')
|
33
|
+
|
34
|
+
let parser = new struct.parser(match)
|
35
|
+
parser.content = [parser.innerText()]
|
36
|
+
expect(parser.toHTML().outerHTML).toBe(html.outerHTML)
|
37
|
+
})
|
38
|
+
})
|
39
|
+
|
40
|
+
|
41
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
let struct = undefined;
|
2
|
+
|
3
|
+
window.Written = {
|
4
|
+
Parsers: {
|
5
|
+
Block: {},
|
6
|
+
register: function(s) {
|
7
|
+
struct = s
|
8
|
+
}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
require('../../../../lib/written/app/assets/javascripts/written/core/html')
|
13
|
+
require('../../../../lib/written/app/assets/javascripts/written/parsers/block/ulist')
|
14
|
+
|
15
|
+
describe('ulist', () => {
|
16
|
+
it('detects a match', () => {
|
17
|
+
let match = struct.rule.exec('- a list')
|
18
|
+
expect(match).not.toBeNull()
|
19
|
+
})
|
20
|
+
|
21
|
+
it('returns the content for the editor', () => {
|
22
|
+
let match = struct.rule.exec('- a list')
|
23
|
+
let html = Written.toHTML('<ul><li>- a list</li></ul>')
|
24
|
+
|
25
|
+
let parser = new struct.parser(match)
|
26
|
+
parser.content = [parser.innerText()]
|
27
|
+
expect(parser.toEditor().outerHTML).toBe(html.outerHTML)
|
28
|
+
})
|
29
|
+
|
30
|
+
it('HTML content should not include the markdown syntax', () => {
|
31
|
+
let match = struct.rule.exec('- a list')
|
32
|
+
let html = Written.toHTML('<ul><li>a list</li></ul>')
|
33
|
+
|
34
|
+
let parser = new struct.parser(match)
|
35
|
+
parser.content = [parser.innerText()]
|
36
|
+
expect(parser.toHTML().outerHTML).toBe(html.outerHTML)
|
37
|
+
})
|
38
|
+
})
|
39
|
+
|
40
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
let struct = undefined;
|
2
|
+
|
3
|
+
window.Written = {
|
4
|
+
Parsers: {
|
5
|
+
Inline: {},
|
6
|
+
register: function(s) {
|
7
|
+
struct = s
|
8
|
+
}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
require('../../../../lib/written/app/assets/javascripts/written/core/html')
|
13
|
+
require('../../../../lib/written/app/assets/javascripts/written/parsers/inline/code')
|
14
|
+
|
15
|
+
describe('code', () => {
|
16
|
+
it('detects a match', () => {
|
17
|
+
let match = struct.rule.exec('~~~ test~~~')
|
18
|
+
expect(match).not.toBeNull()
|
19
|
+
})
|
20
|
+
|
21
|
+
it('ignores text that do not match', () => {
|
22
|
+
let match = struct.rule.exec('test')
|
23
|
+
expect(match).toBeNull()
|
24
|
+
})
|
25
|
+
|
26
|
+
it('returns the content for the editor', () => {
|
27
|
+
struct.rule.lastIndex = 0
|
28
|
+
let match = struct.rule.exec('~~~ test~~~')
|
29
|
+
expect(match).toBeTruthy()
|
30
|
+
let parser = new struct.parser(match)
|
31
|
+
expect(parser.toEditor().outerHTML).toBe(Written.toHTML('<code>~~~ test~~~</code>').outerHTML)
|
32
|
+
})
|
33
|
+
|
34
|
+
it('HTML content should not include the markdown syntax', () => {
|
35
|
+
struct.rule.lastIndex = 0
|
36
|
+
let match = struct.rule.exec('~~~ test~~~')
|
37
|
+
expect(match).toBeTruthy()
|
38
|
+
let parser = new struct.parser(match)
|
39
|
+
expect(parser.toHTML().outerHTML).toBe(Written.toHTML('<code>test</code>').outerHTML)
|
40
|
+
})
|
41
|
+
})
|
@@ -0,0 +1,42 @@
|
|
1
|
+
let struct = undefined;
|
2
|
+
|
3
|
+
window.Written = {
|
4
|
+
Parsers: {
|
5
|
+
Inline: {},
|
6
|
+
register: function(s) {
|
7
|
+
struct = s
|
8
|
+
}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
require('../../../../lib/written/app/assets/javascripts/written/core/html')
|
13
|
+
require('../../../../lib/written/app/assets/javascripts/written/parsers/inline/italic')
|
14
|
+
|
15
|
+
describe('italic', () => {
|
16
|
+
it('detects a match', () => {
|
17
|
+
let match = struct.rule.exec('_test_')
|
18
|
+
expect(match).not.toBeNull()
|
19
|
+
})
|
20
|
+
|
21
|
+
it('ignores text that do not match', () => {
|
22
|
+
let match = struct.rule.exec('test_')
|
23
|
+
expect(match).toBeNull()
|
24
|
+
})
|
25
|
+
|
26
|
+
it('returns the content for the editor', () => {
|
27
|
+
struct.rule.lastIndex = 0
|
28
|
+
let match = struct.rule.exec('_test_')
|
29
|
+
expect(match).toBeTruthy()
|
30
|
+
let parser = new struct.parser(match)
|
31
|
+
expect(parser.toEditor().outerHTML).toBe(Written.toHTML('<em>_test_</em>').outerHTML)
|
32
|
+
})
|
33
|
+
|
34
|
+
it('HTML content should not include the markdown syntax', () => {
|
35
|
+
struct.rule.lastIndex = 0
|
36
|
+
let match = struct.rule.exec('_test_')
|
37
|
+
expect(match).toBeTruthy()
|
38
|
+
let parser = new struct.parser(match)
|
39
|
+
expect(parser.toHTML().outerHTML).toBe(Written.toHTML('<em>test</em>').outerHTML)
|
40
|
+
})
|
41
|
+
})
|
42
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
let struct = undefined;
|
2
|
+
|
3
|
+
window.Written = {
|
4
|
+
Parsers: {
|
5
|
+
Inline: {},
|
6
|
+
register: function(s) {
|
7
|
+
struct = s
|
8
|
+
}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
require('../../../../lib/written/app/assets/javascripts/written/core/html')
|
13
|
+
require('../../../../lib/written/app/assets/javascripts/written/parsers/inline/link')
|
14
|
+
|
15
|
+
describe('link', () => {
|
16
|
+
it('detects a match', () => {
|
17
|
+
let match = struct.rule.exec('[test](a)')
|
18
|
+
expect(match).not.toBeNull()
|
19
|
+
})
|
20
|
+
|
21
|
+
it('ignores text that do not match', () => {
|
22
|
+
let match = struct.rule.exec('[test]')
|
23
|
+
expect(match).toBeNull()
|
24
|
+
})
|
25
|
+
|
26
|
+
it('returns the content for the editor', () => {
|
27
|
+
struct.rule.lastIndex = 0
|
28
|
+
let match = struct.rule.exec('[source](http://github.com/pothibo/written)')
|
29
|
+
expect(match).toBeTruthy()
|
30
|
+
let parser = new struct.parser(match)
|
31
|
+
expect(parser.toEditor().outerHTML).toBe(Written.toHTML('<a><strong>[source]</strong>(http://github.com/pothibo/written)</a>').outerHTML)
|
32
|
+
})
|
33
|
+
|
34
|
+
it('HTML content should not include the markdown syntax', () => {
|
35
|
+
struct.rule.lastIndex = 0
|
36
|
+
let match = struct.rule.exec('[source](http://github.com/pothibo/written)')
|
37
|
+
expect(match).toBeTruthy()
|
38
|
+
let parser = new struct.parser(match)
|
39
|
+
expect(parser.toHTML().outerHTML).toBe(Written.toHTML('<a href="http://github.com/pothibo/written">source</a>').outerHTML)
|
40
|
+
})
|
41
|
+
})
|
42
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
let struct = undefined;
|
2
|
+
|
3
|
+
window.Written = {
|
4
|
+
Parsers: {
|
5
|
+
Inline: {},
|
6
|
+
register: function(s) {
|
7
|
+
struct = s
|
8
|
+
}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
require('../../../../lib/written/app/assets/javascripts/written/core/html')
|
13
|
+
require('../../../../lib/written/app/assets/javascripts/written/parsers/inline/strong')
|
14
|
+
|
15
|
+
describe('strong', () => {
|
16
|
+
it('detects a match', () => {
|
17
|
+
let match = struct.rule.exec('*test*')
|
18
|
+
expect(match).not.toBeNull()
|
19
|
+
})
|
20
|
+
|
21
|
+
it('ignores text that do not match', () => {
|
22
|
+
let match = struct.rule.exec('test*')
|
23
|
+
expect(match).toBeNull()
|
24
|
+
})
|
25
|
+
|
26
|
+
it('returns the content for the editor', () => {
|
27
|
+
struct.rule.lastIndex = 0
|
28
|
+
let match = struct.rule.exec('*test*')
|
29
|
+
expect(match).toBeTruthy()
|
30
|
+
let parser = new struct.parser(match)
|
31
|
+
expect(parser.toEditor().outerHTML).toBe(Written.toHTML('<strong>*test*</strong>').outerHTML)
|
32
|
+
})
|
33
|
+
|
34
|
+
it('HTML content should not include the markdown syntax', () => {
|
35
|
+
struct.rule.lastIndex = 0
|
36
|
+
let match = struct.rule.exec('*test*')
|
37
|
+
expect(match).toBeTruthy()
|
38
|
+
let parser = new struct.parser(match)
|
39
|
+
expect(parser.toHTML().outerHTML).toBe(Written.toHTML('<strong>test</strong>').outerHTML)
|
40
|
+
})
|
41
|
+
})
|
@@ -1,17 +1,16 @@
|
|
1
1
|
#= require 'written'
|
2
|
-
#= require 'written/attachments/image'
|
3
2
|
#= require 'prism'
|
4
|
-
|
5
|
-
|
3
|
+
#
|
6
4
|
document.removeEventListener('DOMContentLoaded', Prism.highlightAll)
|
7
5
|
|
8
|
-
Written.Parsers
|
9
|
-
Prism.highlightElement(element, false)
|
6
|
+
parsers = new Written.Parsers({blocks: ['header', 'code', 'image', 'ulist', 'olist', 'quote'], inlines: ['bold', 'italic', 'code', 'link']})
|
10
7
|
|
11
|
-
|
8
|
+
parsers.get('pre')?.highlightWith (element) ->
|
12
9
|
Prism.highlightElement(element, false)
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
parsers.get('code')?.highlightWith (element) ->
|
12
|
+
Prism.highlightElement(element, false)
|
17
13
|
|
14
|
+
editor = new Written(document.getElementById('Editor'), {
|
15
|
+
parsers: parsers
|
16
|
+
})
|