honey-cms 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,83 @@
1
+ CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
2
+ var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
3
+ var jsMode = CodeMirror.getMode(config, "javascript");
4
+ var cssMode = CodeMirror.getMode(config, "css");
5
+
6
+ function html(stream, state) {
7
+ var style = htmlMode.token(stream, state.htmlState);
8
+ if (style == "tag" && stream.current() == ">" && state.htmlState.context) {
9
+ if (/^script$/i.test(state.htmlState.context.tagName)) {
10
+ state.token = javascript;
11
+ state.localState = jsMode.startState(htmlMode.indent(state.htmlState, ""));
12
+ state.mode = "javascript";
13
+ }
14
+ else if (/^style$/i.test(state.htmlState.context.tagName)) {
15
+ state.token = css;
16
+ state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
17
+ state.mode = "css";
18
+ }
19
+ }
20
+ return style;
21
+ }
22
+ function maybeBackup(stream, pat, style) {
23
+ var cur = stream.current();
24
+ var close = cur.search(pat), m;
25
+ if (close > -1) stream.backUp(cur.length - close);
26
+ else if (m = cur.match(/<\/?$/)) {
27
+ stream.backUp(cur[0].length);
28
+ if (!stream.match(pat, false)) stream.match(cur[0]);
29
+ }
30
+ return style;
31
+ }
32
+ function javascript(stream, state) {
33
+ if (stream.match(/^<\/\s*script\s*>/i, false)) {
34
+ state.token = html;
35
+ state.localState = null;
36
+ state.mode = "html";
37
+ return html(stream, state);
38
+ }
39
+ return maybeBackup(stream, /<\/\s*script\s*>/,
40
+ jsMode.token(stream, state.localState));
41
+ }
42
+ function css(stream, state) {
43
+ if (stream.match(/^<\/\s*style\s*>/i, false)) {
44
+ state.token = html;
45
+ state.localState = null;
46
+ state.mode = "html";
47
+ return html(stream, state);
48
+ }
49
+ return maybeBackup(stream, /<\/\s*style\s*>/,
50
+ cssMode.token(stream, state.localState));
51
+ }
52
+
53
+ return {
54
+ startState: function() {
55
+ var state = htmlMode.startState();
56
+ return {token: html, localState: null, mode: "html", htmlState: state};
57
+ },
58
+
59
+ copyState: function(state) {
60
+ if (state.localState)
61
+ var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState);
62
+ return {token: state.token, localState: local, mode: state.mode,
63
+ htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
64
+ },
65
+
66
+ token: function(stream, state) {
67
+ return state.token(stream, state);
68
+ },
69
+
70
+ indent: function(state, textAfter) {
71
+ if (state.token == html || /^\s*<\//.test(textAfter))
72
+ return htmlMode.indent(state.htmlState, textAfter);
73
+ else if (state.token == javascript)
74
+ return jsMode.indent(state.localState, textAfter);
75
+ else
76
+ return cssMode.indent(state.localState, textAfter);
77
+ },
78
+
79
+ electricChars: "/{}:"
80
+ };
81
+ }, "xml", "javascript", "css");
82
+
83
+ CodeMirror.defineMIME("text/html", "htmlmixed");
@@ -0,0 +1,318 @@
1
+ CodeMirror.defineMode("xml", function(config, parserConfig) {
2
+ var indentUnit = config.indentUnit;
3
+ var Kludges = parserConfig.htmlMode ? {
4
+ autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
5
+ 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
6
+ 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
7
+ 'track': true, 'wbr': true},
8
+ implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
9
+ 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
10
+ 'th': true, 'tr': true},
11
+ contextGrabbers: {
12
+ 'dd': {'dd': true, 'dt': true},
13
+ 'dt': {'dd': true, 'dt': true},
14
+ 'li': {'li': true},
15
+ 'option': {'option': true, 'optgroup': true},
16
+ 'optgroup': {'optgroup': true},
17
+ 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
18
+ 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
19
+ 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
20
+ 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
21
+ 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
22
+ 'rp': {'rp': true, 'rt': true},
23
+ 'rt': {'rp': true, 'rt': true},
24
+ 'tbody': {'tbody': true, 'tfoot': true},
25
+ 'td': {'td': true, 'th': true},
26
+ 'tfoot': {'tbody': true},
27
+ 'th': {'td': true, 'th': true},
28
+ 'thead': {'tbody': true, 'tfoot': true},
29
+ 'tr': {'tr': true}
30
+ },
31
+ doNotIndent: {"pre": true},
32
+ allowUnquoted: true,
33
+ allowMissing: true
34
+ } : {
35
+ autoSelfClosers: {},
36
+ implicitlyClosed: {},
37
+ contextGrabbers: {},
38
+ doNotIndent: {},
39
+ allowUnquoted: false,
40
+ allowMissing: false
41
+ };
42
+ var alignCDATA = parserConfig.alignCDATA;
43
+
44
+ // Return variables for tokenizers
45
+ var tagName, type;
46
+
47
+ function inText(stream, state) {
48
+ function chain(parser) {
49
+ state.tokenize = parser;
50
+ return parser(stream, state);
51
+ }
52
+
53
+ var ch = stream.next();
54
+ if (ch == "<") {
55
+ if (stream.eat("!")) {
56
+ if (stream.eat("[")) {
57
+ if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
58
+ else return null;
59
+ }
60
+ else if (stream.match("--")) return chain(inBlock("comment", "-->"));
61
+ else if (stream.match("DOCTYPE", true, true)) {
62
+ stream.eatWhile(/[\w\._\-]/);
63
+ return chain(doctype(1));
64
+ }
65
+ else return null;
66
+ }
67
+ else if (stream.eat("?")) {
68
+ stream.eatWhile(/[\w\._\-]/);
69
+ state.tokenize = inBlock("meta", "?>");
70
+ return "meta";
71
+ }
72
+ else {
73
+ type = stream.eat("/") ? "closeTag" : "openTag";
74
+ stream.eatSpace();
75
+ tagName = "";
76
+ var c;
77
+ while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
78
+ state.tokenize = inTag;
79
+ return "tag";
80
+ }
81
+ }
82
+ else if (ch == "&") {
83
+ var ok;
84
+ if (stream.eat("#")) {
85
+ if (stream.eat("x")) {
86
+ ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
87
+ } else {
88
+ ok = stream.eatWhile(/[\d]/) && stream.eat(";");
89
+ }
90
+ } else {
91
+ ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
92
+ }
93
+ return ok ? "atom" : "error";
94
+ }
95
+ else {
96
+ stream.eatWhile(/[^&<]/);
97
+ return null;
98
+ }
99
+ }
100
+
101
+ function inTag(stream, state) {
102
+ var ch = stream.next();
103
+ if (ch == ">" || (ch == "/" && stream.eat(">"))) {
104
+ state.tokenize = inText;
105
+ type = ch == ">" ? "endTag" : "selfcloseTag";
106
+ return "tag";
107
+ }
108
+ else if (ch == "=") {
109
+ type = "equals";
110
+ return null;
111
+ }
112
+ else if (/[\'\"]/.test(ch)) {
113
+ state.tokenize = inAttribute(ch);
114
+ return state.tokenize(stream, state);
115
+ }
116
+ else {
117
+ stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/);
118
+ return "word";
119
+ }
120
+ }
121
+
122
+ function inAttribute(quote) {
123
+ return function(stream, state) {
124
+ while (!stream.eol()) {
125
+ if (stream.next() == quote) {
126
+ state.tokenize = inTag;
127
+ break;
128
+ }
129
+ }
130
+ return "string";
131
+ };
132
+ }
133
+
134
+ function inBlock(style, terminator) {
135
+ return function(stream, state) {
136
+ while (!stream.eol()) {
137
+ if (stream.match(terminator)) {
138
+ state.tokenize = inText;
139
+ break;
140
+ }
141
+ stream.next();
142
+ }
143
+ return style;
144
+ };
145
+ }
146
+ function doctype(depth) {
147
+ return function(stream, state) {
148
+ var ch;
149
+ while ((ch = stream.next()) != null) {
150
+ if (ch == "<") {
151
+ state.tokenize = doctype(depth + 1);
152
+ return state.tokenize(stream, state);
153
+ } else if (ch == ">") {
154
+ if (depth == 1) {
155
+ state.tokenize = inText;
156
+ break;
157
+ } else {
158
+ state.tokenize = doctype(depth - 1);
159
+ return state.tokenize(stream, state);
160
+ }
161
+ }
162
+ }
163
+ return "meta";
164
+ };
165
+ }
166
+
167
+ var curState, setStyle;
168
+ function pass() {
169
+ for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
170
+ }
171
+ function cont() {
172
+ pass.apply(null, arguments);
173
+ return true;
174
+ }
175
+
176
+ function pushContext(tagName, startOfLine) {
177
+ var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
178
+ curState.context = {
179
+ prev: curState.context,
180
+ tagName: tagName,
181
+ indent: curState.indented,
182
+ startOfLine: startOfLine,
183
+ noIndent: noIndent
184
+ };
185
+ }
186
+ function popContext() {
187
+ if (curState.context) curState.context = curState.context.prev;
188
+ }
189
+
190
+ function element(type) {
191
+ if (type == "openTag") {
192
+ curState.tagName = tagName;
193
+ return cont(attributes, endtag(curState.startOfLine));
194
+ } else if (type == "closeTag") {
195
+ var err = false;
196
+ if (curState.context) {
197
+ if (curState.context.tagName != tagName) {
198
+ if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
199
+ popContext();
200
+ }
201
+ err = !curState.context || curState.context.tagName != tagName;
202
+ }
203
+ } else {
204
+ err = true;
205
+ }
206
+ if (err) setStyle = "error";
207
+ return cont(endclosetag(err));
208
+ }
209
+ return cont();
210
+ }
211
+ function endtag(startOfLine) {
212
+ return function(type) {
213
+ if (type == "selfcloseTag" ||
214
+ (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase()))) {
215
+ maybePopContext(curState.tagName.toLowerCase());
216
+ return cont();
217
+ }
218
+ if (type == "endTag") {
219
+ maybePopContext(curState.tagName.toLowerCase());
220
+ pushContext(curState.tagName, startOfLine);
221
+ return cont();
222
+ }
223
+ return cont();
224
+ };
225
+ }
226
+ function endclosetag(err) {
227
+ return function(type) {
228
+ if (err) setStyle = "error";
229
+ if (type == "endTag") { popContext(); return cont(); }
230
+ setStyle = "error";
231
+ return cont(arguments.callee);
232
+ };
233
+ }
234
+ function maybePopContext(nextTagName) {
235
+ var parentTagName;
236
+ while (true) {
237
+ if (!curState.context) {
238
+ return;
239
+ }
240
+ parentTagName = curState.context.tagName.toLowerCase();
241
+ if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
242
+ !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
243
+ return;
244
+ }
245
+ popContext();
246
+ }
247
+ }
248
+
249
+ function attributes(type) {
250
+ if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
251
+ if (type == "endTag" || type == "selfcloseTag") return pass();
252
+ setStyle = "error";
253
+ return cont(attributes);
254
+ }
255
+ function attribute(type) {
256
+ if (type == "equals") return cont(attvalue, attributes);
257
+ if (!Kludges.allowMissing) setStyle = "error";
258
+ return (type == "endTag" || type == "selfcloseTag") ? pass() : cont();
259
+ }
260
+ function attvalue(type) {
261
+ if (type == "string") return cont(attvaluemaybe);
262
+ if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
263
+ setStyle = "error";
264
+ return (type == "endTag" || type == "selfCloseTag") ? pass() : cont();
265
+ }
266
+ function attvaluemaybe(type) {
267
+ if (type == "string") return cont(attvaluemaybe);
268
+ else return pass();
269
+ }
270
+
271
+ return {
272
+ startState: function() {
273
+ return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null};
274
+ },
275
+
276
+ token: function(stream, state) {
277
+ if (stream.sol()) {
278
+ state.startOfLine = true;
279
+ state.indented = stream.indentation();
280
+ }
281
+ if (stream.eatSpace()) return null;
282
+
283
+ setStyle = type = tagName = null;
284
+ var style = state.tokenize(stream, state);
285
+ state.type = type;
286
+ if ((style || type) && style != "comment") {
287
+ curState = state;
288
+ while (true) {
289
+ var comb = state.cc.pop() || element;
290
+ if (comb(type || style)) break;
291
+ }
292
+ }
293
+ state.startOfLine = false;
294
+ return setStyle || style;
295
+ },
296
+
297
+ indent: function(state, textAfter, fullLine) {
298
+ var context = state.context;
299
+ if ((state.tokenize != inTag && state.tokenize != inText) ||
300
+ context && context.noIndent)
301
+ return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
302
+ if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
303
+ if (context && /^<\//.test(textAfter))
304
+ context = context.prev;
305
+ while (context && !context.startOfLine)
306
+ context = context.prev;
307
+ if (context) return context.indent + indentUnit;
308
+ else return 0;
309
+ },
310
+
311
+ electricChars: "/"
312
+ };
313
+ });
314
+
315
+ CodeMirror.defineMIME("text/xml", "xml");
316
+ CodeMirror.defineMIME("application/xml", "xml");
317
+ if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
318
+ CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
@@ -1,3 +1,5 @@
1
+ @import 'html_editor';
2
+
1
3
  .cms-page-area {
2
4
  position: relative;
3
5
  &:hover .cms-edit-link { display: block }
@@ -0,0 +1,7 @@
1
+ [role=html-editor] {
2
+ [role=editor] {
3
+ visibility: hidden;
4
+ .CodeMirror{ background-color: white }
5
+ .form-actions { margin: 0 }
6
+ }
7
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honey-cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -17,8 +17,13 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
+ - vendor/assets/javascripts/cms.js.coffee
21
+ - vendor/assets/javascripts/codemirror/htmlmixed.js
22
+ - vendor/assets/javascripts/codemirror/xml.js
23
+ - vendor/assets/javascripts/codemirror.js
20
24
  - vendor/assets/stylesheets/cms.css.scss
21
25
  - vendor/assets/stylesheets/cms_ui.css.scss
26
+ - vendor/assets/stylesheets/html_editor.css.scss
22
27
  - lib/cms/attribute.rb
23
28
  - lib/cms/configuration.rb
24
29
  - lib/cms/controller_stub.rb
@@ -31,7 +36,12 @@ files:
31
36
  - lib/cms/uploader.rb
32
37
  - lib/cms/view_tags.rb
33
38
  - lib/cms.rb
39
+ - lib/generators/cms/admin_area_generator.rb
40
+ - lib/generators/cms/base.rb
34
41
  - lib/generators/cms/cms_generator.rb
42
+ - lib/generators/cms/content_types.rb
43
+ - lib/generators/cms/migration_generator.rb
44
+ - lib/generators/cms/pages_generator.rb
35
45
  - lib/generators/cms/templates/cms_base_controller.rb
36
46
  - lib/generators/cms/templates/cms_model.rb
37
47
  - lib/generators/cms/templates/migration.rb