Skip to content

Commit

Permalink
Add list separator plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
LeaVerou committed Aug 3, 2021
1 parent 549ee91 commit 86447b4
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 0 deletions.
38 changes: 38 additions & 0 deletions list-separator/mavo-list-separator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Mavo.Plugins.register("list-separator", {
hooks: {
"collection-init-end": function() {
this.separator = this.element.getAttribute("mv-list-separator");

if (["\\n", "\\r", "\\r\\n"].includes(this.separator)) {
// Handle line breaks specially, parse any line break, store with detected line break
this.separator = /\r?\n/g;
this.joinSeparator = "\n"; // Default line break to join with
}

// TODO ignore separator if this is not a collection of primitives and print error
},
"node-getdata-end": function(env) {
if (this instanceof Mavo.Collection && this.separator) {
// Escape separator in data
let data = env.data.map(s => (s + "").replaceAll(this.separator, "\\$&"));
env.data = data.join(this.joinSeparator ?? this.separator);
}
},
"node-render-start": function(env) {
if (this instanceof Mavo.Collection && this.separator && env.data.split) {
let separatorString = this.separator.source ?? this.separator;
let separator = RegExp(`(?<!\\\\)${separatorString}`, "g");
let data = env.data.split(separator);

if (this.separator instanceof RegExp && data.length > 1) {
// If the separator is a regexp, we need to store the first occurrence and use it to join when saving
this.joinSeparator = env.data.match(separator)[0];
}

// Unescape separator in the data
data = data.map(s => s.replace(RegExp(`\\\\(?=${separatorString})`, "g"), ""));
env.data = data;
}
}
}
});
134 changes: 134 additions & 0 deletions list-separator/test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<!DOCTYPE html>
<html lang="el">
<head>
<meta charset="UTF-8">
<title>List separator tests</title>
<link rel="stylesheet" href="https://test.mavo.io/style.css" />
<link rel="stylesheet" href="https://get.mavo.io/mavo.css" />
<script src="https://get.mavo.io/mavo.js"></script>
<style>
[mv-list-item] {
border: 1px solid silver;
padding: .2em;
margin: .2em;
background: hsl(0 0% 100% / .3);
white-space: pre-line
}
</style>
</head>
<body>

<h1>List separator tests</h1>
<pre id="datarr">
{
"foo": ["1, 4", "2", "3"]
}
</pre>

<section>
<h1>Basic</h1>

<table class="reftest" data-click=".mv-bar .mv-save wait .1s">
<tr title="Load array, save string">
<td mv-app mv-source="#datarr" mv-storage="#data2">
<div mv-list="foo" mv-list-separator=", ">
<span mv-list-item=""></span>
</div>
</td>
<td>
1, 423
</td>
</tr>
<tr>
<td>
<pre id="data2"></pre>
</td>
<td>
<pre>{
"foo": "1\\, 4, 2, 3"
}</pre>
</td>
</tr>
<tr title="Load string, save string" data-click="[mv-action] after mv-load wait .1s, .mv-save after mv-load wait .3s">
<td mv-app mv-source="#data2" mv-storage="#data3">
<div mv-list="foo" mv-list-separator=", ">
<span mv-list-item=""></span>
</div>
<button mv-action="add(5, foo)" class="test-content-ignore">Add foo</button>
</td>
<td>
1, 4235
</td>
</tr>
<tr>
<td>
<pre id="data3"></pre>
</td>
<td>
<pre>{
"foo": "1\\, 4, 2, 3, 5"
}</pre>
</td>
</tr>
</table>
</section>

<section>
<h1>Line breaks</h1>

<pre id="datarr2">{
"foo": ["1\n4", "2", "3"]
}</pre>

<table class="reftest" data-click=".mv-bar .mv-save wait .1s">
<tr title="Load array, save string">
<td mv-app mv-source="#datarr2" mv-storage="#data4">
<div mv-list="foo" mv-list-separator="\n">
<span mv-list-item=""></span>
</div>
</td>
<td>
1
423
</td>
</tr>
<tr>
<td>
<pre id="data4"></pre>
</td>
<td>
<pre>{
"foo": "1\\\n4\n2\n3"
}</pre>
</td>
</tr>
<tr title="Load string, save string" data-click="[mv-action] after mv-load wait .1s, .mv-save after mv-load wait .3s">
<td mv-app mv-source="#data4" mv-storage="#data5">
<div mv-list="foo" mv-list-separator="\n">
<span mv-list-item=""></span>
</div>
<button mv-action="add(5, foo)" class="test-content-ignore">Add foo</button>
</td>
<td>
1
4235
</td>
</tr>
<tr>
<td>
<pre id="data5"></pre>
</td>
<td>
<pre>{
"foo": "1\\\n4\n2\n3\n5"
}</pre>
</td>
</tr>
</table>
</section>

<script src="mavo-list-separator.js"></script>
<script src="https://test.mavo.io/test.js"></script>

</body>
</html>
7 changes: 7 additions & 0 deletions plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@
"repo": "DmitrySharabin/mavo-gsheets",
"author": "dmitrysharabin"
},
{
"name": "List Separator",
"id": "list-separator",
"description": "Store and read lists of simple properties as a single string. Useful in conjunction with the Google Sheets plugin to store multiple values in a single cell.",
"tag": [],
"author": "leaverou"
},
{
"name": "Google Drive",
"id": "gdrive",
Expand Down

0 comments on commit 86447b4

Please sign in to comment.