page_engine 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. data/app/assets/javascripts/page_engine.js +53 -50
  2. data/app/assets/stylesheets/page_engine.css +2 -0
  3. data/app/controllers/admin/pages_controller.rb +1 -3
  4. data/app/helpers/pages_helper.rb +64 -71
  5. data/app/models/page.rb +6 -18
  6. data/app/views/admin/pages/_form.html.haml +3 -3
  7. data/app/views/admin/pages/_page_part_fields.html.haml +1 -1
  8. data/app/views/admin/pages/duplicate.js.erb +0 -4
  9. data/app/views/admin/pages/index.html.haml +1 -1
  10. data/app/views/pages/_nav_item.html.haml +1 -1
  11. data/lib/generators/page_engine/install/install_generator.rb +64 -0
  12. data/lib/page_engine/extensions.rb +12 -8
  13. data/lib/page_engine/instance_methods.rb +6 -6
  14. data/lib/page_engine.rb +31 -0
  15. data/spec/dummy/app/assets/stylesheets/application.css +250 -0
  16. data/spec/dummy/app/controllers/application_controller.rb +1 -1
  17. data/spec/dummy/app/views/layouts/application.html.haml +5 -3
  18. data/spec/dummy/config/initializers/page_engine.rb +13 -0
  19. data/spec/dummy/db/development.sqlite3 +0 -0
  20. data/spec/dummy/log/development.log +18618 -0
  21. data/spec/dummy/tmp/cache/assets/BF5/7E0/sprockets%2F1681222188324d465309541f4e71f6e8 +0 -0
  22. data/spec/dummy/tmp/cache/assets/C1F/4A0/sprockets%2Fb257125f39b2a708d678262f26152408 +0 -0
  23. data/spec/dummy/tmp/cache/assets/C38/BB0/sprockets%2F122300de3f3142028abb055394919a47 +0 -0
  24. data/spec/dummy/tmp/cache/assets/C51/920/sprockets%2F3522c83d77303240c3548fdd7d186194 +0 -0
  25. data/spec/dummy/tmp/cache/assets/C54/B60/sprockets%2F08007599d13c8b8205959be4709d103d +0 -0
  26. data/spec/dummy/tmp/cache/assets/C83/E20/sprockets%2F2d6f03d170965f27d7626502373e8cd2 +0 -0
  27. data/spec/dummy/tmp/cache/assets/C8E/6D0/sprockets%2F10a754e99f089474b072c71eeb960954 +0 -0
  28. data/spec/dummy/tmp/cache/assets/CAD/1B0/sprockets%2F12cb3832e2e7e34236067e9e350b8c73 +0 -0
  29. data/spec/dummy/tmp/cache/assets/CB8/880/sprockets%2F3b651a5763758db2fc0347488e69a3e1 +0 -0
  30. data/spec/dummy/tmp/cache/assets/CBA/0A0/sprockets%2F2983f7dd6130a7c24892da333c18d779 +0 -0
  31. data/spec/dummy/tmp/cache/assets/CD0/CA0/sprockets%2F719e10ea5f5b1c20b6518a1d3432774e +0 -0
  32. data/spec/dummy/tmp/cache/assets/CD1/EB0/sprockets%2Fba17700b36ee975c05d06042a6af9631 +0 -0
  33. data/spec/dummy/tmp/cache/assets/CD5/8B0/sprockets%2F31178c43077cb48bfc81217ad0872cd1 +0 -0
  34. data/spec/dummy/tmp/cache/assets/CDA/A30/sprockets%2Fd1a7692303d59c495dd61cd1d41246b5 +0 -0
  35. data/spec/dummy/tmp/cache/assets/CDD/D20/sprockets%2F070d2bf7a81574ee0e560e174737a17f +0 -0
  36. data/spec/dummy/tmp/cache/assets/CE0/CD0/sprockets%2Fd206c4ec51748382823dee1e7f28055a +0 -0
  37. data/spec/dummy/tmp/cache/assets/CE3/690/sprockets%2F9531c78d64b8651a60dd128573bbe7e1 +0 -0
  38. data/spec/dummy/tmp/cache/assets/CE3/C10/sprockets%2F05a63f093f971cd73662695fab452b0f +0 -0
  39. data/spec/dummy/tmp/cache/assets/CE7/770/sprockets%2F56570f527d86457c48485cedb2d1c30c +0 -0
  40. data/spec/dummy/tmp/cache/assets/CEE/2B0/sprockets%2F75f58ee42279991f91ac43260b9b0fe3 +0 -0
  41. data/spec/dummy/tmp/cache/assets/CF2/E60/sprockets%2F6cf94481464e607960899cc38adac2b6 +0 -0
  42. data/spec/dummy/tmp/cache/assets/D09/2D0/sprockets%2F731ea2f82a086d10ff127d30c994f53b +0 -0
  43. data/spec/dummy/tmp/cache/assets/D0D/000/sprockets%2Fbb689a9183e1482be8c02ab4f536083b +0 -0
  44. data/spec/dummy/tmp/cache/assets/D13/FF0/sprockets%2Fd62e2814c718d1a22c84c7b3a78eb948 +0 -0
  45. data/spec/dummy/tmp/cache/assets/D16/BA0/sprockets%2F141f6d67a3871387dc3a1a9963de0de7 +0 -0
  46. data/spec/dummy/tmp/cache/assets/D17/DD0/sprockets%2F04f75f0ecb38c984675d23a9144d2be7 +0 -0
  47. data/spec/dummy/tmp/cache/assets/D1A/140/sprockets%2Fe5dbcc46887452182b85e8da04994ea0 +0 -0
  48. data/spec/dummy/tmp/cache/assets/D1F/620/sprockets%2F5eb71efe5276c4b5c148cd75958e2760 +0 -0
  49. data/spec/dummy/tmp/cache/assets/D23/570/sprockets%2Fb79b2bd85b952ef68724f54e3344dd66 +0 -0
  50. data/spec/dummy/tmp/cache/assets/D26/4D0/sprockets%2Faa9fd545084f66b324662ca8f48c88f9 +0 -0
  51. data/spec/dummy/tmp/cache/assets/D27/2F0/sprockets%2F6b6e52b5006574d3fef8d34ef639978d +0 -0
  52. data/spec/dummy/tmp/cache/assets/D30/ED0/sprockets%2Fea74cc14e1532ac70f928d8d205c5a13 +0 -0
  53. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  54. data/spec/dummy/tmp/cache/assets/D33/E40/sprockets%2F06b596c4052fc9ad352a54ac0871cf2c +0 -0
  55. data/spec/dummy/tmp/cache/assets/D3B/4D0/sprockets%2Faf8a08611a00ade8c7f16d626708eb67 +0 -0
  56. data/spec/dummy/tmp/cache/assets/D3E/740/sprockets%2F62194496bd7f322f3b2f6f2bf602e1fb +0 -0
  57. data/spec/dummy/tmp/cache/assets/D3F/170/sprockets%2F13df698b0cd7e1f7045913a1c6a96cc4 +0 -0
  58. data/spec/dummy/tmp/cache/assets/D3F/7C0/sprockets%2F42286191d1dec5e46ae8f89a0af0d147 +0 -0
  59. data/spec/dummy/tmp/cache/assets/D40/720/sprockets%2Fe798537f2ae8abbbac509070c9e06506 +0 -0
  60. data/spec/dummy/tmp/cache/assets/D45/CF0/sprockets%2F577ac52ab81ab676640dda59969cce32 +0 -0
  61. data/spec/dummy/tmp/cache/assets/D47/1D0/sprockets%2F904ef275b101c77ee529b4fe7cf323f7 +0 -0
  62. data/spec/dummy/tmp/cache/assets/D4A/D90/sprockets%2F4f476e9f41ff71e1045d03fc36de6c66 +0 -0
  63. data/spec/dummy/tmp/cache/assets/D4C/EE0/sprockets%2F7ee487bf0d625668f3fcb075c89a420d +0 -0
  64. data/spec/dummy/tmp/cache/assets/D54/ED0/sprockets%2F71c9fa01091d432b131da3bb73faf3d4 +0 -0
  65. data/spec/dummy/tmp/cache/assets/D60/DB0/sprockets%2Fb2b29acaab38e7049fd950a381e05f11 +0 -0
  66. data/spec/dummy/tmp/cache/assets/D68/450/sprockets%2F7290abaa3947f361fb72cb333692beaf +0 -0
  67. data/spec/dummy/tmp/cache/assets/D69/910/sprockets%2F05abeb33740bac77bef60b5445695c8c +0 -0
  68. data/spec/dummy/tmp/cache/assets/D6B/230/sprockets%2F744429c3ae6d8aadf46550ee21cc58b1 +0 -0
  69. data/spec/dummy/tmp/cache/assets/D6C/7E0/sprockets%2Fd3abe581052fc2ffd33b9f465b477b14 +0 -0
  70. data/spec/dummy/tmp/cache/assets/D70/280/sprockets%2F99a543e2b6be1d37c3ccc8a90261f87a +0 -0
  71. data/spec/dummy/tmp/cache/assets/D70/330/sprockets%2F292913c88244b67cdb46da1eed327fda +0 -0
  72. data/spec/dummy/tmp/cache/assets/D71/520/sprockets%2F018fdf705225eaa53bc9c287ebd68c91 +0 -0
  73. data/spec/dummy/tmp/cache/assets/D71/5D0/sprockets%2Fc8e0dae5e23b4b3941152e3b87e7f7c6 +0 -0
  74. data/spec/dummy/tmp/cache/assets/D73/830/sprockets%2F38d93d829b7d163c372f3acd557c2eab +0 -0
  75. data/spec/dummy/tmp/cache/assets/D74/120/sprockets%2Ffbe442bef82371edd6525fe5622de319 +0 -0
  76. data/spec/dummy/tmp/cache/assets/D77/7C0/sprockets%2Fcf660249e6eb81370e70cfe24d771dfe +0 -0
  77. data/spec/dummy/tmp/cache/assets/D7C/660/sprockets%2Fbb4ce966494c0b544c7ea5f4e9c2b866 +0 -0
  78. data/spec/dummy/tmp/cache/assets/D84/210/sprockets%2Fabd0103ccec2b428ac62c94e4c40b384 +0 -0
  79. data/spec/dummy/tmp/cache/assets/D87/FA0/sprockets%2Fed7ffae98375a3c9819ee641f00e388d +0 -0
  80. data/spec/dummy/tmp/cache/assets/D92/E50/sprockets%2F09a8ce459d99efe497507cad2ed88f56 +0 -0
  81. data/spec/dummy/tmp/cache/assets/D93/670/sprockets%2Fdf4cd8447459d7b31b077d0af7aba00b +0 -0
  82. data/spec/dummy/tmp/cache/assets/D94/0C0/sprockets%2Fac68f40dcce2850b0fdd7dfb91505115 +0 -0
  83. data/spec/dummy/tmp/cache/assets/D96/AE0/sprockets%2F6c450fd116d891f54a32bcfcbd4b762b +0 -0
  84. data/spec/dummy/tmp/cache/assets/DA2/0E0/sprockets%2F71a404ff712a059b23edee96c9bfcd75 +0 -0
  85. data/spec/dummy/tmp/cache/assets/DA6/860/sprockets%2Ff5526cc6647cdd14b05aed999377abbc +0 -0
  86. data/spec/dummy/tmp/cache/assets/DA7/5F0/sprockets%2Fe92688bcadd7fcddd86227c04b9712e1 +0 -0
  87. data/spec/dummy/tmp/cache/assets/DA7/6A0/sprockets%2Fa6745bdd80053c25a9ee2d81e96adef9 +0 -0
  88. data/spec/dummy/tmp/cache/assets/DA9/890/sprockets%2Fd1501c9a42bbc34f0cc11eae60b2e22e +0 -0
  89. data/spec/dummy/tmp/cache/assets/DB7/5A0/sprockets%2Fd2fac77222901b5da4abcf1c225d91db +0 -0
  90. data/spec/dummy/tmp/cache/assets/DBE/A90/sprockets%2F40e8db6da00eac4d36841aa33ff46fb3 +0 -0
  91. data/spec/dummy/tmp/cache/assets/DC6/E60/sprockets%2F415f6a64519b7c8ae296dbbafeb105ba +0 -0
  92. data/spec/dummy/tmp/cache/assets/DC8/660/sprockets%2Fbafd7b9ed0b0c06ed5e283463ad4c547 +0 -0
  93. data/spec/dummy/tmp/cache/assets/DCA/BB0/sprockets%2F1a792cae50966aef0d0d4131fe5fafd9 +0 -0
  94. data/spec/dummy/tmp/cache/assets/DD0/D40/sprockets%2Fc5ad6e6949709508d0dbdb0b1a7ecbe9 +0 -0
  95. data/spec/dummy/tmp/cache/assets/DD9/E90/sprockets%2Fd44526e0ec17dcbbccf7e14db768e869 +0 -0
  96. data/spec/dummy/tmp/cache/assets/DDC/270/sprockets%2Fadb8f369db4f8784c76fd2ee1d3633ac +0 -0
  97. data/spec/dummy/tmp/cache/assets/DDE/420/sprockets%2F69cf180e779eb3095cebe85edbfc22b7 +0 -0
  98. data/spec/dummy/tmp/cache/assets/DE0/250/sprockets%2F1559ff83d17dd6b788d6ab7fada65ee1 +0 -0
  99. data/spec/dummy/tmp/cache/assets/DE1/B40/sprockets%2F9c7deec5e90b5957c6d5b31ded7fe074 +0 -0
  100. data/spec/dummy/tmp/cache/assets/DFB/2A0/sprockets%2F801140d7903bfebe6accecc7fc9f71e2 +0 -0
  101. data/spec/dummy/tmp/cache/assets/E01/830/sprockets%2F3359db498c5ca08b6ff0a5fe54c8acda +0 -0
  102. data/spec/dummy/tmp/cache/assets/E04/7E0/sprockets%2Fee9c0f735fc2fed82f00e66fa71bc91d +0 -0
  103. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  104. data/spec/dummy/tmp/cache/assets/E32/C40/sprockets%2Faade2bb8a94be3f057fe7d4a6fd65a84 +0 -0
  105. data/spec/dummy/tmp/cache/assets/E51/940/sprockets%2F5c78b0ffb0472ccdce1fea8dad2142bf +0 -0
  106. data/spec/dummy/tmp/cache/assets/E70/2B0/sprockets%2F7eedcfada8bf8bff28c96d9ea93521d3 +0 -0
  107. data/spec/dummy/tmp/pids/server.pid +1 -0
  108. data/vendor/assets/javascripts/codemirror/codemirror.js +2164 -0
  109. data/vendor/assets/javascripts/codemirror/modes/css.js +124 -0
  110. data/vendor/assets/javascripts/codemirror/modes/javascript.js +348 -0
  111. data/vendor/assets/javascripts/codemirror/overlay.js +51 -0
  112. data/vendor/assets/javascripts/codemirror/runmode.js +27 -0
  113. data/vendor/assets/stylesheets/codemirror/codemirror.css +68 -0
  114. data/vendor/assets/stylesheets/codemirror/themes/cobalt.css +17 -0
  115. data/vendor/assets/stylesheets/codemirror/themes/default.css +19 -0
  116. data/vendor/assets/stylesheets/codemirror/themes/elegant.css +9 -0
  117. data/vendor/assets/stylesheets/codemirror/themes/neat.css +8 -0
  118. data/vendor/assets/stylesheets/codemirror/themes/night.css +20 -0
  119. metadata +194 -18
  120. data/lib/generators/page_engine/page_engine_generator.rb +0 -60
