puffer_pages 0.0.18 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/Gemfile.lock +41 -51
  2. data/VERSION +1 -1
  3. data/app/assets/javascripts/puffer/codemirror.js +2197 -0
  4. data/app/assets/javascripts/puffer/codemirror/css.js +124 -0
  5. data/app/assets/javascripts/puffer/codemirror/htmlmixed.js +84 -0
  6. data/app/assets/javascripts/puffer/codemirror/javascript.js +352 -0
  7. data/app/assets/javascripts/puffer/codemirror/xml.js +231 -0
  8. data/app/assets/javascripts/puffer/overlay.js +51 -0
  9. data/app/assets/javascripts/{puffer_pages → puffer}/puffer_pages.js +21 -11
  10. data/app/assets/javascripts/{puffer_pages → puffer}/right-tabs-src.js +0 -0
  11. data/app/assets/stylesheets/puffer/codemirror.css +68 -0
  12. data/app/assets/stylesheets/puffer/codemirror/cobalt.css +17 -0
  13. data/app/assets/stylesheets/puffer/codemirror/default.css +19 -0
  14. data/app/assets/stylesheets/puffer/codemirror/eclipse.css +24 -0
  15. data/app/assets/stylesheets/puffer/codemirror/elegant.css +9 -0
  16. data/app/assets/stylesheets/puffer/codemirror/neat.css +8 -0
  17. data/app/assets/stylesheets/puffer/codemirror/night.css +20 -0
  18. data/app/assets/stylesheets/puffer/puffer_pages.css +7 -0
  19. data/app/components/page_parts/form.html.erb +7 -6
  20. data/app/controllers/puffer_pages/layouts_base.rb +1 -2
  21. data/app/controllers/puffer_pages/pages_base.rb +1 -2
  22. data/app/controllers/puffer_pages/snippets_base.rb +1 -2
  23. data/puffer_pages.gemspec +18 -12
  24. data/spec/dummy/app/controllers/application_controller.rb +4 -0
  25. data/spec/dummy/config/environments/development.rb +3 -0
  26. data/spec/dummy/db/schema.rb +1 -0
  27. metadata +51 -45
  28. data/app/assets/javascripts/puffer_pages/application.js +0 -3
  29. data/app/assets/javascripts/puffer_pages/codemirror-base.js +0 -1
  30. data/app/assets/javascripts/puffer_pages/codemirror-parser.js +0 -1
  31. data/app/assets/javascripts/puffer_pages/codemirror.js +0 -1
  32. data/app/assets/stylesheets/puffer_pages/application.css +0 -3
  33. data/app/assets/stylesheets/puffer_pages/codemirror.css +0 -135
  34. data/app/assets/stylesheets/puffer_pages/puffer_pages.css +0 -12
  35. data/app/views/layouts/puffer_pages.html.erb +0 -9
