diff --git a/electroshot-config.json b/electroshot-config.json index a2e392a..4d6b25d 100644 --- a/electroshot-config.json +++ b/electroshot-config.json @@ -1 +1 @@ -[{"url":"http://localhost:8080/#/resume-material-dark","delay":0,"selector":"","zoom-factor":1,"format":"pdf","quality":75,"user-agent":"","latency":null,"download":null,"upload":null,"css":"","js":"","debug":false,"root":"","pdf":{"pageSize":"A4","marginsType":1,"printBackground":true,"landscape":false},"size":{"width":2481,"height":3508},"out":"/home/s/workspace/best-resume-ever/pdf/resume-material-dark.pdf"}] \ No newline at end of file +[{"url":"http://localhost:8080/#/resume/material-dark","delay":0,"selector":"","zoom-factor":1,"format":"pdf","quality":75,"user-agent":"","latency":null,"download":null,"upload":null,"css":"","js":"","debug":false,"root":"","pdf":{"pageSize":"A4","marginsType":1,"printBackground":true,"landscape":false},"size":{"width":2481,"height":3508},"out":"/home/s/workspace/best-resume-ever/pdf/material-dark.pdf"}] \ No newline at end of file diff --git a/node/app.js b/node/app.js index 8df9236..0ededa4 100644 --- a/node/app.js +++ b/node/app.js @@ -26,7 +26,7 @@ const convert = async() => { */ const electroshotScript = resume => { const dir = path.join(__dirname, '../pdf'); - return 'electroshot localhost:8080/#/' + resume + + return 'electroshot localhost:8080/#/resume/' + resume + ' 2481x3508 --pdf-margin none --format pdf --out ' + dir + ' --filename "' + resume + '.pdf" --pdf-background; '; }; @@ -41,8 +41,9 @@ const getResumesFromDirectories = () => { .filter(dir => dir.includes('resume-') && dir !== 'resume-XX') .map(dir => { let name = dir.replace('resume-', ''); + let fileName = dir.replace('.vue', ''); return { - path: dir.replace('.vue', ''), + path: fileName.replace('resume-', ''), name: name.replace('-', ' ') }; }); diff --git a/old/public/js/javascript.js b/old/public/js/javascript.js index 4a650a3..d8a9d03 100755 --- a/old/public/js/javascript.js +++ b/old/public/js/javascript.js @@ -64,7 +64,6 @@ const calcNewFontSizes = elements => { .map(el => getFontSizeOfElement(el) * 0.99); }; - /** * checks if DOM-element has box-shadow * @param {HTMLElement} element @@ -74,7 +73,7 @@ const hasBoxShadow = element => { const style = window .getComputedStyle(element, null) .getPropertyValue('box-shadow'); - if (style != 'none') return style; + if (style !== 'none') return style; else return ''; }; @@ -129,7 +128,7 @@ const addNewBoxShadow = (element, position, boxShadow) => { const getElementsWithShadows = elements => { const ar = [].slice.call(elements); return ar - .filter(el => hasBoxShadow(el) != '') + .filter(el => hasBoxShadow(el) !== '') .map(el => { return { element: el, diff --git a/pdf/resume-material-dark.pdf b/pdf/material-dark.pdf similarity index 88% rename from pdf/resume-material-dark.pdf rename to pdf/material-dark.pdf index 8a3700a..a1f7bb3 100644 Binary files a/pdf/resume-material-dark.pdf and b/pdf/material-dark.pdf differ diff --git a/src/App.vue b/src/App.vue index addbc12..e6c3768 100755 --- a/src/App.vue +++ b/src/App.vue @@ -7,6 +7,7 @@ diff --git a/src/router/index.js b/src/router/index.js index 625e89d..b914e4f 100755 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,6 +1,7 @@ import Vue from 'vue'; import Router from 'vue-router'; import ResumeMaterialDark from '@/components/resume-material-dark'; +import Resume from '@/pages/resume'; Vue.use(Router); @@ -10,6 +11,11 @@ export default new Router({ path: '/resume-material-dark', name: 'resume-material-dark', component: ResumeMaterialDark + }, + { + path: '/resume/:resumeid', + name: 'resume', + component: Resume } ] }); diff --git a/static/javascript.js b/static/javascript.js new file mode 100644 index 0000000..d8a9d03 --- /dev/null +++ b/static/javascript.js @@ -0,0 +1,196 @@ +/** + * gets all DOM-elements on page + * @return {HTMLElement[]} DOM-elements + */ +const getAllDOMElements = () => { + return document.getElementsByTagName('*'); +}; + +/** + * gets DOM-element of #resumeX + * @param {HTMLElement} page + * @return {HTMLElement} + */ +const getResumeDOMElement = page => { + return page.children[0]; +}; + +/** + * returns DOM-element of + * @return {HTMLElement} + */ +const getPageDOMElement = () => { + return document.getElementsByTagName('page')[0]; +}; + +/** + * checks whether auto-font adjustment is enabled for resume + * @param {HTMLElement} resume + * @return {boolean} + */ +const autoFontEnabled = resume => { + return resume.hasAttribute('autofont'); +}; + +/** + * checks whether content is greater than page + * @param {HTMLElement} resume + * @param {HTMLElement} page + * @return {boolean} false if content fits to page + */ +const contentIsGreaterThanPage = (resume, page) => { + const pageHeight = page.offsetHeight; + const resumeHeight = resume.offsetHeight; + if (pageHeight < resumeHeight) return true; + else return false; +}; + +/** + * gets font size of DOM-elemnt + * @param {HTMLElement} element + * @return {number} font size of element + */ +const getFontSizeOfElement = element => { + const style = window.getComputedStyle(element, null).getPropertyValue('font-size'); + return parseFloat(style); +}; + +/** + * calculates new font size of all DOM-elements + * @param {HTMLElement[]} + */ +const calcNewFontSizes = elements => { + return elements + .map(el => getFontSizeOfElement(el) * 0.99); +}; + +/** + * checks if DOM-element has box-shadow + * @param {HTMLElement} element + * @return {string} '' if no shadow, otherwise shadow e.g. 'rgba(0, 0, 0, 0.137255) 0px 2px 2px 0px' + */ +const hasBoxShadow = element => { + const style = window + .getComputedStyle(element, null) + .getPropertyValue('box-shadow'); + if (style !== 'none') return style; + else return ''; +}; + +/** + * gets absolute position of element + * @param {HTMLElement} element + * @return {{}} + */ +const getAbsolutePositionOfElement = element => { + return { + top: element.getBoundingClientRect().top, + left: element.getBoundingClientRect().left + }; +}; + +/** + * gets border radius of element + * @param {HTMLElement} element + * @return {string} e.g. '50%' + */ +const getBorderRadiusOfElement = element => { + return window + .getComputedStyle(element, null) + .getPropertyValue('border-radius'); +}; + +/** + * adds new box shadow + * @param {HTMLElement} element + * @param {{}} position e.g. { left: 10, top: 100} + * @param {string} boxShadow e.g. 'rgba(0, 0, 0, 0.137255) 0px 2px 2px 0px' + */ +const addNewBoxShadow = (element, position, boxShadow) => { + let div = document.createElement('div'); + div.style.height = element.offsetHeight; + div.style.width = element.offsetWidth; + div.style.borderRadius = getBorderRadiusOfElement(element); + div.style.position = 'absolute'; + div.style.boxShadow = boxShadow; + div.style.webkitPrintColorAdjust = 'exact'; + div.style.webkitFilter = 'opacity(1)'; + div.style.top = position.top; + div.style.left = position.left; + document.getElementsByTagName('body')[0].appendChild(div); +}; + +/** + * gets all elements with shadows + * @param {HTMLElement[]} elements on page + * @return {HTMLElement[]} elements with shadows + */ +const getElementsWithShadows = elements => { + const ar = [].slice.call(elements); + return ar + .filter(el => hasBoxShadow(el) !== '') + .map(el => { + return { + element: el, + shadow: hasBoxShadow(el) + }; + }); +}; + +/** + * fixes shadows, since normal box-shadow cannot be printed in chrome, + * see: http://stackoverflow.com/questions/13975198/text-shadow-and-box-shadow-while-printing-chrome + */ +const fixBoxShadows = () => { + const elements = getAllDOMElements(); + const elementsWithShadow = getElementsWithShadows(elements); + elementsWithShadow.forEach(element => { + const position = getAbsolutePositionOfElement(element.element); + element.element.style.boxShadow = 'none'; + addNewBoxShadow(element.element, position, element.shadow); + }); +}; + +/** + * checks if the page contains a resume + * @return {Boolean} true if page contains resume + */ +const isResume = () => { + if (document.getElementsByTagName('page')[0]) return true; + else return false; +}; + +/** + * checks whether font needs to be fixed, and if fixes it + */ +const checkFont = () => { + const page = getPageDOMElement(); + const resume = getResumeDOMElement(page); + const fixFont = function(resume, page) { + const elements = getAllDOMElements(); + const elementsAr = [].slice.call(elements); + const newFontSizes = calcNewFontSizes(elementsAr); + elementsAr.forEach((el, i) => el.style.fontSize = newFontSizes[i] + 'px'); + if (contentIsGreaterThanPage(resume, page)) fixFont(resume, page); + }; + if ( + autoFontEnabled(resume) && + contentIsGreaterThanPage(resume, page) + ) fixFont(resume, page); +}; + +const isElectron = () => { + return window && window.process && window.process.type; +} + +/** + * fixes resume + */ +const fixResume = () => { + if (!isResume()) return; + checkFont(); + //if (isElectron()) + fixBoxShadows(); +}; + +fixResume();