client/index.html (599 lines of code) (raw):
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CQL sandbox</title>
<style>
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
font-size: 100%;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
}
/*
1. Use a more-intuitive box-sizing model.
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
/*
Typographic tweaks!
3. Add accessible line-height
4. Improve text rendering
*/
body {
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
/*
5. Improve media defaults
*/
img,
picture,
video,
canvas,
svg {
display: block;
max-width: 100%;
}
/*
6. Remove built-in form typography styles
*/
input,
button,
textarea,
select {
font: inherit;
}
/*
7. Avoid text overflows
*/
p,
h1,
h2,
h3,
h4,
h5,
h6 {
overflow-wrap: break-word;
}
/*
8. Create a root stacking context
*/
#root,
#__next {
isolation: isolate;
}
.Page__header {
display: flex;
align-items: center;
}
.Page__repo-link {
display: flex;
align-items: center;
font-weight: bold;
margin-left: auto;
}
.Page__repo-link:visited {
color: #ccc;
}
.CqlSandbox__debug-container {
margin-top: 10px;
white-space: pre;
font-family: monospace;
}
.CqlDebug__json {
display: flex;
}
.CqlDebug__json > div {
display: flex;
flex-direction: column;
}
.CqlDebug__mapping {
display: flex;
flex-direction: column;
}
.CqlDebug__queryDiagramToken,
.CqlDebug__queryDiagramNode {
margin-bottom: 6rem;
}
.CqlDebug__queryDiagramNode > .CqlDebug__queryDiagramLabel {
padding-top: 0rem;
}
.CqlDebug__queryDiagramNode > .CqlDebug__queryDiagramLabel div + div {
padding-top: 1rem;
}
.Cql__Debug > div {
flex-grow: 1;
}
.CqlDebug__queryDiagram {
display: flex;
}
.CqlDebug__queryDiagramLabel {
padding-top: 2rem;
padding-right: 1rem;
display: flex;
flex-direction: column;
}
.CqlDebug__queryDiagramContent {
display: flex;
}
.CqlDebug__queryBox {
position: relative;
display: flex;
flex-direction: column;
flex-grow: 0;
width: 25px;
padding: 1rem 0;
}
.CqlDebug__queryBox--offset > .CqlDebug__originalChar {
position: relative;
left: 50%;
top: -2rem;
}
.CqlDebug__queryBox--offset > .CqlDebug__queryChar {
position: relative;
left: -50%;
}
.CqlDebug__queryBox > div {
width: 1em;
height: 1rem;
}
.CqlDebug__originalChar {
background-color: rgb(49, 78, 55);
}
.CqlDebug__queryChar {
background-color: rgb(49, 78, 55);
}
.CqlDebug__queryChar + .CqlDebug__queryChar {
margin-top: 3px;
}
.CqlDebug__queryCharAlt {
background-color: rgb(74, 105, 120);
}
.CqlDebug__nodeChar {
background-color: rgb(130, 82, 82);
position: absolute;
bottom: 1rem;
left: -50%;
}
.CqlDebug__nodeLabel,
.CqlDebug__tokenLabel {
position: absolute;
top: 5rem;
width: 1em;
transform: rotate(90deg);
}
.CqlDebug__nodeLabel {
left: 50%;
}
.CqlDebug__nodeDiagram {
display: flex;
}
.CqlSandbox {
margin-top: 30px;
}
.CqlSandbox__query-results {
display: flex;
}
.CqlSandbox__query-results > div {
flex-grow: 1;
}
input {
position: relative;
padding: 5px;
border: 2px solid grey;
border-radius: 5px;
background: none;
color: rgba(255, 255, 255, 0.87);
}
.tree--container {
display: flex;
align-items: center;
flex-direction: column;
width: 100%;
}
.tree {
display: block;
max-width: 100%;
margin-top: 5px;
overflow-y: scroll;
}
/*https://www.cssscript.com/clean-tree-diagram/*/
.tree,
.tree ul,
.tree li {
font-family: monospace;
list-style: none;
margin: 0;
padding: 0;
position: relative;
}
.tree {
margin: 0 0 1em;
text-align: center;
white-space: initial;
}
.tree,
.tree ul {
display: table;
}
.tree ul {
width: 100%;
}
.tree li {
display: table-cell;
padding: 0.5rem 0;
vertical-align: top;
}
.tree li:before {
outline: solid 0.5px #666;
content: "";
left: 0;
position: absolute;
right: 0;
top: -1px;
}
.tree li:first-child:before {
left: 50%;
}
.tree li:last-child:before {
right: 50%;
}
.tree code,
.tree li > span {
background-color: #4b6978;
border-radius: 0.2em;
display: inline-block;
margin: 0 0.2em 0.5em;
padding: 0.2em 0.5em;
position: relative;
}
.node-content {
background-color: rgb(71, 75, 86);
margin-left: 5px;
padding: 1px 5px;
}
.node-pos {
line-break: normal;
padding: 0 4px;
}
.tree ul:before,
.tree code:before,
.tree li > span:before {
outline: solid 0.5px #666;
content: "";
height: 0.5em;
left: 50%;
position: absolute;
}
.tree ul:before {
top: -0.5em;
}
.tree code:before,
.tree li > span:before {
top: -0.55em;
}
.tree > li {
margin-top: 0;
}
.tree > li:before,
.tree > li:after,
.tree > li > code:before,
.tree > li > .span:before {
outline: none;
}
.CqlToken__STRING {
color: lightblue;
}
.CqlToken__AND,
.CqlToken__OR {
color: magenta;
}
.CqlToken__RIGHT_BRACKET,
.CqlToken__LEFT_BRACKET {
color: lightpink;
}
.Cql__ContentEditable.ProseMirror-focused {
outline: 2px solid lightblue;
}
</style>
</head>
<body>
<div id="app">
<div class="Page__header">
<h1>Rich query sandbox</h1>
<a
class="Page__repo-link"
href="https://github.com/guardian/cql"
target="_blank"
>
Repo
<svg
width="20"
height="18"
viewBox="0 0 98 96"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"
fill="#eee"
/>
</svg>
</a>
</div>
<div>
<label for="data-source">Search:</label>
<select id="data-source">
<option value="content-api">Content API</option>
<option value="tools-index">Tools Index</option>
<option value="content-api-simple-input">Content API simple input</option>
</select>
</div>
<div id="cql-input-container">
<cql-input-capi
initial-value=""
id="cql-input"
popover-container-id="popover-container"
></cql-input-capi>
<div id="error"></div>
</div>
<p>Press <tt>+</tt> to select a specific field to search.</p>
<p>
Join search terms with <tt class="CqlToken__AND">OR</tt> and
<tt class="CqlToken__AND">AND</tt>. Consecutive search terms, e.g.
<tt class="CqlToken__STRING">this that</tt>, are implicitly joined with
<tt class="CqlToken__OR">OR</tt>.
</p>
<p>
Group expressions with parenthesis, e.g.
<tt class="CqlToken__STRING"
>one <tt class="CqlToken__LEFT_BRACKET">(</tt>two
<tt class="CqlToken__AND">AND</tt> three<tt
class="CqlToken__RIGHT_BRACKET"
>)</tt
></tt
>
</p>
<div id="cql-sandbox" class="CqlSandbox">
<div class="CqlSandbox__query-results">
<div>
<h2>CQL</h2>
<div id="cql"></div>
</div>
<div>
<h2>API query</h2>
<div id="query"></div>
</div>
</div>
<h2>Config</h2>
<div class="CqlSandbox__input-container">
<input
type="text"
id="endpoint"
placeholder="Add a CQL language server endpoint"
/>
</div>
<div class="CqlSandbox__popover-container" id="popover-container"></div>
</div>
</div>
<script type="module" src="/src/page.ts"></script>
<h2 id="todos">Todos</h2>
<ul>
<li><input checked type="checkbox" /> Scanning</li>
<li><input checked type="checkbox" /> Parsing</li>
<li><input checked type="checkbox" /> Query string builder</li>
<li><input checked type="checkbox" /> Add group and binary syntax</li>
<li><input checked type="checkbox" /> String ranges in scanned tokens</li>
<li><input checked type="checkbox" /> Parse hints for typeahead</li>
<li>
<input checked type="checkbox" />
<del>ScalaJS to provide parser in web env</del> ScalaJS adds 180kb to
your bundle as the price of entry? Yeah we're not doing that
</li>
<li>
<input checked type="checkbox" /> Add a language server for funsies
</li>
<li>
<input checked type="checkbox" /> Web component - environment and first
pass at component infra
</li>
<li>
<input checked type="checkbox" /> Web component - syntax highlighting
<ul>
<li>
<input checked type="checkbox" /> Ensure untokenised string
components still display, we're getting 500s and invisible
characters on trailing + chars
</li>
</ul>
</li>
<li>
<input checked type="checkbox" /> Web component - typeahead
<ul>
<li>
<input checked type="checkbox" /> First pass at implementation
</li>
<li>
<input checked type="checkbox" /> Handle typing on the trailing edge
(off by one)
</li>
</ul>
</li>
<li>
<input type="checkbox" /> Web component - async lookup
<ul>
<li>
<input checked type="checkbox" /> Implement async lookup in language
server
</li>
<li><input type="checkbox" /> Add loading state</li>
</ul>
</li>
<li>
<input checked type="checkbox" /> Bug: open parentheses crashes the
server 🙃
</li>
<li><input checked type="checkbox" /> Fix tests</li>
<li><input checked type="checkbox" /> Fix input scrolling</li>
<li>
<input checked type="checkbox" /> Bug: fix crash on adding query meta
within parentheses or after binary operators (with useful error state)
</li>
<li>
<input checked type="checkbox" /> Add '@' syntax for content
return format (e.g. show-fields)
<ul>
<li>
<input checked type="checkbox" /> Fix issue with incomplete binaries
and output modifiers
</li>
</ul>
</li>
<li>
<input type="checkbox" /> Fill out additional fields:
<ul>
<li>
<input checked type="checkbox" /> Dates!
<ul>
<li>
<input checked type="checkbox" /> Add <code>type</code> property
to suggestion envelope to ensure correct interface is displayed
(NB: Circe wraps sealed trait in object with single key as name
of class)
</li>
<li>
<input checked type="checkbox" /> Correct focus when date
appears
</li>
<li>
<input checked type="checkbox" /> What do we do when users want
to navigate through the string without focus being stolen?
Perhaps we don't need to autofocus? Solution for now:
autofocus on first input, keydown or tab to focus input when
value is already present (to allow user to scrub through dates
unimpeded)
</li>
<li>
<input type="checkbox" /> Parse to correct format for query
</li>
</ul>
</li>
<li><input type="checkbox" /> Other, less fancy fields</li>
</ul>
</li>
<li><input checked type="checkbox" /> Fix crash on empty parens</li>
<li>
<input checked type="checkbox" /> Fix crash on leading colon when key is
not valid query or output key
</li>
<li>
<input checked type="checkbox" /> Move to contenteditable (ProseMirror)
(issues with scrolling in Chrome, e.g.
<a href="https://issues.chromium.org/issues/41081857"
>https://issues.chromium.org/issues/41081857</a
>, make syncing scroll state of overlay difficult)
</li>
<li>
<input checked type="checkbox" /> Handle keyboard navigation on
typeahead menu
</li>
<li>
<input checked type="checkbox" /> Handle selection on typeahead menu
(including clicks)
</li>
<li>
<input checked type="checkbox" /> Correctly display typeahead menu when
there's no content in a chip key or value
</li>
<li><input checked type="checkbox" /> Serialise to CQL string on copy</li>
<li>
<input checked type="checkbox" /> Deletion pattern for chips on
backspace
</li>
<li><input checked type="checkbox" /> Deletion handle for chips UI</li>
<li><input type="checkbox" checked /> Add good testing story</li>
<li>
<input type="checkbox" checked /> 🐛 Suggestions are off by one for
consecutive chips
</li>
<li><input type="checkbox" checked /> Date suggestions</li>
<li><input type="checkbox" /> Relative date suggestions as options</li>
<li><input type="checkbox" /> Chip polarity</li>
<li><input type="checkbox" /> Add typeahead for binaries</li>
<li>
<input type="checkbox" checked /> Error handling, with position, when
the query is malformed
</li>
<li>
<input type="checkbox" checked /> Error handling for >>399 codes
</li>
<li>
<input type="checkbox" /> Cursor movement:
<ul>
<li>
<input type="checkbox" checked /> Ctrl-a, Ctrl-e to move to start
and end of doc
</li>
<li><input type="checkbox" /> ...</li>
</ul>
</li>
<li><input type="checkbox" />Display labels, not values, in chips?</li>
<li>
<input type="checkbox" checked />Move language server to client:
<ul>
<li><input type="checkbox" checked /> Move code and tests</li>
</ul>
</li>
<li>
<input type="checkbox" /> Align typeahead interfaces with server,
simplifying structure
</li>
<li>
<input type="checkbox" /> Accessibility:
<ul>
<li><input type="checkbox" /> ...</li>
</ul>
</li>
<li>
<input type="checkbox" /> Telemetry:
<ul>
<li><input type="checkbox" /> Create chip</li>
<li><input type="checkbox" /> Autocomplete key, value selection</li>
<li><input type="checkbox" /> Remove chip – mouse</li>
<li><input type="checkbox" /> Remove chip – backspace</li>
<li><input type="checkbox" /> Tab behaviour?</li>
<li><input type="checkbox" /> Paste?</li>
<li><input type="checkbox" /> ...</li>
</ul>
</li>
<li><input type="checkbox" /> ...</li>
</ul>
<h3 id="infra">Infra</h3>
<ul>
<li><input checked type="checkbox" /> Configure CI for lambda</li>
<li><input checked type="checkbox" /> Add handler for lambda</li>
<li><input checked type="checkbox" /> Add CI for static site</li>
<li><input checked type="checkbox" /> Add configuration for CAPI key</li>
<li><input type="checkbox" /> ...</li>
</ul>
</body>
</html>