@@ -0,0 +1,231 @@
1
+ CodeMirror.defineMode("xml", function(config, parserConfig) {
2
+ var indentUnit = config.indentUnit;
3
+ var Kludges = parserConfig.htmlMode ? {
4
+ autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true,
5
+ "meta": true, "col": true, "frame": true, "base": true, "area": true},
6
+ doNotIndent: {"pre": true, "!cdata": true},
7
+ allowUnquoted: true
8
+ } : {autoSelfClosers: {}, doNotIndent: {"!cdata": true}, allowUnquoted: false};
9
+ var alignCDATA = parserConfig.alignCDATA;
10
+
11
+ // Return variables for tokenizers
12
+ var tagName, type;
13
+
14
+ function inText(stream, state) {
15
+ function chain(parser) {
16
+ state.tokenize = parser;
17
+ return parser(stream, state);
18
+ }
19
+
20
+ var ch = stream.next();
21
+ if (ch == "<") {
22
+ if (stream.eat("!")) {
23
+ if (stream.eat("[")) {
24
+ if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
25
+ else return null;
26
+ }
27
+ else if (stream.match("--")) return chain(inBlock("comment", "-->"));
28
+ else if (stream.match("DOCTYPE", true, true)) {
29
+ stream.eatWhile(/[\w\._\-]/);
30
+ return chain(inBlock("meta", ">"));
31
+ }
32
+ else return null;
33
+ }
34
+ else if (stream.eat("?")) {
35
+ stream.eatWhile(/[\w\._\-]/);
36
+ state.tokenize = inBlock("meta", "?>");
37
+ return "meta";
38
+ }
39
+ else {
40
+ type = stream.eat("/") ? "closeTag" : "openTag";
41
+ stream.eatSpace();
42
+ tagName = "";
43
+ var c;
44
+ while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
45
+ state.tokenize = inTag;
46
+ return "tag";
47
+ }
48
+ }
49
+ else if (ch == "&") {
50
+ stream.eatWhile(/[^;]/);
51
+ stream.eat(";");
52
+ return "atom";
53
+ }
54
+ else {
55
+ stream.eatWhile(/[^&<]/);
56
+ return null;
57
+ }
58
+ }
59
+
60
+ function inTag(stream, state) {
61
+ var ch = stream.next();
62
+ if (ch == ">" || (ch == "/" && stream.eat(">"))) {
63
+ state.tokenize = inText;
64
+ type = ch == ">" ? "endTag" : "selfcloseTag";
65
+ return "tag";
66
+ }
67
+ else if (ch == "=") {
68
+ type = "equals";
69
+ return null;
70
+ }
71
+ else if (/[\'\"]/.test(ch)) {
72
+ state.tokenize = inAttribute(ch);
73
+ return state.tokenize(stream, state);
74
+ }
75
+ else {
76
+ stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/);
77
+ return "word";
78
+ }
79
+ }
80
+
81
+ function inAttribute(quote) {
82
+ return function(stream, state) {
83
+ while (!stream.eol()) {
84
+ if (stream.next() == quote) {
85
+ state.tokenize = inTag;
86
+ break;
87
+ }
88
+ }
89
+ return "string";
90
+ };
91
+ }
92
+
93
+ function inBlock(style, terminator) {
94
+ return function(stream, state) {
95
+ while (!stream.eol()) {
96
+ if (stream.match(terminator)) {
97
+ state.tokenize = inText;
98
+ break;
99
+ }
100
+ stream.next();
101
+ }
102
+ return style;
103
+ };
104
+ }
105
+
106
+ var curState, setStyle;
107
+ function pass() {
108
+ for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
109
+ }
110
+ function cont() {
111
+ pass.apply(null, arguments);
112
+ return true;
113
+ }
114
+
115
+ function pushContext(tagName, startOfLine) {
116
+ var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
117
+ curState.context = {
118
+ prev: curState.context,
119
+ tagName: tagName,
120
+ indent: curState.indented,
121
+ startOfLine: startOfLine,
122
+ noIndent: noIndent
123
+ };
124
+ }
125
+ function popContext() {
126
+ if (curState.context) curState.context = curState.context.prev;
127
+ }
128
+
129
+ function element(type) {
130
+ if (type == "openTag") {curState.tagName = tagName; return cont(attributes, endtag(curState.startOfLine));}
131
+ else if (type == "closeTag") {
132
+ var err = false;
133
+ if (curState.context) {
134
+ err = curState.context.tagName != tagName;
135
+ } else {
136
+ err = true;
137
+ }
138
+ if (err) setStyle = "error";
139
+ return cont(endclosetag(err));
140
+ }
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();
147
+ }
148
+ function endtag(startOfLine) {
149
+ return function(type) {
150
+ if (type == "selfcloseTag" ||
151
+ (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase())))
152
+ return cont();
153
+ if (type == "endTag") {pushContext(curState.tagName, startOfLine); return cont();}
154
+ return cont();
155
+ };
156
+ }
157
+ function endclosetag(err) {
158
+ return function(type) {
159
+ if (err) setStyle = "error";
160
+ if (type == "endTag") { popContext(); return cont(); }
161
+ setStyle = "error";
162
+ return cont(arguments.callee);
163
+ }
164
+ }
165
+
166
+ function attributes(type) {
167
+ if (type == "word") {setStyle = "attribute"; return cont(attributes);}
168
+ if (type == "equals") return cont(attvalue, attributes);
169
+ return pass();
170
+ }
171
+ function attvalue(type) {
172
+ if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
173
+ if (type == "string") return cont(attvaluemaybe);
174
+ return pass();
175
+ }
176
+ function attvaluemaybe(type) {
177
+ if (type == "string") return cont(attvaluemaybe);
178
+ else return pass();
179
+ }
180
+
181
+ return {
182
+ startState: function() {
183
+ return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null};
184
+ },
185
+
186
+ token: function(stream, state) {
187
+ if (stream.sol()) {
188
+ state.startOfLine = true;
189
+ state.indented = stream.indentation();
190
+ }
191
+ if (stream.eatSpace()) return null;
192
+
193
+ setStyle = type = tagName = null;
194
+ var style = state.tokenize(stream, state);
195
+ if ((style || type) && style != "comment") {
196
+ curState = state;
197
+ while (true) {
198
+ var comb = state.cc.pop() || element;
199
+ if (comb(type || style)) break;
200
+ }
201
+ }
202
+ state.startOfLine = false;
203
+ return setStyle || style;
204
+ },
205
+
206
+ indent: function(state, textAfter) {
207
+ var context = state.context;
208
+ if (context && context.noIndent) return 0;
209
+ if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
210
+ if (context && /^<\//.test(textAfter))
211
+ context = context.prev;
212
+ while (context && !context.startOfLine)
213
+ context = context.prev;
214
+ if (context) return context.indent + indentUnit;
215
+ else return 0;
216
+ },
217
+
218
+ compareStates: function(a, b) {
219
+ if (a.indented != b.indented) return false;
220
+ for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {
221
+ if (!ca || !cb) return ca == cb;
222
+ if (ca.tagName != cb.tagName) return false;
223
+ }
224
+ },
225
+
226
+ electricChars: "/"
227
+ };
228
+ });
229
+
230
+ CodeMirror.defineMIME("application/xml", "xml");
231
+ CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: 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
+ };
@@ -1,3 +1,8 @@
1
+ //= require puffer/right-tabs-src
2
+ //= require puffer/codemirror
3
+ //= require puffer/overlay
4
+ //= require_tree ./codemirror
5
+
1
6
  Tabs.include({
2
7
  initialize: function(options) {
3
8
  this.$super(options);
@@ -26,21 +31,26 @@ var page_part_tab_add = function(event) {
26
31
  var new_id = new Date().getTime();
27
32
  var _this = this;
28
33
  new Dialog.Prompt({label: 'Enter new page part name'}).onOk(function() {
29
- _this.add(this.input.value(), new_page_part_tab_panel.replace(/new_page_part_tab_panel_index/g, new_id), {id: new_id});
30
- _this.tabs.last().panel.first('input[type=hidden]').value(this.input.value());
31
- _this.tabs.last().select();
32
- _this.addButton.insertTo(_this.tabsList);
33
- this.hide();
34
+ var value = this.input.value();
35
+ if (!value.blank()) {
36
+ _this.add(value, new_page_part_tab_panel.replace(/new_page_part_tab_panel_index/g, new_id), {id: new_id});
37
+ _this.tabs.last().panel.first('input[type=hidden]').value(value);
38
+ _this.tabs.last().select();
39
+ _this.addButton.insertTo(_this.tabsList);
40
+ $$('textarea[codemirror]').each(init_codemirror);
41
+ this.hide();
42
+ }
34
43
  }).show();
35
44
  }
36
45
 
37
46
  var init_codemirror = function(textarea) {
38
- CodeMirror.fromTextArea(textarea._, {
39
- basefiles: "/assets/puffer_pages/codemirror-base.js",
40
- parserfile: "/assets/puffer_pages/codemirror-parser.js",
41
- stylesheet: "/assets/puffer_pages/codemirror.css",
42
- tabMode: 'shift'
43
- });
47
+ if (!textarea.codemirror) {
48
+ CodeMirror.fromTextArea(textarea._, {
49
+ mode: 'text/html',
50
+ lineNumbers: true
51
+ });
52
+ textarea.codemirror = true
53
+ }
44
54
  }
45
55
 
46
56
  $(document).onReady(function() {
@@ -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,24 @@
1
+ .cm-s-eclipse span.cm-meta {color: #FF1717;}
2
+ .cm-s-eclipse span.cm-keyword { font-weight: bold; color: #7F0055; }
3
+ .cm-s-eclipse span.cm-atom {color: #219;}
4
+ .cm-s-eclipse span.cm-number {color: #164;}
5
+ .cm-s-eclipse span.cm-def {color: #00f;}
6
+ .cm-s-eclipse span.cm-variable {color: black;}
7
+ .cm-s-eclipse span.cm-variable-2 {color: #0000C0;}
8
+ .cm-s-eclipse span.cm-variable-3 {color: #0000C0;}
9
+ .cm-s-eclipse span.cm-property {color: black;}
10
+ .cm-s-eclipse span.cm-operator {color: black;}
11
+ .cm-s-eclipse span.cm-comment {color: #3F7F5F;}
12
+ .cm-s-eclipse span.cm-string {color: #2A00FF;}
13
+ .cm-s-eclipse span.cm-string-2 {color: #f50;}
14
+ .cm-s-eclipse span.cm-error {color: #f00;}
15
+ .cm-s-eclipse span.cm-qualifier {color: #555;}
16
+ .cm-s-eclipse span.cm-builtin {color: #30a;}
17
+ .cm-s-eclipse span.cm-bracket {color: #cc7;}
18
+ .cm-s-eclipse span.cm-tag {color: #170;}
19
+ .cm-s-eclipse span.cm-attribute {color: #00c;}
20
+
21
+ .CodeMirror-matchingbracket{
22
+ border:1px solid grey;
23
+ color:black !important;;
24
+ }