mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-01-24 03:23:02 +00:00
Compare commits
1 Commits
master
...
upgrade-co
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e497e42913 |
30
changelog.md
30
changelog.md
@@ -83,40 +83,12 @@ pre {
|
||||
.page .exampleTable td,th {
|
||||
border:1px dashed #00000030;
|
||||
}
|
||||
|
||||
.page .df {
|
||||
font-size: 2em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
```
|
||||
|
||||
## changelog
|
||||
For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery).
|
||||
|
||||
### Friday 1/11/2026 - v3.20.1
|
||||
|
||||
{{taskList
|
||||
##### calculuschild
|
||||
* [x] Add D100 "ball" dice icons `:d100:` :df_d100_05:
|
||||
|
||||
##### G-Ambatte
|
||||
* [x] Fix transparent edge on back cover image
|
||||
|
||||
Fixes issue [#4551](https://github.com/naturalcrit/homebrewery/issues/4551)
|
||||
|
||||
* [x] Fix "Out of sync" error when document contains extended unicode characters
|
||||
|
||||
Fixes issue [#4583](https://github.com/naturalcrit/homebrewery/issues/4583)
|
||||
|
||||
##### 5e-Cleric
|
||||
* [x] Fix page count error on Vault
|
||||
|
||||
* [x] Fix cover page footnote set to all-caps
|
||||
|
||||
Fixes issue [#4559](https://github.com/naturalcrit/homebrewery/issues/4559)
|
||||
}}
|
||||
|
||||
### Friday 11/14/2025 - v3.20.0
|
||||
### Friday 11/14/2025 - v13.20.0
|
||||
|
||||
{{taskList
|
||||
##### calculuschild
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import './admin.less';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import BrewUtils from './brewUtils/brewUtils.jsx';
|
||||
import NotificationUtils from './notificationUtils/notificationUtils.jsx';
|
||||
const BrewUtils = require('./brewUtils/brewUtils.jsx');
|
||||
const NotificationUtils = require('./notificationUtils/notificationUtils.jsx');
|
||||
import AuthorUtils from './authorUtils/authorUtils.jsx';
|
||||
import LockTools from './lockTools/lockTools.jsx';
|
||||
|
||||
|
||||
@@ -84,4 +84,4 @@ const authorLookup = ()=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default authorLookup;
|
||||
module.exports = authorLookup;
|
||||
|
||||
@@ -10,4 +10,4 @@ const authorUtils = ()=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default authorUtils;
|
||||
module.exports = authorUtils;
|
||||
@@ -1,8 +1,9 @@
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import request from 'superagent';
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
|
||||
const BrewCleanup = createReactClass({
|
||||
const request = require('superagent');
|
||||
|
||||
const BrewCleanup = createClass({
|
||||
displayName : 'BrewCleanup',
|
||||
getDefaultProps(){
|
||||
return {};
|
||||
@@ -68,4 +69,4 @@ const BrewCleanup = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default BrewCleanup;
|
||||
module.exports = BrewCleanup;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import request from 'superagent';
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const request = require('superagent');
|
||||
|
||||
const BrewCompress = createReactClass({
|
||||
const BrewCompress = createClass({
|
||||
displayName : 'BrewCompress',
|
||||
getDefaultProps(){
|
||||
return {};
|
||||
@@ -85,4 +85,4 @@ const BrewCompress = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default BrewCompress;
|
||||
module.exports = BrewCompress;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import request from 'superagent';
|
||||
import cx from 'classnames';
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const cx = require('classnames');
|
||||
|
||||
import Moment from 'moment';
|
||||
const request = require('superagent');
|
||||
const Moment = require('moment');
|
||||
|
||||
const BrewLookup = createReactClass({
|
||||
|
||||
const BrewLookup = createClass({
|
||||
getDefaultProps() {
|
||||
return {};
|
||||
},
|
||||
@@ -109,4 +110,4 @@ const BrewLookup = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default BrewLookup;
|
||||
module.exports = BrewLookup;
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import React from 'react';
|
||||
import './brewUtils.less';
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
require('./brewUtils.less');
|
||||
|
||||
import BrewCleanup from './brewCleanup/brewCleanup.jsx';
|
||||
import BrewLookup from './brewLookup/brewLookup.jsx';
|
||||
import BrewCompress from './brewCompress/brewCompress.jsx';
|
||||
import Stats from './stats/stats.jsx';
|
||||
const BrewCleanup = require('./brewCleanup/brewCleanup.jsx');
|
||||
const BrewLookup = require('./brewLookup/brewLookup.jsx');
|
||||
const BrewCompress = require ('./brewCompress/brewCompress.jsx');
|
||||
const Stats = require('./stats/stats.jsx');
|
||||
|
||||
const BrewUtils = ()=>{
|
||||
return (
|
||||
<>
|
||||
const BrewUtils = createClass({
|
||||
render : function(){
|
||||
return <>
|
||||
<Stats />
|
||||
<hr />
|
||||
<BrewLookup />
|
||||
@@ -16,7 +17,8 @@ const BrewUtils = ()=>{
|
||||
<BrewCleanup />
|
||||
<hr />
|
||||
<BrewCompress />
|
||||
</>
|
||||
);
|
||||
};
|
||||
export default BrewUtils;
|
||||
</>;
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = BrewUtils;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import request from 'superagent';
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
|
||||
const Stats = createReactClass({
|
||||
const request = require('superagent');
|
||||
|
||||
const Stats = createClass({
|
||||
displayName : 'Stats',
|
||||
getDefaultProps(){
|
||||
return {};
|
||||
@@ -42,4 +43,4 @@ const Stats = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default Stats;
|
||||
module.exports = Stats;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*eslint max-lines: ["warn", {"max": 500, "skipBlankLines": true, "skipComments": true}]*/
|
||||
import './lockTools.less';
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
require('./lockTools.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
|
||||
import request from '../../homebrew/utils/request-middleware.js';
|
||||
|
||||
const LockTools = createReactClass({
|
||||
const LockTools = createClass({
|
||||
displayName : 'LockTools',
|
||||
getInitialState : function() {
|
||||
return {
|
||||
@@ -55,7 +55,7 @@ const LockTools = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
const LockBrew = createReactClass({
|
||||
const LockBrew = createClass({
|
||||
displayName : 'LockBrew',
|
||||
getInitialState : function() {
|
||||
// Default values
|
||||
@@ -183,7 +183,7 @@ const LockBrew = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
const LockTable = createReactClass({
|
||||
const LockTable = createClass({
|
||||
displayName : 'LockTable',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
@@ -273,7 +273,7 @@ const LockTable = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
const LockLookup = createReactClass({
|
||||
const LockLookup = createClass({
|
||||
displayName : 'LockLookup',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
@@ -339,4 +339,4 @@ const LockLookup = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default LockTools;
|
||||
module.exports = LockTools;
|
||||
@@ -1,6 +1,7 @@
|
||||
import './notificationAdd.less';
|
||||
import React, { useState, useRef } from 'react';
|
||||
import request from 'superagent';
|
||||
require('./notificationAdd.less');
|
||||
const React = require('react');
|
||||
const { useState, useRef } = require('react');
|
||||
const request = require('superagent');
|
||||
|
||||
const NotificationAdd = ()=>{
|
||||
const [notificationResult, setNotificationResult] = useState(null);
|
||||
@@ -105,4 +106,4 @@ const NotificationAdd = ()=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default NotificationAdd;
|
||||
module.exports = NotificationAdd;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import './notificationLookup.less';
|
||||
import React, { useState } from 'react';
|
||||
import request from 'superagent';
|
||||
import Moment from 'moment';
|
||||
require('./notificationLookup.less');
|
||||
|
||||
const React = require('react');
|
||||
const { useState } = require('react');
|
||||
const request = require('superagent');
|
||||
const Moment = require('moment');
|
||||
|
||||
const NotificationDetail = ({ notification, onDelete })=>(
|
||||
<>
|
||||
@@ -100,4 +102,4 @@ const NotificationLookup = ()=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default NotificationLookup;
|
||||
module.exports = NotificationLookup;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import NotificationLookup from './notificationLookup/notificationLookup.jsx';
|
||||
import NotificationAdd from './notificationAdd/notificationAdd.jsx';
|
||||
const React = require('react');
|
||||
|
||||
const NotificationLookup = require('./notificationLookup/notificationLookup.jsx');
|
||||
const NotificationAdd = require('./notificationAdd/notificationAdd.jsx');
|
||||
|
||||
const NotificationUtils = ()=>{
|
||||
return (
|
||||
@@ -11,4 +12,4 @@ const NotificationUtils = ()=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default NotificationUtils;
|
||||
module.exports = NotificationUtils;
|
||||
|
||||
@@ -79,6 +79,6 @@ const showAutocompleteEmoji = function(CodeMirror, editor) {
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
showAutocompleteEmoji
|
||||
};
|
||||
@@ -38,11 +38,11 @@ const autoCloseCurlyBraces = function(CodeMirror, cm, typingClosingBrace) {
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
autoCloseCurlyBraces : function(CodeMirror, codeMirror) {
|
||||
const map = { name: 'autoCloseCurlyBraces' };
|
||||
map[`'{'`] = function(cm) { return autoCloseCurlyBraces(CodeMirror, cm); };
|
||||
map[`'}'`] = function(cm) { return autoCloseCurlyBraces(CodeMirror, cm, true); };
|
||||
codeMirror?.addKeyMap(map);
|
||||
codeMirror.addKeyMap(map);
|
||||
}
|
||||
};
|
||||
@@ -1,13 +1,51 @@
|
||||
/* eslint-disable max-lines */
|
||||
import './codeEditor.less';
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import _ from 'lodash';
|
||||
import closeTag from './close-tag';
|
||||
import autoCompleteEmoji from './autocompleteEmoji';
|
||||
let CodeMirror;
|
||||
require('./codeEditor.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
const closeTag = require('./close-tag');
|
||||
const autoCompleteEmoji = require('./autocompleteEmoji');
|
||||
|
||||
const CodeEditor = createReactClass({
|
||||
let CodeMirror;
|
||||
if(typeof window !== 'undefined'){
|
||||
CodeMirror = require('codemirror5');
|
||||
|
||||
//Language Modes
|
||||
require('codemirror5/mode/gfm/gfm.js'); //Github flavoured markdown
|
||||
require('codemirror5/mode/css/css.js');
|
||||
require('codemirror5/mode/javascript/javascript.js');
|
||||
|
||||
//Addons
|
||||
//Code folding
|
||||
require('codemirror5/addon/fold/foldcode.js');
|
||||
require('codemirror5/addon/fold/foldgutter.js');
|
||||
//Search and replace
|
||||
require('codemirror5/addon/search/search.js');
|
||||
require('codemirror5/addon/search/searchcursor.js');
|
||||
require('codemirror5/addon/search/jump-to-line.js');
|
||||
require('codemirror5/addon/search/match-highlighter.js');
|
||||
require('codemirror5/addon/search/matchesonscrollbar.js');
|
||||
require('codemirror5/addon/dialog/dialog.js');
|
||||
//Trailing space highlighting
|
||||
// require('codemirror/addon/edit/trailingspace.js');
|
||||
//Active line highlighting
|
||||
// require('codemirror/addon/selection/active-line.js');
|
||||
//Scroll past last line
|
||||
require('codemirror5/addon/scroll/scrollpastend.js');
|
||||
//Auto-closing
|
||||
//XML code folding is a requirement of the auto-closing tag feature and is not enabled
|
||||
require('codemirror5/addon/fold/xml-fold.js');
|
||||
require('codemirror5/addon/edit/closetag.js');
|
||||
//Autocompletion
|
||||
require('codemirror5/addon/hint/show-hint.js');
|
||||
|
||||
const foldPagesCode = require('./fold-pages');
|
||||
foldPagesCode.registerHomebreweryHelper(CodeMirror);
|
||||
const foldCSSCode = require('./fold-css');
|
||||
foldCSSCode.registerHomebreweryHelper(CodeMirror);
|
||||
}
|
||||
|
||||
const CodeEditor = createClass({
|
||||
displayName : 'CodeEditor',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
@@ -28,54 +66,23 @@ const CodeEditor = createReactClass({
|
||||
|
||||
editor : React.createRef(null),
|
||||
|
||||
async componentDidMount() {
|
||||
CodeMirror = (await import('codemirror')).default;
|
||||
this.CodeMirror = CodeMirror;
|
||||
|
||||
await import('codemirror/mode/gfm/gfm.js');
|
||||
await import('codemirror/mode/css/css.js');
|
||||
await import('codemirror/mode/javascript/javascript.js');
|
||||
|
||||
// addons
|
||||
await import('codemirror/addon/fold/foldcode.js');
|
||||
await import('codemirror/addon/fold/foldgutter.js');
|
||||
await import('codemirror/addon/fold/xml-fold.js');
|
||||
await import('codemirror/addon/search/search.js');
|
||||
await import('codemirror/addon/search/searchcursor.js');
|
||||
await import('codemirror/addon/search/jump-to-line.js');
|
||||
await import('codemirror/addon/search/match-highlighter.js');
|
||||
await import('codemirror/addon/search/matchesonscrollbar.js');
|
||||
await import('codemirror/addon/dialog/dialog.js');
|
||||
await import('codemirror/addon/scroll/scrollpastend.js');
|
||||
await import('codemirror/addon/edit/closetag.js');
|
||||
await import('codemirror/addon/hint/show-hint.js');
|
||||
// import 'codemirror/addon/selection/active-line.js';
|
||||
// import 'codemirror/addon/edit/trailingspace.js';
|
||||
|
||||
|
||||
// register helpers dynamically as well
|
||||
const foldPagesCode = (await import('./fold-pages')).default;
|
||||
const foldCSSCode = (await import('./fold-css')).default;
|
||||
foldPagesCode.registerHomebreweryHelper(CodeMirror);
|
||||
foldCSSCode.registerHomebreweryHelper(CodeMirror);
|
||||
|
||||
componentDidMount : function() {
|
||||
this.buildEditor();
|
||||
const newDoc = CodeMirror?.Doc(this.props.value, this.props.language);
|
||||
this.codeMirror?.swapDoc(newDoc);
|
||||
const newDoc = CodeMirror.Doc(this.props.value, this.props.language);
|
||||
this.codeMirror.swapDoc(newDoc);
|
||||
},
|
||||
|
||||
|
||||
componentDidUpdate : function(prevProps) {
|
||||
if(prevProps.view !== this.props.view){ //view changed; swap documents
|
||||
let newDoc;
|
||||
|
||||
if(!this.state.docs[this.props.view]) {
|
||||
newDoc = CodeMirror?.Doc(this.props.value, this.props.language);
|
||||
newDoc = CodeMirror.Doc(this.props.value, this.props.language);
|
||||
} else {
|
||||
newDoc = this.state.docs[this.props.view];
|
||||
}
|
||||
|
||||
const oldDoc = { [prevProps.view]: this.codeMirror?.swapDoc(newDoc) };
|
||||
const oldDoc = { [prevProps.view]: this.codeMirror.swapDoc(newDoc) };
|
||||
|
||||
this.setState((prevState)=>({
|
||||
docs : _.merge({}, prevState.docs, oldDoc)
|
||||
@@ -83,17 +90,17 @@ const CodeEditor = createReactClass({
|
||||
|
||||
this.props.rerenderParent();
|
||||
} else if(this.codeMirror?.getValue() != this.props.value) { //update editor contents if brew.text is changed from outside
|
||||
this.codeMirror?.setValue(this.props.value);
|
||||
this.codeMirror.setValue(this.props.value);
|
||||
}
|
||||
|
||||
if(this.props.enableFolding) {
|
||||
this.codeMirror?.setOption('foldOptions', this.foldOptions(this.codeMirror));
|
||||
this.codeMirror.setOption('foldOptions', this.foldOptions(this.codeMirror));
|
||||
} else {
|
||||
this.codeMirror?.setOption('foldOptions', false);
|
||||
this.codeMirror.setOption('foldOptions', false);
|
||||
}
|
||||
|
||||
if(prevProps.editorTheme !== this.props.editorTheme){
|
||||
this.codeMirror?.setOption('theme', this.props.editorTheme);
|
||||
this.codeMirror.setOption('theme', this.props.editorTheme);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -181,8 +188,8 @@ const CodeEditor = createReactClass({
|
||||
closeTag.autoCloseCurlyBraces(CodeMirror, this.codeMirror);
|
||||
autoCompleteEmoji.showAutocompleteEmoji(CodeMirror, this.codeMirror);
|
||||
|
||||
// Note: codeMirror passes a copy of itself in this callback. cm === this.codeMirror?. Either one works.
|
||||
this.codeMirror?.on('change', (cm)=>{this.props.onChange(cm.getValue());});
|
||||
// Note: codeMirror passes a copy of itself in this callback. cm === this.codeMirror. Either one works.
|
||||
this.codeMirror.on('change', (cm)=>{this.props.onChange(cm.getValue());});
|
||||
this.updateSize();
|
||||
},
|
||||
|
||||
@@ -196,84 +203,84 @@ const CodeEditor = createReactClass({
|
||||
},
|
||||
|
||||
dedent : function () {
|
||||
this.codeMirror?.execCommand('indentLess');
|
||||
this.codeMirror.execCommand('indentLess');
|
||||
},
|
||||
|
||||
makeHeader : function (number) {
|
||||
const selection = this.codeMirror?.getSelection();
|
||||
const selection = this.codeMirror.getSelection();
|
||||
const header = Array(number).fill('#').join('');
|
||||
this.codeMirror?.replaceSelection(`${header} ${selection}`, 'around');
|
||||
const cursor = this.codeMirror?.getCursor();
|
||||
this.codeMirror?.setCursor({ line: cursor.line, ch: cursor.ch + selection.length + number + 1 });
|
||||
this.codeMirror.replaceSelection(`${header} ${selection}`, 'around');
|
||||
const cursor = this.codeMirror.getCursor();
|
||||
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch + selection.length + number + 1 });
|
||||
},
|
||||
|
||||
makeBold : function() {
|
||||
const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 2) === '**' && selection.slice(-2) === '**';
|
||||
this.codeMirror?.replaceSelection(t ? selection.slice(2, -2) : `**${selection}**`, 'around');
|
||||
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '**' && selection.slice(-2) === '**';
|
||||
this.codeMirror.replaceSelection(t ? selection.slice(2, -2) : `**${selection}**`, 'around');
|
||||
if(selection.length === 0){
|
||||
const cursor = this.codeMirror?.getCursor();
|
||||
this.codeMirror?.setCursor({ line: cursor.line, ch: cursor.ch - 2 });
|
||||
const cursor = this.codeMirror.getCursor();
|
||||
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - 2 });
|
||||
}
|
||||
},
|
||||
|
||||
makeItalic : function() {
|
||||
const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 1) === '*' && selection.slice(-1) === '*';
|
||||
this.codeMirror?.replaceSelection(t ? selection.slice(1, -1) : `*${selection}*`, 'around');
|
||||
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 1) === '*' && selection.slice(-1) === '*';
|
||||
this.codeMirror.replaceSelection(t ? selection.slice(1, -1) : `*${selection}*`, 'around');
|
||||
if(selection.length === 0){
|
||||
const cursor = this.codeMirror?.getCursor();
|
||||
this.codeMirror?.setCursor({ line: cursor.line, ch: cursor.ch - 1 });
|
||||
const cursor = this.codeMirror.getCursor();
|
||||
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - 1 });
|
||||
}
|
||||
},
|
||||
|
||||
makeSuper : function() {
|
||||
const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 1) === '^' && selection.slice(-1) === '^';
|
||||
this.codeMirror?.replaceSelection(t ? selection.slice(1, -1) : `^${selection}^`, 'around');
|
||||
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 1) === '^' && selection.slice(-1) === '^';
|
||||
this.codeMirror.replaceSelection(t ? selection.slice(1, -1) : `^${selection}^`, 'around');
|
||||
if(selection.length === 0){
|
||||
const cursor = this.codeMirror?.getCursor();
|
||||
this.codeMirror?.setCursor({ line: cursor.line, ch: cursor.ch - 1 });
|
||||
const cursor = this.codeMirror.getCursor();
|
||||
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - 1 });
|
||||
}
|
||||
},
|
||||
|
||||
makeSub : function() {
|
||||
const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 2) === '^^' && selection.slice(-2) === '^^';
|
||||
this.codeMirror?.replaceSelection(t ? selection.slice(2, -2) : `^^${selection}^^`, 'around');
|
||||
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '^^' && selection.slice(-2) === '^^';
|
||||
this.codeMirror.replaceSelection(t ? selection.slice(2, -2) : `^^${selection}^^`, 'around');
|
||||
if(selection.length === 0){
|
||||
const cursor = this.codeMirror?.getCursor();
|
||||
this.codeMirror?.setCursor({ line: cursor.line, ch: cursor.ch - 2 });
|
||||
const cursor = this.codeMirror.getCursor();
|
||||
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - 2 });
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
makeNbsp : function() {
|
||||
this.codeMirror?.replaceSelection(' ', 'end');
|
||||
this.codeMirror.replaceSelection(' ', 'end');
|
||||
},
|
||||
|
||||
makeSpace : function() {
|
||||
const selection = this.codeMirror?.getSelection();
|
||||
const selection = this.codeMirror.getSelection();
|
||||
const t = selection.slice(0, 8) === '{{width:' && selection.slice(0 -4) === '% }}';
|
||||
if(t){
|
||||
const percent = parseInt(selection.slice(8, -4)) + 10;
|
||||
this.codeMirror?.replaceSelection(percent < 90 ? `{{width:${percent}% }}` : '{{width:100% }}', 'around');
|
||||
this.codeMirror.replaceSelection(percent < 90 ? `{{width:${percent}% }}` : '{{width:100% }}', 'around');
|
||||
} else {
|
||||
this.codeMirror?.replaceSelection(`{{width:10% }}`, 'around');
|
||||
this.codeMirror.replaceSelection(`{{width:10% }}`, 'around');
|
||||
}
|
||||
},
|
||||
|
||||
removeSpace : function() {
|
||||
const selection = this.codeMirror?.getSelection();
|
||||
const selection = this.codeMirror.getSelection();
|
||||
const t = selection.slice(0, 8) === '{{width:' && selection.slice(0 -4) === '% }}';
|
||||
if(t){
|
||||
const percent = parseInt(selection.slice(8, -4)) - 10;
|
||||
this.codeMirror?.replaceSelection(percent > 10 ? `{{width:${percent}% }}` : '', 'around');
|
||||
this.codeMirror.replaceSelection(percent > 10 ? `{{width:${percent}% }}` : '', 'around');
|
||||
}
|
||||
},
|
||||
|
||||
newColumn : function() {
|
||||
this.codeMirror?.replaceSelection('\n\\column\n\n', 'end');
|
||||
this.codeMirror.replaceSelection('\n\\column\n\n', 'end');
|
||||
},
|
||||
|
||||
newPage : function() {
|
||||
this.codeMirror?.replaceSelection('\n\\page\n\n', 'end');
|
||||
this.codeMirror.replaceSelection('\n\\page\n\n', 'end');
|
||||
},
|
||||
|
||||
injectText : function(injectText, overwrite=true) {
|
||||
@@ -286,29 +293,29 @@ const CodeEditor = createReactClass({
|
||||
},
|
||||
|
||||
makeUnderline : function() {
|
||||
const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 3) === '<u>' && selection.slice(-4) === '</u>';
|
||||
this.codeMirror?.replaceSelection(t ? selection.slice(3, -4) : `<u>${selection}</u>`, 'around');
|
||||
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 3) === '<u>' && selection.slice(-4) === '</u>';
|
||||
this.codeMirror.replaceSelection(t ? selection.slice(3, -4) : `<u>${selection}</u>`, 'around');
|
||||
if(selection.length === 0){
|
||||
const cursor = this.codeMirror?.getCursor();
|
||||
this.codeMirror?.setCursor({ line: cursor.line, ch: cursor.ch - 4 });
|
||||
const cursor = this.codeMirror.getCursor();
|
||||
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - 4 });
|
||||
}
|
||||
},
|
||||
|
||||
makeSpan : function() {
|
||||
const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 2) === '{{' && selection.slice(-2) === '}}';
|
||||
this.codeMirror?.replaceSelection(t ? selection.slice(2, -2) : `{{ ${selection}}}`, 'around');
|
||||
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '{{' && selection.slice(-2) === '}}';
|
||||
this.codeMirror.replaceSelection(t ? selection.slice(2, -2) : `{{ ${selection}}}`, 'around');
|
||||
if(selection.length === 0){
|
||||
const cursor = this.codeMirror?.getCursor();
|
||||
this.codeMirror?.setCursor({ line: cursor.line, ch: cursor.ch - 2 });
|
||||
const cursor = this.codeMirror.getCursor();
|
||||
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - 2 });
|
||||
}
|
||||
},
|
||||
|
||||
makeDiv : function() {
|
||||
const selection = this.codeMirror?.getSelection(), t = selection.slice(0, 2) === '{{' && selection.slice(-2) === '}}';
|
||||
this.codeMirror?.replaceSelection(t ? selection.slice(2, -2) : `{{\n${selection}\n}}`, 'around');
|
||||
const selection = this.codeMirror.getSelection(), t = selection.slice(0, 2) === '{{' && selection.slice(-2) === '}}';
|
||||
this.codeMirror.replaceSelection(t ? selection.slice(2, -2) : `{{\n${selection}\n}}`, 'around');
|
||||
if(selection.length === 0){
|
||||
const cursor = this.codeMirror?.getCursor();
|
||||
this.codeMirror?.setCursor({ line: cursor.line - 1, ch: cursor.ch }); // set to -2? if wanting to enter classes etc. if so, get rid of first \n when replacing selection
|
||||
const cursor = this.codeMirror.getCursor();
|
||||
this.codeMirror.setCursor({ line: cursor.line - 1, ch: cursor.ch }); // set to -2? if wanting to enter classes etc. if so, get rid of first \n when replacing selection
|
||||
}
|
||||
},
|
||||
|
||||
@@ -316,7 +323,7 @@ const CodeEditor = createReactClass({
|
||||
let regex;
|
||||
let cursorPos;
|
||||
let newComment;
|
||||
const selection = this.codeMirror?.getSelection();
|
||||
const selection = this.codeMirror.getSelection();
|
||||
if(this.props.language === 'gfm'){
|
||||
regex = /^\s*(<!--\s?)(.*?)(\s?-->)\s*$/gs;
|
||||
cursorPos = 4;
|
||||
@@ -326,44 +333,44 @@ const CodeEditor = createReactClass({
|
||||
cursorPos = 3;
|
||||
newComment = `/* ${selection} */`;
|
||||
}
|
||||
this.codeMirror?.replaceSelection(regex.test(selection) == true ? selection.replace(regex, '$2') : newComment, 'around');
|
||||
this.codeMirror.replaceSelection(regex.test(selection) == true ? selection.replace(regex, '$2') : newComment, 'around');
|
||||
if(selection.length === 0){
|
||||
const cursor = this.codeMirror?.getCursor();
|
||||
this.codeMirror?.setCursor({ line: cursor.line, ch: cursor.ch - cursorPos });
|
||||
const cursor = this.codeMirror.getCursor();
|
||||
this.codeMirror.setCursor({ line: cursor.line, ch: cursor.ch - cursorPos });
|
||||
};
|
||||
},
|
||||
|
||||
makeLink : function() {
|
||||
const isLink = /^\[(.*)\]\((.*)\)$/;
|
||||
const selection = this.codeMirror?.getSelection().trim();
|
||||
const selection = this.codeMirror.getSelection().trim();
|
||||
let match;
|
||||
if(match = isLink.exec(selection)){
|
||||
const altText = match[1];
|
||||
const url = match[2];
|
||||
this.codeMirror?.replaceSelection(`${altText} ${url}`);
|
||||
const cursor = this.codeMirror?.getCursor();
|
||||
this.codeMirror?.setSelection({ line: cursor.line, ch: cursor.ch - url.length }, { line: cursor.line, ch: cursor.ch });
|
||||
this.codeMirror.replaceSelection(`${altText} ${url}`);
|
||||
const cursor = this.codeMirror.getCursor();
|
||||
this.codeMirror.setSelection({ line: cursor.line, ch: cursor.ch - url.length }, { line: cursor.line, ch: cursor.ch });
|
||||
} else {
|
||||
this.codeMirror?.replaceSelection(`[${selection || 'alt text'}](url)`);
|
||||
const cursor = this.codeMirror?.getCursor();
|
||||
this.codeMirror?.setSelection({ line: cursor.line, ch: cursor.ch - 4 }, { line: cursor.line, ch: cursor.ch - 1 });
|
||||
this.codeMirror.replaceSelection(`[${selection || 'alt text'}](url)`);
|
||||
const cursor = this.codeMirror.getCursor();
|
||||
this.codeMirror.setSelection({ line: cursor.line, ch: cursor.ch - 4 }, { line: cursor.line, ch: cursor.ch - 1 });
|
||||
}
|
||||
},
|
||||
|
||||
makeList : function(listType) {
|
||||
const selectionStart = this.codeMirror?.getCursor('from'), selectionEnd = this.codeMirror?.getCursor('to');
|
||||
this.codeMirror?.setSelection(
|
||||
const selectionStart = this.codeMirror.getCursor('from'), selectionEnd = this.codeMirror.getCursor('to');
|
||||
this.codeMirror.setSelection(
|
||||
{ line: selectionStart.line, ch: 0 },
|
||||
{ line: selectionEnd.line, ch: this.codeMirror?.getLine(selectionEnd.line).length }
|
||||
{ line: selectionEnd.line, ch: this.codeMirror.getLine(selectionEnd.line).length }
|
||||
);
|
||||
const newSelection = this.codeMirror?.getSelection();
|
||||
const newSelection = this.codeMirror.getSelection();
|
||||
|
||||
const regex = /^\d+\.\s|^-\s/gm;
|
||||
if(newSelection.match(regex) != null){ // if selection IS A LIST
|
||||
this.codeMirror?.replaceSelection(newSelection.replace(regex, ''), 'around');
|
||||
this.codeMirror.replaceSelection(newSelection.replace(regex, ''), 'around');
|
||||
} else { // if selection IS NOT A LIST
|
||||
listType == 'UL' ? this.codeMirror?.replaceSelection(newSelection.replace(/^/gm, `- `), 'around') :
|
||||
this.codeMirror?.replaceSelection(newSelection.replace(/^/gm, (()=>{
|
||||
listType == 'UL' ? this.codeMirror.replaceSelection(newSelection.replace(/^/gm, `- `), 'around') :
|
||||
this.codeMirror.replaceSelection(newSelection.replace(/^/gm, (()=>{
|
||||
let n = 1;
|
||||
return ()=>{
|
||||
return `${n++}. `;
|
||||
@@ -373,39 +380,39 @@ const CodeEditor = createReactClass({
|
||||
},
|
||||
|
||||
foldAllCode : function() {
|
||||
this.codeMirror?.execCommand('foldAll');
|
||||
this.codeMirror.execCommand('foldAll');
|
||||
},
|
||||
|
||||
unfoldAllCode : function() {
|
||||
this.codeMirror?.execCommand('unfoldAll');
|
||||
this.codeMirror.execCommand('unfoldAll');
|
||||
},
|
||||
|
||||
//=-- Externally used -==//
|
||||
setCursorPosition : function(line, char){
|
||||
setTimeout(()=>{
|
||||
this.codeMirror?.focus();
|
||||
this.codeMirror?.doc.setCursor(line, char);
|
||||
this.codeMirror.focus();
|
||||
this.codeMirror.doc.setCursor(line, char);
|
||||
}, 10);
|
||||
},
|
||||
getCursorPosition : function(){
|
||||
return this.codeMirror?.getCursor();
|
||||
return this.codeMirror.getCursor();
|
||||
},
|
||||
getTopVisibleLine : function(){
|
||||
const rect = this.codeMirror?.getWrapperElement().getBoundingClientRect();
|
||||
const topVisibleLine = this.codeMirror?.lineAtHeight(rect.top, 'window');
|
||||
const rect = this.codeMirror.getWrapperElement().getBoundingClientRect();
|
||||
const topVisibleLine = this.codeMirror.lineAtHeight(rect.top, 'window');
|
||||
return topVisibleLine;
|
||||
},
|
||||
updateSize : function(){
|
||||
this.codeMirror?.refresh();
|
||||
this.codeMirror.refresh();
|
||||
},
|
||||
redo : function(){
|
||||
return this.codeMirror?.redo();
|
||||
return this.codeMirror.redo();
|
||||
},
|
||||
undo : function(){
|
||||
return this.codeMirror?.undo();
|
||||
return this.codeMirror.undo();
|
||||
},
|
||||
historySize : function(){
|
||||
return this.codeMirror?.doc.historySize();
|
||||
return this.codeMirror.doc.historySize();
|
||||
},
|
||||
|
||||
foldOptions : function(cm){
|
||||
@@ -419,7 +426,7 @@ const CodeEditor = createReactClass({
|
||||
|
||||
let foldPreviewText = '';
|
||||
while (currentLine <= to.line && text.length <= maxLength) {
|
||||
const currentText = this.codeMirror?.getLine(currentLine);
|
||||
const currentText = this.codeMirror.getLine(currentLine);
|
||||
currentLine++;
|
||||
if(currentText[0] == '#'){
|
||||
foldPreviewText = currentText;
|
||||
@@ -454,5 +461,4 @@ const CodeEditor = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default CodeEditor;
|
||||
|
||||
module.exports = CodeEditor;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
@import (less) 'codemirror/lib/codemirror.css';
|
||||
@import (less) 'codemirror/addon/fold/foldgutter.css';
|
||||
@import (less) 'codemirror/addon/search/matchesonscrollbar.css';
|
||||
@import (less) 'codemirror/addon/dialog/dialog.css';
|
||||
@import (less) 'codemirror/addon/hint/show-hint.css';
|
||||
@import (less) 'codemirror5/lib/codemirror.css';
|
||||
@import (less) 'codemirror5/addon/fold/foldgutter.css';
|
||||
@import (less) 'codemirror5/addon/search/matchesonscrollbar.css';
|
||||
@import (less) 'codemirror5/addon/dialog/dialog.css';
|
||||
@import (less) 'codemirror5/addon/hint/show-hint.css';
|
||||
|
||||
//Icon fonts included so they can appear in emoji autosuggest dropdown
|
||||
@import (less) './themes/fonts/iconFonts/diceFont.less';
|
||||
@@ -57,4 +57,4 @@
|
||||
.emojiPreview {
|
||||
font-size : 1.5em;
|
||||
line-height : 1.2em;
|
||||
}
|
||||
}
|
||||
|
||||
191
client/components/codeEditor/codeEditorV6.jsx
Normal file
191
client/components/codeEditor/codeEditorV6.jsx
Normal file
@@ -0,0 +1,191 @@
|
||||
import './codeEditor.less';
|
||||
import React, { useEffect, useImperativeHandle, useMemo, useRef } from 'react';
|
||||
import { Compartment, EditorSelection, EditorState } from '@codemirror/state';
|
||||
import { EditorView, keymap, highlightActiveLine, lineNumbers, highlightActiveLineGutter } from '@codemirror/view';
|
||||
import { history, historyKeymap, undo as historyUndo, redo as historyRedo, undoDepth, redoDepth } from '@codemirror/history';
|
||||
import { defaultKeymap, indentWithTab } from '@codemirror/commands';
|
||||
import { searchKeymap, highlightSelectionMatches } from '@codemirror/search';
|
||||
import { closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete';
|
||||
import { defaultHighlightStyle } from '@codemirror/language';
|
||||
import { syntaxHighlighting } from '@codemirror/language';
|
||||
import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
|
||||
import { languages } from '@codemirror/language-data';
|
||||
import { javascript } from '@codemirror/lang-javascript';
|
||||
import { css } from '@codemirror/lang-css';
|
||||
|
||||
const baseExtensions = [
|
||||
lineNumbers(),
|
||||
highlightActiveLineGutter(),
|
||||
EditorView.lineWrapping,
|
||||
history(),
|
||||
keymap.of([
|
||||
indentWithTab,
|
||||
...closeBracketsKeymap,
|
||||
...searchKeymap,
|
||||
...historyKeymap,
|
||||
...defaultKeymap
|
||||
]),
|
||||
closeBrackets(),
|
||||
highlightSelectionMatches(),
|
||||
highlightActiveLine(),
|
||||
syntaxHighlighting(defaultHighlightStyle, { fallback: true })
|
||||
];
|
||||
|
||||
const languageExtension = (language)=>{
|
||||
switch(language){
|
||||
case 'css':
|
||||
return css();
|
||||
case 'javascript':
|
||||
return javascript({ jsx: true, typescript: true });
|
||||
case 'gfm':
|
||||
default:
|
||||
return markdown({ base: markdownLanguage, codeLanguages: languages });
|
||||
}
|
||||
};
|
||||
|
||||
const CodeEditorV6 = React.forwardRef(({
|
||||
value = '',
|
||||
onChange = ()=>{},
|
||||
language = 'gfm',
|
||||
readOnly = false,
|
||||
style = {},
|
||||
editorTheme,
|
||||
onSelectionChange = ()=>{},
|
||||
onScroll = ()=>{}
|
||||
}, ref)=>{
|
||||
const containerRef = useRef(null);
|
||||
const viewRef = useRef(null);
|
||||
const languageCompartment = useMemo(()=>new Compartment(), []);
|
||||
const readOnlyCompartment = useMemo(()=>new Compartment(), []);
|
||||
|
||||
useImperativeHandle(ref, ()=>({
|
||||
focus : ()=>viewRef.current?.focus(),
|
||||
getView : ()=>viewRef.current,
|
||||
getCM6View : ()=>viewRef.current,
|
||||
getCursorPosition : ()=>{
|
||||
const view = viewRef.current;
|
||||
if(!view) return { line: 0, ch: 0 };
|
||||
const { head } = view.state.selection.main;
|
||||
const lineInfo = view.state.doc.lineAt(head);
|
||||
return { line: lineInfo.number - 1, ch: head - lineInfo.from };
|
||||
},
|
||||
setCursorPosition : ({ line = 0, ch = 0 })=>{
|
||||
const view = viewRef.current;
|
||||
if(!view) return;
|
||||
const docLine = view.state.doc.line(Math.max(1, line + 1));
|
||||
const pos = Math.min(docLine.from + ch, docLine.to);
|
||||
view.dispatch({ selection: EditorSelection.cursor(pos), scrollIntoView: true });
|
||||
},
|
||||
getTopVisibleLine : ()=>{
|
||||
const view = viewRef.current;
|
||||
if(!view) return 0;
|
||||
const top = view.scrollDOM.scrollTop;
|
||||
const block = view.lineBlockAtHeight(top);
|
||||
const lineInfo = view.state.doc.lineAt(block.from);
|
||||
return lineInfo.number - 1;
|
||||
},
|
||||
updateSize : ()=>viewRef.current?.requestMeasure(),
|
||||
injectText : (text, overwrite=true)=>{
|
||||
const view = viewRef.current;
|
||||
if(!view) return;
|
||||
const { from, to } = view.state.selection.main;
|
||||
const insertFrom = overwrite ? from : from;
|
||||
const insertTo = overwrite ? to : from;
|
||||
view.dispatch({
|
||||
changes : { from: insertFrom, to: insertTo, insert: text },
|
||||
selection : EditorSelection.cursor(insertFrom + text.length),
|
||||
scrollIntoView : true
|
||||
});
|
||||
view.focus();
|
||||
},
|
||||
undo : ()=>{
|
||||
const view = viewRef.current;
|
||||
if(!view) return;
|
||||
historyUndo(view);
|
||||
},
|
||||
redo : ()=>{
|
||||
const view = viewRef.current;
|
||||
if(!view) return;
|
||||
historyRedo(view);
|
||||
},
|
||||
historySize : ()=>{
|
||||
const view = viewRef.current;
|
||||
if(!view) return { undo: 0, redo: 0 };
|
||||
return {
|
||||
undo : undoDepth(view.state),
|
||||
redo : redoDepth(view.state)
|
||||
};
|
||||
},
|
||||
foldAllCode : ()=>{},
|
||||
unfoldAllCode : ()=>{}
|
||||
}), []);
|
||||
|
||||
useEffect(()=>{
|
||||
if(!containerRef.current) return;
|
||||
|
||||
const initialExtensions = [
|
||||
...baseExtensions,
|
||||
languageCompartment.of(languageExtension(language)),
|
||||
readOnlyCompartment.of(EditorState.readOnly.of(readOnly)),
|
||||
EditorView.updateListener.of((update)=>{
|
||||
if(update.docChanged) onChange(update.state.doc.toString());
|
||||
if(update.selectionSet) onSelectionChange(update.view);
|
||||
})
|
||||
];
|
||||
|
||||
const state = EditorState.create({
|
||||
doc : value,
|
||||
extensions : initialExtensions
|
||||
});
|
||||
|
||||
const view = new EditorView({
|
||||
state,
|
||||
parent : containerRef.current
|
||||
});
|
||||
viewRef.current = view;
|
||||
|
||||
const handleScroll = ()=>onScroll(view);
|
||||
view.scrollDOM.addEventListener('scroll', handleScroll);
|
||||
|
||||
return ()=>{
|
||||
view.scrollDOM.removeEventListener('scroll', handleScroll);
|
||||
view.destroy();
|
||||
viewRef.current = null;
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(()=>{
|
||||
const view = viewRef.current;
|
||||
if(!view) return;
|
||||
view.dispatch({
|
||||
effects : languageCompartment.reconfigure(languageExtension(language))
|
||||
});
|
||||
}, [language, languageCompartment]);
|
||||
|
||||
useEffect(()=>{
|
||||
const view = viewRef.current;
|
||||
if(!view) return;
|
||||
view.dispatch({
|
||||
effects : readOnlyCompartment.reconfigure(EditorState.readOnly.of(readOnly))
|
||||
});
|
||||
}, [readOnly, readOnlyCompartment]);
|
||||
|
||||
useEffect(()=>{
|
||||
const view = viewRef.current;
|
||||
if(!view) return;
|
||||
const currentValue = view.state.doc.toString();
|
||||
if(value === currentValue) return;
|
||||
const transaction = view.state.update({
|
||||
changes : { from: 0, to: currentValue.length, insert: value }
|
||||
});
|
||||
view.dispatch(transaction);
|
||||
}, [value]);
|
||||
|
||||
return (
|
||||
<div className='codeEditor' ref={containerRef} style={style} data-editor='cm6'></div>
|
||||
);
|
||||
});
|
||||
|
||||
CodeEditorV6.displayName = 'CodeEditorV6';
|
||||
|
||||
export default CodeEditorV6;
|
||||
@@ -1,4 +1,4 @@
|
||||
export default {
|
||||
module.exports = {
|
||||
registerHomebreweryHelper : function(CodeMirror) {
|
||||
CodeMirror.registerHelper('fold', 'homebrewerycss', function(cm, start) {
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export default {
|
||||
module.exports = {
|
||||
registerHomebreweryHelper : function(CodeMirror) {
|
||||
CodeMirror.registerHelper('fold', 'homebrewery', function(cm, start) {
|
||||
const matcher = /^\\page.*/;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import _ from 'lodash';
|
||||
import './combobox.less';
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
require('./combobox.less');
|
||||
|
||||
const Combobox = createReactClass({
|
||||
const Combobox = createClass({
|
||||
displayName : 'Combobox',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
@@ -126,4 +126,4 @@ const Combobox = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default Combobox;
|
||||
module.exports = Combobox;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import './renderWarnings.less';
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import _ from 'lodash';
|
||||
require('./renderWarnings.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
|
||||
import Dialog from '../dialog.jsx';
|
||||
|
||||
const RenderWarnings = createReactClass({
|
||||
const RenderWarnings = createClass({
|
||||
displayName : 'RenderWarnings',
|
||||
getInitialState : function() {
|
||||
return {
|
||||
@@ -57,4 +57,4 @@ const RenderWarnings = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default RenderWarnings;
|
||||
module.exports = RenderWarnings;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import './splitPane.less';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
require('./splitPane.less');
|
||||
const React = require('react');
|
||||
const { useState, useEffect } = React;
|
||||
|
||||
const PANE_WIDTH_KEY = 'HB_editor_splitWidth';
|
||||
const LIVE_SCROLL_KEY = 'HB_editor_liveScroll';
|
||||
@@ -107,4 +108,4 @@ const Pane = ({ width, children, isDragging, moveBrew, moveSource, liveScroll, s
|
||||
);
|
||||
};
|
||||
|
||||
export default SplitPane;
|
||||
module.exports = SplitPane;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
|
||||
export default function(props){
|
||||
module.exports = function(props){
|
||||
return <svg version='1.1' x='0px' y='0px' viewBox='0 0 90 112.5' enableBackground='new 0 0 90 90' >
|
||||
<path d='M25.363,25.54c0,1.906,8.793,3.454,19.636,3.454c10.848,0,19.638-1.547,19.638-3.454c0-1.12-3.056-2.117-7.774-2.75 c-1.418,1.891-3.659,3.133-6.208,3.133c-2.85,0-5.315-1.547-6.67-3.833C33.617,22.185,25.363,23.692,25.363,25.54z'/><path d='M84.075,54.142c0-8.68-2.868-17.005-8.144-23.829c1.106-1.399,1.41-2.771,1.41-3.854c0-6.574-10.245-9.358-19.264-10.533 c0.209,0.706,0.359,1.439,0.359,2.215c0,0.09-0.022,0.17-0.028,0.26l0,0c-0.028,0.853-0.195,1.667-0.479,2.429 c9.106,1.282,14.508,3.754,14.508,5.63c0,2.644-10.688,6.486-27.439,6.486c-16.748,0-27.438-3.842-27.438-6.486 c0-2.542,9.904-6.183,25.559-6.459c-0.098-0.396-0.159-0.807-0.2-1.223c0.006,0,0.013,0,0.017,0 c-0.017-0.213-0.063-0.417-0.063-0.636c0-1.084,0.226-2.119,0.628-3.058c-6.788,0.129-30.846,1.299-30.846,11.376 c0,1.083,0.305,2.455,1.411,3.854c-5.276,6.823-8.145,15.149-8.145,23.829c0,11.548,5.187,20.107,14.693,25.115 c-0.902,3.146-1.391,7.056,1.111,8.181c2.626,1.178,5.364-2.139,7.111-5.005c4.73,1.261,10.13,1.923,16.161,1.923 c6.034,0,11.428-0.661,16.158-1.922c1.75,2.865,4.493,6.18,7.112,5.004c2.504-1.123,2.014-5.035,1.113-8.179 C78.889,74.249,84.075,65.689,84.075,54.142z M70.39,31.392c5.43,6.046,8.78,14,8.78,22.75c0,20.919-18.582,25.309-34.171,25.309 c-15.587,0-34.17-4.39-34.17-25.309c0-8.75,3.35-16.7,8.781-22.753c5.561,2.643,15.502,4.009,25.389,4.009 C54.886,35.397,64.829,34.031,70.39,31.392z'/><path d='M50.654,23.374c2.892,0,5.234-2.341,5.234-5.233c0-2.887-2.343-5.23-5.234-5.23c-2.887,0-5.231,2.343-5.231,5.23 C45.423,21.032,47.768,23.374,50.654,23.374z'/>
|
||||
<circle cx='62.905' cy='10.089' r='3.595'/>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
|
||||
export default function(props){
|
||||
module.exports = function(props){
|
||||
return <svg version='1.1' x='0px' y='0px' viewBox='0 0 100 100' enableBackground='new 0 0 100 100'><path d='M80.644,87.982l16.592-41.483c0.054-0.128,0.088-0.26,0.108-0.394c0.006-0.039,0.007-0.077,0.011-0.116 c0.007-0.087,0.008-0.174,0.002-0.26c-0.003-0.046-0.007-0.091-0.014-0.137c-0.014-0.089-0.036-0.176-0.063-0.262 c-0.012-0.034-0.019-0.069-0.031-0.103c-0.047-0.118-0.106-0.229-0.178-0.335c-0.004-0.006-0.006-0.012-0.01-0.018L67.999,3.358 c-0.01-0.013-0.003-0.026-0.013-0.04L68,3.315V4c0,0-0.033,0-0.037,0c-0.403-1-1.094-1.124-1.752-0.976 c0,0.004-0.004-0.012-0.007-0.012C66.201,3.016,66.194,3,66.194,3H66.19h-0.003h-0.003h-0.004h-0.003c0,0-0.004,0-0.007,0 s-0.003-0.151-0.007-0.151L20.495,15.227c-0.025,0.007-0.046-0.019-0.071-0.011c-0.087,0.028-0.172,0.041-0.253,0.083 c-0.054,0.027-0.102,0.053-0.152,0.085c-0.051,0.033-0.101,0.061-0.147,0.099c-0.044,0.036-0.084,0.073-0.124,0.113 c-0.048,0.048-0.093,0.098-0.136,0.152c-0.03,0.039-0.059,0.076-0.085,0.117c-0.046,0.07-0.084,0.145-0.12,0.223 c-0.011,0.023-0.027,0.042-0.036,0.066L2.911,57.664C2.891,57.715,3,57.768,3,57.82v0.002c0,0.186,0,0.375,0,0.562 c0,0.004,0,0.004,0,0.008c0,0,0,0,0,0.002c0,0,0,0,0,0.004v0.004v0.002c0,0.074-0.002,0.15,0.012,0.223 C3.015,58.631,3,58.631,3,58.633c0,0.004,0,0.004,0,0.008c0,0,0,0,0,0.002c0,0,0,0,0,0.004v0.004c0,0,0,0,0,0.002v0.004 c0,0.191-0.046,0.377,0.06,0.545c0-0.002-0.03,0.004-0.03,0.004c0,0.004-0.03,0.004-0.03,0.004c0,0.002,0,0.002,0,0.002 l-0.045,0.004c0.03,0.047,0.036,0.09,0.068,0.133l29.049,37.359c0.002,0.004,0,0.006,0.002,0.01c0.002,0.002,0,0.004,0.002,0.008 c0.006,0.008,0.014,0.014,0.021,0.021c0.024,0.029,0.052,0.051,0.078,0.078c0.027,0.029,0.053,0.057,0.082,0.082 c0.03,0.027,0.055,0.062,0.086,0.088c0.026,0.02,0.057,0.033,0.084,0.053c0.04,0.027,0.081,0.053,0.123,0.076 c0.005,0.004,0.01,0.008,0.016,0.01c0.087,0.051,0.176,0.09,0.269,0.123c0.042,0.014,0.082,0.031,0.125,0.043 c0.021,0.006,0.041,0.018,0.062,0.021c0.123,0.027,0.249,0.043,0.375,0.043c0.099,0,0.202-0.012,0.304-0.027l45.669-8.303 c0.057-0.01,0.108-0.021,0.163-0.037C79.547,88.992,79.562,89,79.575,89c0.004,0,0.004,0,0.004,0c0.021,0,0.039-0.027,0.06-0.035 c0.041-0.014,0.08-0.034,0.12-0.052c0.021-0.01,0.044-0.019,0.064-0.03c0.017-0.01,0.026-0.015,0.033-0.017 c0.014-0.008,0.023-0.021,0.037-0.028c0.14-0.078,0.269-0.174,0.38-0.285c0.014-0.016,0.024-0.034,0.038-0.048 c0.109-0.119,0.201-0.252,0.271-0.398c0.006-0.01,0.016-0.018,0.021-0.029c0.004-0.008,0.008-0.017,0.011-0.026 c0.002-0.004,0.003-0.006,0.005-0.01C80.627,88.021,80.635,88.002,80.644,87.982z M77.611,84.461L48.805,66.453l32.407-25.202 L77.611,84.461z M46.817,63.709L35.863,23.542l43.818,14.608L46.817,63.709z M84.668,40.542l8.926,5.952l-11.902,29.75 L84.668,40.542z M89.128,39.446L84.53,36.38l-6.129-12.257L89.128,39.446z M79.876,34.645L37.807,20.622L65.854,6.599L79.876,34.645 z M33.268,19.107l-6.485-2.162l23.781-6.487L33.268,19.107z M21.92,18.895l8.67,2.891L10.357,47.798L21.92,18.895z M32.652,24.649 l10.845,39.757L7.351,57.178L32.652,24.649z M43.472,67.857L32.969,92.363L8.462,60.855L43.472,67.857z M46.631,69.09l27.826,17.393 l-38.263,6.959L46.631,69.09z'></path></svg>;
|
||||
};
|
||||
@@ -1,19 +1,20 @@
|
||||
/*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/
|
||||
import './brewRenderer.less';
|
||||
import React, { useState, useRef, useMemo, useEffect } from 'react';
|
||||
import _ from 'lodash';
|
||||
require('./brewRenderer.less');
|
||||
const React = require('react');
|
||||
const { useState, useRef, useMemo, useEffect } = React;
|
||||
const _ = require('lodash');
|
||||
|
||||
import MarkdownLegacy from '../../../shared/markdownLegacy.js';
|
||||
import Markdown from '../../../shared/markdown.js';
|
||||
import ErrorBar from './errorBar/errorBar.jsx';
|
||||
import ToolBar from './toolBar/toolBar.jsx';
|
||||
const MarkdownLegacy = require('markdownLegacy.js');
|
||||
import Markdown from 'markdown.js';
|
||||
const ErrorBar = require('./errorBar/errorBar.jsx');
|
||||
const ToolBar = require('./toolBar/toolBar.jsx');
|
||||
|
||||
//TODO: move to the brew renderer
|
||||
import RenderWarnings from '../../components/renderWarnings/renderWarnings.jsx';
|
||||
import NotificationPopup from './notificationPopup/notificationPopup.jsx';
|
||||
import Frame from 'react-frame-component';
|
||||
import dedent from 'dedent';
|
||||
import { printCurrentBrew } from '../../../shared/helpers.js';
|
||||
const RenderWarnings = require('client/components/renderWarnings/renderWarnings.jsx');
|
||||
const NotificationPopup = require('./notificationPopup/notificationPopup.jsx');
|
||||
const Frame = require('react-frame-component').default;
|
||||
const dedent = require('dedent-tabs').default;
|
||||
const { printCurrentBrew } = require('../../../shared/helpers.js');
|
||||
|
||||
import HeaderNav from './headerNav/headerNav.jsx';
|
||||
import { safeHTML } from './safeHTML.js';
|
||||
@@ -344,4 +345,4 @@ const BrewRenderer = (props)=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default BrewRenderer;
|
||||
module.exports = BrewRenderer;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import './errorBar.less';
|
||||
import React from 'react';
|
||||
require('./errorBar.less');
|
||||
const React = require('react');
|
||||
|
||||
import Dialog from '../../../components/dialog.jsx';
|
||||
|
||||
@@ -50,4 +50,4 @@ const ErrorBar = (props)=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default ErrorBar;
|
||||
module.exports = ErrorBar;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import './headerNav.less';
|
||||
require('./headerNav.less');
|
||||
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
const MAX_TEXT_LENGTH = 40;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import './notificationPopup.less';
|
||||
require('./notificationPopup.less');
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import request from '../../utils/request-middleware.js';
|
||||
import Markdown from 'markdown.js';
|
||||
@@ -62,4 +62,4 @@ const NotificationPopup = ()=>{
|
||||
</Dialog>;
|
||||
};
|
||||
|
||||
export default NotificationPopup;
|
||||
module.exports = NotificationPopup;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/* eslint-disable max-lines */
|
||||
import './toolBar.less';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import _ from 'lodash';
|
||||
require('./toolBar.less');
|
||||
const React = require('react');
|
||||
const { useState, useEffect } = React;
|
||||
const _ = require('lodash');
|
||||
|
||||
import { Anchored, AnchoredBox, AnchoredTrigger } from '../../../components/Anchored.jsx';
|
||||
|
||||
@@ -258,4 +259,4 @@ const ToolBar = ({ displayOptions, onDisplayOptionsChange, visiblePages, totalPa
|
||||
);
|
||||
};
|
||||
|
||||
export default ToolBar;
|
||||
module.exports = ToolBar;
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
/*eslint max-lines: ["warn", {"max": 500, "skipBlankLines": true, "skipComments": true}]*/
|
||||
import './editor.less';
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import _ from 'lodash';
|
||||
import dedent from 'dedent';
|
||||
require('./editor.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
import Markdown from '../../../shared/markdown.js';
|
||||
|
||||
import CodeEditor from '../../components/codeEditor/codeEditor.jsx';
|
||||
import SnippetBar from './snippetbar/snippetbar.jsx';
|
||||
import MetadataEditor from './metadataEditor/metadataEditor.jsx';
|
||||
const CodeEditor = require('client/components/codeEditor/codeEditor.jsx');
|
||||
import CodeEditorV6 from 'client/components/codeEditor/codeEditorV6.jsx';
|
||||
|
||||
const USE_CM6 = global?.config?.enable_CM6 === true;
|
||||
const SnippetBar = require('./snippetbar/snippetbar.jsx');
|
||||
const MetadataEditor = require('./metadataEditor/metadataEditor.jsx');
|
||||
|
||||
const EDITOR_THEME_KEY = 'HB_editor_theme';
|
||||
|
||||
@@ -31,7 +34,7 @@ const DEFAULT_SNIPPET_TEXT = dedent`
|
||||
`;
|
||||
let isJumping = false;
|
||||
|
||||
const Editor = createReactClass({
|
||||
const Editor = createClass({
|
||||
displayName : 'Editor',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
@@ -58,12 +61,38 @@ const Editor = createReactClass({
|
||||
return {
|
||||
editorTheme : this.props.editorTheme,
|
||||
view : 'text', //'text', 'style', 'meta', 'snippet'
|
||||
snippetBarHeight : 26,
|
||||
snippetbarHeight : 25
|
||||
};
|
||||
},
|
||||
|
||||
editor : React.createRef(null),
|
||||
codeEditor : React.createRef(null),
|
||||
editor : React.createRef(null),
|
||||
codeEditor : React.createRef(null),
|
||||
codeEditorV6 : React.createRef(null),
|
||||
|
||||
getActiveEditor : function(){
|
||||
return USE_CM6 ? this.codeEditorV6.current : this.codeEditor.current;
|
||||
},
|
||||
|
||||
focusActiveEditor : function(){
|
||||
const editor = this.getActiveEditor();
|
||||
if(!editor) return;
|
||||
if(USE_CM6) editor.focus?.();
|
||||
else editor.codeMirror?.focus();
|
||||
},
|
||||
|
||||
handleCM6SelectionChange : function(view){
|
||||
if(!USE_CM6 || !view) return;
|
||||
const { head } = view.state.selection.main;
|
||||
const lineInfo = view.state.doc.lineAt(head);
|
||||
this.updateCurrentCursorPage({ line: lineInfo.number - 1 });
|
||||
},
|
||||
|
||||
handleCM6Scroll : function(){
|
||||
if(!USE_CM6) return;
|
||||
const topLine = this.codeEditorV6.current?.getTopVisibleLine?.();
|
||||
if(topLine == null) return;
|
||||
this.updateCurrentViewPage(topLine);
|
||||
},
|
||||
|
||||
isText : function() {return this.state.view == 'text';},
|
||||
isStyle : function() {return this.state.view == 'style';},
|
||||
@@ -76,8 +105,10 @@ const Editor = createReactClass({
|
||||
document.getElementById('BrewRenderer').addEventListener('keydown', this.handleControlKeys);
|
||||
document.addEventListener('keydown', this.handleControlKeys);
|
||||
|
||||
this.codeEditor.current.codeMirror?.on('cursorActivity', (cm)=>{this.updateCurrentCursorPage(cm.getCursor());});
|
||||
this.codeEditor.current.codeMirror?.on('scroll', _.throttle(()=>{this.updateCurrentViewPage(this.codeEditor.current.getTopVisibleLine());}, 200));
|
||||
if(!USE_CM6) {
|
||||
this.codeEditor.current?.codeMirror?.on('cursorActivity', (cm)=>{this.updateCurrentCursorPage(cm.getCursor());});
|
||||
this.codeEditor.current?.codeMirror?.on('scroll', _.throttle(()=>{this.updateCurrentViewPage(this.codeEditor.current.getTopVisibleLine());}, 200));
|
||||
}
|
||||
|
||||
const editorTheme = window.localStorage.getItem(EDITOR_THEME_KEY);
|
||||
if(editorTheme) {
|
||||
@@ -85,20 +116,12 @@ const Editor = createReactClass({
|
||||
editorTheme : editorTheme
|
||||
});
|
||||
}
|
||||
const snippetBar = document.querySelector('.editor > .snippetBar');
|
||||
if (!snippetBar) return;
|
||||
|
||||
this.resizeObserver = new ResizeObserver(entries => {
|
||||
const height = document.querySelector('.editor > .snippetBar').offsetHeight;
|
||||
this.setState({ snippetBarHeight: height });
|
||||
});
|
||||
|
||||
this.resizeObserver.observe(snippetBar);
|
||||
this.setState({ snippetbarHeight: document.querySelector('.editor > .snippetBar').offsetHeight });
|
||||
},
|
||||
|
||||
componentDidUpdate : function(prevProps, prevState, snapshot) {
|
||||
|
||||
this.highlightCustomMarkdown();
|
||||
if(!USE_CM6) this.highlightCustomMarkdown();
|
||||
if(prevProps.moveBrew !== this.props.moveBrew)
|
||||
this.brewJump();
|
||||
|
||||
@@ -116,10 +139,6 @@ const Editor = createReactClass({
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.resizeObserver) this.resizeObserver.disconnect();
|
||||
},
|
||||
|
||||
handleControlKeys : function(e){
|
||||
if(!(e.ctrlKey && e.metaKey && e.shiftKey)) return;
|
||||
const LEFTARROW_KEY = 37;
|
||||
@@ -133,7 +152,8 @@ const Editor = createReactClass({
|
||||
},
|
||||
|
||||
updateCurrentCursorPage : function(cursor) {
|
||||
const lines = this.props.brew.text.split('\n').slice(1, cursor.line + 1);
|
||||
const cursorLine = cursor.line ?? cursor;
|
||||
const lines = this.props.brew.text.split('\n').slice(1, cursorLine + 1);
|
||||
const pageRegex = this.props.brew.renderer == 'V3' ? PAGEBREAK_REGEX_V3 : /\\page/;
|
||||
const currentPage = lines.reduce((count, line)=>count + (pageRegex.test(line) ? 1 : 0), 1);
|
||||
this.props.onCursorPageChange(currentPage);
|
||||
@@ -156,21 +176,21 @@ const Editor = createReactClass({
|
||||
this.setState({
|
||||
view : newView
|
||||
}, ()=>{
|
||||
this.codeEditor.current?.codeMirror?.focus();
|
||||
this.codeEditor.current?.codeMirror.focus();
|
||||
});
|
||||
},
|
||||
|
||||
highlightCustomMarkdown : function(){
|
||||
if(!this.codeEditor.current?.codeMirror) return;
|
||||
if(!this.codeEditor.current) return;
|
||||
if((this.state.view === 'text') ||(this.state.view === 'snippet')) {
|
||||
const codeMirror = this.codeEditor.current.codeMirror;
|
||||
|
||||
codeMirror?.operation(()=>{ // Batch CodeMirror styling
|
||||
codeMirror.operation(()=>{ // Batch CodeMirror styling
|
||||
|
||||
const foldLines = [];
|
||||
|
||||
//reset custom text styles
|
||||
const customHighlights = codeMirror?.getAllMarks().filter((mark)=>{
|
||||
const customHighlights = codeMirror.getAllMarks().filter((mark)=>{
|
||||
// Record details of folded sections
|
||||
if(mark.__isFold) {
|
||||
const fold = mark.find();
|
||||
@@ -191,10 +211,10 @@ const Editor = createReactClass({
|
||||
const textOrSnip = this.state.view === 'text';
|
||||
|
||||
//reset custom line styles
|
||||
codeMirror?.removeLineClass(lineNumber, 'background', 'pageLine');
|
||||
codeMirror?.removeLineClass(lineNumber, 'background', 'snippetLine');
|
||||
codeMirror?.removeLineClass(lineNumber, 'text');
|
||||
codeMirror?.removeLineClass(lineNumber, 'wrap', 'sourceMoveFlash');
|
||||
codeMirror.removeLineClass(lineNumber, 'background', 'pageLine');
|
||||
codeMirror.removeLineClass(lineNumber, 'background', 'snippetLine');
|
||||
codeMirror.removeLineClass(lineNumber, 'text');
|
||||
codeMirror.removeLineClass(lineNumber, 'wrap', 'sourceMoveFlash');
|
||||
|
||||
// Don't process lines inside folded text
|
||||
// If the current lineNumber is inside any folded marks, skip line styling
|
||||
@@ -210,19 +230,19 @@ const Editor = createReactClass({
|
||||
else if(this.state.view !== 'text') userSnippetCount += 1;
|
||||
|
||||
// add back the original class 'background' but also add the new class '.pageline'
|
||||
codeMirror?.addLineClass(lineNumber, 'background', tabHighlight);
|
||||
codeMirror.addLineClass(lineNumber, 'background', tabHighlight);
|
||||
const pageCountElement = Object.assign(document.createElement('span'), {
|
||||
className : 'editor-page-count',
|
||||
textContent : textOrSnip ? editorPageCount : userSnippetCount
|
||||
});
|
||||
codeMirror?.setBookmark({ line: lineNumber, ch: line.length }, pageCountElement);
|
||||
codeMirror.setBookmark({ line: lineNumber, ch: line.length }, pageCountElement);
|
||||
};
|
||||
|
||||
|
||||
// New CodeMirror styling for V3 renderer
|
||||
// New Codemirror styling for V3 renderer
|
||||
if(this.props.renderer === 'V3') {
|
||||
if(line.match(/^\\column(?:break)?$/)){
|
||||
codeMirror?.addLineClass(lineNumber, 'text', 'columnSplit');
|
||||
codeMirror.addLineClass(lineNumber, 'text', 'columnSplit');
|
||||
}
|
||||
|
||||
// definition lists
|
||||
@@ -231,14 +251,14 @@ const Editor = createReactClass({
|
||||
const regex = /^([^\n]*?:?\s?)(::[^\n]*)(?:\n|$)/ymd; // the `d` flag, for match indices, throws an ESLint error.
|
||||
let match;
|
||||
while ((match = regex.exec(line)) != null){
|
||||
codeMirror?.markText({ line: lineNumber, ch: match.indices[0][0] }, { line: lineNumber, ch: match.indices[0][1] }, { className: 'dl-highlight' });
|
||||
codeMirror?.markText({ line: lineNumber, ch: match.indices[1][0] }, { line: lineNumber, ch: match.indices[1][1] }, { className: 'dt-highlight' });
|
||||
codeMirror?.markText({ line: lineNumber, ch: match.indices[2][0] }, { line: lineNumber, ch: match.indices[2][1] }, { className: 'dd-highlight' });
|
||||
codeMirror.markText({ line: lineNumber, ch: match.indices[0][0] }, { line: lineNumber, ch: match.indices[0][1] }, { className: 'dl-highlight' });
|
||||
codeMirror.markText({ line: lineNumber, ch: match.indices[1][0] }, { line: lineNumber, ch: match.indices[1][1] }, { className: 'dt-highlight' });
|
||||
codeMirror.markText({ line: lineNumber, ch: match.indices[2][0] }, { line: lineNumber, ch: match.indices[2][1] }, { className: 'dd-highlight' });
|
||||
const ddIndex = match.indices[2][0];
|
||||
const colons = /::/g;
|
||||
const colonMatches = colons.exec(match[2]);
|
||||
if(colonMatches !== null){
|
||||
codeMirror?.markText({ line: lineNumber, ch: colonMatches.index + ddIndex }, { line: lineNumber, ch: colonMatches.index + colonMatches[0].length + ddIndex }, { className: 'dl-colon-highlight' });
|
||||
codeMirror.markText({ line: lineNumber, ch: colonMatches.index + ddIndex }, { line: lineNumber, ch: colonMatches.index + colonMatches[0].length + ddIndex }, { className: 'dl-colon-highlight' });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,7 +275,7 @@ const Editor = createReactClass({
|
||||
const match = subRegex.exec(line) || superRegex.exec(line);
|
||||
if(match) {
|
||||
isSuper = !subRegex.lastIndex;
|
||||
codeMirror?.markText({ line: lineNumber, ch: match.index }, { line: lineNumber, ch: match.index + match[0].length }, { className: isSuper ? 'superscript' : 'subscript' });
|
||||
codeMirror.markText({ line: lineNumber, ch: match.index }, { line: lineNumber, ch: match.index + match[0].length }, { className: isSuper ? 'superscript' : 'subscript' });
|
||||
}
|
||||
startIndex = line.indexOf('^', Math.max(startIndex + 1, subRegex.lastIndex, superRegex.lastIndex));
|
||||
}
|
||||
@@ -266,7 +286,7 @@ const Editor = createReactClass({
|
||||
const regex = /(?:^|[^{\n])({(?=((?:[:=](?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':={}\s]*)*))\2})/gm;
|
||||
let match;
|
||||
while ((match = regex.exec(line)) != null) {
|
||||
codeMirror?.markText({ line: lineNumber, ch: line.indexOf(match[1]) }, { line: lineNumber, ch: line.indexOf(match[1]) + match[1].length }, { className: 'injection' });
|
||||
codeMirror.markText({ line: lineNumber, ch: line.indexOf(match[1]) }, { line: lineNumber, ch: line.indexOf(match[1]) + match[1].length }, { className: 'injection' });
|
||||
}
|
||||
}
|
||||
// Highlight inline spans {{content}}
|
||||
@@ -284,7 +304,7 @@ const Editor = createReactClass({
|
||||
blockCount = 0;
|
||||
continue;
|
||||
}
|
||||
codeMirror?.markText({ line: lineNumber, ch: match.index }, { line: lineNumber, ch: match.index + match[0].length }, { className: 'inline-block' });
|
||||
codeMirror.markText({ line: lineNumber, ch: match.index }, { line: lineNumber, ch: match.index + match[0].length }, { className: 'inline-block' });
|
||||
}
|
||||
} else if(line.trimLeft().startsWith('{{') || line.trimLeft().startsWith('}}')){
|
||||
// Highlight block divs {{\n Content \n}}
|
||||
@@ -293,7 +313,7 @@ const Editor = createReactClass({
|
||||
const match = line.match(/^ *{{(?=((?:[:=](?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':={}\s]*)*))\1 *$|^ *}}$/);
|
||||
if(match)
|
||||
endCh = match.index+match[0].length;
|
||||
codeMirror?.markText({ line: lineNumber, ch: 0 }, { line: lineNumber, ch: endCh }, { className: 'block' });
|
||||
codeMirror.markText({ line: lineNumber, ch: 0 }, { line: lineNumber, ch: endCh }, { className: 'block' });
|
||||
}
|
||||
|
||||
// Emojis
|
||||
@@ -314,11 +334,11 @@ const Editor = createReactClass({
|
||||
const endPos = { line: lineNumber, ch: match.index + match[0].length };
|
||||
|
||||
// Iterate over conflicting marks and clear them
|
||||
const marks = codeMirror?.findMarks(startPos, endPos);
|
||||
const marks = codeMirror.findMarks(startPos, endPos);
|
||||
marks.forEach(function(marker) {
|
||||
if(!marker.__isFold) marker.clear();
|
||||
});
|
||||
codeMirror?.markText(startPos, endPos, { className: 'emoji' });
|
||||
codeMirror.markText(startPos, endPos, { className: 'emoji' });
|
||||
}
|
||||
startIndex = line.indexOf(':', Math.max(startIndex + 1, emojiRegex.lastIndex));
|
||||
}
|
||||
@@ -378,51 +398,53 @@ const Editor = createReactClass({
|
||||
const textString = this.props.brew.text.split(textSplit).slice(0, targetPage-1).join(textSplit);
|
||||
const targetLine = textString.match('\n') ? textString.split('\n').length - 1 : -1;
|
||||
|
||||
let currentY = this.codeEditor.current.codeMirror?.getScrollInfo().top;
|
||||
let targetY = this.codeEditor.current.codeMirror?.heightAtLine(targetLine, 'local', true);
|
||||
let currentY = this.codeEditor.current.codeMirror.getScrollInfo().top;
|
||||
let targetY = this.codeEditor.current.codeMirror.heightAtLine(targetLine, 'local', true);
|
||||
|
||||
let scrollingTimeout;
|
||||
const checkIfScrollComplete = ()=>{ // Prevent interrupting a scroll in progress if user clicks multiple times
|
||||
clearTimeout(scrollingTimeout); // Reset the timer every time a scroll event occurs
|
||||
scrollingTimeout = setTimeout(()=>{
|
||||
isJumping = false;
|
||||
this.codeEditor.current.codeMirror?.off('scroll', checkIfScrollComplete);
|
||||
this.codeEditor.current.codeMirror.off('scroll', checkIfScrollComplete);
|
||||
}, 150); // If 150 ms pass without a scroll event, assume scrolling is done
|
||||
};
|
||||
|
||||
isJumping = true;
|
||||
checkIfScrollComplete();
|
||||
if (this.codeEditor.current?.codeMirror) {
|
||||
this.codeEditor.current.codeMirror?.on('scroll', checkIfScrollComplete);
|
||||
}
|
||||
this.codeEditor.current.codeMirror.on('scroll', checkIfScrollComplete);
|
||||
|
||||
if(smooth) {
|
||||
//Scroll 1/10 of the way every 10ms until 1px off.
|
||||
const incrementalScroll = setInterval(()=>{
|
||||
currentY += (targetY - currentY) / 10;
|
||||
this.codeEditor.current.codeMirror?.scrollTo(null, currentY);
|
||||
this.codeEditor.current.codeMirror.scrollTo(null, currentY);
|
||||
|
||||
// Update target: target height is not accurate until within +-10 lines of the visible window
|
||||
if(Math.abs(targetY - currentY > 100))
|
||||
targetY = this.codeEditor.current.codeMirror?.heightAtLine(targetLine, 'local', true);
|
||||
targetY = this.codeEditor.current.codeMirror.heightAtLine(targetLine, 'local', true);
|
||||
|
||||
// End when close enough
|
||||
if(Math.abs(targetY - currentY) < 1) {
|
||||
this.codeEditor.current.codeMirror?.scrollTo(null, targetY); // Scroll any remaining difference
|
||||
this.codeEditor.current.codeMirror.scrollTo(null, targetY); // Scroll any remaining difference
|
||||
this.codeEditor.current.setCursorPosition({ line: targetLine + 1, ch: 0 });
|
||||
this.codeEditor.current.codeMirror?.addLineClass(targetLine + 1, 'wrap', 'sourceMoveFlash');
|
||||
this.codeEditor.current.codeMirror.addLineClass(targetLine + 1, 'wrap', 'sourceMoveFlash');
|
||||
clearInterval(incrementalScroll);
|
||||
}
|
||||
}, 10);
|
||||
} else {
|
||||
this.codeEditor.current.codeMirror?.scrollTo(null, targetY); // Scroll any remaining difference
|
||||
this.codeEditor.current.codeMirror.scrollTo(null, targetY); // Scroll any remaining difference
|
||||
this.codeEditor.current.setCursorPosition({ line: targetLine + 1, ch: 0 });
|
||||
this.codeEditor.current.codeMirror?.addLineClass(targetLine + 1, 'wrap', 'sourceMoveFlash');
|
||||
this.codeEditor.current.codeMirror.addLineClass(targetLine + 1, 'wrap', 'sourceMoveFlash');
|
||||
}
|
||||
},
|
||||
|
||||
//Called when there are changes to the editor's dimensions
|
||||
update : function(){},
|
||||
update : function(){
|
||||
const snipHeight = document.querySelector('.editor > .snippetBar').offsetHeight;
|
||||
if(snipHeight !== this.state.snippetbarHeight)
|
||||
this.setState({ snippetbarHeight: snipHeight });
|
||||
},
|
||||
|
||||
updateEditorTheme : function(newTheme){
|
||||
window.localStorage.setItem(EDITOR_THEME_KEY, newTheme);
|
||||
@@ -447,7 +469,7 @@ const Editor = createReactClass({
|
||||
onChange={this.props.onBrewChange('text')}
|
||||
editorTheme={this.state.editorTheme}
|
||||
rerenderParent={this.rerenderParent}
|
||||
style={{ height: `calc(100% - ${this.state.snippetBarHeight}px)` }} />
|
||||
style={{ height: `calc(100% - ${this.state.snippetbarHeight}px)` }} />
|
||||
</>;
|
||||
}
|
||||
if(this.isStyle()){
|
||||
@@ -461,7 +483,7 @@ const Editor = createReactClass({
|
||||
enableFolding={true}
|
||||
editorTheme={this.state.editorTheme}
|
||||
rerenderParent={this.rerenderParent}
|
||||
style={{ height: `calc(100% - ${this.state.snippetBarHeight}px)` }} />
|
||||
style={{ height: `calc(100% - ${this.state.snippetbarHeight}px)` }} />
|
||||
</>;
|
||||
}
|
||||
if(this.isMeta()){
|
||||
@@ -478,6 +500,7 @@ const Editor = createReactClass({
|
||||
userThemes={this.props.userThemes}/>
|
||||
</>;
|
||||
}
|
||||
|
||||
if(this.isSnip()){
|
||||
if(!this.props.brew.snippets) { this.props.brew.snippets = DEFAULT_SNIPPET_TEXT; }
|
||||
return <>
|
||||
@@ -490,7 +513,7 @@ const Editor = createReactClass({
|
||||
enableFolding={true}
|
||||
editorTheme={this.state.editorTheme}
|
||||
rerenderParent={this.rerenderParent}
|
||||
style={{ height: `calc(100% -${this.state.snippetBarHeight}px)` }} />
|
||||
style={{ height: `calc(100% - ${this.state.snippetbarHeight}px)` }} />
|
||||
</>;
|
||||
}
|
||||
},
|
||||
@@ -544,4 +567,4 @@ const Editor = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default Editor;
|
||||
module.exports = Editor;
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
/* eslint-disable max-lines */
|
||||
import './metadataEditor.less';
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import _ from 'lodash';
|
||||
require('./metadataEditor.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
import request from '../../utils/request-middleware.js';
|
||||
import Combobox from '../../../components/combobox.jsx';
|
||||
import TagInput from '../tagInput/tagInput.jsx';
|
||||
const Combobox = require('client/components/combobox.jsx');
|
||||
const TagInput = require('../tagInput/tagInput.jsx');
|
||||
|
||||
import Themes from 'themes/themes.json';
|
||||
import validations from './validations.js';
|
||||
|
||||
const Themes = require('themes/themes.json');
|
||||
const validations = require('./validations.js');
|
||||
|
||||
const SYSTEMS = ['5e', '4e', '3.5e', 'Pathfinder'];
|
||||
|
||||
import homebreweryThumbnail from '../../thumbnail.png';
|
||||
const homebreweryThumbnail = require('../../thumbnail.png');
|
||||
|
||||
const callIfExists = (val, fn, ...args)=>{
|
||||
if(val[fn]) {
|
||||
@@ -20,7 +21,7 @@ const callIfExists = (val, fn, ...args)=>{
|
||||
}
|
||||
};
|
||||
|
||||
const MetadataEditor = createReactClass({
|
||||
const MetadataEditor = createClass({
|
||||
displayName : 'MetadataEditor',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
@@ -410,4 +411,4 @@ const MetadataEditor = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default MetadataEditor;
|
||||
module.exports = MetadataEditor;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export default {
|
||||
module.exports = {
|
||||
title : [
|
||||
(value)=>{
|
||||
return value?.length > 100 ? 'Max title length of 100 characters' : null;
|
||||
|
||||
@@ -1,36 +1,29 @@
|
||||
/*eslint max-lines: ["warn", {"max": 350, "skipBlankLines": true, "skipComments": true}]*/
|
||||
import './snippetbar.less';
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
|
||||
import _ from 'lodash';
|
||||
import cx from 'classnames';
|
||||
require('./snippetbar.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
const cx = require('classnames');
|
||||
|
||||
import { loadHistory } from '../../utils/versionHistory.js';
|
||||
import { brewSnippetsToJSON } from '../../../../shared/helpers.js';
|
||||
|
||||
import Legacy5ePHB from 'themes/Legacy/5ePHB/snippets.js';
|
||||
import V3_5ePHB from 'themes/V3/5ePHB/snippets.js';
|
||||
import V3_5eDMG from 'themes/V3/5eDMG/snippets.js';
|
||||
import V3_Journal from 'themes/V3/Journal/snippets.js';
|
||||
import V3_Blank from 'themes/V3/Blank/snippets.js';
|
||||
//Import all themes
|
||||
const ThemeSnippets = {};
|
||||
ThemeSnippets['Legacy_5ePHB'] = require('themes/Legacy/5ePHB/snippets.js');
|
||||
ThemeSnippets['V3_5ePHB'] = require('themes/V3/5ePHB/snippets.js');
|
||||
ThemeSnippets['V3_5eDMG'] = require('themes/V3/5eDMG/snippets.js');
|
||||
ThemeSnippets['V3_Journal'] = require('themes/V3/Journal/snippets.js');
|
||||
ThemeSnippets['V3_Blank'] = require('themes/V3/Blank/snippets.js');
|
||||
|
||||
const ThemeSnippets = {
|
||||
Legacy_5ePHB : Legacy5ePHB,
|
||||
V3_5ePHB : V3_5ePHB,
|
||||
V3_5eDMG : V3_5eDMG,
|
||||
V3_Journal : V3_Journal,
|
||||
V3_Blank : V3_Blank,
|
||||
};
|
||||
|
||||
import EditorThemes from 'build/homebrew/codeMirror/editorThemes.json';
|
||||
const EditorThemes = require('build/homebrew/codeMirror/editorThemes.json');
|
||||
|
||||
const execute = function(val, props){
|
||||
if(_.isFunction(val)) return val(props);
|
||||
return val;
|
||||
};
|
||||
|
||||
const Snippetbar = createReactClass({
|
||||
const Snippetbar = createClass({
|
||||
displayName : 'SnippetBar',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
@@ -288,9 +281,9 @@ const Snippetbar = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default Snippetbar;
|
||||
module.exports = Snippetbar;
|
||||
|
||||
const SnippetGroup = createReactClass({
|
||||
const SnippetGroup = createClass({
|
||||
displayName : 'SnippetGroup',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
.snippets {
|
||||
display : flex;
|
||||
justify-content : flex-start;
|
||||
min-width : 499.35px; //must be controlled every time an item is added, must be hardcoded for the wrapping as it is applied
|
||||
min-width : 432.18px; //must be controlled every time an item is added, must be hardcoded for the wrapping as it is applied
|
||||
}
|
||||
|
||||
.editors {
|
||||
@@ -237,7 +237,7 @@
|
||||
}
|
||||
|
||||
}
|
||||
@container editor (width < 750px) {
|
||||
@container editor (width < 683px) {
|
||||
.snippetBar {
|
||||
.editors {
|
||||
flex : 1;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import './tagInput.less';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import _ from 'lodash';
|
||||
require('./tagInput.less');
|
||||
const React = require('react');
|
||||
const { useState, useEffect } = React;
|
||||
const _ = require('lodash');
|
||||
|
||||
const TagInput = ({ unique = true, values = [], ...props })=>{
|
||||
const [tempInputText, setTempInputText] = useState('');
|
||||
@@ -101,4 +102,4 @@ const TagInput = ({ unique = true, values = [], ...props })=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default TagInput;
|
||||
module.exports = TagInput;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
/* eslint-disable camelcase */
|
||||
import 'core-js/es/string/to-well-formed.js'; //Polyfill for older browsers
|
||||
import './homebrew.less';
|
||||
import React from 'react';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import request from 'superagent';
|
||||
import Nav from './nav.jsx';
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
const request = require('superagent');
|
||||
|
||||
const Account = createReactClass({
|
||||
const Account = createClass({
|
||||
displayName : 'AccountNavItem',
|
||||
getInitialState : function() {
|
||||
return {
|
||||
@@ -111,4 +111,4 @@ const Account = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default Account;
|
||||
module.exports = Account;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import './error-navitem.less';
|
||||
import React from 'react';
|
||||
import Nav from './nav.jsx';
|
||||
require('./error-navitem.less');
|
||||
const React = require('react');
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
|
||||
const ErrorNavItem = ({ error = '', clearError })=>{
|
||||
const response = error.response;
|
||||
@@ -144,4 +144,4 @@ const ErrorNavItem = ({ error = '', clearError })=>{
|
||||
</Nav.item>;
|
||||
};
|
||||
|
||||
export default ErrorNavItem;
|
||||
module.exports = ErrorNavItem;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import dedent from 'dedent';
|
||||
const React = require('react');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
import Nav from './nav.jsx';
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
|
||||
export default function(props){
|
||||
module.exports = function(props){
|
||||
return <Nav.dropdown>
|
||||
<Nav.item color='grey' icon='fas fa-question-circle'>
|
||||
need help?
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import Moment from 'moment';
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const Moment = require('moment');
|
||||
|
||||
import Nav from './nav.jsx';
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
|
||||
|
||||
const MetadataNav = createReactClass({
|
||||
const MetadataNav = createClass({
|
||||
displayName : 'MetadataNav',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
@@ -86,4 +86,4 @@ const MetadataNav = createReactClass({
|
||||
|
||||
});
|
||||
|
||||
export default MetadataNav;
|
||||
module.exports = MetadataNav;
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import './navbar.less';
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import _ from 'lodash';
|
||||
import cx from 'classnames';
|
||||
require('client/homebrew/navbar/navbar.less');
|
||||
const React = require('react');
|
||||
const { useState, useRef, useEffect } = React;
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
const cx = require('classnames');
|
||||
|
||||
import NaturalCritIcon from '../../components/svg/naturalcrit-d20.svg.jsx';
|
||||
const NaturalCritIcon = require('client/components/svg/naturalcrit-d20.svg.jsx');
|
||||
|
||||
const Nav = {
|
||||
base : createReactClass({
|
||||
base : createClass({
|
||||
displayName : 'Nav.base',
|
||||
render : function(){
|
||||
return <nav>
|
||||
@@ -24,7 +25,7 @@ const Nav = {
|
||||
</a>;
|
||||
},
|
||||
|
||||
section : createReactClass({
|
||||
section : createClass({
|
||||
displayName : 'Nav.section',
|
||||
render : function(){
|
||||
return <div className={`navSection ${this.props.className ?? ''}`}>
|
||||
@@ -33,7 +34,7 @@ const Nav = {
|
||||
}
|
||||
}),
|
||||
|
||||
item : createReactClass({
|
||||
item : createClass({
|
||||
displayName : 'Nav.item',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
@@ -116,4 +117,4 @@ const Nav = {
|
||||
};
|
||||
|
||||
|
||||
export default Nav;
|
||||
module.exports = Nav;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import './navbar.less';
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
require('./navbar.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
|
||||
import Nav from './nav.jsx';
|
||||
import PatreonNavItem from './patreon.navitem.jsx';
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
const PatreonNavItem = require('./patreon.navitem.jsx');
|
||||
|
||||
const Navbar = createReactClass({
|
||||
const Navbar = createClass({
|
||||
displayName : 'Navbar',
|
||||
getInitialState : function() {
|
||||
return {
|
||||
@@ -49,4 +49,4 @@ const Navbar = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default Navbar;
|
||||
module.exports = Navbar;
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
import Nav from './nav.jsx';
|
||||
import { splitTextStyleAndMetadata } from '../../../shared/helpers.js';
|
||||
const React = require('react');
|
||||
const _ = require('lodash');
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
const { splitTextStyleAndMetadata } = require('../../../shared/helpers.js'); // Importing the function from helpers.js
|
||||
|
||||
const BREWKEY = 'HB_newPage_content';
|
||||
const STYLEKEY = 'HB_newPage_style';
|
||||
const METAKEY = 'HB_newPage_meta';
|
||||
const BREWKEY = 'homebrewery-new';
|
||||
const STYLEKEY = 'homebrewery-new-style';
|
||||
const METAKEY = 'homebrewery-new-meta';
|
||||
|
||||
const NewBrew = ()=>{
|
||||
const handleFileChange = (e)=>{
|
||||
const file = e.target.files[0];
|
||||
if(!file) return;
|
||||
|
||||
if(!confirmLocalStorageChange()) return;
|
||||
const currentNew = localStorage.getItem(BREWKEY);
|
||||
if(currentNew && !confirm(
|
||||
`You have some text in the new brew space, if you load a file that text will be lost, are you sure you want to load the file?`
|
||||
)) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e)=>{
|
||||
@@ -34,35 +37,12 @@ const NewBrew = ()=>{
|
||||
|
||||
alert(`This file is invalid: ${!type ? 'Missing file extension' :`.${type} files are not supported`}. Only .txt files exported from the Homebrewery are allowed.`);
|
||||
|
||||
|
||||
console.log(file);
|
||||
};
|
||||
reader.readAsText(file);
|
||||
};
|
||||
|
||||
const confirmLocalStorageChange = ()=>{
|
||||
const currentText = localStorage.getItem(BREWKEY);
|
||||
const currentStyle = localStorage.getItem(STYLEKEY);
|
||||
const currentMeta = localStorage.getItem(METAKEY);
|
||||
|
||||
// TRUE if no data in any local storage key
|
||||
// TRUE if data in any local storage key AND approval given
|
||||
// FALSE if data in any local storage key AND approval declined
|
||||
return (!(currentText || currentStyle || currentMeta) || confirm(
|
||||
`You have made changes in the new brew space. If you continue, that information will be PERMANENTLY LOST.\nAre you sure you wish to continue?`
|
||||
));
|
||||
};
|
||||
|
||||
const clearLocalStorage = ()=>{
|
||||
if(!confirmLocalStorageChange()) return;
|
||||
|
||||
localStorage.removeItem(BREWKEY);
|
||||
localStorage.removeItem(STYLEKEY);
|
||||
localStorage.removeItem(METAKEY);
|
||||
|
||||
window.location.href = '/new';
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<Nav.dropdown>
|
||||
@@ -70,34 +50,27 @@ const NewBrew = ()=>{
|
||||
className='new'
|
||||
color='purple'
|
||||
icon='fa-solid fa-plus-square'>
|
||||
new
|
||||
new
|
||||
</Nav.item>
|
||||
<Nav.item
|
||||
className='new'
|
||||
className='fromBlank'
|
||||
href='/new'
|
||||
newTab={true}
|
||||
color='purple'
|
||||
icon='fa-solid fa-file'>
|
||||
resume draft
|
||||
</Nav.item>
|
||||
<Nav.item
|
||||
className='fromBlank'
|
||||
newTab={true}
|
||||
color='yellow'
|
||||
icon='fa-solid fa-file-circle-plus'
|
||||
onClick={()=>{ clearLocalStorage(); }}>
|
||||
from blank
|
||||
from blank
|
||||
</Nav.item>
|
||||
|
||||
<Nav.item
|
||||
className='fromFile'
|
||||
color='green'
|
||||
color='purple'
|
||||
icon='fa-solid fa-upload'
|
||||
onClick={()=>{ document.getElementById('uploadTxt').click(); }}>
|
||||
<input id='uploadTxt' className='newFromLocal' type='file' onChange={handleFileChange} style={{ display: 'none' }} />
|
||||
from file
|
||||
from file
|
||||
</Nav.item>
|
||||
</Nav.dropdown>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewBrew;
|
||||
module.exports = NewBrew;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import Nav from './nav.jsx';
|
||||
const React = require('react');
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
|
||||
export default function(props){
|
||||
module.exports = function(props){
|
||||
return <Nav.item
|
||||
className='patreon'
|
||||
newTab={true}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import Nav from './nav.jsx';
|
||||
import { printCurrentBrew } from '../../../shared/helpers.js';
|
||||
const React = require('react');
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
const { printCurrentBrew } = require('../../../shared/helpers.js');
|
||||
|
||||
export default function(){
|
||||
module.exports = function(){
|
||||
return <Nav.item onClick={printCurrentBrew} color='purple' icon='far fa-file-pdf'>
|
||||
get PDF
|
||||
</Nav.item>;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import _ from 'lodash';
|
||||
import Moment from 'moment';
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
const Moment = require('moment');
|
||||
|
||||
import Nav from './nav.jsx';
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
|
||||
const EDIT_KEY = 'HB_nav_recentlyEdited';
|
||||
const VIEW_KEY = 'HB_nav_recentlyViewed';
|
||||
|
||||
|
||||
const RecentItems = createReactClass({
|
||||
const RecentItems = createClass({
|
||||
DisplayName : 'RecentItems',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
@@ -175,7 +175,7 @@ const RecentItems = createReactClass({
|
||||
|
||||
});
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
|
||||
edited : (props)=>{
|
||||
return <RecentItems
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import dedent from 'dedent';
|
||||
import Nav from './nav.jsx';
|
||||
import dedent from 'dedent-tabs';
|
||||
import Nav from 'client/homebrew/navbar/nav.jsx';
|
||||
|
||||
const getShareId = (brew)=>(
|
||||
brew.googleId && !brew.stubbed
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
const React = require('react');
|
||||
|
||||
import Nav from './nav.jsx';
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
|
||||
export default function (props) {
|
||||
module.exports = function (props) {
|
||||
return (
|
||||
<Nav.item
|
||||
color='purple'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import UIPage from '../basePages/uiPage/uiPage.jsx';
|
||||
import NaturalCritIcon from '../../../components/svg/naturalcrit-d20.svg.jsx';
|
||||
const React = require('react');
|
||||
const moment = require('moment');
|
||||
const UIPage = require('../basePages/uiPage/uiPage.jsx');
|
||||
const NaturalCritIcon = require('client/components/svg/naturalcrit-d20.svg.jsx');
|
||||
|
||||
let SAVEKEY = '';
|
||||
|
||||
@@ -79,4 +79,4 @@ const AccountPage = (props)=>{
|
||||
</UIPage>);
|
||||
};
|
||||
|
||||
export default AccountPage;
|
||||
module.exports = AccountPage;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import './brewItem.less';
|
||||
import React, { useCallback } from 'react';
|
||||
import moment from 'moment';
|
||||
require('./brewItem.less');
|
||||
const React = require('react');
|
||||
const { useCallback } = React;
|
||||
const moment = require('moment');
|
||||
import request from '../../../../utils/request-middleware.js';
|
||||
|
||||
import googleDriveIcon from '../../../../googleDrive.svg';
|
||||
import homebreweryIcon from '../../../../thumbnail.svg';
|
||||
import dedent from 'dedent';
|
||||
const googleDriveIcon = require('../../../../googleDrive.svg');
|
||||
const homebreweryIcon = require('../../../../thumbnail.svg');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
const BrewItem = ({
|
||||
brew = {
|
||||
@@ -175,4 +176,4 @@ const BrewItem = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default BrewItem;
|
||||
module.exports = BrewItem;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/
|
||||
import './listPage.less';
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
require('./listPage.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
const moment = require('moment');
|
||||
|
||||
import BrewItem from './brewItem/brewItem.jsx';
|
||||
const BrewItem = require('./brewItem/brewItem.jsx');
|
||||
|
||||
const USERPAGE_SORT_DIR = 'HB_listPage_sortDir';
|
||||
const USERPAGE_SORT_TYPE = 'HB_listPage_sortType';
|
||||
@@ -14,7 +14,7 @@ const USERPAGE_GROUP_VISIBILITY_PREFIX = 'HB_listPage_visibility_group';
|
||||
const DEFAULT_SORT_TYPE = 'alpha';
|
||||
const DEFAULT_SORT_DIR = 'asc';
|
||||
|
||||
const ListPage = createReactClass({
|
||||
const ListPage = createClass({
|
||||
displayName : 'ListPage',
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
@@ -279,4 +279,4 @@ const ListPage = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default ListPage;
|
||||
module.exports = ListPage;
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import './uiPage.less';
|
||||
import React from 'react';
|
||||
import createReactClass from 'create-react-class';
|
||||
require('./uiPage.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
|
||||
import Nav from '../../../navbar/nav.jsx';
|
||||
import Navbar from '../../../navbar/navbar.jsx';
|
||||
import NewBrewItem from '../../../navbar/newbrew.navitem.jsx';
|
||||
import HelpNavItem from '../../../navbar/help.navitem.jsx';
|
||||
import RecentNavItems from '../../../navbar/recent.navitem.jsx';
|
||||
const { both: RecentNavItem } = RecentNavItems;
|
||||
import Account from '../../../navbar/account.navitem.jsx';
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
const Navbar = require('client/homebrew/navbar/navbar.jsx');
|
||||
const NewBrewItem = require('client/homebrew/navbar/newbrew.navitem.jsx');
|
||||
const HelpNavItem = require('client/homebrew/navbar/help.navitem.jsx');
|
||||
const RecentNavItem = require('client/homebrew/navbar/recent.navitem.jsx').both;
|
||||
const Account = require('client/homebrew/navbar/account.navitem.jsx');
|
||||
|
||||
|
||||
const UIPage = createReactClass({
|
||||
const UIPage = createClass({
|
||||
displayName : 'UIPage',
|
||||
|
||||
render : function(){
|
||||
@@ -36,4 +35,4 @@ const UIPage = createReactClass({
|
||||
}
|
||||
});
|
||||
|
||||
export default UIPage;
|
||||
module.exports = UIPage;
|
||||
|
||||
@@ -4,26 +4,25 @@ import './editPage.less';
|
||||
// Common imports
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import request from '../../utils/request-middleware.js';
|
||||
import Markdown from '../../../../shared/markdown.js';
|
||||
import Markdown from 'markdown.js';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { DEFAULT_BREW_LOAD } from '../../../../server/brewDefaults.js';
|
||||
import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '../../../../shared/helpers.js';
|
||||
|
||||
import SplitPane from '../../../components/splitPane/splitPane.jsx';
|
||||
import SplitPane from 'client/components/splitPane/splitPane.jsx';
|
||||
import Editor from '../../editor/editor.jsx';
|
||||
import BrewRenderer from '../../brewRenderer/brewRenderer.jsx';
|
||||
|
||||
import Nav from '../../navbar/nav.jsx';
|
||||
import Navbar from '../../navbar/navbar.jsx';
|
||||
import NewBrewItem from '../../navbar/newbrew.navitem.jsx';
|
||||
import AccountNavItem from '../../navbar/account.navitem.jsx';
|
||||
import ErrorNavItem from '../../navbar/error-navitem.jsx';
|
||||
import HelpNavItem from '../../navbar/help.navitem.jsx';
|
||||
import VaultNavItem from '../../navbar/vault.navitem.jsx';
|
||||
import PrintNavItem from '../../navbar/print.navitem.jsx';
|
||||
import RecentNavItems from '../../navbar/recent.navitem.jsx';
|
||||
const { both: RecentNavItem } = RecentNavItems;
|
||||
import Nav from 'client/homebrew/navbar/nav.jsx';
|
||||
import Navbar from 'client/homebrew/navbar/navbar.jsx';
|
||||
import NewBrewItem from 'client/homebrew/navbar/newbrew.navitem.jsx';
|
||||
import AccountNavItem from 'client/homebrew/navbar/account.navitem.jsx';
|
||||
import ErrorNavItem from 'client/homebrew/navbar/error-navitem.jsx';
|
||||
import HelpNavItem from 'client/homebrew/navbar/help.navitem.jsx';
|
||||
import VaultNavItem from 'client/homebrew/navbar/vault.navitem.jsx';
|
||||
import PrintNavItem from 'client/homebrew/navbar/print.navitem.jsx';
|
||||
import { both as RecentNavItem } from 'client/homebrew/navbar/recent.navitem.jsx';
|
||||
|
||||
// Page specific imports
|
||||
import { Meta } from 'vitreum/headtags';
|
||||
@@ -31,7 +30,7 @@ import { md5 } from 'hash-wasm';
|
||||
import { gzipSync, strToU8 } from 'fflate';
|
||||
import { makePatches, stringifyPatches } from '@sanity/diff-match-patch';
|
||||
|
||||
import ShareNavItem from '../../navbar/share.navitem.jsx';
|
||||
import ShareNavItem from 'client/homebrew/navbar/share.navitem.jsx';
|
||||
import LockNotification from './lockNotification/lockNotification.jsx';
|
||||
import { updateHistory, versionHistoryGarbageCollection } from '../../utils/versionHistory.js';
|
||||
import googleDriveIcon from '../../googleDrive.svg';
|
||||
@@ -217,7 +216,7 @@ const EditPage = (props)=>{
|
||||
text : brew.text.normalize('NFC'),
|
||||
pageCount : ((brew.renderer === 'legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^\\page$/gm)) || []).length + 1,
|
||||
patches : stringifyPatches(makePatches(encodeURI(lastSavedBrew.current.text.normalize('NFC')), encodeURI(brew.text.normalize('NFC')))),
|
||||
hash : await md5(lastSavedBrew.current.text.normalize('NFC')),
|
||||
hash : await md5(lastSavedBrew.current.text),
|
||||
textBin : undefined,
|
||||
version : lastSavedBrew.current.version
|
||||
};
|
||||
@@ -416,4 +415,4 @@ const EditPage = (props)=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default EditPage;
|
||||
module.exports = EditPage;
|
||||
|
||||
@@ -40,4 +40,4 @@ function LockNotification(props) {
|
||||
</Dialog>;
|
||||
};
|
||||
|
||||
export default LockNotification;
|
||||
module.exports = LockNotification;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import './errorPage.less';
|
||||
import React from 'react';
|
||||
import UIPage from '../basePages/uiPage/uiPage.jsx';
|
||||
import Markdown from '../../../../shared/markdown.js';
|
||||
import ErrorIndex from './errors/errorIndex.js';
|
||||
require('./errorPage.less');
|
||||
const React = require('react');
|
||||
const UIPage = require('../basePages/uiPage/uiPage.jsx');
|
||||
import Markdown from '../../../../shared/markdown.js';
|
||||
const ErrorIndex = require('./errors/errorIndex.js');
|
||||
|
||||
const ErrorPage = ({ brew })=>{
|
||||
// Retrieving the error text based on the brew's error code from ErrorIndex
|
||||
@@ -22,4 +22,4 @@ const ErrorPage = ({ brew })=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default ErrorPage;
|
||||
module.exports = ErrorPage;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import dedent from 'dedent';
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
const loginUrl = 'https://www.naturalcrit.com/login';
|
||||
|
||||
@@ -268,4 +268,4 @@ const errorIndex = (props)=>{
|
||||
};
|
||||
};
|
||||
|
||||
export default errorIndex;
|
||||
module.exports = errorIndex;
|
||||
|
||||
@@ -4,27 +4,25 @@ import './homePage.less';
|
||||
// Common imports
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import request from '../../utils/request-middleware.js';
|
||||
import Markdown from '../../../../shared/markdown.js';
|
||||
import Markdown from 'markdown.js';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { DEFAULT_BREW } from '../../../../server/brewDefaults.js';
|
||||
import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '../../../../shared/helpers.js';
|
||||
|
||||
import SplitPane from '../../../components/splitPane/splitPane.jsx';
|
||||
import SplitPane from 'client/components/splitPane/splitPane.jsx';
|
||||
import Editor from '../../editor/editor.jsx';
|
||||
import BrewRenderer from '../../brewRenderer/brewRenderer.jsx';
|
||||
|
||||
import Nav from '../../navbar/nav.jsx';
|
||||
import Navbar from '../../navbar/navbar.jsx';
|
||||
import NewBrewItem from '../../navbar/newbrew.navitem.jsx';
|
||||
import AccountNavItem from '../../navbar/account.navitem.jsx';
|
||||
import ErrorNavItem from '../../navbar/error-navitem.jsx';
|
||||
import HelpNavItem from '../../navbar/help.navitem.jsx';
|
||||
import VaultNavItem from '../../navbar/vault.navitem.jsx';
|
||||
import PrintNavItem from '../../navbar/print.navitem.jsx';
|
||||
import RecentNavItems from '../../navbar/recent.navitem.jsx';
|
||||
const { both: RecentNavItem } = RecentNavItems;
|
||||
|
||||
import Nav from 'client/homebrew/navbar/nav.jsx';
|
||||
import Navbar from 'client/homebrew/navbar/navbar.jsx';
|
||||
import NewBrewItem from 'client/homebrew/navbar/newbrew.navitem.jsx';
|
||||
import AccountNavItem from 'client/homebrew/navbar/account.navitem.jsx';
|
||||
import ErrorNavItem from 'client/homebrew/navbar/error-navitem.jsx';
|
||||
import HelpNavItem from 'client/homebrew/navbar/help.navitem.jsx';
|
||||
import VaultNavItem from 'client/homebrew/navbar/vault.navitem.jsx';
|
||||
import PrintNavItem from 'client/homebrew/navbar/print.navitem.jsx';
|
||||
import { both as RecentNavItem } from 'client/homebrew/navbar/recent.navitem.jsx';
|
||||
|
||||
// Page specific imports
|
||||
import { Meta } from 'vitreum/headtags';
|
||||
@@ -232,4 +230,4 @@ const HomePage =(props)=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default HomePage;
|
||||
module.exports = HomePage;
|
||||
|
||||
@@ -4,26 +4,25 @@ import './newPage.less';
|
||||
// Common imports
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import request from '../../utils/request-middleware.js';
|
||||
import Markdown from '../../../../shared/markdown.js';
|
||||
import Markdown from 'markdown.js';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { DEFAULT_BREW } from '../../../../server/brewDefaults.js';
|
||||
import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '../../../../shared/helpers.js';
|
||||
|
||||
import SplitPane from '../../../components/splitPane/splitPane.jsx';
|
||||
import SplitPane from 'client/components/splitPane/splitPane.jsx';
|
||||
import Editor from '../../editor/editor.jsx';
|
||||
import BrewRenderer from '../../brewRenderer/brewRenderer.jsx';
|
||||
|
||||
import Nav from '../../navbar/nav.jsx';
|
||||
import Navbar from '../../navbar/navbar.jsx';
|
||||
import NewBrewItem from '../../navbar/newbrew.navitem.jsx';
|
||||
import AccountNavItem from '../../navbar/account.navitem.jsx';
|
||||
import ErrorNavItem from '../../navbar/error-navitem.jsx';
|
||||
import HelpNavItem from '../../navbar/help.navitem.jsx';
|
||||
import VaultNavItem from '../../navbar/vault.navitem.jsx';
|
||||
import PrintNavItem from '../../navbar/print.navitem.jsx';
|
||||
import RecentNavItems from '../../navbar/recent.navitem.jsx';
|
||||
const { both: RecentNavItem } = RecentNavItems;
|
||||
import Nav from 'client/homebrew/navbar/nav.jsx';
|
||||
import Navbar from 'client/homebrew/navbar/navbar.jsx';
|
||||
import NewBrewItem from 'client/homebrew/navbar/newbrew.navitem.jsx';
|
||||
import AccountNavItem from 'client/homebrew/navbar/account.navitem.jsx';
|
||||
import ErrorNavItem from 'client/homebrew/navbar/error-navitem.jsx';
|
||||
import HelpNavItem from 'client/homebrew/navbar/help.navitem.jsx';
|
||||
import VaultNavItem from 'client/homebrew/navbar/vault.navitem.jsx';
|
||||
import PrintNavItem from 'client/homebrew/navbar/print.navitem.jsx';
|
||||
import { both as RecentNavItem } from 'client/homebrew/navbar/recent.navitem.jsx';
|
||||
|
||||
// Page specific imports
|
||||
import { Meta } from 'vitreum/headtags';
|
||||
@@ -277,4 +276,4 @@ const NewPage = (props)=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default NewPage;
|
||||
module.exports = NewPage;
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
.newPage {
|
||||
.navItem.save {
|
||||
.fadeInRight();
|
||||
.transition(opacity);
|
||||
background-color : @orange;
|
||||
transition:all 0.2s;
|
||||
&:hover { background-color : @green; }
|
||||
|
||||
&.neverSaved {
|
||||
translate:-100%;
|
||||
.fadeOutRight();
|
||||
opacity: 0;
|
||||
background-color :#333;
|
||||
cursor:auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import './sharePage.less';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { Meta } from 'vitreum/headtags';
|
||||
require('./sharePage.less');
|
||||
const React = require('react');
|
||||
const { useState, useEffect, useCallback } = React;
|
||||
const { Meta } = require('vitreum/headtags');
|
||||
|
||||
import Nav from '../../navbar/nav.jsx';
|
||||
import Navbar from '../../navbar/navbar.jsx';
|
||||
import MetadataNav from '../../navbar/metadata.navitem.jsx';
|
||||
import PrintNavItem from '../../navbar/print.navitem.jsx';
|
||||
import RecentNavItems from '../../navbar/recent.navitem.jsx';
|
||||
const { both: RecentNavItem } = RecentNavItems;
|
||||
import Account from '../../navbar/account.navitem.jsx';
|
||||
import BrewRenderer from '../../brewRenderer/brewRenderer.jsx';
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
const Navbar = require('client/homebrew/navbar/navbar.jsx');
|
||||
const MetadataNav = require('client/homebrew/navbar/metadata.navitem.jsx');
|
||||
const PrintNavItem = require('client/homebrew/navbar/print.navitem.jsx');
|
||||
const RecentNavItem = require('client/homebrew/navbar/recent.navitem.jsx').both;
|
||||
const Account = require('client/homebrew/navbar/account.navitem.jsx');
|
||||
const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
|
||||
|
||||
import { DEFAULT_BREW_LOAD } from '../../../../server/brewDefaults.js';
|
||||
import { printCurrentBrew, fetchThemeBundle } from '../../../../shared/helpers.js';
|
||||
const { DEFAULT_BREW_LOAD } = require('../../../../server/brewDefaults.js');
|
||||
const { printCurrentBrew, fetchThemeBundle } = require('../../../../shared/helpers.js');
|
||||
|
||||
const SharePage = (props)=>{
|
||||
const { brew = DEFAULT_BREW_LOAD, disableMeta = false } = props;
|
||||
@@ -116,4 +116,4 @@ const SharePage = (props)=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default SharePage;
|
||||
module.exports = SharePage;
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import React, { useState } from 'react';
|
||||
import _ from 'lodash';
|
||||
const React = require('react');
|
||||
const { useState } = React;
|
||||
const _ = require('lodash');
|
||||
|
||||
import ListPage from '../basePages/listPage/listPage.jsx';
|
||||
const ListPage = require('../basePages/listPage/listPage.jsx');
|
||||
|
||||
import Nav from '../../navbar/nav.jsx';
|
||||
import Navbar from '../../navbar/navbar.jsx';
|
||||
import RecentNavItems from '../../navbar/recent.navitem.jsx';
|
||||
const { both: RecentNavItem } = RecentNavItems;
|
||||
import Account from '../../navbar/account.navitem.jsx';
|
||||
import NewBrew from '../../navbar/newbrew.navitem.jsx';
|
||||
import HelpNavItem from '../../navbar/help.navitem.jsx';
|
||||
import ErrorNavItem from '../../navbar/error-navitem.jsx';
|
||||
import VaultNavitem from '../../navbar/vault.navitem.jsx';
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
const Navbar = require('client/homebrew/navbar/navbar.jsx');
|
||||
const RecentNavItem = require('client/homebrew/navbar/recent.navitem.jsx').both;
|
||||
const Account = require('client/homebrew/navbar/account.navitem.jsx');
|
||||
const NewBrew = require('client/homebrew/navbar/newbrew.navitem.jsx');
|
||||
const HelpNavItem = require('client/homebrew/navbar/help.navitem.jsx');
|
||||
const ErrorNavItem = require('client/homebrew/navbar/error-navitem.jsx');
|
||||
const VaultNavitem = require('client/homebrew/navbar/vault.navitem.jsx');
|
||||
|
||||
const UserPage = (props)=>{
|
||||
props = {
|
||||
@@ -61,4 +61,4 @@ const UserPage = (props)=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default UserPage;
|
||||
module.exports = UserPage;
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
/*eslint max-lines: ["warn", {"max": 400, "skipBlankLines": true, "skipComments": true}]*/
|
||||
/*eslint max-params:["warn", { max: 10 }], */
|
||||
import './vaultPage.less';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
require('./vaultPage.less');
|
||||
|
||||
import Nav from '../../navbar/nav.jsx';
|
||||
import Navbar from '../../navbar/navbar.jsx';
|
||||
import RecentNavItems from '../../navbar/recent.navitem.jsx';
|
||||
const { both: RecentNavItem } = RecentNavItems;
|
||||
import Account from '../../navbar/account.navitem.jsx';
|
||||
import NewBrew from '../../navbar/newbrew.navitem.jsx';
|
||||
import HelpNavItem from '../../navbar/help.navitem.jsx';
|
||||
import BrewItem from '../basePages/listPage/brewItem/brewItem.jsx';
|
||||
import SplitPane from '../../../components/splitPane/splitPane.jsx';
|
||||
import ErrorIndex from '../errorPage/errors/errorIndex.js';
|
||||
const React = require('react');
|
||||
const { useState, useEffect, useRef } = React;
|
||||
|
||||
const Nav = require('client/homebrew/navbar/nav.jsx');
|
||||
const Navbar = require('client/homebrew/navbar/navbar.jsx');
|
||||
const RecentNavItem = require('client/homebrew/navbar/recent.navitem.jsx').both;
|
||||
const Account = require('client/homebrew/navbar/account.navitem.jsx');
|
||||
const NewBrew = require('client/homebrew/navbar/newbrew.navitem.jsx');
|
||||
const HelpNavItem = require('client/homebrew/navbar/help.navitem.jsx');
|
||||
const BrewItem = require('../basePages/listPage/brewItem/brewItem.jsx');
|
||||
const SplitPane = require('client/components/splitPane/splitPane.jsx');
|
||||
const ErrorIndex = require('../errorPage/errors/errorIndex.js');
|
||||
|
||||
import request from '../../utils/request-middleware.js';
|
||||
|
||||
@@ -100,7 +101,7 @@ const VaultPage = (props)=>{
|
||||
|
||||
const title = titleRef.current.value || '';
|
||||
const author = authorRef.current.value || '';
|
||||
const count = countRef.current.value || 20;
|
||||
const count = countRef.current.value || 10;
|
||||
const v3 = v3Ref.current.checked != false;
|
||||
const legacy = legacyRef.current.checked != false;
|
||||
const sortOption = sort || 'title';
|
||||
@@ -287,8 +288,7 @@ const VaultPage = (props)=>{
|
||||
const renderPaginationControls = ()=>{
|
||||
if(!totalBrews || totalBrews < 10) return null;
|
||||
|
||||
|
||||
const countInt = parseInt(countRef.current.value || 20);
|
||||
const countInt = parseInt(brewCollection.length || 20);
|
||||
const totalPages = Math.ceil(totalBrews / countInt);
|
||||
|
||||
let startPage, endPage;
|
||||
@@ -429,4 +429,4 @@ const VaultPage = (props)=>{
|
||||
);
|
||||
};
|
||||
|
||||
export default VaultPage;
|
||||
module.exports = VaultPage;
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
"local_environments" : ["docker", "local"],
|
||||
"publicUrl" : "https://homebrewery.naturalcrit.com",
|
||||
"hb_images" : null,
|
||||
"hb_fonts" : null
|
||||
"hb_fonts" : null,
|
||||
"enable_CM6" : true
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ export default [{
|
||||
"max-depth" : ["warn", { max: 4 }],
|
||||
"max-params" : ["warn", { max: 5 }],
|
||||
"no-restricted-syntax" : ["warn", "ClassDeclaration", "SwitchStatement"],
|
||||
"no-unused-vars" : ["warn", { vars: "all", args: "none", varsIgnorePattern: "config|_|cx|createReactClass" }],
|
||||
"no-unused-vars" : ["warn", { vars: "all", args: "none", varsIgnorePattern: "config|_|cx|createClass" }],
|
||||
"react/jsx-uses-vars" : "warn",
|
||||
|
||||
/** Fixable **/
|
||||
|
||||
3281
package-lock.json
generated
3281
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
49
package.json
49
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "homebrewery",
|
||||
"description": "Create authentic looking D&D homebrews using only markdown",
|
||||
"version": "3.20.1",
|
||||
"version": "3.20.0",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"npm": "^10.8.x",
|
||||
@@ -61,11 +61,8 @@
|
||||
"server"
|
||||
],
|
||||
"transformIgnorePatterns": [
|
||||
"node_modules/(?!(nanoid|@exodus/bytes|parse5)/)"
|
||||
"node_modules/(?!nanoid/).*"
|
||||
],
|
||||
"transform": {
|
||||
"^.+\\.js$": "babel-jest"
|
||||
},
|
||||
"coveragePathIgnorePatterns": [
|
||||
"build/*"
|
||||
],
|
||||
@@ -91,19 +88,35 @@
|
||||
"@babel/core": "^7.28.4",
|
||||
"@babel/plugin-transform-runtime": "^7.28.3",
|
||||
"@babel/preset-env": "^7.28.3",
|
||||
"@babel/preset-react": "^7.28.5",
|
||||
"@babel/preset-react": "^7.27.1",
|
||||
"@babel/runtime": "^7.28.4",
|
||||
"@dmsnell/diff-match-patch": "^1.1.0",
|
||||
"@googleapis/drive": "^19.2.0",
|
||||
"@googleapis/drive": "^18.0.0",
|
||||
"@sanity/diff-match-patch": "^3.2.0",
|
||||
"body-parser": "^2.2.0",
|
||||
"classnames": "^2.5.1",
|
||||
"codemirror": "^5.65.6",
|
||||
"@codemirror/autocomplete": "^6.18.2",
|
||||
"@codemirror/commands": "^6.7.2",
|
||||
"@codemirror/fold": "^6.7.1",
|
||||
"@codemirror/history": "^6.3.0",
|
||||
"@codemirror/lang-css": "^6.3.0",
|
||||
"@codemirror/lang-html": "^6.4.7",
|
||||
"@codemirror/lang-javascript": "^6.2.2",
|
||||
"@codemirror/lang-markdown": "^6.2.3",
|
||||
"@codemirror/language": "^6.10.2",
|
||||
"@codemirror/lint": "^6.8.0",
|
||||
"@codemirror/search": "^6.5.6",
|
||||
"@codemirror/state": "^6.4.1",
|
||||
"@codemirror/view": "^6.27.0",
|
||||
"@lezer/common": "^1.2.1",
|
||||
"@lezer/highlight": "^1.2.0",
|
||||
"codemirror": "^6.0.1",
|
||||
"codemirror5": "npm:codemirror@^5.65.19",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"core-js": "^3.47.0",
|
||||
"core-js": "^3.46.0",
|
||||
"cors": "^2.8.5",
|
||||
"create-react-class": "^15.7.0",
|
||||
"dedent": "^1.7.1",
|
||||
"dedent-tabs": "^0.10.3",
|
||||
"expr-eval": "^2.0.2",
|
||||
"express": "^5.1.0",
|
||||
"express-async-handler": "^1.2.0",
|
||||
@@ -112,29 +125,29 @@
|
||||
"fs-extra": "11.3.2",
|
||||
"hash-wasm": "^4.12.0",
|
||||
"idb-keyval": "^6.2.2",
|
||||
"js-yaml": "^4.1.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"jwt-simple": "^0.5.6",
|
||||
"less": "^3.13.1",
|
||||
"lodash": "^4.17.21",
|
||||
"marked": "15.0.12",
|
||||
"marked-alignment-paragraphs": "^1.0.0",
|
||||
"marked-definition-lists": "^1.0.1",
|
||||
"marked-emoji": "^2.0.2",
|
||||
"marked-emoji": "^2.0.1",
|
||||
"marked-extended-tables": "^2.0.1",
|
||||
"marked-gfm-heading-id": "^4.1.3",
|
||||
"marked-gfm-heading-id": "^4.1.2",
|
||||
"marked-nonbreaking-spaces": "^1.0.1",
|
||||
"marked-smartypants-lite": "^1.0.3",
|
||||
"marked-subsuper-text": "^1.0.4",
|
||||
"marked-variables": "^1.0.4",
|
||||
"markedLegacy": "npm:marked@^0.3.19",
|
||||
"moment": "^2.30.1",
|
||||
"mongoose": "^8.20.0",
|
||||
"mongoose": "^8.19.1",
|
||||
"nanoid": "5.1.6",
|
||||
"nconf": "^0.13.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-frame-component": "^4.1.3",
|
||||
"react-router": "^7.9.6",
|
||||
"react-router": "^7.9.4",
|
||||
"romans": "^3.1.0",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"superagent": "^10.2.1",
|
||||
@@ -143,15 +156,13 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@stylistic/stylelint-plugin": "^4.0.0",
|
||||
"babel-jest": "^30.2.0",
|
||||
"babel-plugin-transform-import-meta": "^2.3.3",
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-plugin-jest": "^29.1.0",
|
||||
"eslint": "^9.37.0",
|
||||
"eslint-plugin-jest": "^29.0.1",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"globals": "^16.4.0",
|
||||
"jest": "^30.2.0",
|
||||
"jest-expect-message": "^1.1.3",
|
||||
"jsdom": "^27.4.0",
|
||||
"jsdom-global": "^3.0.2",
|
||||
"postcss-less": "^6.0.0",
|
||||
"stylelint": "^16.25.0",
|
||||
|
||||
@@ -8,24 +8,24 @@
|
||||
"create-react-class",
|
||||
"lodash",
|
||||
"classnames",
|
||||
"codemirror",
|
||||
"codemirror/mode/gfm/gfm.js",
|
||||
"codemirror/mode/css/css.js",
|
||||
"codemirror/mode/javascript/javascript.js",
|
||||
"codemirror/addon/fold/foldcode.js",
|
||||
"codemirror/addon/fold/foldgutter.js",
|
||||
"codemirror/addon/fold/xml-fold.js",
|
||||
"codemirror/addon/scroll/scrollpastend.js",
|
||||
"codemirror/addon/search/search.js",
|
||||
"codemirror/addon/search/searchcursor.js",
|
||||
"codemirror/addon/search/jump-to-line.js",
|
||||
"codemirror/addon/search/match-highlighter.js",
|
||||
"codemirror/addon/search/matchesonscrollbar.js",
|
||||
"codemirror/addon/dialog/dialog.js",
|
||||
"codemirror/addon/edit/closetag.js",
|
||||
"codemirror/addon/edit/trailingspace.js",
|
||||
"codemirror/addon/selection/active-line.js",
|
||||
"codemirror/addon/hint/show-hint.js",
|
||||
"codemirror5",
|
||||
"codemirror5/mode/gfm/gfm.js",
|
||||
"codemirror5/mode/css/css.js",
|
||||
"codemirror5/mode/javascript/javascript.js",
|
||||
"codemirror5/addon/fold/foldcode.js",
|
||||
"codemirror5/addon/fold/foldgutter.js",
|
||||
"codemirror5/addon/fold/xml-fold.js",
|
||||
"codemirror5/addon/scroll/scrollpastend.js",
|
||||
"codemirror5/addon/search/search.js",
|
||||
"codemirror5/addon/search/searchcursor.js",
|
||||
"codemirror5/addon/search/jump-to-line.js",
|
||||
"codemirror5/addon/search/match-highlighter.js",
|
||||
"codemirror5/addon/search/matchesonscrollbar.js",
|
||||
"codemirror5/addon/dialog/dialog.js",
|
||||
"codemirror5/addon/edit/closetag.js",
|
||||
"codemirror5/addon/edit/trailingspace.js",
|
||||
"codemirror5/addon/selection/active-line.js",
|
||||
"codemirror5/addon/hint/show-hint.js",
|
||||
"moment",
|
||||
"superagent",
|
||||
"@sanity/diff-match-patch",
|
||||
|
||||
@@ -554,7 +554,8 @@ const renderPage = async (req, res)=>{
|
||||
publicUrl : config.get('publicUrl') ?? '',
|
||||
baseUrl : `${req.protocol}://${req.get('host')}`,
|
||||
environment : nodeEnv,
|
||||
deployment : config.get('heroku_app_name') ?? ''
|
||||
deployment : config.get('heroku_app_name') ?? '',
|
||||
enable_CM6 : config.get('enable_CM6') ?? false
|
||||
};
|
||||
const props = {
|
||||
version : version,
|
||||
|
||||
@@ -6,7 +6,6 @@ import config from './config.js';
|
||||
|
||||
|
||||
let serviceAuth;
|
||||
let clientEmail;
|
||||
if(!config.get('service_account')){
|
||||
const reset = '\x1b[0m'; // Reset to default style
|
||||
const yellow = '\x1b[33m'; // yellow color
|
||||
@@ -16,10 +15,6 @@ if(!config.get('service_account')){
|
||||
JSON.parse(config.get('service_account')) :
|
||||
config.get('service_account');
|
||||
|
||||
if(keys?.client_email) {
|
||||
clientEmail = keys.client_email;
|
||||
}
|
||||
|
||||
try {
|
||||
serviceAuth = googleDrive.auth.fromJSON(keys);
|
||||
serviceAuth.scopes = ['https://www.googleapis.com/auth/drive'];
|
||||
@@ -232,30 +227,14 @@ const GoogleActions = {
|
||||
|
||||
if(!obj) return;
|
||||
|
||||
if(clientEmail) {
|
||||
await drive.permissions.create({
|
||||
resource : {
|
||||
type : 'user',
|
||||
emailAddress : clientEmail,
|
||||
role : 'writer'
|
||||
},
|
||||
fileId : obj.data.id,
|
||||
fields : 'id',
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error adding Service Account permissions on Google Drive file');
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
await drive.permissions.create({
|
||||
resource : { type : 'anyone',
|
||||
role : 'writer' },
|
||||
role : 'writer' },
|
||||
fileId : obj.data.id,
|
||||
fields : 'id',
|
||||
})
|
||||
.catch((err)=>{
|
||||
console.log('Error adding "Anyone" permissions on Google Drive file');
|
||||
console.log('Error updating permissions');
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ import MarkedAlignedParagraphs from 'marked-alignment-paragraphs';
|
||||
import MarkedNonbreakingSpaces from 'marked-nonbreaking-spaces';
|
||||
import MarkedSubSuperText from 'marked-subsuper-text';
|
||||
import { markedVariables,
|
||||
setMarkedVariablePage,
|
||||
setMarkedVariable,
|
||||
getMarkedVariable } from 'marked-variables';
|
||||
setMarkedVariablePage,
|
||||
setMarkedVariable,
|
||||
getMarkedVariable } from 'marked-variables';
|
||||
import { markedSmartypantsLite as MarkedSmartypantsLite } from 'marked-smartypants-lite';
|
||||
import { gfmHeadingId as MarkedGFMHeadingId, resetHeadings as MarkedGFMResetHeadingIDs } from 'marked-gfm-heading-id';
|
||||
import { markedEmoji as MarkedEmojis } from 'marked-emoji';
|
||||
@@ -31,12 +31,7 @@ renderer.html = function (token) {
|
||||
const openTag = html.substring(0, html.indexOf('>')+1);
|
||||
html = html.substring(html.indexOf('>')+1);
|
||||
html = html.substring(0, html.lastIndexOf('</div>'));
|
||||
|
||||
// Repeat the markdown processing for content inside the div, minus the preprocessing and postprocessing hooks which should only run once globally
|
||||
const opts = Marked.defaults;
|
||||
const tokens = Marked.lexer(html, opts);
|
||||
Marked.walkTokens(tokens, opts.walkTokens);
|
||||
return `${openTag} ${Marked.parser(tokens, opts)} </div>`;
|
||||
return `${openTag} ${Marked.parse(html)} </div>`;
|
||||
}
|
||||
return html;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import Markdown from 'markedLegacy';
|
||||
const _ = require('lodash');
|
||||
const Markdown = require('markedLegacy');
|
||||
const renderer = new Markdown.Renderer();
|
||||
|
||||
//Processes the markdown within an HTML block if it's just a class-wrapper
|
||||
@@ -103,7 +103,7 @@ const voidTags = new Set([
|
||||
]);
|
||||
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
marked : Markdown,
|
||||
render : (rawBrewText)=>{
|
||||
return Markdown(
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import globalJsdom from 'jsdom-global';
|
||||
globalJsdom();
|
||||
|
||||
|
||||
require('jsdom-global')();
|
||||
|
||||
import { safeHTML } from '../../client/homebrew/brewRenderer/safeHTML';
|
||||
|
||||
test('Exit if no document', function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Markdown from 'markdown.js';
|
||||
import dedent from 'dedent';
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
// Marked.js adds line returns after closing tags on some default tokens.
|
||||
// This removes those line returns for comparison sake.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable max-lines */
|
||||
|
||||
import dedent from 'dedent';
|
||||
const dedent = require('dedent-tabs').default;
|
||||
import Markdown from 'markdown.js';
|
||||
|
||||
// Marked.js adds line returns after closing tags on some default tokens.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable max-lines */
|
||||
|
||||
import dedent from 'dedent';
|
||||
const dedent = require('dedent-tabs').default;
|
||||
import Markdown from 'markdown.js';
|
||||
|
||||
// Marked.js adds line returns after closing tags on some default tokens.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/* eslint-disable max-lines */
|
||||
|
||||
import MagicGen from './snippets/magic.gen.js';
|
||||
import ClassTableGen from './snippets/classtable.gen.js';
|
||||
import MonsterBlockGen from './snippets/monsterblock.gen.js';
|
||||
import ClassFeatureGen from './snippets/classfeature.gen.js';
|
||||
import CoverPageGen from './snippets/coverpage.gen.js';
|
||||
import TableOfContentsGen from './snippets/tableOfContents.gen.js';
|
||||
import dedent from 'dedent';
|
||||
const MagicGen = require('./snippets/magic.gen.js');
|
||||
const ClassTableGen = require('./snippets/classtable.gen.js');
|
||||
const MonsterBlockGen = require('./snippets/monsterblock.gen.js');
|
||||
const ClassFeatureGen = require('./snippets/classfeature.gen.js');
|
||||
const CoverPageGen = require('./snippets/coverpage.gen.js');
|
||||
const TableOfContentsGen = require('./snippets/tableOfContents.gen.js');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
export default [
|
||||
module.exports = [
|
||||
|
||||
{
|
||||
groupName : 'Text Editor',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
const _ = require('lodash');
|
||||
|
||||
export default function(classname){
|
||||
module.exports = function(classname){
|
||||
|
||||
classname = _.sample(['archivist', 'fancyman', 'linguist', 'fletcher',
|
||||
'notary', 'berserker-typist', 'fishmongerer', 'manicurist', 'haberdasher', 'concierge']);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
const _ = require('lodash');
|
||||
|
||||
const features = [
|
||||
'Astrological Botany',
|
||||
@@ -50,7 +50,7 @@ const getFeature = (level)=>{
|
||||
return res.join(', ');
|
||||
};
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
full : function(){
|
||||
const classname = _.sample(classnames);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
const _ = require('lodash');
|
||||
|
||||
const titles = [
|
||||
'The Burning Gallows',
|
||||
@@ -98,7 +98,7 @@ const subtitles = [
|
||||
];
|
||||
|
||||
|
||||
export default ()=>{
|
||||
module.exports = ()=>{
|
||||
return `<style>
|
||||
.phb#p1{ text-align:center; }
|
||||
.phb#p1:after{ display:none; }
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import _ from 'lodash';
|
||||
const _ = require('lodash');
|
||||
|
||||
import ClassFeatureGen from './classfeature.gen.js';
|
||||
const ClassFeatureGen = require('./classfeature.gen.js');
|
||||
|
||||
import ClassTableGen from './classtable.gen.js';
|
||||
const ClassTableGen = require('./classtable.gen.js');
|
||||
|
||||
export default function(){
|
||||
module.exports = function(){
|
||||
|
||||
const classname = _.sample(['Archivist', 'Fancyman', 'Linguist', 'Fletcher',
|
||||
'Notary', 'Berserker-Typist', 'Fishmongerer', 'Manicurist', 'Haberdasher', 'Concierge']);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
const _ = require('lodash');
|
||||
|
||||
const spellNames = [
|
||||
'Astral Rite of Acne',
|
||||
@@ -48,7 +48,7 @@ const spellNames = [
|
||||
'Ultimate Ritual of Mouthwash',
|
||||
];
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
|
||||
spellList : function(){
|
||||
const levels = ['Cantrips (0 Level)', '1st Level', '2nd Level', '3rd Level', '4th Level', '5th Level', '6th Level', '7th Level', '8th Level', '9th Level'];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
const _ = require('lodash');
|
||||
|
||||
const genList = function(list, max){
|
||||
return _.sampleSize(list, _.random(0, max)).join(', ') || 'None';
|
||||
@@ -137,7 +137,7 @@ const genAction = function(){
|
||||
};
|
||||
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
|
||||
full : function(){
|
||||
return `${[
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
const _ = require('lodash');
|
||||
|
||||
const getTOC = (pages)=>{
|
||||
const add1 = (title, page)=>{
|
||||
@@ -47,7 +47,7 @@ const getTOC = (pages)=>{
|
||||
return res;
|
||||
};
|
||||
|
||||
export default function(props){
|
||||
module.exports = function(props){
|
||||
const pages = props.brew.text.split('\\page');
|
||||
const TOC = getTOC(pages);
|
||||
const markdown = _.reduce(TOC, (r, g1, idx1)=>{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
export default [
|
||||
module.exports = [
|
||||
];
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
/* eslint-disable max-lines */
|
||||
import MagicGen from './snippets/magic.gen.js';
|
||||
import ClassTableGen from './snippets/classtable.gen.js';
|
||||
import MonsterBlockGen from './snippets/monsterblock.gen.js';
|
||||
import scriptGen from './snippets/script.gen.js';
|
||||
import ClassFeatureGen from './snippets/classfeature.gen.js';
|
||||
import CoverPageGen from './snippets/coverpage.gen.js';
|
||||
import QuoteGen from './snippets/quote.gen.js';
|
||||
import dedent from 'dedent';
|
||||
|
||||
export default [
|
||||
const MagicGen = require('./snippets/magic.gen.js');
|
||||
const ClassTableGen = require('./snippets/classtable.gen.js');
|
||||
const MonsterBlockGen = require('./snippets/monsterblock.gen.js');
|
||||
const scriptGen = require('./snippets/script.gen.js');
|
||||
const ClassFeatureGen = require('./snippets/classfeature.gen.js');
|
||||
const CoverPageGen = require('./snippets/coverpage.gen.js');
|
||||
const QuoteGen = require('./snippets/quote.gen.js');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
groupName : 'Style Editor',
|
||||
icon : 'fas fa-pencil-alt',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import dedent from 'dedent';
|
||||
const _ = require('lodash');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
export default function(classname){
|
||||
module.exports = function(classname){
|
||||
|
||||
classname = _.sample(['archivist', 'fancyman', 'linguist', 'fletcher',
|
||||
'notary', 'berserker-typist', 'fishmongerer', 'manicurist', 'haberdasher', 'concierge']);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import dedent from 'dedent';
|
||||
const _ = require('lodash');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
const features = [
|
||||
'Astrological Botany', 'Biochemical Sorcery', 'Civil Divination',
|
||||
@@ -18,7 +18,7 @@ const classnames = [
|
||||
'Haberdasher', 'Manicurist', 'Netrunner', 'Weirkeeper'
|
||||
];
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
non : function(snippetClasses){
|
||||
return dedent`
|
||||
{{${snippetClasses}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import dedent from 'dedent';
|
||||
const _ = require('lodash');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
const titles = [
|
||||
'The Burning Gallows', 'The Ring of Nenlast',
|
||||
@@ -78,7 +78,7 @@ const coverText = [
|
||||
'Enter a world of wonder and danger, where you can find allies and enemies among the various races and factions that inhabit it. You can choose to join or oppose any of them, or forge your own path. The game world is alive and responsive to your actions.'
|
||||
];
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
|
||||
front : function() {
|
||||
return dedent`
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import _ from 'lodash';
|
||||
const _ = require('lodash');
|
||||
|
||||
import ClassFeatureGen from './classfeature.gen.js';
|
||||
import ClassTableGen from './classtable.gen.js';
|
||||
const ClassFeatureGen = require('./classfeature.gen.js');
|
||||
|
||||
export default function(){
|
||||
const ClassTableGen = require('./classtable.gen.js');
|
||||
|
||||
module.exports = function(){
|
||||
|
||||
const classname = _.sample(['Archivist', 'Fancyman', 'Linguist', 'Fletcher',
|
||||
'Notary', 'Berserker-Typist', 'Fishmongerer', 'Manicurist', 'Haberdasher', 'Concierge']);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
const _ = require('lodash');
|
||||
|
||||
const spellNames = [
|
||||
'Astral Rite of Acne',
|
||||
@@ -54,7 +54,7 @@ const itemNames = [
|
||||
'Staff of Endless Confetti',
|
||||
];
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
|
||||
spellList : function(){
|
||||
const levels = ['Cantrips (0 Level)', '1st Level', '2nd Level', '3rd Level', '4th Level', '5th Level', '6th Level', '7th Level', '8th Level', '9th Level'];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import dedent from 'dedent';
|
||||
const _ = require('lodash');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
const genList = function(list, max){
|
||||
return _.sampleSize(list, _.random(0, max)).join(', ') || 'None';
|
||||
@@ -152,7 +152,7 @@ const genAction = function(){
|
||||
};
|
||||
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
|
||||
monster : function(classes, genLines){
|
||||
return dedent`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import _ from 'lodash';
|
||||
const _ = require('lodash');
|
||||
|
||||
const quotes = [
|
||||
'The sword glinted in the dim light, its edges keen and deadly. As the adventurer reached for it, he couldn\'t help but feel a surge of excitement mixed with fear. This was no ordinary blade.',
|
||||
@@ -40,7 +40,7 @@ const books = [
|
||||
'Frost and Fury',
|
||||
|
||||
];
|
||||
export default ()=>{
|
||||
module.exports = ()=>{
|
||||
return `
|
||||
{{quote
|
||||
${_.sample(quotes)}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import dedent from 'dedent';
|
||||
const _ = require('lodash');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
dwarvish : ()=>{
|
||||
return dedent `##### Dwarvish Runes: Sample Alphabet
|
||||
{{runeTable,wide,frame,font-family:Davek
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
const _ = require('lodash');
|
||||
|
||||
export default ()=>{
|
||||
module.exports = ()=>{
|
||||
return `{{watercolor${_.random(1, 12)},top:20px,left:30px,width:300px,background-color:#BBAD82,opacity:80%}}\n\n`;
|
||||
};
|
||||
|
||||
@@ -615,7 +615,6 @@
|
||||
text-align : center;
|
||||
-webkit-text-stroke : 0.1cm black;
|
||||
paint-order : stroke;
|
||||
text-transform : none;
|
||||
}
|
||||
.logo {
|
||||
position : absolute;
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
/* eslint-disable max-lines */
|
||||
import dedent from 'dedent';
|
||||
import WatercolorGen from './snippets/watercolor.gen.js';
|
||||
import ImageMaskGen from './snippets/imageMask.gen.js';
|
||||
import FooterGen from './snippets/footer.gen.js';
|
||||
import LicenseGenWotC from './snippets/licenseWotC.gen.js';
|
||||
import LicenseGenGNU from './snippets/licenseGNU.gen.js';
|
||||
import LicenseGen from './snippets/license.gen.js';
|
||||
import LicenseGenAelf from './snippets/licenseAELF.js';
|
||||
import LicenseDTTRPGGCC from './snippets/licenseDTRPGCC.gen.js';
|
||||
import LicenseMongoosePublishing from './snippets/licenseMongoose.gen.js';
|
||||
import TableOfContentsGen from './snippets/tableOfContents.gen.js';
|
||||
import indexGen from './snippets/index.gen.js';
|
||||
|
||||
export default [
|
||||
const WatercolorGen = require('./snippets/watercolor.gen.js');
|
||||
const ImageMaskGen = require('./snippets/imageMask.gen.js');
|
||||
const FooterGen = require('./snippets/footer.gen.js');
|
||||
const LicenseGenWotC = require('./snippets/licenseWotC.gen.js');
|
||||
const LicenseGenGNU = require('./snippets/licenseGNU.gen.js');
|
||||
const LicenseGen = require('./snippets/license.gen.js');
|
||||
const LicenseGenAelf = require('./snippets/licenseAELF.js');
|
||||
const LicenseDTTRPGGCC = require('./snippets/licenseDTRPGCC.gen.js');
|
||||
const LicenseMongoosePublishing = require('./snippets/licenseMongoose.gen.js');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
const TableOfContentsGen = require('./snippets/tableOfContents.gen.js');
|
||||
const indexGen = require('./snippets/index.gen.js');
|
||||
|
||||
module.exports = [
|
||||
|
||||
{
|
||||
groupName : 'Text Editor',
|
||||
@@ -208,7 +209,7 @@ export default [
|
||||
view : 'text',
|
||||
snippets : [
|
||||
{
|
||||
name : 'AELF',
|
||||
name : 'AELF',
|
||||
subsnippets : [
|
||||
{
|
||||
name : 'Title Page Declaration',
|
||||
@@ -328,51 +329,51 @@ export default [
|
||||
]
|
||||
},
|
||||
{
|
||||
name : 'DTRPG Community Content',
|
||||
incon : 'fab fa-dtrpg',
|
||||
name : 'DTRPG Community Content',
|
||||
incon : 'fab fa-dtrpg',
|
||||
subsnippets : [
|
||||
{
|
||||
name : 'Chronicle System Guild Colophon',
|
||||
name : "Chronicle System Guild Colophon",
|
||||
gen : LicenseDTTRPGGCC.greenRoninChronicleSystemGuildColophon,
|
||||
},
|
||||
|
||||
{
|
||||
name : 'Green Ronin\'s Age Creator\'s Alliance',
|
||||
name : 'Green Ronin\'s Age Creator\'s Alliance',
|
||||
subsnippets : [
|
||||
{
|
||||
name : 'Required Text',
|
||||
name : "Required Text",
|
||||
subsnippets : [
|
||||
{
|
||||
name : 'Colophon',
|
||||
name : "Colophon",
|
||||
gen : LicenseDTTRPGGCC.greenRoninAgeCreatorsAllianceColophon,
|
||||
},
|
||||
|
||||
{
|
||||
name : 'Cover',
|
||||
name : "Cover",
|
||||
gen : LicenseDTTRPGGCC.greenRoninAgeCreatorsAllianceCover,
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
name : 'Logos',
|
||||
name : "Logos",
|
||||
subsnippets : [
|
||||
{
|
||||
name : 'Age',
|
||||
name : "Age",
|
||||
gen : LicenseDTTRPGGCC.greenRoninAgeCreatorsAllianceLogo,
|
||||
},
|
||||
|
||||
{
|
||||
name : 'Blue Rose',
|
||||
name : "Blue Rose",
|
||||
gen : LicenseDTTRPGGCC.greenRoninAgeCreatorsAllianceBlueRoseLogo,
|
||||
},
|
||||
|
||||
{
|
||||
name : 'Fantasy Age Compatible',
|
||||
name : "Fantasy Age Compatible",
|
||||
gen : LicenseDTTRPGGCC.greenRoninAgeCreatorsAllianceFantasyAgeCompatible,
|
||||
},
|
||||
|
||||
{
|
||||
name : 'Modern AGE Compatible',
|
||||
name : "Modern AGE Compatible",
|
||||
gen : LicenseDTTRPGGCC.greenRoninAgeCreatorsAllianceModernAGECompatible,
|
||||
},
|
||||
]
|
||||
@@ -381,30 +382,30 @@ export default [
|
||||
},
|
||||
|
||||
{
|
||||
name : 'Hero Kid\'s Creators Guild',
|
||||
name : "Hero Kid\'s Creators Guild",
|
||||
subsnippets : [
|
||||
|
||||
{
|
||||
name : 'Required Text',
|
||||
name: "Required Text",
|
||||
subsnippets : [
|
||||
|
||||
|
||||
{
|
||||
name : 'heroForgeHeroKidsCreatorsGuildColophon',
|
||||
name : "heroForgeHeroKidsCreatorsGuildColophon",
|
||||
gen : LicenseDTTRPGGCC.heroForgeHeroKidsCreatorsGuildColophon,
|
||||
},
|
||||
|
||||
{
|
||||
name : 'heroForgeHeroKidsCreatorsGuildSuperKidsColophon',
|
||||
name : "heroForgeHeroKidsCreatorsGuildSuperKidsColophon",
|
||||
gen : LicenseDTTRPGGCC.heroForgeHeroKidsCreatorsGuildSuperKidsColophon,
|
||||
},
|
||||
|
||||
{
|
||||
name : 'heroForgeHeroKidsCreatorsGuildCover',
|
||||
name : "heroForgeHeroKidsCreatorsGuildCover",
|
||||
gen : LicenseDTTRPGGCC.heroForgeHeroKidsCreatorsGuildCover,
|
||||
},
|
||||
|
||||
{
|
||||
name : 'heroForgeHeroKidsCreatorsGuildSuperKidsCover',
|
||||
name : "heroForgeHeroKidsCreatorsGuildSuperKidsCover",
|
||||
gen : LicenseDTTRPGGCC.heroForgeHeroKidsCreatorsGuildSuperKidsCover,
|
||||
},
|
||||
]
|
||||
@@ -413,33 +414,33 @@ export default [
|
||||
},
|
||||
|
||||
{
|
||||
name : 'Travellers\' Aid Society',
|
||||
name : "Travellers' Aid Society",
|
||||
subsnippets : [
|
||||
{
|
||||
name : 'Legal Statement',
|
||||
name : "Legal Statement",
|
||||
gen : LicenseMongoosePublishing.TASLegal,
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
name : 'Super-Powered by M&M',
|
||||
name : "Super-Powered by M&M",
|
||||
subsnippets : [
|
||||
{
|
||||
name : 'Required Text',
|
||||
name : "Required Text",
|
||||
subsnippets : [
|
||||
{
|
||||
name : 'Colophon',
|
||||
name : "Colophon",
|
||||
gen : LicenseDTTRPGGCC.greenRoninSuperPoweredMMColophon,
|
||||
},
|
||||
|
||||
{
|
||||
name : 'Cover',
|
||||
name : "Cover",
|
||||
gen : LicenseDTTRPGGCC.greenRoninSuperPoweredMMCover,
|
||||
},
|
||||
|
||||
{
|
||||
name : 'Section 15',
|
||||
name : "Section 15",
|
||||
gen : LicenseDTTRPGGCC.greenRoninSuperPoweredMMSection15,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Markdown from '../../../../shared/markdown.js';
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
createFooterFunc : function(headerSize=1){
|
||||
return (props)=>{
|
||||
const cursorPos = props.cursorPos;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import dedent from 'dedent';
|
||||
const _ = require('lodash');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
export default {
|
||||
module.exports = {
|
||||
center : ()=>{
|
||||
return dedent`
|
||||
{{imageMaskCenter${_.random(1, 16)},--offsetX:0%,--offsetY:0%,--rotation:0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import dedent from 'dedent';
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
export default ()=>{
|
||||
module.exports = ()=>{
|
||||
return dedent`
|
||||
{{index,wide,columns:5;
|
||||
##### Index
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user