0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-25 01:03:08 +00:00

Compare commits

...

98 Commits

Author SHA1 Message Date
Scott Tolksdorf
20b719d0de Added in a function to sanatize script tags specifically 2018-12-03 09:55:49 +00:00
Scott Tolksdorf
8b04cc9269 Adding some more text to the default issue title to guide peopel to add an issue title 2018-11-27 10:38:29 +00:00
Marius
96466211c7 Make imgur link https in order to display image
Newer browsers warn and/or do not display content that gets loaded via HTTP if site is visited via HTTPS.
2018-11-26 20:13:25 -05:00
Kurtis Miller
34741291c7 Fix ESLint errors 2018-11-26 20:12:59 -05:00
Kurtis Miller
fcb0cd8ee7 Reset to previous commit 2018-11-26 20:12:59 -05:00
Kurtis Miller
aafac16af2 Add bold/italic shortcuts, reposition renderer warning 2018-11-26 20:12:59 -05:00
Trevor Buckner
911d1d4f9c Hide duplicate scrollbar in brewRenderer 2018-11-13 15:24:46 -05:00
Trevor Buckner
2cd7b44e12 Merge branch 'PRODUCTION' into master 2018-11-11 04:02:12 -05:00
Trevor Buckner
bfccd1d9e4 Wrap the text in the "source" page.
See #332.
2018-11-11 03:10:27 -05:00
Trevor Buckner
bf1bf6c191 Added spaces for lint... 2018-11-08 16:11:10 -05:00
Trevor Buckner
cc5cb677a1 Found the lint-friendly way to do it. Just needed to pass along the event data. 2018-11-08 16:11:10 -05:00
Trevor Buckner
2dcd7101f3 Fix metadata not working. Some earlier linting caused the handleFieldChange and handleSystem functions to not have access to event data. Returning these to their pre-lint state for now, but there might be a more lint-friendly way to do this later. 2018-11-08 16:11:10 -05:00
Trevor Buckner
f4e7e46a04 Added spaces for lint... 2018-11-08 16:04:14 -05:00
Trevor Buckner
8b3b7cb5aa Found the lint-friendly way to do it. Just needed to pass along the event data. 2018-11-08 16:04:14 -05:00
Trevor Buckner
77081b39b4 Fix metadata not working. Some earlier linting caused the handleFieldChange and handleSystem functions to not have access to event data. Returning these to their pre-lint state for now, but there might be a more lint-friendly way to do this later. 2018-11-08 16:04:14 -05:00
Trevor Buckner
a06236e3ff Fix regression with updated Pico-Router
This variable name changed with the v2.0.0 of Pico-Router and it wasn't changed here. This was causing every page to display a  `<div class="homePage page">` rather than the appropriate `editPage` or `sharePage`. It just wasn't immediately noticeable since `homePage` and `editPage` are almost identical. The problem is clearly visible on `sharePage` however.

