Simple Custom CSS and JS - Version 3.41

Version Description

  • 10/05/2022
  • Feature: code folding in the editor
Download this release

Release Info

Developer diana_burduja
Plugin Icon 128x128 Simple Custom CSS and JS
Version 3.41
Comparing to
See all releases

Code changes from version 3.40 to 3.41

assets/ccj_admin.css CHANGED
@@ -184,7 +184,7 @@ i.ccj-i-beautifier::before {
184
  }
185
  .code-mirror-before div {
186
  color: #8F8F8F;
187
- margin-left: 29px;
188
  border-left: 1px solid #ddd;
189
  padding: 3px 8px;
190
  background-color: #fff;
@@ -196,7 +196,7 @@ i.ccj-i-beautifier::before {
196
  }
197
  .code-mirror-after div {
198
  color: #8F8F8F;
199
- margin-left: 29px;
200
  border-left: 1px solid #ddd;
201
  padding: 3px 8px;
202
  background-color: #fff;
184
  }
185
  .code-mirror-before div {
186
  color: #8F8F8F;
187
+ margin-left: 38px;
188
  border-left: 1px solid #ddd;
189
  padding: 3px 8px;
190
  background-color: #fff;
196
  }
197
  .code-mirror-after div {
198
  color: #8F8F8F;
199
+ margin-left: 38px;
200
  border-left: 1px solid #ddd;
201
  padding: 3px 8px;
202
  background-color: #fff;
assets/ccj_admin.js CHANGED
@@ -31,6 +31,13 @@ jQuery(document).ready( function($) {
31
 
32
  var editor = CodeMirror.fromTextArea(document.getElementById("ccj_content"), CCJ.codemirror);
33
 
 
 
 
 
 
 
 
34
  // Note: ccj-postID cookie will save cursor line, cursor character, editor height and fullscreen values
35
  var cookies = (getCookie('ccj-' + postID) || '0,0,0,0').split(',');
36
 
@@ -105,18 +112,18 @@ jQuery(document).ready( function($) {
105
  // Restoring fullscreen
106
  editor.setOption("fullScreen", parseFloat(cookies[3]));
107
  fullscreen_buttons( Boolean(parseFloat(cookies[3])) );
108
- }
109
 
110
- // Action for the `fullscreen` button
111
- $("#ccj-fullscreen-button").click( function() {
112
- editor.triggerOnKeyDown({type: 'keydown', keyCode: 122});
113
- });
114
 
115
- $("#publish").click(function(e){
116
- var cookies = (getCookie('ccj-' + postID) || '0,0,0,0').split(',');
117
- var curPos = editor.getCursor();
118
- document.cookie = 'ccj-' + postID + '=' + [curPos.line, curPos.ch, cookies[2], Number(editor.getOption('fullScreen'))].join(',') + '; SameSite=Lax';
119
- });
 
120
 
121
  // Enable the tipsy
122
  $('span[rel=tipsy].tipsy-no-html').tipsy({fade: true, gravity: 's'});
31
 
32
  var editor = CodeMirror.fromTextArea(document.getElementById("ccj_content"), CCJ.codemirror);
33
 
34
+ // Code folding
35
+ editor.setOption("lineNumbers", true);
36
+ editor.setOption("lineWrapping", true);
37
+ editor.setOption("foldGutter", true);
38
+ editor.setOption("gutters", ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]);
39
+ CCJ.codemirror.extraKeys["Ctrl-Q"] = function(cm){ cm.foldCode(cm.getCursor()); };
40
+
41
  // Note: ccj-postID cookie will save cursor line, cursor character, editor height and fullscreen values
42
  var cookies = (getCookie('ccj-' + postID) || '0,0,0,0').split(',');
43
 
112
  // Restoring fullscreen
113
  editor.setOption("fullScreen", parseFloat(cookies[3]));
114
  fullscreen_buttons( Boolean(parseFloat(cookies[3])) );
 
115
 
116
+ // Action for the `fullscreen` button
117
+ $("#ccj-fullscreen-button").click( function() {
118
+ editor.triggerOnKeyDown({type: 'keydown', keyCode: 122});
119
+ });
120
 
121
+ $("#publish").click(function(e){
122
+ var cookies = (getCookie('ccj-' + postID) || '0,0,0,0').split(',');
123
+ var curPos = editor.getCursor();
124
+ document.cookie = 'ccj-' + postID + '=' + [curPos.line, curPos.ch, cookies[2], Number(editor.getOption('fullScreen'))].join(',') + '; SameSite=Lax';
125
+ });
126
+ }
127
 
128
  // Enable the tipsy
129
  $('span[rel=tipsy].tipsy-no-html').tipsy({fade: true, gravity: 's'});
assets/codemirror/addon/fold/brace-fold.js ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/5/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ function bracketFolding(pairs) {
15
+ return function(cm, start) {
16
+ var line = start.line, lineText = cm.getLine(line);
17
+
18
+ function findOpening(pair) {
19
+ var tokenType;
20
+ for (var at = start.ch, pass = 0;;) {
21
+ var found = at <= 0 ? -1 : lineText.lastIndexOf(pair[0], at - 1);
22
+ if (found == -1) {
23
+ if (pass == 1) break;
24
+ pass = 1;
25
+ at = lineText.length;
26
+ continue;
27
+ }
28
+ if (pass == 1 && found < start.ch) break;
29
+ tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
30
+ if (!/^(comment|string)/.test(tokenType)) return {ch: found + 1, tokenType: tokenType, pair: pair};
31
+ at = found - 1;
32
+ }
33
+ }
34
+
35
+ function findRange(found) {
36
+ var count = 1, lastLine = cm.lastLine(), end, startCh = found.ch, endCh
37
+ outer: for (var i = line; i <= lastLine; ++i) {
38
+ var text = cm.getLine(i), pos = i == line ? startCh : 0;
39
+ for (;;) {
40
+ var nextOpen = text.indexOf(found.pair[0], pos), nextClose = text.indexOf(found.pair[1], pos);
41
+ if (nextOpen < 0) nextOpen = text.length;
42
+ if (nextClose < 0) nextClose = text.length;
43
+ pos = Math.min(nextOpen, nextClose);
44
+ if (pos == text.length) break;
45
+ if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == found.tokenType) {
46
+ if (pos == nextOpen) ++count;
47
+ else if (!--count) { end = i; endCh = pos; break outer; }
48
+ }
49
+ ++pos;
50
+ }
51
+ }
52
+
53
+ if (end == null || line == end) return null
54
+ return {from: CodeMirror.Pos(line, startCh),
55
+ to: CodeMirror.Pos(end, endCh)};
56
+ }
57
+
58
+ var found = []
59
+ for (var i = 0; i < pairs.length; i++) {
60
+ var open = findOpening(pairs[i])
61
+ if (open) found.push(open)
62
+ }
63
+ found.sort(function(a, b) { return a.ch - b.ch })
64
+ for (var i = 0; i < found.length; i++) {
65
+ var range = findRange(found[i])
66
+ if (range) return range
67
+ }
68
+ return null
69
+ }
70
+ }
71
+
72
+ CodeMirror.registerHelper("fold", "brace", bracketFolding([["{", "}"], ["[", "]"]]));
73
+
74
+ CodeMirror.registerHelper("fold", "brace-paren", bracketFolding([["{", "}"], ["[", "]"], ["(", ")"]]));
75
+
76
+ CodeMirror.registerHelper("fold", "import", function(cm, start) {
77
+ function hasImport(line) {
78
+ if (line < cm.firstLine() || line > cm.lastLine()) return null;
79
+ var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
80
+ if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
81
+ if (start.type != "keyword" || start.string != "import") return null;
82
+ // Now find closing semicolon, return its position
83
+ for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) {
84
+ var text = cm.getLine(i), semi = text.indexOf(";");
85
+ if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)};
86
+ }
87
+ }
88
+
89
+ var startLine = start.line, has = hasImport(startLine), prev;
90
+ if (!has || hasImport(startLine - 1) || ((prev = hasImport(startLine - 2)) && prev.end.line == startLine - 1))
91
+ return null;
92
+ for (var end = has.end;;) {
93
+ var next = hasImport(end.line + 1);
94
+ if (next == null) break;
95
+ end = next.end;
96
+ }
97
+ return {from: cm.clipPos(CodeMirror.Pos(startLine, has.startCh + 1)), to: end};
98
+ });
99
+
100
+ CodeMirror.registerHelper("fold", "include", function(cm, start) {
101
+ function hasInclude(line) {
102
+ if (line < cm.firstLine() || line > cm.lastLine()) return null;
103
+ var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
104
+ if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
105
+ if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8;
106
+ }
107
+
108
+ var startLine = start.line, has = hasInclude(startLine);
109
+ if (has == null || hasInclude(startLine - 1) != null) return null;
110
+ for (var end = startLine;;) {
111
+ var next = hasInclude(end + 1);
112
+ if (next == null) break;
113
+ ++end;
114
+ }
115
+ return {from: CodeMirror.Pos(startLine, has + 1),
116
+ to: cm.clipPos(CodeMirror.Pos(end))};
117
+ });
118
+
119
+ });
assets/codemirror/addon/fold/comment-fold.js ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/5/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.registerGlobalHelper("fold", "comment", function(mode) {
15
+ return mode.blockCommentStart && mode.blockCommentEnd;
16
+ }, function(cm, start) {
17
+ var mode = cm.getModeAt(start), startToken = mode.blockCommentStart, endToken = mode.blockCommentEnd;
18
+ if (!startToken || !endToken) return;
19
+ var line = start.line, lineText = cm.getLine(line);
20
+
21
+ var startCh;
22
+ for (var at = start.ch, pass = 0;;) {
23
+ var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1);
24
+ if (found == -1) {
25
+ if (pass == 1) return;
26
+ pass = 1;
27
+ at = lineText.length;
28
+ continue;
29
+ }
30
+ if (pass == 1 && found < start.ch) return;
31
+ if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1))) &&
32
+ (found == 0 || lineText.slice(found - endToken.length, found) == endToken ||
33
+ !/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found))))) {
34
+ startCh = found + startToken.length;
35
+ break;
36
+ }
37
+ at = found - 1;
38
+ }
39
+
40
+ var depth = 1, lastLine = cm.lastLine(), end, endCh;
41
+ outer: for (var i = line; i <= lastLine; ++i) {
42
+ var text = cm.getLine(i), pos = i == line ? startCh : 0;
43
+ for (;;) {
44
+ var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
45
+ if (nextOpen < 0) nextOpen = text.length;
46
+ if (nextClose < 0) nextClose = text.length;
47
+ pos = Math.min(nextOpen, nextClose);
48
+ if (pos == text.length) break;
49
+ if (pos == nextOpen) ++depth;
50
+ else if (!--depth) { end = i; endCh = pos; break outer; }
51
+ ++pos;
52
+ }
53
+ }
54
+ if (end == null || line == end && endCh == startCh) return;
55
+ return {from: CodeMirror.Pos(line, startCh),
56
+ to: CodeMirror.Pos(end, endCh)};
57
+ });
58
+
59
+ });
assets/codemirror/addon/fold/foldcode.js ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/5/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ function doFold(cm, pos, options, force) {
15
+ if (options && options.call) {
16
+ var finder = options;
17
+ options = null;
18
+ } else {
19
+ var finder = getOption(cm, options, "rangeFinder");
20
+ }
21
+ if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
22
+ var minSize = getOption(cm, options, "minFoldSize");
23
+
24
+ function getRange(allowFolded) {
25
+ var range = finder(cm, pos);
26
+ if (!range || range.to.line - range.from.line < minSize) return null;
27
+ if (force === "fold") return range;
28
+
29
+ var marks = cm.findMarksAt(range.from);
30
+ for (var i = 0; i < marks.length; ++i) {
31
+ if (marks[i].__isFold) {
32
+ if (!allowFolded) return null;
33
+ range.cleared = true;
34
+ marks[i].clear();
35
+ }
36
+ }
37
+ return range;
38
+ }
39
+
40
+ var range = getRange(true);
41
+ if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) {
42
+ pos = CodeMirror.Pos(pos.line - 1, 0);
43
+ range = getRange(false);
44
+ }
45
+ if (!range || range.cleared || force === "unfold") return;
46
+
47
+ var myWidget = makeWidget(cm, options, range);
48
+ CodeMirror.on(myWidget, "mousedown", function(e) {
49
+ myRange.clear();
50
+ CodeMirror.e_preventDefault(e);
51
+ });
52
+ var myRange = cm.markText(range.from, range.to, {
53
+ replacedWith: myWidget,
54
+ clearOnEnter: getOption(cm, options, "clearOnEnter"),
55
+ __isFold: true
56
+ });
57
+ myRange.on("clear", function(from, to) {
58
+ CodeMirror.signal(cm, "unfold", cm, from, to);
59
+ });
60
+ CodeMirror.signal(cm, "fold", cm, range.from, range.to);
61
+ }
62
+
63
+ function makeWidget(cm, options, range) {
64
+ var widget = getOption(cm, options, "widget");
65
+
66
+ if (typeof widget == "function") {
67
+ widget = widget(range.from, range.to);
68
+ }
69
+
70
+ if (typeof widget == "string") {
71
+ var text = document.createTextNode(widget);
72
+ widget = document.createElement("span");
73
+ widget.appendChild(text);
74
+ widget.className = "CodeMirror-foldmarker";
75
+ } else if (widget) {
76
+ widget = widget.cloneNode(true)
77
+ }
78
+ return widget;
79
+ }
80
+
81
+ // Clumsy backwards-compatible interface
82
+ CodeMirror.newFoldFunction = function(rangeFinder, widget) {
83
+ return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); };
84
+ };
85
+
86
+ // New-style interface
87
+ CodeMirror.defineExtension("foldCode", function(pos, options, force) {
88
+ doFold(this, pos, options, force);
89
+ });
90
+
91
+ CodeMirror.defineExtension("isFolded", function(pos) {
92
+ var marks = this.findMarksAt(pos);
93
+ for (var i = 0; i < marks.length; ++i)
94
+ if (marks[i].__isFold) return true;
95
+ });
96
+
97
+ CodeMirror.commands.toggleFold = function(cm) {
98
+ cm.foldCode(cm.getCursor());
99
+ };
100
+ CodeMirror.commands.fold = function(cm) {
101
+ cm.foldCode(cm.getCursor(), null, "fold");
102
+ };
103
+ CodeMirror.commands.unfold = function(cm) {
104
+ cm.foldCode(cm.getCursor(), { scanUp: false }, "unfold");
105
+ };
106
+ CodeMirror.commands.foldAll = function(cm) {
107
+ cm.operation(function() {
108
+ for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
109
+ cm.foldCode(CodeMirror.Pos(i, 0), { scanUp: false }, "fold");
110
+ });
111
+ };
112
+ CodeMirror.commands.unfoldAll = function(cm) {
113
+ cm.operation(function() {
114
+ for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
115
+ cm.foldCode(CodeMirror.Pos(i, 0), { scanUp: false }, "unfold");
116
+ });
117
+ };
118
+
119
+ CodeMirror.registerHelper("fold", "combine", function() {
120
+ var funcs = Array.prototype.slice.call(arguments, 0);
121
+ return function(cm, start) {
122
+ for (var i = 0; i < funcs.length; ++i) {
123
+ var found = funcs[i](cm, start);
124
+ if (found) return found;
125
+ }
126
+ };
127
+ });
128
+
129
+ CodeMirror.registerHelper("fold", "auto", function(cm, start) {
130
+ var helpers = cm.getHelpers(start, "fold");
131
+ for (var i = 0; i < helpers.length; i++) {
132
+ var cur = helpers[i](cm, start);
133
+ if (cur) return cur;
134
+ }
135
+ });
136
+
137
+ var defaultOptions = {
138
+ rangeFinder: CodeMirror.fold.auto,
139
+ widget: "\u2194",
140
+ minFoldSize: 0,
141
+ scanUp: false,
142
+ clearOnEnter: true
143
+ };
144
+
145
+ CodeMirror.defineOption("foldOptions", null);
146
+
147
+ function getOption(cm, options, name) {
148
+ if (options && options[name] !== undefined)
149
+ return options[name];
150
+ var editorOptions = cm.options.foldOptions;
151
+ if (editorOptions && editorOptions[name] !== undefined)
152
+ return editorOptions[name];
153
+ return defaultOptions[name];
154
+ }
155
+
156
+ CodeMirror.defineExtension("foldOption", function(options, name) {
157
+ return getOption(this, options, name);
158
+ });
159
+ });
assets/codemirror/addon/fold/foldgutter.css ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .CodeMirror-foldmarker {
2
+ color: blue;
3
+ text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
4
+ font-family: arial;
5
+ line-height: .3;
6
+ cursor: pointer;
7
+ }
8
+ .CodeMirror-foldgutter {
9
+ width: .7em;
10
+ }
11
+ .CodeMirror-foldgutter-open,
12
+ .CodeMirror-foldgutter-folded {
13
+ cursor: pointer;
14
+ }
15
+ .CodeMirror-foldgutter-open:after {
16
+ content: "\25BE";
17
+ }
18
+ .CodeMirror-foldgutter-folded:after {
19
+ content: "\25B8";
20
+ }
assets/codemirror/addon/fold/foldgutter.js ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/5/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"), require("./foldcode"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror", "./foldcode"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineOption("foldGutter", false, function(cm, val, old) {
15
+ if (old && old != CodeMirror.Init) {
16
+ cm.clearGutter(cm.state.foldGutter.options.gutter);
17
+ cm.state.foldGutter = null;
18
+ cm.off("gutterClick", onGutterClick);
19
+ cm.off("changes", onChange);
20
+ cm.off("viewportChange", onViewportChange);
21
+ cm.off("fold", onFold);
22
+ cm.off("unfold", onFold);
23
+ cm.off("swapDoc", onChange);
24
+ cm.off("optionChange", optionChange);
25
+ }
26
+ if (val) {
27
+ cm.state.foldGutter = new State(parseOptions(val));
28
+ updateInViewport(cm);
29
+ cm.on("gutterClick", onGutterClick);
30
+ cm.on("changes", onChange);
31
+ cm.on("viewportChange", onViewportChange);
32
+ cm.on("fold", onFold);
33
+ cm.on("unfold", onFold);
34
+ cm.on("swapDoc", onChange);
35
+ cm.on("optionChange", optionChange);
36
+ }
37
+ });
38
+
39
+ var Pos = CodeMirror.Pos;
40
+
41
+ function State(options) {
42
+ this.options = options;
43
+ this.from = this.to = 0;
44
+ }
45
+
46
+ function parseOptions(opts) {
47
+ if (opts === true) opts = {};
48
+ if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter";
49
+ if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open";
50
+ if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded";
51
+ return opts;
52
+ }
53
+
54
+ function isFolded(cm, line) {
55
+ var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0));
56
+ for (var i = 0; i < marks.length; ++i) {
57
+ if (marks[i].__isFold) {
58
+ var fromPos = marks[i].find(-1);
59
+ if (fromPos && fromPos.line === line)
60
+ return marks[i];
61
+ }
62
+ }
63
+ }
64
+
65
+ function marker(spec) {
66
+ if (typeof spec == "string") {
67
+ var elt = document.createElement("div");
68
+ elt.className = spec + " CodeMirror-guttermarker-subtle";
69
+ return elt;
70
+ } else {
71
+ return spec.cloneNode(true);
72
+ }
73
+ }
74
+
75
+ function updateFoldInfo(cm, from, to) {
76
+ var opts = cm.state.foldGutter.options, cur = from - 1;
77
+ var minSize = cm.foldOption(opts, "minFoldSize");
78
+ var func = cm.foldOption(opts, "rangeFinder");
79
+ // we can reuse the built-in indicator element if its className matches the new state
80
+ var clsFolded = typeof opts.indicatorFolded == "string" && classTest(opts.indicatorFolded);
81
+ var clsOpen = typeof opts.indicatorOpen == "string" && classTest(opts.indicatorOpen);
82
+ cm.eachLine(from, to, function(line) {
83
+ ++cur;
84
+ var mark = null;
85
+ var old = line.gutterMarkers;
86
+ if (old) old = old[opts.gutter];
87
+ if (isFolded(cm, cur)) {
88
+ if (clsFolded && old && clsFolded.test(old.className)) return;
89
+ mark = marker(opts.indicatorFolded);
90
+ } else {
91
+ var pos = Pos(cur, 0);
92
+ var range = func && func(cm, pos);
93
+ if (range && range.to.line - range.from.line >= minSize) {
94
+ if (clsOpen && old && clsOpen.test(old.className)) return;
95
+ mark = marker(opts.indicatorOpen);
96
+ }
97
+ }
98
+ if (!mark && !old) return;
99
+ cm.setGutterMarker(line, opts.gutter, mark);
100
+ });
101
+ }
102
+
103
+ // copied from CodeMirror/src/util/dom.js
104
+ function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }
105
+
106
+ function updateInViewport(cm) {
107
+ var vp = cm.getViewport(), state = cm.state.foldGutter;
108
+ if (!state) return;
109
+ cm.operation(function() {
110
+ updateFoldInfo(cm, vp.from, vp.to);
111
+ });
112
+ state.from = vp.from; state.to = vp.to;
113
+ }
114
+
115
+ function onGutterClick(cm, line, gutter) {
116
+ var state = cm.state.foldGutter;
117
+ if (!state) return;
118
+ var opts = state.options;
119
+ if (gutter != opts.gutter) return;
120
+ var folded = isFolded(cm, line);
121
+ if (folded) folded.clear();
122
+ else cm.foldCode(Pos(line, 0), opts);
123
+ }
124
+
125
+ function optionChange(cm, option) {
126
+ if (option == "mode") onChange(cm)
127
+ }
128
+
129
+ function onChange(cm) {
130
+ var state = cm.state.foldGutter;
131
+ if (!state) return;
132
+ var opts = state.options;
133
+ state.from = state.to = 0;
134
+ clearTimeout(state.changeUpdate);
135
+ state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
136
+ }
137
+
138
+ function onViewportChange(cm) {
139
+ var state = cm.state.foldGutter;
140
+ if (!state) return;
141
+ var opts = state.options;
142
+ clearTimeout(state.changeUpdate);
143
+ state.changeUpdate = setTimeout(function() {
144
+ var vp = cm.getViewport();
145
+ if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
146
+ updateInViewport(cm);
147
+ } else {
148
+ cm.operation(function() {
149
+ if (vp.from < state.from) {
150
+ updateFoldInfo(cm, vp.from, state.from);
151
+ state.from = vp.from;
152
+ }
153
+ if (vp.to > state.to) {
154
+ updateFoldInfo(cm, state.to, vp.to);
155
+ state.to = vp.to;
156
+ }
157
+ });
158
+ }
159
+ }, opts.updateViewportTimeSpan || 400);
160
+ }
161
+
162
+ function onFold(cm, from) {
163
+ var state = cm.state.foldGutter;
164
+ if (!state) return;
165
+ var line = from.line;
166
+ if (line >= state.from && line < state.to)
167
+ updateFoldInfo(cm, line, line + 1);
168
+ }
169
+ });
assets/codemirror/addon/fold/indent-fold.js ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/5/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ function lineIndent(cm, lineNo) {
15
+ var text = cm.getLine(lineNo)
16
+ var spaceTo = text.search(/\S/)
17
+ if (spaceTo == -1 || /\bcomment\b/.test(cm.getTokenTypeAt(CodeMirror.Pos(lineNo, spaceTo + 1))))
18
+ return -1
19
+ return CodeMirror.countColumn(text, null, cm.getOption("tabSize"))
20
+ }
21
+
22
+ CodeMirror.registerHelper("fold", "indent", function(cm, start) {
23
+ var myIndent = lineIndent(cm, start.line)
24
+ if (myIndent < 0) return
25
+ var lastLineInFold = null
26
+
27
+ // Go through lines until we find a line that definitely doesn't belong in
28
+ // the block we're folding, or to the end.
29
+ for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) {
30
+ var indent = lineIndent(cm, i)
31
+ if (indent == -1) {
32
+ } else if (indent > myIndent) {
33
+ // Lines with a greater indent are considered part of the block.
34
+ lastLineInFold = i;
35
+ } else {
36
+ // If this line has non-space, non-comment content, and is
37
+ // indented less or equal to the start line, it is the start of
38
+ // another block.
39
+ break;
40
+ }
41
+ }
42
+ if (lastLineInFold) return {
43
+ from: CodeMirror.Pos(start.line, cm.getLine(start.line).length),
44
+ to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length)
45
+ };
46
+ });
47
+
48
+ });
assets/codemirror/addon/fold/markdown-fold.js ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: https://codemirror.net/5/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.registerHelper("fold", "markdown", function(cm, start) {
15
+ var maxDepth = 100;
16
+
17
+ function isHeader(lineNo) {
18
+ var tokentype = cm.getTokenTypeAt(CodeMirror.Pos(lineNo, 0));
19
+ return tokentype && /\bheader\b/.test(tokentype);
20
+ }
21
+
22
+ function headerLevel(lineNo, line, nextLine) {
23
+ var match = line && line.match(/^#+/);
24
+ if (match && isHeader(lineNo)) return match[0].length;
25
+ match = nextLine && nextLine.match(/^[=\-]+\s*$/);
26
+ if (match && isHeader(lineNo + 1)) return nextLine[0] == "=" ? 1 : 2;
27
+ return maxDepth;
28
+ }
29
+
30
+ var firstLine = cm.getLine(start.line), nextLine = cm.getLine(start.line + 1);
31
+ var level = headerLevel(start.line, firstLine, nextLine);
32
+ if (level === maxDepth) return undefined;
33
+
34
+ var lastLineNo = cm.lastLine();
35
+ var end = start.line, nextNextLine = cm.getLine(end + 2);
36
+ while (end < lastLineNo) {
37
+ if (headerLevel(end + 1, nextLine, nextNextLine) <= level) break;
38
+ ++end;
39
+ nextLine = nextNextLine;
40
+ nextNextLine = cm.getLine(end + 2);
41
+ }
42
+
43
+ return {
44
+ from: CodeMirror.Pos(start.line, firstLine.length),
45
+ to: CodeMirror.Pos(end, cm.getLine(end).length)
46
+ };
47
+ });
48
+
49
+ });
custom-css-js.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Simple Custom CSS and JS
4
  * Plugin URI: https://wordpress.org/plugins/custom-css-js/
