nodebb-plugin-markdown 8.14.5 → 9.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-markdown",
3
- "version": "8.14.5",
3
+ "version": "9.0.2",
4
4
  "description": "A Markdown parser for NodeBB",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -29,7 +29,8 @@
29
29
  ]
30
30
  },
31
31
  "dependencies": {
32
- "highlight.js": "10.4.1",
32
+ "@highlightjs/cdn-assets": "^11.4.0",
33
+ "highlightjs-line-numbers.js": "^2.8.0",
33
34
  "markdown-it": "^12.0.6",
34
35
  "markdown-it-checkbox": "^1.1.0",
35
36
  "markdown-it-multimd-table": "^4.0.1",
@@ -39,12 +40,12 @@
39
40
  "compatibility": "^1.17.0"
40
41
  },
41
42
  "devDependencies": {
42
- "@commitlint/cli": "15.0.0",
43
- "@commitlint/config-angular": "15.0.0",
44
- "eslint": "8.4.0",
43
+ "@commitlint/cli": "16.1.0",
44
+ "@commitlint/config-angular": "16.0.0",
45
+ "eslint": "8.8.0",
45
46
  "eslint-config-airbnb-base": "15.0.0",
46
- "eslint-plugin-import": "2.25.3",
47
+ "eslint-plugin-import": "2.25.4",
47
48
  "husky": "7.0.4",
48
- "lint-staged": "12.1.2"
49
+ "lint-staged": "12.3.2"
49
50
  }
50
51
  }
package/plugin.json CHANGED
@@ -14,13 +14,12 @@
14
14
  "public/js/admin.js"
15
15
  ],
16
16
  "staticDirs": {
17
- "styles": "../highlight.js/styles",
18
- "js": "public/js"
17
+ "themes": "./node_modules/@highlightjs/cdn-assets/styles"
18
+ },
19
+ "modules": {
20
+ "highlight.js": "./node_modules/@highlightjs/cdn-assets/highlight.min.js",
21
+ "highlightjs-line-numbers.js": "./public/js/highlightjs-line-numbers.js"
19
22
  },
20
- "modules": [
21
- "./public/js/highlight.js",
22
- "./public/js/highlightjs-line-numbers.js"
23
- ],
24
23
  "languages": "public/languages",
25
24
  "defaultLang": "en_GB",
26
25
  "templates": "./public/templates",
@@ -37,5 +36,8 @@
37
36
  { "hook": "filter:config.get", "method": "getConfig" },
38
37
  { "hook": "filter:meta.getLinkTags", "method": "getLinkTags"},
39
38
  { "hook": "filter:sanitize.config", "method": "updateSanitizeConfig" }
39
+ ],
40
+ "upgrades": [
41
+ "upgrades/reset_md_hljs_theme.js"
40
42
  ]
41
43
  }