`homebrew.jsx` was set to always render a defaultUrl of ` ` which creates a `<div class="homePage page">` by default, overwriting the expected `<div>` on for the current url.
2018-11-07 16:11:18 -05:00
Rae Che
c8585775be Change circleci mongo version to one that still exists 2018-11-07 16:00:24 -05:00
Scott Tolksdorf
439cdfa1ea upgrading to mongoose v5 2018-11-07 16:00:24 -05:00
Scott Tolksdorf
4c36f254c4 Removing picofluc for now 2018-11-07 16:00:24 -05:00
Scott Tolksdorf
b6815593fd adding bithoundrc and updating pico-router 2018-11-07 16:00:24 -05:00
Scott Tolksdorf
84054d1aae Updating some packages 2018-11-07 16:00:24 -05:00
Trevor Buckner
24aec1c649 Fixed typo "is" -> "in" 2018-11-07 15:15:07 -05:00
sprigunn
8caae18a12 Update README.md
Typos and additional license to sync up with http://homebrewery.naturalcrit.com.
2018-11-07 15:15:07 -05:00
Rae Che
3532d75365 s/let/const/ to satisfy ESLint 2018-08-24 10:12:53 -04:00
Rae2che5
ea81bb5ebc Add missing volume declaration. 2018-08-22 01:44:48 -07:00
Schemen
8d217f8785 Update according to change request 2018-08-22 01:44:48 -07:00
Schemen
d35db1f702 Add dockerization and example compose file 2018-08-22 01:44:48 -07:00
Rae Che
f6b058f3c9 brewRenderer: Capture event properties while still in event loop.
React [pools events](https://github.com/facebook/react/issues/2850),
which means that once the lambda runs later on the properties we want
to read will be null. Instead, we capture the properties in the event
loop.
2018-08-20 14:14:52 -04:00
Rae Che
5ab7c29b9d Change circleci mongo version to one that still exists 2018-08-20 13:20:05 -04:00
Rae Che
c5ecb9d57d ESLint reformatting 2018-05-31 10:53:07 -04:00
Rae Che
d0c473878a BrewSearch: Remove stale piece of React state 2018-05-31 10:53:07 -04:00
Rae Che
796df9a1ac EditPage: Remove stale bit of React state 2018-05-31 10:53:07 -04:00
Rae Che
9e8e403195 HomebrewAdmin: Remove stale piece of React state 2018-05-31 10:53:07 -04:00
Rae Che
a369871a06 ESLint reformatting 2018-05-31 10:53:07 -04:00
Rae Che
f2f45f3657 RenderWarnings: Remove dead code 2018-05-31 10:53:07 -04:00
Rae Che
e86ce5cf06 PrintPage: Fix potentially inconsistent React state update 2018-05-31 10:53:07 -04:00
Rae Che
8d73ff6833 BrewLookup: Mark links as noreferrer 2018-05-31 10:53:07 -04:00
Rae Che
c4397d34f8 BrewItem: Mark links as noreferrer 2018-05-31 10:53:07 -04:00
Rae Che
66c0c96a4f EditPage: Mark link as noreferrer 2018-05-31 10:53:07 -04:00
Rae Che
838b64c589 EditPage: Simplify hasChanges.
In particular, remove unreachable `return` statement.
2018-05-31 10:53:07 -04:00
Rae Che
730dde730c MetadataEditor: Mark link as noreferrer 2018-05-31 10:53:07 -04:00
Rae Che
d867aa7ce1 EditPage: Consistent trySave on handle[Metadata|Text]change
Previously, one of these happened in React's post-state-update callback,
while the other happened directly. They now both use the callback.
2018-05-31 10:53:07 -04:00
Rae Che
761597e71f EditPage: Fix potentially inconsistent React state updates 2018-05-31 10:53:07 -04:00
Rae Che
4bde5fcbf8 HomebrewAdmin: Mark links as noreferrer. 2018-05-31 10:53:07 -04:00
Rae Che
ff0aa56ddc HomebrewAdmin: Remove direct React state mutation. 2018-05-31 10:53:07 -04:00
Rae Che
74f92f3e44 Use noreferrer in recent-brew links. 2018-05-31 10:53:07 -04:00
Rae Che
84285f7359 Remove redundant expression. 2018-05-31 10:53:07 -04:00
Rae Che
ec0de7a408 BrewRenderer: Remove redundant errors state property.
The errors are in fact tracked in `this.props`, not `this.state`.
2018-05-31 10:53:07 -04:00
Rae Che
9ea99236ff Omit redundant property definition in brew renderer 2018-05-31 10:53:07 -04:00
Rae Che
f806328e75 Omit redundant property in eslintrc 2018-05-31 10:53:07 -04:00
Rae Che
15ac397b63 Fix inconsistent React state update.
Flagged by lgtm.com (as js/react/inconsistent-state-update).
2018-05-31 10:53:07 -04:00
Rae Che
b8105eb147 Config: Read MongoDB URL from config files too. 2018-05-29 11:04:57 -04:00
Trevor Buckner
31cbd9ef40 Fix regression with updated Pico-Router
This variable name changed with the v2.0.0 of Pico-Router and it wasn't changed here. This was causing every page to display a  `<div class="homePage page">` rather than the appropriate `editPage` or `sharePage`. It just wasn't immediately noticeable since `homePage` and `editPage` are almost identical. The problem is clearly visible on `sharePage` however.

`homebrew.jsx` was set to always render a defaultUrl of ` ` which creates a `<div class="homePage page">` by default, overwriting the expected `<div>` on for the current url.
2018-05-23 17:41:50 +01:00
Trevor Buckner
eaab6de691 Fix border-image bug on PDFs
I think this might be caused by a new bug in Chrome or something since it seems to have popped up in GMBinder as well in the last couple weeks. See #683

Anyway, the error only occurs on the Class Table and Descriptive Text Box, which are also the only ones to use `border-image-repeat: round`. I changed it to `border-image-repeat: stretch` which solves the graphical issue and doesn't affect the appearance otherwise in this particular case.
2018-05-22 10:01:03 +01:00
Trevor Buckner
d417c76c56 Remove unused event triggers
Removed `onMouseOver` and `onMouseOut` since they are no longer needed to trigger `will-change`
2018-05-14 08:30:19 +01:00
Trevor Buckner
2f15cc5611 Lint 2018-05-14 08:30:19 +01:00
Trevor Buckner
eb08172fb1 Move will-change to stylesheet
This makes `will-change: transform` permanent in the brewRenderer stylesheet rather than trying to load and unload it programatically.
2018-05-14 08:30:19 +01:00
Trevor Buckner
0cc87a4f0f Lint Fixes 2? 2018-05-14 08:30:19 +01:00
Trevor Buckner
004dc79eb2 Lint fixes 2018-05-14 08:30:19 +01:00
Trevor Buckner
a8a70c2d70 Unified spacing 2018-05-14 08:30:19 +01:00
Trevor Buckner
825c259fba Optimize for smooth scrolling of BrewRenderer
The will-change property allows the browser to optimize for smoother animations. This completely eliminates the scrolling stutter.
2018-05-14 08:30:19 +01:00
Rae2che5
cbbb7292d9 Revert "Fix duplicated text from Class Feature snippet"
This reverts commit 9519a0b4e4.
2018-05-11 20:44:53 +01:00
Trevor Buckner
9519a0b4e4 Fix duplicated text from Class Feature snippet
When adding the Class Feature snippet, all curent text in the document is inserted in place of the randomly generated class name, creating several duplicates of the document and generally creating a mess.  See #413 which was closed but the issue was never fixed.

Most of the snippet code generators do not have any input arguments in the `module.exports` function, so they don't have this issue. However, Table of Contents needs to parse the text in the brew, so it is passed a copy of the brew document. Unfortunately, Class Feature (classfeature.gen.js) also has an input parameter for when it is used as part of the Full Class snippet.  Thus, the unintended consequence occurs in snippetbar.jsx in the `execute` function.

This fix simply adds a check to the execute function and only passes in the brew as an argument if the clicked snipped actually is the Table of Contents. Some restructuring might later reveal a cleaner way to do this rather than an awkward special case check like this.
2018-05-11 10:20:18 +01:00
Eric Scheid
9dd16b6dd5 add page-break-inside to support Firefox, the laggard 2018-05-10 14:36:24 -04:00
Eric Scheid
d693301c37 Fix property name break-inside 2018-05-10 14:36:24 -04:00
Rae Che
fd5d142c16 Fix calculation of currently-viewed page.
Previously, this relied on a hard-coded constant determining the
height of a page. However, that's unnecessary -- we know the scroll
height of the window and the number of pages, so we can compute it.
2018-05-10 14:35:03 -04:00
Trevor Buckner
ee63d2d857 Fix duplicate table headers
Fixes a common issue. See #318.
2018-05-10 18:26:46 +01:00
Vincent Durmont
7c3946fb03 Some typos 2018-05-10 13:11:40 -04:00
Trevor Buckner
3e69e8c1aa Revert "Merge pull request #1 from calculuschild/Fix-Duplicated-Table-Headers"
This reverts commit 1a0bc1952c, reversing
changes made to 4f4ef908e0.
2018-05-08 21:33:34 -04:00
Trevor Buckner
1a0bc1952c Merge pull request #1 from calculuschild/Fix-Duplicated-Table-Headers
Fix Duplicated Table Header
2018-05-08 12:45:02 -04:00
Trevor Buckner
7e2c3381ae Fix Duplicated Table Header
Fixes a pretty common issue. See #318.
2018-05-08 12:42:11 -04:00
Trevor Buckner
4f4ef908e0 Merge branch 'master' of https://github.com/calculuschild/homebrewery 2018-05-08 12:39:50 -04:00
Trevor Buckner
3fe2360d92 Revert "Fix duplicated table headers"
This reverts commit 13a2a7efd2.
2018-05-08 12:36:30 -04:00
Trevor Buckner
13a2a7efd2 Fix duplicated table headers
Fixes a pretty common issue. See #318.
2018-05-08 12:33:36 -04:00
Trevor Buckner
073fb73bde Wrap the text in the "source" page.
See #332.
2018-05-07 10:56:23 +01:00
Trevor Buckner
847615ef8e Wrap the text in the "source" page.
See #332.
2018-04-17 21:03:50 -04:00
Scott Tolksdorf
3583c2e776 upgrading to mongoose v5 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
2a753ccc7c Removing picofluc for now 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
55c529473a adding bithoundrc and updating pico-router 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
164f646e08 Updating some packages 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
6f4962926c Upping version 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
f18a181e2e Updating to user create-react-class 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
c4bff6afa0 Upping the node ver on circleci 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
63e8a0d9b7 Updating superagent 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
ce3fda683b Adding in the missing repository field 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
9594b73b0d Updating build scripts and libraries 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
78ad4bea09 Updating build scripts and libraries 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
ed1b5252be lint 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
bf27250990 Updating navbar link to go to the new subreddit 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
bab11d692e Adding mongo image to the circleci config 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
3350b04f64 Updating contributing and issue guides, added new verify npm task 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
5ebba25183 Moving babelrc into package 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
8f77ac9e56 Adding in test case runner 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
3f728e7993 adding a circleCI task 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
3f22572f98 Adding circleCI and eslint 2018-04-09 00:12:56 -04:00
Scott Tolksdorf
a52f628fdf Adding circleCI 2018-04-09 00:12:56 -04:00
Trevor Buckner
fe63133d7c Re-enable Box Shadows in PDF
Box shadows have been fixed in Chrome. No reason to hide them anymore.
2018-04-08 23:23:49 -04:00
Scott Tolksdorf
3247cab214 Fixing issue#413 class feature duping entire brew 2017-06-04 16:07:49 -04:00
29 changed files with 235 additions and 229 deletions

7
.bithoundrc Normal file
View File

@@ -0,0 +1,7 @@
{
"dependencies": {
"unused-ignores": [
"react-dom"
]
}
}

View File

@@ -7,7 +7,7 @@ jobs:
build:
docker:
- image: circleci/node:8.9
- image: circleci/mongo:3.4.4
- image: circleci/mongo:3.4-jessie
working_directory: ~/repo

6
.dockerignore Normal file
View File

@@ -0,0 +1,6 @@
node_modules
npm-debug.log
.git
Dockerfile
docker-compose.yml
tests

View File

@@ -44,7 +44,6 @@ module.exports = {
'arrow-parens' : ['warn', 'always'],
'brace-style' : ['warn', '1tbs', { allowSingleLine: true }],
'jsx-quotes' : ['warn', 'prefer-single'],
'linebreak-style' : ['warn', 'unix'],
'no-var' : 'warn',
'prefer-const' : 'warn',
'prefer-template' : 'warn',

14
Dockerfile Normal file
View File

@@ -0,0 +1,14 @@
FROM node:8
# Create app directory
WORKDIR /usr/src/app
# Bundle app source
COPY . .
ENV NODE_ENV=docker
RUN yarn
EXPOSE 8000
CMD [ "yarn", "start" ]

View File

@@ -1,13 +1,13 @@
# The Homebrewery
The Homebrewery is a tool for making authnetic looking [D&D content](http://dnd.wizards.com/products/tabletop-games/rpg-products/rpg_playershandbook) using only [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). Check it out [here](http://homebrewery.naturalcrit.com).
The Homebrewery is a tool for making authentic looking [D&D content](http://dnd.wizards.com/products/tabletop-games/rpg-products/rpg_playershandbook) using only [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). Check it out [here](http://homebrewery.naturalcrit.com).
### issues, suggestions, bugs
If you run into any issues using The Homebrewery, please submit an issues [here](/issues)
If you run into any issues using The Homebrewery, please submit an issue [here](/issues).
### local dev
Homebrewery is open source, so feel free to clone it, tinker with it, or run your own local version.
The Homebrewery is open source, so feel free to clone it, tinker with it, or run your own local version.
#### pre-reqs
1. install [node](https://nodejs.org/en/)
@@ -20,14 +20,16 @@ Homebrewery is open source, so feel free to clone it, tinker with it, or run you
1. `npm start`
#### standalone PHB stylesheet
If you just want the stylesheet that is generated to make pages look like they are from the PLayer's Handbook, you have find it [here](https://github.com/stolksdorf/homebrewery/blob/master/phb.standalone.css)
If you just want the stylesheet that is generated to make pages look like they are from the Player's Handbook, you will find it [here](https://github.com/stolksdorf/homebrewery/blob/master/phb.standalone.css).
If you are developing locally and would like to generate your own, follow the above steps and then run `npm run phb`.
### changelog
You can check out the changelog [here](https://github.com/stolksdorf/homebrewery/blob/master/changelog.md)
You can check out the changelog [here](https://github.com/stolksdorf/homebrewery/blob/master/changelog.md).
### license
This project is licensed under [MIT](./license)
This project is licensed under [MIT](./license). Which means you are free to use The Homebrewery in any way that you want, except for claiming that you made it yourself.
If you wish to sell or in some way gain profit for what's created on this site, it's your responsibility to ensure you have the proper licenses/rights for any images or resources used.

View File

@@ -47,8 +47,8 @@ const BrewLookup = createClass({
return <div className='brewRow'>
<div>{brew.title}</div>
<div>{brew.authors.join(', ')}</div>
<div><a href={`/edit/${brew.editId}`} target='_blank'>/edit/{brew.editId}</a></div>
<div><a href={`/share/${brew.shareId}`} target='_blank'>/share/{brew.shareId}</a></div>
<div><a href={`/edit/${brew.editId}`} target='_blank' rel='noopener noreferrer'>/edit/{brew.editId}</a></div>
<div><a href={`/share/${brew.shareId}`} target='_blank' rel='noopener noreferrer'>/share/{brew.shareId}</a></div>
<div>{Moment(brew.updatedAt).fromNow()}</div>
<div>{brew.views}</div>
</div>;

View File

@@ -17,16 +17,11 @@ const BrewSearch = createClass({
return {
searchTerm : '',
brew : null,
searching : false
};
},
search : function(){
this.setState({
searching : true
});
request.get(`/homebrew/api/search?id=${this.state.searchTerm}`)
.query({
admin_key : this.props.admin_key,
@@ -35,8 +30,6 @@ const BrewSearch = createClass({
console.log(err, res, res.body.brews[0]);
this.setState({
brew : res.body.brews[0],
searching : false
});
});
},

View File

@@ -23,8 +23,6 @@ const HomebrewAdmin = createClass({
count : 20,
brewCache : {},
total : 0,
processingOldBrews : false
};
},
@@ -38,9 +36,10 @@ const HomebrewAdmin = createClass({
})
.end((err, res)=>{
if(err || !res.body || !res.body.brews) return;
this.state.brewCache[page] = res.body.brews;
const newCache = _.extend({}, this.state.brewCache);
newCache[page] = res.body.brews;
this.setState({
brewCache : this.state.brewCache,
brewCache : newCache,
total : res.body.total,
count : res.body.count
});
@@ -106,8 +105,8 @@ const HomebrewAdmin = createClass({
const brews = this.state.brewCache[this.state.page] || _.times(this.state.count);
return _.map(brews, (brew)=>{
return <tr className={cx('brewRow', { 'isEmpty': brew.text == 'false' })} key={brew.shareId || brew}>
<td><a href={`/edit/${brew.editId}`} target='_blank'>{brew.editId}</a></td>
<td><a href={`/share/${brew.shareId}`} target='_blank'>{brew.shareId}</a></td>
<td><a href={`/edit/${brew.editId}`} target='_blank' rel='noopener noreferrer'>{brew.editId}</a></td>
<td><a href={`/share/${brew.shareId}`} target='_blank' rel='noopener noreferrer'>{brew.shareId}</a></td>
<td>{Moment(brew.createdAt).fromNow()}</td>
<td>{Moment(brew.updatedAt).fromNow()}</td>
<td>{Moment(brew.lastViewed).fromNow()}</td>

View File

@@ -27,16 +27,11 @@ const BrewRenderer = createClass({
height : 0,
isMounted : false,
usePPR : true,
pages : pages,
usePPR : pages.length >= PPR_THRESHOLD,
errors : []
};
},
height : 0,
pageHeight : PAGE_HEIGHT,
lastRender : <div></div>,
componentDidMount : function() {
@@ -48,8 +43,6 @@ const BrewRenderer = createClass({
},
componentWillReceiveProps : function(nextProps) {
if(this.refs.pages && this.refs.pages.firstChild) this.pageHeight = this.refs.pages.firstChild.clientHeight;
const pages = nextProps.text.split('\\page');
this.setState({
pages : pages,
@@ -58,10 +51,6 @@ const BrewRenderer = createClass({
},
updateSize : function() {
setTimeout(()=>{
if(this.refs.pages && this.refs.pages.firstChild) this.pageHeight = this.refs.pages.firstChild.clientHeight;
}, 1);
this.setState({
height : this.refs.main.parentNode.clientHeight,
isMounted : true
@@ -69,9 +58,10 @@ const BrewRenderer = createClass({
},
handleScroll : function(e){
this.setState({
viewablePageNumber : Math.floor(e.target.scrollTop / this.pageHeight)
});
const target = e.target;
this.setState((prevState)=>({
viewablePageNumber : Math.floor(target.scrollTop / target.scrollHeight * prevState.pages.length)
}));
},
shouldRender : function(pageText, index){
@@ -134,20 +124,24 @@ const BrewRenderer = createClass({
},
render : function(){
return <div className='brewRenderer'
onScroll={this.handleScroll}
ref='main'
style={{ height: this.state.height }}>
return (
<React.Fragment>
<div className='brewRenderer'
onScroll={this.handleScroll}
ref='main'
style={{ height: this.state.height }}>
<ErrorBar errors={this.props.errors} />
<RenderWarnings />
<ErrorBar errors={this.props.errors} />
<RenderWarnings />
<div className='pages' ref='pages'>
{this.renderPages()}
</div>
{this.renderPageInfo()}
{this.renderPPRmsg()}
</div>;
<div className='pages' ref='pages'>
{this.renderPages()}
</div>
</div>;
{this.renderPageInfo()}
{this.renderPPRmsg()}
</React.Fragment>
);
}
});

View File

@@ -4,29 +4,8 @@
position : relative;
}
.brewRenderer{
overflow-y : scroll;
.pageInfo{
position : absolute;
right : 17px;
bottom : 0;
z-index : 1000;
padding : 8px 10px;
background-color : #333;
font-size : 10px;
font-weight : 800;
color : white;
}
.ppr_msg{
position : absolute;
left : 0px;
bottom : 0;
z-index : 1000;
padding : 8px 10px;
background-color : #333;
font-size : 10px;
font-weight : 800;
color : white;
}
will-change : transform;
overflow-y : scroll;
.pages{
margin : 30px 0px;
&>.phb{
@@ -36,4 +15,26 @@
box-shadow : 1px 4px 14px #000;
}
}
}
.pageInfo{
position : absolute;
right : 17px;
bottom : 0;
z-index : 1000;
padding : 8px 10px;
background-color : #333;
font-size : 10px;
font-weight : 800;
color : white;
}
.ppr_msg{
position : absolute;
left : 0px;
bottom : 0;
z-index : 1000;
padding : 8px 10px;
background-color : #333;
font-size : 10px;
font-weight : 800;
color : white;
}

View File

@@ -68,7 +68,7 @@ const MetadataEditor = createClass({
<input
type='checkbox'
checked={_.includes(this.props.metadata.systems, val)}
onChange={()=>this.handleSystem(val)} />
onChange={(e)=>this.handleSystem(val, e)} />
{val}
</label>;
});
@@ -118,7 +118,7 @@ const MetadataEditor = createClass({
return <div className='field reddit'>
<label>reddit</label>
<div className='value'>
<a href={this.getRedditLink()} target='_blank'>
<a href={this.getRedditLink()} target='_blank' rel='noopener noreferrer'>
<button className='publish'>
<i className='fa fa-reddit-alien' /> share to reddit
</button>
@@ -133,18 +133,18 @@ const MetadataEditor = createClass({
<label>title</label>
<input type='text' className='value'
value={this.props.metadata.title}
onChange={()=>this.handleFieldChange('title')} />
onChange={(e)=>this.handleFieldChange('title', e)} />
</div>
<div className='field description'>
<label>description</label>
<textarea value={this.props.metadata.description} className='value'
onChange={()=>this.handleFieldChange('description')} />
onChange={(e)=>this.handleFieldChange('description', e)} />
</div>
{/*}
<div className='field tags'>
<label>tags</label>
<textarea value={this.props.metadata.tags}
onChange={()=>this.handleFieldChange('tags')} />
onChange={(e)=>this.handleFieldChange('tags', e)} />
</div>
*/}

View File

@@ -82,7 +82,7 @@ const Homebrew = createClass({
},
render : function(){
return <div className='homebrew'>
<Router initialUrl={this.props.url}/>
<Router defaultUrl={this.props.url}/>
</div>;
}
});

View File

@@ -3,7 +3,11 @@ const createClass = require('create-react-class');
const Nav = require('naturalcrit/nav/nav.jsx');
module.exports = function(props){
return <Nav.item newTab={true} href='https://www.reddit.com/r/homebrewery/submit?selftext=true&title=[Issue]' color='red' icon='fa-bug'>
return <Nav.item
newTab={true}
color='red'
icon='fa-bug'
href={`https://www.reddit.com/r/homebrewery/submit?selftext=true&title=${encodeURIComponent('[Issue] Describe Your Issue Here')}`} >
report issue
</Nav.item>;
};

View File

@@ -59,7 +59,7 @@ const BaseItem = createClass({
if(!this.state.showDropdown) return null;
const items = _.map(this.state.brews, (brew)=>{
return <a href={brew.url} className='item' key={brew.id} target='_blank'>
return <a href={brew.url} className='item' key={brew.id} target='_blank' rel='noopener noreferrer'>
<span className='title'>{brew.title}</span>
<span className='time'>{Moment(brew.ts).fromNow()}</span>
</a>;
@@ -172,7 +172,7 @@ module.exports = {
const makeItems = (brews)=>{
return _.map(brews, (brew)=>{
return <a href={brew.url} className='item' key={brew.id} target='_blank'>
return <a href={brew.url} className='item' key={brew.id} target='_blank' rel='noopener noreferrer'>
<span className='title'>{brew.title}</span>
<span className='time'>{Moment(brew.ts).fromNow()}</span>
</a>;

View File

@@ -45,11 +45,10 @@ const EditPage = createClass({
return {
brew : this.props.brew,
isSaving : false,
isPending : false,
errors : null,
htmlErrors : Markdown.validate(this.props.brew.text),
lastUpdated : this.props.brew.updatedAt
isSaving : false,
isPending : false,
errors : null,
htmlErrors : Markdown.validate(this.props.brew.text),
};
},
savedBrew : null,
@@ -62,9 +61,9 @@ const EditPage = createClass({
}
};
this.setState({
htmlErrors : Markdown.validate(this.state.brew.text)
});
this.setState((prevState)=>({
htmlErrors : Markdown.validate(prevState.brew.text)
}));
document.addEventListener('keydown', this.handleControlKeys);
},
@@ -91,12 +90,10 @@ const EditPage = createClass({
},
handleMetadataChange : function(metadata){
this.setState({
brew : _.merge({}, this.state.brew, metadata),
this.setState((prevState)=>({
brew : _.merge({}, prevState.brew, metadata),
isPending : true,
}, ()=>{
this.trySave();
});
}), ()=>this.trySave());
},
@@ -106,22 +103,16 @@ const EditPage = createClass({
let htmlErrors = this.state.htmlErrors;
if(htmlErrors.length) htmlErrors = Markdown.validate(text);
this.setState({
brew : _.merge({}, this.state.brew, { text: text }),
this.setState((prevState)=>({
brew : _.merge({}, prevState.brew, { text: text }),
isPending : true,
htmlErrors : htmlErrors
});
this.trySave();
}), ()=>this.trySave());
},
hasChanges : function(){
if(this.savedBrew){
return !_.isEqual(this.state.brew, this.savedBrew);
} else {
return !_.isEqual(this.state.brew, this.props.brew);
}
return false;
const savedBrew = this.savedBrew ? this.savedBrew : this.props.brew;
return !_.isEqual(this.state.brew, savedBrew);
},
trySave : function(){
@@ -136,11 +127,11 @@ const EditPage = createClass({
save : function(){
if(this.debounceSave && this.debounceSave.cancel) this.debounceSave.cancel();
this.setState({
this.setState((prevState)=>({
isSaving : true,
errors : null,
htmlErrors : Markdown.validate(this.state.brew.text)
});
htmlErrors : Markdown.validate(prevState.brew.text)
}));
request
.put(`/api/update/${this.props.brew.editId}`)
@@ -153,9 +144,8 @@ const EditPage = createClass({
} else {
this.savedBrew = res.body;
this.setState({
isPending : false,
isSaving : false,
lastUpdated : res.body.updatedAt
isPending : false,
isSaving : false,
});
}
});
@@ -173,7 +163,8 @@ const EditPage = createClass({
Oops!
<div className='errorContainer'>
Looks like there was a problem saving. <br />
Report the issue <a target='_blank' href={`https://github.com/stolksdorf/naturalcrit/issues/new?body=${encodeURIComponent(errMsg)}`}>
Report the issue <a target='_blank' rel='noopener noreferrer'
href={`https://github.com/stolksdorf/naturalcrit/issues/new?body=${encodeURIComponent(errMsg)}`}>
here
</a>.
</div>

View File

@@ -55,7 +55,7 @@ If you are looking for more 5e Homebrew resources check out [r/UnearthedArcana](
<img src='http://i.imgur.com/hMna6G0.png' style='position:absolute;bottom:50px;right:30px;width:280px' />
<img src='https://i.imgur.com/hMna6G0.png' style='position:absolute;bottom:50px;right:30px;width:280px' />
<div class='pageNumber'>1</div>
<div class='footnote'>PART 1 | FANCINESS</div>

View File

@@ -22,7 +22,9 @@ const PrintPage = createClass({
componentDidMount : function() {
if(this.props.query.local){
this.setState({ brewText: localStorage.getItem(this.props.query.local) });
this.setState((prevState, prevProps)=>({
brewText : localStorage.getItem(prevProps.query.local)
}));
}
if(this.props.query.dialog) window.print();

View File

@@ -38,7 +38,7 @@ const BrewItem = createClass({
renderEditLink : function(){
if(!this.props.brew.editId) return;
return <a href={`/edit/${this.props.brew.editId}`} target='_blank'>
return <a href={`/edit/${this.props.brew.editId}`} target='_blank' rel='noopener noreferrer'>
<i className='fa fa-pencil' />
</a>;
},
@@ -63,7 +63,7 @@ const BrewItem = createClass({
</div>
<div className='links'>
<a href={`/share/${brew.shareId}`} target='_blank'>
<a href={`/share/${brew.shareId}`} target='_blank' rel='noopener noreferrer'>
<i className='fa fa-share-alt' />
</a>
{this.renderEditLink()}

View File

@@ -156,6 +156,7 @@ body {
margin-bottom : 1em;
font-size : 10pt;
thead{
display: table-row-group;
font-weight : 800;
th{
vertical-align : bottom;
@@ -337,7 +338,8 @@ body {
p,blockquote,table{
z-index : 15;
-webkit-column-break-inside : avoid;
column-break-inside : avoid;
page-break-inside : avoid;
break-inside : avoid;
overflow: hidden; /* Firefox fix */
}
//Better spacing for spell blocks
@@ -355,7 +357,8 @@ body {
}
li{
-webkit-column-break-inside : avoid;
column-break-inside : avoid;
page-break-inside : avoid;
break-inside : avoid;
}
}
//*****************************
@@ -380,7 +383,8 @@ body {
text-indent : -1em;
list-style-type : none;
-webkit-column-break-inside : auto;
column-break-inside : auto;
page-break-inside : auto;
break-inside : auto;
}
}
//*****************************
@@ -449,7 +453,8 @@ body {
// *****************************/
.phb .toc{
-webkit-column-break-inside : avoid;
column-break-inside : avoid;
page-break-inside : avoid;
break-inside : avoid;
a{
color : black;
text-decoration : none;

17
docker-compose.yml Normal file
View File

@@ -0,0 +1,17 @@
version: '2'
services:
mongodb:
image: mongo:latest
volumes:
- mongodata:/data/db
homebrewery:
build:
context: .
dockerfile: Dockerfile
image: homebrewery
environment:
MONGODB_URI: mongodb://mongodb/homebrewery
ports:
- "8000:8000"
volumes:
mongodata:

118
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "homebrewery",
"version": "2.7.5",
"version": "2.8.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1067,9 +1067,12 @@
"integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w=="
},
"basic-auth": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz",
"integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ="
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
"integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=",
"requires": {
"safe-buffer": "5.1.1"
}
},
"bcrypt-pbkdf": {
"version": "1.0.1",
@@ -2231,11 +2234,6 @@
"is-symbol": "1.0.1"
}
},
"es6-promise": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz",
"integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q="
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -3863,11 +3861,6 @@
"os-tmpdir": "1.0.2"
}
},
"hooks-fixed": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-2.0.2.tgz",
"integrity": "sha512-YurCM4gQSetcrhwEtpQHhQ4M7Zo7poNGqY4kQGeBS6eZtOcT3tnNs01ThFa0jYBByAiYt1MjMjP/YApG0EnAvQ=="
},
"htmlescape": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz",
@@ -4514,9 +4507,9 @@
"integrity": "sha1-eeoBiRth3mto4T5nwLS1vak3spQ="
},
"kareem": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/kareem/-/kareem-1.5.0.tgz",
"integrity": "sha1-4+QQHZ3P3imXadr0tNtk2JXRdEg="
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.0.6.tgz",
"integrity": "sha512-/C+l8gABdHsAIfNpykJNWmYodpTnDRyn+JhORkP2VgEf1GgdAc+oTHjVADwISwCJKta031EOIwY6+Hki5z8SpQ=="
},
"kind-of": {
"version": "3.2.2",
@@ -4877,58 +4870,54 @@
"integrity": "sha512-1muXCh8jb1N/gHRbn9VDUBr0GYb8A/aVcHlII9QSB68a50spqEVLIGN6KVmCOnSvJrUhC0edGgKU5ofnGXdYdg=="
},
"mongodb": {
"version": "2.2.34",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.34.tgz",
"integrity": "sha1-o09Zu+thdUrsQy3nLD/iFSakTBo=",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.0.4.tgz",
"integrity": "sha512-90YIIs7A4ko4kCGafxxXj3foexCAlJBC0YLwwIKgSLoE7Vni2IqUMz6HSsZ3zbXOfR1KWtxfnc0RyAMAY/ViLg==",
"requires": {
"es6-promise": "3.2.1",
"mongodb-core": "2.1.18",
"readable-stream": "2.2.7"
"mongodb-core": "3.0.4"
}
},
"mongodb-core": {
"version": "2.1.18",
"resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.18.tgz",
"integrity": "sha1-TEYTm986HwMt7ZHbSfOO7AFlkFA=",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.0.4.tgz",
"integrity": "sha512-OTH267FjfwBdEufSnrgd+u8HuLWRuQ6p8DR0XirPl2BdlLEMh4XwjJf1RTlruILp5p2m1w8dDC8rCxibC3W8qQ==",
"requires": {
"bson": "1.0.6",
"require_optional": "1.0.1"
}
},
"mongoose": {
"version": "4.13.12",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.13.12.tgz",
"integrity": "sha512-pH8NK5AYGbnPeEFFGs5ACk18vzzcy4DFT48U9kKvkfg6SI3nJZkzGfN7o1NDWjy+kP26hWyU/AMhYTfe5hSVnA==",
"version": "5.0.13",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.0.13.tgz",
"integrity": "sha512-VCiutgdxwhTuNHIuUgMRWVYvv0GFw6FUi4j14B7um/Wcy1uhuwF552a6XVKUCth/AY8C+PjVU9fVGJ5K0JmrmQ==",
"requires": {
"async": "2.1.4",
"bson": "1.0.6",
"hooks-fixed": "2.0.2",
"kareem": "1.5.0",
"kareem": "2.0.6",
"lodash.get": "4.4.2",
"mongodb": "2.2.34",
"mongodb": "3.0.4",
"mongoose-legacy-pluralize": "1.0.2",
"mpath": "0.3.0",
"mpromise": "0.5.5",
"mquery": "2.3.3",
"mquery": "3.0.0",
"ms": "2.0.0",
"muri": "1.3.0",
"regexp-clone": "0.0.1",
"sliced": "1.0.1"
}
},
"mongoose-legacy-pluralize": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz",
"integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ=="
},
"mpath": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/mpath/-/mpath-0.3.0.tgz",
"integrity": "sha1-elj3iem1/TyUUgY0FXlg8mvV70Q="
},
"mpromise": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mpromise/-/mpromise-0.5.5.tgz",
"integrity": "sha1-9bJCWddjrMIlewoMjG2Gb9UXMuY="
},
"mquery": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/mquery/-/mquery-2.3.3.tgz",
"integrity": "sha512-NC8L14kn+qxJbbJ1gbcEMDxF0sC3sv+1cbRReXXwVvowcwY1y9KoVZFq0ebwARibsadu8lx8nWGvm3V0Pf0ZWQ==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mquery/-/mquery-3.0.0.tgz",
"integrity": "sha512-WL1Lk8v4l8VFSSwN3yCzY9TXw+fKVYKn6f+w86TRzOLSE8k1yTgGaLBPUByJQi8VcLbOdnUneFV/y3Kv874pnQ==",
"requires": {
"bluebird": "3.5.0",
"debug": "2.6.9",
@@ -4948,11 +4937,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"muri": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/muri/-/muri-1.3.0.tgz",
"integrity": "sha512-FiaFwKl864onHFFUV/a2szAl7X0fxVlSKNdhTf+BM8i8goEgYut8u5P9MqQqIYwvaMxjzVESsoEm/2kfkFH1rg=="
},
"mute-stream": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
@@ -5008,9 +4992,9 @@
"dev": true
},
"nconf": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/nconf/-/nconf-0.8.5.tgz",
"integrity": "sha1-8pQeFWGVL6kGu7MjKM+I1MY155Q=",
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/nconf/-/nconf-0.10.0.tgz",
"integrity": "sha512-fKiXMQrpP7CYWJQzKkPPx9hPgmq+YLDyxcG9N8RpiE9FoCkCbzD0NyW0YhE3xn3Aupe7nnDeIx4PFzYehpHT9Q==",
"requires": {
"async": "1.5.2",
"ini": "1.3.5",
@@ -6088,35 +6072,16 @@
}
}
},
"pico-flux": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/pico-flux/-/pico-flux-1.1.0.tgz",
"integrity": "sha1-GgRFbQQValgtKo6Rhyxxk2WMC/s="
},
"pico-router": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/pico-router/-/pico-router-1.3.0.tgz",
"integrity": "sha512-VYvL+ycNF+xxqd/vZdBxEUw4KzYNF0EjpFto0lLllEoN0fRzPLoM76Wkx1iOFbNFKfmUbciV4ec+tdPOOxN3Dw==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/pico-router/-/pico-router-2.1.0.tgz",
"integrity": "sha512-aUTyqGvqbRifVn3StnP7V8QBVcSfsbfpHt+neMgXKPLdxlfgD7kwHv6WzGZxwZ4u6/S6io89hftDy2k1kJHJLQ==",
"requires": {
"create-react-class": "15.6.3",
"lodash": "4.17.5",
"react": "15.6.2",
"react": "16.3.1",
"url": "0.11.0",
"url-pattern": "1.0.3"
},
"dependencies": {
"react": {
"version": "15.6.2",
"resolved": "https://registry.npmjs.org/react/-/react-15.6.2.tgz",
"integrity": "sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=",
"requires": {
"create-react-class": "15.6.3",
"fbjs": "0.8.16",
"loose-envify": "1.3.1",
"object-assign": "4.1.1",
"prop-types": "15.6.1"
}
}
}
},
"pify": {
@@ -7219,11 +7184,6 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
},
"striptags": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/striptags/-/striptags-2.2.1.tgz",
"integrity": "sha1-TEULcI1BuL85zyTEn/I0/Gqr/TI="
},
"subarg": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",

View File

@@ -1,7 +1,7 @@
{
"name": "homebrewery",
"description": "Create authentic looking D&D homebrews using only markdown",
"version": "2.8.0",
"version": "2.8.1",
"repository": {
"type": "git",
"url": "git://github.com/stolksdorf/homebrewery.git"
@@ -38,7 +38,7 @@
"dependencies": {
"babel-preset-env": "^1.1.8",
"babel-preset-react": "^6.24.1",
"basic-auth": "^1.0.3",
"basic-auth": "^2.0.0",
"body-parser": "^1.14.2",
"classnames": "^2.2.0",
"codemirror": "^5.22.0",
@@ -49,14 +49,12 @@
"lodash": "^4.11.2",
"marked": "^0.3.5",
"moment": "^2.11.0",
"mongoose": "^4.3.3",
"nconf": "^0.8.4",
"pico-flux": "^1.1.0",
"pico-router": "^1.1.0",
"mongoose": "^5.0.13",
"nconf": "^0.10.0",
"pico-router": "^2.1.0",
"react": "^16.3.1",
"react-dom": "^16.3.1",
"shortid": "^2.2.4",
"striptags": "^2.1.1",
"superagent": "^3.8.2",
"vitreum": "^4.10.1"
},

View File

@@ -14,7 +14,6 @@
"moment",
"superagent",
"marked",
"pico-router",
"pico-flux"
"pico-router"
]
}

View File

@@ -3,7 +3,7 @@ const jwt = require('jwt-simple');
const express = require('express');
const app = express();
app.use(express.static(`${__dirname}/build`));'';
app.use(express.static(`${__dirname}/build`));
app.use(require('body-parser').json({ limit: '25mb' }));
app.use(require('cookie-parser')());
@@ -14,12 +14,13 @@ const config = require('nconf')
.file('defaults', { file: 'config/default.json' });
//DB
require('mongoose')
.connect(process.env.MONGODB_URI || process.env.MONGOLAB_URI || 'mongodb://localhost/naturalcrit')
.connection.on('error', ()=>{
console.log('Error : Could not connect to a Mongo Database.');
console.log(' If you are running locally, make sure mongodb.exe is running.');
});
const mongoose = require('mongoose');
mongoose.connect(config.get('mongodb_uri') || config.get('mongolab_uri') || 'mongodb://localhost/naturalcrit');
mongoose.connection.on('error', ()=>{
console.log('Error : Could not connect to a Mongo Database.');
console.log(' If you are running locally, make sure mongodb.exe is running.');
throw 'Can not connect to Mongo';
});
//Account MIddleware
@@ -48,7 +49,7 @@ app.get('/source/:id', (req, res)=>{
HomebrewModel.get({ shareId: req.params.id })
.then((brew)=>{
const text = brew.text.replaceAll('<', '&lt;').replaceAll('>', '&gt;');
return res.send(`<code><pre>${text}</pre></code>`);
return res.send(`<code><pre style="white-space: pre-wrap;">${text}</pre></code>`);
})
.catch((err)=>{
console.log(err);
@@ -137,4 +138,4 @@ app.use((req, res)=>{
const PORT = process.env.PORT || 8000;
app.listen(PORT);
console.log(`server on port:${PORT}`);
console.log(`server on port:${PORT}`);

View File

@@ -32,15 +32,6 @@ const RenderWarnings = createClass({
</li>;
}
},
zoom : function(){
return false;
if(window.devicePixelRatio !== 1){
return <li key='zoom'>
<em>Your browser is zoomed. </em> <br />
This can cause content to jump columns.
</li>;
}
}
},
checkWarnings : function(){
const hideDismiss = localStorage.getItem(DISMISS_KEY);

View File

@@ -30,7 +30,11 @@ const CodeEditor = createClass({
value : this.props.value,
lineNumbers : true,
lineWrapping : this.props.wrap,
mode : this.props.language
mode : this.props.language,
extraKeys : {
'Ctrl-B' : this.makeBold,
'Ctrl-I' : this.makeItalic
}
});
this.codeMirror.on('change', this.handleChange);
@@ -38,6 +42,16 @@ const CodeEditor = createClass({
this.updateSize();
},
makeBold : function() {
const selection = this.codeMirror.getSelection();
this.codeMirror.replaceSelection(`**${selection}**`, 'around');
},
makeItalic : function() {
const selection = this.codeMirror.getSelection();
this.codeMirror.replaceSelection(`*${selection}*`, 'around');
},
componentWillReceiveProps : function(nextProps){
if(this.codeMirror && nextProps.value !== undefined && this.codeMirror.getValue() != nextProps.value) {
this.codeMirror.setValue(nextProps.value);

View File

@@ -13,6 +13,11 @@ renderer.html = function (html) {
return html;
};
const sanatizeScriptTags = (content)=>{
return content
.replace(/<script/g, '&lt;script')
.replace(/<\/script>/g, '&lt;/script&gt;');
};
const tagTypes = ['div', 'span', 'a'];
const tagRegex = new RegExp(`(${
@@ -24,7 +29,10 @@ const tagRegex = new RegExp(`(${
module.exports = {
marked : Markdown,
render : (rawBrewText)=>{
return Markdown(rawBrewText, { renderer: renderer });
return Markdown(
sanatizeScriptTags(rawBrewText),
{ renderer: renderer }
);
},
validate : (rawBrewText)=>{

View File

@@ -7,6 +7,7 @@
flex-direction : row;
.pane{
overflow-x : hidden;
overflow-y : hidden;
flex : 1;
}
.divider{
@@ -28,4 +29,4 @@
}
}
}
}
}