diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index 38d7454a4..6a4040b4d 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -13,6 +13,7 @@ const RenderWarnings = require('homebrewery/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'); const DOMPurify = require('dompurify'); const purifyConfig = { FORCE_BODY: true, SANITIZE_DOM: false }; @@ -159,6 +160,16 @@ const BrewRenderer = (props)=>{ return renderedPages; }; + const handleControlKeys = (e)=>{ + if(!(e.ctrlKey || e.metaKey)) return; + const P_KEY = 80; + if(e.keyCode == P_KEY && props.allowPrint) printCurrentBrew(); + if(e.keyCode == P_KEY) { + e.stopPropagation(); + e.preventDefault(); + } + }; + const frameDidMount = ()=>{ //This triggers when iFrame finishes internal "componentDidMount" setTimeout(()=>{ //We still see a flicker where the style isn't applied yet, so wait 100ms before showing iFrame updateSize(); @@ -200,6 +211,8 @@ const BrewRenderer = (props)=>{ >
diff --git a/client/homebrew/brewRenderer/brewRenderer.less b/client/homebrew/brewRenderer/brewRenderer.less index 0406cad29..28ea8005e 100644 --- a/client/homebrew/brewRenderer/brewRenderer.less +++ b/client/homebrew/brewRenderer/brewRenderer.less @@ -64,3 +64,16 @@ color : white; background-color : #333333; } + +@media print { + .brewRenderer { + height: 100%; + overflow-y: unset; + .pages { + margin: 0px; + &>.page { + box-shadow: unset; + } + } + } +} \ No newline at end of file diff --git a/client/homebrew/homebrew.jsx b/client/homebrew/homebrew.jsx index 8c82f33e7..2489bc1ca 100644 --- a/client/homebrew/homebrew.jsx +++ b/client/homebrew/homebrew.jsx @@ -10,7 +10,6 @@ const UserPage = require('./pages/userPage/userPage.jsx'); const SharePage = require('./pages/sharePage/sharePage.jsx'); const NewPage = require('./pages/newPage/newPage.jsx'); const ErrorPage = require('./pages/errorPage/errorPage.jsx'); -const PrintPage = require('./pages/printPage/printPage.jsx'); const AccountPage = require('./pages/accountPage/accountPage.jsx'); const WithRoute = (props)=>{ @@ -72,15 +71,13 @@ const Homebrew = createClass({ } /> } /> } /> - } /> - } /> } /> } /> } /> } /> } /> - } /> - } /> + } /> + } />
@@ -88,15 +85,4 @@ const Homebrew = createClass({ } }); -module.exports = Homebrew; - -//TODO: Nicer Error page instead of just "cant get that" -// '/share/:id' : (args)=>{ -// if(!this.props.brew.shareId){ -// return ; -// } -// -// return ; -// }, +module.exports = Homebrew; \ No newline at end of file diff --git a/client/homebrew/navbar/print.navitem.jsx b/client/homebrew/navbar/print.navitem.jsx index 54af0bb41..f80c1aa66 100644 --- a/client/homebrew/navbar/print.navitem.jsx +++ b/client/homebrew/navbar/print.navitem.jsx @@ -1,8 +1,9 @@ const React = require('react'); const Nav = require('naturalcrit/nav/nav.jsx'); +const { printCurrentBrew } = require('../../../shared/helpers.js'); -module.exports = function(props){ - return +module.exports = function(){ + return get PDF ; }; diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 3e7bd0c2a..20282f9b5 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -11,7 +11,7 @@ const Navbar = require('../../navbar/navbar.jsx'); const NewBrew = require('../../navbar/newbrew.navitem.jsx'); const HelpNavItem = require('../../navbar/help.navitem.jsx'); -const PrintLink = require('../../navbar/print.navitem.jsx'); +const PrintNavItem = require('../../navbar/print.navitem.jsx'); const ErrorNavItem = require('../../navbar/error-navitem.jsx'); const Account = require('../../navbar/account.navitem.jsx'); const RecentNavItem = require('../../navbar/recent.navitem.jsx').both; @@ -23,6 +23,7 @@ const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); const Markdown = require('naturalcrit/markdown.js'); const { DEFAULT_BREW_LOAD } = require('../../../../server/brewDefaults.js'); +const { printCurrentBrew } = require('../../../../shared/helpers.js'); const googleDriveIcon = require('../../googleDrive.svg'); @@ -95,7 +96,7 @@ const EditPage = createClass({ const S_KEY = 83; const P_KEY = 80; if(e.keyCode == S_KEY) this.trySave(true); - if(e.keyCode == P_KEY) window.open(`/print/${this.processShareId()}?dialog=true`, '_blank').focus(); + if(e.keyCode == P_KEY) printCurrentBrew(); if(e.keyCode == P_KEY || e.keyCode == S_KEY){ e.stopPropagation(); e.preventDefault(); @@ -378,7 +379,7 @@ const EditPage = createClass({ post to reddit - + @@ -410,6 +411,7 @@ const EditPage = createClass({ errors={this.state.htmlErrors} lang={this.state.brew.lang} currentEditorPage={this.state.currentEditorPage} + allowPrint={true} /> diff --git a/client/homebrew/pages/hijackPrint.js b/client/homebrew/pages/hijackPrint.js deleted file mode 100644 index c59076413..000000000 --- a/client/homebrew/pages/hijackPrint.js +++ /dev/null @@ -1,12 +0,0 @@ -//TODO: Depricate - -module.exports = function(shareId){ - return function(event){ - event = event || window.event; - if((event.ctrlKey || event.metaKey) && event.keyCode == 80){ - const win = window.open(`/homebrew/print/${shareId}?dialog=true`, '_blank'); - win.focus(); - event.preventDefault(); - } - }; -}; \ No newline at end of file diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index 99a1beb64..f2525c425 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -7,6 +7,7 @@ const request = require('../../utils/request-middleware.js'); const Markdown = require('naturalcrit/markdown.js'); const Nav = require('naturalcrit/nav/nav.jsx'); +const PrintNavItem = require('../../navbar/print.navitem.jsx'); const Navbar = require('../../navbar/navbar.jsx'); const AccountNavItem = require('../../navbar/account.navitem.jsx'); const ErrorNavItem = require('../../navbar/error-navitem.jsx'); @@ -18,6 +19,7 @@ const Editor = require('../../editor/editor.jsx'); const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); const { DEFAULT_BREW } = require('../../../../server/brewDefaults.js'); +const { printCurrentBrew } = require('../../../../shared/helpers.js'); const BREWKEY = 'homebrewery-new'; const STYLEKEY = 'homebrewery-new-style'; @@ -89,7 +91,7 @@ const NewPage = createClass({ const S_KEY = 83; const P_KEY = 80; if(e.keyCode == S_KEY) this.save(); - if(e.keyCode == P_KEY) this.print(); + if(e.keyCode == P_KEY) printCurrentBrew(); if(e.keyCode == P_KEY || e.keyCode == S_KEY){ e.stopPropagation(); e.preventDefault(); @@ -180,16 +182,6 @@ const NewPage = createClass({ } }, - print : function(){ - window.open('/print?dialog=true&local=print', '_blank'); - }, - - renderLocalPrintButton : function(){ - return - get PDF - ; - }, - renderNavbar : function(){ return @@ -202,7 +194,7 @@ const NewPage = createClass({ : this.renderSaveButton() } - {this.renderLocalPrintButton()} + @@ -231,6 +223,7 @@ const NewPage = createClass({ errors={this.state.htmlErrors} lang={this.state.brew.lang} currentEditorPage={this.state.currentEditorPage} + allowPrint={true} /> diff --git a/client/homebrew/pages/printPage/printPage.jsx b/client/homebrew/pages/printPage/printPage.jsx deleted file mode 100644 index 7cda5d8c0..000000000 --- a/client/homebrew/pages/printPage/printPage.jsx +++ /dev/null @@ -1,112 +0,0 @@ -require('./printPage.less'); -const React = require('react'); -const createClass = require('create-react-class'); -const _ = require('lodash'); -const { Meta } = require('vitreum/headtags'); -const MarkdownLegacy = require('naturalcrit/markdownLegacy.js'); -const Markdown = require('naturalcrit/markdown.js'); - -const Themes = require('themes/themes.json'); - -const BREWKEY = 'homebrewery-new'; -const STYLEKEY = 'homebrewery-new-style'; -const METAKEY = 'homebrewery-new-meta'; - -const PrintPage = createClass({ - displayName : 'PrintPage', - getDefaultProps : function() { - return { - query : {}, - brew : { - text : '', - style : '', - renderer : 'legacy', - lang : '' - } - }; - }, - - getInitialState : function() { - return { - brew : { - text : this.props.brew.text || '', - style : this.props.brew.style || undefined, - renderer : this.props.brew.renderer || 'legacy', - theme : this.props.brew.theme || '5ePHB', - lang : this.props.brew.lang || 'en' - } - }; - }, - - componentDidMount : function() { - if(this.props.query.local == 'print'){ - const brewStorage = localStorage.getItem(BREWKEY); - const styleStorage = localStorage.getItem(STYLEKEY); - const metaStorage = JSON.parse(localStorage.getItem(METAKEY)); - - this.setState((prevState, prevProps)=>{ - return { - brew : { - text : brewStorage, - style : styleStorage, - renderer : metaStorage?.renderer || 'legacy', - theme : metaStorage?.theme || '5ePHB', - lang : metaStorage?.lang || 'en' - } - }; - }); - } - - if(this.props.query.dialog) window.print(); - }, - - renderStyle : function() { - if(!this.state.brew.style) return; - //return
@layer styleTab {\n${this.state.brew.style}\n} ` }} />; - return
\n${this.state.brew.style}\n` }} />; - }, - - renderPages : function(){ - if(this.state.brew.renderer == 'legacy') { - return _.map(this.state.brew.text.split('\\page'), (pageText, index)=>{ - return
; - }); - } else { - return _.map(this.state.brew.text.split(/^\\page$/gm), (pageText, index)=>{ - pageText += `\n\n \n\\column\n `; //Artificial column break at page end to emulate column-fill:auto (until `wide` is used, when column-fill:balance will reappear) - return ( -
-
-
- ); - }); - } - - }, - - render : function(){ - const rendererPath = this.state.brew.renderer == 'V3' ? 'V3' : 'Legacy'; - const themePath = this.state.brew.theme ?? '5ePHB'; - const baseThemePath = Themes[rendererPath][themePath].baseTheme; - - return
- - - {baseThemePath && - - } - - {/* Apply CSS from Style tab */} - {this.renderStyle()} -
- {this.renderPages()} -
-
; - } -}); - -module.exports = PrintPage; diff --git a/client/homebrew/pages/printPage/printPage.less b/client/homebrew/pages/printPage/printPage.less deleted file mode 100644 index 0d9e7b68b..000000000 --- a/client/homebrew/pages/printPage/printPage.less +++ /dev/null @@ -1,3 +0,0 @@ -.printPage{ - -} \ No newline at end of file diff --git a/client/homebrew/pages/sharePage/sharePage.jsx b/client/homebrew/pages/sharePage/sharePage.jsx index 2eab5f34a..9695ee810 100644 --- a/client/homebrew/pages/sharePage/sharePage.jsx +++ b/client/homebrew/pages/sharePage/sharePage.jsx @@ -6,14 +6,13 @@ const { Meta } = require('vitreum/headtags'); const Nav = require('naturalcrit/nav/nav.jsx'); const Navbar = require('../../navbar/navbar.jsx'); const MetadataNav = require('../../navbar/metadata.navitem.jsx'); -const PrintLink = require('../../navbar/print.navitem.jsx'); +const PrintNavItem = require('../../navbar/print.navitem.jsx'); const RecentNavItem = require('../../navbar/recent.navitem.jsx').both; const Account = require('../../navbar/account.navitem.jsx'); - - const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx'); const { DEFAULT_BREW_LOAD } = require('../../../../server/brewDefaults.js'); +const { printCurrentBrew } = require('../../../../shared/helpers.js'); const SharePage = createClass({ displayName : 'SharePage', @@ -35,7 +34,7 @@ const SharePage = createClass({ if(!(e.ctrlKey || e.metaKey)) return; const P_KEY = 80; if(e.keyCode == P_KEY){ - window.open(`/print/${this.processShareId()}?dialog=true`, '_blank').focus(); + if(e.keyCode == P_KEY) printCurrentBrew(); e.stopPropagation(); e.preventDefault(); } @@ -72,7 +71,7 @@ const SharePage = createClass({ {this.props.brew.shareId && <> - + source @@ -95,7 +94,13 @@ const SharePage = createClass({
- +
; } diff --git a/server/app.js b/server/app.js index a08ab4404..e26c98f54 100644 --- a/server/app.js +++ b/server/app.js @@ -331,13 +331,6 @@ app.get('/share/:id', asyncHandler(getBrew('share')), asyncHandler(async (req, r return next(); })); -//Print Page -app.get('/print/:id', asyncHandler(getBrew('share')), (req, res, next)=>{ - sanitizeBrew(req.brew, 'share'); - splitTextStyleAndMetadata(req.brew); - next(); -}); - //Account Page app.get('/account', asyncHandler(async (req, res, next)=>{ const data = {}; diff --git a/shared/helpers.js b/shared/helpers.js index 42dd09e3f..8ca185046 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -17,6 +17,18 @@ const splitTextStyleAndMetadata = (brew)=>{ } }; -module.exports = { - splitTextStyleAndMetadata +const printCurrentBrew = ()=>{ + if(window.typeof !== 'undefined') { + window.frames['BrewRenderer'].contentWindow.print(); + //Force DOM reflow; Print dialog causes a repaint, and @media print CSS somehow makes out-of-view pages disappear + const node = window.frames['BrewRenderer'].contentDocument.getElementsByClassName('brewRenderer').item(0); + node.style.display='none'; + node.offsetHeight; // accessing this is enough to trigger a reflow + node.style.display=''; + } +}; + +module.exports = { + splitTextStyleAndMetadata, + printCurrentBrew };