@@ -17,7 +17,7 @@ define('admin/plugins/markdown', ['settings', 'alerts'], function (Settings, ale
17
17
  langPrefix: 'language-',
18
18
  highlight: true,
19
19
  highlightLinesLanguageList: [],
20
- highlightTheme: 'railscasts.css',
20
+ highlightTheme: 'default.min.css',
21
21
 
22
22
  probe: true,
23
23
  probeCacheSize: 256,
@@ -1,246 +1,251 @@
1
- 'use strict';
2
-
3
- /* global window, jQuery, $, require, config, socket */
4
-
5
- (function () {
6
- var Markdown = {};
7
-
8
- $(window).on('action:composer.enhanced', function (evt, data) {
9
- var textareaEl = data.postContainer.find('textarea');
10
- Markdown.capturePaste(textareaEl);
11
- Markdown.prepareFormattingTools();
12
- });
13
-
14
- Markdown.enhanceCheckbox = function (ev, data) {
15
- if (!data.posts && !data.post) {
16
- return;
17
- } if (data.hasOwnProperty('post')) {
18
- data.posts = [data.post];
19
- }
20
-
21
- var disable;
22
- var checkboxEls;
23
- data.posts.forEach(function (post) {
24
- disable = !post.display_edit_tools;
25
- checkboxEls = $('.posts li[data-pid="' + post.pid + '"] .content div.plugin-markdown input[type="checkbox"]');
26
-
27
- checkboxEls.on('click', function (e) {
28
- if (disable) {
29
- // Find the post's checkboxes in DOM and make them readonly
30
- e.preventDefault();
31
- }
32
-
33
- // Otherwise, edit the post to reflect state change
34
- var _this = this;
35
- var pid = $(this).parents('li[data-pid]').attr('data-pid');
36
- var index = $(this).parents('.content').find('input[type="checkbox"]').toArray().reduce(function (memo, cur, index) {
37
- if (cur === _this) {
38
- memo = index;
39
- }
40
-
41
- return memo;
42
- }, null);
43
-
44
- socket.emit('plugins.markdown.checkbox.edit', {
45
- pid: pid,
46
- index: index,
47
- state: $(_this).prop('checked'),
48
- });
49
- });
50
- });
51
- };
52
-
53
- Markdown.capturePaste = function (targetEl) {
54
- targetEl.on('paste', function (e) {
55
- var triggers = [/^>\s*/, /^\s*\*\s+/, /^\s*\d+\.\s+/, /^\s{4,}/];
56
- var start = e.target.selectionStart;
57
- var line = getLine(targetEl.val(), start);
58
-
59
- var trigger = triggers.reduce(function (regexp, cur) {
60
- if (regexp) {
61
- return regexp;
62
- }
63
-
64
- return cur.test(line) ? cur : false;
65
- }, false);
66
-
67
- var prefix = line.match(trigger);
68
- if (prefix) {
69
- prefix = prefix.shift();
70
-
71
- var payload = e.originalEvent.clipboardData.getData('text');
72
- var fixed = payload.replace(/^/gm, prefix).slice(prefix.length);
73
-
74
- setTimeout(function () {
75
- var replacement = targetEl.val().slice(0, start) + fixed + targetEl.val().slice(start + payload.length);
76
- targetEl.val(replacement);
77
- }, 0);
78
- }
79
- });
80
-
81
- function getLine(text, selectionStart) {
82
- // Break apart into lines, return the line the cursor is in
83
- var lines = text.split('\n');
84
-
85
- return lines.reduce(function (memo, cur) {
86
- if (typeof memo !== 'number') {
87
- return memo;
88
- } if (selectionStart > (memo + cur.length)) {
89
- return memo + cur.length + 1;
90
- }
91
-
92
- return cur;
93
- }, 0);
94
- }
95
- };
96
-
97
- Markdown.highlight = function (data) {
98
- if (data instanceof jQuery.Event) {
99
- highlight($(data.data.selector));
100
- } else {
101
- highlight(data);
102
- }
103
- };
104
-
105
- Markdown.prepareFormattingTools = function () {
106
- require([
107
- 'composer/formatting',
108
- 'composer/controls',
109
- 'translator',
110
- ], function (formatting, controls, translator) {
111
- if (formatting && controls) {
112
- translator.getTranslations(window.config.userLang || window.config.defaultLang, 'markdown', function (strings) {
113
- formatting.addButtonDispatch('bold', function (textarea, selectionStart, selectionEnd) {
114
- if (selectionStart === selectionEnd) {
115
- var block = controls.getBlockData(textarea, '**', selectionStart);
116
-
117
- if (block.in && block.atEnd) {
118
- // At end of bolded string, move cursor past delimiters
119
- controls.updateTextareaSelection(textarea, selectionStart + 2, selectionStart + 2);
120
- } else {
121
- controls.insertIntoTextarea(textarea, '**' + strings.bold + '**');
122
- controls.updateTextareaSelection(textarea, selectionStart + 2, selectionStart + strings.bold.length + 2);
123
- }
124
- } else {
125
- var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '**');
126
- controls.updateTextareaSelection(textarea, selectionStart + 2 + wrapDelta[0], selectionEnd + 2 - wrapDelta[1]);
127
- }
128
- });
129
-
130
- formatting.addButtonDispatch('italic', function (textarea, selectionStart, selectionEnd) {
131
- if (selectionStart === selectionEnd) {
132
- var block = controls.getBlockData(textarea, '*', selectionStart);
133
-
134
- if (block.in && block.atEnd) {
135
- // At end of italicised string, move cursor past delimiters
136
- controls.updateTextareaSelection(textarea, selectionStart + 1, selectionStart + 1);
137
- } else {
138
- controls.insertIntoTextarea(textarea, '*' + strings.italic + '*');
139
- controls.updateTextareaSelection(textarea, selectionStart + 1, selectionStart + strings.italic.length + 1);
140
- }
141
- } else {
142
- var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '*');
143
- controls.updateTextareaSelection(textarea, selectionStart + 1 + wrapDelta[0], selectionEnd + 1 - wrapDelta[1]);
144
- }
145
- });
146
-
147
- formatting.addButtonDispatch('list', function (textarea, selectionStart, selectionEnd) {
148
- if (selectionStart === selectionEnd) {
149
- controls.insertIntoTextarea(textarea, '\n* ' + strings.list_item);
150
-
151
- // Highlight "list item"
152
- controls.updateTextareaSelection(textarea, selectionStart + 3, selectionStart + strings.list_item.length + 3);
153
- } else {
154
- var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '\n* ', '');
155
- controls.updateTextareaSelection(textarea, selectionStart + 3 + wrapDelta[0], selectionEnd + 3 - wrapDelta[1]);
156
- }
157
- });
158
-
159
- formatting.addButtonDispatch('strikethrough', function (textarea, selectionStart, selectionEnd) {
160
- if (selectionStart === selectionEnd) {
161
- var block = controls.getBlockData(textarea, '~~', selectionStart);
162
-
163
- if (block.in && block.atEnd) {
164
- // At end of bolded string, move cursor past delimiters
165
- controls.updateTextareaSelection(textarea, selectionStart + 2, selectionStart + 2);
166
- } else {
167
- controls.insertIntoTextarea(textarea, '~~' + strings.strikethrough_text + '~~');
168
- controls.updateTextareaSelection(textarea, selectionStart + 2, selectionEnd + strings.strikethrough_text.length + 2);
169
- }
170
- } else {
171
- var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '~~', '~~');
172
- controls.updateTextareaSelection(textarea, selectionStart + 2 + wrapDelta[0], selectionEnd + 2 - wrapDelta[1]);
173
- }
174
- });
175
-
176
- formatting.addButtonDispatch('code', function (textarea, selectionStart, selectionEnd) {
177
- if (selectionStart === selectionEnd) {
178
- controls.insertIntoTextarea(textarea, '```\n' + strings.code_text + '\n```');
179
- controls.updateTextareaSelection(textarea, selectionStart + 4, selectionEnd + strings.code_text.length + 4);
180
- } else {
181
- var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '```\n', '\n```');
182
- controls.updateTextareaSelection(textarea, selectionStart + 4 + wrapDelta[0], selectionEnd + 4 - wrapDelta[1]);
183
- }
184
- });
185
-
186
- formatting.addButtonDispatch('link', function (textarea, selectionStart, selectionEnd) {
187
- if (selectionStart === selectionEnd) {
188
- controls.insertIntoTextarea(textarea, '[' + strings.link_text + '](' + strings.link_url + ')');
189
- controls.updateTextareaSelection(textarea, selectionStart + strings.link_text.length + 3, selectionEnd + strings.link_text.length + strings.link_url.length + 3);
190
- } else {
191
- var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '[', '](' + strings.link_url + ')');
192
- controls.updateTextareaSelection(textarea, selectionEnd + 3 - wrapDelta[1], selectionEnd + strings.link_url.length + 3 - wrapDelta[1]);
193
- }
194
- });
195
-
196
- formatting.addButtonDispatch('picture-o', function (textarea, selectionStart, selectionEnd) {
197
- if (selectionStart === selectionEnd) {
198
- controls.insertIntoTextarea(textarea, '![' + strings.picture_text + '](' + strings.picture_url + ')');
199
- controls.updateTextareaSelection(textarea, selectionStart + strings.picture_text.length + 4, selectionEnd + strings.picture_text.length + strings.picture_url.length + 4);
200
- } else {
201
- var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '![', '](' + strings.picture_url + ')');
202
- controls.updateTextareaSelection(textarea, selectionEnd + 4 - wrapDelta[1], selectionEnd + strings.picture_url.length + 4 - wrapDelta[1]);
203
- }
204
- });
205
- });
206
- }
207
- });
208
- };
209
-
210
- function highlight(elements) {
211
- if (parseInt(config.markdown.highlight, 10)) {
212
- require(['highlight', 'highlightjs-line-numbers'], function (hljs) {
213
- elements.each(function (i, block) {
214
- $(block.parentNode).addClass('markdown-highlight');
215
- hljs.highlightBlock(block);
216
-
217
- // Check detected language against whitelist and add lines if enabled
218
- if (block.className.split(' ').map(function (className) {
219
- if (className.indexOf('language-') === 0) {
220
- className = className.slice(9);
221
- }
222
- return config.markdown.highlightLinesLanguageList.includes(className) || config.markdown.highlightLinesLanguageList.includes(className);
223
- }).some(Boolean)) {
224
- $(block).attr('data-lines', 1);
225
- hljs.lineNumbersBlock(block);
226
- }
227
- });
228
- });
229
- }
230
- }
231
-
232
- $(window).on('action:composer.preview', {
233
- selector: '.composer .preview pre code',
234
- }, Markdown.highlight);
235
-
236
- $(window).on('action:topic.loaded', Markdown.enhanceCheckbox);
237
- $(window).on('action:posts.loaded', Markdown.enhanceCheckbox);
238
- $(window).on('action:posts.edited', Markdown.enhanceCheckbox);
239
-
240
-
241
- $(window).on('action:posts.loaded action:topic.loaded action:posts.edited', function () {
242
- require(['components'], function (components) {
243
- Markdown.highlight(components.get('post/content').find('pre code'));
244
- });
245
- });
246
- }());
1
+ 'use strict';
2
+
3
+ /* global window, jQuery, $, config, socket */
4
+
5
+ (function () {
6
+ var Markdown = {};
7
+
8
+ $(window).on('action:composer.enhanced', function (evt, data) {
9
+ var textareaEl = data.postContainer.find('textarea');
10
+ Markdown.capturePaste(textareaEl);
11
+ Markdown.prepareFormattingTools();
12
+ });
13
+
14
+ Markdown.enhanceCheckbox = function (ev, data) {
15
+ if (!data.posts && !data.post) {
16
+ return;
17
+ } if (data.hasOwnProperty('post')) {
18
+ data.posts = [data.post];
19
+ }
20
+
21
+ var disable;
22
+ var checkboxEls;
23
+ data.posts.forEach(function (post) {
24
+ disable = !post.display_edit_tools;
25
+ checkboxEls = $('.posts li[data-pid="' + post.pid + '"] .content div.plugin-markdown input[type="checkbox"]');
26
+
27
+ checkboxEls.on('click', function (e) {
28
+ if (disable) {
29
+ // Find the post's checkboxes in DOM and make them readonly
30
+ e.preventDefault();
31
+ }
32
+
33
+ // Otherwise, edit the post to reflect state change
34
+ var _this = this;
35
+ var pid = $(this).parents('li[data-pid]').attr('data-pid');
36
+ var index = $(this).parents('.content').find('input[type="checkbox"]').toArray().reduce(function (memo, cur, index) {
37
+ if (cur === _this) {
38
+ memo = index;
39
+ }
40
+
41
+ return memo;
42
+ }, null);
43
+
44
+ socket.emit('plugins.markdown.checkbox.edit', {
45
+ pid: pid,
46
+ index: index,
47
+ state: $(_this).prop('checked'),
48
+ });
49
+ });
50
+ });
51
+ };
52
+
53
+ Markdown.capturePaste = function (targetEl) {
54
+ targetEl.on('paste', function (e) {
55
+ var triggers = [/^>\s*/, /^\s*\*\s+/, /^\s*\d+\.\s+/, /^\s{4,}/];
56
+ var start = e.target.selectionStart;
57
+ var line = getLine(targetEl.val(), start);
58
+
59
+ var trigger = triggers.reduce(function (regexp, cur) {
60
+ if (regexp) {
61
+ return regexp;
62
+ }
63
+
64
+ return cur.test(line) ? cur : false;
65
+ }, false);
66
+
67
+ var prefix = line.match(trigger);
68
+ if (prefix) {
69
+ prefix = prefix.shift();
70
+
71
+ var payload = e.originalEvent.clipboardData.getData('text');
72
+ var fixed = payload.replace(/^/gm, prefix).slice(prefix.length);
73
+
74
+ setTimeout(function () {
75
+ var replacement = targetEl.val().slice(0, start) + fixed + targetEl.val().slice(start + payload.length);
76
+ targetEl.val(replacement);
77
+ }, 0);
78
+ }
79
+ });
80
+
81
+ function getLine(text, selectionStart) {
82
+ // Break apart into lines, return the line the cursor is in
83
+ var lines = text.split('\n');
84
+
85
+ return lines.reduce(function (memo, cur) {
86
+ if (typeof memo !== 'number') {
87
+ return memo;
88
+ } if (selectionStart > (memo + cur.length)) {
89
+ return memo + cur.length + 1;
90
+ }
91
+
92
+ return cur;
93
+ }, 0);
94
+ }
95
+ };
96
+
97
+ Markdown.highlight = function (data) {
98
+ if (data instanceof jQuery.Event) {
99
+ highlight($(data.data.selector));
100
+ } else {
101
+ highlight(data);
102
+ }
103
+ };
104
+
105
+ Markdown.prepareFormattingTools = function () {
106
+ require([
107
+ 'composer/formatting',
108
+ 'composer/controls',
109
+ 'translator',
110
+ ], function (formatting, controls, translator) {
111
+ if (formatting && controls) {
112
+ translator.getTranslations(window.config.userLang || window.config.defaultLang, 'markdown', function (strings) {
113
+ formatting.addButtonDispatch('bold', function (textarea, selectionStart, selectionEnd) {
114
+ if (selectionStart === selectionEnd) {
115
+ var block = controls.getBlockData(textarea, '**', selectionStart);
116
+
117
+ if (block.in && block.atEnd) {
118
+ // At end of bolded string, move cursor past delimiters
119
+ controls.updateTextareaSelection(textarea, selectionStart + 2, selectionStart + 2);
120
+ } else {
121
+ controls.insertIntoTextarea(textarea, '**' + strings.bold + '**');
122
+ controls.updateTextareaSelection(textarea, selectionStart + 2, selectionStart + strings.bold.length + 2);
123
+ }
124
+ } else {
125
+ var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '**');
126
+ controls.updateTextareaSelection(textarea, selectionStart + 2 + wrapDelta[0], selectionEnd + 2 - wrapDelta[1]);
127
+ }
128
+ });
129
+
130
+ formatting.addButtonDispatch('italic', function (textarea, selectionStart, selectionEnd) {
131
+ if (selectionStart === selectionEnd) {
132
+ var block = controls.getBlockData(textarea, '*', selectionStart);
133
+
134
+ if (block.in && block.atEnd) {
135
+ // At end of italicised string, move cursor past delimiters
136
+ controls.updateTextareaSelection(textarea, selectionStart + 1, selectionStart + 1);
137
+ } else {
138
+ controls.insertIntoTextarea(textarea, '*' + strings.italic + '*');
139
+ controls.updateTextareaSelection(textarea, selectionStart + 1, selectionStart + strings.italic.length + 1);
140
+ }
141
+ } else {
142
+ var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '*');
143
+ controls.updateTextareaSelection(textarea, selectionStart + 1 + wrapDelta[0], selectionEnd + 1 - wrapDelta[1]);
144
+ }
145
+ });
146
+
147
+ formatting.addButtonDispatch('list', function (textarea, selectionStart, selectionEnd) {
148
+ if (selectionStart === selectionEnd) {
149
+ controls.insertIntoTextarea(textarea, '\n* ' + strings.list_item);
150
+
151
+ // Highlight "list item"
152
+ controls.updateTextareaSelection(textarea, selectionStart + 3, selectionStart + strings.list_item.length + 3);
153
+ } else {
154
+ var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '\n* ', '');
155
+ controls.updateTextareaSelection(textarea, selectionStart + 3 + wrapDelta[0], selectionEnd + 3 - wrapDelta[1]);
156
+ }
157
+ });
158
+
159
+ formatting.addButtonDispatch('strikethrough', function (textarea, selectionStart, selectionEnd) {
160
+ if (selectionStart === selectionEnd) {
161
+ var block = controls.getBlockData(textarea, '~~', selectionStart);
162
+
163
+ if (block.in && block.atEnd) {
164
+ // At end of bolded string, move cursor past delimiters
165
+ controls.updateTextareaSelection(textarea, selectionStart + 2, selectionStart + 2);
166
+ } else {
167
+ controls.insertIntoTextarea(textarea, '~~' + strings.strikethrough_text + '~~');
168
+ controls.updateTextareaSelection(textarea, selectionStart + 2, selectionEnd + strings.strikethrough_text.length + 2);
169
+ }
170
+ } else {
171
+ var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '~~', '~~');
172
+ controls.updateTextareaSelection(textarea, selectionStart + 2 + wrapDelta[0], selectionEnd + 2 - wrapDelta[1]);
173
+ }
174
+ });
175
+
176
+ formatting.addButtonDispatch('code', function (textarea, selectionStart, selectionEnd) {
177
+ if (selectionStart === selectionEnd) {
178
+ controls.insertIntoTextarea(textarea, '```\n' + strings.code_text + '\n```');
179
+ controls.updateTextareaSelection(textarea, selectionStart + 4, selectionEnd + strings.code_text.length + 4);
180
+ } else {
181
+ var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '```\n', '\n```');
182
+ controls.updateTextareaSelection(textarea, selectionStart + 4 + wrapDelta[0], selectionEnd + 4 - wrapDelta[1]);
183
+ }
184
+ });
185
+
186
+ formatting.addButtonDispatch('link', function (textarea, selectionStart, selectionEnd) {
187
+ if (selectionStart === selectionEnd) {
188
+ controls.insertIntoTextarea(textarea, '[' + strings.link_text + '](' + strings.link_url + ')');
189
+ controls.updateTextareaSelection(textarea, selectionStart + strings.link_text.length + 3, selectionEnd + strings.link_text.length + strings.link_url.length + 3);
190
+ } else {
191
+ var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '[', '](' + strings.link_url + ')');
192
+ controls.updateTextareaSelection(textarea, selectionEnd + 3 - wrapDelta[1], selectionEnd + strings.link_url.length + 3 - wrapDelta[1]);
193
+ }
194
+ });
195
+
196
+ formatting.addButtonDispatch('picture-o', function (textarea, selectionStart, selectionEnd) {
197
+ if (selectionStart === selectionEnd) {
198
+ controls.insertIntoTextarea(textarea, '![' + strings.picture_text + '](' + strings.picture_url + ')');
199
+ controls.updateTextareaSelection(textarea, selectionStart + strings.picture_text.length + 4, selectionEnd + strings.picture_text.length + strings.picture_url.length + 4);
200
+ } else {
201
+ var wrapDelta = controls.wrapSelectionInTextareaWith(textarea, '![', '](' + strings.picture_url + ')');
202
+ controls.updateTextareaSelection(textarea, selectionEnd + 4 - wrapDelta[1], selectionEnd + strings.picture_url.length + 4 - wrapDelta[1]);
203
+ }
204
+ });
205
+ });
206
+ }
207
+ });
208
+ };
209
+
210
+ function highlight(elements) {
211
+ if (parseInt(config.markdown.highlight, 10)) {
212
+ require(['highlight', 'highlightjs-line-numbers'], function () {
213
+ elements.each(function (i, block) {
214
+ $(block.parentNode).addClass('markdown-highlight');
215
+
216
+ // Default language if set in ACP
217
+ if (!Array.prototype.some.call(block.classList, (className) => className.startsWith('language-')) && config.markdown.defaultHighlightLanguage) {
218
+ block.classList.add(`language-${config.markdown.defaultHighlightLanguage}`);
219
+ }
220
+
221
+ window.hljs.highlightElement(block);
222
+
223
+ // Check detected language against whitelist and add lines if enabled
224
+ if (block.className.split(' ').map(function (className) {
225
+ if (className.indexOf('language-') === 0) {
226
+ className = className.slice(9);
227
+ }
228
+ return config.markdown.highlightLinesLanguageList.includes(className) || config.markdown.highlightLinesLanguageList.includes(className);
229
+ }).some(Boolean)) {
230
+ $(block).attr('data-lines', 1);
231
+ window.hljs.lineNumbersBlock(block);
232
+ }
233
+ });
234
+ });
235
+ }
236
+ }
237
+
238
+ $(window).on('action:composer.preview', {
239
+ selector: '.composer .preview pre code',
240
+ }, Markdown.highlight);
241
+
242
+ $(window).on('action:topic.loaded', Markdown.enhanceCheckbox);
243
+ $(window).on('action:posts.loaded', Markdown.enhanceCheckbox);
244
+ $(window).on('action:posts.edited', Markdown.enhanceCheckbox);
245
+
246
+ $(window).on('action:posts.loaded action:topic.loaded action:posts.edited', function () {
247
+ require(['components'], function (components) {
248
+ Markdown.highlight(components.get('post/content').find('pre code'));
249
+ });
250
+ });
251
+ }());