5
  * Description: Easily add Custom CSS or JS to your website with an awesome editor.
6
- * Version: 3.40
7
  * Author: SilkyPress.com
8
  * Author URI: https://www.silkypress.com
9
  * License: GPL2
@@ -12,7 +12,7 @@
12
  * Domain Path: /languages/
13
  *
14
  * WC requires at least: 3.0.0
15
- * WC tested up to: 6.9
16
  */
17
 
18
  if ( ! defined( 'ABSPATH' ) ) {
@@ -228,7 +228,7 @@ if ( ! class_exists( 'CustomCSSandJS' ) ) :
228
  public function set_constants() {
229
  $dir = wp_upload_dir();
230
  $constants = array(
231
- 'CCJ_VERSION' => '3.40',
232
  'CCJ_UPLOAD_DIR' => $dir['basedir'] . '/custom-css-js',
233
  'CCJ_UPLOAD_URL' => $dir['baseurl'] . '/custom-css-js',
234
  'CCJ_PLUGIN_FILE' => __FILE__,
3
  * Plugin Name: Simple Custom CSS and JS
4
  * Plugin URI: https://wordpress.org/plugins/custom-css-js/
5
  * Description: Easily add Custom CSS or JS to your website with an awesome editor.
6
+ * Version: 3.41
7
  * Author: SilkyPress.com
8
  * Author URI: https://www.silkypress.com
9
  * License: GPL2
12
  * Domain Path: /languages/
13
  *
14
  * WC requires at least: 3.0.0
15
+ * WC tested up to: 7.0
16
  */
17
 
18
  if ( ! defined( 'ABSPATH' ) ) {
228
  public function set_constants() {
229
  $dir = wp_upload_dir();
230
  $constants = array(
231
+ 'CCJ_VERSION' => '3.41',
232
  'CCJ_UPLOAD_DIR' => $dir['basedir'] . '/custom-css-js',
233
  'CCJ_UPLOAD_URL' => $dir['baseurl'] . '/custom-css-js',
234
  'CCJ_PLUGIN_FILE' => __FILE__,
includes/admin-screens.php CHANGED
@@ -152,7 +152,6 @@ class CustomCSSandJS_Admin {
152
  $cma = $cm . '/addon/';
153
  wp_enqueue_script( 'ccj-closebrackets', $cma . 'edit/closebrackets.js', array( 'ccj-codemirror' ), $v, false );
154
  wp_enqueue_script( 'ccj-matchbrackets', $cma . 'edit/matchbrackets.js', array( 'ccj-codemirror' ), $v, false );
155
- wp_enqueue_script( 'ccj-xmlfold', $cma . 'fold/xml-fold.js', array( 'ccj-codemirror' ), $v, false );
156
  wp_enqueue_script( 'ccj-matchtags', $cma . 'edit/matchtags.js', array( 'ccj-codemirror' ), $v, false );
157
  wp_enqueue_script( 'cm-dialog', $cma . 'dialog/dialog.js', array( 'ccj-codemirror' ), $v, false );
158
  wp_enqueue_script( 'cm-search', $cma . 'search/search.js', array( 'ccj-codemirror' ), $v, false );
@@ -173,6 +172,16 @@ class CustomCSSandJS_Admin {
173
  wp_enqueue_script( 'ccj-hint-anyword', $cma . 'hint/anyword-hint.js', array( 'ccj-codemirror' ), $v, false );
174
  wp_enqueue_style( 'ccj-hint', $cma . 'hint/show-hint.css', array(), $v );
175
 
 
 
 
 
 
 
 
 
 
 
176
  // remove the assets from other plugins so it doesn't interfere with CodeMirror
177
  global $wp_scripts;
178
  if ( is_array( $wp_scripts->registered ) && count( $wp_scripts->registered ) != 0 ) {
@@ -1563,6 +1572,7 @@ endif;
1563
  <tr><td><strong>Replace</strong></td><td> <code>Shift</code> + <code>Ctrl</code> + <code>F</code></td></tr>
1564
  <tr><td><strong>Save</strong></td><td> <code>Ctrl</code> + <code>S</code></td></tr>
1565
  <tr><td><strong>Comment line/block</strong></td><td> <code>Ctrl</code> + <code>/</code></td></tr>
 
1566
  </table></p>',
1567
  )
1568
  );
152
  $cma = $cm . '/addon/';
153
  wp_enqueue_script( 'ccj-closebrackets', $cma . 'edit/closebrackets.js', array( 'ccj-codemirror' ), $v, false );
154
  wp_enqueue_script( 'ccj-matchbrackets', $cma . 'edit/matchbrackets.js', array( 'ccj-codemirror' ), $v, false );
 
155
  wp_enqueue_script( 'ccj-matchtags', $cma . 'edit/matchtags.js', array( 'ccj-codemirror' ), $v, false );
156
  wp_enqueue_script( 'cm-dialog', $cma . 'dialog/dialog.js', array( 'ccj-codemirror' ), $v, false );
157
  wp_enqueue_script( 'cm-search', $cma . 'search/search.js', array( 'ccj-codemirror' ), $v, false );
172
  wp_enqueue_script( 'ccj-hint-anyword', $cma . 'hint/anyword-hint.js', array( 'ccj-codemirror' ), $v, false );
173
  wp_enqueue_style( 'ccj-hint', $cma . 'hint/show-hint.css', array(), $v );
174
 
175
+ // Fold Addons
176
+ wp_enqueue_script( 'ccj-fold-brace', $cma . 'fold/brace-fold.js', array( 'ccj-codemirror' ), $v, false );
177
+ wp_enqueue_script( 'ccj-fold-comment', $cma . 'fold/comment-fold.js', array( 'ccj-codemirror' ), $v, false );
178
+ wp_enqueue_script( 'ccj-fold-code', $cma . 'fold/foldcode.js', array( 'ccj-codemirror' ), $v, false );
179
+ wp_enqueue_script( 'ccj-fold-gutter', $cma . 'fold/foldgutter.js', array( 'ccj-codemirror' ), $v, false );
180
+ wp_enqueue_script( 'ccj-fold-indent', $cma . 'fold/indent-fold.js', array( 'ccj-codemirror' ), $v, false );
181
+ wp_enqueue_script( 'ccj-fold-markdown', $cma . 'fold/markdown-fold.js', array( 'ccj-codemirror' ), $v, false );
182
+ wp_enqueue_script( 'ccj-fold-xml', $cma . 'fold/xml-fold.js', array( 'ccj-codemirror' ), $v, false );
183
+ wp_enqueue_style( 'ccj-fold-gutter', $cma . 'fold/foldgutter.css', array(), $v );
184
+
185
  // remove the assets from other plugins so it doesn't interfere with CodeMirror
186
  global $wp_scripts;
187
  if ( is_array( $wp_scripts->registered ) && count( $wp_scripts->registered ) != 0 ) {
1572
  <tr><td><strong>Replace</strong></td><td> <code>Shift</code> + <code>Ctrl</code> + <code>F</code></td></tr>
1573
  <tr><td><strong>Save</strong></td><td> <code>Ctrl</code> + <code>S</code></td></tr>
1574
  <tr><td><strong>Comment line/block</strong></td><td> <code>Ctrl</code> + <code>/</code></td></tr>
1575
+ <tr><td><strong>Code folding</strong></td><td> <code>Ctrl</code> + <code>Q</code></td></tr>
1576
  </table></p>',
1577
  )
1578
  );
readme.txt CHANGED
@@ -5,7 +5,7 @@ Email: diana@burduja.eu
5
  Tags: CSS, JS, javascript, custom CSS, custom JS, custom style, site css, add style, customize theme, custom code, external css, css3, style, styles, stylesheet, theme, editor, design, admin
6
  Requires at least: 3.0.1
7
  Tested up to: 6.1
8
- Stable tag: 3.40
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
11
  Requires PHP: 5.2.4
@@ -105,6 +105,10 @@ $. Add/Edit HTML
105
 
106
  == Changelog ==
107
 
 
 
 
 
108
  = 3.40 =
109
  * 06/10/2022
110
  * Feature: keep the user-set editor's height upon page loads and custom code saves
5
  Tags: CSS, JS, javascript, custom CSS, custom JS, custom style, site css, add style, customize theme, custom code, external css, css3, style, styles, stylesheet, theme, editor, design, admin
6
  Requires at least: 3.0.1
7
  Tested up to: 6.1
8
+ Stable tag: 3.41
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
11
  Requires PHP: 5.2.4
105
 
106
  == Changelog ==
107
 
108
+ = 3.41 =
109
+ * 10/05/2022
110
+ * Feature: code folding in the editor
111
+
112
  = 3.40 =
113
  * 06/10/2022
114
  * Feature: keep the user-set editor's height upon page loads and custom code saves