hyde_admin 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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,217 @@
|
|
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}, "css");
|
6
|
+
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
|
7
|
+
|
8
|
+
// Error, because "foobarhello" is neither a known type or property, but
|
9
|
+
// property was expected (after "and"), and it should be in parentheses.
|
10
|
+
MT("atMediaUnknownType",
|
11
|
+
"[def @media] [attribute screen] [keyword and] [error foobarhello] { }");
|
12
|
+
|
13
|
+
// Soft error, because "foobarhello" is not a known property or type.
|
14
|
+
MT("atMediaUnknownProperty",
|
15
|
+
"[def @media] [attribute screen] [keyword and] ([error foobarhello]) { }");
|
16
|
+
|
17
|
+
// Make sure nesting works with media queries
|
18
|
+
MT("atMediaMaxWidthNested",
|
19
|
+
"[def @media] [attribute screen] [keyword and] ([property max-width]: [number 25px]) { [tag foo] { } }");
|
20
|
+
|
21
|
+
MT("atMediaFeatureValueKeyword",
|
22
|
+
"[def @media] ([property orientation]: [keyword landscape]) { }");
|
23
|
+
|
24
|
+
MT("atMediaUnknownFeatureValueKeyword",
|
25
|
+
"[def @media] ([property orientation]: [error upsidedown]) { }");
|
26
|
+
|
27
|
+
MT("atMediaUppercase",
|
28
|
+
"[def @MEDIA] ([property orienTAtion]: [keyword landScape]) { }");
|
29
|
+
|
30
|
+
MT("tagSelector",
|
31
|
+
"[tag foo] { }");
|
32
|
+
|
33
|
+
MT("classSelector",
|
34
|
+
"[qualifier .foo-bar_hello] { }");
|
35
|
+
|
36
|
+
MT("idSelector",
|
37
|
+
"[builtin #foo] { [error #foo] }");
|
38
|
+
|
39
|
+
MT("tagSelectorUnclosed",
|
40
|
+
"[tag foo] { [property margin]: [number 0] } [tag bar] { }");
|
41
|
+
|
42
|
+
MT("tagStringNoQuotes",
|
43
|
+
"[tag foo] { [property font-family]: [variable hello] [variable world]; }");
|
44
|
+
|
45
|
+
MT("tagStringDouble",
|
46
|
+
"[tag foo] { [property font-family]: [string \"hello world\"]; }");
|
47
|
+
|
48
|
+
MT("tagStringSingle",
|
49
|
+
"[tag foo] { [property font-family]: [string 'hello world']; }");
|
50
|
+
|
51
|
+
MT("tagColorKeyword",
|
52
|
+
"[tag foo] {",
|
53
|
+
" [property color]: [keyword black];",
|
54
|
+
" [property color]: [keyword navy];",
|
55
|
+
" [property color]: [keyword yellow];",
|
56
|
+
"}");
|
57
|
+
|
58
|
+
MT("tagColorHex3",
|
59
|
+
"[tag foo] { [property background]: [atom #fff]; }");
|
60
|
+
|
61
|
+
MT("tagColorHex4",
|
62
|
+
"[tag foo] { [property background]: [atom #ffff]; }");
|
63
|
+
|
64
|
+
MT("tagColorHex6",
|
65
|
+
"[tag foo] { [property background]: [atom #ffffff]; }");
|
66
|
+
|
67
|
+
MT("tagColorHex8",
|
68
|
+
"[tag foo] { [property background]: [atom #ffffffff]; }");
|
69
|
+
|
70
|
+
MT("tagColorHex5Invalid",
|
71
|
+
"[tag foo] { [property background]: [atom&error #fffff]; }");
|
72
|
+
|
73
|
+
MT("tagColorHexInvalid",
|
74
|
+
"[tag foo] { [property background]: [atom&error #ffg]; }");
|
75
|
+
|
76
|
+
MT("tagNegativeNumber",
|
77
|
+
"[tag foo] { [property margin]: [number -5px]; }");
|
78
|
+
|
79
|
+
MT("tagPositiveNumber",
|
80
|
+
"[tag foo] { [property padding]: [number 5px]; }");
|
81
|
+
|
82
|
+
MT("tagVendor",
|
83
|
+
"[tag foo] { [meta -foo-][property box-sizing]: [meta -foo-][atom border-box]; }");
|
84
|
+
|
85
|
+
MT("tagBogusProperty",
|
86
|
+
"[tag foo] { [property&error barhelloworld]: [number 0]; }");
|
87
|
+
|
88
|
+
MT("tagTwoProperties",
|
89
|
+
"[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }");
|
90
|
+
|
91
|
+
MT("tagTwoPropertiesURL",
|
92
|
+
"[tag foo] { [property background]: [variable&callee url]([string //example.com/foo.png]); [property padding]: [number 0]; }");
|
93
|
+
|
94
|
+
MT("indent_tagSelector",
|
95
|
+
"[tag strong], [tag em] {",
|
96
|
+
" [property background]: [variable&callee rgba](",
|
97
|
+
" [number 255], [number 255], [number 0], [number .2]",
|
98
|
+
" );",
|
99
|
+
"}");
|
100
|
+
|
101
|
+
MT("indent_atMedia",
|
102
|
+
"[def @media] {",
|
103
|
+
" [tag foo] {",
|
104
|
+
" [property color]:",
|
105
|
+
" [keyword yellow];",
|
106
|
+
" }",
|
107
|
+
"}");
|
108
|
+
|
109
|
+
MT("indent_comma",
|
110
|
+
"[tag foo] {",
|
111
|
+
" [property font-family]: [variable verdana],",
|
112
|
+
" [atom sans-serif];",
|
113
|
+
"}");
|
114
|
+
|
115
|
+
MT("indent_parentheses",
|
116
|
+
"[tag foo]:[variable-3 before] {",
|
117
|
+
" [property background]: [variable&callee url](",
|
118
|
+
"[string blahblah]",
|
119
|
+
"[string etc]",
|
120
|
+
"[string ]) [keyword !important];",
|
121
|
+
"}");
|
122
|
+
|
123
|
+
MT("font_face",
|
124
|
+
"[def @font-face] {",
|
125
|
+
" [property font-family]: [string 'myfont'];",
|
126
|
+
" [error nonsense]: [string 'abc'];",
|
127
|
+
" [property src]: [variable&callee url]([string http://blah]),",
|
128
|
+
" [variable&callee url]([string http://foo]);",
|
129
|
+
"}");
|
130
|
+
|
131
|
+
MT("empty_url",
|
132
|
+
"[def @import] [variable&callee url]() [attribute screen];");
|
133
|
+
|
134
|
+
MT("parens",
|
135
|
+
"[qualifier .foo] {",
|
136
|
+
" [property background-image]: [variable&callee fade]([atom #000], [number 20%]);",
|
137
|
+
" [property border-image]: [variable&callee linear-gradient](",
|
138
|
+
" [atom to] [atom bottom],",
|
139
|
+
" [variable&callee fade]([atom #000], [number 20%]) [number 0%],",
|
140
|
+
" [variable&callee fade]([atom #000], [number 20%]) [number 100%]",
|
141
|
+
" );",
|
142
|
+
"}");
|
143
|
+
|
144
|
+
MT("css_variable",
|
145
|
+
":[variable-3 root] {",
|
146
|
+
" [variable-2 --main-color]: [atom #06c];",
|
147
|
+
"}",
|
148
|
+
"[tag h1][builtin #foo] {",
|
149
|
+
" [property color]: [variable&callee var]([variable-2 --main-color]);",
|
150
|
+
"}");
|
151
|
+
|
152
|
+
MT("blank_css_variable",
|
153
|
+
":[variable-3 root] {",
|
154
|
+
" [variable-2 --]: [atom #06c];",
|
155
|
+
"}",
|
156
|
+
"[tag h1][builtin #foo] {",
|
157
|
+
" [property color]: [variable&callee var]([variable-2 --]);",
|
158
|
+
"}");
|
159
|
+
|
160
|
+
MT("supports",
|
161
|
+
"[def @supports] ([keyword not] (([property text-align-last]: [atom justify]) [keyword or] ([meta -moz-][property text-align-last]: [atom justify])) {",
|
162
|
+
" [property text-align-last]: [atom justify];",
|
163
|
+
"}");
|
164
|
+
|
165
|
+
MT("document",
|
166
|
+
"[def @document] [variable&callee url]([string http://blah]),",
|
167
|
+
" [variable&callee url-prefix]([string https://]),",
|
168
|
+
" [variable&callee domain]([string blah.com]),",
|
169
|
+
" [variable&callee regexp]([string \".*blah.+\"]) {",
|
170
|
+
" [builtin #id] {",
|
171
|
+
" [property background-color]: [keyword white];",
|
172
|
+
" }",
|
173
|
+
" [tag foo] {",
|
174
|
+
" [property font-family]: [variable Verdana], [atom sans-serif];",
|
175
|
+
" }",
|
176
|
+
"}");
|
177
|
+
|
178
|
+
MT("document_url",
|
179
|
+
"[def @document] [variable&callee url]([string http://blah]) { [qualifier .class] { } }");
|
180
|
+
|
181
|
+
MT("document_urlPrefix",
|
182
|
+
"[def @document] [variable&callee url-prefix]([string https://]) { [builtin #id] { } }");
|
183
|
+
|
184
|
+
MT("document_domain",
|
185
|
+
"[def @document] [variable&callee domain]([string blah.com]) { [tag foo] { } }");
|
186
|
+
|
187
|
+
MT("document_regexp",
|
188
|
+
"[def @document] [variable&callee regexp]([string \".*blah.+\"]) { [builtin #id] { } }");
|
189
|
+
|
190
|
+
MT("counter-style",
|
191
|
+
"[def @counter-style] [variable binary] {",
|
192
|
+
" [property system]: [atom numeric];",
|
193
|
+
" [property symbols]: [number 0] [number 1];",
|
194
|
+
" [property suffix]: [string \".\"];",
|
195
|
+
" [property range]: [atom infinite];",
|
196
|
+
" [property speak-as]: [atom numeric];",
|
197
|
+
"}");
|
198
|
+
|
199
|
+
MT("counter-style-additive-symbols",
|
200
|
+
"[def @counter-style] [variable simple-roman] {",
|
201
|
+
" [property system]: [atom additive];",
|
202
|
+
" [property additive-symbols]: [number 10] [variable X], [number 5] [variable V], [number 1] [variable I];",
|
203
|
+
" [property range]: [number 1] [number 49];",
|
204
|
+
"}");
|
205
|
+
|
206
|
+
MT("counter-style-use",
|
207
|
+
"[tag ol][qualifier .roman] { [property list-style]: [variable simple-roman]; }");
|
208
|
+
|
209
|
+
MT("counter-style-symbols",
|
210
|
+
"[tag ol] { [property list-style]: [variable&callee symbols]([atom cyclic] [string \"*\"] [string \"\\2020\"] [string \"\\2021\"] [string \"\\A7\"]); }");
|
211
|
+
|
212
|
+
MT("comment-does-not-disrupt",
|
213
|
+
"[def @font-face] [comment /* foo */] {",
|
214
|
+
" [property src]: [variable&callee url]([string x]);",
|
215
|
+
" [property font-family]: [variable One];",
|
216
|
+
"}")
|
217
|
+
})();
|
@@ -0,0 +1,37 @@
|
|
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"), require("../htmlmixed/htmlmixed"),
|
7
|
+
require("../../addon/mode/multiplex"));
|
8
|
+
else if (typeof define == "function" && define.amd) // AMD
|
9
|
+
define(["../../lib/codemirror", "../htmlmixed/htmlmixed",
|
10
|
+
"../../addon/mode/multiplex"], mod);
|
11
|
+
else // Plain browser env
|
12
|
+
mod(CodeMirror);
|
13
|
+
})(function(CodeMirror) {
|
14
|
+
"use strict";
|
15
|
+
|
16
|
+
CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
|
17
|
+
var closeComment = parserConfig.closeComment || "--%>"
|
18
|
+
return CodeMirror.multiplexingMode(CodeMirror.getMode(config, "htmlmixed"), {
|
19
|
+
open: parserConfig.openComment || "<%--",
|
20
|
+
close: closeComment,
|
21
|
+
delimStyle: "comment",
|
22
|
+
mode: {token: function(stream) {
|
23
|
+
stream.skipTo(closeComment) || stream.skipToEnd()
|
24
|
+
return "comment"
|
25
|
+
}}
|
26
|
+
}, {
|
27
|
+
open: parserConfig.open || parserConfig.scriptStartRegex || "<%",
|
28
|
+
close: parserConfig.close || parserConfig.scriptEndRegex || "%>",
|
29
|
+
mode: CodeMirror.getMode(config, parserConfig.scriptingModeSpec)
|
30
|
+
});
|
31
|
+
}, "htmlmixed");
|
32
|
+
|
33
|
+
CodeMirror.defineMIME("application/x-ejs", {name: "htmlembedded", scriptingModeSpec:"javascript"});
|
34
|
+
CodeMirror.defineMIME("application/x-aspx", {name: "htmlembedded", scriptingModeSpec:"text/x-csharp"});
|
35
|
+
CodeMirror.defineMIME("application/x-jsp", {name: "htmlembedded", scriptingModeSpec:"text/x-java"});
|
36
|
+
CodeMirror.defineMIME("application/x-erb", {name: "htmlembedded", scriptingModeSpec:"ruby"});
|
37
|
+
});
|
@@ -0,0 +1,60 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
|
3
|
+
<title>CodeMirror: Html Embedded Scripts 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/xml.js"></script>
|
10
|
+
<script src="../javascript/javascript.js"></script>
|
11
|
+
<script src="../css/css.js"></script>
|
12
|
+
<script src="../htmlmixed/htmlmixed.js"></script>
|
13
|
+
<script src="../../addon/mode/multiplex.js"></script>
|
14
|
+
<script src="htmlembedded.js"></script>
|
15
|
+
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
16
|
+
<div id=nav>
|
17
|
+
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
|
18
|
+
|
19
|
+
<ul>
|
20
|
+
<li><a href="../../index.html">Home</a>
|
21
|
+
<li><a href="../../doc/manual.html">Manual</a>
|
22
|
+
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
23
|
+
</ul>
|
24
|
+
<ul>
|
25
|
+
<li><a href="../index.html">Language modes</a>
|
26
|
+
<li><a class=active href="#">Html Embedded Scripts</a>
|
27
|
+
</ul>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<article>
|
31
|
+
<h2>Html Embedded Scripts mode</h2>
|
32
|
+
<form><textarea id="code" name="code">
|
33
|
+
<%
|
34
|
+
function hello(who) {
|
35
|
+
return "Hello " + who;
|
36
|
+
}
|
37
|
+
%>
|
38
|
+
This is an example of EJS (embedded javascript)
|
39
|
+
<p>The program says <%= hello("world") %>.</p>
|
40
|
+
<script>
|
41
|
+
alert("And here is some normal JS code"); // also colored
|
42
|
+
</script>
|
43
|
+
</textarea></form>
|
44
|
+
|
45
|
+
<script>
|
46
|
+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
47
|
+
lineNumbers: true,
|
48
|
+
mode: "application/x-ejs",
|
49
|
+
indentUnit: 4,
|
50
|
+
indentWithTabs: true
|
51
|
+
});
|
52
|
+
</script>
|
53
|
+
|
54
|
+
<p>Mode for html embedded scripts like JSP and ASP.NET. Depends on multiplex and HtmlMixed which in turn depends on
|
55
|
+
JavaScript, CSS and XML.<br />Other dependencies include those of the scripting language chosen.</p>
|
56
|
+
|
57
|
+
<p><strong>MIME types defined:</strong> <code>application/x-aspx</code> (ASP.NET),
|
58
|
+
<code>application/x-ejs</code> (Embedded JavaScript), <code>application/x-jsp</code> (JavaServer Pages)
|
59
|
+
and <code>application/x-erb</code></p>
|
60
|
+
</article>
|
@@ -0,0 +1,153 @@
|
|
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"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
|
7
|
+
else if (typeof define == "function" && define.amd) // AMD
|
8
|
+
define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
|
9
|
+
else // Plain browser env
|
10
|
+
mod(CodeMirror);
|
11
|
+
})(function(CodeMirror) {
|
12
|
+
"use strict";
|
13
|
+
|
14
|
+
var defaultTags = {
|
15
|
+
script: [
|
16
|
+
["lang", /(javascript|babel)/i, "javascript"],
|
17
|
+
["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i, "javascript"],
|
18
|
+
["type", /./, "text/plain"],
|
19
|
+
[null, null, "javascript"]
|
20
|
+
],
|
21
|
+
style: [
|
22
|
+
["lang", /^css$/i, "css"],
|
23
|
+
["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"],
|
24
|
+
["type", /./, "text/plain"],
|
25
|
+
[null, null, "css"]
|
26
|
+
]
|
27
|
+
};
|
28
|
+
|
29
|
+
function maybeBackup(stream, pat, style) {
|
30
|
+
var cur = stream.current(), close = cur.search(pat);
|
31
|
+
if (close > -1) {
|
32
|
+
stream.backUp(cur.length - close);
|
33
|
+
} else if (cur.match(/<\/?$/)) {
|
34
|
+
stream.backUp(cur.length);
|
35
|
+
if (!stream.match(pat, false)) stream.match(cur);
|
36
|
+
}
|
37
|
+
return style;
|
38
|
+
}
|
39
|
+
|
40
|
+
var attrRegexpCache = {};
|
41
|
+
function getAttrRegexp(attr) {
|
42
|
+
var regexp = attrRegexpCache[attr];
|
43
|
+
if (regexp) return regexp;
|
44
|
+
return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*");
|
45
|
+
}
|
46
|
+
|
47
|
+
function getAttrValue(text, attr) {
|
48
|
+
var match = text.match(getAttrRegexp(attr))
|
49
|
+
return match ? /^\s*(.*?)\s*$/.exec(match[2])[1] : ""
|
50
|
+
}
|
51
|
+
|
52
|
+
function getTagRegexp(tagName, anchored) {
|
53
|
+
return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i");
|
54
|
+
}
|
55
|
+
|
56
|
+
function addTags(from, to) {
|
57
|
+
for (var tag in from) {
|
58
|
+
var dest = to[tag] || (to[tag] = []);
|
59
|
+
var source = from[tag];
|
60
|
+
for (var i = source.length - 1; i >= 0; i--)
|
61
|
+
dest.unshift(source[i])
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
function findMatchingMode(tagInfo, tagText) {
|
66
|
+
for (var i = 0; i < tagInfo.length; i++) {
|
67
|
+
var spec = tagInfo[i];
|
68
|
+
if (!spec[0] || spec[1].test(getAttrValue(tagText, spec[0]))) return spec[2];
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
CodeMirror.defineMode("htmlmixed", function (config, parserConfig) {
|
73
|
+
var htmlMode = CodeMirror.getMode(config, {
|
74
|
+
name: "xml",
|
75
|
+
htmlMode: true,
|
76
|
+
multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
|
77
|
+
multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag,
|
78
|
+
allowMissingTagName: parserConfig.allowMissingTagName,
|
79
|
+
});
|
80
|
+
|
81
|
+
var tags = {};
|
82
|
+
var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes;
|
83
|
+
addTags(defaultTags, tags);
|
84
|
+
if (configTags) addTags(configTags, tags);
|
85
|
+
if (configScript) for (var i = configScript.length - 1; i >= 0; i--)
|
86
|
+
tags.script.unshift(["type", configScript[i].matches, configScript[i].mode])
|
87
|
+
|
88
|
+
function html(stream, state) {
|
89
|
+
var style = htmlMode.token(stream, state.htmlState), tag = /\btag\b/.test(style), tagName
|
90
|
+
if (tag && !/[<>\s\/]/.test(stream.current()) &&
|
91
|
+
(tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase()) &&
|
92
|
+
tags.hasOwnProperty(tagName)) {
|
93
|
+
state.inTag = tagName + " "
|
94
|
+
} else if (state.inTag && tag && />$/.test(stream.current())) {
|
95
|
+
var inTag = /^([\S]+) (.*)/.exec(state.inTag)
|
96
|
+
state.inTag = null
|
97
|
+
var modeSpec = stream.current() == ">" && findMatchingMode(tags[inTag[1]], inTag[2])
|
98
|
+
var mode = CodeMirror.getMode(config, modeSpec)
|
99
|
+
var endTagA = getTagRegexp(inTag[1], true), endTag = getTagRegexp(inTag[1], false);
|
100
|
+
state.token = function (stream, state) {
|
101
|
+
if (stream.match(endTagA, false)) {
|
102
|
+
state.token = html;
|
103
|
+
state.localState = state.localMode = null;
|
104
|
+
return null;
|
105
|
+
}
|
106
|
+
return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState));
|
107
|
+
};
|
108
|
+
state.localMode = mode;
|
109
|
+
state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, "", ""));
|
110
|
+
} else if (state.inTag) {
|
111
|
+
state.inTag += stream.current()
|
112
|
+
if (stream.eol()) state.inTag += " "
|
113
|
+
}
|
114
|
+
return style;
|
115
|
+
};
|
116
|
+
|
117
|
+
return {
|
118
|
+
startState: function () {
|
119
|
+
var state = CodeMirror.startState(htmlMode);
|
120
|
+
return {token: html, inTag: null, localMode: null, localState: null, htmlState: state};
|
121
|
+
},
|
122
|
+
|
123
|
+
copyState: function (state) {
|
124
|
+
var local;
|
125
|
+
if (state.localState) {
|
126
|
+
local = CodeMirror.copyState(state.localMode, state.localState);
|
127
|
+
}
|
128
|
+
return {token: state.token, inTag: state.inTag,
|
129
|
+
localMode: state.localMode, localState: local,
|
130
|
+
htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
|
131
|
+
},
|
132
|
+
|
133
|
+
token: function (stream, state) {
|
134
|
+
return state.token(stream, state);
|
135
|
+
},
|
136
|
+
|
137
|
+
indent: function (state, textAfter, line) {
|
138
|
+
if (!state.localMode || /^\s*<\//.test(textAfter))
|
139
|
+
return htmlMode.indent(state.htmlState, textAfter, line);
|
140
|
+
else if (state.localMode.indent)
|
141
|
+
return state.localMode.indent(state.localState, textAfter, line);
|
142
|
+
else
|
143
|
+
return CodeMirror.Pass;
|
144
|
+
},
|
145
|
+
|
146
|
+
innerMode: function (state) {
|
147
|
+
return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
|
148
|
+
}
|
149
|
+
};
|
150
|
+
}, "xml", "javascript", "css");
|
151
|
+
|
152
|
+
CodeMirror.defineMIME("text/html", "htmlmixed");
|
153
|
+
});
|
@@ -0,0 +1,100 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
|
3
|
+
<title>CodeMirror: HTML mixed 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="../../addon/selection/selection-pointer.js"></script>
|
10
|
+
<script src="../xml/xml.js"></script>
|
11
|
+
<script src="../javascript/javascript.js"></script>
|
12
|
+
<script src="../css/css.js"></script>
|
13
|
+
<script src="../vbscript/vbscript.js"></script>
|
14
|
+
<script src="htmlmixed.js"></script>
|
15
|
+
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
16
|
+
<div id=nav>
|
17
|
+
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
|
18
|
+
|
19
|
+
<ul>
|
20
|
+
<li><a href="../../index.html">Home</a>
|
21
|
+
<li><a href="../../doc/manual.html">Manual</a>
|
22
|
+
<li><a href="https://github.com/codemirror/codemirror">Code</a>
|
23
|
+
</ul>
|
24
|
+
<ul>
|
25
|
+
<li><a href="../index.html">Language modes</a>
|
26
|
+
<li><a class=active href="#">HTML mixed</a>
|
27
|
+
</ul>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<article>
|
31
|
+
<h2>HTML mixed mode</h2>
|
32
|
+
<form><textarea id="code" name="code">
|
33
|
+
<html style="color: green">
|
34
|
+
<!-- this is a comment -->
|
35
|
+
<head>
|
36
|
+
<title>Mixed HTML Example</title>
|
37
|
+
<style>
|
38
|
+
h1 {font-family: comic sans; color: #f0f;}
|
39
|
+
div {background: yellow !important;}
|
40
|
+
body {
|
41
|
+
max-width: 50em;
|
42
|
+
margin: 1em 2em 1em 5em;
|
43
|
+
}
|
44
|
+
</style>
|
45
|
+
</head>
|
46
|
+
<body>
|
47
|
+
<h1>Mixed HTML Example</h1>
|
48
|
+
<script>
|
49
|
+
function jsFunc(arg1, arg2) {
|
50
|
+
if (arg1 && arg2) document.body.innerHTML = "achoo";
|
51
|
+
}
|
52
|
+
</script>
|
53
|
+
</body>
|
54
|
+
</html>
|
55
|
+
</textarea></form>
|
56
|
+
<script>
|
57
|
+
// Define an extended mixed-mode that understands vbscript and
|
58
|
+
// leaves mustache/handlebars embedded templates in html mode
|
59
|
+
var mixedMode = {
|
60
|
+
name: "htmlmixed",
|
61
|
+
scriptTypes: [{matches: /\/x-handlebars-template|\/x-mustache/i,
|
62
|
+
mode: null},
|
63
|
+
{matches: /(text|application)\/(x-)?vb(a|script)/i,
|
64
|
+
mode: "vbscript"}]
|
65
|
+
};
|
66
|
+
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
67
|
+
mode: mixedMode,
|
68
|
+
selectionPointer: true
|
69
|
+
});
|
70
|
+
</script>
|
71
|
+
|
72
|
+
<p>The HTML mixed mode depends on the XML, JavaScript, and CSS modes.</p>
|
73
|
+
|
74
|
+
<p>It takes an optional mode configuration
|
75
|
+
option, <code>tags</code>, which can be used to add custom
|
76
|
+
behavior for specific tags. When given, it should be an object
|
77
|
+
mapping tag names (for example <code>script</code>) to arrays or
|
78
|
+
three-element arrays. Those inner arrays indicate [attributeName,
|
79
|
+
valueRegexp, <a href="../../doc/manual.html#option_mode">modeSpec</a>]
|
80
|
+
specifications. For example, you could use <code>["type", /^foo$/,
|
81
|
+
"foo"]</code> to map the attribute <code>type="foo"</code> to
|
82
|
+
the <code>foo</code> mode. When the first two fields are null
|
83
|
+
(<code>[null, null, "mode"]</code>), the given mode is used for
|
84
|
+
any such tag that doesn't match any of the previously given
|
85
|
+
attributes. For example:</p>
|
86
|
+
|
87
|
+
<pre>var myModeSpec = {
|
88
|
+
name: "htmlmixed",
|
89
|
+
tags: {
|
90
|
+
style: [["type", /^text\/(x-)?scss$/, "text/x-scss"],
|
91
|
+
[null, null, "css"]],
|
92
|
+
custom: [[null, null, "customMode"]]
|
93
|
+
}
|
94
|
+
}</pre>
|
95
|
+
|
96
|
+
<p><strong>MIME types defined:</strong> <code>text/html</code>
|
97
|
+
(redefined, only takes effect if you load this parser after the
|
98
|
+
XML parser).</p>
|
99
|
+
|
100
|
+
</article>
|