hyde_admin 0.0.1 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) 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 +35 -0
  6. data/README.md +23 -0
  7. data/TODO.md +3 -0
  8. data/bin/admin_views/admin_layout.html.erb +204 -108
  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/partials/image_element.html.erb +4 -0
  16. data/bin/admin_views/partials/images_page.html.erb +8 -0
  17. data/bin/admin_views/posts/edit.erb +158 -0
  18. data/bin/admin_views/posts/listing.erb +37 -0
  19. data/bin/admin_views/upload_image_form.erb +45 -0
  20. data/bin/fslightbox/fslightbox.js +1 -0
  21. data/bin/hyde_admin +3 -0
  22. data/bin/hyde_admin.ru +306 -56
  23. data/bin/hyde_admin.yml +12 -5
  24. data/bin/hyde_assets/hyde_admin.css +37 -0
  25. data/bin/hyde_assets/hyde_admin.js +24 -0
  26. data/bin/i18n/en.yml +77 -1
  27. data/bin/i18n/fr.yml +77 -1
  28. data/bin/lib/codemirror.css +349 -0
  29. data/bin/lib/codemirror.js +9833 -0
  30. data/bin/mode/css/css.js +864 -0
  31. data/bin/mode/css/gss.html +104 -0
  32. data/bin/mode/css/gss_test.js +17 -0
  33. data/bin/mode/css/index.html +81 -0
  34. data/bin/mode/css/less.html +152 -0
  35. data/bin/mode/css/less_test.js +54 -0
  36. data/bin/mode/css/scss.html +158 -0
  37. data/bin/mode/css/scss_test.js +110 -0
  38. data/bin/mode/css/test.js +217 -0
  39. data/bin/mode/htmlembedded/htmlembedded.js +37 -0
  40. data/bin/mode/htmlembedded/index.html +60 -0
  41. data/bin/mode/htmlmixed/htmlmixed.js +153 -0
  42. data/bin/mode/htmlmixed/index.html +100 -0
  43. data/bin/mode/javascript/index.html +118 -0
  44. data/bin/mode/javascript/javascript.js +959 -0
  45. data/bin/mode/javascript/json-ld.html +72 -0
  46. data/bin/mode/javascript/test.js +521 -0
  47. data/bin/mode/javascript/typescript.html +62 -0
  48. data/bin/mode/markdown/index.html +418 -0
  49. data/bin/mode/markdown/markdown.js +886 -0
  50. data/bin/mode/markdown/test.js +1319 -0
  51. data/bin/mode/ruby/index.html +183 -0
  52. data/bin/mode/ruby/ruby.js +303 -0
  53. data/bin/mode/ruby/test.js +23 -0
  54. data/bin/mode/sass/index.html +68 -0
  55. data/bin/mode/sass/sass.js +459 -0
  56. data/bin/mode/sass/test.js +122 -0
  57. data/bin/mode/spreadsheet/index.html +42 -0
  58. data/bin/mode/spreadsheet/spreadsheet.js +112 -0
  59. data/bin/mode/xml/index.html +61 -0
  60. data/bin/mode/xml/test.js +51 -0
  61. data/bin/mode/xml/xml.js +417 -0
  62. data/bin/mode/yaml/index.html +80 -0
  63. data/bin/mode/yaml/yaml.js +120 -0
  64. data/bin/mode/yaml-frontmatter/index.html +121 -0
  65. data/bin/mode/yaml-frontmatter/yaml-frontmatter.js +72 -0
  66. data/hyde_admin.gemspec +7 -1
  67. data/lib/hyde_admin/version.rb +1 -1
  68. metadata +131 -7
  69. data/bin/admin_views/edit.erb +0 -57
  70. data/bin/admin_views/listing.erb +0 -32
  71. 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
+ });