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" >
2023-11-08 16:50:33 +01:00
< script src = "https://biowasm.com/cdn/v3/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;
2023-11-21 17:05:00 +01:00
let query = params.get('query');
2023-07-16 13:43:46 +02:00
if (query) {
document.getElementById("filter").value = query;
}
2023-11-21 17:05:00 +01:00
['compact-output', 'sort-keys', 'raw-input', 'raw-output', 'slurp'].forEach(option => {
let p = params.get(option);
if (p === 'true') {
document.getElementById(option).checked = true;
}
});
2023-07-16 13:43:46 +02:00
}
2021-09-22 21:55:33 +02:00
async function jq() {
let data = document.getElementById("input-json").value;
let query = document.getElementById("filter").value;
2023-11-21 17:05:00 +01:00
let params = (new URL(document.location)).searchParams;
2021-09-22 21:55:33 +02:00
let options = ["--monochrome-output"];
2023-11-21 17:05:00 +01:00
['compact-output', 'sort-keys', 'raw-input', 'raw-output', 'slurp'].forEach(option => {
let part = document.getElementById(option).checked;
if (part) {
params.set(option, true);
options.push('--' + option);
} else {
params.delete(option);
}
});
2023-07-16 13:43:46 +02:00
// Update url query params with current query
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();
2023-11-21 16:41:40 +01:00
let CLI = await new Aioli("jq/1.7");
2023-07-16 13:43:46 +02:00
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 >
2023-11-21 16:41:40 +01:00
< a href = "https://jqlang.github.io/jq/manual/v1.7/" target = "_blank" > Manual (jq 1.7)< / a >
2023-07-16 14:30:46 +02:00
< / 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
2023-11-08 16:50:33 +01:00
< / html >