123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- function loadScript(src) {
- return new Promise((resolve, reject) => {
- const s = document.createElement('script');
- s.src = src;
- s.onload = resolve;
- s.onerror = reject;
- document.head.appendChild(s);
- });
- }
- async function createApi() {
- await loadScript('qrc:///qtwebchannel/qwebchannel.js');
- const channel = await new Promise((resolve) => {
- /*global QWebChannel */
- new QWebChannel(window.qt.webChannelTransport, resolve);
- });
- return channel.objects;
- }
- window.apiPromise = createApi();
- async function tryConnect(server) {
- document.getElementById('connect-button').disabled = true;
- try {
- if (!server.startsWith("http")) {
- server = "http://" + server;
- }
- const url = new URL("/System/Info/Public", server);
- const response = await fetch(url);
- if (response.ok && (await response.json()).Id) {
- const htmlResponse = await fetch(server);
- if (!htmlResponse.ok) {
- throw new Error("Status not ok");
- }
- if (response.headers.get("content-security-policy")) {
- // Sigh... If we just navigate to the URL, the server's CSP will block us loading other resources.
- // So we have to parse the HTML, set a new base href, and then write it back to the page.
- // We also have to override the history functions to make sure they use the correct URL.
- console.log("Using CSP workaround");
- const webUrl = htmlResponse.url.replace(/\/[^\/]*$/, "/");
- const realUrl = window.location.href;
- const html = await htmlResponse.text();
- const parser = new DOMParser();
- const doc = parser.parseFromString(html, "text/html");
- const base = doc.createElement("base");
- base.href = webUrl
- doc.head.insertBefore(base, doc.head.firstChild);
-
- const oldPushState = window.history.pushState;
- window.history.pushState = function(state, title, url) {
- url = (new URL(url, realUrl)).toString();
- return oldPushState.call(window.history, state, title, url);
- };
- const oldReplaceState = window.history.replaceState;
- window.history.replaceState = function(state, title, url) {
- url = (new URL(url, realUrl)).toString();
- return oldReplaceState.call(window.history, state, title, url);
- };
- document.open();
- document.write((new XMLSerializer()).serializeToString(doc));
- document.close();
- } else {
- console.log("Using normal navigation");
- window.location = server;
- }
- const api = await window.apiPromise;
- await new Promise(resolve => {
- api.settings.setValue('main', 'userWebClient', server, resolve);
- });
- return true;
- }
- } catch (e) {
- console.error(e);
- document.getElementById('connect-button').disabled = false;
- return false;
- }
- }
- document.getElementById('connect-form').addEventListener('submit', async (e) => {
- e.preventDefault();
- const server = document.getElementById('address').value;
- const result = await tryConnect(server);
- if (!result) {
- document.getElementById('backdrop').style.display = 'block';
- }
- });
- document.getElementById('connect-fail-button').addEventListener('click', () => {
- document.getElementById('backdrop').style.display = 'none';
- });
- // load the server if we have one
- (async() => {
- const api = await window.apiPromise;
- const savedServer = await new Promise(resolve => {
- api.settings.value('main', 'userWebClient', resolve);
- });
- if (!savedServer || !(await tryConnect(savedServer))) {
- document.getElementById('splash').style.display = 'none';
- document.getElementById('main').style.display = 'block';
- }
- })();
|