2019-03-06 09:55:04 +01:00
<!DOCTYPE html>
2021-09-22 21:55:33 +02:00
< html lang = "en" >
< head >
2019-03-06 09:55:04 +01:00
< meta charset = "utf-8" >
2023-07-16 14:30:46 +02:00
< meta name = "description" content = "Jq Play Offline is a web assembly
version of jqplay, allowing you to run the full featured
jq in your browser, without sending anything to any backend.">
< link rel = "icon" type = "image/png" href = "favicon.png" >
2021-09-22 21:55:33 +02:00
< title > Jq Play Offline< / title >
2021-10-03 17:44:07 +02:00
< script >
if('serviceWorker' in navigator) {
2021-10-03 17:50:22 +02:00
navigator.serviceWorker.register('/jq_offline/service_worker.js', { scope: '/jq_offline' })
2021-10-03 17:44:07 +02:00
.then(function(registration) {
console.log('Service Worker Registered');
})
.catch(e => {
console.log('Unable to register service worker', e);
});
navigator.serviceWorker.ready.then(function(registration) {
console.log('Service Worker Ready');
})
.catch(e => {
console.log('Service worker unable to get ready', e);
});
}
< / script >
2019-03-06 09:55:04 +01:00
< link rel = "stylesheet" href = "style.css" >
2021-09-22 22:13:09 +02:00
< script src = "https://cdn.biowasm.com/v2/aioli/latest/aioli.js" > < / script >
2021-09-22 21:55:33 +02:00
< script defer type = "module" >
2023-07-16 13:43:46 +02:00
async function setup() {
// Populate the form from the url parameters
let params = (new URL(document.location)).searchParams;
let query = params.get('query');
if (query) {
document.getElementById("filter").value = query;
}
}
2021-09-22 21:55:33 +02:00
async function jq() {
let data = document.getElementById("input-json").value;
let query = document.getElementById("filter").value;
let compactOutput = document.getElementById("compact-output").checked;
let sortKeys = document.getElementById("sort-keys").checked;
2023-07-16 13:43:46 +02:00
let rawInput = document.getElementById("raw-input").checked;
let rawOutput = document.getElementById("raw-output").checked;
let slurp = document.getElementById("slurp").checked;
2021-09-22 21:55:33 +02:00
let options = ["--monochrome-output"];
if (compactOutput) {
options.push("--compact-output");
}
if (sortKeys) {
options.push("--sort-keys");
}
2023-07-16 13:43:46 +02:00
if (rawInput) {
options.push("--raw-input");
}
if (rawOutput) {
options.push("--raw-output");
}
if (slurp) {
options.push("--slurp");
}
// Update url query params with current query
let params = (new URL(document.location)).searchParams;
params.set('query', query);
const url = new URL(document.location);
url.search = params.toString();
window.history.replaceState({}, 'Jq Offline', url);
2021-09-22 21:55:33 +02:00
// Create mock JSON file
await CLI.fs.writeFile("test.json", data);
options.push(query);
options.push("test.json");
let output = await CLI.exec("jq", options);
document.getElementById("output-json").value = output;
}
2019-03-06 09:55:04 +01:00
2021-09-22 21:55:33 +02:00
// buffer and call the callback only after no activity for "interval": aka debounce
// This reduces load on the browser by avoiding jq evaluation while the user is typing
function debounce(callback, interval) {
let debounceTimeoutId;
2019-03-06 09:55:04 +01:00
2021-09-22 21:55:33 +02:00
return function(...args) {
clearTimeout(debounceTimeoutId);
debounceTimeoutId = setTimeout(() => callback.apply(this, args), interval);
};
}
let delayedJq = debounce(jq, 400);
2023-07-16 13:43:46 +02:00
setup();
let CLI = await new Aioli("jq/1.6");
2021-09-22 21:55:33 +02:00
document.getElementById("filter").addEventListener('input', delayedJq);
document.getElementById("input-json").addEventListener('input', delayedJq);
document.getElementById("compact-output").addEventListener('input', jq);
document.getElementById("sort-keys").addEventListener('input', jq);
2023-07-16 13:43:46 +02:00
document.getElementById("raw-input").addEventListener('input', jq);
document.getElementById("raw-output").addEventListener('input', jq);
document.getElementById("slurp").addEventListener('input', jq);
2021-09-22 21:55:33 +02:00
// Call jq the first time without any changes
2023-07-16 13:43:46 +02:00
jq();
2021-09-22 21:55:33 +02:00
< / script >
< / head >
< body >
< div id = "top" >
< h1 > Jq Play Offline< / h1 >
2023-07-16 14:30:46 +02:00
< div id = "links" >
< a href = "https://gitlab.com/jiehong/jq_offline" target = "_blank" > Code< / a >
< a href = "https://stedolan.github.io/jq/manual/v1.6/" target = "_blank" > Manual< / a >
< / div >
2021-09-22 21:55:33 +02:00
< / div >
< div id = "content" >
< div id = "query" >
< label id = "filter-label" for = "filter" > Query< / label >
2021-10-03 10:43:02 +02:00
< input
id="filter"
type="text"
name="filter"
2021-10-02 23:48:22 +02:00
autocapitalize="off"
2021-10-03 10:43:02 +02:00
autocomplete="on"
2021-10-02 23:48:22 +02:00
spellcheck="false"
autocorrect="off"
2023-07-16 13:43:46 +02:00
autofocus
2021-10-02 23:48:22 +02:00
/>
2021-09-22 21:55:33 +02:00
< ul id = "options" >
< p > Options< / p >
< li >
< input type = "checkbox" id = "compact-output" name = "co" >
2023-07-16 13:43:46 +02:00
< label for = "co" title = "By default, jq pretty-prints JSON output. Using this option will result in more compact output by instead putting each JSON object on a single line." > --compact-output< / label >
2021-09-22 21:55:33 +02:00
< / li >
< li >
< input type = "checkbox" id = "sort-keys" name = "sk" >
2023-07-16 13:43:46 +02:00
< label for = "sk" title = "Output the fields of each object with the keys in sorted order." > --sort-key< / label >
< / li >
< li >
< input type = "checkbox" id = "raw-input" name = "ri" >
< label for = "ri" title = "Don't parse the input as JSON. Instead, each line of text is passed to the filter as a string. If combined with --slurp, then the entire input is passed to the filter as a single long string." > --raw-input< / label >
< / li >
< li >
< input type = "checkbox" id = "raw-output" name = "ro" >
< label for = "ro" title = "With this option, if the filter's result is a string then it will be written directly to standard output rather than being formatted as a JSON string with quotes. This can be useful for making jq filters talk to non-JSON-based systems." > --raw-output< / label >
< / li >
< li >
< input type = "checkbox" id = "slurp" name = "s" >
< label for = "s" title = "Instead of running the filter for each JSON object in the input, read the entire input stream into a large array and run the filter just once." > --slurp< / label >
2021-09-22 21:55:33 +02:00
< / li >
< / ul >
< / div >
2021-10-03 10:43:02 +02:00
2021-09-22 21:55:33 +02:00
< div id = "input" >
< label id = "input-label" for = "input-json" > Input< / label >
2021-10-03 10:43:02 +02:00
< textarea
id="input-json"
name="input"
placeholder="Paste your input json here"
autocapitalize="off"
autocomplete="off"
spellcheck="false"
autocorrect="off"
>< / textarea >
2021-09-22 21:55:33 +02:00
< / div >
< div id = "output" >
< label id = "output-label" for = "output-json" > Result< / label >
2021-10-03 10:43:02 +02:00
< textarea
id="output-json"
placeholder="Output will appear here"
readonly
>< / textarea >
2021-09-22 21:55:33 +02:00
< / div >
< / div >
< / body >
2019-03-06 09:55:04 +01:00
2021-09-22 21:55:33 +02:00
< / html >