puffer_pages 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +1 -2
  2. data/.rvmrc +1 -0
  3. data/.travis.yml +6 -0
  4. data/CHANGELOG.md +12 -0
  5. data/Gemfile.lock +83 -78
  6. data/app/assets/javascripts/puffer/codemirror.js +1382 -818
  7. data/app/assets/javascripts/puffer/codemirror/htmlmixed.js +4 -5
  8. data/app/assets/javascripts/puffer/codemirror/javascript.js +12 -4
  9. data/app/assets/javascripts/puffer/codemirror/xml.js +35 -14
  10. data/app/assets/javascripts/puffer/liquid.js +15 -0
  11. data/app/assets/javascripts/puffer/puffer_pages.js +56 -6
  12. data/app/assets/stylesheets/puffer/codemirror.css +50 -14
  13. data/app/assets/stylesheets/puffer/codemirror/cobalt.css +1 -0
  14. data/app/assets/stylesheets/puffer/codemirror/eclipse.css +3 -2
  15. data/app/assets/stylesheets/puffer/codemirror/elegant.css +1 -0
  16. data/app/assets/stylesheets/puffer/codemirror/monokai.css +28 -0
  17. data/app/assets/stylesheets/puffer/codemirror/neat.css +1 -0
  18. data/app/assets/stylesheets/puffer/codemirror/night.css +1 -0
  19. data/app/assets/stylesheets/puffer/codemirror/rubyblue.css +21 -0
  20. data/app/assets/stylesheets/puffer/puffer_pages.css +59 -3
  21. data/app/components/codemirror/form.html.erb +16 -0
  22. data/app/components/codemirror_component.rb +9 -0
  23. data/app/components/page_parts/form.html.erb +13 -4
  24. data/app/controllers/pages_controller.rb +1 -10
  25. data/app/controllers/puffer_pages/layouts_base.rb +1 -1
  26. data/app/controllers/puffer_pages/pages_base.rb +1 -1
  27. data/app/controllers/puffer_pages/snippets_base.rb +1 -1
  28. data/app/models/puffer_pages/page.rb +4 -3
  29. data/app/views/layouts/puffer_pages_layout.html.erb +2 -1
  30. data/gemfiles/Gemfile-rails-3.1 +5 -0
  31. data/gemfiles/Gemfile-rails-3.1.lock +173 -0
  32. data/gemfiles/Gemfile-rails-3.2 +5 -0
  33. data/gemfiles/Gemfile-rails-3.2.lock +171 -0
  34. data/lib/puffer_pages.rb +5 -0
  35. data/lib/puffer_pages/extensions/controller.rb +12 -16
  36. data/lib/puffer_pages/extensions/mapper.rb +7 -13
  37. data/lib/puffer_pages/liquid/tags/page_attribute.rb +39 -0
  38. data/lib/puffer_pages/version.rb +1 -1
  39. data/puffer_pages.gemspec +7 -4
  40. data/spec/dummy/app/controllers/application_controller.rb +4 -0
  41. data/spec/lib/tags_spec.rb +25 -3
  42. data/spec/models/page_spec.rb +2 -3
  43. metadata +75 -43
  44. data/app/assets/stylesheets/puffer/codemirror/default.css +0 -19
  45. data/app/components/page_part_body/form.html.erb +0 -3
  46. data/app/components/page_part_body_component.rb +0 -3
@@ -1,8 +1,3 @@
1
- //= require ./xml
2
- //= require ./css
3
- //= require ./javascript
4
- //= require_self
5
-
6
1
  CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
7
2
  var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
8
3
  var jsMode = CodeMirror.getMode(config, "javascript");
@@ -77,6 +72,10 @@ CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
77
72
  return cssMode.indent(state.localState, textAfter);
78
73
  },
79
74
 
75
+ compareStates: function(a, b) {
76
+ return htmlMode.compareStates(a.htmlState, b.htmlState);
77
+ },
78
+
80
79
  electricChars: "/{}:"
81
80
  }
82
81
  });
@@ -11,7 +11,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
11
11
  return {
12
12
  "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
13
13
  "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
14
- "var": kw("var"), "function": kw("function"), "catch": kw("catch"),
14
+ "var": kw("var"), "const": kw("var"), "let": kw("var"),
15
+ "function": kw("function"), "catch": kw("catch"),
15
16
  "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
16
17
  "in": operator, "typeof": operator, "instanceof": operator,
17
18
  "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
@@ -54,7 +55,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
54
55
  return ret("number", "number");
55
56
  }
56
57
  else if (/\d/.test(ch)) {
57
- stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/);
58
+ stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
58
59
  return ret("number", "number");
