hyde_admin 0.0.1 → 0.0.3

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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +3 -0
  3. data/.idea/hyde_admin.iml +2 -0
  4. data/.idea/vcs.xml +6 -0
  5. data/CHANGELOG.md +11 -0
  6. data/README.md +23 -0
  7. data/TODO.md +1 -0
  8. data/bin/admin_views/admin_layout.html.erb +138 -109
  9. data/bin/admin_views/configuration.erb +13 -0
  10. data/bin/admin_views/dashboard.erb +1 -1
  11. data/bin/admin_views/editor_html.erb +24 -0
  12. data/bin/admin_views/editor_js.erb +120 -0
  13. data/bin/admin_views/files/edit.erb +30 -0
  14. data/bin/admin_views/files/listing.erb +111 -0
  15. data/bin/admin_views/posts/edit.erb +156 -0
  16. data/bin/admin_views/posts/listing.erb +34 -0
  17. data/bin/fslightbox/fslightbox.js +1 -0
  18. data/bin/hyde_admin +3 -0
  19. data/bin/hyde_admin.ru +243 -55
  20. data/bin/hyde_admin.yml +12 -5
  21. data/bin/hyde_assets/hyde_admin.css +18 -0
  22. data/bin/hyde_assets/hyde_admin.js +24 -0
  23. data/bin/i18n/en.yml +62 -1
  24. data/bin/i18n/fr.yml +62 -1
  25. data/bin/lib/codemirror.css +349 -0
  26. data/bin/lib/codemirror.js +9833 -0
  27. data/bin/mode/css/css.js +864 -0
  28. data/bin/mode/css/gss.html +104 -0
  29. data/bin/mode/css/gss_test.js +17 -0
  30. data/bin/mode/css/index.html +81 -0
  31. data/bin/mode/css/less.html +152 -0
  32. data/bin/mode/css/less_test.js +54 -0
  33. data/bin/mode/css/scss.html +158 -0
  34. data/bin/mode/css/scss_test.js +110 -0
  35. data/bin/mode/css/test.js +217 -0
  36. data/bin/mode/htmlembedded/htmlembedded.js +37 -0
  37. data/bin/mode/htmlembedded/index.html +60 -0
  38. data/bin/mode/htmlmixed/htmlmixed.js +153 -0
  39. data/bin/mode/htmlmixed/index.html +100 -0
  40. data/bin/mode/javascript/index.html +118 -0
  41. data/bin/mode/javascript/javascript.js +959 -0
  42. data/bin/mode/javascript/json-ld.html +72 -0
  43. data/bin/mode/javascript/test.js +521 -0
  44. data/bin/mode/javascript/typescript.html +62 -0
  45. data/bin/mode/markdown/index.html +418 -0
  46. data/bin/mode/markdown/markdown.js +886 -0
  47. data/bin/mode/markdown/test.js +1319 -0
  48. data/bin/mode/ruby/index.html +183 -0
  49. data/bin/mode/ruby/ruby.js +303 -0
  50. data/bin/mode/ruby/test.js +23 -0
  51. data/bin/mode/sass/index.html +68 -0
  52. data/bin/mode/sass/sass.js +459 -0
  53. data/bin/mode/sass/test.js +122 -0
  54. data/bin/mode/spreadsheet/index.html +42 -0
  55. data/bin/mode/spreadsheet/spreadsheet.js +112 -0
  56. data/bin/mode/xml/index.html +61 -0
  57. data/bin/mode/xml/test.js +51 -0
  58. data/bin/mode/xml/xml.js +417 -0
  59. data/bin/mode/yaml/index.html +80 -0
  60. data/bin/mode/yaml/yaml.js +120 -0
  61. data/bin/mode/yaml-frontmatter/index.html +121 -0
  62. data/bin/mode/yaml-frontmatter/yaml-frontmatter.js +72 -0
  63. data/hyde_admin.gemspec +6 -1
  64. data/lib/hyde_admin/version.rb +1 -1
  65. metadata +114 -7
  66. data/bin/admin_views/edit.erb +0 -57
  67. data/bin/admin_views/listing.erb +0 -32
  68. data/bin/hyde_admin.sh +0 -3
