-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathindex.html
273 lines (244 loc) · 8.75 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="Robert Aboukhalil">
<title>jq kung fu</title>
<!-- Bootstrap core CSS -->
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
<style>
body { padding-top: 5rem; }
#error { color: red; }
</style>
</head>
<body>
<nav class="navbar navbar-dark bg-warning fixed-top mt-0" style="padding-top: 2px;">
<div class="text-center text-dark small w-100">
Check out sandbox.bio's jq playground at <a href="https://sandbox.bio/playgrounds?id=jq">sandbox.bio/playgrounds?id=jq</a>
</div>
</nav>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top mt-4">
<div class="navbar-brand">
<strong>jq kung fu</strong>
<small class="ml-3 text-light">
A jq playground built with WebAssembly
</small>
</div>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto"></ul>
<div>
<a style="color:#ccc" class="nav-link" href="https://github.com/robertaboukhalil/jqkungfu" target="_blank">Code on GitHub</a>
</div>
</div>
</nav>
<div class="text-center mt-3">
<p id="loading" class="lead">
<img src="loading.gif" alt="Loading..." height="100">
</p>
</div>
<main id="jq" role="main" class="container" style="display: none">
<div class="row">
<div class="col-md-11">
<small>Your query:</small>
</div>
<div class="col-md-11">
<textarea data-autoresize class="form-control" id="query" autofocus>.[1]</textarea>
<small>
<span id="error"></span>
</small>
<br /><br />
</div>
<div class="col-md-1">
<input id="btnRun" type="button" value="Go" class="form-control" disabled>
</div>
</div>
<div class="row">
<div class="col-md-6">
<small>Input JSON <small>(sample data from <a href="https://jsonplaceholder.typicode.com/" target="_blank">JSONPlaceholder</a>):</small></small>
<div id="input" style="height: 65vh;">[
{
"postId": 1,
"id": 4,
"name": "alias odio sit",
"email": "[email protected]",
"body": "non et atque\noccaecati deserunt quas accusantium unde odit nobis qui voluptatem\nquia voluptas consequuntur itaque dolor\net qui rerum deleniti ut occaecati"
},
{
"postId": 1,
"id": 5,
"name": "vero eaque aliquid doloribus et culpa",
"email": "[email protected]",
"body": "harum non quasi et ratione\ntempore iure ex voluptates in ratione\nharum architecto fugit inventore cupiditate\nvoluptates magni quo et"
},
{
"postId": 2,
"id": 6,
"name": "et fugit eligendi deleniti quidem qui sint nihil autem",
"email": "[email protected]",
"body": "doloribus at sed quis culpa deserunt consectetur qui praesentium\naccusamus fugiat dicta\nvoluptatem rerum ut voluptate autem\nvoluptatem repellendus aspernatur dolorem in"
},
{
"postId": 2,
"id": 7,
"name": "repellat consequatur praesentium vel minus molestias voluptatum",
"email": "[email protected]",
"body": "maiores sed dolores similique labore et inventore et\nquasi temporibus esse sunt id et\neos voluptatem aliquam\naliquid ratione corporis molestiae mollitia quia et magnam dolor"
}
]</div>
</div>
<div class="col-md-6">
<div class="row small">
<div class="col-md-3">
Output JSON:
</div>
<div class="col-md-9 text-right">
<input id="jq-options-slurp" class="jq-options" type="checkbox" data-cli="-s">
<label for="jq-options-slurp">Slurp</label>
<input id="jq-options-compact" class="jq-options" type="checkbox" data-cli="-c">
<label for="jq-options-compact">Compact</label>
<input id="jq-options-raw" class="jq-options" type="checkbox" data-cli="-r">
<label for="jq-options-raw">Raw</label>
<input id="jq-options-sort" class="jq-options" type="checkbox" data-cli="-S">
<label for="jq-options-sort">Sort Keys</label>
</div>
</div>
<div id="output" style="height: 65vh;">{
"postId": 1,
"id": 5,
"name": "vero eaque aliquid doloribus et culpa",
"email": "[email protected]",
"body": "harum non quasi et ratione\ntempore iure ex voluptates in ratione\nharum architecto fugit inventore cupiditate\nvoluptates magni quo et"
}</div>
</div>
</div>
<div class="row">
<div class="col-md-12 text-center">
<hr />
<!-- <br /> -->
<p>Want to learn how to build WebAssembly applications like this one? Check out my book <a href="http://levelupwasm.com" target="_blank">Level Up with WebAssembly</a>.</p>
</div>
</div>
</main>
<!-- Main logic -->
<script type="text/javascript">
// WebAssembly module config
var STDOUT = [],
STDERR = [],
FILE_DATA = "/tmp/data.json",
CONFIG_EDITOR = {
mode: "ace/mode/json",
selectionStyle: "text",
tabSize: 2
};
var Module = {
// Don't run main on page load
noInitialRun: true,
// Print functions
print: stdout => STDOUT.push(stdout),
printErr: stderr => STDERR.push(stderr),
// When the module is ready
onRuntimeInitialized: function() {
document.getElementById("loading").style.display = "none";
document.getElementById("jq").style.display = "block";
document.getElementById("btnRun").disabled = false;
}
};
// Utility function to run jq
function jq(jsonStr, query, options)
{
// Custom jq options.
// Default = -M = disable colors
var mainOptions = [ "-M" ];
if(options != null && options.length > 0)
mainOptions = mainOptions.concat(options);
// Create file from object
FS.writeFile(FILE_DATA, jsonStr);
// Clear previous stdout/stderr before launching jq
STDOUT = [];
STDERR = [];
// Launch jq's main() function
mainOptions = mainOptions.concat([ query, FILE_DATA ]);
Module.callMain(mainOptions);
// Re-open stdout/stderr after jq closes them
FS.streams[1] = FS.open("/dev/stdout", "w");
FS.streams[2] = FS.open("/dev/stderr", "w");
return {
stdout: STDOUT.join("\n"),
stderr: `${STDERR[0]}\n${STDERR[1]}`
}
}
// Launch jq on current field values
function launch()
{
var elError = document.getElementById("error"),
elQuery = document.getElementById("query"),
elsOptions = document.getElementsByClassName("jq-options");
// Collect options
var options = [];
for(var el of elsOptions)
if(el.checked)
options.push(el.getAttribute("data-cli"));
// Call jq
var out = jq(editorInput.getValue(), elQuery.value, options);
// Parse jq errors
elError.innerHTML = "";
if(out.stdout != "")
editorOutput.setValue(out.stdout, 1);
else
elError.innerHTML = out.stderr;
}
// On page load
document.addEventListener("DOMContentLoaded", function()
{
// Launch jq when click button
document.getElementById("btnRun").addEventListener("click", launch);
// Auto-resizing input textarea (https://stephanwagner.me/auto-resizing-textarea-with-vanilla-javascript)
document.querySelectorAll("[data-autoresize]").forEach(function (element) {
element.style.boxSizing = "border-box";
const offset = element.offsetHeight - element.clientHeight;
element.addEventListener("input", function (event) {
event.target.style.height = "auto";
event.target.style.height = event.target.scrollHeight + offset + "px";
});
element.removeAttribute("data-autoresize");
});
// Setup ACE editors
var elInput = document.getElementById("input"),
elOutput = document.getElementById("output"),
elQuery = document.getElementById("query"),
elsOptions = document.getElementsByClassName("jq-options");
editorInput = ace.edit(elInput, CONFIG_EDITOR);
editorOutput = ace.edit(elOutput, CONFIG_EDITOR);
editorInput.getSession().on("change", launch);
// Logic for auto-launching jq
var timerIsTyping = null;
elQuery.addEventListener("keyup", function(e)
{
// Detect pressing Enter
if(e.keyCode == 13)
launch();
// Auto launch after 300ms post changing the query
clearTimeout(timerIsTyping);
timerIsTyping = setTimeout(launch, 300);
});
elQuery.addEventListener("keydown", function(e){
clearTimeout(timerIsTyping);
});
// Output options
for(var el of elsOptions)
el.addEventListener("change", launch);
});
</script>
<!-- JS Libraries -->
<script src="build/jq.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.2/ace.js"></script>
</body>
</html>