Commit 468d80c8 authored by Tomáš Hübelbauer's avatar Tomáš Hübelbauer

Introduce the new UI with selectable index

parent f697cf75
......@@ -14,6 +14,14 @@ body {
width: 400px;
}
#fileDiv {
display: flex;
}
#fileSelect {
flex: 1;
}
#paneDiv textarea {
display: block;
flex: 1;
......@@ -25,6 +33,14 @@ body {
flex-direction: column;
}
#indexDiv {
display: flex;
}
#indexRange {
flex: 1;
}
#diffDiv iframe {
flex: 1;
}
......@@ -8,12 +8,18 @@
</head>
<body>
<div id="paneDiv">
<h1 id="nameH1"></h1>
<button id="advanceButton">Advance</button>
<textarea id="processedSourceTextArea" readonly></textarea>
<textarea id="unprocessedSourceTextArea" readonly></textarea>
<div id="fileDiv">
<select id="fileSelect"></select>
<button id="loadButton">Load</button>
</div>
<textarea id="sourceTextArea" readonly></textarea>
</div>
<div id="diffDiv">
<div id="indexDiv">
<input id="indexRangeInput" type="range" />
<input id="indexNumberInput" type="number" />
<span id="lengthSpan">0</span>
</div>
<iframe id="stateDiffIframe"></iframe>
<iframe id="sourceDiffIframe"></iframe>
</div>
......
window.addEventListener('load', async _ => {
const nameH1 = document.querySelector<HTMLHeadingElement>('#nameH1');
const advanceButton = document.querySelector<HTMLButtonElement>('#advanceButton');
const processedSourceTextArea = document.querySelector<HTMLTextAreaElement>('#processedSourceTextArea');
const unprocessedSourceTextArea = document.querySelector<HTMLTextAreaElement>('#unprocessedSourceTextArea');
const fileSelect = document.querySelector<HTMLSelectElement>('#fileSelect');
const loadButton = document.querySelector<HTMLButtonElement>('#loadButton');
const indexRangeInput = document.querySelector<HTMLInputElement>('#indexRangeInput');
const indexNumberInput = document.querySelector<HTMLInputElement>('#indexNumberInput');
const lengthSpan = document.querySelector<HTMLSpanElement>('#lengthSpan');
const sourceTextArea = document.querySelector<HTMLTextAreaElement>('#sourceTextArea');
const stateDiffIframe = document.querySelector<HTMLIFrameElement>("#stateDiffIframe");
const sourceDiffIframe = document.querySelector<HTMLIFrameElement>("#sourceDiffIframe");
const response = await fetch('http://localhost:3001/');
const data = await response.json();
nameH1.textContent = data.name;
const { files } = await response.json();
advanceButton.addEventListener('click', async _ => {
const response = await fetch('http://localhost:3001/advance');
const data = await response.json();
for (const file of files) {
const fileOption = document.createElement('option');
fileOption.text = file;
fileOption.value = file;
fileSelect.options.add(fileOption);
}
processedSourceTextArea.value = data.processedSource;
unprocessedSourceTextArea.value = data.unprocessedSource;
loadButton.addEventListener('click', async _ => {
const response = await fetch('http://localhost:3001/file/' + fileSelect.value);
const text = await response.text();
indexRangeInput.valueAsNumber = 0;
indexNumberInput.valueAsNumber = 0;
lengthSpan.textContent = text.length.toString();
sourceTextArea.value = text;
render();
});
indexRangeInput.addEventListener('change', _ => {
indexNumberInput.value = indexRangeInput.value;
render();
});
stateDiffIframe.src = 'http://localhost:3001/state-diff';
sourceDiffIframe.src = 'http://localhost:3001/source-diff';
indexNumberInput.addEventListener('change', _ => {
indexRangeInput.value = indexNumberInput.value;
render();
});
advanceButton.click();
function render() {
stateDiffIframe.src = `http://localhost:3001/state-diff?index=${indexNumberInput.value}&file=${fileSelect.value}`;
sourceDiffIframe.src = `http://localhost:3001/source-diff?index=${indexNumberInput.value}&file=${fileSelect.value}`;
}
});
......@@ -5,46 +5,35 @@ import * as prettydiff from 'prettydiff';
import MarkDownDOM from '../../lib/dom';
const server = express();
const testFilePath = '../../test/complete.md';
let source = '';
let index = 0;
let priorDom: MarkDownDOM;
let currentDom: MarkDownDOM;
// Allow localhost:1234 to fetch localhost:3001.
server.use(cors());
// Loads the file in memory and advances to the first character.
server.get('/', async (request, response) => {
source = String(await fs.readFile(testFilePath));
response.json({ name: testFilePath });
const files = (await fs.readdir('../../test')).filter(file => file.endsWith('.md'));
response.json({ files });
});
// Advances to the next character and reports whether the output matches the input.
server.get('/advance', (request, response) => {
index++;
const processedSource = source.substring(0, index);
const unprocessedSource = source.substring(index);
priorDom = currentDom;
currentDom = MarkDownDOM.parse(processedSource);
response.json({ processedSource, unprocessedSource });
});
// Serves a file for demonstration so that the user doesn't have to come up with their own
server.use('/file', express.static('../../'));
// Displays a graphical diff between the prior and current states.
server.get('/state-diff', (request, response) => {
// TODO: Read index and file, compare state for the two slices.
response.send(prettydiff.api({
source: JSON.stringify(priorDom || {}, null, 2),
diff: JSON.stringify(currentDom || {}, null, 2),
source: JSON.stringify({}, null, 2),
diff: JSON.stringify({}, null, 2),
lang: 'json'
})[0]);
});
// Displays a graphical diff between the input and the output sources.
server.get('/source-diff', (request, response) => {
const sourceSlice = source.substring(0, index);
// TODO: Read index and file, compare state for the two slices.
response.send(prettydiff.api({
source: sourceSlice,
diff: MarkDownDOM.parse(sourceSlice).serialize(),
source: '',
diff: '',
lang: 'markdown'
})[0]);
});
......
......@@ -8,6 +8,7 @@
},
"dependencies": {
"@types/express": "^4.11.1",
"@types/fs-extra": "^5.0.1",
"cors": "^2.8.4",
"express": "^4.16.2",
"fs-extra": "^5.0.0",
......
......@@ -28,6 +28,12 @@
"@types/express-serve-static-core" "*"
"@types/serve-static" "*"
"@types/fs-extra@^5.0.1":
version "5.0.1"
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.0.1.tgz#cd856fbbdd6af2c11f26f8928fd8644c9e9616c9"
dependencies:
"@types/node" "*"
"@types/mime@*":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment