puffer_pages 0.0.18 → 0.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }