Support functions as fold widget argument
So that the widgets can be dynamic with regards to their content. Expand the fold demo with a JSON editor that shows the number of elements in folded regions.
This commit is contained in:
parent
00281786f0
commit
3ace5da283
|
@ -42,7 +42,7 @@
|
|||
}
|
||||
if (!range || range.cleared || force === "unfold") return;
|
||||
|
||||
var myWidget = makeWidget(cm, options);
|
||||
var myWidget = makeWidget(cm, options, range);
|
||||
CodeMirror.on(myWidget, "mousedown", function(e) {
|
||||
myRange.clear();
|
||||
CodeMirror.e_preventDefault(e);
|
||||
|
@ -58,8 +58,13 @@
|
|||
CodeMirror.signal(cm, "fold", cm, range.from, range.to);
|
||||
}
|
||||
|
||||
function makeWidget(cm, options) {
|
||||
function makeWidget(cm, options, range) {
|
||||
var widget = getOption(cm, options, "widget");
|
||||
|
||||
if (typeof widget == "function") {
|
||||
widget = widget(range.from, range.to);
|
||||
}
|
||||
|
||||
if (typeof widget == "string") {
|
||||
var text = document.createTextNode(widget);
|
||||
widget = document.createElement("span");
|
||||
|
|
|
@ -53,7 +53,23 @@
|
|||
<div style="max-width: 50em; margin-bottom: 1em">JavaScript:<br>
|
||||
<textarea id="code" name="code"></textarea></div>
|
||||
<div style="max-width: 50em; margin-bottom: 1em">HTML:<br>
|
||||
<textarea id="code-html" name="code-html"></textarea></div>
|
||||
<textarea id="code-html" name="code-html"></textarea></div>
|
||||
<div style="max-width: 50em; margin-bottom: 1em">JSON with custom widget:<br>
|
||||
<textarea id="code-json" name="code-json">
|
||||
{
|
||||
"menu": {
|
||||
"id": "file",
|
||||
"value": "File",
|
||||
"popup": {
|
||||
"menuitem": [
|
||||
{"value": "New", "onclick": "CreateNewDoc()"},
|
||||
{"value": "Open", "onclick": "OpenDoc()"},
|
||||
{"value": "Close", "onclick": "CloseDoc()"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</textarea></div>
|
||||
<div style="max-width: 50em">Python:<br>
|
||||
<textarea id="code-python" name="code">
|
||||
def foo():
|
||||
|
@ -89,6 +105,7 @@ window.onload = function() {
|
|||
var te_python = document.getElementById("code-python");
|
||||
var te_markdown = document.getElementById("code-markdown");
|
||||
te_markdown.value = "# Foo\n## Bar\n\nblah blah\n\n## Baz\n\nblah blah\n\n# Quux\n\nblah blah\n"
|
||||
var te_json = document.getElementById("code-json");
|
||||
|
||||
window.editor = CodeMirror.fromTextArea(te, {
|
||||
mode: "javascript",
|
||||
|
@ -100,6 +117,40 @@ window.onload = function() {
|
|||
});
|
||||
editor.foldCode(CodeMirror.Pos(13, 0));
|
||||
|
||||
window.editor_json = CodeMirror.fromTextArea(te_json, {
|
||||
mode: {name: "javascript", json: true},
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
|
||||
foldGutter: true,
|
||||
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
|
||||
foldOptions: {
|
||||
widget: (from, to) => {
|
||||
var count = undefined;
|
||||
|
||||
// Get open / close token
|
||||
var startToken = '{', endToken = '}';
|
||||
var prevLine = window.editor_json.getLine(from.line);
|
||||
if (prevLine.lastIndexOf('[') > prevLine.lastIndexOf('{')) {
|
||||
startToken = '[', endToken = ']';
|
||||
}
|
||||
|
||||
// Get json content
|
||||
var internal = window.editor_json.getRange(from, to);
|
||||
var toParse = startToken + internal + endToken;
|
||||
|
||||
// Get key count
|
||||
try {
|
||||
var parsed = JSON.parse(toParse);
|
||||
count = Object.keys(parsed).length;
|
||||
} catch(e) { }
|
||||
|
||||
return count ? `\u21A4${count}\u21A6` : '\u2194';
|
||||
}
|
||||
}
|
||||
});
|
||||
editor_json.foldCode(CodeMirror.Pos(5, 0));
|
||||
|
||||
window.editor_html = CodeMirror.fromTextArea(te_html, {
|
||||
mode: "text/html",
|
||||
lineNumbers: true,
|
||||
|
|
|
@ -2564,10 +2564,14 @@ editor.setOption("extraKeys", {
|
|||
and <code>CodeMirror.fold.xml</code>, for XML-style languages,
|
||||
and <code>CodeMirror.fold.comment</code>, for folding comment
|
||||
blocks.</dd>
|
||||
<dt><code><strong>widget</strong>: string|Element</code></dt>
|
||||
<dt><code><strong>widget</strong>: string | Element | fn(from: Pos, to: Pos) → string|Element</code></dt>
|
||||
<dd>The widget to show for folded ranges. Can be either a
|
||||
string, in which case it'll become a span with
|
||||
class <code>CodeMirror-foldmarker</code>, or a DOM node.</dd>
|
||||
class <code>CodeMirror-foldmarker</code>, or a DOM node.
|
||||
To dynamically generate the widget, this can be a function
|
||||
that returns a string or DOM node, which will then render
|
||||
as described. The function will be invoked with parameters
|
||||
identifying the range to be folded.</dd>
|
||||
<dt><code><strong>scanUp</strong>: boolean</code></dt>
|
||||
<dd>When true (default is false), the addon will try to find
|
||||
foldable ranges on the lines above the current one if there
|
||||
|
|
Loading…
Reference in New Issue