Move HTML generation back to JavaScript.

- Functionality maintained
- File operations removed from server
- Browsers should again be able to cache the tutorial
This commit is contained in:
Chris Wilson 2020-08-14 20:09:59 -04:00
parent 87ea87a2e9
commit b47e8cbbf2
5 changed files with 53 additions and 29 deletions

View File

@ -10,7 +10,6 @@ from flask import Flask, request, redirect, url_for, render_template, Response,
from flask_caching import Cache
from flaskext.autoversion import Autoversion
from flask_compress import Compress
import markdown
from .models import *
@ -76,14 +75,8 @@ def register_session():
@app.route('/tutorial')
@app.route('/tutorial/<string:lang>')
@cache.memoize(timeout=300) # update every 300 seconds
def tutorial(lang='en'):
try:
md_file = open(os.path.join('WebHostLib', 'tutorial', f"tutorial_{lang}.md"), encoding="utf-8-sig")
except FileNotFoundError:
return render_template("tutorial.html", tutorial='The tutorial is not available in that language yet, sorry.')
else:
return render_template("tutorial.html", tutorial=markdown.markdown(md_file.read()))
return render_template(f"tutorial.html", lang=lang)
@app.route('/seed/<suuid:seed>')

View File

@ -5,4 +5,3 @@ flask-caching>=1.9.0
Flask-Autoversion>=0.2.0
Flask-Compress>=1.5.0
Flask-Limiter>=1.3.1
markdown>=3.2.2

View File

@ -1,15 +1,48 @@
window.addEventListener('load', () => {
const headers = Array.from(document.querySelectorAll('h1, h2, h3, h4, h5, h6'));
const scrollTargetIndex = window.location.href.search(/#[A-z0-9-_]*$/);
for (let i=1; i < headers.length; i++){
const headerId = headers[i].innerText.replace(/[ ]/g,'-').toLowerCase()
headers[i].setAttribute('id', headerId);
headers[i].addEventListener('click', () =>
window.location.href = window.location.href.substring(0, scrollTargetIndex) + `#${headerId}`);
}
const tutorialWrapper = document.getElementById('tutorial-wrapper');
new Promise((resolve, reject) => {
const ajax = new XMLHttpRequest();
ajax.onreadystatechange = () => {
if (ajax.readyState !== 4) { return; }
if (ajax.status === 404) {
reject("Sorry, the tutorial is not available in that language yet.");
return;
}
if (ajax.status !== 200) {
reject("Something went wrong while loading the tutorial.");
return;
}
resolve(ajax.responseText);
};
ajax.open('GET', `${window.location.origin}/static/assets/tutorial/tutorial_` +
`${tutorialWrapper.getAttribute('data-language')}.md`, true);
ajax.send();
}).then((results) => {
// Populate page with HTML generated from markdown
tutorialWrapper.innerHTML = (new showdown.Converter()).makeHtml(results);
if (scrollTargetIndex > -1) {
const scrollTarget = window.location.href.substring(scrollTargetIndex + 1);
document.getElementById(scrollTarget).scrollIntoView({ behavior: "smooth" });
}
// Reset the id of all header divs to something nicer
const headers = Array.from(document.querySelectorAll('h1, h2, h3, h4, h5, h6'));
const scrollTargetIndex = window.location.href.search(/#[A-z0-9-_]*$/);
for (let i=0; i < headers.length; i++){
const headerId = headers[i].innerText.replace(/[ ]/g,'-').toLowerCase()
headers[i].setAttribute('id', headerId);
headers[i].addEventListener('click', () =>
window.location.href = window.location.href.substring(0, scrollTargetIndex) + `#${headerId}`);
}
// Manually scroll the user to the appropriate header if anchor navigation is used
if (scrollTargetIndex > -1) {
try{
const scrollTarget = window.location.href.substring(scrollTargetIndex + 1);
document.getElementById(scrollTarget).scrollIntoView({ behavior: "smooth" });
} catch(error) {
console.error(error);
}
}
}).catch((error) => {
tutorialWrapper.innerHTML =
`<h2>${error}</h2>
<h3>Click <a href="${window.location.origin}/tutorial">here</a> to return to safety.</h3>`;
});
});

View File

@ -55,13 +55,11 @@ the players folder and is called `easy.yaml`
### Your YAML file is weighted
Throughout your YAML file, you will see many options which look similar to this:
<pre>
```
```yaml
map_shuffle:
on: 5
off: 15
```
</pre>
In the above example, imagine the generator creates a bucket labelled "map_shuffle", and places a folded
piece of paper into the bucket for each sub-option. Here, there are twenty pieces of paper in the bucket:
five for "on" and fifteen for "off". When the generator is deciding whether or not to turn on map shuffle
@ -83,8 +81,7 @@ which do not affect gameplay. These options are also weighted, in case you want
of your hearts or by the silliness of your overworld palette.
If you would like to add a sprite to the list, simply include its name and give it a weight like so:
<pre>
```
```yaml
rom:
sprite: # Enter the name of your preferred sprite and weight it appropriately
random: 0
@ -95,7 +92,6 @@ rom:
rocko: 5
luigi: 3
```
</pre>
### Verifying your YAML file
If you would like to validate your YAML file to make sure it works, you may do so on the

View File

@ -3,11 +3,14 @@
{% block head %}
<title>Setup Tutorial</title>
<link rel="stylesheet" type="text/css" href="{{ static_autoversion("styles/tutorial.css") }}" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.9.1/showdown.min.js"
integrity="sha512-L03kznCrNOfVxOUovR6ESfCz9Gfny7gihUX/huVbQB9zjODtYpxaVtIaAkpetoiyV2eqWbvxMH9fiSv5enX7bw=="
crossorigin="anonymous"></script>
<script type="application/ecmascript" src="{{ static_autoversion("assets/tutorial.js") }}"></script>
{% endblock %}
{% block body %}
<div id="tutorial-wrapper" class="main-content">
{{ tutorial|safe }}
<div id="tutorial-wrapper" class="main-content" data-language="{{ lang }}">
<!-- Content generated by JavaScript -->
</div>
{% endblock %}