feat: update the playground from upstream reference
This commit is contained in:
committed by
Michael Hoffmann
parent
3a58dc8928
commit
f5ebf32b8c
163
docs/index.html
163
docs/index.html
@@ -1,83 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Tree Sitter HCL Playground</title>
|
||||
<style>
|
||||
#playground-container {
|
||||
max-width: 640px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
#playground-container .CodeMirror {
|
||||
border: 1px solid;
|
||||
}
|
||||
#create-issue-btn {
|
||||
padding: 0.2em;
|
||||
float: right;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
#checkboxes {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
#output-container {
|
||||
border: 1px solid;
|
||||
}
|
||||
.highlight {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!--
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Tree Sitter HCL Playground</title>
|
||||
<style>
|
||||
#playground-container {
|
||||
max-width: 640px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
#playground-container .CodeMirror {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
#create-issue-btn {
|
||||
padding: 0.2em;
|
||||
float: right;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
#checkboxes {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
#output-container {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!--
|
||||
This file is licensed under MIT license
|
||||
Copyright (c) 2018 Max Brunsfeld
|
||||
Taken from https://github.com/tree-sitter/tree-sitter/docs/section-7-playground.html
|
||||
-->
|
||||
Taken from https://github.com/tree-sitter/tree-sitter/blob/master/docs/src/7-playground.md
|
||||
-->
|
||||
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.45.0/codemirror.min.css"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/clusterize.js/0.18.0/clusterize.min.css"
|
||||
/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/6.65.7/codemirror.min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/clusterize.js/0.19.0/clusterize.min.css">
|
||||
|
||||
<div id="playground-container">
|
||||
<h1>Tree Sitter HCL Playground</h1>
|
||||
<h4>Code</h4>
|
||||
<div id="checkboxes">
|
||||
<input id="logging-checkbox" type="checkbox" />
|
||||
<label for="logging-checkbox">Log</label>
|
||||
<h1>Tree Sitter HCL Playground</h1>
|
||||
|
||||
<input id="query-checkbox" type="checkbox" />
|
||||
<label for="query-checkbox">Query</label>
|
||||
<div id="playground-container" class="ts-playground" style="visibility: hidden;">
|
||||
<h2>Code</h2>
|
||||
|
||||
<div class="custom-select">
|
||||
<button id="language-button" class="select-button">
|
||||
<span class="selected-value">JavaScript</span>
|
||||
<svg class="arrow" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<polyline points="6 9 12 15 18 9"></polyline>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="select-dropdown">
|
||||
<div class="option" data-value="hcl">HCL</div>
|
||||
</div>
|
||||
<select id="language-select" style="display: none;">
|
||||
<option value="hcl">HCL</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<textarea id="code-input">
|
||||
<input id="logging-checkbox" type="checkbox"></input>
|
||||
<label for="logging-checkbox">Log</label>
|
||||
|
||||
<input id="anonymous-nodes-checkbox" type="checkbox"></input>
|
||||
<label for="anonymous-nodes-checkbox">Show anonymous nodes</label>
|
||||
|
||||
<input id="query-checkbox" type="checkbox"></input>
|
||||
<label for="query-checkbox">Query</label>
|
||||
|
||||
<input id="accessibility-checkbox" type="checkbox"></input>
|
||||
<label for="accessibility-checkbox">Accessibility</label>
|
||||
|
||||
<textarea id="code-input">
|
||||
example "test" {
|
||||
foo = "bar"
|
||||
}
|
||||
</textarea>
|
||||
</textarea>
|
||||
|
||||
<div id="query-container" style="visibility: hidden; position: absolute">
|
||||
<h4>Query</h4>
|
||||
<textarea id="query-input"></textarea>
|
||||
</div>
|
||||
|
||||
<h4>Tree</h4>
|
||||
<span id="update-time"></span>
|
||||
<div id="output-container-scroll">
|
||||
<pre id="output-container" class="highlight"></pre>
|
||||
</div>
|
||||
<button id="create-issue-btn" type="button">Create Issue</button>
|
||||
<div id="query-container" style="visibility: hidden; position: absolute;">
|
||||
<h2>Query</h2>
|
||||
<textarea id="query-input"></textarea>
|
||||
</div>
|
||||
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.45.0/codemirror.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/clusterize.js/0.18.0/clusterize.min.js"></script>
|
||||
<script src="./vendor/tree-sitter.js"></script>
|
||||
<script id="playground-script" src="./playground.js?v=3"></script>
|
||||
</body>
|
||||
<h2>Tree</h2>
|
||||
<span id="update-time"></span>
|
||||
<div id="output-container-scroll">
|
||||
<pre id="output-container" class="highlight"></pre>
|
||||
</div>
|
||||
<button id="create-issue-btn" type="button">Create Issue</button>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/6.65.7/codemirror.min.js"></script>
|
||||
<script id="playground-script" src="./playground.js?v=3"></script>
|
||||
|
||||
<script type="module">
|
||||
import * as TreeSitter from './vendor/web-tree-sitter.js';
|
||||
window.TreeSitter = TreeSitter;
|
||||
setTimeout(() => window.initializePlayground({ local: false }), 1);
|
||||
</script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/clusterize.js/0.19.0/clusterize.min.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,49 +1,146 @@
|
||||
// This file is licensed under MIT license
|
||||
// Copyright (c) 2018 Max Brunsfeld
|
||||
// Taken from https://github.com/tree-sitter/tree-sitter/docs/assets/playground.js
|
||||
let tree;
|
||||
// Taken from https://github.com/tree-sitter/tree-sitter/docs/src/assets/js/playground.js
|
||||
|
||||
function initializeLocalTheme() {
|
||||
const themeToggle = document.getElementById('theme-toggle');
|
||||
if (!themeToggle) return;
|
||||
|
||||
// Load saved theme or use system preference
|
||||
const savedTheme = localStorage.getItem('theme');
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const initialTheme = savedTheme || (prefersDark ? 'dark' : 'light');
|
||||
|
||||
// Set initial theme
|
||||
document.documentElement.setAttribute('data-theme', initialTheme);
|
||||
|
||||
themeToggle.addEventListener('click', () => {
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme');
|
||||
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
|
||||
document.documentElement.setAttribute('data-theme', newTheme);
|
||||
localStorage.setItem('theme', newTheme);
|
||||
});
|
||||
}
|
||||
|
||||
function initializeCustomSelect({ initialValue = null, addListeners = false }) {
|
||||
const button = document.getElementById('language-button');
|
||||
const select = document.getElementById('language-select');
|
||||
if (!button || !select) return;
|
||||
|
||||
const dropdown = button.nextElementSibling;
|
||||
const selectedValue = button.querySelector('.selected-value');
|
||||
|
||||
if (initialValue) {
|
||||
select.value = initialValue;
|
||||
}
|
||||
if (select.selectedIndex >= 0 && select.options[select.selectedIndex]) {
|
||||
selectedValue.textContent = select.options[select.selectedIndex].text;
|
||||
} else {
|
||||
selectedValue.textContent = 'JavaScript';
|
||||
}
|
||||
|
||||
if (addListeners) {
|
||||
button.addEventListener('click', (e) => {
|
||||
e.preventDefault(); // Prevent form submission
|
||||
dropdown.classList.toggle('show');
|
||||
});
|
||||
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!button.contains(e.target)) {
|
||||
dropdown.classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
dropdown.querySelectorAll('.option').forEach(option => {
|
||||
option.addEventListener('click', () => {
|
||||
selectedValue.textContent = option.textContent;
|
||||
select.value = option.dataset.value;
|
||||
dropdown.classList.remove('show');
|
||||
|
||||
const event = new Event('change');
|
||||
select.dispatchEvent(event);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
window.initializePlayground = async (opts) => {
|
||||
const { Parser, Language } = window.TreeSitter;
|
||||
|
||||
const { local } = opts;
|
||||
if (local) {
|
||||
initializeLocalTheme();
|
||||
}
|
||||
initializeCustomSelect({ addListeners: true });
|
||||
|
||||
let tree;
|
||||
|
||||
(async () => {
|
||||
const CAPTURE_REGEX = /@\s*([\w\._-]+)/g;
|
||||
const COLORS_BY_INDEX = [
|
||||
"blue",
|
||||
"chocolate",
|
||||
"darkblue",
|
||||
"darkcyan",
|
||||
"darkgreen",
|
||||
"darkred",
|
||||
"darkslategray",
|
||||
"dimgray",
|
||||
"green",
|
||||
"indigo",
|
||||
"navy",
|
||||
"red",
|
||||
"sienna",
|
||||
const LIGHT_COLORS = [
|
||||
"#0550ae", // blue
|
||||
"#ab5000", // rust brown
|
||||
"#116329", // forest green
|
||||
"#844708", // warm brown
|
||||
"#6639ba", // purple
|
||||
"#7d4e00", // orange brown
|
||||
"#0969da", // bright blue
|
||||
"#1a7f37", // green
|
||||
"#cf222e", // red
|
||||
"#8250df", // violet
|
||||
"#6e7781", // gray
|
||||
"#953800", // dark orange
|
||||
"#1b7c83" // teal
|
||||
];
|
||||
|
||||
const scriptURL = document.getElementById("playground-script").src;
|
||||
const DARK_COLORS = [
|
||||
"#79c0ff", // light blue
|
||||
"#ffa657", // orange
|
||||
"#7ee787", // light green
|
||||
"#ff7b72", // salmon
|
||||
"#d2a8ff", // light purple
|
||||
"#ffa198", // pink
|
||||
"#a5d6ff", // pale blue
|
||||
"#56d364", // bright green
|
||||
"#ff9492", // light red
|
||||
"#e0b8ff", // pale purple
|
||||
"#9ca3af", // gray
|
||||
"#ffb757", // yellow orange
|
||||
"#80cbc4" // light teal
|
||||
];
|
||||
|
||||
const codeInput = document.getElementById("code-input");
|
||||
const languageSelect = document.getElementById("language-select");
|
||||
const loggingCheckbox = document.getElementById("logging-checkbox");
|
||||
const anonymousNodes = document.getElementById('anonymous-nodes-checkbox');
|
||||
const outputContainer = document.getElementById("output-container");
|
||||
const createIssueBtn = document.getElementById("create-issue-btn");
|
||||
const outputContainerScroll = document.getElementById(
|
||||
"output-container-scroll",
|
||||
);
|
||||
const playgroundContainer = document.getElementById("playground-container");
|
||||
const queryCheckbox = document.getElementById("query-checkbox");
|
||||
const createIssueBtn = document.getElementById("create-issue-btn");
|
||||
const queryContainer = document.getElementById("query-container");
|
||||
const queryInput = document.getElementById("query-input");
|
||||
const accessibilityCheckbox = document.getElementById("accessibility-checkbox");
|
||||
const updateTimeSpan = document.getElementById("update-time");
|
||||
const languagesByName = {};
|
||||
|
||||
loadState();
|
||||
|
||||
await TreeSitter.init();
|
||||
await Parser.init();
|
||||
|
||||
const parser = new Parser();
|
||||
|
||||
console.log(parser, codeInput, queryInput);
|
||||
|
||||
const parser = new TreeSitter();
|
||||
const codeEditor = CodeMirror.fromTextArea(codeInput, {
|
||||
lineNumbers: true,
|
||||
showCursorWhenSelecting: true,
|
||||
showCursorWhenSelecting: true
|
||||
});
|
||||
|
||||
codeEditor.on('keydown', (_, event) => {
|
||||
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
||||
event.stopPropagation(); // Prevent mdBook from going back/forward
|
||||
}
|
||||
});
|
||||
|
||||
const queryEditor = CodeMirror.fromTextArea(queryInput, {
|
||||
@@ -51,6 +148,12 @@ let tree;
|
||||
showCursorWhenSelecting: true,
|
||||
});
|
||||
|
||||
queryEditor.on('keydown', (_, event) => {
|
||||
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
||||
event.stopPropagation(); // Prevent mdBook from going back/forward
|
||||
}
|
||||
});
|
||||
|
||||
const cluster = new Clusterize({
|
||||
rows: [],
|
||||
noDataText: null,
|
||||
@@ -61,7 +164,7 @@ let tree;
|
||||
const saveStateOnChange = debounce(saveState, 2000);
|
||||
const runTreeQueryOnChange = debounce(runTreeQuery, 50);
|
||||
|
||||
let languageName = "hcl";
|
||||
let languageName = languageSelect.value;
|
||||
let treeRows = null;
|
||||
let treeRowHighlightedIndex = -1;
|
||||
let parseCount = 0;
|
||||
@@ -74,20 +177,37 @@ let tree;
|
||||
queryEditor.on("changes", debounce(handleQueryChange, 150));
|
||||
|
||||
loggingCheckbox.addEventListener("change", handleLoggingChange);
|
||||
anonymousNodes.addEventListener('change', renderTree);
|
||||
queryCheckbox.addEventListener("change", handleQueryEnableChange);
|
||||
accessibilityCheckbox.addEventListener("change", handleQueryChange);
|
||||
languageSelect.addEventListener("change", handleLanguageChange);
|
||||
outputContainer.addEventListener("click", handleTreeClick);
|
||||
createIssueBtn.addEventListener("click", handleCreateIssue);
|
||||
|
||||
handleQueryEnableChange();
|
||||
await loadLanguage();
|
||||
await handleLanguageChange();
|
||||
|
||||
playgroundContainer.style.visibility = "visible";
|
||||
|
||||
async function loadLanguage() {
|
||||
const query = new URL(scriptURL).search;
|
||||
const url = `tree-sitter-hcl.wasm${query}`;
|
||||
const language = await TreeSitter.Language.load(url);
|
||||
async function handleLanguageChange() {
|
||||
const newLanguageName = languageSelect.value;
|
||||
if (!languagesByName[newLanguageName]) {
|
||||
const url = `tree-sitter-${newLanguageName}.wasm`;
|
||||
languageSelect.disabled = true;
|
||||
try {
|
||||
languagesByName[newLanguageName] = await Language.load(url);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
languageSelect.value = languageName;
|
||||
return;
|
||||
} finally {
|
||||
languageSelect.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
tree = null;
|
||||
parser.setLanguage(language);
|
||||
languageName = newLanguageName;
|
||||
parser.setLanguage(languagesByName[newLanguageName]);
|
||||
handleCodeChange();
|
||||
handleQueryChange();
|
||||
}
|
||||
@@ -127,7 +247,7 @@ let tree;
|
||||
|
||||
for (let i = 0; ; i++) {
|
||||
if (i > 0 && i % 10000 === 0) {
|
||||
await new Promise(r => setTimeout(r, 0));
|
||||
await new Promise((r) => setTimeout(r, 0));
|
||||
if (parseCount !== currentRenderCount) {
|
||||
cursor.delete();
|
||||
isRendering--;
|
||||
@@ -137,9 +257,12 @@ let tree;
|
||||
|
||||
let displayName;
|
||||
if (cursor.nodeIsMissing) {
|
||||
displayName = `MISSING ${cursor.nodeType}`;
|
||||
const nodeTypeText = cursor.nodeIsNamed ? cursor.nodeType : `"${cursor.nodeType}"`;
|
||||
displayName = `MISSING ${nodeTypeText}`;
|
||||
} else if (cursor.nodeIsNamed) {
|
||||
displayName = cursor.nodeType;
|
||||
} else if (anonymousNodes.checked) {
|
||||
displayName = cursor.nodeType
|
||||
}
|
||||
|
||||
if (visitedChildren) {
|
||||
@@ -165,19 +288,25 @@ let tree;
|
||||
const start = cursor.startPosition;
|
||||
const end = cursor.endPosition;
|
||||
const id = cursor.nodeId;
|
||||
let fieldName = cursor.currentFieldName();
|
||||
let fieldName = cursor.currentFieldName;
|
||||
if (fieldName) {
|
||||
fieldName += ": ";
|
||||
} else {
|
||||
fieldName = "";
|
||||
}
|
||||
row = `<div>${" ".repeat(
|
||||
indentLevel,
|
||||
)}${fieldName}<a class='plain' href="#" data-id=${id} data-range="${
|
||||
start.row
|
||||
},${start.column},${end.row},${end.column}">${displayName}</a> [${
|
||||
start.row
|
||||
}, ${start.column}] - [${end.row}, ${end.column}])`;
|
||||
|
||||
const nodeClass =
|
||||
displayName === 'ERROR' || displayName.startsWith('MISSING')
|
||||
? 'node-link error'
|
||||
: cursor.nodeIsNamed
|
||||
? 'node-link named'
|
||||
: 'node-link anonymous';
|
||||
|
||||
row = `<div class="tree-row">${" ".repeat(indentLevel)}${fieldName}` +
|
||||
`<a class='${nodeClass}' href="#" data-id=${id} ` +
|
||||
`data-range="${start.row},${start.column},${end.row},${end.column}">` +
|
||||
`${displayName}</a> <span class="position-info">` +
|
||||
`[${start.row}, ${start.column}] - [${end.row}, ${end.column}]</span>`;
|
||||
finishedRow = true;
|
||||
}
|
||||
|
||||
@@ -201,6 +330,14 @@ let tree;
|
||||
handleCursorMovement();
|
||||
}
|
||||
|
||||
function getCaptureCSS(name) {
|
||||
if (accessibilityCheckbox.checked) {
|
||||
return `color: white; background-color: ${colorForCaptureName(name)}`;
|
||||
} else {
|
||||
return `color: ${colorForCaptureName(name)}`;
|
||||
}
|
||||
}
|
||||
|
||||
function runTreeQuery(_, startRow, endRow) {
|
||||
if (endRow == null) {
|
||||
const viewport = codeEditor.getViewport();
|
||||
@@ -210,7 +347,7 @@ let tree;
|
||||
|
||||
codeEditor.operation(() => {
|
||||
const marks = codeEditor.getAllMarks();
|
||||
marks.forEach(m => m.clear());
|
||||
marks.forEach((m) => m.clear());
|
||||
|
||||
if (tree && query) {
|
||||
const captures = query.captures(
|
||||
@@ -229,7 +366,7 @@ let tree;
|
||||
{
|
||||
inclusiveLeft: true,
|
||||
inclusiveRight: true,
|
||||
css: `color: ${colorForCaptureName(name)}`,
|
||||
css: getCaptureCSS(name),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -237,6 +374,21 @@ let tree;
|
||||
});
|
||||
}
|
||||
|
||||
// When we change from a dark theme to a light theme (and vice versa), the colors of the
|
||||
// captures need to be updated.
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
if (mutation.attributeName === 'class') {
|
||||
handleQueryChange();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class']
|
||||
});
|
||||
|
||||
function handleQueryChange() {
|
||||
if (query) {
|
||||
query.delete();
|
||||
@@ -245,17 +397,17 @@ let tree;
|
||||
}
|
||||
|
||||
queryEditor.operation(() => {
|
||||
queryEditor.getAllMarks().forEach(m => m.clear());
|
||||
queryEditor.getAllMarks().forEach((m) => m.clear());
|
||||
if (!queryCheckbox.checked) return;
|
||||
|
||||
const queryText = queryEditor.getValue();
|
||||
|
||||
try {
|
||||
query = parser.getLanguage().query(queryText);
|
||||
query = parser.language.query(queryText);
|
||||
let match;
|
||||
|
||||
let row = 0;
|
||||
queryEditor.eachLine(line => {
|
||||
queryEditor.eachLine((line) => {
|
||||
while ((match = CAPTURE_REGEX.exec(line.text))) {
|
||||
queryEditor.markText(
|
||||
{ line: row, ch: match.index },
|
||||
@@ -322,7 +474,7 @@ let tree;
|
||||
"plain",
|
||||
);
|
||||
}
|
||||
treeRowHighlightedIndex = treeRows.findIndex(row =>
|
||||
treeRowHighlightedIndex = treeRows.findIndex((row) =>
|
||||
row.includes(`data-id=${node.id}`),
|
||||
);
|
||||
if (treeRowHighlightedIndex !== -1) {
|
||||
@@ -339,9 +491,9 @@ let tree;
|
||||
const containerHeight = outputContainerScroll.clientHeight;
|
||||
const offset = treeRowHighlightedIndex * lineHeight;
|
||||
if (scrollTop > offset - 20) {
|
||||
$(outputContainerScroll).animate({ scrollTop: offset - 20 }, 150);
|
||||
outputContainerScroll.animate({ scrollTop: offset - 20 }, 150);
|
||||
} else if (scrollTop < offset + lineHeight + 40 - containerHeight) {
|
||||
$(outputContainerScroll).animate(
|
||||
outputContainerScroll.animate(
|
||||
{ scrollTop: offset - containerHeight + 40 },
|
||||
150,
|
||||
);
|
||||
@@ -364,7 +516,7 @@ ${outputText}
|
||||
const queryParams = `title=${encodeURIComponent(
|
||||
title,
|
||||
)}&body=${encodeURIComponent(body)}`;
|
||||
const url = `https://github.com/MichaHoffmann/tree-sitter-hcl/issues/new?${queryParams}`;
|
||||
const url = `https://github.com/tree-sitter-grammars/tree-sitter-hcl/issues/new?${queryParams}`;
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
@@ -372,7 +524,7 @@ ${outputText}
|
||||
if (event.target.tagName === "A") {
|
||||
event.preventDefault();
|
||||
const [startRow, startColumn, endRow, endColumn] =
|
||||
event.target.dataset.range.split(",").map(n => parseInt(n));
|
||||
event.target.dataset.range.split(",").map((n) => parseInt(n));
|
||||
codeEditor.focus();
|
||||
codeEditor.setSelection(
|
||||
{ line: startRow, ch: startColumn },
|
||||
@@ -440,43 +592,40 @@ ${outputText}
|
||||
|
||||
function colorForCaptureName(capture) {
|
||||
const id = query.captureNames.indexOf(capture);
|
||||
return COLORS_BY_INDEX[id % COLORS_BY_INDEX.length];
|
||||
}
|
||||
const isDark = document.querySelector('html').classList.contains('ayu') ||
|
||||
document.querySelector('html').classList.contains('coal') ||
|
||||
document.querySelector('html').classList.contains('navy');
|
||||
|
||||
function storageGetItem(lookupKey) {
|
||||
try {
|
||||
return localStorage.getItem(lookupKey);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function storageSetItem(lookupKey, value) {
|
||||
try {
|
||||
return localStorage.setIem(lookupKey, value);
|
||||
} catch {}
|
||||
const colors = isDark ? DARK_COLORS : LIGHT_COLORS;
|
||||
return colors[id % colors.length];
|
||||
}
|
||||
|
||||
function loadState() {
|
||||
const language = storageGetItem("language");
|
||||
const sourceCode = storageGetItem("sourceCode");
|
||||
const query = storageGetItem("query");
|
||||
const queryEnabled = storageGetItem("queryEnabled");
|
||||
const language = localStorage.getItem("language");
|
||||
const sourceCode = localStorage.getItem("sourceCode");
|
||||
const anonNodes = localStorage.getItem("anonymousNodes");
|
||||
const query = localStorage.getItem("query");
|
||||
const queryEnabled = localStorage.getItem("queryEnabled");
|
||||
if (language != null && sourceCode != null && query != null) {
|
||||
queryInput.value = query;
|
||||
codeInput.value = sourceCode;
|
||||
languageSelect.value = language;
|
||||
initializeCustomSelect({ initialValue: language });
|
||||
anonymousNodes.checked = anonNodes === "true";
|
||||
queryCheckbox.checked = queryEnabled === "true";
|
||||
}
|
||||
}
|
||||
|
||||
function saveState() {
|
||||
storageSetItem("sourceCode", codeEditor.getValue());
|
||||
localStorage.setItem("language", languageSelect.value);
|
||||
localStorage.setItem("sourceCode", codeEditor.getValue());
|
||||
localStorage.setItem("anonymousNodes", anonymousNodes.checked);
|
||||
saveQueryState();
|
||||
}
|
||||
|
||||
function saveQueryState() {
|
||||
storageSetItem("queryEnabled", queryCheckbox.checked);
|
||||
storageSetItem("query", queryEditor.getValue());
|
||||
localStorage.setItem("queryEnabled", queryCheckbox.checked);
|
||||
localStorage.setItem("query", queryEditor.getValue());
|
||||
}
|
||||
|
||||
function debounce(func, wait, immediate) {
|
||||
@@ -494,5 +643,4 @@ ${outputText}
|
||||
if (callNow) func.apply(context, args);
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
};
|
||||
Binary file not shown.
1
docs/vendor/tree-sitter.js
vendored
1
docs/vendor/tree-sitter.js
vendored
File diff suppressed because one or more lines are too long
BIN
docs/vendor/tree-sitter.wasm
vendored
BIN
docs/vendor/tree-sitter.wasm
vendored
Binary file not shown.
4001
docs/vendor/web-tree-sitter.js
vendored
Normal file
4001
docs/vendor/web-tree-sitter.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user