59
60
  }
60
61
  else if (ch == "/") {
@@ -86,7 +87,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
86
87
  else {
87
88
  stream.eatWhile(/[\w\$_]/);
88
89
  var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
89
- return known ? ret(known.type, known.style, word) :
90
+ return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
90
91
  ret("variable", "variable", word);
91
92
  }
92
93
  }
@@ -228,13 +229,18 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
228
229
  function expression(type) {
229
230
  if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
230
231
  if (type == "function") return cont(functiondef);
231
- if (type == "keyword c") return cont(expression);
232
+ if (type == "keyword c") return cont(maybeexpression);
232
233
  if (type == "(") return cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator);
233
234
  if (type == "operator") return cont(expression);
234
235
  if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
235
236
  if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
236
237
  return cont();
237
238
  }
239
+ function maybeexpression(type) {
240
+ if (type.match(/[;\}\)\],]/)) return pass();
241
+ return pass(expression);
242
+ }
243
+
238
244
  function maybeoperator(type, value) {
239
245
  if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
240
246
  if (type == "operator") return cont(expression);
@@ -310,6 +316,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
310
316
  return {
311
317
  tokenize: jsTokenBase,
312
318
  reAllowed: true,
319
+ kwAllowed: true,
313
320
  cc: [],
314
321
  lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
315
322
  localVars: null,
@@ -328,6 +335,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
328
335
  var style = state.tokenize(stream, state);
329
336
  if (type == "comment") return style;
330
337
  state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/);
338
+ state.kwAllowed = type != '.';
331
339
  return parseJS(state, style, type, content, stream);
332
340
  },
333
341
 
@@ -3,9 +3,9 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
3
3
  var Kludges = parserConfig.htmlMode ? {
4
4
  autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true,
5
5
  "meta": true, "col": true, "frame": true, "base": true, "area": true},
6
- doNotIndent: {"pre": true, "!cdata": true},
6
+ doNotIndent: {"pre": true},
7
7
  allowUnquoted: true
8
- } : {autoSelfClosers: {}, doNotIndent: {"!cdata": true}, allowUnquoted: false};
8
+ } : {autoSelfClosers: {}, doNotIndent: {}, allowUnquoted: false};
9
9
  var alignCDATA = parserConfig.alignCDATA;
10
10
 
11
11
  // Return variables for tokenizers
@@ -27,7 +27,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
27
27
  else if (stream.match("--")) return chain(inBlock("comment", "-->"));
28
28
  else if (stream.match("DOCTYPE", true, true)) {
29
29
  stream.eatWhile(/[\w\._\-]/);
30
- return chain(inBlock("meta", ">"));
30
+ return chain(doctype(1));
31
31
  }
32
32
  else return null;
33
33
  }
@@ -102,6 +102,26 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
102
102
  return style;
103
103
  };
104
104
  }
105
+ function doctype(depth) {
106
+ return function(stream, state) {
107
+ var ch;
108
+ while ((ch = stream.next()) != null) {
109
+ if (ch == "<") {
110
+ state.tokenize = doctype(depth + 1);
111
+ return state.tokenize(stream, state);
112
+ } else if (ch == ">") {
113
+ if (depth == 1) {
114
+ state.tokenize = inText;
115
+ break;
116
+ } else {
117
+ state.tokenize = doctype(depth - 1);
118
+ return state.tokenize(stream, state);
119
+ }
120
+ }
121
+ }
122
+ return "meta";
123
+ };
124
+ }
105
125
 
106
126
  var curState, setStyle;
107
127
  function pass() {
@@ -127,8 +147,10 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
127
147
  }
128
148
 
129
149
  function element(type) {
130
- if (type == "openTag") {curState.tagName = tagName; return cont(attributes, endtag(curState.startOfLine));}
131
- else if (type == "closeTag") {
150
+ if (type == "openTag") {
151
+ curState.tagName = tagName;
152
+ return cont(attributes, endtag(curState.startOfLine));
153
+ } else if (type == "closeTag") {
132
154
  var err = false;
133
155
  if (curState.context) {
134
156
  err = curState.context.tagName != tagName;
@@ -138,12 +160,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
138
160
  if (err) setStyle = "error";
139
161
  return cont(endclosetag(err));
140
162
  }
141
- else if (type == "string") {
142
- if (!curState.context || curState.context.name != "!cdata") pushContext("!cdata");
143
- if (curState.tokenize == inText) popContext();
144
- return cont();
145
- }
146
- else return cont();
163
+ return cont();
147
164
  }
148
165
  function endtag(startOfLine) {
149
166
  return function(type) {
@@ -166,6 +183,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
166
183
  function attributes(type) {
167
184
  if (type == "word") {setStyle = "attribute"; return cont(attributes);}
168
185
  if (type == "equals") return cont(attvalue, attributes);
186
+ if (type == "string") {setStyle = "error"; return cont(attributes);}
169
187
  return pass();
170
188
  }
171
189
  function attvalue(type) {
@@ -192,6 +210,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
192
210
 
193
211
  setStyle = type = tagName = null;
194
212
  var style = state.tokenize(stream, state);
213
+ state.type = type;
195
214
  if ((style || type) && style != "comment") {
196
215
  curState = state;
197
216
  while (true) {
@@ -203,9 +222,11 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
203
222
  return setStyle || style;
204
223
  },
205
224
 
206
- indent: function(state, textAfter) {
225
+ indent: function(state, textAfter, fullLine) {
207
226
  var context = state.context;
208
- if (context && context.noIndent) return 0;
227
+ if ((state.tokenize != inTag && state.tokenize != inText) ||
228
+ context && context.noIndent)
229
+ return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
209
230
  if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
210
231
  if (context && /^<\//.test(textAfter))
211
232
  context = context.prev;
@@ -216,7 +237,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
216
237
  },
217
238
 
218
239
  compareStates: function(a, b) {
219
- if (a.indented != b.indented) return false;
240
+ if (a.indented != b.indented || a.tokenize != b.tokenize) return false;
220
241
  for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
221
242
  if (!ca || !cb) return ca == cb;
222
243
  if (ca.tagName != cb.tagName) return false;
@@ -0,0 +1,15 @@
1
+ CodeMirror.defineMode("liquid", function(config, parserConfig) {
2
+ var liquidOverlay = {
3
+ token: function(stream, state) {
4
+ if (stream.match("{{") || stream.match("{%")) {
5
+ while ((ch = stream.next()) != null)
6
+ if ((ch == "}" || ch == "%") && stream.next() == "}") break;
7
+ return "liquid";
8
+ }
9
+ while (stream.next() != null && !(stream.match("{{", false) || !stream.match("{%", false))) {}
10
+ return null;
11
+ }
12
+ };
13
+
14
+ return CodeMirror.overlayParser(CodeMirror.getMode(config, parserConfig.backdrop || "text/html"), liquidOverlay);
15
+ });
@@ -1,7 +1,11 @@
1
1
  //= require puffer/right-tabs-src
2
2
  //= require puffer/codemirror
3
3
  //= require puffer/overlay
4
+ //= require puffer/codemirror/xml
5
+ //= require puffer/codemirror/javascript
6
+ //= require puffer/codemirror/css
4
7
  //= require_tree ./codemirror
8
+ //= require puffer/liquid
5
9
 
6
10
  Tabs.include({
7
11
  initialize: function(options) {
@@ -17,6 +21,13 @@ Tabs.include({
17
21
  }
18
22
  });
19
23
 
24
+ var page_part_tab_select = function(event) {
25
+ var textarea = event.target.panel.first('textarea[data-codemirror]');
26
+ if (textarea.codemirror) {
27
+ textarea.codemirror.refresh();
28
+ }
29
+ }
30
+
20
31
  var page_part_tab_remove = function(event) {
21
32
  var destroy_mark = event.target.panel.first('.destroy_mark');
22
33
  var page_part_param = destroy_mark.next();
@@ -37,7 +48,7 @@ var page_part_tab_add = function(event) {
37
48
  _this.tabs.last().panel.first('input[type=hidden]').value(value);
38
49
  _this.tabs.last().select();
39
50
  _this.addButton.insertTo(_this.tabsList);
40
- $$('textarea[codemirror]').each(init_codemirror);
51
+ $$('textarea[data-codemirror]').each(init_codemirror);
41
52
  this.hide();
42
53
  }
43
54
  }).show();
@@ -45,14 +56,53 @@ var page_part_tab_add = function(event) {
45
56
 
46
57
  var init_codemirror = function(textarea) {
47
58
  if (!textarea.codemirror) {
48
- CodeMirror.fromTextArea(textarea._, {
49
- mode: 'text/html',
50
- lineNumbers: true
59
+ var codemirror = CodeMirror.fromTextArea(textarea._, {
60
+ mode: 'liquid',
61
+ lineNumbers: true,
62
+ lineWrapping: true,
63
+ onCursorActivity: function(editor) {
64
+ if (editor.last_active_line != undefined) {
65
+ editor.setLineClass(editor.last_active_line, null);
66
+ }
67
+ editor.last_active_line = editor.getCursor().line;
68
+ editor.setLineClass(editor.last_active_line, "active_line");
69
+ },
70
+ extraKeys: {
71
+ "Esc": codemirror_fullscreen
72
+ }
51
73
  });
52
- textarea.codemirror = true
74
+
75
+ textarea.codemirror = codemirror;
76
+ codemirror.buttons = textarea.prev('.codemirror_buttons');
53
77
  }
54
78
  }
55
79
 
56
80
  $(document).onReady(function() {
57
- $$('textarea[codemirror]').each(init_codemirror);
81
+ $$('textarea[data-codemirror]').each(init_codemirror);
82
+ });
83
+
84
+ "*[data-codemirror-button]".onClick(function(event) {
85
+ if (event.which != 1) return;
86
+ window['codemirror_' + this.data('codemirror-button')](this.parent('ul').next('textarea').codemirror);
58
87
  });
88
+
89
+ ".codemirror_buttons_fulscreen".onMouseenter('morph', {'top': '0px'});
90
+ ".codemirror_buttons_fulscreen".onMouseleave('morph', {'top': '-20px'});
91
+
92
+ var codemirror_fullscreen = function(editor) {
93
+ var scroll = $(editor.getWrapperElement()).children('.CodeMirror-scroll').first();
94
+ var body = $$('body').first();
95
+
96
+ if (scroll.hasClass('fullscreen')) {
97
+ scroll.removeClass('fullscreen');
98
+ editor.buttons.removeClass('codemirror_buttons_fulscreen');
99
+ body.setStyle('overflow', 'auto');
100
+ } else {
101
+ scroll.addClass('fullscreen');
102
+ editor.buttons.addClass('codemirror_buttons_fulscreen');
103
+ body.setStyle('overflow', 'hidden');
104
+ }
105
+
106
+ editor.refresh();
107
+ editor.focus();
108
+ }
@@ -23,6 +23,7 @@
23
23
  color: #aaa;
24
24
  text-align: right;
25
25
  padding: .4em .2em .4em .4em;
26
+ white-space: pre !important;
26
27
  }
27
28
  .CodeMirror-lines {
28
29
  padding: .4em;
@@ -41,28 +42,63 @@
41
42
  word-wrap: normal;
42
43
  }
43
44
 
45
+ .CodeMirror-wrap pre {
46
+ word-wrap: break-word;
47
+ white-space: pre-wrap;
48
+ }
49
+ .CodeMirror-wrap .CodeMirror-scroll {
50
+ overflow-x: hidden;
51
+ }
52
+
44
53
  .CodeMirror textarea {
45
- font-family: inherit !important;
46
- font-size: inherit !important;
54
+ outline: none !important;
47
55
  }
48
56
 
49
- .CodeMirror-cursor {
57
+ .CodeMirror pre.CodeMirror-cursor {
50
58
  z-index: 10;
51
59
  position: absolute;
52
60
  visibility: hidden;
53
- border-left: 1px solid black !important;
61
+ border-left: 1px solid black;
54
62
  }
55
- .CodeMirror-focused .CodeMirror-cursor {
63
+ .CodeMirror-focused pre.CodeMirror-cursor {
56
64
  visibility: visible;
57
65
  }
58
66
 
59
- span.CodeMirror-selected {
60
- background: #ccc !important;
61
- color: HighlightText !important;
62
- }
63
- .CodeMirror-focused span.CodeMirror-selected {
64
- background: Highlight !important;
65
- }
67
+ span.CodeMirror-selected { background: #d9d9d9; }
68
+ .CodeMirror-focused span.CodeMirror-selected { background: #d2dcf8; }
69
+
70
+ .CodeMirror-searching {background: #ffa;}
71
+
72
+ /* Default theme */
73
+
74
+ .cm-s-default span.cm-keyword {color: #708;}
75
+ .cm-s-default span.cm-atom {color: #219;}
76
+ .cm-s-default span.cm-number {color: #164;}
77
+ .cm-s-default span.cm-def {color: #00f;}
78
+ .cm-s-default span.cm-variable {color: black;}
79
+ .cm-s-default span.cm-variable-2 {color: #05a;}
80
+ .cm-s-default span.cm-variable-3 {color: #085;}
81
+ .cm-s-default span.cm-property {color: black;}
82
+ .cm-s-default span.cm-operator {color: black;}
83
+ .cm-s-default span.cm-comment {color: #a50;}
84
+ .cm-s-default span.cm-string {color: #a11;}
85
+ .cm-s-default span.cm-string-2 {color: #f50;}
86
+ .cm-s-default span.cm-meta {color: #555;}
87
+ .cm-s-default span.cm-error {color: #f00;}
88
+ .cm-s-default span.cm-qualifier {color: #555;}
89
+ .cm-s-default span.cm-builtin {color: #30a;}
90
+ .cm-s-default span.cm-bracket {color: #cc7;}
91
+ .cm-s-default span.cm-tag {color: #170;}
92
+ .cm-s-default span.cm-attribute {color: #00c;}
93
+ .cm-s-default span.cm-header {color: #a0a;}
94
+ .cm-s-default span.cm-quote {color: #090;}
95
+ .cm-s-default span.cm-hr {color: #999;}
96
+ .cm-s-default span.cm-link {color: #00c;}
97
+
98
+ span.cm-header, span.cm-strong {font-weight: bold;}
99
+ span.cm-em {font-style: italic;}
100
+ span.cm-emstrong {font-style: italic; font-weight: bold;}
101
+ span.cm-link {text-decoration: underline;}
66
102
 
67
- .CodeMirror-matchingbracket {color: #0f0 !important;}
68
- .CodeMirror-nonmatchingbracket {color: #f22 !important;}
103
+ div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
104
+ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
@@ -15,3 +15,4 @@
15
15
  .cm-s-cobalt span.cm-error { color: #9d1e15; }
16
16
  .cm-s-cobalt span.cm-bracket { color: #d8d8d8; }
17
17
  .cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; }
18
+ .cm-s-cobalt span.cm-link { color: #845dc4; }
@@ -17,8 +17,9 @@
17
17
  .cm-s-eclipse span.cm-bracket {color: #cc7;}
18
18
  .cm-s-eclipse span.cm-tag {color: #170;}
19
19
  .cm-s-eclipse span.cm-attribute {color: #00c;}
20
+ .cm-s-eclipse span.cm-link {color: #219;}
20
21
 
21
- .CodeMirror-matchingbracket{
22
+ .cm-s-eclipse .CodeMirror-matchingbracket {
22
23
  border:1px solid grey;
23
24
  color:black !important;;
24
- }
25
+ }
@@ -7,3 +7,4 @@
7
7
  .cm-s-elegant span.cm-keyword {color: #730;}
8
8
  .cm-s-elegant span.cm-builtin {color: #30a;}
9
9
  .cm-s-elegant span.cm-error {background-color: #fdd;}
10
+ .cm-s-elegant span.cm-link {color: #762;}
@@ -0,0 +1,28 @@
1
+ /* Based on Sublime Text's Monokai theme */
2
+
3
+ .cm-s-monokai {background: #272822; color: #f8f8f2;}
4
+ .cm-s-monokai span.CodeMirror-selected {background: #ffe792 !important;}
5
+ .cm-s-monokai .CodeMirror-gutter {background: #272822; border-right: 0px;}
6
+ .cm-s-monokai .CodeMirror-gutter-text {color: #d0d0d0;}
7
+ .cm-s-monokai .CodeMirror-cursor {border-left: 1px solid #f8f8f0 !important;}
8
+
9
+ .cm-s-monokai span.cm-comment {color: #75715e;}
10
+ .cm-s-monokai span.cm-atom {color: #ae81ff;}
11
+ .cm-s-monokai span.cm-number {color: #ae81ff;}
12
+
13
+ .cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute {color: #a6e22e;}
14
+ .cm-s-monokai span.cm-keyword {color: #f92672;}
15
+ .cm-s-monokai span.cm-string {color: #e6db74;}
16
+
17
+ .cm-s-monokai span.cm-variable {color: #a6e22e;}
18
+ .cm-s-monokai span.cm-variable-2 {color: #9effff;}
19
+ .cm-s-monokai span.cm-def {color: #fd971f;}
20
+ .cm-s-monokai span.cm-error {background: #f92672; color: #f8f8f0;}
21
+ .cm-s-monokai span.cm-bracket {color: #f8f8f2;}
22
+ .cm-s-monokai span.cm-tag {color: #f92672;}
23
+ .cm-s-monokai span.cm-link {color: #ae81ff;}
24
+
25
+ .cm-s-monokai .CodeMirror-matchingbracket {
26
+ text-decoration: underline;
27
+ color: white !important;
28
+ }
@@ -6,3 +6,4 @@
6
6
  .cm-s-neat span.cm-variable { color: black; }
7
7
  .cm-s-neat span.cm-number, .cm-s-neat span.cm-atom { color: #3a3; }
8
8
  .cm-s-neat span.cm-meta {color: #555;}
9
+ .cm-s-neat span.cm-link { color: #3a3; }