1
0
mirror of synced 2024-11-27 15:40:48 +01:00

Update to allow using fragment shorthand syntax, switch to standard HTML compliant rendering mode, fix a few things here and there with that switch, use fragments for all components and arcade/admin endpoints.

This commit is contained in:
Jennifer Taylor 2022-10-08 21:26:48 +00:00
parent c92b4a04c4
commit ff1dbebe77
22 changed files with 122 additions and 110 deletions

View File

@ -141,7 +141,7 @@ def jsx(filename: str) -> Response:
if jsx is None:
with open(jsxfile, 'rb') as f:
transformer = JSXTransformer()
jsx = transformer.transform_string(f.read().decode('utf-8'))
jsx = transformer.transform_string(polyfill_fragments(f.read().decode('utf-8')))
# Set the cache to one year, since we namespace on this file's update time
g.cache.set(namespace, jsx, timeout=86400 * 365)
return Response(jsx, mimetype='application/javascript')
@ -163,6 +163,12 @@ def jsx(filename: str) -> Response:
raise
def polyfill_fragments(jsx: str) -> str:
jsx = jsx.replace("<>", "<React.Fragment>")
jsx = jsx.replace("</>", "</React.Fragment>")
return jsx
def render_react(
title: str,
controller: str,

View File

@ -23,44 +23,44 @@ var ExceptionEvent = createReactClass({
if (event.data.service == 'frontend') {
location = 'Web UI';
details = (
<span>
<>
<div>
<div className="inline">URI:</div>
<pre className="inline">{event.data.request}</pre>
</div>
<div>Exception:</div>
<LongMessage>{event.data.traceback}</LongMessage>
</span>
</>
);
} else if(event.data.service == 'xrpc') {
location = 'Game Services';
details = (
<span>
<>
<div>Request:</div>
<LongMessage>{event.data.request}</LongMessage>
<div>Exception:</div>
<LongMessage>{event.data.traceback}</LongMessage>
</span>
</>
);
} else if(event.data.service == 'scheduler') {
location = 'Work Scheduler';
details = (
<span>
<>
<div>Exception:</div>
<LongMessage>{event.data.traceback}</LongMessage>
</span>
</>
);
} else if (event.data.service == 'api') {
location = 'Data Exchange API';
details = (
<span>
<>
<div>
<div className="inline">URI:</div>
<pre className="inline">{event.data.request}</pre>
</div>
<div>Exception:</div>
<LongMessage>{event.data.traceback}</LongMessage>
</span>
</>
);
}

View File

@ -196,11 +196,11 @@ var GameSettings = createReactClass({
/>
{ this.state.settings_saving[this.state.current_setting] ?
<img className="loading" src={Link.get('static', 'loading-16.gif')} /> :
null
null
}
{ this.state.settings_saved[this.state.current_setting] ?
<span>{ "\u2713" }</span> :
null
null
}
</div>
</div>

View File

@ -3,13 +3,13 @@
var Nav = createReactClass({
render: function() {
var title = (
<span>
<>
{this.props.title}
{this.props.showAlert ?
<span className="alert">{ "\u26a0" }</span> :
null
}
</span>
</>
);
return (
<Button

View File

@ -13,14 +13,14 @@ var Slider = createReactClass({
}
}.bind(this)}
>{ this.props.value ?
<span>
<>
<span className="ball on"></span>
<span className="label on">{this.props.on}</span>
</span> :
<span>
</> :
<>
<span className="label off">{this.props.off}</span>
<span className="ball off"></span>
</span>
</>
}</div>
);
},

View File

@ -87,14 +87,14 @@ var account_management = createReactClass({
return (
<LabelledSection vertical={true} label="Password">{
!this.state.editing_password ?
<span>
<>
<span>&bull;&bull;&bull;&bull;&bull;&bull;</span>
<Edit
onClick={function(event) {
this.setState({editing_password: true});
}.bind(this)}
/>
</span> :
</> :
<form className="inline" onSubmit={this.savePassword}>
<div>
<label for="old">Current password:</label>
@ -158,14 +158,14 @@ var account_management = createReactClass({
return (
<LabelledSection vertical={true} label="Email Address">{
!this.state.editing_email ?
<span>
<>
<span>{ this.state.email }</span>
<Edit
onClick={function(event) {
this.setState({editing_email: true});
}.bind(this)}
/>
</span> :
</> :
<form className="inline" onSubmit={this.saveEmail}>
<div>
<label for="old">Current password:</label>
@ -217,14 +217,14 @@ var account_management = createReactClass({
return (
<LabelledSection vertical={true} label="PIN">{
!this.state.editing_pin ?
<span>
<>
<span>&bull;&bull;&bull;&bull;</span>
<Edit
onClick={function(event) {
this.setState({editing_pin: true});
}.bind(this)}
/>
</span> :
</> :
<form className="inline" onSubmit={this.savePin}>
<input
type="text"

View File

@ -187,7 +187,7 @@ var api_management = createReactClass({
if(this.state.editing_client) {
if (this.state.editing_client.id == client.id) {
return (
<span>
<>
<input
type="submit"
value="save"
@ -201,14 +201,14 @@ var api_management = createReactClass({
});
}.bind(this)}
/>
</span>
</>
);
} else {
return <span></span>;
return null;
}
} else {
return (
<span>
<>
<Edit
onClick={function(event) {
var editing_client = null;
@ -227,7 +227,7 @@ var api_management = createReactClass({
this.deleteExistingClient(event, client.id);
}.bind(this)}
/>
</span>
</>
);
}
},
@ -269,7 +269,7 @@ var api_management = createReactClass({
if(this.state.editing_server) {
if (this.state.editing_server.id == server.id) {
return (
<span>
<>
<input
type="submit"
value="save"
@ -283,14 +283,14 @@ var api_management = createReactClass({
});
}.bind(this)}
/>
</span>
</>
);
} else {
return <span></span>;
return null;
}
} else {
return (
<span>
<>
<Edit
onClick={function(event) {
var editing_server = null;
@ -309,7 +309,7 @@ var api_management = createReactClass({
this.deleteExistingServer(event, server.id);
}.bind(this)}
/>
</span>
</>
);
}
},
@ -368,10 +368,10 @@ var api_management = createReactClass({
}
if (this.state.info[server.id].loading) {
return (
<span>
<>
<img className="loading" src={Link.get('static', 'loading-16.gif')} />
{' querying server for info...'}
</span>
</>
);
}
if (this.state.info[server.id].status == 'badauth') {
@ -386,7 +386,7 @@ var api_management = createReactClass({
}
return (
<span>
<>
<div>
<b>{this.state.info[server.id].name}</b>
{' administered by '}
@ -395,14 +395,14 @@ var api_management = createReactClass({
{ this.state.info[server.id].status == 'badversion' ?
<span className='placeholder'>This server supports an incompatible version of the API!</span> : null
}
</span>
</>
);
},
renderServerAllowedData: function(server) {
if (this.state.editing_server && server.id == this.state.editing_server.id) {
return (
<span>
<>
<div>
<input
name="stats"
@ -435,7 +435,7 @@ var api_management = createReactClass({
/>
<label htmlFor="scores">rivals and scores</label>
</div>
</span>
</>
);
} else {
if (!server.allow_stats && !server.allow_scores) {

View File

@ -94,7 +94,7 @@ var card_management = createReactClass({
if(this.state.editing_arcade) {
if (this.state.editing_arcade.id == arcade.id) {
return (
<span>
<>
<input
type="submit"
value="save"
@ -108,14 +108,14 @@ var card_management = createReactClass({
});
}.bind(this)}
/>
</span>
</>
);
} else {
return <span></span>;
return null;
}
} else {
return (
<span>
<>
<Edit
onClick={function(event) {
var editing_arcade = null;
@ -135,7 +135,7 @@ var card_management = createReactClass({
this.deleteExistingArcade(event, arcade.id);
}.bind(this)}
/>
</span>
</>
);
}
},

View File

@ -91,15 +91,15 @@ var card_management = createReactClass({
renderEditButton: function(card) {
return (
<span>
<Nav
<>
<Edit
title="view/edit"
onClick={function(event) {
window.location=Link.get('viewuser', card.id);
}.bind(this)}
/>
<Delete onClick={this.deleteExistingCard.bind(this, card.number)} />
</span>
</>
);
},

View File

@ -244,7 +244,7 @@ var machine_management = createReactClass({
};
return (
<span>
<>
<select
name="function"
value={value}
@ -275,7 +275,7 @@ var machine_management = createReactClass({
<option value="atmost">specific game or older</option>
</select>
{extra}
</span>
</>
);
} else {
if (machine.game == 'any') {
@ -325,20 +325,18 @@ var machine_management = createReactClass({
renderArcade: function(machine) {
if (this.state.editing_machine && machine.pcbid == this.state.editing_machine.pcbid) {
return (
<span>
<SelectArcade
name="owner"
value={ this.state.editing_machine.arcade }
arcades={ this.state.arcades }
onChange={function(owner) {
var machine = this.state.editing_machine;
machine.arcade = parseInt(owner);
this.setState({
editing_machine: machine,
});
}.bind(this)}
/>
</span>
<SelectArcade
name="owner"
value={ this.state.editing_machine.arcade }
arcades={ this.state.arcades }
onChange={function(owner) {
var machine = this.state.editing_machine;
machine.arcade = parseInt(owner);
this.setState({
editing_machine: machine,
});
}.bind(this)}
/>
);
} else {
if (machine.arcade) {
@ -397,7 +395,7 @@ var machine_management = createReactClass({
if (this.state.editing_machine) {
if (this.state.editing_machine.pcbid == machine.pcbid) {
return (
<span>
<>
<input
type="submit"
value="save"
@ -411,14 +409,14 @@ var machine_management = createReactClass({
});
}.bind(this)}
/>
</span>
</>
);
} else {
return <span></span>;
return null;
}
} else {
return (
<span>
<>
<Edit
onClick={function(event) {
var editing_machine = null;
@ -437,7 +435,7 @@ var machine_management = createReactClass({
this.deleteExistingMachine(event, machine.pcbid);
}.bind(this)}
/>
</span>
</>
);
}
},

View File

@ -153,7 +153,7 @@ var news_management = createReactClass({
if (this.state.editing_news) {
if (this.state.editing_news.id == entry.id) {
return (
<span>
<>
<input
type="button"
value="preview"
@ -174,14 +174,14 @@ var news_management = createReactClass({
});
}.bind(this)}
/>
</span>
</>
);
} else {
return <span></span>;
return null;
}
} else {
return (
<span>
<>
<Edit
onClick={function(event) {
var editing_news = null;
@ -200,7 +200,7 @@ var news_management = createReactClass({
this.deleteExistingNews(event, entry.id);
}.bind(this)}
/>
</span>
</>
);
}
},

View File

@ -195,7 +195,7 @@ var user_management = createReactClass({
return (
<LabelledSection vertical={true} label="Username">{
!this.state.editing_username ?
<span>
<>
{
this.state.username ?
<span>{ this.state.username }</span> :
@ -206,7 +206,7 @@ var user_management = createReactClass({
this.setState({editing_username: true});
}.bind(this)}
/>
</span> :
</> :
<form className="inline" onSubmit={this.saveUsername}>
<input
type="text"
@ -242,14 +242,14 @@ var user_management = createReactClass({
return (
<LabelledSection vertical={true} label="Password">{
!this.state.editing_password ?
<span>
<>
<span>&bull;&bull;&bull;&bull;&bull;&bull;</span>
<Edit
onClick={function(event) {
this.setState({editing_password: true});
}.bind(this)}
/>
</span> :
</> :
<form className="inline" onSubmit={this.savePassword}>
<div>
<label htmlFor="new1">New password:</label>
@ -301,7 +301,7 @@ var user_management = createReactClass({
return (
<LabelledSection vertical={true} label="Email Address">{
!this.state.editing_email ?
<span>
<>
{
this.state.email ?
<span>{ this.state.email }</span> :
@ -312,7 +312,7 @@ var user_management = createReactClass({
this.setState({editing_email: true});
}.bind(this)}
/>
</span> :
</> :
<form className="inline" onSubmit={this.saveEmail}>
<input
type="text"
@ -348,14 +348,14 @@ var user_management = createReactClass({
return (
<LabelledSection vertical={true} label="PIN">{
!this.state.editing_pin ?
<span>
<>
<span>&bull;&bull;&bull;&bull;</span>
<Edit
onClick={function(event) {
this.setState({editing_pin: true});
}.bind(this)}
/>
</span> :
</> :
<form className="inline" onSubmit={this.savePin}>
<input
type="text"

View File

@ -207,14 +207,14 @@ var arcade_management = createReactClass({
return (
<LabelledSection vertical={true} label="PIN">{
!this.state.editing_pin ?
<span>
<>
<span>{this.state.pin}</span>
<Edit
onClick={function(event) {
this.setState({editing_pin: true, new_pin: this.state.pin});
}.bind(this)}
/>
</span> :
</> :
<form className="inline" onSubmit={this.savePin}>
<input
type="text"
@ -255,14 +255,14 @@ var arcade_management = createReactClass({
return (
<LabelledSection vertical={true} label="Region">{
!this.state.editing_region ?
<span>
<>
<span>{ window.regions[this.state.region] }</span>
<Edit
onClick={function(event) {
this.setState({editing_region: true, new_region: this.state.region});
}.bind(this)}
/>
</span> :
</> :
<form className="inline" onSubmit={this.saveRegion}>
<SelectInt
name="region"
@ -413,7 +413,7 @@ var arcade_management = createReactClass({
if (this.state.editing_machine) {
if (this.state.editing_machine.pcbid == machine.pcbid) {
return (
<span>
<>
<input
type="submit"
value="save"
@ -427,15 +427,15 @@ var arcade_management = createReactClass({
});
}.bind(this)}
/>
</span>
</>
);
} else {
return <span></span>;
return null;
}
} else {
if (window.max_pcbids > 0 && machine.editable) {
return (
<span>
<>
<Edit
onClick={function(event) {
var editing_machine = null;
@ -454,10 +454,10 @@ var arcade_management = createReactClass({
this.deleteExistingMachine(event, machine.pcbid);
}.bind(this)}
/>
</span>
</>
);
} else {
return <span></span>;
return null;
}
}
},
@ -475,13 +475,13 @@ var arcade_management = createReactClass({
{this.renderPIN()}
{this.renderRegion()}
<LabelledSection vertical={true} label={
<span>
<>
PASELI Enabled
{ this.state.paseli_enabled_saving ?
<img className="loading" src={Link.get('static', 'loading-16.gif')} /> :
null
}
</span>
</>
}>
<Slider
on="yes"
@ -494,13 +494,13 @@ var arcade_management = createReactClass({
/>
</LabelledSection>
<LabelledSection vertical={true} label={
<span>
<>
PASELI Infinite
{ this.state.paseli_infinite_saving ?
<img className="loading" src={Link.get('static', 'loading-16.gif')} /> :
null
}
</span>
</>
}>
<Slider
on="yes"
@ -513,13 +513,13 @@ var arcade_management = createReactClass({
/>
</LabelledSection>
<LabelledSection vertical={true} label={
<span>
<>
Mask Web Address
{ this.state.mask_services_url_saving ?
<img className="loading" src={Link.get('static', 'loading-16.gif')} /> :
null
}
</span>
</>
}>
<Slider
on="yes"

View File

@ -51,7 +51,6 @@ input[type="button"], button.nav, button.toggle, button.edit, button.add, button
border: 1px solid #6a6a6a;
color: #b0b1b2;
background: #282828;
margin-right: 5px;
}

View File

@ -186,11 +186,10 @@ span.filter:not(:last-child) {
span.slider-label {
position: relative;
padding-right: 20px;
top: -4px;
top: -3px;
}
.slider.fix .label {
margin-top: 1px;
margin-bottom: -1px;
}
}

View File

@ -284,7 +284,8 @@ span.checkbox {
}
div.slider {
display: inline-block;
display: inline-flex;
height: 18px;
border-radius: 10px;
}
@ -302,7 +303,7 @@ div.slider span.label {
width: 70px;
font-weight: normal;
font-size: small;
height: 18px;
height: 16px;
display: inline-block;
}
@ -325,5 +326,5 @@ div.slider span.ball {
}
div.slider span.ball.off {
margin-left: -16px;
margin-left: 54px;
}

View File

@ -45,6 +45,9 @@ table td.center {
table.list input[type="text"], table.add input[type="text"] {
width: 100%;
box-sizing: border-box;
-webkit-box-sizing:border-box;
-moz-box-sizing: border-box;
}
table.list select, table.add select {

View File

@ -186,8 +186,7 @@ span.filter:not(:last-child) {
span.slider-label {
position: relative;
padding-right: 20px;
top: -4px;
top: -3px;
}
.slider.fix .label {

View File

@ -278,7 +278,8 @@ span.checkbox {
}
div.slider {
display: inline-block;
display: inline-flex;
height: 18px;
border-radius: 10px;
}
@ -296,7 +297,7 @@ div.slider span.label {
width: 70px;
font-weight: normal;
font-size: small;
height: 18px;
height: 16px;
display: inline-block;
}
@ -319,5 +320,5 @@ div.slider span.ball {
}
div.slider span.ball.off {
margin-left: -16px;
margin-left: 54px;
}

View File

@ -45,6 +45,9 @@ table td.center {
table.list input[type="text"], table.add input[type="text"] {
width: 100%;
box-sizing: border-box;
-webkit-box-sizing:border-box;
-moz-box-sizing: border-box;
}
table.list select, table.add select {

View File

@ -1,3 +1,4 @@
<!DOCTYPE html>
<html>
<head>
{% if title %}

View File

@ -2,6 +2,8 @@ import argparse
import os
from react.jsx import JSXTransformer # type: ignore
from bemani.frontend.app import polyfill_fragments
SCRIPT_PATH: str = os.path.dirname(os.path.realpath(__file__))
@ -42,7 +44,7 @@ def main() -> None:
os.makedirs(os.path.dirname(outfile), exist_ok=True)
with open(infile, 'rb') as f:
jsx = transformer.transform_string(f.read().decode('utf-8')).encode('utf-8')
jsx = transformer.transform_string(polyfill_fragments(f.read().decode('utf-8'))).encode('utf-8')
print(f"Writing {outfile}...")
with open(outfile, 'wb') as f: