mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-14 22:35:14 +00:00
121 lines
5.4 KiB
HTML
121 lines
5.4 KiB
HTML
<!--
|
|
This file is used to add preview of the `.slint` snippets in the generated rustdoc documentation.
|
|
It can be injected via the `--html-in-header slint-docs-preview.html` option of rustdoc.
|
|
-->
|
|
<script type="module">
|
|
"use strict";
|
|
//import * as slint from 'https://slint.dev/releases/0.x.0/wasm-interpreter/slint_wasm_interpreter.js';
|
|
//const editor_url = "https://slint.dev/releases/0.x.0/editor/";
|
|
import * as slint from 'https://slint.dev/snapshots/master/wasm-interpreter/slint_wasm_interpreter.js';
|
|
const editor_url = "https://slint.dev/snapshots/master/editor/";
|
|
// keep them alive
|
|
var all_instances = new Array;
|
|
|
|
async function render_or_error(source, div) {
|
|
let canvas_id = 'canvas_' + Math.random().toString(36).substr(2, 9);
|
|
let canvas = document.createElement("canvas");
|
|
canvas.id = canvas_id;
|
|
div.appendChild(canvas);
|
|
|
|
let { component, error_string } = await slint.compile_from_string(source, "");
|
|
if (error_string != "") {
|
|
var text = document.createTextNode(error_string);
|
|
var p = document.createElement('pre');
|
|
p.appendChild(text);
|
|
div.innerHTML = "<pre style='color: red; background-color:#fee; margin:0'>" + p.innerHTML + "</pre>";
|
|
}
|
|
if (component !== undefined) {
|
|
let instance = await component.create(canvas_id);
|
|
await instance.show();
|
|
all_instances.push(instance);
|
|
}
|
|
}
|
|
|
|
async function create_preview(element, source_code) {
|
|
// Style the preview such that a flexbox lays out the source code box
|
|
// (which should take up any spare space), followed by the preview canvas.
|
|
// The latter may wrap into a new row on mobile. The edit/play buttons are
|
|
// placed last by flexbox order attribute.
|
|
let div = document.createElement("div");
|
|
let sourceCodeBox = element.firstElementChild;
|
|
element.style = "display: flex; flex-wrap: wrap;";
|
|
sourceCodeBox.style = "flex-grow: 2";
|
|
element.append(div);
|
|
await render_or_error(source_code, div);
|
|
}
|
|
|
|
function should_show_automatic_preview(element) {
|
|
// The `no-auto-preview` doesn't map directly to a dedicated class but it's mangled differently
|
|
// between rustdoc and sphinx, so match fuzzy on the entire class list:
|
|
return !element.className.includes("no-auto-preview");
|
|
}
|
|
|
|
async function create_click_to_play_and_edit_buttons(element) {
|
|
let source = element.innerText;
|
|
|
|
let link_section = document.createElement("div");
|
|
// Ensure the link section is always last and on a row of its own in the flexbox.
|
|
link_section.style = "order: 100; flex-basis: 100%;";
|
|
element.append(link_section);
|
|
|
|
let button_style = "text-decoration: none;"
|
|
|
|
let edit_button = document.createElement("a");
|
|
edit_button.style = button_style;
|
|
edit_button.href = `${editor_url}?snippet=${encodeURIComponent(source)}`;
|
|
edit_button.target = "_blank";
|
|
edit_button.innerText = "Edit 📝";
|
|
link_section.append(edit_button);
|
|
|
|
if (should_show_automatic_preview(element)) {
|
|
create_preview(element, source);
|
|
} else {
|
|
let play_button = document.createElement("a");
|
|
play_button.style = button_style;
|
|
play_button.innerText = "Preview ▶️";
|
|
play_button.onclick = async () => {
|
|
play_button.remove();
|
|
create_preview(element, source);
|
|
};
|
|
|
|
link_section.prepend(play_button);
|
|
}
|
|
}
|
|
|
|
async function run() {
|
|
await slint.default();
|
|
|
|
try {
|
|
slint.run_event_loop();
|
|
// this will trigger a JS exception, so this line will never be reached!
|
|
} catch (e) {
|
|
// The winit event loop, when targeting wasm, throws a JavaScript exception to break out of
|
|
// Rust without running any destructors. Don't rethrow the exception but swallow it, as
|
|
// this is no error and we truly want to resolve the promise of this function by returning
|
|
// the model markers.
|
|
}
|
|
|
|
let selector = ["code.language-slint", ".rustdoc pre.language-slint", "div.highlight-slint div.highlight", "div.highlight-slint\\,no-auto-preview div.highlight"]
|
|
.map((sel) => `${sel}:not([class*=slint\\,ignore]):not([class*=slint\\,no-preview])`).join(",");
|
|
var elements = document.querySelectorAll(selector);
|
|
for (var i = 0; i < elements.length; ++i) {
|
|
await create_click_to_play_and_edit_buttons(elements[i]);
|
|
}
|
|
}
|
|
run();
|
|
|
|
// Included markdown files may have links to other markdown files, which may not have been
|
|
// resolved by rustdoc. This helper locates such links and resolves them, assuming that each
|
|
// .md file gets its own sub-directory with an index.html.
|
|
function fix_markdown_links() {
|
|
for (let anchor of document.querySelectorAll('a[href$=".md"], a[href*=".md#"]')) {
|
|
let url = new URL(anchor.href);
|
|
let dir_separator = Math.max(url.pathname.lastIndexOf("/"), 0);
|
|
let base_name = url.pathname.slice(dir_separator + 1, -3);
|
|
let base_path = url.pathname.slice(0, dir_separator);
|
|
url.pathname = base_path + "/../" + base_name + "/index.html";
|
|
anchor.setAttribute("href", url);
|
|
}
|
|
}
|
|
fix_markdown_links()
|
|
</script>
|