Passed
Push — master ( d286b7...24e4a5 )
by Jan
04:36
created

public/ckeditor/plugins/markdown/plugin.js   A

Complexity

Total Complexity 16
Complexity/F 1.6

Size

Lines of Code 131
Function Count 10

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 86
c 0
b 0
f 0
dl 0
loc 131
rs 10
wmc 16
mnd 6
bc 6
fnc 10
bpm 0.6
cpm 1.6
noi 14
1
/**
2
 * A markdown output plugin for CKEDITOR.
3
 * Uses showdown.js for conversion and DOMPurifier for HTML filtering.
4
 *
5
 * This software is licensed under MIT License.
6
 *
7
 * Copyright (c) 2019 Jan Böhmer
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10
 * of this software and associated documentation files (the "Software"), to deal
11
 * in the Software without restriction, including without limitation the rights
12
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 * copies of the Software, and to permit persons to whom the Software is
14
 * furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in all
17
 * copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
 * SOFTWARE.
26
 */
27
28
(function() {
29
30
	function overrideDataProcessor(editor)
31
	{
32
		//Both showdown and DOMPurify must be loaded
33
		if(typeof(showdown) == 'undefined') return;
34
		if (typeof(DOMPurify) == 'undefined') return;
35
36
		//If the dataprocessor were already be overriden do nothing
37
		if(editor.dataProcessor.markdown) return;
38
39
		var converter = new showdown.Converter();
40
		//Set some useful options on Showdown
41
		converter.setFlavor('github');
42
		converter.setOption('tables', true);
43
		converter.setOption('strikethrough', true);
44
		converter.setOption('parseImgDimensions', true);
45
		converter.setOption('smartIndentationFix', true);
46
47
		editor.dataProcessor = {
48
			toDataFormat: function(html, fixForBody) {
49
				//html = html.replace(/(\r\n|\n|\r)/gm,"");
50
				html = html.replace('<br>', '\n');
51
				//Support for strikethrough in markdown
52
				html = html.replace('<s>', '<del>').replace('</s>', '</del>');
53
				return converter.makeMarkdown(html);
54
			},
55
			toHtml: function(data){
56
				//Convert markdown to HTML and remove unsafe things from it.
57
				var unsafe = converter.makeHtml(data);
58
				return DOMPurify.sanitize(unsafe);
59
			},
60
			//Mark this dataprocessor
61
			markdown: true
62
		};
63
64
		//Set the original data
65
		if(editor.markdown_unchangedData) {
66
			editor.setData(editor.markdown_unchangedData);
67
			editor.markdown_unchangedData = null;
68
		}
69
	}
70
71
	CKEDITOR.plugins.add( 'markdown', {
72
		//requires: 'entities',
73
74
		onLoad: function() {
75
76
			CKEDITOR.addCss(
77
				//Show borders on tables generated by Showdown
78
				'table {\n' +
79
				'     border-width: 1px 0 0 1px;\n' +
80
				'     border-color: #bbb;\n' +
81
				'     border-style: solid;\n' +
82
				' }\n' +
83
				'\n' +
84
				'table td, table th {\n' +
85
				'    border-width: 0 1px 1px 0;\n' +
86
				'    border-color: #bbb;\n' +
87
				'    border-style: solid;\n' +
88
				'    padding: 10px;\n' +
89
				'}' +
90
				//Show code blocks
91
				'pre {\n' +
92
				'    display: block;\n' +
93
				'    padding: 9.5px;\n' +
94
				'    margin: 0 0 10px;\n' +
95
				'    font-size: 13px;\n' +
96
				'    line-height: 1.42857143;\n' +
97
				'    color: #333;\n' +
98
				'    word-break: break-all;\n' +
99
				'    word-wrap: break-word;\n' +
100
				'    background-color: #f5f5f5;\n' +
101
				'    border: 1px solid #ccc;\n' +
102
				'    border-radius: 4px;\n' +
103
				'}' +
104
				'padding: 0;\n' +
105
				'    font-size: inherit;\n' +
106
				'    color: inherit;\n' +
107
				'    white-space: pre-wrap;\n' +
108
				'    background-color: transparent;\n' +
109
				'    border-radius: 0;' +
110
				'code, kbd, pre, samp {\n' +
111
				'    font-family: Menlo, Monaco, Consolas, "Courier New", monospace;\n' +
112
				'}' +
113
				//Show images small
114
				'img {\n' +
115
				'    max-width: 35%;\n' +
116
				'    vertical-align: middle;' +
117
				'}'
118
			);
119
		},
120
121
		beforeInit: function( editor ) {
122
			var config = editor.config;
123
124
			CKEDITOR.tools.extend( config, {
125
				basicEntities: false,
126
				entities: false,
127
				fillEmptyBlocks: false
128
			}, true );
129
130
			editor.filter.disable();
131
		},
132
133
		init: function( editor ) {
134
			var config = editor.config;
135
136
			var rootPath = this.path;
137
			//We override the dataprocessor later (after we loaded the needes scripts), sow we need the save untouched data now.
138
			editor.markdown_unchangedData = editor.getData();
139
140
			if (typeof(showdown) == 'undefined') {
141
				CKEDITOR.scriptLoader.load(rootPath + 'js/showdown.min.js', function() {
142
					overrideDataProcessor(editor);
143
				}, CKEDITOR, true);
144
			}
145
146
			if (typeof(DOMPurify) == 'undefined') {
147
				CKEDITOR.scriptLoader.load(rootPath + 'js/purify.min.js', function() {
148
					overrideDataProcessor()
149
				}, CKEDITOR, true);
150
			}
151
		},
152
153
		afterInit: function( editor ) {
154
			//Override the data processor with our for Markdown.
155
			overrideDataProcessor(editor);
156
		}
157
	} );
158
} )();
159