mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-27 16:03:07 +00:00
Compare commits
142 Commits
Print-dire
...
3.13.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a87e420437 | ||
|
|
46085c8d44 | ||
|
|
179e21755c | ||
|
|
e9ca68e7d3 | ||
|
|
9886200fa9 | ||
|
|
9a1070bb06 | ||
|
|
3b8dbe8a04 | ||
|
|
68f95f6130 | ||
|
|
35ae5e09ee | ||
|
|
552a23585b | ||
|
|
e635877b66 | ||
|
|
954bcbdaf6 | ||
|
|
559de2527b | ||
|
|
4c14774f1a | ||
|
|
ea380ae6a9 | ||
|
|
e2a946674f | ||
|
|
75926e34a2 | ||
|
|
37bc37bd94 | ||
|
|
528359dd9f | ||
|
|
f745fdefb3 | ||
|
|
2d9b80a81e | ||
|
|
299acfb92c | ||
|
|
8fc97493c5 | ||
|
|
7c7c6341f9 | ||
|
|
227ab192c4 | ||
|
|
ad48c0cd76 | ||
|
|
958b168906 | ||
|
|
51d4b5042c | ||
|
|
371ac9680c | ||
|
|
f68af555de | ||
|
|
66fdf808a6 | ||
|
|
65770782c2 | ||
|
|
fdf6acd80a | ||
|
|
08b61a6bb4 | ||
|
|
33c2bee873 | ||
|
|
8bbf2e1ce4 | ||
|
|
476002ae4d | ||
|
|
54ec1b8827 | ||
|
|
7bb92bc790 | ||
|
|
a87d62c9c2 | ||
|
|
8c315980e9 | ||
|
|
359a64968c | ||
|
|
866548deec | ||
|
|
ed39852a8f | ||
|
|
38fc647495 | ||
|
|
fa7b3ea2a0 | ||
|
|
9e041d26bd | ||
|
|
978c0c4c7b | ||
|
|
4f4cef0f6c | ||
|
|
556ded9b08 | ||
|
|
0efcd5d258 | ||
|
|
31b6e0c4f6 | ||
|
|
423413e41b | ||
|
|
ec514cdb51 | ||
|
|
7272544724 | ||
|
|
99ff7fdf14 | ||
|
|
491b38c330 | ||
|
|
4033d3ad99 | ||
|
|
9285d355b2 | ||
|
|
24e67e2270 | ||
|
|
5f6d5f53cc | ||
|
|
865c5678bc | ||
|
|
05ba7b41d1 | ||
|
|
e7735e242a | ||
|
|
1111d8275c | ||
|
|
f3b01bc75c | ||
|
|
8685c5cae4 | ||
|
|
e0a457bf40 | ||
|
|
d20c9c502c | ||
|
|
8c5e68e571 | ||
|
|
fbe65a4e93 | ||
|
|
3875dabfd2 | ||
|
|
930709223a | ||
|
|
a6ce36689c | ||
|
|
2424d34682 | ||
|
|
8fc224e9a1 | ||
|
|
98fc007efd | ||
|
|
7fb23c7362 | ||
|
|
a2f0546a6d | ||
|
|
fc22e6cd53 | ||
|
|
62ed026757 | ||
|
|
7cef4316d7 | ||
|
|
0df53daa4c | ||
|
|
b496ef3597 | ||
|
|
3ae5d4c1e3 | ||
|
|
d9d4d74b71 | ||
|
|
af82d71e4f | ||
|
|
f897cbfdf4 | ||
|
|
1773e77cb9 | ||
|
|
511c9ffada | ||
|
|
ea03538552 | ||
|
|
afb5ccec81 | ||
|
|
c0beae6e46 | ||
|
|
9c6ece3e7f | ||
|
|
5494c02f00 | ||
|
|
632efe8b9f | ||
|
|
bf38f95d25 | ||
|
|
f6daeb4acd | ||
|
|
10a7f34abb | ||
|
|
3a054f1ae0 | ||
|
|
9d6076f642 | ||
|
|
b86502aec7 | ||
|
|
2a148cb138 | ||
|
|
9426c6acd9 | ||
|
|
90ce48b170 | ||
|
|
448af683a0 | ||
|
|
ec5f8254f1 | ||
|
|
9f31a2c8a2 | ||
|
|
09cf5a9b04 | ||
|
|
4c6953a4e0 | ||
|
|
b4b4fbe375 | ||
|
|
4bc07ceb4e | ||
|
|
fde1706a0c | ||
|
|
b087e849b5 | ||
|
|
963ec282d3 | ||
|
|
7690fb9287 | ||
|
|
2e54520b32 | ||
|
|
cdf5b29ac2 | ||
|
|
733b929940 | ||
|
|
211fe48e29 | ||
|
|
9d3f7fe556 | ||
|
|
5d87508d0e | ||
|
|
40d0e7e90e | ||
|
|
7ca10ff5a4 | ||
|
|
1705e66be2 | ||
|
|
1e4f804542 | ||
|
|
6a03be9d64 | ||
|
|
591278862a | ||
|
|
9848e4b600 | ||
|
|
f0a8020189 | ||
|
|
a957ea37f6 | ||
|
|
a4d426bc00 | ||
|
|
41d43e84a5 | ||
|
|
bfd3eff6f2 | ||
|
|
75c41f4466 | ||
|
|
85caf0a892 | ||
|
|
692205b0e6 | ||
|
|
02e6a3df99 | ||
|
|
b8ee696b69 | ||
|
|
26c4b1afa6 | ||
|
|
622827efda | ||
|
|
854c21639a |
39
changelog.md
39
changelog.md
@@ -84,6 +84,45 @@ pre {
|
|||||||
## changelog
|
## changelog
|
||||||
For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery).
|
For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery).
|
||||||
|
|
||||||
|
### Friday 28/6/2024 - v3.13.0
|
||||||
|
{{taskList
|
||||||
|
|
||||||
|
##### calculuschild
|
||||||
|
|
||||||
|
* [x] Add `:emoji:` Markdown syntax, with autosuggest; start typing after the first `:` for matching emojis from
|
||||||
|
:fab_font_awesome: FontAwesome, :df_d20: DiceFont, :ei_action: ElderberryInn, and a subset of :gi_broadsword: GameIcons
|
||||||
|
|
||||||
|
* [x] Fix `{curly injection}` to append to, rather than erase and replace target CSS
|
||||||
|
* [x] {{openSans **GET PDF**}} {{fa,fa-file-pdf}} now opens the print dialog directly, rather than redirecting to a separate page
|
||||||
|
|
||||||
|
##### Gazook
|
||||||
|
|
||||||
|
* [x] Several small style tweaks to the UI
|
||||||
|
* [x] Cleaning and refactoring several large pieces of code
|
||||||
|
|
||||||
|
##### 5e-Cleric
|
||||||
|
|
||||||
|
* [x] For error pages, add links to user account and `/share` page if available
|
||||||
|
|
||||||
|
Fixes issue [#3298](https://github.com/naturalcrit/homebrewery/issues/3298)
|
||||||
|
|
||||||
|
* [x] Change FrontCover title to use stroke outline instead of faking it with dozens of shadows
|
||||||
|
* [x] Cleaning and refactoring several large pieces of CSS
|
||||||
|
|
||||||
|
##### abquintic
|
||||||
|
|
||||||
|
* [x] Added additional {{openSans **TABLE OF CONTENTS**}} snippet options. Explicitly include or exclude items from the ToC generation via CSS properties
|
||||||
|
`--TOC:exclude` or `--TOC:include`, or change the included header depth from 3 to 6 (default 3) with `tocDepthH6`
|
||||||
|
|
||||||
|
##### MurdoMaclachlan *(new contributor!)*
|
||||||
|
|
||||||
|
* [x] Added "proficiency bonus" to Monster Stat Block snippet.
|
||||||
|
|
||||||
|
Fixes issue [#3397](https://github.com/naturalcrit/homebrewery/issues/3397)
|
||||||
|
}}
|
||||||
|
|
||||||
|
\column
|
||||||
|
|
||||||
### Monday 18/3/2024 - v3.12.0
|
### Monday 18/3/2024 - v3.12.0
|
||||||
{{taskList
|
{{taskList
|
||||||
|
|
||||||
|
|||||||
29
client/components/dialog.jsx
Normal file
29
client/components/dialog.jsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// Dialog box, for popups and modal blocking messages
|
||||||
|
const React = require('react');
|
||||||
|
const { useRef, useEffect } = React;
|
||||||
|
|
||||||
|
function Dialog({ dismissKey, closeText = 'Close', blocking = false, ...rest }) {
|
||||||
|
const dialogRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
if(!dismissKey || !localStorage.getItem(dismissKey)) {
|
||||||
|
blocking ? dialogRef.current?.showModal() : dialogRef.current?.show();
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const dismiss = ()=>{
|
||||||
|
dismissKey && localStorage.setItem(dismissKey, true);
|
||||||
|
dialogRef.current?.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<dialog ref={dialogRef} onCancel={dismiss} {...rest}>
|
||||||
|
{rest.children}
|
||||||
|
<button className='dismiss' onClick={dismiss}>
|
||||||
|
{closeText}
|
||||||
|
</button>
|
||||||
|
</dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Dialog;
|
||||||
@@ -203,6 +203,12 @@ const BrewRenderer = (props)=>{
|
|||||||
</div>
|
</div>
|
||||||
: null}
|
: null}
|
||||||
|
|
||||||
|
<ErrorBar errors={props.errors} />
|
||||||
|
<div className='popups'>
|
||||||
|
<RenderWarnings />
|
||||||
|
<NotificationPopup />
|
||||||
|
</div>
|
||||||
|
|
||||||
{/*render in iFrame so broken code doesn't crash the site.*/}
|
{/*render in iFrame so broken code doesn't crash the site.*/}
|
||||||
<Frame id='BrewRenderer' initialContent={INITIAL_CONTENT}
|
<Frame id='BrewRenderer' initialContent={INITIAL_CONTENT}
|
||||||
style={{ width: '100%', height: '100%', visibility: state.visibility }}
|
style={{ width: '100%', height: '100%', visibility: state.visibility }}
|
||||||
@@ -215,11 +221,6 @@ const BrewRenderer = (props)=>{
|
|||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
style={{ height: state.height }}>
|
style={{ height: state.height }}>
|
||||||
|
|
||||||
<ErrorBar errors={props.errors} />
|
|
||||||
<div className='popups'>
|
|
||||||
<RenderWarnings />
|
|
||||||
<NotificationPopup />
|
|
||||||
</div>
|
|
||||||
<link href={`/themes/${rendererPath}/Blank/style.css`} type='text/css' rel='stylesheet'/>
|
<link href={`/themes/${rendererPath}/Blank/style.css`} type='text/css' rel='stylesheet'/>
|
||||||
{baseThemePath &&
|
{baseThemePath &&
|
||||||
<link href={`/themes/${rendererPath}/${baseThemePath}/style.css`} type='text/css' rel='stylesheet'/>
|
<link href={`/themes/${rendererPath}/${baseThemePath}/style.css`} type='text/css' rel='stylesheet'/>
|
||||||
|
|||||||
@@ -1,80 +1,45 @@
|
|||||||
require('./notificationPopup.less');
|
require('./notificationPopup.less');
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const createClass = require('create-react-class');
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
|
||||||
|
import Dialog from '../../../components/dialog.jsx';
|
||||||
|
|
||||||
const DISMISS_KEY = 'dismiss_notification12-04-23';
|
const DISMISS_KEY = 'dismiss_notification12-04-23';
|
||||||
|
const DISMISS_BUTTON = <i className='fas fa-times dismiss' />;
|
||||||
|
|
||||||
const NotificationPopup = createClass({
|
const NotificationPopup = ()=>{
|
||||||
displayName : 'NotificationPopup',
|
return <Dialog className='notificationPopup' dismissKey={DISMISS_KEY} closeText={DISMISS_BUTTON} >
|
||||||
getInitialState : function() {
|
<div className='header'>
|
||||||
return {
|
<i className='fas fa-info-circle info'></i>
|
||||||
notifications : {}
|
<h3>Notice</h3>
|
||||||
};
|
<small>This website is always improving and we are still adding new features and squashing bugs. Keep the following in mind:</small>
|
||||||
},
|
</div>
|
||||||
componentDidMount : function() {
|
<ul>
|
||||||
this.checkNotifications();
|
<li key='psa'>
|
||||||
window.addEventListener('resize', this.checkNotifications);
|
<em>Don't store IMAGES in Google Drive</em><br />
|
||||||
},
|
Google Drive is not an image service, and will block images from being used
|
||||||
componentWillUnmount : function() {
|
in brews if they get more views than expected. Google has confirmed they won't fix
|
||||||
window.removeEventListener('resize', this.checkNotifications);
|
this, so we recommend you look for another image hosting service such as imgur, ImgBB or Google Photos.
|
||||||
},
|
</li>
|
||||||
notifications : {
|
|
||||||
psa : function(){
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<li key='psa'>
|
|
||||||
<em>Don't store IMAGES in Google Drive</em><br />
|
|
||||||
Google Drive is not an image service, and will block images from being used
|
|
||||||
in brews if they get more views than expected. Google has confirmed they won't fix
|
|
||||||
this, so we recommend you look for another image hosting service such as imgur, ImgBB or Google Photos.
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li key='googleDriveFolder'>
|
<li key='googleDriveFolder'>
|
||||||
<em>Don't delete your Homebrewery folder on Google Drive!</em> <br />
|
<em>Don't delete your Homebrewery folder on Google Drive!</em> <br />
|
||||||
We have had several reports of users losing their brews, not realizing
|
We have had several reports of users losing their brews, not realizing
|
||||||
that they had deleted the files on their Google Drive. If you have a Homebrewery folder
|
that they had deleted the files on their Google Drive. If you have a Homebrewery folder
|
||||||
on your Google Drive with *.txt files inside, <em>do not delete it</em>!
|
on your Google Drive with *.txt files inside, <em>do not delete it</em>!
|
||||||
We cannot help you recover files that you have deleted from your own
|
We cannot help you recover files that you have deleted from your own
|
||||||
Google Drive.
|
Google Drive.
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li key='faq'>
|
<li key='faq'>
|
||||||
<em>Protect your work! </em> <br />
|
<em>Protect your work! </em> <br />
|
||||||
If you opt not to use your Google Drive, keep in mind that we do not save a history of your projects. Please make frequent backups of your brews!
|
If you opt not to use your Google Drive, keep in mind that we do not save a history of your projects. Please make frequent backups of your brews!
|
||||||
<a target='_blank' href='https://www.reddit.com/r/homebrewery/comments/adh6lh/faqs_psas_announcements/'>
|
<a target='_blank' href='https://www.reddit.com/r/homebrewery/comments/adh6lh/faqs_psas_announcements/'>
|
||||||
See the FAQ
|
See the FAQ
|
||||||
</a> to learn how to avoid losing your work!
|
</a> to learn how to avoid losing your work!
|
||||||
</li>
|
</li>
|
||||||
</>
|
</ul>
|
||||||
);
|
</Dialog>;
|
||||||
}
|
};
|
||||||
},
|
|
||||||
checkNotifications : function(){
|
|
||||||
const hideDismiss = localStorage.getItem(DISMISS_KEY);
|
|
||||||
if(hideDismiss) return this.setState({ notifications: {} });
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
notifications : _.mapValues(this.notifications, (fn)=>{ return fn(); }) //Convert notification functions into their return text value
|
|
||||||
});
|
|
||||||
},
|
|
||||||
dismiss : function(){
|
|
||||||
localStorage.setItem(DISMISS_KEY, true);
|
|
||||||
this.checkNotifications();
|
|
||||||
},
|
|
||||||
render : function(){
|
|
||||||
if(_.isEmpty(this.state.notifications)) return null;
|
|
||||||
|
|
||||||
return <div className='notificationPopup'>
|
|
||||||
<i className='fas fa-times dismiss' onClick={this.dismiss}/>
|
|
||||||
<i className='fas fa-info-circle info' />
|
|
||||||
<div className='header'>
|
|
||||||
<h3>Notice</h3>
|
|
||||||
<small>This website is always improving and we are still adding new features and squashing bugs. Keep the following in mind:</small>
|
|
||||||
</div>
|
|
||||||
<ul>{_.values(this.state.notifications)}</ul>
|
|
||||||
</div>;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = NotificationPopup;
|
module.exports = NotificationPopup;
|
||||||
|
|||||||
@@ -1,64 +1,60 @@
|
|||||||
.popups{
|
.popups {
|
||||||
position : fixed;
|
position : fixed;
|
||||||
top : @navbarHeight;
|
top : @navbarHeight;
|
||||||
right : 15px;
|
right : 24px;
|
||||||
z-index : 10001;
|
z-index : 10001;
|
||||||
width : 450px;
|
width : 450px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notificationPopup{
|
.notificationPopup {
|
||||||
position : relative;
|
position : relative;
|
||||||
display : inline-block;
|
|
||||||
width : 100%;
|
width : 100%;
|
||||||
padding : 15px;
|
padding : 15px;
|
||||||
padding-bottom : 10px;
|
padding-bottom : 10px;
|
||||||
padding-left : 25px;
|
padding-left : 25px;
|
||||||
background-color : @blue;
|
|
||||||
color : white;
|
color : white;
|
||||||
a{
|
background-color : @blue;
|
||||||
color : #e0e5c1;
|
border : none;
|
||||||
|
&[open] { display : inline-block; }
|
||||||
|
a {
|
||||||
font-weight : 800;
|
font-weight : 800;
|
||||||
|
color : #E0E5C1;
|
||||||
}
|
}
|
||||||
i.info{
|
i.info {
|
||||||
position : absolute;
|
position : absolute;
|
||||||
top : 12px;
|
top : 12px;
|
||||||
left : 12px;
|
left : 12px;
|
||||||
opacity : 0.8;
|
|
||||||
font-size : 2.5em;
|
font-size : 2.5em;
|
||||||
|
opacity : 0.8;
|
||||||
}
|
}
|
||||||
i.dismiss{
|
button.dismiss {
|
||||||
position : absolute;
|
position : absolute;
|
||||||
top : 10px;
|
top : 10px;
|
||||||
right : 10px;
|
right : 10px;
|
||||||
cursor : pointer;
|
cursor : pointer;
|
||||||
opacity : 0.6;
|
background-color : transparent;
|
||||||
&:hover{
|
opacity : 0.6;
|
||||||
opacity : 1;
|
&:hover { opacity : 1; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.header {
|
.header { padding-left : 50px; }
|
||||||
padding-left : 50px;
|
small {
|
||||||
}
|
|
||||||
small{
|
|
||||||
opacity : 0.7;
|
|
||||||
font-size : 0.6em;
|
font-size : 0.6em;
|
||||||
|
opacity : 0.7;
|
||||||
}
|
}
|
||||||
h3{
|
h3 {
|
||||||
font-size : 1.1em;
|
font-size : 1.1em;
|
||||||
font-weight : 800;
|
font-weight : 800;
|
||||||
}
|
}
|
||||||
ul{
|
ul {
|
||||||
margin-top : 15px;
|
margin-top : 15px;
|
||||||
font-size : 0.8em;
|
font-size : 0.8em;
|
||||||
list-style-position : outside;
|
list-style-position : outside;
|
||||||
list-style-type : disc;
|
list-style-type : disc;
|
||||||
li{
|
li {
|
||||||
|
margin-top : 1.4em;
|
||||||
font-size : 0.8em;
|
font-size : 0.8em;
|
||||||
line-height : 1.4em;
|
line-height : 1.4em;
|
||||||
margin-top : 1.4em;
|
em { font-weight : 800; }
|
||||||
em{
|
|
||||||
font-weight : 800;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
|
|||||||
const Editor = require('../../editor/editor.jsx');
|
const Editor = require('../../editor/editor.jsx');
|
||||||
const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
|
const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
|
||||||
|
|
||||||
|
const LockNotification = require('./lockNotification/lockNotification.jsx');
|
||||||
|
|
||||||
const Markdown = require('naturalcrit/markdown.js');
|
const Markdown = require('naturalcrit/markdown.js');
|
||||||
|
|
||||||
const { DEFAULT_BREW_LOAD } = require('../../../../server/brewDefaults.js');
|
const { DEFAULT_BREW_LOAD } = require('../../../../server/brewDefaults.js');
|
||||||
@@ -52,7 +54,8 @@ const EditPage = createClass({
|
|||||||
autoSave : true,
|
autoSave : true,
|
||||||
autoSaveWarning : false,
|
autoSaveWarning : false,
|
||||||
unsavedTime : new Date(),
|
unsavedTime : new Date(),
|
||||||
currentEditorPage : 0
|
currentEditorPage : 0,
|
||||||
|
displayLockMessage : this.props.brew.lock || false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -393,6 +396,7 @@ const EditPage = createClass({
|
|||||||
{this.renderNavbar()}
|
{this.renderNavbar()}
|
||||||
|
|
||||||
<div className='content'>
|
<div className='content'>
|
||||||
|
{this.props.brew.lock && <LockNotification shareId={this.props.brew.shareId} message={this.props.brew.lock.editMessage} />}
|
||||||
<SplitPane onDragFinish={this.handleSplitMove}>
|
<SplitPane onDragFinish={this.handleSplitMove}>
|
||||||
<Editor
|
<Editor
|
||||||
ref={this.editor}
|
ref={this.editor}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
require('./lockNotification.less');
|
||||||
|
const React = require('react');
|
||||||
|
import Dialog from '../../../../components/dialog.jsx';
|
||||||
|
|
||||||
|
function LockNotification(props) {
|
||||||
|
props = {
|
||||||
|
shareId : 0,
|
||||||
|
disableLock : ()=>{},
|
||||||
|
message : '',
|
||||||
|
...props
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeLock = ()=>{
|
||||||
|
alert(`Not yet implemented - ID ${props.shareId}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
return <Dialog className='lockNotification' blocking closeText='CONTINUE TO EDITOR' >
|
||||||
|
<h1>BREW LOCKED</h1>
|
||||||
|
<p>This brew been locked by the Administrators. It will not be accessible by any method other than the Editor until the lock is removed.</p>
|
||||||
|
<hr />
|
||||||
|
<h3>LOCK REASON</h3>
|
||||||
|
<p>{props.message || 'Unable to retrieve Lock Message'}</p>
|
||||||
|
<hr />
|
||||||
|
<p>Once you have resolved this issue, click REQUEST LOCK REMOVAL to notify the Administrators for review.</p>
|
||||||
|
<p>Click CONTINUE TO EDITOR to temporarily hide this notification; it will reappear the next time the page is reloaded.</p>
|
||||||
|
<button onClick={removeLock}>REQUEST LOCK REMOVAL</button>
|
||||||
|
</Dialog>;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = LockNotification;
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
.lockNotification {
|
||||||
|
z-index : 1;
|
||||||
|
width : 80%;
|
||||||
|
padding : 10px;
|
||||||
|
margin : 5% 10%;
|
||||||
|
line-height : 1.5em;
|
||||||
|
color : black;
|
||||||
|
text-align : center;
|
||||||
|
background-color : #CCCCCC;
|
||||||
|
|
||||||
|
&::backdrop { background-color : #000000AA; }
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin : 10px;
|
||||||
|
color : white;
|
||||||
|
background-color : #333333;
|
||||||
|
|
||||||
|
&:hover { background-color : #777777; }
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h3 {
|
||||||
|
font-family : 'Open Sans', sans-serif;
|
||||||
|
font-weight : 800;
|
||||||
|
}
|
||||||
|
h1 { font-size : 24px; }
|
||||||
|
h3 { font-size : 18px; }
|
||||||
|
}
|
||||||
@@ -140,7 +140,7 @@ const errorIndex = (props)=>{
|
|||||||
'100' : dedent`
|
'100' : dedent`
|
||||||
## This brew has been locked.
|
## This brew has been locked.
|
||||||
|
|
||||||
Please contact the Administrators to unlock this document.
|
Only an author may request that this lock is removed.
|
||||||
|
|
||||||
:
|
:
|
||||||
|
|
||||||
|
|||||||
1509
package-lock.json
generated
1509
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
20
package.json
20
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "homebrewery",
|
"name": "homebrewery",
|
||||||
"description": "Create authentic looking D&D homebrews using only markdown",
|
"description": "Create authentic looking D&D homebrews using only markdown",
|
||||||
"version": "3.12.0",
|
"version": "3.13.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"npm": "^10.2.x",
|
"npm": "^10.2.x",
|
||||||
"node": "^20.8.x"
|
"node": "^20.8.x"
|
||||||
@@ -82,18 +82,18 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.24.5",
|
"@babel/core": "^7.24.7",
|
||||||
"@babel/plugin-transform-runtime": "^7.24.3",
|
"@babel/plugin-transform-runtime": "^7.24.7",
|
||||||
"@babel/preset-env": "^7.24.5",
|
"@babel/preset-env": "^7.24.7",
|
||||||
"@babel/preset-react": "^7.24.1",
|
"@babel/preset-react": "^7.24.7",
|
||||||
"@googleapis/drive": "^8.8.0",
|
"@googleapis/drive": "^8.10.0",
|
||||||
"body-parser": "^1.20.2",
|
"body-parser": "^1.20.2",
|
||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"codemirror": "^5.65.6",
|
"codemirror": "^5.65.6",
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"create-react-class": "^15.7.0",
|
"create-react-class": "^15.7.0",
|
||||||
"dedent-tabs": "^0.10.3",
|
"dedent-tabs": "^0.10.3",
|
||||||
"dompurify": "^3.1.4",
|
"dompurify": "^3.1.5",
|
||||||
"expr-eval": "^2.0.2",
|
"expr-eval": "^2.0.2",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"express-async-handler": "^1.2.0",
|
"express-async-handler": "^1.2.0",
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
"marked-smartypants-lite": "^1.0.2",
|
"marked-smartypants-lite": "^1.0.2",
|
||||||
"markedLegacy": "npm:marked@^0.3.19",
|
"markedLegacy": "npm:marked@^0.3.19",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"mongoose": "^8.4.0",
|
"mongoose": "^8.4.1",
|
||||||
"nanoid": "3.3.4",
|
"nanoid": "3.3.4",
|
||||||
"nconf": "^0.12.1",
|
"nconf": "^0.12.1",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
@@ -123,8 +123,8 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-plugin-jest": "^28.5.0",
|
"eslint-plugin-jest": "^28.6.0",
|
||||||
"eslint-plugin-react": "^7.34.1",
|
"eslint-plugin-react": "^7.34.2",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"jest-expect-message": "^1.1.3",
|
"jest-expect-message": "^1.1.3",
|
||||||
"postcss-less": "^6.0.0",
|
"postcss-less": "^6.0.0",
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ const api = {
|
|||||||
stub = stub?.toObject();
|
stub = stub?.toObject();
|
||||||
|
|
||||||
if(stub?.lock?.locked && accessType != 'edit') {
|
if(stub?.lock?.locked && accessType != 'edit') {
|
||||||
throw { HBErrorCode: '100', code: stub.lock.code, message: stub.lock.message, brewId: stub.shareId, brewTitle: stub.title };
|
throw { HBErrorCode: '100', code: stub.lock.code, message: stub.lock.shareMessage, brewId: stub.shareId, brewTitle: stub.title };
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a google id, try to find the google brew
|
// If there is a google id, try to find the google brew
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ describe('Tests for api', ()=>{
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('access is denied to a locked brew', async()=>{
|
it('access is denied to a locked brew', async()=>{
|
||||||
const lockBrew = { title: 'test brew', shareId: '1', lock: { locked: true, code: 404, message: 'brew locked' } };
|
const lockBrew = { title: 'test brew', shareId: '1', lock: { locked: true, code: 404, shareMessage: 'brew locked' } };
|
||||||
model.get = jest.fn(()=>toBrewPromise(lockBrew));
|
model.get = jest.fn(()=>toBrewPromise(lockBrew));
|
||||||
api.getId = jest.fn(()=>({ id: '1', googleId: undefined }));
|
api.getId = jest.fn(()=>({ id: '1', googleId: undefined }));
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ const React = require('react');
|
|||||||
const createClass = require('create-react-class');
|
const createClass = require('create-react-class');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
|
||||||
const DISMISS_KEY = 'dismiss_render_warning';
|
import Dialog from '../../../client/components/dialog.jsx';
|
||||||
|
|
||||||
const RenderWarnings = createClass({
|
const RenderWarnings = createClass({
|
||||||
displayName : 'RenderWarnings',
|
displayName : 'RenderWarnings',
|
||||||
@@ -34,9 +34,6 @@ const RenderWarnings = createClass({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
checkWarnings : function(){
|
checkWarnings : function(){
|
||||||
const hideDismiss = localStorage.getItem(DISMISS_KEY);
|
|
||||||
if(hideDismiss) return this.setState({ warnings: {} });
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
warnings : _.reduce(this.warnings, (r, fn, type)=>{
|
warnings : _.reduce(this.warnings, (r, fn, type)=>{
|
||||||
const element = fn();
|
const element = fn();
|
||||||
@@ -45,20 +42,18 @@ const RenderWarnings = createClass({
|
|||||||
}, {})
|
}, {})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
dismiss : function(){
|
|
||||||
localStorage.setItem(DISMISS_KEY, true);
|
|
||||||
this.checkWarnings();
|
|
||||||
},
|
|
||||||
render : function(){
|
render : function(){
|
||||||
if(_.isEmpty(this.state.warnings)) return null;
|
if(_.isEmpty(this.state.warnings)) return null;
|
||||||
|
|
||||||
return <div className='renderWarnings'>
|
const DISMISS_KEY = 'dismiss_render_warning';
|
||||||
<i className='fas fa-times dismiss' onClick={this.dismiss}/>
|
const DISMISS_TEXT = <i className='fas fa-times dismiss' />;
|
||||||
|
|
||||||
|
return <Dialog className='renderWarnings' dismissKey={DISMISS_KEY} closeText={DISMISS_TEXT}>
|
||||||
<i className='fas fa-exclamation-triangle ohno' />
|
<i className='fas fa-exclamation-triangle ohno' />
|
||||||
<h3>Render Warnings</h3>
|
<h3>Render Warnings</h3>
|
||||||
<small>If this homebrew is rendering badly if might be because of the following:</small>
|
<small>If this homebrew is rendering badly if might be because of the following:</small>
|
||||||
<ul>{_.values(this.state.warnings)}</ul>
|
<ul>{_.values(this.state.warnings)}</ul>
|
||||||
</div>;
|
</Dialog>;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,53 +1,48 @@
|
|||||||
.renderWarnings{
|
.renderWarnings {
|
||||||
position : relative;
|
position : relative;
|
||||||
float : right;
|
float : right;
|
||||||
display : inline-block;
|
|
||||||
width : 350px;
|
width : 350px;
|
||||||
padding : 20px;
|
padding : 20px;
|
||||||
padding-bottom : 10px;
|
padding-bottom : 10px;
|
||||||
padding-left : 85px;
|
padding-left : 85px;
|
||||||
margin-bottom : 10px;
|
margin-bottom : 10px;
|
||||||
background-color : @yellow;
|
|
||||||
color : white;
|
color : white;
|
||||||
a{
|
background-color : @yellow;
|
||||||
font-weight : 800;
|
border : none;
|
||||||
}
|
a { font-weight : 800; }
|
||||||
i.ohno{
|
i.ohno {
|
||||||
position : absolute;
|
position : absolute;
|
||||||
top : 24px;
|
top : 24px;
|
||||||
left : 24px;
|
left : 24px;
|
||||||
opacity : 0.8;
|
|
||||||
font-size : 2.5em;
|
font-size : 2.5em;
|
||||||
|
opacity : 0.8;
|
||||||
}
|
}
|
||||||
i.dismiss{
|
button.dismiss {
|
||||||
position : absolute;
|
position : absolute;
|
||||||
top : 10px;
|
top : 10px;
|
||||||
right : 10px;
|
right : 10px;
|
||||||
cursor : pointer;
|
cursor : pointer;
|
||||||
opacity : 0.6;
|
background-color : transparent;
|
||||||
&:hover{
|
opacity : 0.6;
|
||||||
opacity : 1;
|
&:hover { opacity : 1; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
small{
|
small {
|
||||||
opacity : 0.7;
|
|
||||||
font-size : 0.6em;
|
font-size : 0.6em;
|
||||||
|
opacity : 0.7;
|
||||||
}
|
}
|
||||||
h3{
|
h3 {
|
||||||
font-size : 1.1em;
|
font-size : 1.1em;
|
||||||
font-weight : 800;
|
font-weight : 800;
|
||||||
}
|
}
|
||||||
ul{
|
ul {
|
||||||
margin-top : 15px;
|
margin-top : 15px;
|
||||||
font-size : 0.8em;
|
font-size : 0.8em;
|
||||||
list-style-position : outside;
|
list-style-position : outside;
|
||||||
list-style-type : disc;
|
list-style-type : disc;
|
||||||
li{
|
li {
|
||||||
font-size : 0.8em;
|
font-size : 0.8em;
|
||||||
line-height : 1.6em;
|
line-height : 1.6em;
|
||||||
em{
|
em { font-weight : 800; }
|
||||||
font-weight : 800;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
@import (less) './themes/fonts/iconFonts/diceFont.less';
|
@import (less) './themes/fonts/iconFonts/diceFont.less';
|
||||||
@import (less) './themes/fonts/iconFonts/elderberryInn.less';
|
@import (less) './themes/fonts/iconFonts/elderberryInn.less';
|
||||||
@import (less) './themes/fonts/iconFonts/gameIcons.less';
|
@import (less) './themes/fonts/iconFonts/gameIcons.less';
|
||||||
|
@import (less) './themes/fonts/iconFonts/fontAwesome.less';
|
||||||
|
|
||||||
@keyframes sourceMoveAnimation {
|
@keyframes sourceMoveAnimation {
|
||||||
50% {background-color: red; color: white;}
|
50% {background-color: red; color: white;}
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ const Nav = {
|
|||||||
color : null
|
color : null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleClick : function(){
|
handleClick : function(e){
|
||||||
this.props.onClick();
|
this.props.onClick(e);
|
||||||
},
|
},
|
||||||
render : function(){
|
render : function(){
|
||||||
const classes = cx('navItem', this.props.color, this.props.className);
|
const classes = cx('navItem', this.props.color, this.props.className);
|
||||||
|
|||||||
@@ -21,9 +21,43 @@ module.exports = [
|
|||||||
view : 'text',
|
view : 'text',
|
||||||
snippets : [
|
snippets : [
|
||||||
{
|
{
|
||||||
name : 'Table of Contents',
|
name : 'Table of Contents',
|
||||||
icon : 'fas fa-book',
|
icon : 'fas fa-book',
|
||||||
gen : TableOfContentsGen
|
gen : TableOfContentsGen,
|
||||||
|
experimental : true,
|
||||||
|
subsnippets : [
|
||||||
|
{
|
||||||
|
name : 'Table of Contents',
|
||||||
|
icon : 'fas fa-book',
|
||||||
|
gen : TableOfContentsGen,
|
||||||
|
experimental : true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'Include in ToC up to H3',
|
||||||
|
icon : 'fas fa-dice-three',
|
||||||
|
gen : dedent `\n{{tocDepthH3
|
||||||
|
}}\n`,
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'Include in ToC up to H4',
|
||||||
|
icon : 'fas fa-dice-four',
|
||||||
|
gen : dedent `\n{{tocDepthH4
|
||||||
|
}}\n`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'Include in ToC up to H5',
|
||||||
|
icon : 'fas fa-dice-five',
|
||||||
|
gen : dedent `\n{{tocDepthH5
|
||||||
|
}}\n`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name : 'Include in ToC up to H6',
|
||||||
|
icon : 'fas fa-dice-six',
|
||||||
|
gen : dedent `\n{{tocDepthH6
|
||||||
|
}}\n`,
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name : 'Index',
|
name : 'Index',
|
||||||
|
|||||||
@@ -2,77 +2,68 @@ const _ = require('lodash');
|
|||||||
const dedent = require('dedent-tabs').default;
|
const dedent = require('dedent-tabs').default;
|
||||||
|
|
||||||
const getTOC = (pages)=>{
|
const getTOC = (pages)=>{
|
||||||
const add1 = (title, page)=>{
|
|
||||||
res.push({
|
const recursiveAdd = (title, page, targetDepth, child, curDepth=0)=>{
|
||||||
title : title,
|
if(curDepth > 5) return; // Something went wrong.
|
||||||
page : page + 1,
|
if(curDepth == targetDepth) {
|
||||||
children : []
|
child.push({
|
||||||
});
|
title : title,
|
||||||
};
|
page : page + 1,
|
||||||
const add2 = (title, page)=>{
|
children : []
|
||||||
if(!_.last(res)) add1(null, page);
|
});
|
||||||
_.last(res).children.push({
|
} else {
|
||||||
title : title,
|
if(child.length == 0) {
|
||||||
page : page + 1,
|
child.push({
|
||||||
children : []
|
title : null,
|
||||||
});
|
page : page + 1,
|
||||||
};
|
children : []
|
||||||
const add3 = (title, page)=>{
|
});
|
||||||
if(!_.last(res)) add1(null, page);
|
}
|
||||||
if(!_.last(_.last(res).children)) add2(null, page);
|
recursiveAdd(title, page, targetDepth, _.last(child).children, curDepth+1,);
|
||||||
_.last(_.last(res).children).children.push({
|
}
|
||||||
title : title,
|
|
||||||
page : page + 1,
|
|
||||||
children : []
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = [];
|
const res = [];
|
||||||
_.each(pages, (page, pageNum)=>{
|
|
||||||
if(!page.includes('{{frontCover}}') && !page.includes('{{insideCover}}') && !page.includes('{{partCover}}') && !page.includes('{{backCover}}')) {
|
const iframe = document.getElementById('BrewRenderer');
|
||||||
const lines = page.split('\n');
|
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
|
||||||
_.each(lines, (line)=>{
|
const headings = iframeDocument.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
||||||
if(_.startsWith(line, '# ')){
|
const headerDepth = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'];
|
||||||
const title = line.replace('# ', '');
|
|
||||||
add1(title, pageNum);
|
_.each(headings, (heading)=>{
|
||||||
}
|
const onPage = parseInt(heading.closest('.page').id?.replace(/^p/, ''));
|
||||||
if(_.startsWith(line, '## ')){
|
const ToCExclude = getComputedStyle(heading).getPropertyValue('--TOC');
|
||||||
const title = line.replace('## ', '');
|
|
||||||
add2(title, pageNum);
|
if(ToCExclude != 'exclude') {
|
||||||
}
|
recursiveAdd(heading.innerText.trim(), onPage, headerDepth.indexOf(heading.tagName), res);
|
||||||
if(_.startsWith(line, '### ')){
|
|
||||||
const title = line.replace('### ', '');
|
|
||||||
add3(title, pageNum);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const ToCIterate = (entries, curDepth=0)=>{
|
||||||
|
const levelPad = ['- ###', ' - ####', ' - ', ' - ', ' - ', ' - '];
|
||||||
|
const toc = [];
|
||||||
|
if(entries.title !== null){
|
||||||
|
toc.push(`${levelPad[curDepth]} [{{ ${entries.title}}}{{ ${entries.page}}}](#p${entries.page})`);
|
||||||
|
}
|
||||||
|
if(entries.children.length) {
|
||||||
|
_.each(entries.children, (entry, idx)=>{
|
||||||
|
const children = ToCIterate(entry, entry.title == null ? curDepth : curDepth+1);
|
||||||
|
if(children.length) {
|
||||||
|
toc.push(...children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return toc;
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = function(props){
|
module.exports = function(props){
|
||||||
const pages = props.brew.text.split('\\page');
|
const pages = props.brew.text.split('\\page');
|
||||||
const TOC = getTOC(pages);
|
const TOC = getTOC(pages);
|
||||||
const markdown = _.reduce(TOC, (r, g1, idx1)=>{
|
const markdown = _.reduce(TOC, (r, g1, idx1)=>{
|
||||||
if(g1.title !== null) {
|
r.push(ToCIterate(g1).join('\n'));
|
||||||
r.push(`- ### [{{ ${g1.title}}}{{ ${g1.page}}}](#p${g1.page})`);
|
|
||||||
}
|
|
||||||
if(g1.children.length){
|
|
||||||
_.each(g1.children, (g2, idx2)=>{
|
|
||||||
if(g2.title !== null) {
|
|
||||||
r.push(` - #### [{{ ${g2.title}}}{{ ${g2.page}}}](#p${g2.page})`);
|
|
||||||
}
|
|
||||||
if(g2.children.length){
|
|
||||||
_.each(g2.children, (g3, idx3)=>{
|
|
||||||
if(g2.title !== null) {
|
|
||||||
r.push(` - [{{ ${g3.title}}}{{ ${g3.page}}}](#p${g3.page})`);
|
|
||||||
} else { // Don't over-indent if no level-2 parent entry
|
|
||||||
r.push(` - [{{ ${g3.title}}}{{ ${g3.page}}}](#p${g3.page})`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return r;
|
return r;
|
||||||
}, []).join('\n');
|
}, []).join('\n');
|
||||||
|
|
||||||
|
|||||||
@@ -786,6 +786,39 @@
|
|||||||
// *****************************
|
// *****************************
|
||||||
// * TABLE OF CONTENTS
|
// * TABLE OF CONTENTS
|
||||||
// *****************************/
|
// *****************************/
|
||||||
|
|
||||||
|
// Default Exclusions
|
||||||
|
// Anything not exlcuded is included, default Headers are H1, H2, and H3.
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
.page:has(.frontCover),
|
||||||
|
.page:has(.backCover),
|
||||||
|
.page:has(.insideCover),
|
||||||
|
.monster,
|
||||||
|
.noToC,
|
||||||
|
.toc { --TOC: exclude; }
|
||||||
|
|
||||||
|
.tocDepthH2 :is(h1, h2) {--TOC: include; }
|
||||||
|
.tocDepthH3 :is(h1, h2, h3) {--TOC: include; }
|
||||||
|
.tocDepthH4 :is(h1, h2, h3, h4) {--TOC: include; }
|
||||||
|
.tocDepthH5 :is(h1, h2, h3, h4, h5) {--TOC: include; }
|
||||||
|
.tocDepthH6 :is(h1, h2, h3, h4, h5, h6) {--TOC: include; }
|
||||||
|
|
||||||
|
.tocIncludeH1 h1 {--TOC: include; }
|
||||||
|
.tocIncludeH2 h2 {--TOC: include; }
|
||||||
|
.tocIncludeH3 h3 {--TOC: include; }
|
||||||
|
.tocIncludeH4 h4 {--TOC: include; }
|
||||||
|
.tocIncludeH5 h5 {--TOC: include; }
|
||||||
|
.tocIncludeH6 h6 {--TOC: include; }
|
||||||
|
|
||||||
|
.page:has(.partCover) {
|
||||||
|
--TOC: exclude;
|
||||||
|
& h1 {
|
||||||
|
--TOC: include;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
&:has(.toc)::after { display : none; }
|
&:has(.toc)::after { display : none; }
|
||||||
.toc {
|
.toc {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
@import (less) './themes/fonts/iconFonts/elderberryInn.less';
|
@import (less) './themes/fonts/iconFonts/elderberryInn.less';
|
||||||
@import (less) './themes/fonts/iconFonts/diceFont.less';
|
@import (less) './themes/fonts/iconFonts/diceFont.less';
|
||||||
@import (less) './themes/fonts/iconFonts/gameIcons.less';
|
@import (less) './themes/fonts/iconFonts/gameIcons.less';
|
||||||
|
@import (less) './themes/fonts/iconFonts/fontAwesome.less';
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
//Colors
|
//Colors
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
background-color: rgba(35,153,153,0.5);
|
background-color: rgba(35,153,153,0.5);
|
||||||
}
|
}
|
||||||
.pageLine {
|
.pageLine {
|
||||||
background-color: rgba(255,255,255,0.75);
|
background-color: rgba(255,255,255,0.5);
|
||||||
& ~ pre.CodeMirror-line {
|
& ~ pre.CodeMirror-line {
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.df {
|
.df {
|
||||||
display : inline-block;
|
display : inline;
|
||||||
font-family : 'DiceFont';
|
font-family : 'DiceFont';
|
||||||
font-style : normal;
|
font-style : normal;
|
||||||
font-weight : normal;
|
font-weight : normal;
|
||||||
@@ -16,8 +16,11 @@
|
|||||||
text-decoration : inherit;
|
text-decoration : inherit;
|
||||||
text-transform : none;
|
text-transform : none;
|
||||||
text-rendering : optimizeLegibility;
|
text-rendering : optimizeLegibility;
|
||||||
-moz-osx-font-smoothing : grayscale;
|
|
||||||
|
/* Better Font Rendering =========== */
|
||||||
-webkit-font-smoothing : antialiased;
|
-webkit-font-smoothing : antialiased;
|
||||||
|
-moz-osx-font-smoothing : grayscale;
|
||||||
|
|
||||||
&.F::before { content : '\f190'; }
|
&.F::before { content : '\f190'; }
|
||||||
&.F-minus::before { content : '\f191'; }
|
&.F-minus::before { content : '\f191'; }
|
||||||
&.F-plus::before { content : '\f192'; }
|
&.F-plus::before { content : '\f192'; }
|
||||||
|
|||||||
@@ -7,15 +7,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ei {
|
.ei {
|
||||||
display : inline-block;
|
display : inline;
|
||||||
margin-right : 3px;
|
|
||||||
font-family : 'Elderberry-Inn';
|
font-family : 'Elderberry-Inn';
|
||||||
line-height : 1;
|
line-height : 1;
|
||||||
vertical-align : baseline;
|
vertical-align : baseline;
|
||||||
-moz-osx-font-smoothing : grayscale;
|
|
||||||
-webkit-font-smoothing : antialiased;
|
|
||||||
text-rendering : auto;
|
text-rendering : auto;
|
||||||
|
|
||||||
|
/* Better Font Rendering =========== */
|
||||||
|
-webkit-font-smoothing : antialiased;
|
||||||
|
-moz-osx-font-smoothing : grayscale;
|
||||||
|
|
||||||
&.book::before { content : '\E900'; }
|
&.book::before { content : '\E900'; }
|
||||||
&.screen::before { content : '\E901'; }
|
&.screen::before { content : '\E901'; }
|
||||||
|
|
||||||
|
|||||||
2
themes/fonts/iconFonts/fontAwesome.less
Normal file
2
themes/fonts/iconFonts/fontAwesome.less
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/* Icon Font: Font Awesome */
|
||||||
|
.far,.fas,.fab { display : inline; }
|
||||||
@@ -8,20 +8,16 @@
|
|||||||
|
|
||||||
.gi {
|
.gi {
|
||||||
/* use !important to prevent issues with browser extensions that change fonts */
|
/* use !important to prevent issues with browser extensions that change fonts */
|
||||||
display : inline-block;
|
display : inline;
|
||||||
margin-right : 3px;
|
|
||||||
font-family : 'Game-Icons' !important;
|
font-family : 'Game-Icons' !important;
|
||||||
line-height : 1;
|
line-height : 1;
|
||||||
vertical-align : baseline;
|
vertical-align : baseline;
|
||||||
-moz-osx-font-smoothing : grayscale;
|
|
||||||
-webkit-font-smoothing : antialiased;
|
|
||||||
text-rendering : auto;
|
text-rendering : auto;
|
||||||
|
|
||||||
/* Better Font Rendering =========== */
|
/* Better Font Rendering =========== */
|
||||||
-webkit-font-smoothing : antialiased;
|
-webkit-font-smoothing : antialiased;
|
||||||
-moz-osx-font-smoothing : grayscale;
|
-moz-osx-font-smoothing : grayscale;
|
||||||
|
|
||||||
|
|
||||||
&.zigzag-leaf::before { content : '\e900'; }
|
&.zigzag-leaf::before { content : '\e900'; }
|
||||||
&.zebra-shield::before { content : '\e901'; }
|
&.zebra-shield::before { content : '\e901'; }
|
||||||
&.x-mark::before { content : '\e902'; }
|
&.x-mark::before { content : '\e902'; }
|
||||||
|
|||||||
Reference in New Issue
Block a user