@@ -0,0 +1,124 @@
1
+ CodeMirror.defineMode("css", function(config) {
2
+ var indentUnit = config.indentUnit, type;
3
+ function ret(style, tp) {type = tp; return style;}
4
+
5
+ function tokenBase(stream, state) {
6
+ var ch = stream.next();
7
+ if (ch == "@") {stream.eatWhile(/\w/); return ret("meta", stream.current());}
8
+ else if (ch == "/" && stream.eat("*")) {
9
+ state.tokenize = tokenCComment;
10
+ return tokenCComment(stream, state);
11
+ }
12
+ else if (ch == "<" && stream.eat("!")) {
13
+ state.tokenize = tokenSGMLComment;
14
+ return tokenSGMLComment(stream, state);
15
+ }
16
+ else if (ch == "=") ret(null, "compare");
17
+ else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
18
+ else if (ch == "\"" || ch == "'") {
19
+ state.tokenize = tokenString(ch);
20
+ return state.tokenize(stream, state);
21
+ }
22
+ else if (ch == "#") {
23
+ stream.eatWhile(/\w/);
24
+ return ret("atom", "hash");
25
+ }
26
+ else if (ch == "!") {
27
+ stream.match(/^\s*\w*/);
28
+ return ret("keyword", "important");
29
+ }
30
+ else if (/\d/.test(ch)) {
31
+ stream.eatWhile(/[\w.%]/);
32
+ return ret("number", "unit");
33
+ }
34
+ else if (/[,.+>*\/]/.test(ch)) {
35
+ return ret(null, "select-op");
36
+ }
37
+ else if (/[;{}:\[\]]/.test(ch)) {
38
+ return ret(null, ch);
39
+ }
40
+ else {
41
+ stream.eatWhile(/[\w\\\-_]/);
42
+ return ret("variable", "variable");
43
+ }
44
+ }
45
+
46
+ function tokenCComment(stream, state) {
47
+ var maybeEnd = false, ch;
48
+ while ((ch = stream.next()) != null) {
49
+ if (maybeEnd && ch == "/") {
50
+ state.tokenize = tokenBase;
51
+ break;
52
+ }
53
+ maybeEnd = (ch == "*");
54
+ }
55
+ return ret("comment", "comment");
56
+ }
57
+
58
+ function tokenSGMLComment(stream, state) {
59
+ var dashes = 0, ch;
60
+ while ((ch = stream.next()) != null) {
61
+ if (dashes >= 2 && ch == ">") {
62
+ state.tokenize = tokenBase;
63
+ break;
64
+ }
65
+ dashes = (ch == "-") ? dashes + 1 : 0;
66
+ }
67
+ return ret("comment", "comment");
68
+ }
69
+
70
+ function tokenString(quote) {
71
+ return function(stream, state) {
72
+ var escaped = false, ch;
73
+ while ((ch = stream.next()) != null) {
74
+ if (ch == quote && !escaped)
75
+ break;
76
+ escaped = !escaped && ch == "\\";
77
+ }
78
+ if (!escaped) state.tokenize = tokenBase;
79
+ return ret("string", "string");
80
+ };
81
+ }
82
+
83
+ return {
84
+ startState: function(base) {
85
+ return {tokenize: tokenBase,
86
+ baseIndent: base || 0,
87
+ stack: []};
88
+ },
89
+
90
+ token: function(stream, state) {
91
+ if (stream.eatSpace()) return null;
92
+ var style = state.tokenize(stream, state);
93
+
94
+ var context = state.stack[state.stack.length-1];
95
+ if (type == "hash" && context == "rule") style = "atom";
96
+ else if (style == "variable") {
97
+ if (context == "rule") style = "number";
98
+ else if (!context || context == "@media{") style = "tag";
99
+ }
100
+
101
+ if (context == "rule" && /^[\{\};]$/.test(type))
102
+ state.stack.pop();
103
+ if (type == "{") {
104
+ if (context == "@media") state.stack[state.stack.length-1] = "@media{";
105
+ else state.stack.push("{");
106
+ }
107
+ else if (type == "}") state.stack.pop();
108
+ else if (type == "@media") state.stack.push("@media");
109
+ else if (context == "{" && type != "comment") state.stack.push("rule");
110
+ return style;
111
+ },
112
+
113
+ indent: function(state, textAfter) {
114
+ var n = state.stack.length;
115
+ if (/^\}/.test(textAfter))
116
+ n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1;
117
+ return state.baseIndent + n * indentUnit;
118
+ },
119
+
120
+ electricChars: "}"
121
+ };
122
+ });
123
+
124
+ CodeMirror.defineMIME("text/css", "css");
@@ -0,0 +1,348 @@
1
+ CodeMirror.defineMode("javascript", function(config, parserConfig) {
2
+ var indentUnit = config.indentUnit;
3
+ var jsonMode = parserConfig.json;
4
+
5
+ // Tokenizer
6
+
7
+ var keywords = function(){
8
+ function kw(type) {return {type: type, style: "keyword"};}
9
+ var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
10
+ var operator = kw("operator"), atom = {type: "atom", style: "atom"};
11
+ return {
12
+ "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
13
+ "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
14
+ "var": kw("var"), "function": kw("function"), "catch": kw("catch"),
15
+ "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
16
+ "in": operator, "typeof": operator, "instanceof": operator,
17
+ "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
18
+ };
19
+ }();
20
+
21
+ var isOperatorChar = /[+\-*&%=<>!?|]/;
22
+
23
+ function chain(stream, state, f) {
24
+ state.tokenize = f;
25
+ return f(stream, state);
26
+ }
27
+
28
+ function nextUntilUnescaped(stream, end) {
29
+ var escaped = false, next;
30
+ while ((next = stream.next()) != null) {
31
+ if (next == end && !escaped)
32
+ return false;
33
+ escaped = !escaped && next == "\\";
34
+ }
35
+ return escaped;
36
+ }
37
+
38
+ // Used as scratch variables to communicate multiple values without
39
+ // consing up tons of objects.
40
+ var type, content;
41
+ function ret(tp, style, cont) {
42
+ type = tp; content = cont;
43
+ return style;
44
+ }
45
+
46
+ function jsTokenBase(stream, state) {
47
+ var ch = stream.next();
48
+ if (ch == '"' || ch == "'")
49
+ return chain(stream, state, jsTokenString(ch));
50
+ else if (/[\[\]{}\(\),;\:\.]/.test(ch))
51
+ return ret(ch);
52
+ else if (ch == "0" && stream.eat(/x/i)) {
53
+ stream.eatWhile(/[\da-f]/i);
54
+ return ret("number", "number");
55
+ }
56
+ else if (/\d/.test(ch)) {
57
+ stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/);
58
+ return ret("number", "number");
59
+ }
60
+ else if (ch == "/") {
61
+ if (stream.eat("*")) {
62
+ return chain(stream, state, jsTokenComment);
63
+ }
64
+ else if (stream.eat("/")) {
65
+ stream.skipToEnd();
66
+ return ret("comment", "comment");
67
+ }
68
+ else if (state.reAllowed) {
69
+ nextUntilUnescaped(stream, "/");
70
+ stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
71
+ return ret("regexp", "string");
72
+ }
73
+ else {
74
+ stream.eatWhile(isOperatorChar);
75
+ return ret("operator", null, stream.current());
76
+ }
77
+ }
78
+ else if (isOperatorChar.test(ch)) {
79
+ stream.eatWhile(isOperatorChar);
80
+ return ret("operator", null, stream.current());
81
+ }
82
+ else {
83
+ stream.eatWhile(/[\w\$_]/);
84
+ var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
85
+ return known ? ret(known.type, known.style, word) :
86
+ ret("variable", "variable", word);
87
+ }
88
+ }
89
+
90
+ function jsTokenString(quote) {
91
+ return function(stream, state) {
92
+ if (!nextUntilUnescaped(stream, quote))
93
+ state.tokenize = jsTokenBase;
94
+ return ret("string", "string");
95
+ };
96
+ }
97
+
98
+ function jsTokenComment(stream, state) {
99
+ var maybeEnd = false, ch;
100
+ while (ch = stream.next()) {
101
+ if (ch == "/" && maybeEnd) {
102
+ state.tokenize = jsTokenBase;
103
+ break;
104
+ }
105
+ maybeEnd = (ch == "*");
106
+ }
107
+ return ret("comment", "comment");
108
+ }
109
+
110
+ // Parser
111
+
112
+ var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
113
+
114
+ function JSLexical(indented, column, type, align, prev, info) {
115
+ this.indented = indented;
116
+ this.column = column;
117
+ this.type = type;
118
+ this.prev = prev;
119
+ this.info = info;
120
+ if (align != null) this.align = align;
121
+ }
122
+
123
+ function inScope(state, varname) {
124
+ for (var v = state.localVars; v; v = v.next)
125
+ if (v.name == varname) return true;
126
+ }
127
+
128
+ function parseJS(state, style, type, content, stream) {
129
+ var cc = state.cc;
130
+ // Communicate our context to the combinators.
131
+ // (Less wasteful than consing up a hundred closures on every call.)
132
+ cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
133
+
134
+ if (!state.lexical.hasOwnProperty("align"))
135
+ state.lexical.align = true;
136
+
137
+ while(true) {
138
+ var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
139
+ if (combinator(type, content)) {
140
+ while(cc.length && cc[cc.length - 1].lex)
141
+ cc.pop()();
142
+ if (cx.marked) return cx.marked;
143
+ if (type == "variable" && inScope(state, content)) return "variable-2";
144
+ return style;
145
+ }
146
+ }
147
+ }
148
+
149
+ // Combinator utils
150
+
151
+ var cx = {state: null, column: null, marked: null, cc: null};
152
+ function pass() {
153
+ for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
154
+ }
155
+ function cont() {
156
+ pass.apply(null, arguments);
157
+ return true;
158
+ }
159
+ function register(varname) {
160
+ var state = cx.state;
161
+ if (state.context) {
162
+ cx.marked = "def";
163
+ for (var v = state.localVars; v; v = v.next)
164
+ if (v.name == varname) return;
165
+ state.localVars = {name: varname, next: state.localVars};
166
+ }
167
+ }
168
+
169
+ // Combinators
170
+
171
+ var defaultVars = {name: "this", next: {name: "arguments"}};
172
+ function pushcontext() {
173
+ if (!cx.state.context) cx.state.localVars = defaultVars;
174
+ cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
175
+ }
176
+ function popcontext() {
177
+ cx.state.localVars = cx.state.context.vars;
178
+ cx.state.context = cx.state.context.prev;
179
+ }
180
+ function pushlex(type, info) {
181
+ var result = function() {
182
+ var state = cx.state;
183
+ state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info)
184
+ };
185
+ result.lex = true;
186
+ return result;
187
+ }
188
+ function poplex() {
189
+ var state = cx.state;
190
+ if (state.lexical.prev) {
191
+ if (state.lexical.type == ")")
192
+ state.indented = state.lexical.indented;
193
+ state.lexical = state.lexical.prev;
194
+ }
195
+ }
196
+ poplex.lex = true;
197
+
198
+ function expect(wanted) {
199
+ return function expecting(type) {
200
+ if (type == wanted) return cont();
201
+ else if (wanted == ";") return pass();
202
+ else return cont(arguments.callee);
203
+ };
204
+ }
205
+
206
+ function statement(type) {
207
+ if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
208
+ if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
209
+ if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
210
+ if (type == "{") return cont(pushlex("}"), block, poplex);
211
+ if (type == ";") return cont();
212
+ if (type == "function") return cont(functiondef);
213
+ if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
214
+ poplex, statement, poplex);
215
+ if (type == "variable") return cont(pushlex("stat"), maybelabel);
216
+ if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
217
+ block, poplex, poplex);
218
+ if (type == "case") return cont(expression, expect(":"));
219
+ if (type == "default") return cont(expect(":"));
220
+ if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
221
+ statement, poplex, popcontext);
222
+ return pass(pushlex("stat"), expression, expect(";"), poplex);
223
+ }
224
+ function expression(type) {
225
+ if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
226
+ if (type == "function") return cont(functiondef);
227
+ if (type == "keyword c") return cont(expression);
228
+ if (type == "(") return cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator);
229
+ if (type == "operator") return cont(expression);
230
+ if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
231
+ if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
232
+ return cont();
233
+ }
234
+ function maybeoperator(type, value) {
235
+ if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
236
+ if (type == "operator") return cont(expression);
237
+ if (type == ";") return;
238
+ if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
239
+ if (type == ".") return cont(property, maybeoperator);
240
+ if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
241
+ }
242
+ function maybelabel(type) {
243
+ if (type == ":") return cont(poplex, statement);
244
+ return pass(maybeoperator, expect(";"), poplex);
245
+ }
246
+ function property(type) {
247
+ if (type == "variable") {cx.marked = "property"; return cont();}
248
+ }
249
+ function objprop(type) {
250
+ if (type == "variable") cx.marked = "property";
251
+ if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
252
+ }
253
+ function commasep(what, end) {
254
+ function proceed(type) {
255
+ if (type == ",") return cont(what, proceed);
256
+ if (type == end) return cont();
257
+ return cont(expect(end));
258
+ }
259
+ return function commaSeparated(type) {
260
+ if (type == end) return cont();
261
+ else return pass(what, proceed);
262
+ };
263
+ }
264
+ function block(type) {
265
+ if (type == "}") return cont();
266
+ return pass(statement, block);
267
+ }
268
+ function vardef1(type, value) {
269
+ if (type == "variable"){register(value); return cont(vardef2);}
270
+ return cont();
271
+ }
272
+ function vardef2(type, value) {
273
+ if (value == "=") return cont(expression, vardef2);
274
+ if (type == ",") return cont(vardef1);
275
+ }
276
+ function forspec1(type) {
277
+ if (type == "var") return cont(vardef1, forspec2);
278
+ if (type == ";") return pass(forspec2);
279
+ if (type == "variable") return cont(formaybein);
280
+ return pass(forspec2);
281
+ }
282
+ function formaybein(type, value) {
283
+ if (value == "in") return cont(expression);
284
+ return cont(maybeoperator, forspec2);
285
+ }
286
+ function forspec2(type, value) {
287
+ if (type == ";") return cont(forspec3);
288
+ if (value == "in") return cont(expression);
289
+ return cont(expression, expect(";"), forspec3);
290
+ }
291
+ function forspec3(type) {
292
+ if (type != ")") cont(expression);
293
+ }
294
+ function functiondef(type, value) {
295
+ if (type == "variable") {register(value); return cont(functiondef);}
296
+ if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
297
+ }
298
+ function funarg(type, value) {
299
+ if (type == "variable") {register(value); return cont();}
300
+ }
301
+
302
+ // Interface
303
+
304
+ return {
305
+ startState: function(basecolumn) {
306
+ return {
307
+ tokenize: jsTokenBase,
308
+ reAllowed: true,
309
+ cc: [],
310
+ lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
311
+ localVars: null,
312
+ context: null,
313
+ indented: 0
314
+ };
315
+ },
316
+
317
+ token: function(stream, state) {
318
+ if (stream.sol()) {
319
+ if (!state.lexical.hasOwnProperty("align"))
320
+ state.lexical.align = false;
321
+ state.indented = stream.indentation();
322
+ }
323
+ if (stream.eatSpace()) return null;
324
+ var style = state.tokenize(stream, state);
325
+ if (type == "comment") return style;
326
+ state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/);
327
+ return parseJS(state, style, type, content, stream);
328
+ },
329
+
330
+ indent: function(state, textAfter) {
331
+ if (state.tokenize != jsTokenBase) return 0;
332
+ var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
333
+ type = lexical.type, closing = firstChar == type;
334
+ if (type == "vardef") return lexical.indented + 4;
335
+ else if (type == "form" && firstChar == "{") return lexical.indented;
336
+ else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
337
+ else if (lexical.info == "switch" && !closing)
338
+ return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
339
+ else if (lexical.align) return lexical.column + (closing ? 0 : 1);
340
+ else return lexical.indented + (closing ? 0 : indentUnit);
341
+ },
342
+
343
+ electricChars: ":{}"
344
+ };
345
+ });
346
+
347
+ CodeMirror.defineMIME("text/javascript", "javascript");
348
+ CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
@@ -0,0 +1,51 @@
1
+ // Utility function that allows modes to be combined. The mode given
2
+ // as the base argument takes care of most of the normal mode
3
+ // functionality, but a second (typically simple) mode is used, which
4
+ // can override the style of text. Both modes get to parse all of the
5
+ // text, but when both assign a non-null style to a piece of code, the
6
+ // overlay wins, unless the combine argument was true, in which case
7
+ // the styles are combined.
8
+
9
+ CodeMirror.overlayParser = function(base, overlay, combine) {
10
+ return {
11
+ startState: function() {
12
+ return {
13
+ base: CodeMirror.startState(base),
14
+ overlay: CodeMirror.startState(overlay),
15
+ basePos: 0, baseCur: null,
16
+ overlayPos: 0, overlayCur: null
17
+ };
18
+ },
19
+ copyState: function(state) {
20
+ return {
21
+ base: CodeMirror.copyState(base, state.base),
22
+ overlay: CodeMirror.copyState(overlay, state.overlay),
23
+ basePos: state.basePos, baseCur: null,
24
+ overlayPos: state.overlayPos, overlayCur: null
25
+ };
26
+ },
27
+
28
+ token: function(stream, state) {
29
+ if (stream.start == state.basePos) {
30
+ state.baseCur = base.token(stream, state.base);
31
+ state.basePos = stream.pos;
32
+ }
33
+ if (stream.start == state.overlayPos) {
34
+ stream.pos = stream.start;
35
+ state.overlayCur = overlay.token(stream, state.overlay);
36
+ state.overlayPos = stream.pos;
37
+ }
38
+ stream.pos = Math.min(state.basePos, state.overlayPos);
39
+ if (stream.eol()) state.basePos = state.overlayPos = 0;
40
+
41
+ if (state.overlayCur == null) return state.baseCur;
42
+ if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur;
43
+ else return state.overlayCur;
44
+ },
45
+
46
+ indent: function(state, textAfter) {
47
+ return base.indent(state.base, textAfter);
48
+ },
49
+ electricChars: base.electricChars
50
+ };
51
+ };
@@ -0,0 +1,27 @@
1
+ CodeMirror.runMode = function(string, modespec, callback) {
2
+ var mode = CodeMirror.getMode({indentUnit: 2}, modespec);
3
+ var isNode = callback.nodeType == 1;
4
+ if (isNode) {
5
+ var node = callback, accum = [];
6
+ callback = function(string, style) {
7
+ if (string == "\n")
8
+ accum.push("<br>");
9
+ else if (style)
10
+ accum.push("<span class=\"cm-" + CodeMirror.htmlEscape(style) + "\">" + CodeMirror.htmlEscape(string) + "</span>");
11
+ else
12
+ accum.push(CodeMirror.htmlEscape(string));
13
+ }
14
+ }
15
+ var lines = CodeMirror.splitLines(string), state = CodeMirror.startState(mode);
16
+ for (var i = 0, e = lines.length; i < e; ++i) {
17
+ if (i) callback("\n");
18
+ var stream = new CodeMirror.StringStream(lines[i]);
19
+ while (!stream.eol()) {
20
+ var style = mode.token(stream, state);
21
+ callback(stream.current(), style);
22
+ stream.start = stream.pos;
23
+ }
24
+ }
25
+ if (isNode)
26
+ node.innerHTML = accum.join("");
27
+ };
@@ -0,0 +1,68 @@
1
+ .CodeMirror {
2
+ line-height: 1em;
3
+ font-family: monospace;
4
+ }
5
+
6
+ .CodeMirror-scroll {
7
+ overflow: auto;
8
+ height: 300px;
9
+ /* This is needed to prevent an IE[67] bug where the scrolled content
10
+ is visible outside of the scrolling box. */
11
+ position: relative;
12
+ }
13
+
14
+ .CodeMirror-gutter {
15
+ position: absolute; left: 0; top: 0;
16
+ z-index: 10;
17
+ background-color: #f7f7f7;
18
+ border-right: 1px solid #eee;
19
+ min-width: 2em;
20
+ height: 100%;
21
+ }
22
+ .CodeMirror-gutter-text {
23
+ color: #aaa;
24
+ text-align: right;
25
+ padding: .4em .2em .4em .4em;
26
+ }
27
+ .CodeMirror-lines {
28
+ padding: .4em;
29
+ }
30
+
31
+ .CodeMirror pre {
32
+ -moz-border-radius: 0;
33
+ -webkit-border-radius: 0;
34
+ -o-border-radius: 0;
35
+ border-radius: 0;
36
+ border-width: 0; margin: 0; padding: 0; background: transparent;
37
+ font-family: inherit;
38
+ font-size: inherit;
39
+ padding: 0; margin: 0;
40
+ white-space: pre;
41
+ word-wrap: normal;
42
+ }
43
+
44
+ .CodeMirror textarea {
45
+ font-family: inherit !important;
46
+ font-size: inherit !important;
47
+ }
48
+
49
+ .CodeMirror-cursor {
50
+ z-index: 10;
51
+ position: absolute;
52
+ visibility: hidden;
53
+ border-left: 1px solid black !important;
54
+ }
55
+ .CodeMirror-focused .CodeMirror-cursor {
56
+ visibility: visible;
57
+ }
58
+
59
+ span.CodeMirror-selected {
60
+ background: #ccc !important;
61
+ color: HighlightText !important;
62
+ }
63
+ .CodeMirror-focused span.CodeMirror-selected {
64
+ background: Highlight !important;
65
+ }
66
+
67
+ .CodeMirror-matchingbracket {color: #0f0 !important;}
68
+ .CodeMirror-nonmatchingbracket {color: #f22 !important;}
@@ -0,0 +1,17 @@
1
+ .cm-s-cobalt { background: #002240; color: white; }
2
+ .cm-s-cobalt span.CodeMirror-selected { background: #b36539 !important; }
3
+ .cm-s-cobalt .CodeMirror-gutter { background: #002240; border-right: 1px solid #aaa; }
4
+ .cm-s-cobalt .CodeMirror-gutter-text { color: #d0d0d0; }
5
+ .cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white !important; }
6
+
7
+ .cm-s-cobalt span.cm-comment { color: #08f; }
8
+ .cm-s-cobalt span.cm-atom { color: #845dc4; }
9
+ .cm-s-cobalt span.cm-number, .cm-s-cobalt span.cm-attribute { color: #ff80e1; }
10
+ .cm-s-cobalt span.cm-keyword { color: #ffee80; }
11
+ .cm-s-cobalt span.cm-string { color: #3ad900; }
12
+ .cm-s-cobalt span.cm-meta { color: #ff9d00; }
13
+ .cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; }
14
+ .cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def { color: white; }
15
+ .cm-s-cobalt span.cm-error { color: #9d1e15; }
16
+ .cm-s-cobalt span.cm-bracket { color: #d8d8d8; }
17
+ .cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; }
@@ -0,0 +1,19 @@
1
+ .cm-s-default span.cm-keyword {color: #708;}
2
+ .cm-s-default span.cm-atom {color: #219;}
3
+ .cm-s-default span.cm-number {color: #164;}
4
+ .cm-s-default span.cm-def {color: #00f;}
5
+ .cm-s-default span.cm-variable {color: black;}
6
+ .cm-s-default span.cm-variable-2 {color: #05a;}
7
+ .cm-s-default span.cm-variable-3 {color: #0a5;}
8
+ .cm-s-default span.cm-property {color: black;}
9
+ .cm-s-default span.cm-operator {color: black;}
10
+ .cm-s-default span.cm-comment {color: #a50;}
11
+ .cm-s-default span.cm-string {color: #a11;}
12
+ .cm-s-default span.cm-string-2 {color: #f50;}
13
+ .cm-s-default span.cm-meta {color: #555;}
14
+ .cm-s-default span.cm-error {color: #f00;}
15
+ .cm-s-default span.cm-qualifier {color: #555;}
16
+ .cm-s-default span.cm-builtin {color: #30a;}
17
+ .cm-s-default span.cm-bracket {color: #cc7;}
18
+ .cm-s-default span.cm-tag {color: #170;}
19
+ .cm-s-default span.cm-attribute {color: #00c;}
@@ -0,0 +1,9 @@
1
+ .cm-s-elegant span.cm-number, .cm-s-elegant span.cm-string, .cm-s-elegant span.cm-atom {color: #762;}
2
+ .cm-s-elegant span.cm-comment {color: #262;font-style: italic;}
3
+ .cm-s-elegant span.cm-meta {color: #555;font-style: italic;}
4
+ .cm-s-elegant span.cm-variable {color: black;}
5
+ .cm-s-elegant span.cm-variable-2 {color: #b11;}
6
+ .cm-s-elegant span.cm-qualifier {color: #555;}
7
+ .cm-s-elegant span.cm-keyword {color: #730;}
8
+ .cm-s-elegant span.cm-builtin {color: #30a;}
9
+ .cm-s-elegant span.cm-error {background-color: #fdd;}
@@ -0,0 +1,8 @@
1
+ .cm-s-neat span.cm-comment { color: #a86; }
2
+ .cm-s-neat span.cm-keyword { font-weight: bold; color: blue; }
3
+ .cm-s-neat span.cm-string { color: #a22; }
4
+ .cm-s-neat span.cm-builtin { font-weight: bold; color: #077; }
5
+ .cm-s-neat span.cm-special { font-weight: bold; color: #0aa; }
6
+ .cm-s-neat span.cm-variable { color: black; }
7
+ .cm-s-neat span.cm-number, .cm-s-neat span.cm-atom { color: #3a3; }
8
+ .cm-s-neat span.cm-meta {color: #555;}