Commit e115dcec authored by Robert Knight's avatar Robert Knight

Extract logic for "Unload client" button out of `serve-dev.js`

Per discussion on the PR, it is preferable to put markup and JS in the
dev server in external files rather than as string literals in
`serve-dev.js`. This enables them to be edited without having to restart
the dev server.

 - Extract shared functions for loading and unloading client into
   `scripts/util.js`

 - Move logic specific to the index template into `scripts/index.js`.
parent 388838e6
...@@ -28,35 +28,12 @@ const TEMPLATE_PATH = `${__dirname}/templates/`; ...@@ -28,35 +28,12 @@ const TEMPLATE_PATH = `${__dirname}/templates/`;
function renderScript(context) { function renderScript(context) {
const scriptTemplate = ` const scriptTemplate = `
{{{hypothesisConfig}}} {{{hypothesisConfig}}}
<script>
// Button to load/unload the client. Not present on all pages so we create <script type="module">
// a dummy one if missing. import { loadClient } from '/scripts/util.js';
const toggleClientButton = document.querySelector('.js-toggle-client') || document.createElement('button');
function loadClient() { const clientUrl = '{{{clientUrl}}}'.replace('{current_host}', document.location.hostname);
const embedScript = document.createElement('script'); loadClient(clientUrl);
embedScript.src = '{{{clientUrl}}}'.replace('{current_host}', document.location.hostname);
document.body.appendChild(embedScript);
toggleClientButton.textContent = 'Unload client';
}
function unloadClient() {
const annotatorLink = document.querySelector('link[type="application/annotator+html"]');
annotatorLink?.dispatchEvent(new Event('destroy'));
toggleClientButton.textContent = 'Load client';
}
toggleClientButton.onclick = () => {
const isLoaded = document.querySelector('link[type="application/annotator+html"]');
if (isLoaded) {
unloadClient();
} else {
loadClient();
}
};
loadClient();
</script> </script>
`; `;
return Mustache.render(scriptTemplate, context); return Mustache.render(scriptTemplate, context);
......
import { activeClientUrl, loadClient, unloadClient } from './util.js';
const toggleClientButton = document.querySelector('.js-toggle-client');
toggleClientButton.textContent = 'Unload client';
const clientUrl = activeClientUrl;
toggleClientButton.onclick = () => {
if (activeClientUrl) {
unloadClient();
toggleClientButton.textContent = 'Load client';
} else {
loadClient(clientUrl);
toggleClientButton.textContent = 'Unload client';
}
};
/** @type {string|null} */
export let activeClientUrl;
/**
* Load the Hypothesis client into the page.
*
* @param {string} clientUrl
*/
export function loadClient(clientUrl) {
const embedScript = document.createElement('script');
embedScript.src = clientUrl;
document.body.appendChild(embedScript);
activeClientUrl = clientUrl;
}
/**
* Remove the Hypothesis client from the page.
*
* This uses the same method as the browser extension does to deactivate the client.
*/
export function unloadClient() {
const annotatorLink = document.querySelector('link[type="application/annotator+html"]');
annotatorLink?.dispatchEvent(new Event('destroy'));
activeClientUrl = null;
}
...@@ -49,5 +49,6 @@ ...@@ -49,5 +49,6 @@
<li><a href="https://h.readthedocs.io/en/latest/api/">Hypothesis API documentation</a></li> <li><a href="https://h.readthedocs.io/en/latest/api/">Hypothesis API documentation</a></li>
</ul> </ul>
{{{hypothesisScript}}} {{{hypothesisScript}}}
<script type="module" src="/scripts/index.js"></script>
</body> </body>
</html> </html>
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