@@ -0,0 +1,112 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineMode("spreadsheet", function () {
15
+ return {
16
+ startState: function () {
17
+ return {
18
+ stringType: null,
19
+ stack: []
20
+ };
21
+ },
22
+ token: function (stream, state) {
23
+ if (!stream) return;
24
+
25
+ //check for state changes
26
+ if (state.stack.length === 0) {
27
+ //strings
28
+ if ((stream.peek() == '"') || (stream.peek() == "'")) {
29
+ state.stringType = stream.peek();
30
+ stream.next(); // Skip quote
31
+ state.stack.unshift("string");
32
+ }
33
+ }
34
+
35
+ //return state
36
+ //stack has
37
+ switch (state.stack[0]) {
38
+ case "string":
39
+ while (state.stack[0] === "string" && !stream.eol()) {
40
+ if (stream.peek() === state.stringType) {
41
+ stream.next(); // Skip quote
42
+ state.stack.shift(); // Clear flag
43
+ } else if (stream.peek() === "\\") {
44
+ stream.next();
45
+ stream.next();
46
+ } else {
47
+ stream.match(/^.[^\\\"\']*/);
48
+ }
49
+ }
50
+ return "string";
51
+
52
+ case "characterClass":
53
+ while (state.stack[0] === "characterClass" && !stream.eol()) {
54
+ if (!(stream.match(/^[^\]\\]+/) || stream.match(/^\\./)))
55
+ state.stack.shift();
56
+ }
57
+ return "operator";
58
+ }
59
+
60
+ var peek = stream.peek();
61
+
62
+ //no stack
63
+ switch (peek) {
64
+ case "[":
65
+ stream.next();
66
+ state.stack.unshift("characterClass");
67
+ return "bracket";
68
+ case ":":
69
+ stream.next();
70
+ return "operator";
71
+ case "\\":
72
+ if (stream.match(/\\[a-z]+/)) return "string-2";
73
+ else {
74
+ stream.next();
75
+ return "atom";
76
+ }
77
+ case ".":
78
+ case ",":
79
+ case ";":
80
+ case "*":
81
+ case "-":
82
+ case "+":
83
+ case "^":
84
+ case "<":
85
+ case "/":
86
+ case "=":
87
+ stream.next();
88
+ return "atom";
89
+ case "$":
90
+ stream.next();
91
+ return "builtin";
92
+ }
93
+
94
+ if (stream.match(/\d+/)) {
95
+ if (stream.match(/^\w+/)) return "error";
96
+ return "number";
97
+ } else if (stream.match(/^[a-zA-Z_]\w*/)) {
98
+ if (stream.match(/(?=[\(.])/, false)) return "keyword";
99
+ return "variable-2";
100
+ } else if (["[", "]", "(", ")", "{", "}"].indexOf(peek) != -1) {
101
+ stream.next();
102
+ return "bracket";
103
+ } else if (!stream.eatSpace()) {
104
+ stream.next();
105
+ }
106
+ return null;
107
+ }
108
+ };
109
+ });
110
+
111
+ CodeMirror.defineMIME("text/x-spreadsheet", "spreadsheet");
112
+ });
@@ -0,0 +1,61 @@
1
+ <!doctype html>
2
+
3
+ <title>CodeMirror: XML mode</title>
4
+ <meta charset="utf-8"/>
5
+ <link rel=stylesheet href="../../doc/docs.css">
6
+
7
+ <link rel="stylesheet" href="../../lib/codemirror.css">
8
+ <script src="../../lib/codemirror.js"></script>
9
+ <script src="xml.js"></script>
10
+ <style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
11
+ <div id=nav>
12
+ <a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
13
+
14
+ <ul>
15
+ <li><a href="../../index.html">Home</a>
16
+ <li><a href="../../doc/manual.html">Manual</a>
17
+ <li><a href="https://github.com/codemirror/codemirror">Code</a>
18
+ </ul>
19
+ <ul>
20
+ <li><a href="../index.html">Language modes</a>
21
+ <li><a class=active href="#">XML</a>
22
+ </ul>
23
+ </div>
24
+
25
+ <article>
26
+ <h2>XML mode</h2>
27
+ <form><textarea id="code" name="code">
28
+ &lt;html style="color: green"&gt;
29
+ &lt;!-- this is a comment --&gt;
30
+ &lt;head&gt;
31
+ &lt;title&gt;HTML Example&lt;/title&gt;
32
+ &lt;/head&gt;
33
+ &lt;body&gt;
34
+ The indentation tries to be &lt;em&gt;somewhat &amp;quot;do what
35
+ I mean&amp;quot;&lt;/em&gt;... but might not match your style.
36
+ &lt;/body&gt;
37
+ &lt;/html&gt;
38
+ </textarea></form>
39
+ <script>
40
+ var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
41
+ mode: "text/html",
42
+ lineNumbers: true
43
+ });
44
+ </script>
45
+ <p>The XML mode supports these configuration parameters:</p>
46
+ <dl>
47
+ <dt><code>htmlMode (boolean)</code></dt>
48
+ <dd>This switches the mode to parse HTML instead of XML. This
49
+ means attributes do not have to be quoted, and some elements
50
+ (such as <code>br</code>) do not require a closing tag.</dd>
51
+ <dt><code>matchClosing (boolean)</code></dt>
52
+ <dd>Controls whether the mode checks that close tags match the
53
+ corresponding opening tag, and highlights mismatches as errors.
54
+ Defaults to true.</dd>
55
+ <dt><code>alignCDATA (boolean)</code></dt>
56
+ <dd>Setting this to true will force the opening tag of CDATA
57
+ blocks to not be indented.</dd>
58
+ </dl>
59
+
60
+ <p><strong>MIME types defined:</strong> <code>application/xml</code>, <code>text/html</code>.</p>
61
+ </article>
@@ -0,0 +1,51 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/LICENSE
3
+
4
+ (function() {
5
+ var mode = CodeMirror.getMode({indentUnit: 2}, "xml"), mname = "xml";
6
+ function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), mname); }
7
+
8
+ MT("matching",
9
+ "[tag&bracket <][tag top][tag&bracket >]",
10
+ " text",
11
+ " [tag&bracket <][tag inner][tag&bracket />]",
12
+ "[tag&bracket </][tag top][tag&bracket >]");
13
+
14
+ MT("nonmatching",
15
+ "[tag&bracket <][tag top][tag&bracket >]",
16
+ " [tag&bracket <][tag inner][tag&bracket />]",
17
+ " [tag&bracket </][tag&error tip][tag&bracket&error >]");
18
+
19
+ MT("doctype",
20
+ "[meta <!doctype foobar>]",
21
+ "[tag&bracket <][tag top][tag&bracket />]");
22
+
23
+ MT("cdata",
24
+ "[tag&bracket <][tag top][tag&bracket >]",
25
+ " [atom <![CDATA[foo]",
26
+ "[atom barbazguh]]]]>]",
27
+ "[tag&bracket </][tag top][tag&bracket >]");
28
+
29
+ // HTML tests
30
+ mode = CodeMirror.getMode({indentUnit: 2}, "text/html");
31
+
32
+ MT("selfclose",
33
+ "[tag&bracket <][tag html][tag&bracket >]",
34
+ " [tag&bracket <][tag link] [attribute rel]=[string stylesheet] [attribute href]=[string \"/foobar\"][tag&bracket >]",
35
+ "[tag&bracket </][tag html][tag&bracket >]");
36
+
37
+ MT("list",
38
+ "[tag&bracket <][tag ol][tag&bracket >]",
39
+ " [tag&bracket <][tag li][tag&bracket >]one",
40
+ " [tag&bracket <][tag li][tag&bracket >]two",
41
+ "[tag&bracket </][tag ol][tag&bracket >]");
42
+
43
+ MT("valueless",
44
+ "[tag&bracket <][tag input] [attribute type]=[string checkbox] [attribute checked][tag&bracket />]");
45
+
46
+ MT("pThenArticle",
47
+ "[tag&bracket <][tag p][tag&bracket >]",
48
+ " foo",
49
+ "[tag&bracket <][tag article][tag&bracket >]bar");
50
+
51
+ })();
@@ -0,0 +1,417 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ var htmlConfig = {
15
+ autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
16
+ 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
17
+ 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
18
+ 'track': true, 'wbr': true, 'menuitem': true},
19
+ implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
20
+ 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
21
+ 'th': true, 'tr': true},
22
+ contextGrabbers: {
23
+ 'dd': {'dd': true, 'dt': true},
24
+ 'dt': {'dd': true, 'dt': true},
25
+ 'li': {'li': true},
26
+ 'option': {'option': true, 'optgroup': true},
27
+ 'optgroup': {'optgroup': true},
28
+ 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
29
+ 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
30
+ 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
31
+ 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
32
+ 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
33
+ 'rp': {'rp': true, 'rt': true},
34
+ 'rt': {'rp': true, 'rt': true},
35
+ 'tbody': {'tbody': true, 'tfoot': true},
36
+ 'td': {'td': true, 'th': true},
37
+ 'tfoot': {'tbody': true},
38
+ 'th': {'td': true, 'th': true},
39
+ 'thead': {'tbody': true, 'tfoot': true},
40
+ 'tr': {'tr': true}
41
+ },
42
+ doNotIndent: {"pre": true},
43
+ allowUnquoted: true,
44
+ allowMissing: true,
45
+ caseFold: true
46
+ }
47
+
48
+ var xmlConfig = {
49
+ autoSelfClosers: {},
50
+ implicitlyClosed: {},
51
+ contextGrabbers: {},
52
+ doNotIndent: {},
53
+ allowUnquoted: false,
54
+ allowMissing: false,
55
+ allowMissingTagName: false,
56
+ caseFold: false
57
+ }
58
+
59
+ CodeMirror.defineMode("xml", function(editorConf, config_) {
60
+ var indentUnit = editorConf.indentUnit
61
+ var config = {}
62
+ var defaults = config_.htmlMode ? htmlConfig : xmlConfig
63
+ for (var prop in defaults) config[prop] = defaults[prop]
64
+ for (var prop in config_) config[prop] = config_[prop]
65
+
66
+ // Return variables for tokenizers
67
+ var type, setStyle;
68
+
69
+ function inText(stream, state) {
70
+ function chain(parser) {
71
+ state.tokenize = parser;
72
+ return parser(stream, state);
73
+ }
74
+
75
+ var ch = stream.next();
76
+ if (ch == "<") {
77
+ if (stream.eat("!")) {
78
+ if (stream.eat("[")) {
79
+ if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
80
+ else return null;
81
+ } else if (stream.match("--")) {
82
+ return chain(inBlock("comment", "-->"));
83
+ } else if (stream.match("DOCTYPE", true, true)) {
84
+ stream.eatWhile(/[\w\._\-]/);
85
+ return chain(doctype(1));
86
+ } else {
87
+ return null;
88
+ }
89
+ } else if (stream.eat("?")) {
90
+ stream.eatWhile(/[\w\._\-]/);
91
+ state.tokenize = inBlock("meta", "?>");
92
+ return "meta";
93
+ } else {
94
+ type = stream.eat("/") ? "closeTag" : "openTag";
95
+ state.tokenize = inTag;
96
+ return "tag bracket";
97
+ }
98
+ } else if (ch == "&") {
99
+ var ok;
100
+ if (stream.eat("#")) {
101
+ if (stream.eat("x")) {
102
+ ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
103
+ } else {
104
+ ok = stream.eatWhile(/[\d]/) && stream.eat(";");
105
+ }
106
+ } else {
107
+ ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
108
+ }
109
+ return ok ? "atom" : "error";
110
+ } else {
111
+ stream.eatWhile(/[^&<]/);
112
+ return null;
113
+ }
114
+ }
115
+ inText.isInText = true;
116
+
117
+ function inTag(stream, state) {
118
+ var ch = stream.next();
119
+ if (ch == ">" || (ch == "/" && stream.eat(">"))) {
120
+ state.tokenize = inText;
121
+ type = ch == ">" ? "endTag" : "selfcloseTag";
122
+ return "tag bracket";
123
+ } else if (ch == "=") {
124
+ type = "equals";
125
+ return null;
126
+ } else if (ch == "<") {
127
+ state.tokenize = inText;
128
+ state.state = baseState;
129
+ state.tagName = state.tagStart = null;
130
+ var next = state.tokenize(stream, state);
131
+ return next ? next + " tag error" : "tag error";
132
+ } else if (/[\'\"]/.test(ch)) {
133
+ state.tokenize = inAttribute(ch);
134
+ state.stringStartCol = stream.column();
135
+ return state.tokenize(stream, state);
136
+ } else {
137
+ stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
138
+ return "word";
139
+ }
140
+ }
141
+
142
+ function inAttribute(quote) {
143
+ var closure = function(stream, state) {
144
+ while (!stream.eol()) {
145
+ if (stream.next() == quote) {
146
+ state.tokenize = inTag;
147
+ break;
148
+ }
149
+ }
150
+ return "string";
151
+ };
152
+ closure.isInAttribute = true;
153
+ return closure;
154
+ }
155
+
156
+ function inBlock(style, terminator) {
157
+ return function(stream, state) {
158
+ while (!stream.eol()) {
159
+ if (stream.match(terminator)) {
160
+ state.tokenize = inText;
161
+ break;
162
+ }
163
+ stream.next();
164
+ }
165
+ return style;
166
+ }
167
+ }
168
+
169
+ function doctype(depth) {
170
+ return function(stream, state) {
171
+ var ch;
172
+ while ((ch = stream.next()) != null) {
173
+ if (ch == "<") {
174
+ state.tokenize = doctype(depth + 1);
175
+ return state.tokenize(stream, state);
176
+ } else if (ch == ">") {
177
+ if (depth == 1) {
178
+ state.tokenize = inText;
179
+ break;
180
+ } else {
181
+ state.tokenize = doctype(depth - 1);
182
+ return state.tokenize(stream, state);
183
+ }
184
+ }
185
+ }
186
+ return "meta";
187
+ };
188
+ }
189
+
190
+ function lower(tagName) {
191
+ return tagName && tagName.toLowerCase();
192
+ }
193
+
194
+ function Context(state, tagName, startOfLine) {
195
+ this.prev = state.context;
196
+ this.tagName = tagName || "";
197
+ this.indent = state.indented;
198
+ this.startOfLine = startOfLine;
199
+ if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
200
+ this.noIndent = true;
201
+ }
202
+ function popContext(state) {
203
+ if (state.context) state.context = state.context.prev;
204
+ }
205
+ function maybePopContext(state, nextTagName) {
206
+ var parentTagName;
207
+ while (true) {
208
+ if (!state.context) {
209
+ return;
210
+ }
211
+ parentTagName = state.context.tagName;
212
+ if (!config.contextGrabbers.hasOwnProperty(lower(parentTagName)) ||
213
+ !config.contextGrabbers[lower(parentTagName)].hasOwnProperty(lower(nextTagName))) {
214
+ return;
215
+ }
216
+ popContext(state);
217
+ }
218
+ }
219
+
220
+ function baseState(type, stream, state) {
221
+ if (type == "openTag") {
222
+ state.tagStart = stream.column();
223
+ return tagNameState;
224
+ } else if (type == "closeTag") {
225
+ return closeTagNameState;
226
+ } else {
227
+ return baseState;
228
+ }
229
+ }
230
+ function tagNameState(type, stream, state) {
231
+ if (type == "word") {
232
+ state.tagName = stream.current();
233
+ setStyle = "tag";
234
+ return attrState;
235
+ } else if (config.allowMissingTagName && type == "endTag") {
236
+ setStyle = "tag bracket";
237
+ return attrState(type, stream, state);
238
+ } else {
239
+ setStyle = "error";
240
+ return tagNameState;
241
+ }
242
+ }
243
+ function closeTagNameState(type, stream, state) {
244
+ if (type == "word") {
245
+ var tagName = stream.current();
246
+ if (state.context && state.context.tagName != tagName &&
247
+ config.implicitlyClosed.hasOwnProperty(lower(state.context.tagName)))
248
+ popContext(state);
249
+ if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
250
+ setStyle = "tag";
251
+ return closeState;
252
+ } else {
253
+ setStyle = "tag error";
254
+ return closeStateErr;
255
+ }
256
+ } else if (config.allowMissingTagName && type == "endTag") {
257
+ setStyle = "tag bracket";
258
+ return closeState(type, stream, state);
259
+ } else {
260
+ setStyle = "error";
261
+ return closeStateErr;
262
+ }
263
+ }
264
+
265
+ function closeState(type, _stream, state) {
266
+ if (type != "endTag") {
267
+ setStyle = "error";
268
+ return closeState;
269
+ }
270
+ popContext(state);
271
+ return baseState;
272
+ }
273
+ function closeStateErr(type, stream, state) {
274
+ setStyle = "error";
275
+ return closeState(type, stream, state);
276
+ }
277
+
278
+ function attrState(type, _stream, state) {
279
+ if (type == "word") {
280
+ setStyle = "attribute";
281
+ return attrEqState;
282
+ } else if (type == "endTag" || type == "selfcloseTag") {
283
+ var tagName = state.tagName, tagStart = state.tagStart;
284
+ state.tagName = state.tagStart = null;
285
+ if (type == "selfcloseTag" ||
286
+ config.autoSelfClosers.hasOwnProperty(lower(tagName))) {
287
+ maybePopContext(state, tagName);
288
+ } else {
289
+ maybePopContext(state, tagName);
290
+ state.context = new Context(state, tagName, tagStart == state.indented);
291
+ }
292
+ return baseState;
293
+ }
294
+ setStyle = "error";
295
+ return attrState;
296
+ }
297
+ function attrEqState(type, stream, state) {
298
+ if (type == "equals") return attrValueState;
299
+ if (!config.allowMissing) setStyle = "error";
300
+ return attrState(type, stream, state);
301
+ }
302
+ function attrValueState(type, stream, state) {
303
+ if (type == "string") return attrContinuedState;
304
+ if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
305
+ setStyle = "error";
306
+ return attrState(type, stream, state);
307
+ }
308
+ function attrContinuedState(type, stream, state) {
309
+ if (type == "string") return attrContinuedState;
310
+ return attrState(type, stream, state);
311
+ }
312
+
313
+ return {
314
+ startState: function(baseIndent) {
315
+ var state = {tokenize: inText,
316
+ state: baseState,
317
+ indented: baseIndent || 0,
318
+ tagName: null, tagStart: null,
319
+ context: null}
320
+ if (baseIndent != null) state.baseIndent = baseIndent
321
+ return state
322
+ },
323
+
324
+ token: function(stream, state) {
325
+ if (!state.tagName && stream.sol())
326
+ state.indented = stream.indentation();
327
+
328
+ if (stream.eatSpace()) return null;
329
+ type = null;
330
+ var style = state.tokenize(stream, state);
331
+ if ((style || type) && style != "comment") {
332
+ setStyle = null;
333
+ state.state = state.state(type || style, stream, state);
334
+ if (setStyle)
335
+ style = setStyle == "error" ? style + " error" : setStyle;
336
+ }
337
+ return style;
338
+ },
339
+
340
+ indent: function(state, textAfter, fullLine) {
341
+ var context = state.context;
342
+ // Indent multi-line strings (e.g. css).
343
+ if (state.tokenize.isInAttribute) {
344
+ if (state.tagStart == state.indented)
345
+ return state.stringStartCol + 1;
346
+ else
347
+ return state.indented + indentUnit;
348
+ }
349
+ if (context && context.noIndent) return CodeMirror.Pass;
350
+ if (state.tokenize != inTag && state.tokenize != inText)
351
+ return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
352
+ // Indent the starts of attribute names.
353
+ if (state.tagName) {
354
+ if (config.multilineTagIndentPastTag !== false)
355
+ return state.tagStart + state.tagName.length + 2;
356
+ else
357
+ return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
358
+ }
359
+ if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
360
+ var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
361
+ if (tagAfter && tagAfter[1]) { // Closing tag spotted
362
+ while (context) {
363
+ if (context.tagName == tagAfter[2]) {
364
+ context = context.prev;
365
+ break;
366
+ } else if (config.implicitlyClosed.hasOwnProperty(lower(context.tagName))) {
367
+ context = context.prev;
368
+ } else {
369
+ break;
370
+ }
371
+ }
372
+ } else if (tagAfter) { // Opening tag spotted
373
+ while (context) {
374
+ var grabbers = config.contextGrabbers[lower(context.tagName)];
375
+ if (grabbers && grabbers.hasOwnProperty(lower(tagAfter[2])))
376
+ context = context.prev;
377
+ else
378
+ break;
379
+ }
380
+ }
381
+ while (context && context.prev && !context.startOfLine)
382
+ context = context.prev;
383
+ if (context) return context.indent + indentUnit;
384
+ else return state.baseIndent || 0;
385
+ },
386
+
387
+ electricInput: /<\/[\s\w:]+>$/,
388
+ blockCommentStart: "<!--",
389
+ blockCommentEnd: "-->",
390
+
391
+ configuration: config.htmlMode ? "html" : "xml",
392
+ helperType: config.htmlMode ? "html" : "xml",
393
+
394
+ skipAttribute: function(state) {
395
+ if (state.state == attrValueState)
396
+ state.state = attrState
397
+ },
398
+
399
+ xmlCurrentTag: function(state) {
400
+ return state.tagName ? {name: state.tagName, close: state.type == "closeTag"} : null
401
+ },
402
+
403
+ xmlCurrentContext: function(state) {
404
+ var context = []
405
+ for (var cx = state.context; cx; cx = cx.prev)
406
+ context.push(cx.tagName)
407
+ return context.reverse()
408
+ }
409
+ };
410
+ });
411
+
412
+ CodeMirror.defineMIME("text/xml", "xml");
413
+ CodeMirror.defineMIME("application/xml", "xml");
414
+ if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
415
+ CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
416
+
417
+ });