mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-10 18:02:57 +00:00
This commit is contained in:
4
.vscode/extensions.json
vendored
4
.vscode/extensions.json
vendored
@@ -2,6 +2,8 @@
|
|||||||
"recommendations": [
|
"recommendations": [
|
||||||
"gbasood.byond-dm-language-support",
|
"gbasood.byond-dm-language-support",
|
||||||
"platymuus.dm-langclient",
|
"platymuus.dm-langclient",
|
||||||
"EditorConfig.EditorConfig"
|
"EditorConfig.EditorConfig",
|
||||||
|
"arcanis.vscode-zipfs",
|
||||||
|
"dbaeumer.vscode-eslint"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
18
.vscode/settings.json
vendored
Normal file
18
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"eslint.nodePath": "tgui/.yarn/sdks",
|
||||||
|
"eslint.workingDirectories": [
|
||||||
|
"./tgui"
|
||||||
|
],
|
||||||
|
"search.exclude": {
|
||||||
|
"tgui/.yarn": true,
|
||||||
|
"tgui/.pnp.*": true
|
||||||
|
},
|
||||||
|
"workbench.editorAssociations": [
|
||||||
|
{
|
||||||
|
"filenamePattern": "*.dmi",
|
||||||
|
"viewType": "imagePreview.previewEditor"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"files.eol": "\n",
|
||||||
|
"gitlens.advanced.blame.customArguments": ["-w"]
|
||||||
|
}
|
||||||
@@ -71,21 +71,21 @@
|
|||||||
// Generate page html
|
// Generate page html
|
||||||
var/html = SStgui.basehtml
|
var/html = SStgui.basehtml
|
||||||
html = replacetextEx(html, "\[tgui:windowId]", id)
|
html = replacetextEx(html, "\[tgui:windowId]", id)
|
||||||
// Process inline assets
|
// Inject inline assets
|
||||||
var/inline_styles = ""
|
var/inline_assets_str = ""
|
||||||
var/inline_scripts = ""
|
|
||||||
for(var/datum/asset/asset in inline_assets)
|
for(var/datum/asset/asset in inline_assets)
|
||||||
var/mappings = asset.get_url_mappings()
|
var/mappings = asset.get_url_mappings()
|
||||||
for(var/name in mappings)
|
for(var/name in mappings)
|
||||||
var/url = mappings[name]
|
var/url = mappings[name]
|
||||||
// Not urlencoding since asset strings are considered safe
|
// Not encoding since asset strings are considered safe
|
||||||
if(copytext(name, -4) == ".css")
|
if(copytext(name, -4) == ".css")
|
||||||
inline_styles += "<link rel=\"stylesheet\" type=\"text/css\" href=\"[url]\">\n"
|
inline_assets_str += "Byond.loadCss('[url]', true);\n"
|
||||||
else if(copytext(name, -3) == ".js")
|
else if(copytext(name, -3) == ".js")
|
||||||
inline_scripts += "<script type=\"text/javascript\" defer src=\"[url]\"></script>\n"
|
inline_assets_str += "Byond.loadJs('[url]', true);\n"
|
||||||
asset.send(client)
|
asset.send(client)
|
||||||
html = replacetextEx(html, "<!-- tgui:styles -->\n", inline_styles)
|
if(length(inline_assets_str))
|
||||||
html = replacetextEx(html, "<!-- tgui:scripts -->\n", inline_scripts)
|
inline_assets_str = "<script>\n" + inline_assets_str + "</script>\n"
|
||||||
|
html = replacetextEx(html, "<!-- tgui:assets -->\n", inline_assets_str)
|
||||||
// Inject custom HTML
|
// Inject custom HTML
|
||||||
html = replacetextEx(html, "<!-- tgui:html -->\n", inline_html)
|
html = replacetextEx(html, "<!-- tgui:html -->\n", inline_html)
|
||||||
// Open the window
|
// Open the window
|
||||||
|
|||||||
20
tgui/.yarn/sdks/eslint/bin/eslint.js
vendored
Normal file
20
tgui/.yarn/sdks/eslint/bin/eslint.js
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const {existsSync} = require(`fs`);
|
||||||
|
const {createRequire, createRequireFromPath} = require(`module`);
|
||||||
|
const {resolve, dirname} = require(`path`);
|
||||||
|
|
||||||
|
const relPnpApiPath = "../../../../.pnp.js";
|
||||||
|
|
||||||
|
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
|
||||||
|
const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
|
||||||
|
|
||||||
|
if (existsSync(absPnpApiPath)) {
|
||||||
|
if (!process.versions.pnp) {
|
||||||
|
// Setup the environment to be able to require eslint/bin/eslint.js
|
||||||
|
require(absPnpApiPath).setup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defer to the real eslint/bin/eslint.js your application uses
|
||||||
|
module.exports = absRequire(`eslint/bin/eslint.js`);
|
||||||
6
tgui/.yarn/sdks/eslint/package.json
vendored
Normal file
6
tgui/.yarn/sdks/eslint/package.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "eslint",
|
||||||
|
"version": "7.4.0-pnpify",
|
||||||
|
"main": "./lib/api.js",
|
||||||
|
"type": "commonjs"
|
||||||
|
}
|
||||||
5
tgui/.yarn/sdks/integrations.yml
vendored
Normal file
5
tgui/.yarn/sdks/integrations.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# This file is automatically generated by PnPify.
|
||||||
|
# Manual changes will be lost!
|
||||||
|
|
||||||
|
integrations:
|
||||||
|
- vscode
|
||||||
12
tgui/global.d.ts
vendored
12
tgui/global.d.ts
vendored
@@ -97,11 +97,21 @@ interface ByondType {
|
|||||||
winset(id: string, propName: string, propValue: any): void;
|
winset(id: string, propName: string, propValue: any): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses BYOND JSON
|
* Parses BYOND JSON.
|
||||||
*
|
*
|
||||||
* Uses a special encoding to preverse Infinity and NaN.
|
* Uses a special encoding to preverse Infinity and NaN.
|
||||||
*/
|
*/
|
||||||
parseJson(text: string): any;
|
parseJson(text: string): any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a stylesheet into the document.
|
||||||
|
*/
|
||||||
|
loadCss(url: string): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a script into the document.
|
||||||
|
*/
|
||||||
|
loadJs(url: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare const Byond: ByondType;
|
declare const Byond: ByondType;
|
||||||
|
|||||||
@@ -30,7 +30,6 @@
|
|||||||
@include meta.load-css('~tgui/styles/components/Dimmer.scss');
|
@include meta.load-css('~tgui/styles/components/Dimmer.scss');
|
||||||
@include meta.load-css('~tgui/styles/components/Divider.scss');
|
@include meta.load-css('~tgui/styles/components/Divider.scss');
|
||||||
@include meta.load-css('~tgui/styles/components/Dropdown.scss');
|
@include meta.load-css('~tgui/styles/components/Dropdown.scss');
|
||||||
@include meta.load-css('~tgui/styles/components/FatalError.scss');
|
|
||||||
@include meta.load-css('~tgui/styles/components/Flex.scss');
|
@include meta.load-css('~tgui/styles/components/Flex.scss');
|
||||||
@include meta.load-css('~tgui/styles/components/Input.scss');
|
@include meta.load-css('~tgui/styles/components/Input.scss');
|
||||||
@include meta.load-css('~tgui/styles/components/Knob.scss');
|
@include meta.load-css('~tgui/styles/components/Knob.scss');
|
||||||
|
|||||||
@@ -4,68 +4,9 @@
|
|||||||
* @license MIT
|
* @license MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { loadCSS as fgLoadCss } from 'fg-loadcss';
|
|
||||||
import { createLogger } from './logging';
|
|
||||||
|
|
||||||
const logger = createLogger('assets');
|
|
||||||
|
|
||||||
const EXCLUDED_PATTERNS = [/v4shim/i];
|
const EXCLUDED_PATTERNS = [/v4shim/i];
|
||||||
const RETRY_ATTEMPTS = 5;
|
|
||||||
const RETRY_INTERVAL = 3000;
|
|
||||||
|
|
||||||
const loadedStyleSheetByUrl = {};
|
|
||||||
const loadedMappings = {};
|
const loadedMappings = {};
|
||||||
|
|
||||||
export const loadStyleSheet = (url, attempt = 1) => {
|
|
||||||
if (loadedStyleSheetByUrl[url]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
loadedStyleSheetByUrl[url] = true;
|
|
||||||
logger.log(`loading stylesheet '${url}'`);
|
|
||||||
/** @type {HTMLLinkElement} */
|
|
||||||
let node = fgLoadCss(url);
|
|
||||||
node.addEventListener('load', () => {
|
|
||||||
if (!isStyleSheetReallyLoaded(node, url)) {
|
|
||||||
node.parentNode.removeChild(node);
|
|
||||||
node = null;
|
|
||||||
loadedStyleSheetByUrl[url] = null;
|
|
||||||
if (attempt >= RETRY_ATTEMPTS) {
|
|
||||||
logger.error(`Error: Failed to load the stylesheet `
|
|
||||||
+ `'${url}' after ${RETRY_ATTEMPTS} attempts.\nIt was either `
|
|
||||||
+ `not found, or you're trying to load an empty stylesheet `
|
|
||||||
+ `that has no CSS rules in it.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setTimeout(() => loadStyleSheet(url, attempt + 1), RETRY_INTERVAL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the stylesheet was registered in the DOM
|
|
||||||
* and is not empty.
|
|
||||||
*/
|
|
||||||
const isStyleSheetReallyLoaded = (node, url) => {
|
|
||||||
// Method #1 (works on IE10+)
|
|
||||||
const styleSheet = node.sheet;
|
|
||||||
if (styleSheet) {
|
|
||||||
return styleSheet.rules.length > 0;
|
|
||||||
}
|
|
||||||
// Method #2
|
|
||||||
const styleSheets = document.styleSheets;
|
|
||||||
const len = styleSheets.length;
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
const styleSheet = styleSheets[i];
|
|
||||||
if (styleSheet.href.includes(url)) {
|
|
||||||
return styleSheet.rules.length > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// All methods failed
|
|
||||||
logger.warn(`Warning: stylesheet '${url}' was not found in the DOM`);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const resolveAsset = name => (
|
export const resolveAsset = name => (
|
||||||
loadedMappings[name] || name
|
loadedMappings[name] || name
|
||||||
);
|
);
|
||||||
@@ -73,7 +14,7 @@ export const resolveAsset = name => (
|
|||||||
export const assetMiddleware = store => next => action => {
|
export const assetMiddleware = store => next => action => {
|
||||||
const { type, payload } = action;
|
const { type, payload } = action;
|
||||||
if (type === 'asset/stylesheet') {
|
if (type === 'asset/stylesheet') {
|
||||||
loadStyleSheet(payload);
|
Byond.loadCss(payload);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (type === 'asset/mappings') {
|
if (type === 'asset/mappings') {
|
||||||
@@ -86,7 +27,10 @@ export const assetMiddleware = store => next => action => {
|
|||||||
const ext = name.split('.').pop();
|
const ext = name.split('.').pop();
|
||||||
loadedMappings[name] = url;
|
loadedMappings[name] = url;
|
||||||
if (ext === 'css') {
|
if (ext === 'css') {
|
||||||
loadStyleSheet(url);
|
Byond.loadCss(url);
|
||||||
|
}
|
||||||
|
if (ext === 'js') {
|
||||||
|
Byond.loadJs(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -189,6 +189,9 @@ export const backendMiddleware = store => {
|
|||||||
|
|
||||||
// Resume on incoming update
|
// Resume on incoming update
|
||||||
if (type === 'backend/update' && suspended) {
|
if (type === 'backend/update' && suspended) {
|
||||||
|
// Show the payload
|
||||||
|
logger.log('backend/update', payload);
|
||||||
|
// Signal renderer that we have resumed
|
||||||
resumeRenderer();
|
resumeRenderer();
|
||||||
// Setup drag
|
// Setup drag
|
||||||
setupDrag();
|
setupDrag();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export const debugMiddleware = store => {
|
|||||||
if (key.code === KEY_F12) {
|
if (key.code === KEY_F12) {
|
||||||
store.dispatch(toggleKitchenSink());
|
store.dispatch(toggleKitchenSink());
|
||||||
}
|
}
|
||||||
if (key.ctrl && key.shift && key.code === KEY_BACKSPACE) {
|
if (key.ctrl && key.alt && key.code === KEY_BACKSPACE) {
|
||||||
// NOTE: We need to call this in a timeout, because we need a clean
|
// NOTE: We need to call this in a timeout, because we need a clean
|
||||||
// stack in order for this to be a fatal error.
|
// stack in order for this to be a fatal error.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|||||||
@@ -4,8 +4,7 @@
|
|||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"common": "workspace:*",
|
"common": "workspace:*",
|
||||||
"dompurify": "^2.0.11",
|
"dompurify": "^2.0.12",
|
||||||
"fg-loadcss": "^2.1.0",
|
|
||||||
"inferno": "^7.4.2",
|
"inferno": "^7.4.2",
|
||||||
"inferno-vnode-flags": "^7.4.2",
|
"inferno-vnode-flags": "^7.4.2",
|
||||||
"marked": "^1.1.0",
|
"marked": "^1.1.0",
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2020 Aleksej Komarov
|
|
||||||
* SPDX-License-Identifier: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
.FatalError {
|
|
||||||
display: block !important;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
padding: 12px;
|
|
||||||
font-size: 12px;
|
|
||||||
font-family: Consolas, monospace;
|
|
||||||
color: #ffffff;
|
|
||||||
background-color: #0000dd;
|
|
||||||
z-index: 1000;
|
|
||||||
overflow: hidden;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.FatalError__logo {
|
|
||||||
display: inline-block;
|
|
||||||
text-align: left;
|
|
||||||
font-size: 10px;
|
|
||||||
line-height: 8px;
|
|
||||||
position: relative;
|
|
||||||
margin-top: 12px;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
animation:
|
|
||||||
FatalError__rainbow 2s linear infinite alternate,
|
|
||||||
FatalError__shadow 4s linear infinite alternate,
|
|
||||||
FatalError__tfmX 3s infinite alternate,
|
|
||||||
FatalError__tfmY 4s infinite alternate;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.FatalError__header {
|
|
||||||
margin-top: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.FatalError__stack {
|
|
||||||
text-align: left;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-break: break-all;
|
|
||||||
margin-top: 24px;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.FatalError__footer {
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes FatalError__rainbow {
|
|
||||||
0% {
|
|
||||||
color: #ff0;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
color: #0ff;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
color: #f0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes FatalError__shadow {
|
|
||||||
0% {
|
|
||||||
left: -2px;
|
|
||||||
text-shadow: 4px 0 #f0f;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
left: 0px;
|
|
||||||
text-shadow: 0px 0 #0ff;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
left: 2px;
|
|
||||||
text-shadow: -4px 0 #ff0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes FatalError__tfmX {
|
|
||||||
0% {
|
|
||||||
left: 15px;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
left: -15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes FatalError__tfmY {
|
|
||||||
100% {
|
|
||||||
top: -15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,7 +23,6 @@
|
|||||||
@include meta.load-css('./components/Dimmer.scss');
|
@include meta.load-css('./components/Dimmer.scss');
|
||||||
@include meta.load-css('./components/Divider.scss');
|
@include meta.load-css('./components/Divider.scss');
|
||||||
@include meta.load-css('./components/Dropdown.scss');
|
@include meta.load-css('./components/Dropdown.scss');
|
||||||
@include meta.load-css('./components/FatalError.scss');
|
|
||||||
@include meta.load-css('./components/Flex.scss');
|
@include meta.load-css('./components/Flex.scss');
|
||||||
@include meta.load-css('./components/Input.scss');
|
@include meta.load-css('./components/Input.scss');
|
||||||
@include meta.load-css('./components/Knob.scss');
|
@include meta.load-css('./components/Knob.scss');
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -17,9 +17,7 @@ if (window.__windowId__ === '[' + 'tgui:windowId' + ']') {
|
|||||||
window.__windowId__ = null;
|
window.__windowId__ = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BYOND API object
|
(function () {
|
||||||
window.Byond = (function () {
|
|
||||||
var Byond = {};
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
var hasOwn = Object.prototype.hasOwnProperty;
|
var hasOwn = Object.prototype.hasOwnProperty;
|
||||||
var assign = function (target) {
|
var assign = function (target) {
|
||||||
@@ -33,6 +31,11 @@ window.Byond = (function () {
|
|||||||
}
|
}
|
||||||
return target;
|
return target;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// BYOND API object
|
||||||
|
// ------------------------------------------------------
|
||||||
|
|
||||||
|
var Byond = window.Byond = {};
|
||||||
// Trident engine version
|
// Trident engine version
|
||||||
var tridentVersion = (function () {
|
var tridentVersion = (function () {
|
||||||
var groups = navigator.userAgent.match(/Trident\/(\d+).+?;/i);
|
var groups = navigator.userAgent.match(/Trident\/(\d+).+?;/i);
|
||||||
@@ -170,7 +173,135 @@ window.Byond = (function () {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return Byond;
|
|
||||||
|
// Asset loaders
|
||||||
|
// ------------------------------------------------------
|
||||||
|
|
||||||
|
var RETRY_ATTEMPTS = 5;
|
||||||
|
var RETRY_INTERVAL = 2000;
|
||||||
|
|
||||||
|
var loadedCssByUrl = {};
|
||||||
|
var loadedJsByUrl = {};
|
||||||
|
|
||||||
|
var isStyleSheetLoaded = function (node, url) {
|
||||||
|
// Method #1 (works on IE10+)
|
||||||
|
var styleSheet = node.sheet;
|
||||||
|
if (styleSheet) {
|
||||||
|
return styleSheet.rules.length > 0;
|
||||||
|
}
|
||||||
|
// Method #2
|
||||||
|
var styleSheets = document.styleSheets;
|
||||||
|
var len = styleSheets.length;
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
var styleSheet = styleSheets[i];
|
||||||
|
if (styleSheet.href.indexOf(url) !== -1) {
|
||||||
|
return styleSheet.rules.length > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// All methods failed
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
var onDocumentBodyReady = function (done) {
|
||||||
|
if (document.body) {
|
||||||
|
return done();
|
||||||
|
}
|
||||||
|
setTimeout(function () {
|
||||||
|
onDocumentBodyReady(done);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var getRefNode = function () {
|
||||||
|
var refs = (document.body || document.getElementsByTagName('head')[0])
|
||||||
|
.childNodes;
|
||||||
|
return refs[refs.length - 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Based on fg-loadcss package
|
||||||
|
// See: https://github.com/filamentgroup/loadCSS
|
||||||
|
Byond.loadCss = function (url, sync, attempt) {
|
||||||
|
if (loadedCssByUrl[url]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!attempt) {
|
||||||
|
attempt = 1;
|
||||||
|
}
|
||||||
|
loadedCssByUrl[url] = true;
|
||||||
|
// Inject the stylesheet
|
||||||
|
var ref = getRefNode();
|
||||||
|
/** @type {HTMLLinkElement} */
|
||||||
|
var node = document.createElement('link');
|
||||||
|
node.type = 'text/css';
|
||||||
|
node.rel = 'stylesheet';
|
||||||
|
node.href = url;
|
||||||
|
// Temporarily set media to something inapplicable
|
||||||
|
// to ensure it'll fetch without blocking render
|
||||||
|
if (!sync) {
|
||||||
|
node.media = 'only x';
|
||||||
|
}
|
||||||
|
onDocumentBodyReady(function () {
|
||||||
|
ref.parentNode.insertBefore(node, ref.nextSibling);
|
||||||
|
});
|
||||||
|
// Listen for the load event
|
||||||
|
node.onload = function () {
|
||||||
|
node.onload = null;
|
||||||
|
if (isStyleSheetLoaded(node, url)) {
|
||||||
|
// Render the stylesheet
|
||||||
|
node.media = 'all';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Try again
|
||||||
|
node.parentNode.removeChild(node);
|
||||||
|
node = null;
|
||||||
|
loadedCssByUrl[url] = null;
|
||||||
|
if (attempt >= RETRY_ATTEMPTS) {
|
||||||
|
throw new Error("Error: Failed to load the stylesheet "
|
||||||
|
+ "'" + url + "' after " + RETRY_ATTEMPTS + " attempts.\n"
|
||||||
|
+ "It was either not found, or you're trying to load "
|
||||||
|
+ "an empty stylesheet that has no CSS rules in it.");
|
||||||
|
}
|
||||||
|
setTimeout(function () {
|
||||||
|
Byond.loadCss(url, sync, attempt + 1);
|
||||||
|
}, RETRY_INTERVAL);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Byond.loadJs = function (url, sync, attempt) {
|
||||||
|
if (loadedJsByUrl[url]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!attempt) {
|
||||||
|
attempt = 1;
|
||||||
|
}
|
||||||
|
loadedJsByUrl[url] = true;
|
||||||
|
// Inject the stylesheet
|
||||||
|
var ref = getRefNode();
|
||||||
|
var node = document.createElement('script');
|
||||||
|
node.type = 'text/javascript';
|
||||||
|
if (sync) {
|
||||||
|
node.defer = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node.async = true;
|
||||||
|
}
|
||||||
|
node.src = url;
|
||||||
|
onDocumentBodyReady(function () {
|
||||||
|
ref.parentNode.insertBefore(node, ref.nextSibling);
|
||||||
|
});
|
||||||
|
node.onerror = function () {
|
||||||
|
node.onerror = null;
|
||||||
|
node.parentNode.removeChild(node);
|
||||||
|
node = null;
|
||||||
|
loadedJsByUrl[url] = null;
|
||||||
|
if (attempt >= RETRY_ATTEMPTS) {
|
||||||
|
throw new Error("Error: Failed to load the script "
|
||||||
|
+ "'" + url + "' after " + RETRY_ATTEMPTS + " attempts.");
|
||||||
|
}
|
||||||
|
setTimeout(function () {
|
||||||
|
Byond.loadJs(url, sync, attempt + 1);
|
||||||
|
}, RETRY_INTERVAL);
|
||||||
|
};
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// Global error handling
|
// Global error handling
|
||||||
@@ -190,7 +321,7 @@ window.onerror = function (msg, url, line, col, error) {
|
|||||||
var errorRoot = document.getElementById('FatalError');
|
var errorRoot = document.getElementById('FatalError');
|
||||||
var errorStack = document.getElementById('FatalError__stack');
|
var errorStack = document.getElementById('FatalError__stack');
|
||||||
if (errorRoot) {
|
if (errorRoot) {
|
||||||
errorRoot.className = 'FatalError';
|
errorRoot.className = 'FatalError FatalError--visible';
|
||||||
if (errorStack.textContent) {
|
if (errorStack.textContent) {
|
||||||
errorStack.textContent += '\n\n' + stack;
|
errorStack.textContent += '\n\n' + stack;
|
||||||
}
|
}
|
||||||
@@ -263,15 +394,97 @@ if (!Function.prototype.bind) (function () {
|
|||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Styles -->
|
<style>
|
||||||
<!-- tgui:styles -->
|
.FatalError {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: Consolas, monospace;
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #0000dd;
|
||||||
|
z-index: 1000;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
<!-- Scripts -->
|
.FatalError--visible {
|
||||||
<!-- tgui:scripts -->
|
display: block !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.FatalError__logo {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 12px;
|
||||||
|
position: relative;
|
||||||
|
margin: 16px;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
animation:
|
||||||
|
FatalError__rainbow 2s linear infinite alternate,
|
||||||
|
FatalError__shadow 4s linear infinite alternate,
|
||||||
|
FatalError__tfmX 3s infinite alternate,
|
||||||
|
FatalError__tfmY 4s infinite alternate;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
.FatalError__header {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.FatalError__stack {
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-all;
|
||||||
|
margin-top: 24px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.FatalError__footer {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes FatalError__rainbow {
|
||||||
|
0% { color: #ff0; }
|
||||||
|
50% { color: #0ff; }
|
||||||
|
100% { color: #f0f; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes FatalError__shadow {
|
||||||
|
0% {
|
||||||
|
left: -2px;
|
||||||
|
text-shadow: 4px 0 #f0f;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
left: 0px;
|
||||||
|
text-shadow: 0px 0 #0ff;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: 2px;
|
||||||
|
text-shadow: -4px 0 #ff0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes FatalError__tfmX {
|
||||||
|
0% { left: 15px; }
|
||||||
|
100% { left: -15px; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes FatalError__tfmY {
|
||||||
|
100% { top: -15px; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<!-- Inline assets -->
|
||||||
|
<!-- tgui:assets -->
|
||||||
|
|
||||||
<!-- Inline HTML -->
|
<!-- Inline HTML -->
|
||||||
<!-- tgui:html -->
|
<!-- tgui:html -->
|
||||||
|
|
||||||
@@ -279,36 +492,22 @@ if (!Function.prototype.bind) (function () {
|
|||||||
<div id="react-root"></div>
|
<div id="react-root"></div>
|
||||||
|
|
||||||
<!-- Fatal error container -->
|
<!-- Fatal error container -->
|
||||||
<div id="FatalError" style="display: none">
|
<div id="FatalError" class="FatalError">
|
||||||
<div class="FatalError__logo">
|
<div class="FatalError__logo">
|
||||||
_____ _____ _______ _____
|
ooooo ooo . .oooooo. .oooooo..o
|
||||||
/\ \ /\ \ /::\ \ /\ \
|
`888b. `8' .o8 d8P' `Y8b d8P' `Y8
|
||||||
/::\____\ /::\ \ /::::\ \ /::\ \
|
8 `88b. 8 .o888oo 888 888 Y88bo.
|
||||||
/::::| | \:::\ \ /::::::\ \ /::::\ \
|
8 `88b. 8 888 888 888 `"Y8888o.
|
||||||
/:::::| | \:::\ \ /::::::::\ \ /::::::\ \
|
8 `88b.8 888 888 888 `"Y88b
|
||||||
/::::::| | \:::\ \ /:::/~~\:::\ \ /:::/\:::\ \
|
8 `888 888 . `88b d88' oo .d8P
|
||||||
/:::/|::| | \:::\ \ /:::/ \:::\ \ /:::/__\:::\ \
|
o8o `8 "888" `Y8bood8P' 8""88888P'
|
||||||
/:::/ |::| | /::::\ \ /:::/ / \:::\ \ \:::\ \:::\ \
|
|
||||||
/:::/ |::| | _____ /::::::\ \ /:::/____/ \:::\____\ ___\:::\ \:::\ \
|
|
||||||
/:::/ |::| |/\ \ /:::/\:::\ \|:::| | |:::| |/\ \:::\ \:::\ \
|
|
||||||
/:: / |::| /::\____\/:::/ \:::\____\:::|____| |:::| /::\ \:::\ \:::\____\
|
|
||||||
\::/ /|::| /:::/ /:::/ \::/ /\:::\ \ /:::/ /\:::\ \:::\ \::/ /
|
|
||||||
\/____/ |::| /:::/ /:::/ / \/____/ \:::\ \ /:::/ / \:::\ \:::\ \/____/
|
|
||||||
|::|/:::/ /:::/ / \:::\ /:::/ / \:::\ \:::\ \
|
|
||||||
|::::::/ /:::/ / \:::\__/:::/ / \:::\ \:::\____\
|
|
||||||
|:::::/ /\::/ / \::::::::/ / \:::\ /:::/ /
|
|
||||||
|::::/ / \/____/ \::::::/ / \:::\/:::/ /
|
|
||||||
/:::/ / \::::/ / \::::::/ /
|
|
||||||
/:::/ / \::/____/ \::::/ /
|
|
||||||
\::/ / \::/ /
|
|
||||||
\/____/ \/____/
|
|
||||||
</div>
|
</div>
|
||||||
<marquee class="FatalError__header">
|
<marquee class="FatalError__header">
|
||||||
A fatal exception has occurred at 002B:C562F1B7 in TGUI.
|
A fatal exception has occurred at 002B:C562F1B7 in TGUI.
|
||||||
The current application will be terminated.
|
The current application will be terminated.
|
||||||
Please remain calm. Get to the nearest NTNet workstation
|
Please remain calm. Get to the nearest NTNet workstation
|
||||||
and send the copy of the following stack trace to:
|
and send the copy of the following stack trace to:
|
||||||
www.github.com/tgstation/tgstation. Thank you for your cooperation.
|
www.github.com/Citadel-Station-13/Citadel-Station-13/issues. Thank you for your cooperation.
|
||||||
</marquee>
|
</marquee>
|
||||||
<div id="FatalError__stack" class="FatalError__stack"></div>
|
<div id="FatalError__stack" class="FatalError__stack"></div>
|
||||||
<div class="FatalError__footer">
|
<div class="FatalError__footer">
|
||||||
|
|||||||
@@ -3062,10 +3062,10 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"dompurify@npm:^2.0.11":
|
"dompurify@npm:^2.0.12":
|
||||||
version: 2.0.12
|
version: 2.2.2
|
||||||
resolution: "dompurify@npm:2.0.12"
|
resolution: "dompurify@npm:2.2.2"
|
||||||
checksum: 72fe758306be02d95c7ac51cecaf9d887dea6291cd83012b1c251d21912545c18d6ccc7140b84da2278a6910517cd1e996258991c7e3dda9b6da34f0b6040b91
|
checksum: eab7b8763c56256bb4fb009e59b814f750fe0a4be40f996f037f136a40dbe8107820989c7b548b92263076fce7023ee31c58a11ad479cba16b4626b8d91559f1
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -3637,13 +3637,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"fg-loadcss@npm:^2.1.0":
|
|
||||||
version: 2.1.0
|
|
||||||
resolution: "fg-loadcss@npm:2.1.0"
|
|
||||||
checksum: 5672a437bd51ba418ffa3c304394a4f85d6b53ae2bbcec2ef54d6498642af4e2c11a9902a55bf95cd96e7e787483c2087f56569484a3120a4228d880ffec6309
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"figgy-pudding@npm:^3.5.1":
|
"figgy-pudding@npm:^3.5.1":
|
||||||
version: 3.5.2
|
version: 3.5.2
|
||||||
resolution: "figgy-pudding@npm:3.5.2"
|
resolution: "figgy-pudding@npm:3.5.2"
|
||||||
@@ -8155,8 +8148,7 @@ fsevents@~2.1.2:
|
|||||||
resolution: "tgui@workspace:packages/tgui"
|
resolution: "tgui@workspace:packages/tgui"
|
||||||
dependencies:
|
dependencies:
|
||||||
common: "workspace:*"
|
common: "workspace:*"
|
||||||
dompurify: ^2.0.11
|
dompurify: ^2.0.12
|
||||||
fg-loadcss: ^2.1.0
|
|
||||||
inferno: ^7.4.2
|
inferno: ^7.4.2
|
||||||
inferno-vnode-flags: ^7.4.2
|
inferno-vnode-flags: ^7.4.2
|
||||||
marked: ^1.1.0
|
marked: ^1.1.0
|
||||||
|
|||||||
Reference in New Issue
Block a user