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.
- checksums.yaml +4 -4
- data/.gitattributes +3 -0
- data/.idea/hyde_admin.iml +2 -0
- data/.idea/vcs.xml +6 -0
- data/CHANGELOG.md +11 -0
- data/README.md +23 -0
- data/TODO.md +1 -0
- data/bin/admin_views/admin_layout.html.erb +138 -109
- data/bin/admin_views/configuration.erb +13 -0
- data/bin/admin_views/dashboard.erb +1 -1
- data/bin/admin_views/editor_html.erb +24 -0
- data/bin/admin_views/editor_js.erb +120 -0
- data/bin/admin_views/files/edit.erb +30 -0
- data/bin/admin_views/files/listing.erb +111 -0
- data/bin/admin_views/posts/edit.erb +156 -0
- data/bin/admin_views/posts/listing.erb +34 -0
- data/bin/fslightbox/fslightbox.js +1 -0
- data/bin/hyde_admin +3 -0
- data/bin/hyde_admin.ru +243 -55
- data/bin/hyde_admin.yml +12 -5
- data/bin/hyde_assets/hyde_admin.css +18 -0
- data/bin/hyde_assets/hyde_admin.js +24 -0
- data/bin/i18n/en.yml +62 -1
- data/bin/i18n/fr.yml +62 -1
- data/bin/lib/codemirror.css +349 -0
- data/bin/lib/codemirror.js +9833 -0
- data/bin/mode/css/css.js +864 -0
- data/bin/mode/css/gss.html +104 -0
- data/bin/mode/css/gss_test.js +17 -0
- data/bin/mode/css/index.html +81 -0
- data/bin/mode/css/less.html +152 -0
- data/bin/mode/css/less_test.js +54 -0
- data/bin/mode/css/scss.html +158 -0
- data/bin/mode/css/scss_test.js +110 -0
- data/bin/mode/css/test.js +217 -0
- data/bin/mode/htmlembedded/htmlembedded.js +37 -0
- data/bin/mode/htmlembedded/index.html +60 -0
- data/bin/mode/htmlmixed/htmlmixed.js +153 -0
- data/bin/mode/htmlmixed/index.html +100 -0
- data/bin/mode/javascript/index.html +118 -0
- data/bin/mode/javascript/javascript.js +959 -0
- data/bin/mode/javascript/json-ld.html +72 -0
- data/bin/mode/javascript/test.js +521 -0
- data/bin/mode/javascript/typescript.html +62 -0
- data/bin/mode/markdown/index.html +418 -0
- data/bin/mode/markdown/markdown.js +886 -0
- data/bin/mode/markdown/test.js +1319 -0
- data/bin/mode/ruby/index.html +183 -0
- data/bin/mode/ruby/ruby.js +303 -0
- data/bin/mode/ruby/test.js +23 -0
- data/bin/mode/sass/index.html +68 -0
- data/bin/mode/sass/sass.js +459 -0
- data/bin/mode/sass/test.js +122 -0
- data/bin/mode/spreadsheet/index.html +42 -0
- data/bin/mode/spreadsheet/spreadsheet.js +112 -0
- data/bin/mode/xml/index.html +61 -0
- data/bin/mode/xml/test.js +51 -0
- data/bin/mode/xml/xml.js +417 -0
- data/bin/mode/yaml/index.html +80 -0
- data/bin/mode/yaml/yaml.js +120 -0
- data/bin/mode/yaml-frontmatter/index.html +121 -0
- data/bin/mode/yaml-frontmatter/yaml-frontmatter.js +72 -0
- data/hyde_admin.gemspec +6 -1
- data/lib/hyde_admin/version.rb +1 -1
- metadata +114 -7
- data/bin/admin_views/edit.erb +0 -57
- data/bin/admin_views/listing.erb +0 -32
- 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
|
+
<html style="color: green">
|
29
|
+
<!-- this is a comment -->
|
30
|
+
<head>
|
31
|
+
<title>HTML Example</title>
|
32
|
+
</head>
|
33
|
+
<body>
|
34
|
+
The indentation tries to be <em>somewhat &quot;do what
|
35
|
+
I mean&quot;</em>... but might not match your style.
|
36
|
+
</body>
|
37
|
+
</html>
|
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
|
+
})();
|
data/bin/mode/xml/xml.js
ADDED
@@ -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
|
+
});
|