kit_cms 2.3.16 → 2.3.17
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.
- data/app/assets/images/kit/toolbar/bold.png +0 -0
- data/app/assets/images/kit/toolbar/formatted.png +0 -0
- data/app/assets/images/kit/toolbar/image.png +0 -0
- data/app/assets/images/kit/toolbar/link.png +0 -0
- data/app/assets/images/kit/toolbar/list.png +0 -0
- data/app/assets/images/kit/toolbar/numbered_list.png +0 -0
- data/app/assets/images/kit/toolbar/preview.png +0 -0
- data/app/assets/images/kit/toolbar/quote.png +0 -0
- data/app/assets/images/kit/toolbar/redo.png +0 -0
- data/app/assets/images/kit/toolbar/underline.png +0 -0
- data/app/assets/images/kit/toolbar/undo.png +0 -0
- data/app/assets/images/kit/toolbar/video.png +0 -0
- data/app/assets/javascripts/codemirror/editor.js +183 -0
- data/app/assets/javascripts/codemirror/markdown.js +475 -0
- data/app/assets/javascripts/jquery.contextmenu.js +7 -7
- data/app/assets/javascripts/kit/kit.js +0 -1
- data/app/assets/javascripts/kit/markdown.js +1 -37
- data/app/assets/javascripts/kit/tree.js +18 -10
- data/app/assets/javascripts/kit/utilities.js +1 -1
- data/app/assets/stylesheets/codemirror/editor.css +3 -3
- data/app/assets/stylesheets/codemirror/theme.css +76 -1
- data/app/assets/stylesheets/kit/calendar.css +58 -97
- data/app/assets/stylesheets/kit/cms/cms.css +19 -0
- data/app/assets/stylesheets/kit/cms/dsc_tree.css +4 -0
- data/app/assets/stylesheets/kit/forums.css +30 -0
- data/app/assets/stylesheets/kit/kit.css +0 -1
- data/app/controllers/admin/dashboard_controller.rb +11 -2
- data/app/controllers/admin/page_templates_controller.rb +14 -1
- data/app/controllers/admin/user_controller.rb +2 -3
- data/app/controllers/category_controller.rb +5 -6
- data/app/controllers/form_controller.rb +1 -1
- data/app/controllers/forum_controller.rb +2 -2
- data/app/controllers/kit_controller.rb +2 -2
- data/app/controllers/pages_controller.rb +24 -0
- data/app/controllers/user/passwords_controller.rb +2 -0
- data/app/controllers/user/registrations_controller.rb +1 -4
- data/app/controllers/user/sessions_controller.rb +2 -0
- data/app/controllers/user/unlocks_controller.rb +2 -0
- data/app/controllers/user_controller.rb +1 -1
- data/app/helpers/calendar_helper.rb +4 -1
- data/app/helpers/kit_helper.rb +3 -3
- data/app/mailers/notification.rb +3 -3
- data/app/models/activity.rb +5 -2
- data/app/models/calendar.rb +1 -1
- data/app/models/category.rb +18 -4
- data/app/models/experiment.rb +2 -0
- data/app/models/form_submission.rb +2 -2
- data/app/models/html_asset.rb +3 -0
- data/app/models/mapping.rb +1 -0
- data/app/models/user.rb +1 -1
- data/app/views/admin/blocks/_form.html.haml +1 -1
- data/app/views/admin/dashboard/user_comments.html.haml +19 -8
- data/app/views/admin/experiments/show.html.haml +1 -1
- data/app/views/admin/form/_form.html.haml +8 -0
- data/app/views/admin/page_templates/_form.html.haml +1 -1
- data/app/views/admin/views/_form.html.haml +4 -4
- data/app/views/calendar/_calendar_scripts.js.erb +2 -2
- data/app/views/calendar/_month.html.haml +58 -27
- data/app/views/category/_select_options.html.erb +1 -1
- data/app/views/form/_show.html.haml +9 -1
- data/app/views/forum/_add_post.html.haml +3 -2
- data/app/views/forum/_mod_thread.js.erb +2 -2
- data/app/views/forum/_post_scripts.js.erb +1 -2
- data/app/views/forum/thread.html.haml +4 -0
- data/app/views/layouts/_application.html.erb +1 -0
- data/app/views/layouts/minimal.html.erb +2 -2
- data/app/views/notification/form_submission.text.erb +2 -0
- data/app/views/pages/_form.html.haml +7 -8
- data/app/views/pages/_page_scripts.js.erb +1 -3
- data/app/views/pages/_page_template_script.js.erb +28 -0
- data/app/views/pages/cookie_text.html.haml +1 -1
- data/app/views/pages/info.html.erb +2 -2
- data/app/views/pages/page_template.html.haml +40 -0
- data/app/views/utility/_cm_editor.html.erb +34 -5
- data/app/views/utility/_cm_toolbar_markdown.html.haml +49 -0
- data/config/initializers/devise_extender.rb +9 -0
- data/config/initializers/html_assets.rb +4 -0
- data/config/initializers/quiet_asserts.rb +1 -1
- data/config/routes.rb +2 -0
- metadata +21 -3
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -5,6 +5,7 @@
|
|
5
5
|
*= require "./htmlmixed"
|
6
6
|
*= require "./sass"
|
7
7
|
*= require "./css"
|
8
|
+
*= require "./markdown"
|
8
9
|
*= require "./xml"
|
9
10
|
*= require "./javascript"
|
10
11
|
*= require "./dialog"
|
@@ -16,4 +17,186 @@
|
|
16
17
|
*
|
17
18
|
*/
|
18
19
|
|
20
|
+
var html_editors = new Array();
|
19
21
|
|
22
|
+
function do_bold(editor) {
|
23
|
+
insert_formatting(editor, "*", "*", "Bold");
|
24
|
+
}
|
25
|
+
|
26
|
+
function do_underline(editor) {
|
27
|
+
insert_formatting(editor, "_", "_", "Underlined");
|
28
|
+
}
|
29
|
+
|
30
|
+
function do_cmd(editor, cmd) {
|
31
|
+
if (cmd=='list') {
|
32
|
+
do_list(editor, '-');
|
33
|
+
}
|
34
|
+
if (cmd=='numbered_list') {
|
35
|
+
do_list(editor, '1.');
|
36
|
+
}
|
37
|
+
if (cmd=='image') {
|
38
|
+
do_image(editor);
|
39
|
+
}
|
40
|
+
if (cmd=='video') {
|
41
|
+
do_video(editor);
|
42
|
+
}
|
43
|
+
if (cmd=='link') {
|
44
|
+
do_link(editor);
|
45
|
+
}
|
46
|
+
if (cmd=='bold') {
|
47
|
+
insert_formatting(editor, '**', '**', 'Bold');
|
48
|
+
}
|
49
|
+
if (cmd=='underline') {
|
50
|
+
insert_formatting(editor, '_', '_', 'Underline');
|
51
|
+
}
|
52
|
+
if (cmd=='pre') {
|
53
|
+
do_prefix(editor, ' ');
|
54
|
+
}
|
55
|
+
if (cmd=='quote') {
|
56
|
+
do_prefix(editor, '> ');
|
57
|
+
}
|
58
|
+
if (cmd=='undo') {
|
59
|
+
do_undo(editor);
|
60
|
+
}
|
61
|
+
if (cmd=='redo') {
|
62
|
+
do_redo(editor);
|
63
|
+
}
|
64
|
+
if (cmd=='preview') {
|
65
|
+
do_preview(editor);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
function do_prefix(editor, prefix) {
|
70
|
+
var editor = html_editors[editor];
|
71
|
+
var start_pos = editor.getCursor('start');
|
72
|
+
var end_pos = editor.getCursor('end');
|
73
|
+
|
74
|
+
if (editor.somethingSelected()) {
|
75
|
+
for (var i = start_pos.line; i <= end_pos.line; i++) {
|
76
|
+
editor.setLine(i, prefix + editor.getLine(i));
|
77
|
+
}
|
78
|
+
} else {
|
79
|
+
if (start_pos.ch==0) {
|
80
|
+
editor.replaceSelection(prefix);
|
81
|
+
}
|
82
|
+
else {
|
83
|
+
editor.setLine(start_pos.line, prefix + editor.getLine(start_pos.line));
|
84
|
+
}
|
85
|
+
start_pos.ch = start_pos.ch + prefix.length;
|
86
|
+
editor.setCursor(start_pos);
|
87
|
+
}
|
88
|
+
editor.focus();
|
89
|
+
}
|
90
|
+
|
91
|
+
function do_link(editor) {
|
92
|
+
var url = prompt("Enter the full URL for the link", "http://");
|
93
|
+
|
94
|
+
insert_formatting(editor, '[', '](' + url + ')', 'Link');
|
95
|
+
}
|
96
|
+
|
97
|
+
function do_video(editor) {
|
98
|
+
var editor = html_editors[editor];
|
99
|
+
var start_pos = editor.getCursor('start');
|
100
|
+
var url = prompt("Enter Youtube 'share' URL or Vimeo URL");
|
101
|
+
|
102
|
+
editor.replaceSelection(url);
|
103
|
+
start_pos.ch = start_pos.ch + url.length;
|
104
|
+
editor.setCursor(start_pos);
|
105
|
+
editor.focus();
|
106
|
+
}
|
107
|
+
|
108
|
+
function do_undo(editor) {
|
109
|
+
var editor = html_editors[editor];
|
110
|
+
editor.undo();
|
111
|
+
}
|
112
|
+
|
113
|
+
function do_redo(editor) {
|
114
|
+
var editor = html_editors[editor];
|
115
|
+
editor.redo();
|
116
|
+
}
|
117
|
+
|
118
|
+
function do_image(editor) {
|
119
|
+
var editor = html_editors[editor];
|
120
|
+
var url = prompt("Enter the full URL of the image", "http://");
|
121
|
+
var start_pos = editor.getCursor('start');
|
122
|
+
|
123
|
+
editor.replaceSelection("");
|
124
|
+
start_pos.ch = start_pos.ch + url.length + 5;
|
125
|
+
editor.setCursor(start_pos);
|
126
|
+
editor.focus();
|
127
|
+
}
|
128
|
+
|
129
|
+
function do_list(editor_name,list) {
|
130
|
+
var editor = html_editors[editor_name];
|
131
|
+
var start_pos = editor.getCursor('start');
|
132
|
+
var end_pos = editor.getCursor('end');
|
133
|
+
var to_insert = '';
|
134
|
+
|
135
|
+
if (editor.somethingSelected()) {
|
136
|
+
if (start_pos.line != end_pos.line) {
|
137
|
+
do_prefix(editor_name, list);
|
138
|
+
return;
|
139
|
+
}
|
140
|
+
else {
|
141
|
+
var selection = editor.getSelection();
|
142
|
+
editor.replaceSelection(((start_pos.ch==0) ? '' : '\r') + list + ' ' + selection + '\r' + list + ' ');
|
143
|
+
start_pos.line = start_pos.line + 2;
|
144
|
+
start_pos.ch = selection.length + list.length;
|
145
|
+
}
|
146
|
+
editor.setCursor(start_pos);
|
147
|
+
}
|
148
|
+
else {
|
149
|
+
if (start_pos.ch>0) {
|
150
|
+
var line = editor.getLine(start_pos.line);
|
151
|
+
if (line && line.indexOf(list)==0) {
|
152
|
+
editor.setLine(start_pos.line, editor.getLine(start_pos.line) + '\r' + list + ' ');
|
153
|
+
}
|
154
|
+
else {
|
155
|
+
editor.setLine(start_pos.line, list + ' ' + editor.getLine(start_pos.line) + '\r' + list + ' ');
|
156
|
+
}
|
157
|
+
start_pos.line = start_pos.line + 1;
|
158
|
+
editor.setCursor(start_pos);
|
159
|
+
} else {
|
160
|
+
editor.replaceSelection(list + ' ');
|
161
|
+
start_pos.ch = list.length+1;
|
162
|
+
editor.setCursor(start_pos);
|
163
|
+
}
|
164
|
+
}
|
165
|
+
editor.focus();
|
166
|
+
}
|
167
|
+
|
168
|
+
function insert_formatting(editor,start,end,placeholder) {
|
169
|
+
var editor = html_editors[editor];
|
170
|
+
var current = editor.getSelection();
|
171
|
+
var placeholder_mode = false;
|
172
|
+
var start_pos = editor.getCursor("start");
|
173
|
+
var end_pos = editor.getCursor("end");
|
174
|
+
|
175
|
+
if (!editor.somethingSelected()) {
|
176
|
+
current = placeholder;
|
177
|
+
placeholder_mode = true;
|
178
|
+
}
|
179
|
+
|
180
|
+
editor.replaceSelection(start + current + end);
|
181
|
+
if (placeholder_mode) {
|
182
|
+
start_pos.ch = start_pos.ch + start.length;
|
183
|
+
end_pos.ch = start_pos.ch + placeholder.length;
|
184
|
+
editor.setSelection( start_pos, end_pos);
|
185
|
+
}
|
186
|
+
else {
|
187
|
+
end_pos.ch = end_pos.ch + (start.length*2);
|
188
|
+
editor.setCursor(end_pos);
|
189
|
+
}
|
190
|
+
editor.focus();
|
191
|
+
}
|
192
|
+
|
193
|
+
|
194
|
+
function do_preview(field) {
|
195
|
+
var editor = html_editors[field];
|
196
|
+
$('#preview_' + field).dialog({ autoOpen: true,
|
197
|
+
width: 800, height: 500, modal: true, resizable: true, show: {effect:"drop"}, title: "Preview", closeOnEscape: true, dialogClass: "modal_markdown_preview" });
|
198
|
+
|
199
|
+
$.post('/utility/markdown_preview', {body: editor.getValue()}, function(data) {
|
200
|
+
$('#preview_' + field).html(data);
|
201
|
+
});
|
202
|
+
}
|
@@ -0,0 +1,475 @@
|
|
1
|
+
CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
2
|
+
|
3
|
+
var htmlFound = CodeMirror.mimeModes.hasOwnProperty("text/html");
|
4
|
+
var htmlMode = CodeMirror.getMode(cmCfg, htmlFound ? "text/html" : "text/plain");
|
5
|
+
var aliases = {
|
6
|
+
html: "htmlmixed",
|
7
|
+
js: "javascript",
|
8
|
+
json: "application/json",
|
9
|
+
c: "text/x-csrc",
|
10
|
+
"c++": "text/x-c++src",
|
11
|
+
java: "text/x-java",
|
12
|
+
csharp: "text/x-csharp",
|
13
|
+
"c#": "text/x-csharp",
|
14
|
+
scala: "text/x-scala"
|
15
|
+
};
|
16
|
+
|
17
|
+
var getMode = (function () {
|
18
|
+
var i, modes = {}, mimes = {}, mime;
|
19
|
+
|
20
|
+
var list = [];
|
21
|
+
for (var m in CodeMirror.modes)
|
22
|
+
if (CodeMirror.modes.propertyIsEnumerable(m)) list.push(m);
|
23
|
+
for (i = 0; i < list.length; i++) {
|
24
|
+
modes[list[i]] = list[i];
|
25
|
+
}
|
26
|
+
var mimesList = [];
|
27
|
+
for (var m in CodeMirror.mimeModes)
|
28
|
+
if (CodeMirror.mimeModes.propertyIsEnumerable(m))
|
29
|
+
mimesList.push({mime: m, mode: CodeMirror.mimeModes[m]});
|
30
|
+
for (i = 0; i < mimesList.length; i++) {
|
31
|
+
mime = mimesList[i].mime;
|
32
|
+
mimes[mime] = mimesList[i].mime;
|
33
|
+
}
|
34
|
+
|
35
|
+
for (var a in aliases) {
|
36
|
+
if (aliases[a] in modes || aliases[a] in mimes)
|
37
|
+
modes[a] = aliases[a];
|
38
|
+
}
|
39
|
+
|
40
|
+
return function (lang) {
|
41
|
+
return modes[lang] ? CodeMirror.getMode(cmCfg, modes[lang]) : null;
|
42
|
+
};
|
43
|
+
}());
|
44
|
+
|
45
|
+
// Should underscores in words open/close em/strong?
|
46
|
+
if (modeCfg.underscoresBreakWords === undefined)
|
47
|
+
modeCfg.underscoresBreakWords = true;
|
48
|
+
|
49
|
+
// Turn on fenced code blocks? ("```" to start/end)
|
50
|
+
if (modeCfg.fencedCodeBlocks === undefined) modeCfg.fencedCodeBlocks = false;
|
51
|
+
|
52
|
+
var codeDepth = 0;
|
53
|
+
var prevLineHasContent = false
|
54
|
+
, thisLineHasContent = false;
|
55
|
+
|
56
|
+
var header = 'header'
|
57
|
+
, code = 'comment'
|
58
|
+
, quote = 'quote'
|
59
|
+
, list = 'string'
|
60
|
+
, hr = 'hr'
|
61
|
+
, image = 'tag'
|
62
|
+
, linkinline = 'link'
|
63
|
+
, linkemail = 'link'
|
64
|
+
, linktext = 'link'
|
65
|
+
, linkhref = 'string'
|
66
|
+
, em = 'em'
|
67
|
+
, strong = 'strong'
|
68
|
+
, emstrong = 'emstrong';
|
69
|
+
|
70
|
+
var hrRE = /^([*\-=_])(?:\s*\1){2,}\s*$/
|
71
|
+
, ulRE = /^[*\-+]\s+/
|
72
|
+
, olRE = /^[0-9]+\.\s+/
|
73
|
+
, headerRE = /^(?:\={1,}|-{1,})$/
|
74
|
+
, textRE = /^[^!\[\]*_\\<>` "'(]+/;
|
75
|
+
|
76
|
+
function switchInline(stream, state, f) {
|
77
|
+
state.f = state.inline = f;
|
78
|
+
return f(stream, state);
|
79
|
+
}
|
80
|
+
|
81
|
+
function switchBlock(stream, state, f) {
|
82
|
+
state.f = state.block = f;
|
83
|
+
return f(stream, state);
|
84
|
+
}
|
85
|
+
|
86
|
+
|
87
|
+
// Blocks
|
88
|
+
|
89
|
+
function blankLine(state) {
|
90
|
+
// Reset linkTitle state
|
91
|
+
state.linkTitle = false;
|
92
|
+
// Reset EM state
|
93
|
+
state.em = false;
|
94
|
+
// Reset STRONG state
|
95
|
+
state.strong = false;
|
96
|
+
// Reset state.quote
|
97
|
+
state.quote = false;
|
98
|
+
if (!htmlFound && state.f == htmlBlock) {
|
99
|
+
state.f = inlineNormal;
|
100
|
+
state.block = blockNormal;
|
101
|
+
}
|
102
|
+
return null;
|
103
|
+
}
|
104
|
+
|
105
|
+
function blockNormal(stream, state) {
|
106
|
+
|
107
|
+
if (state.list !== false && state.indentationDiff >= 0) { // Continued list
|
108
|
+
if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
|
109
|
+
state.indentation -= state.indentationDiff;
|
110
|
+
}
|
111
|
+
state.list = null;
|
112
|
+
} else { // No longer a list
|
113
|
+
state.list = false;
|
114
|
+
}
|
115
|
+
|
116
|
+
if (state.indentationDiff >= 4) {
|
117
|
+
state.indentation -= 4;
|
118
|
+
stream.skipToEnd();
|
119
|
+
return code;
|
120
|
+
} else if (stream.eatSpace()) {
|
121
|
+
return null;
|
122
|
+
} else if (stream.peek() === '#' || (prevLineHasContent && stream.match(headerRE)) ) {
|
123
|
+
state.header = true;
|
124
|
+
} else if (stream.eat('>')) {
|
125
|
+
state.indentation++;
|
126
|
+
state.quote = true;
|
127
|
+
} else if (stream.peek() === '[') {
|
128
|
+
return switchInline(stream, state, footnoteLink);
|
129
|
+
} else if (stream.match(hrRE, true)) {
|
130
|
+
return hr;
|
131
|
+
} else if (stream.match(ulRE, true) || stream.match(olRE, true)) {
|
132
|
+
state.indentation += 4;
|
133
|
+
state.list = true;
|
134
|
+
} else if (modeCfg.fencedCodeBlocks && stream.match(/^```([\w+#]*)/, true)) {
|
135
|
+
// try switching mode
|
136
|
+
state.localMode = getMode(RegExp.$1);
|
137
|
+
if (state.localMode) state.localState = state.localMode.startState();
|
138
|
+
switchBlock(stream, state, local);
|
139
|
+
return code;
|
140
|
+
}
|
141
|
+
|
142
|
+
return switchInline(stream, state, state.inline);
|
143
|
+
}
|
144
|
+
|
145
|
+
function htmlBlock(stream, state) {
|
146
|
+
var style = htmlMode.token(stream, state.htmlState);
|
147
|
+
if (htmlFound && style === 'tag' && state.htmlState.type !== 'openTag' && !state.htmlState.context) {
|
148
|
+
state.f = inlineNormal;
|
149
|
+
state.block = blockNormal;
|
150
|
+
}
|
151
|
+
if (state.md_inside && stream.current().indexOf(">")!=-1) {
|
152
|
+
state.f = inlineNormal;
|
153
|
+
state.block = blockNormal;
|
154
|
+
state.htmlState.context = undefined;
|
155
|
+
}
|
156
|
+
return style;
|
157
|
+
}
|
158
|
+
|
159
|
+
function local(stream, state) {
|
160
|
+
if (stream.sol() && stream.match(/^```/, true)) {
|
161
|
+
state.localMode = state.localState = null;
|
162
|
+
state.f = inlineNormal;
|
163
|
+
state.block = blockNormal;
|
164
|
+
return code;
|
165
|
+
} else if (state.localMode) {
|
166
|
+
return state.localMode.token(stream, state.localState);
|
167
|
+
} else {
|
168
|
+
stream.skipToEnd();
|
169
|
+
return code;
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
173
|
+
// Inline
|
174
|
+
function getType(state) {
|
175
|
+
var styles = [];
|
176
|
+
|
177
|
+
if (state.strong) { styles.push(state.em ? emstrong : strong); }
|
178
|
+
else if (state.em) { styles.push(em); }
|
179
|
+
|
180
|
+
if (state.linkText) { styles.push(linktext); }
|
181
|
+
|
182
|
+
if (state.code) { styles.push(code); }
|
183
|
+
|
184
|
+
if (state.header) { styles.push(header); }
|
185
|
+
if (state.quote) { styles.push(quote); }
|
186
|
+
if (state.list !== false) { styles.push(list); }
|
187
|
+
|
188
|
+
return styles.length ? styles.join(' ') : null;
|
189
|
+
}
|
190
|
+
|
191
|
+
function handleText(stream, state) {
|
192
|
+
if (stream.match(textRE, true)) {
|
193
|
+
return getType(state);
|
194
|
+
}
|
195
|
+
return undefined;
|
196
|
+
}
|
197
|
+
|
198
|
+
function inlineNormal(stream, state) {
|
199
|
+
var style = state.text(stream, state);
|
200
|
+
if (typeof style !== 'undefined')
|
201
|
+
return style;
|
202
|
+
|
203
|
+
if (state.list) { // List marker (*, +, -, 1., etc)
|
204
|
+
state.list = null;
|
205
|
+
return list;
|
206
|
+
}
|
207
|
+
|
208
|
+
var ch = stream.next();
|
209
|
+
|
210
|
+
if (ch === '\\') {
|
211
|
+
stream.next();
|
212
|
+
return getType(state);
|
213
|
+
}
|
214
|
+
|
215
|
+
// Matches link titles present on next line
|
216
|
+
if (state.linkTitle) {
|
217
|
+
state.linkTitle = false;
|
218
|
+
var matchCh = ch;
|
219
|
+
if (ch === '(') {
|
220
|
+
matchCh = ')';
|
221
|
+
}
|
222
|
+
matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
|
223
|
+
var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
|
224
|
+
if (stream.match(new RegExp(regex), true)) {
|
225
|
+
return linkhref;
|
226
|
+
}
|
227
|
+
}
|
228
|
+
|
229
|
+
// If this block is changed, it may need to be updated in GFM mode
|
230
|
+
if (ch === '`') {
|
231
|
+
var t = getType(state);
|
232
|
+
var before = stream.pos;
|
233
|
+
stream.eatWhile('`');
|
234
|
+
var difference = 1 + stream.pos - before;
|
235
|
+
if (!state.code) {
|
236
|
+
codeDepth = difference;
|
237
|
+
state.code = true;
|
238
|
+
return getType(state);
|
239
|
+
} else {
|
240
|
+
if (difference === codeDepth) { // Must be exact
|
241
|
+
state.code = false;
|
242
|
+
return t;
|
243
|
+
}
|
244
|
+
return getType(state);
|
245
|
+
}
|
246
|
+
} else if (state.code) {
|
247
|
+
return getType(state);
|
248
|
+
}
|
249
|
+
|
250
|
+
if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
|
251
|
+
stream.match(/\[[^\]]*\]/);
|
252
|
+
state.inline = state.f = linkHref;
|
253
|
+
return image;
|
254
|
+
}
|
255
|
+
|
256
|
+
if (ch === '[' && stream.match(/.*\](\(| ?\[)/, false)) {
|
257
|
+
state.linkText = true;
|
258
|
+
return getType(state);
|
259
|
+
}
|
260
|
+
|
261
|
+
if (ch === ']' && state.linkText) {
|
262
|
+
var type = getType(state);
|
263
|
+
state.linkText = false;
|
264
|
+
state.inline = state.f = linkHref;
|
265
|
+
return type;
|
266
|
+
}
|
267
|
+
|
268
|
+
if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, true)) {
|
269
|
+
return switchInline(stream, state, inlineElement(linkinline, '>'));
|
270
|
+
}
|
271
|
+
|
272
|
+
if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, true)) {
|
273
|
+
return switchInline(stream, state, inlineElement(linkemail, '>'));
|
274
|
+
}
|
275
|
+
|
276
|
+
if (ch === '<' && stream.match(/^\w/, false)) {
|
277
|
+
if (stream.string.indexOf(">")!=-1) {
|
278
|
+
var atts = stream.string.substring(1,stream.string.indexOf(">"));
|
279
|
+
if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) {
|
280
|
+
state.md_inside = true;
|
281
|
+
}
|
282
|
+
}
|
283
|
+
stream.backUp(1);
|
284
|
+
return switchBlock(stream, state, htmlBlock);
|
285
|
+
}
|
286
|
+
|
287
|
+
if (ch === '<' && stream.match(/^\/\w*?>/)) {
|
288
|
+
state.md_inside = false;
|
289
|
+
return "tag";
|
290
|
+
}
|
291
|
+
|
292
|
+
var ignoreUnderscore = false;
|
293
|
+
if (!modeCfg.underscoresBreakWords) {
|
294
|
+
if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
|
295
|
+
var prevPos = stream.pos - 2;
|
296
|
+
if (prevPos >= 0) {
|
297
|
+
var prevCh = stream.string.charAt(prevPos);
|
298
|
+
if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
|
299
|
+
ignoreUnderscore = true;
|
300
|
+
}
|
301
|
+
}
|
302
|
+
}
|
303
|
+
}
|
304
|
+
var t = getType(state);
|
305
|
+
if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
|
306
|
+
if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
|
307
|
+
state.strong = false;
|
308
|
+
return t;
|
309
|
+
} else if (!state.strong && stream.eat(ch)) { // Add STRONG
|
310
|
+
state.strong = ch;
|
311
|
+
return getType(state);
|
312
|
+
} else if (state.em === ch) { // Remove EM
|
313
|
+
state.em = false;
|
314
|
+
return t;
|
315
|
+
} else if (!state.em) { // Add EM
|
316
|
+
state.em = ch;
|
317
|
+
return getType(state);
|
318
|
+
}
|
319
|
+
} else if (ch === ' ') {
|
320
|
+
if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
|
321
|
+
if (stream.peek() === ' ') { // Surrounded by spaces, ignore
|
322
|
+
return getType(state);
|
323
|
+
} else { // Not surrounded by spaces, back up pointer
|
324
|
+
stream.backUp(1);
|
325
|
+
}
|
326
|
+
}
|
327
|
+
}
|
328
|
+
|
329
|
+
return getType(state);
|
330
|
+
}
|
331
|
+
|
332
|
+
function linkHref(stream, state) {
|
333
|
+
// Check if space, and return NULL if so (to avoid marking the space)
|
334
|
+
if(stream.eatSpace()){
|
335
|
+
return null;
|
336
|
+
}
|
337
|
+
var ch = stream.next();
|
338
|
+
if (ch === '(' || ch === '[') {
|
339
|
+
return switchInline(stream, state, inlineElement(linkhref, ch === '(' ? ')' : ']'));
|
340
|
+
}
|
341
|
+
return 'error';
|
342
|
+
}
|
343
|
+
|
344
|
+
function footnoteLink(stream, state) {
|
345
|
+
if (stream.match(/^[^\]]*\]:/, true)) {
|
346
|
+
state.f = footnoteUrl;
|
347
|
+
return linktext;
|
348
|
+
}
|
349
|
+
return switchInline(stream, state, inlineNormal);
|
350
|
+
}
|
351
|
+
|
352
|
+
function footnoteUrl(stream, state) {
|
353
|
+
// Check if space, and return NULL if so (to avoid marking the space)
|
354
|
+
if(stream.eatSpace()){
|
355
|
+
return null;
|
356
|
+
}
|
357
|
+
// Match URL
|
358
|
+
stream.match(/^[^\s]+/, true);
|
359
|
+
// Check for link title
|
360
|
+
if (stream.peek() === undefined) { // End of line, set flag to check next line
|
361
|
+
state.linkTitle = true;
|
362
|
+
} else { // More content on line, check if link title
|
363
|
+
stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
|
364
|
+
}
|
365
|
+
state.f = state.inline = inlineNormal;
|
366
|
+
return linkhref;
|
367
|
+
}
|
368
|
+
|
369
|
+
var savedInlineRE = [];
|
370
|
+
function inlineRE(endChar) {
|
371
|
+
if (!savedInlineRE[endChar]) {
|
372
|
+
// Escape endChar for RegExp (taken from http://stackoverflow.com/a/494122/526741)
|
373
|
+
endChar = (endChar+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
|
374
|
+
// Match any non-endChar, escaped character, as well as the closing
|
375
|
+
// endChar.
|
376
|
+
savedInlineRE[endChar] = new RegExp('^(?:[^\\\\]|\\\\.)*?(' + endChar + ')');
|
377
|
+
}
|
378
|
+
return savedInlineRE[endChar];
|
379
|
+
}
|
380
|
+
|
381
|
+
function inlineElement(type, endChar, next) {
|
382
|
+
next = next || inlineNormal;
|
383
|
+
return function(stream, state) {
|
384
|
+
stream.match(inlineRE(endChar));
|
385
|
+
state.inline = state.f = next;
|
386
|
+
return type;
|
387
|
+
};
|
388
|
+
}
|
389
|
+
|
390
|
+
return {
|
391
|
+
startState: function() {
|
392
|
+
prevLineHasContent = false;
|
393
|
+
thisLineHasContent = false;
|
394
|
+
return {
|
395
|
+
f: blockNormal,
|
396
|
+
|
397
|
+
block: blockNormal,
|
398
|
+
htmlState: CodeMirror.startState(htmlMode),
|
399
|
+
indentation: 0,
|
400
|
+
|
401
|
+
inline: inlineNormal,
|
402
|
+
text: handleText,
|
403
|
+
|
404
|
+
linkText: false,
|
405
|
+
linkTitle: false,
|
406
|
+
em: false,
|
407
|
+
strong: false,
|
408
|
+
header: false,
|
409
|
+
list: false,
|
410
|
+
quote: false
|
411
|
+
};
|
412
|
+
},
|
413
|
+
|
414
|
+
copyState: function(s) {
|
415
|
+
return {
|
416
|
+
f: s.f,
|
417
|
+
|
418
|
+
block: s.block,
|
419
|
+
htmlState: CodeMirror.copyState(htmlMode, s.htmlState),
|
420
|
+
indentation: s.indentation,
|
421
|
+
|
422
|
+
localMode: s.localMode,
|
423
|
+
localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
|
424
|
+
|
425
|
+
inline: s.inline,
|
426
|
+
text: s.text,
|
427
|
+
linkTitle: s.linkTitle,
|
428
|
+
em: s.em,
|
429
|
+
strong: s.strong,
|
430
|
+
header: s.header,
|
431
|
+
list: s.list,
|
432
|
+
quote: s.quote,
|
433
|
+
md_inside: s.md_inside
|
434
|
+
};
|
435
|
+
},
|
436
|
+
|
437
|
+
token: function(stream, state) {
|
438
|
+
if (stream.sol()) {
|
439
|
+
if (stream.match(/^\s*$/, true)) {
|
440
|
+
prevLineHasContent = false;
|
441
|
+
return blankLine(state);
|
442
|
+
} else {
|
443
|
+
if(thisLineHasContent){
|
444
|
+
prevLineHasContent = true;
|
445
|
+
thisLineHasContent = false;
|
446
|
+
}
|
447
|
+
thisLineHasContent = true;
|
448
|
+
}
|
449
|
+
|
450
|
+
// Reset state.header
|
451
|
+
state.header = false;
|
452
|
+
|
453
|
+
// Reset state.code
|
454
|
+
state.code = false;
|
455
|
+
|
456
|
+
state.f = state.block;
|
457
|
+
var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
|
458
|
+
var difference = Math.floor((indentation - state.indentation) / 4) * 4;
|
459
|
+
if (difference > 4) difference = 4;
|
460
|
+
var adjustedIndentation = state.indentation + difference;
|
461
|
+
state.indentationDiff = adjustedIndentation - state.indentation;
|
462
|
+
state.indentation = adjustedIndentation;
|
463
|
+
if (indentation > 0) return null;
|
464
|
+
}
|
465
|
+
return state.f(stream, state);
|
466
|
+
},
|
467
|
+
|
468
|
+
blankLine: blankLine,
|
469
|
+
|
470
|
+
getType: getType
|
471
|
+
};
|
472
|
+
|
473
|
+
}, "xml");
|
474
|
+
|
475
|
+
CodeMirror.defineMIME("text/x-markdown", "markdown");
|