vinsol_spree_themes 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +36 -0
- data/.ruby-version +1 -0
- data/Appraisals +16 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +386 -0
- data/LICENSE +26 -0
- data/README.md +250 -0
- data/Rakefile +21 -0
- data/app/assets/javascripts/spree/backend/codemirror/codemirror.js +9351 -0
- data/app/assets/javascripts/spree/backend/codemirror/css-hint.js +60 -0
- data/app/assets/javascripts/spree/backend/codemirror/fullscreen.js +41 -0
- data/app/assets/javascripts/spree/backend/codemirror/html-hint.js +348 -0
- data/app/assets/javascripts/spree/backend/codemirror/javascript-hint.js +155 -0
- data/app/assets/javascripts/spree/backend/codemirror/javascript.js +813 -0
- data/app/assets/javascripts/spree/backend/codemirror/markdown.js +796 -0
- data/app/assets/javascripts/spree/backend/codemirror/ruby.js +295 -0
- data/app/assets/javascripts/spree/backend/codemirror/show-hint.js +438 -0
- data/app/assets/javascripts/spree/backend/editor.js +11 -0
- data/app/assets/javascripts/spree/backend/jquery.treemenu.js +87 -0
- data/app/assets/javascripts/spree/backend/main.js +26 -0
- data/app/assets/javascripts/spree/backend/spree_themes.js +2 -0
- data/app/assets/javascripts/spree/backend/template.js +51 -0
- data/app/assets/javascripts/spree/backend/theme.js +17 -0
- data/app/assets/javascripts/spree/frontend/spree_themes.js +2 -0
- data/app/assets/stylesheets/spree/backend/codemirror/codemirror.css +340 -0
- data/app/assets/stylesheets/spree/backend/codemirror/fullscreen.css +6 -0
- data/app/assets/stylesheets/spree/backend/codemirror/show-hint.css +36 -0
- data/app/assets/stylesheets/spree/backend/editor.css +7 -0
- data/app/assets/stylesheets/spree/backend/jquery.treemenu.css +8 -0
- data/app/assets/stylesheets/spree/backend/spree_themes.css +7 -0
- data/app/assets/stylesheets/spree/backend/style.css +239 -0
- data/app/assets/stylesheets/spree/backend/template_editor.css +39 -0
- data/app/assets/stylesheets/spree/frontend/spree_themes.css +6 -0
- data/app/assets/stylesheets/spree/frontend/theme_preview.css +9 -0
- data/app/controllers/spree/admin/themes_controller.rb +80 -0
- data/app/controllers/spree/admin/themes_preview_controller.rb +30 -0
- data/app/controllers/spree/admin/themes_templates_controller.rb +60 -0
- data/app/controllers/spree/fragment_cache_controller.rb +13 -0
- data/app/controllers/spree/store_controller_decorator.rb +37 -0
- data/app/helpers/spree/base_helper_decorator.rb +45 -0
- data/app/models/spree/theme.rb +153 -0
- data/app/models/spree/themes_template.rb +67 -0
- data/app/models/spree/themes_template/cache_resolver.rb +37 -0
- data/app/overrides/spree/add_preview_bar_to_store.html.rb +6 -0
- data/app/overrides/spree/add_theme_meta_details_to_store.html.rb +6 -0
- data/app/overrides/spree/admin/add_themes_tab.html.rb +6 -0
- data/app/services/assets_precompiler_service.rb +86 -0
- data/app/services/file_generator_service.rb +29 -0
- data/app/services/template_generator_service.rb +101 -0
- data/app/services/zip_file_builder.rb +87 -0
- data/app/services/zip_file_extractor.rb +52 -0
- data/app/views/spree/admin/shared/_theme_menu_button.html.erb +5 -0
- data/app/views/spree/admin/themes/_themes.html.erb +44 -0
- data/app/views/spree/admin/themes/_upload.html.erb +17 -0
- data/app/views/spree/admin/themes/index.html.erb +50 -0
- data/app/views/spree/admin/themes_templates/_editor.html.erb +29 -0
- data/app/views/spree/admin/themes_templates/_template.html.erb +12 -0
- data/app/views/spree/admin/themes_templates/edit.html.erb +13 -0
- data/app/views/spree/admin/themes_templates/edit.js.erb +1 -0
- data/app/views/spree/admin/themes_templates/index.html.erb +27 -0
- data/app/views/spree/admin/themes_templates/new.html.erb +56 -0
- data/app/views/spree/shared/_preview_bar.html.erb +7 -0
- data/app/views/spree/shared/_theme_metadata.html.erb +9 -0
- data/bin/rails +7 -0
- data/config/initializers/assets.rb +24 -0
- data/config/initializers/sprockets.rb +85 -0
- data/config/locales/en.yml +52 -0
- data/config/routes.rb +22 -0
- data/db/migrate/20170628072452_vinsol_spree_themes_create_themes_and_themes_templates_table.rb +24 -0
- data/gemfiles/spree_3_1.gemfile +8 -0
- data/gemfiles/spree_3_2.gemfile +9 -0
- data/gemfiles/spree_master.gemfile +9 -0
- data/lib/generators/themes/default.zip +0 -0
- data/lib/generators/vinsol_spree_themes/install/install_generator.rb +50 -0
- data/lib/tasks/sync_templates.rake +47 -0
- data/lib/vinsol_spree_themes.rb +3 -0
- data/lib/vinsol_spree_themes/engine.rb +22 -0
- data/lib/vinsol_spree_themes/factories.rb +6 -0
- data/lib/vinsol_spree_themes/version.rb +18 -0
- data/spec/spec_helper.rb +93 -0
- data/vinsol_spree_themes.gemspec +43 -0
- metadata +374 -0
@@ -0,0 +1,796 @@
|
|
1
|
+
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
2
|
+
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
3
|
+
|
4
|
+
(function(mod) {
|
5
|
+
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
6
|
+
mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta"));
|
7
|
+
else if (typeof define == "function" && define.amd) // AMD
|
8
|
+
define(["../../lib/codemirror", "../xml/xml", "../meta"], mod);
|
9
|
+
else // Plain browser env
|
10
|
+
mod(CodeMirror);
|
11
|
+
})(function(CodeMirror) {
|
12
|
+
"use strict";
|
13
|
+
|
14
|
+
CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
|
15
|
+
|
16
|
+
var htmlMode = CodeMirror.getMode(cmCfg, "text/html");
|
17
|
+
var htmlModeMissing = htmlMode.name == "null"
|
18
|
+
|
19
|
+
function getMode(name) {
|
20
|
+
if (CodeMirror.findModeByName) {
|
21
|
+
var found = CodeMirror.findModeByName(name);
|
22
|
+
if (found) name = found.mime || found.mimes[0];
|
23
|
+
}
|
24
|
+
var mode = CodeMirror.getMode(cmCfg, name);
|
25
|
+
return mode.name == "null" ? null : mode;
|
26
|
+
}
|
27
|
+
|
28
|
+
// Should characters that affect highlighting be highlighted separate?
|
29
|
+
// Does not include characters that will be output (such as `1.` and `-` for lists)
|
30
|
+
if (modeCfg.highlightFormatting === undefined)
|
31
|
+
modeCfg.highlightFormatting = false;
|
32
|
+
|
33
|
+
// Maximum number of nested blockquotes. Set to 0 for infinite nesting.
|
34
|
+
// Excess `>` will emit `error` token.
|
35
|
+
if (modeCfg.maxBlockquoteDepth === undefined)
|
36
|
+
modeCfg.maxBlockquoteDepth = 0;
|
37
|
+
|
38
|
+
// Use `fencedCodeBlocks` to configure fenced code blocks. false to
|
39
|
+
// disable, string to specify a precise regexp that the fence should
|
40
|
+
// match, and true to allow three or more backticks or tildes (as
|
41
|
+
// per CommonMark).
|
42
|
+
|
43
|
+
// Turn on task lists? ("- [ ] " and "- [x] ")
|
44
|
+
if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
|
45
|
+
|
46
|
+
// Turn on strikethrough syntax
|
47
|
+
if (modeCfg.strikethrough === undefined)
|
48
|
+
modeCfg.strikethrough = false;
|
49
|
+
|
50
|
+
// Allow token types to be overridden by user-provided token types.
|
51
|
+
if (modeCfg.tokenTypeOverrides === undefined)
|
52
|
+
modeCfg.tokenTypeOverrides = {};
|
53
|
+
|
54
|
+
var tokenTypes = {
|
55
|
+
header: "header",
|
56
|
+
code: "comment",
|
57
|
+
quote: "quote",
|
58
|
+
list1: "variable-2",
|
59
|
+
list2: "variable-3",
|
60
|
+
list3: "keyword",
|
61
|
+
hr: "hr",
|
62
|
+
image: "image",
|
63
|
+
imageAltText: "image-alt-text",
|
64
|
+
imageMarker: "image-marker",
|
65
|
+
formatting: "formatting",
|
66
|
+
linkInline: "link",
|
67
|
+
linkEmail: "link",
|
68
|
+
linkText: "link",
|
69
|
+
linkHref: "string",
|
70
|
+
em: "em",
|
71
|
+
strong: "strong",
|
72
|
+
strikethrough: "strikethrough"
|
73
|
+
};
|
74
|
+
|
75
|
+
for (var tokenType in tokenTypes) {
|
76
|
+
if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) {
|
77
|
+
tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType];
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
|
82
|
+
, listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/
|
83
|
+
, taskListRE = /^\[(x| )\](?=\s)/ // Must follow listRE
|
84
|
+
, atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
|
85
|
+
, setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
|
86
|
+
, textRE = /^[^#!\[\]*_\\<>` "'(~]+/
|
87
|
+
, fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) +
|
88
|
+
")[ \\t]*([\\w+#\-]*)")
|
89
|
+
, punctuation = /[!\"#$%&\'()*+,\-\.\/:;<=>?@\[\\\]^_`{|}~—]/
|
90
|
+
|
91
|
+
function switchInline(stream, state, f) {
|
92
|
+
state.f = state.inline = f;
|
93
|
+
return f(stream, state);
|
94
|
+
}
|
95
|
+
|
96
|
+
function switchBlock(stream, state, f) {
|
97
|
+
state.f = state.block = f;
|
98
|
+
return f(stream, state);
|
99
|
+
}
|
100
|
+
|
101
|
+
function lineIsEmpty(line) {
|
102
|
+
return !line || !/\S/.test(line.string)
|
103
|
+
}
|
104
|
+
|
105
|
+
// Blocks
|
106
|
+
|
107
|
+
function blankLine(state) {
|
108
|
+
// Reset linkTitle state
|
109
|
+
state.linkTitle = false;
|
110
|
+
// Reset EM state
|
111
|
+
state.em = false;
|
112
|
+
// Reset STRONG state
|
113
|
+
state.strong = false;
|
114
|
+
// Reset strikethrough state
|
115
|
+
state.strikethrough = false;
|
116
|
+
// Reset state.quote
|
117
|
+
state.quote = 0;
|
118
|
+
// Reset state.indentedCode
|
119
|
+
state.indentedCode = false;
|
120
|
+
if (state.f == htmlBlock) {
|
121
|
+
state.f = inlineNormal;
|
122
|
+
state.block = blockNormal;
|
123
|
+
}
|
124
|
+
// Reset state.trailingSpace
|
125
|
+
state.trailingSpace = 0;
|
126
|
+
state.trailingSpaceNewLine = false;
|
127
|
+
// Mark this line as blank
|
128
|
+
state.prevLine = state.thisLine
|
129
|
+
state.thisLine = null
|
130
|
+
return null;
|
131
|
+
}
|
132
|
+
|
133
|
+
function blockNormal(stream, state) {
|
134
|
+
|
135
|
+
var sol = stream.sol();
|
136
|
+
|
137
|
+
var prevLineIsList = state.list !== false,
|
138
|
+
prevLineIsIndentedCode = state.indentedCode;
|
139
|
+
|
140
|
+
state.indentedCode = false;
|
141
|
+
|
142
|
+
if (prevLineIsList) {
|
143
|
+
if (state.indentationDiff >= 0) { // Continued list
|
144
|
+
if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
|
145
|
+
state.indentation -= state.indentationDiff;
|
146
|
+
}
|
147
|
+
state.list = null;
|
148
|
+
} else if (state.indentation > 0) {
|
149
|
+
state.list = null;
|
150
|
+
} else { // No longer a list
|
151
|
+
state.list = false;
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
var match = null;
|
156
|
+
if (state.indentationDiff >= 4) {
|
157
|
+
stream.skipToEnd();
|
158
|
+
if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) {
|
159
|
+
state.indentation -= 4;
|
160
|
+
state.indentedCode = true;
|
161
|
+
return tokenTypes.code;
|
162
|
+
} else {
|
163
|
+
return null;
|
164
|
+
}
|
165
|
+
} else if (stream.eatSpace()) {
|
166
|
+
return null;
|
167
|
+
} else if ((match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
|
168
|
+
state.header = match[1].length;
|
169
|
+
if (modeCfg.highlightFormatting) state.formatting = "header";
|
170
|
+
state.f = state.inline;
|
171
|
+
return getType(state);
|
172
|
+
} else if (!lineIsEmpty(state.prevLine) && !state.quote && !prevLineIsList &&
|
173
|
+
!prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) {
|
174
|
+
state.header = match[0].charAt(0) == '=' ? 1 : 2;
|
175
|
+
if (modeCfg.highlightFormatting) state.formatting = "header";
|
176
|
+
state.f = state.inline;
|
177
|
+
return getType(state);
|
178
|
+
} else if (stream.eat('>')) {
|
179
|
+
state.quote = sol ? 1 : state.quote + 1;
|
180
|
+
if (modeCfg.highlightFormatting) state.formatting = "quote";
|
181
|
+
stream.eatSpace();
|
182
|
+
return getType(state);
|
183
|
+
} else if (stream.peek() === '[') {
|
184
|
+
return switchInline(stream, state, footnoteLink);
|
185
|
+
} else if (stream.match(hrRE, true)) {
|
186
|
+
state.hr = true;
|
187
|
+
return tokenTypes.hr;
|
188
|
+
} else if (match = stream.match(listRE)) {
|
189
|
+
var listType = match[1] ? "ol" : "ul";
|
190
|
+
state.indentation = stream.column() + stream.current().length;
|
191
|
+
state.list = true;
|
192
|
+
|
193
|
+
// While this list item's marker's indentation
|
194
|
+
// is less than the deepest list item's content's indentation,
|
195
|
+
// pop the deepest list item indentation off the stack.
|
196
|
+
while (state.listStack && stream.column() < state.listStack[state.listStack.length - 1]) {
|
197
|
+
state.listStack.pop();
|
198
|
+
}
|
199
|
+
|
200
|
+
// Add this list item's content's indentation to the stack
|
201
|
+
state.listStack.push(state.indentation);
|
202
|
+
|
203
|
+
if (modeCfg.taskLists && stream.match(taskListRE, false)) {
|
204
|
+
state.taskList = true;
|
205
|
+
}
|
206
|
+
state.f = state.inline;
|
207
|
+
if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
|
208
|
+
return getType(state);
|
209
|
+
} else if (modeCfg.fencedCodeBlocks && (match = stream.match(fencedCodeRE, true))) {
|
210
|
+
state.fencedChars = match[1]
|
211
|
+
// try switching mode
|
212
|
+
state.localMode = getMode(match[2]);
|
213
|
+
if (state.localMode) state.localState = CodeMirror.startState(state.localMode);
|
214
|
+
state.f = state.block = local;
|
215
|
+
if (modeCfg.highlightFormatting) state.formatting = "code-block";
|
216
|
+
state.code = -1
|
217
|
+
return getType(state);
|
218
|
+
}
|
219
|
+
|
220
|
+
return switchInline(stream, state, state.inline);
|
221
|
+
}
|
222
|
+
|
223
|
+
function htmlBlock(stream, state) {
|
224
|
+
var style = htmlMode.token(stream, state.htmlState);
|
225
|
+
if (!htmlModeMissing) {
|
226
|
+
var inner = CodeMirror.innerMode(htmlMode, state.htmlState)
|
227
|
+
if ((inner.mode.name == "xml" && inner.state.tagStart === null &&
|
228
|
+
(!inner.state.context && inner.state.tokenize.isInText)) ||
|
229
|
+
(state.md_inside && stream.current().indexOf(">") > -1)) {
|
230
|
+
state.f = inlineNormal;
|
231
|
+
state.block = blockNormal;
|
232
|
+
state.htmlState = null;
|
233
|
+
}
|
234
|
+
}
|
235
|
+
return style;
|
236
|
+
}
|
237
|
+
|
238
|
+
function local(stream, state) {
|
239
|
+
if (state.fencedChars && stream.match(state.fencedChars)) {
|
240
|
+
if (modeCfg.highlightFormatting) state.formatting = "code-block";
|
241
|
+
var returnType = getType(state)
|
242
|
+
state.localMode = state.localState = null;
|
243
|
+
state.block = blockNormal;
|
244
|
+
state.f = inlineNormal;
|
245
|
+
state.fencedChars = null;
|
246
|
+
state.code = 0
|
247
|
+
return returnType;
|
248
|
+
} else if (state.fencedChars && stream.skipTo(state.fencedChars)) {
|
249
|
+
return "comment"
|
250
|
+
} else if (state.localMode) {
|
251
|
+
return state.localMode.token(stream, state.localState);
|
252
|
+
} else {
|
253
|
+
stream.skipToEnd();
|
254
|
+
return tokenTypes.code;
|
255
|
+
}
|
256
|
+
}
|
257
|
+
|
258
|
+
// Inline
|
259
|
+
function getType(state) {
|
260
|
+
var styles = [];
|
261
|
+
|
262
|
+
if (state.formatting) {
|
263
|
+
styles.push(tokenTypes.formatting);
|
264
|
+
|
265
|
+
if (typeof state.formatting === "string") state.formatting = [state.formatting];
|
266
|
+
|
267
|
+
for (var i = 0; i < state.formatting.length; i++) {
|
268
|
+
styles.push(tokenTypes.formatting + "-" + state.formatting[i]);
|
269
|
+
|
270
|
+
if (state.formatting[i] === "header") {
|
271
|
+
styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header);
|
272
|
+
}
|
273
|
+
|
274
|
+
// Add `formatting-quote` and `formatting-quote-#` for blockquotes
|
275
|
+
// Add `error` instead if the maximum blockquote nesting depth is passed
|
276
|
+
if (state.formatting[i] === "quote") {
|
277
|
+
if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
|
278
|
+
styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote);
|
279
|
+
} else {
|
280
|
+
styles.push("error");
|
281
|
+
}
|
282
|
+
}
|
283
|
+
}
|
284
|
+
}
|
285
|
+
|
286
|
+
if (state.taskOpen) {
|
287
|
+
styles.push("meta");
|
288
|
+
return styles.length ? styles.join(' ') : null;
|
289
|
+
}
|
290
|
+
if (state.taskClosed) {
|
291
|
+
styles.push("property");
|
292
|
+
return styles.length ? styles.join(' ') : null;
|
293
|
+
}
|
294
|
+
|
295
|
+
if (state.linkHref) {
|
296
|
+
styles.push(tokenTypes.linkHref, "url");
|
297
|
+
} else { // Only apply inline styles to non-url text
|
298
|
+
if (state.strong) { styles.push(tokenTypes.strong); }
|
299
|
+
if (state.em) { styles.push(tokenTypes.em); }
|
300
|
+
if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
|
301
|
+
if (state.linkText) { styles.push(tokenTypes.linkText); }
|
302
|
+
if (state.code) { styles.push(tokenTypes.code); }
|
303
|
+
if (state.image) { styles.push(tokenTypes.image); }
|
304
|
+
if (state.imageAltText) { styles.push(tokenTypes.imageAltText, "link"); }
|
305
|
+
if (state.imageMarker) { styles.push(tokenTypes.imageMarker); }
|
306
|
+
}
|
307
|
+
|
308
|
+
if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); }
|
309
|
+
|
310
|
+
if (state.quote) {
|
311
|
+
styles.push(tokenTypes.quote);
|
312
|
+
|
313
|
+
// Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
|
314
|
+
if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
|
315
|
+
styles.push(tokenTypes.quote + "-" + state.quote);
|
316
|
+
} else {
|
317
|
+
styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth);
|
318
|
+
}
|
319
|
+
}
|
320
|
+
|
321
|
+
if (state.list !== false) {
|
322
|
+
var listMod = (state.listStack.length - 1) % 3;
|
323
|
+
if (!listMod) {
|
324
|
+
styles.push(tokenTypes.list1);
|
325
|
+
} else if (listMod === 1) {
|
326
|
+
styles.push(tokenTypes.list2);
|
327
|
+
} else {
|
328
|
+
styles.push(tokenTypes.list3);
|
329
|
+
}
|
330
|
+
}
|
331
|
+
|
332
|
+
if (state.trailingSpaceNewLine) {
|
333
|
+
styles.push("trailing-space-new-line");
|
334
|
+
} else if (state.trailingSpace) {
|
335
|
+
styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
|
336
|
+
}
|
337
|
+
|
338
|
+
return styles.length ? styles.join(' ') : null;
|
339
|
+
}
|
340
|
+
|
341
|
+
function handleText(stream, state) {
|
342
|
+
if (stream.match(textRE, true)) {
|
343
|
+
return getType(state);
|
344
|
+
}
|
345
|
+
return undefined;
|
346
|
+
}
|
347
|
+
|
348
|
+
function inlineNormal(stream, state) {
|
349
|
+
var style = state.text(stream, state);
|
350
|
+
if (typeof style !== 'undefined')
|
351
|
+
return style;
|
352
|
+
|
353
|
+
if (state.list) { // List marker (*, +, -, 1., etc)
|
354
|
+
state.list = null;
|
355
|
+
return getType(state);
|
356
|
+
}
|
357
|
+
|
358
|
+
if (state.taskList) {
|
359
|
+
var taskOpen = stream.match(taskListRE, true)[1] !== "x";
|
360
|
+
if (taskOpen) state.taskOpen = true;
|
361
|
+
else state.taskClosed = true;
|
362
|
+
if (modeCfg.highlightFormatting) state.formatting = "task";
|
363
|
+
state.taskList = false;
|
364
|
+
return getType(state);
|
365
|
+
}
|
366
|
+
|
367
|
+
state.taskOpen = false;
|
368
|
+
state.taskClosed = false;
|
369
|
+
|
370
|
+
if (state.header && stream.match(/^#+$/, true)) {
|
371
|
+
if (modeCfg.highlightFormatting) state.formatting = "header";
|
372
|
+
return getType(state);
|
373
|
+
}
|
374
|
+
|
375
|
+
var ch = stream.next();
|
376
|
+
|
377
|
+
// Matches link titles present on next line
|
378
|
+
if (state.linkTitle) {
|
379
|
+
state.linkTitle = false;
|
380
|
+
var matchCh = ch;
|
381
|
+
if (ch === '(') {
|
382
|
+
matchCh = ')';
|
383
|
+
}
|
384
|
+
matchCh = (matchCh+'').replace(/([.?*+^\[\]\\(){}|-])/g, "\\$1");
|
385
|
+
var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
|
386
|
+
if (stream.match(new RegExp(regex), true)) {
|
387
|
+
return tokenTypes.linkHref;
|
388
|
+
}
|
389
|
+
}
|
390
|
+
|
391
|
+
// If this block is changed, it may need to be updated in GFM mode
|
392
|
+
if (ch === '`') {
|
393
|
+
var previousFormatting = state.formatting;
|
394
|
+
if (modeCfg.highlightFormatting) state.formatting = "code";
|
395
|
+
stream.eatWhile('`');
|
396
|
+
var count = stream.current().length
|
397
|
+
if (state.code == 0) {
|
398
|
+
state.code = count
|
399
|
+
return getType(state)
|
400
|
+
} else if (count == state.code) { // Must be exact
|
401
|
+
var t = getType(state)
|
402
|
+
state.code = 0
|
403
|
+
return t
|
404
|
+
} else {
|
405
|
+
state.formatting = previousFormatting
|
406
|
+
return getType(state)
|
407
|
+
}
|
408
|
+
} else if (state.code) {
|
409
|
+
return getType(state);
|
410
|
+
}
|
411
|
+
|
412
|
+
if (ch === '\\') {
|
413
|
+
stream.next();
|
414
|
+
if (modeCfg.highlightFormatting) {
|
415
|
+
var type = getType(state);
|
416
|
+
var formattingEscape = tokenTypes.formatting + "-escape";
|
417
|
+
return type ? type + " " + formattingEscape : formattingEscape;
|
418
|
+
}
|
419
|
+
}
|
420
|
+
|
421
|
+
if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
|
422
|
+
state.imageMarker = true;
|
423
|
+
state.image = true;
|
424
|
+
if (modeCfg.highlightFormatting) state.formatting = "image";
|
425
|
+
return getType(state);
|
426
|
+
}
|
427
|
+
|
428
|
+
if (ch === '[' && state.imageMarker && stream.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/, false)) {
|
429
|
+
state.imageMarker = false;
|
430
|
+
state.imageAltText = true
|
431
|
+
if (modeCfg.highlightFormatting) state.formatting = "image";
|
432
|
+
return getType(state);
|
433
|
+
}
|
434
|
+
|
435
|
+
if (ch === ']' && state.imageAltText) {
|
436
|
+
if (modeCfg.highlightFormatting) state.formatting = "image";
|
437
|
+
var type = getType(state);
|
438
|
+
state.imageAltText = false;
|
439
|
+
state.image = false;
|
440
|
+
state.inline = state.f = linkHref;
|
441
|
+
return type;
|
442
|
+
}
|
443
|
+
|
444
|
+
if (ch === '[' && !state.image) {
|
445
|
+
state.linkText = true;
|
446
|
+
if (modeCfg.highlightFormatting) state.formatting = "link";
|
447
|
+
return getType(state);
|
448
|
+
}
|
449
|
+
|
450
|
+
if (ch === ']' && state.linkText) {
|
451
|
+
if (modeCfg.highlightFormatting) state.formatting = "link";
|
452
|
+
var type = getType(state);
|
453
|
+
state.linkText = false;
|
454
|
+
state.inline = state.f = stream.match(/\(.*?\)| ?\[.*?\]/, false) ? linkHref : inlineNormal
|
455
|
+
return type;
|
456
|
+
}
|
457
|
+
|
458
|
+
if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
|
459
|
+
state.f = state.inline = linkInline;
|
460
|
+
if (modeCfg.highlightFormatting) state.formatting = "link";
|
461
|
+
var type = getType(state);
|
462
|
+
if (type){
|
463
|
+
type += " ";
|
464
|
+
} else {
|
465
|
+
type = "";
|
466
|
+
}
|
467
|
+
return type + tokenTypes.linkInline;
|
468
|
+
}
|
469
|
+
|
470
|
+
if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
|
471
|
+
state.f = state.inline = linkInline;
|
472
|
+
if (modeCfg.highlightFormatting) state.formatting = "link";
|
473
|
+
var type = getType(state);
|
474
|
+
if (type){
|
475
|
+
type += " ";
|
476
|
+
} else {
|
477
|
+
type = "";
|
478
|
+
}
|
479
|
+
return type + tokenTypes.linkEmail;
|
480
|
+
}
|
481
|
+
|
482
|
+
if (ch === '<' && stream.match(/^(!--|[a-z]+(?:\s+[a-z_:.\-]+(?:\s*=\s*[^ >]+)?)*\s*>)/i, false)) {
|
483
|
+
var end = stream.string.indexOf(">", stream.pos);
|
484
|
+
if (end != -1) {
|
485
|
+
var atts = stream.string.substring(stream.start, end);
|
486
|
+
if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true;
|
487
|
+
}
|
488
|
+
stream.backUp(1);
|
489
|
+
state.htmlState = CodeMirror.startState(htmlMode);
|
490
|
+
return switchBlock(stream, state, htmlBlock);
|
491
|
+
}
|
492
|
+
|
493
|
+
if (ch === '<' && stream.match(/^\/\w*?>/)) {
|
494
|
+
state.md_inside = false;
|
495
|
+
return "tag";
|
496
|
+
} else if (ch === "*" || ch === "_") {
|
497
|
+
var len = 1, before = stream.pos == 1 ? " " : stream.string.charAt(stream.pos - 2)
|
498
|
+
while (len < 3 && stream.eat(ch)) len++
|
499
|
+
var after = stream.peek() || " "
|
500
|
+
// See http://spec.commonmark.org/0.27/#emphasis-and-strong-emphasis
|
501
|
+
var leftFlanking = !/\s/.test(after) && (!punctuation.test(after) || /\s/.test(before) || punctuation.test(before))
|
502
|
+
var rightFlanking = !/\s/.test(before) && (!punctuation.test(before) || /\s/.test(after) || punctuation.test(after))
|
503
|
+
var setEm = null, setStrong = null
|
504
|
+
if (len % 2) { // Em
|
505
|
+
if (!state.em && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before)))
|
506
|
+
setEm = true
|
507
|
+
else if (state.em == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after)))
|
508
|
+
setEm = false
|
509
|
+
}
|
510
|
+
if (len > 1) { // Strong
|
511
|
+
if (!state.strong && leftFlanking && (ch === "*" || !rightFlanking || punctuation.test(before)))
|
512
|
+
setStrong = true
|
513
|
+
else if (state.strong == ch && rightFlanking && (ch === "*" || !leftFlanking || punctuation.test(after)))
|
514
|
+
setStrong = false
|
515
|
+
}
|
516
|
+
if (setStrong != null || setEm != null) {
|
517
|
+
if (modeCfg.highlightFormatting) state.formatting = setEm == null ? "strong" : setStrong == null ? "em" : "strong em"
|
518
|
+
if (setEm === true) state.em = ch
|
519
|
+
if (setStrong === true) state.strong = ch
|
520
|
+
var t = getType(state)
|
521
|
+
if (setEm === false) state.em = false
|
522
|
+
if (setStrong === false) state.strong = false
|
523
|
+
return t
|
524
|
+
}
|
525
|
+
} else if (ch === ' ') {
|
526
|
+
if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
|
527
|
+
if (stream.peek() === ' ') { // Surrounded by spaces, ignore
|
528
|
+
return getType(state);
|
529
|
+
} else { // Not surrounded by spaces, back up pointer
|
530
|
+
stream.backUp(1);
|
531
|
+
}
|
532
|
+
}
|
533
|
+
}
|
534
|
+
|
535
|
+
if (modeCfg.strikethrough) {
|
536
|
+
if (ch === '~' && stream.eatWhile(ch)) {
|
537
|
+
if (state.strikethrough) {// Remove strikethrough
|
538
|
+
if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
|
539
|
+
var t = getType(state);
|
540
|
+
state.strikethrough = false;
|
541
|
+
return t;
|
542
|
+
} else if (stream.match(/^[^\s]/, false)) {// Add strikethrough
|
543
|
+
state.strikethrough = true;
|
544
|
+
if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
|
545
|
+
return getType(state);
|
546
|
+
}
|
547
|
+
} else if (ch === ' ') {
|
548
|
+
if (stream.match(/^~~/, true)) { // Probably surrounded by space
|
549
|
+
if (stream.peek() === ' ') { // Surrounded by spaces, ignore
|
550
|
+
return getType(state);
|
551
|
+
} else { // Not surrounded by spaces, back up pointer
|
552
|
+
stream.backUp(2);
|
553
|
+
}
|
554
|
+
}
|
555
|
+
}
|
556
|
+
}
|
557
|
+
|
558
|
+
if (ch === ' ') {
|
559
|
+
if (stream.match(/ +$/, false)) {
|
560
|
+
state.trailingSpace++;
|
561
|
+
} else if (state.trailingSpace) {
|
562
|
+
state.trailingSpaceNewLine = true;
|
563
|
+
}
|
564
|
+
}
|
565
|
+
|
566
|
+
return getType(state);
|
567
|
+
}
|
568
|
+
|
569
|
+
function linkInline(stream, state) {
|
570
|
+
var ch = stream.next();
|
571
|
+
|
572
|
+
if (ch === ">") {
|
573
|
+
state.f = state.inline = inlineNormal;
|
574
|
+
if (modeCfg.highlightFormatting) state.formatting = "link";
|
575
|
+
var type = getType(state);
|
576
|
+
if (type){
|
577
|
+
type += " ";
|
578
|
+
} else {
|
579
|
+
type = "";
|
580
|
+
}
|
581
|
+
return type + tokenTypes.linkInline;
|
582
|
+
}
|
583
|
+
|
584
|
+
stream.match(/^[^>]+/, true);
|
585
|
+
|
586
|
+
return tokenTypes.linkInline;
|
587
|
+
}
|
588
|
+
|
589
|
+
function linkHref(stream, state) {
|
590
|
+
// Check if space, and return NULL if so (to avoid marking the space)
|
591
|
+
if(stream.eatSpace()){
|
592
|
+
return null;
|
593
|
+
}
|
594
|
+
var ch = stream.next();
|
595
|
+
if (ch === '(' || ch === '[') {
|
596
|
+
state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
|
597
|
+
if (modeCfg.highlightFormatting) state.formatting = "link-string";
|
598
|
+
state.linkHref = true;
|
599
|
+
return getType(state);
|
600
|
+
}
|
601
|
+
return 'error';
|
602
|
+
}
|
603
|
+
|
604
|
+
var linkRE = {
|
605
|
+
")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,
|
606
|
+
"]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\]]|\\.)*\])*?(?=\])/
|
607
|
+
}
|
608
|
+
|
609
|
+
function getLinkHrefInside(endChar) {
|
610
|
+
return function(stream, state) {
|
611
|
+
var ch = stream.next();
|
612
|
+
|
613
|
+
if (ch === endChar) {
|
614
|
+
state.f = state.inline = inlineNormal;
|
615
|
+
if (modeCfg.highlightFormatting) state.formatting = "link-string";
|
616
|
+
var returnState = getType(state);
|
617
|
+
state.linkHref = false;
|
618
|
+
return returnState;
|
619
|
+
}
|
620
|
+
|
621
|
+
stream.match(linkRE[endChar])
|
622
|
+
state.linkHref = true;
|
623
|
+
return getType(state);
|
624
|
+
};
|
625
|
+
}
|
626
|
+
|
627
|
+
function footnoteLink(stream, state) {
|
628
|
+
if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) {
|
629
|
+
state.f = footnoteLinkInside;
|
630
|
+
stream.next(); // Consume [
|
631
|
+
if (modeCfg.highlightFormatting) state.formatting = "link";
|
632
|
+
state.linkText = true;
|
633
|
+
return getType(state);
|
634
|
+
}
|
635
|
+
return switchInline(stream, state, inlineNormal);
|
636
|
+
}
|
637
|
+
|
638
|
+
function footnoteLinkInside(stream, state) {
|
639
|
+
if (stream.match(/^\]:/, true)) {
|
640
|
+
state.f = state.inline = footnoteUrl;
|
641
|
+
if (modeCfg.highlightFormatting) state.formatting = "link";
|
642
|
+
var returnType = getType(state);
|
643
|
+
state.linkText = false;
|
644
|
+
return returnType;
|
645
|
+
}
|
646
|
+
|
647
|
+
stream.match(/^([^\]\\]|\\.)+/, true);
|
648
|
+
|
649
|
+
return tokenTypes.linkText;
|
650
|
+
}
|
651
|
+
|
652
|
+
function footnoteUrl(stream, state) {
|
653
|
+
// Check if space, and return NULL if so (to avoid marking the space)
|
654
|
+
if(stream.eatSpace()){
|
655
|
+
return null;
|
656
|
+
}
|
657
|
+
// Match URL
|
658
|
+
stream.match(/^[^\s]+/, true);
|
659
|
+
// Check for link title
|
660
|
+
if (stream.peek() === undefined) { // End of line, set flag to check next line
|
661
|
+
state.linkTitle = true;
|
662
|
+
} else { // More content on line, check if link title
|
663
|
+
stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
|
664
|
+
}
|
665
|
+
state.f = state.inline = inlineNormal;
|
666
|
+
return tokenTypes.linkHref + " url";
|
667
|
+
}
|
668
|
+
|
669
|
+
var mode = {
|
670
|
+
startState: function() {
|
671
|
+
return {
|
672
|
+
f: blockNormal,
|
673
|
+
|
674
|
+
prevLine: null,
|
675
|
+
thisLine: null,
|
676
|
+
|
677
|
+
block: blockNormal,
|
678
|
+
htmlState: null,
|
679
|
+
indentation: 0,
|
680
|
+
|
681
|
+
inline: inlineNormal,
|
682
|
+
text: handleText,
|
683
|
+
|
684
|
+
formatting: false,
|
685
|
+
linkText: false,
|
686
|
+
linkHref: false,
|
687
|
+
linkTitle: false,
|
688
|
+
code: 0,
|
689
|
+
em: false,
|
690
|
+
strong: false,
|
691
|
+
header: 0,
|
692
|
+
hr: false,
|
693
|
+
taskList: false,
|
694
|
+
list: false,
|
695
|
+
listStack: [],
|
696
|
+
quote: 0,
|
697
|
+
trailingSpace: 0,
|
698
|
+
trailingSpaceNewLine: false,
|
699
|
+
strikethrough: false,
|
700
|
+
fencedChars: null
|
701
|
+
};
|
702
|
+
},
|
703
|
+
|
704
|
+
copyState: function(s) {
|
705
|
+
return {
|
706
|
+
f: s.f,
|
707
|
+
|
708
|
+
prevLine: s.prevLine,
|
709
|
+
thisLine: s.thisLine,
|
710
|
+
|
711
|
+
block: s.block,
|
712
|
+
htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
|
713
|
+
indentation: s.indentation,
|
714
|
+
|
715
|
+
localMode: s.localMode,
|
716
|
+
localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
|
717
|
+
|
718
|
+
inline: s.inline,
|
719
|
+
text: s.text,
|
720
|
+
formatting: false,
|
721
|
+
linkText: s.linkText,
|
722
|
+
linkTitle: s.linkTitle,
|
723
|
+
code: s.code,
|
724
|
+
em: s.em,
|
725
|
+
strong: s.strong,
|
726
|
+
strikethrough: s.strikethrough,
|
727
|
+
header: s.header,
|
728
|
+
hr: s.hr,
|
729
|
+
taskList: s.taskList,
|
730
|
+
list: s.list,
|
731
|
+
listStack: s.listStack.slice(0),
|
732
|
+
quote: s.quote,
|
733
|
+
indentedCode: s.indentedCode,
|
734
|
+
trailingSpace: s.trailingSpace,
|
735
|
+
trailingSpaceNewLine: s.trailingSpaceNewLine,
|
736
|
+
md_inside: s.md_inside,
|
737
|
+
fencedChars: s.fencedChars
|
738
|
+
};
|
739
|
+
},
|
740
|
+
|
741
|
+
token: function(stream, state) {
|
742
|
+
|
743
|
+
// Reset state.formatting
|
744
|
+
state.formatting = false;
|
745
|
+
|
746
|
+
if (stream != state.thisLine) {
|
747
|
+
var forceBlankLine = state.header || state.hr;
|
748
|
+
|
749
|
+
// Reset state.header and state.hr
|
750
|
+
state.header = 0;
|
751
|
+
state.hr = false;
|
752
|
+
|
753
|
+
if (stream.match(/^\s*$/, true) || forceBlankLine) {
|
754
|
+
blankLine(state);
|
755
|
+
if (!forceBlankLine) return null
|
756
|
+
state.prevLine = null
|
757
|
+
}
|
758
|
+
|
759
|
+
state.prevLine = state.thisLine
|
760
|
+
state.thisLine = stream
|
761
|
+
|
762
|
+
// Reset state.taskList
|
763
|
+
state.taskList = false;
|
764
|
+
|
765
|
+
// Reset state.trailingSpace
|
766
|
+
state.trailingSpace = 0;
|
767
|
+
state.trailingSpaceNewLine = false;
|
768
|
+
|
769
|
+
state.f = state.block;
|
770
|
+
var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
|
771
|
+
state.indentationDiff = Math.min(indentation - state.indentation, 4);
|
772
|
+
state.indentation = state.indentation + state.indentationDiff;
|
773
|
+
if (indentation > 0) return null;
|
774
|
+
}
|
775
|
+
return state.f(stream, state);
|
776
|
+
},
|
777
|
+
|
778
|
+
innerMode: function(state) {
|
779
|
+
if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};
|
780
|
+
if (state.localState) return {state: state.localState, mode: state.localMode};
|
781
|
+
return {state: state, mode: mode};
|
782
|
+
},
|
783
|
+
|
784
|
+
blankLine: blankLine,
|
785
|
+
|
786
|
+
getType: getType,
|
787
|
+
|
788
|
+
closeBrackets: "()[]{}''\"\"``",
|
789
|
+
fold: "markdown"
|
790
|
+
};
|
791
|
+
return mode;
|
792
|
+
}, "xml");
|
793
|
+
|
794
|
+
CodeMirror.defineMIME("text/x-markdown", "markdown");
|
795
|
+
|
796
|
+
});
|