Merge pull request #2926 from emanuelschuetze/issue-2923
Fixed dynamic pdf header and footer for worker (Fixed #2923).
This commit is contained in:
commit
aade91cead
@ -34,7 +34,7 @@
|
|||||||
"ngstorage": "~0.3.11",
|
"ngstorage": "~0.3.11",
|
||||||
"ngBootbox": "~0.1.3",
|
"ngBootbox": "~0.1.3",
|
||||||
"papaparse": "~4.1.2",
|
"papaparse": "~4.1.2",
|
||||||
"pdfmake": "0.1.23",
|
"pdfmake": "0.1.25",
|
||||||
"roboto-fontface": "~0.6.0"
|
"roboto-fontface": "~0.6.0"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
|
@ -228,9 +228,13 @@ gulp.task('default', [
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Watches changes in JavaScript and templates.
|
// Watches changes in JavaScript and templates.
|
||||||
gulp.task('watch', ['js', 'templates'], function () {
|
gulp.task('watch', ['js', 'templates', 'pdf-worker'], function () {
|
||||||
gulp.watch(path.join('openslides', '*', 'static', 'js', '**', '*.js'), ['js']);
|
gulp.watch([
|
||||||
|
path.join('openslides', '*', 'static', 'js', '**', '*.js'),
|
||||||
|
'!' + path.join('openslides', 'core', 'static', 'js', 'core', 'pdf-worker.js')
|
||||||
|
], ['js']);
|
||||||
gulp.watch(path.join('openslides', '*', 'static', 'templates', '**', '*.html'), ['templates']);
|
gulp.watch(path.join('openslides', '*', 'static', 'templates', '**', '*.html'), ['templates']);
|
||||||
|
gulp.watch(path.join('openslides', 'core', 'static', 'js', 'core', 'pdf-worker.js'), ['pdf-worker']);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Extracts translatable strings using angular-gettext and saves them in file
|
// Extracts translatable strings using angular-gettext and saves them in file
|
||||||
|
@ -30,6 +30,72 @@ pdfMake.fonts = {
|
|||||||
// Create PDF on message and return the base64 decoded document
|
// Create PDF on message and return the base64 decoded document
|
||||||
self.addEventListener('message', function(e) {
|
self.addEventListener('message', function(e) {
|
||||||
var data = JSON.parse(e.data);
|
var data = JSON.parse(e.data);
|
||||||
|
|
||||||
|
// Workaround for using dynamic footer with page number.
|
||||||
|
// TODO: Needs improvement of pdfmake's web worker support.
|
||||||
|
// see https://github.com/bpampuch/pdfmake/issues/38
|
||||||
|
if (data.footerTpl) {
|
||||||
|
data.footer = function (currentPage, pageCount) {
|
||||||
|
var footerText = data.footerTpl.text
|
||||||
|
.replace('{{currentPage}}', currentPage)
|
||||||
|
.replace('{{pageCount}}', pageCount);
|
||||||
|
return {
|
||||||
|
text: footerText,
|
||||||
|
alignment: data.footerTpl.alignment,
|
||||||
|
fontSize: data.footerTpl.fontSize,
|
||||||
|
color: data.footerTpl.color
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Workaround for using table layout functions.
|
||||||
|
// TODO: Needs improvement of pdfmake's web worker support.
|
||||||
|
// Currently only functions are allowed for 'layout'.
|
||||||
|
// But functions cannot be passed to workers (via JSON).
|
||||||
|
//
|
||||||
|
// ballot paper crop marks
|
||||||
|
for (var i = 0; i < data.content.length; i++) {
|
||||||
|
if (data.content[i].layout === "{{ballot-placeholder-to-insert-functions-here}}") {
|
||||||
|
data.content[i].layout = {
|
||||||
|
hLineWidth: function(i, node) {
|
||||||
|
if (i === 0){
|
||||||
|
return 0;
|
||||||
|
} else if (i === node.table.body.length) {
|
||||||
|
if (node.rowsperpage && node.rowsperpage > i) {
|
||||||
|
return 0.5;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0.5;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
vLineWidth: function(i, node) {
|
||||||
|
return (i === 0 || i === node.table.widths.length) ? 0 : 0.5;
|
||||||
|
},
|
||||||
|
hLineColor: function() {
|
||||||
|
return 'gray';
|
||||||
|
},
|
||||||
|
vLineColor: function() {
|
||||||
|
return 'gray';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// motion meta table border lines
|
||||||
|
if (data.content[i].layout === "{{motion-placeholder-to-insert-functions-here}}") {
|
||||||
|
data.content[i].layout = {
|
||||||
|
hLineWidth: function(i, node) {
|
||||||
|
return (i === 0 || i === node.table.body.length) ? 0 : 0.5;
|
||||||
|
},
|
||||||
|
vLineWidth: function() {
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
hLineColor: function() {
|
||||||
|
return 'white';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
var pdf = pdfMake.createPdf(data);
|
var pdf = pdfMake.createPdf(data);
|
||||||
pdf.getBase64(function (base64) {
|
pdf.getBase64(function (base64) {
|
||||||
self.postMessage(base64);
|
self.postMessage(base64);
|
||||||
|
@ -84,40 +84,7 @@ angular.module('OpenSlidesApp.core.pdf', [])
|
|||||||
|
|
||||||
// crop marks for ballot papers
|
// crop marks for ballot papers
|
||||||
PDFLayout.getBallotLayoutLines = function() {
|
PDFLayout.getBallotLayoutLines = function() {
|
||||||
return {
|
return '{{ballot-placeholder-to-insert-functions-here}}';
|
||||||
hLineWidth: function(i, node) {
|
|
||||||
if (i === 0){
|
|
||||||
return 0;
|
|
||||||
} else if (i === node.table.body.length) {
|
|
||||||
if (node.rowsperpage && node.rowsperpage > i) {
|
|
||||||
return 0.5;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return 0.5;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
vLineWidth: function(i, node) {
|
|
||||||
return (i === 0 || i === node.table.widths.length) ? 0 : 0.5;
|
|
||||||
},
|
|
||||||
hLineColor: function(i, node) {
|
|
||||||
if (i === 0){
|
|
||||||
return 'none';
|
|
||||||
} else if (i === node.table.body.length) {
|
|
||||||
if (node.rowsperpage && node.rowsperpage > i) {
|
|
||||||
return 'gray';
|
|
||||||
} else {
|
|
||||||
return 'none';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return 'gray';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
vLineColor: function(i, node) {
|
|
||||||
return (i === 0 || i === node.table.widths.length) ? 'none' : 'gray';
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return PDFLayout;
|
return PDFLayout;
|
||||||
@ -161,8 +128,7 @@ angular.module('OpenSlidesApp.core.pdf', [])
|
|||||||
*/
|
*/
|
||||||
var createInstance = function(contentProvider) {
|
var createInstance = function(contentProvider) {
|
||||||
// PDF header
|
// PDF header
|
||||||
var header = function() {
|
var getHeader = function() {
|
||||||
var date = new Date();
|
|
||||||
var columns = [];
|
var columns = [];
|
||||||
|
|
||||||
// add here your custom logo (which has to be added to a custom vfs_fonts.js)
|
// add here your custom logo (which has to be added to a custom vfs_fonts.js)
|
||||||
@ -196,14 +162,17 @@ angular.module('OpenSlidesApp.core.pdf', [])
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// PDF footer
|
// PDF footer
|
||||||
var footer = function(currentPage, pageCount) {
|
// Used placeholder for currentPage and pageCount which
|
||||||
|
// are replaced by dynamic footer function in pdf-worker.js.
|
||||||
|
var getFooter = function() {
|
||||||
return {
|
return {
|
||||||
alignment: 'center',
|
alignment: 'center',
|
||||||
fontSize: 8,
|
fontSize: 8,
|
||||||
color: '#555',
|
color: '#555',
|
||||||
text: gettextCatalog.getString('Page') + ' ' + currentPage.toString() +
|
text: gettextCatalog.getString('Page') +
|
||||||
' / ' + pageCount.toString()
|
' {{currentPage}} / {{pageCount}}'
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
// Generates the document(definition) for pdfMake
|
// Generates the document(definition) for pdfMake
|
||||||
@ -211,13 +180,13 @@ angular.module('OpenSlidesApp.core.pdf', [])
|
|||||||
var content = contentProvider.getContent();
|
var content = contentProvider.getContent();
|
||||||
return {
|
return {
|
||||||
pageSize: 'A4',
|
pageSize: 'A4',
|
||||||
pageMargins: [80, 90, 80, 60],
|
pageMargins: [80, 90, 80, 100],
|
||||||
defaultStyle: {
|
defaultStyle: {
|
||||||
font: 'PdfFont',
|
font: 'PdfFont',
|
||||||
fontSize: 10
|
fontSize: 10
|
||||||
},
|
},
|
||||||
header: header,
|
header: getHeader(),
|
||||||
footer: noFooter ? '' : footer,
|
footerTpl: noFooter ? '' : getFooter(),
|
||||||
content: content,
|
content: content,
|
||||||
styles: {
|
styles: {
|
||||||
title: {
|
title: {
|
||||||
@ -393,12 +362,12 @@ angular.module('OpenSlidesApp.core.pdf', [])
|
|||||||
"u": ["text-decoration:underline"],
|
"u": ["text-decoration:underline"],
|
||||||
"em": ["font-style:italic"],
|
"em": ["font-style:italic"],
|
||||||
"i": ["font-style:italic"],
|
"i": ["font-style:italic"],
|
||||||
"h1": ["font-size:30"],
|
"h1": ["font-size:14", "font-weight:bold"],
|
||||||
"h2": ["font-size:28"],
|
"h2": ["font-size:12", "font-weight:bold"],
|
||||||
"h3": ["font-size:26"],
|
"h3": ["font-size:10", "font-weight:bold"],
|
||||||
"h4": ["font-size:24"],
|
"h4": ["font-size:10", "font-style:italic"],
|
||||||
"h5": ["font-size:22"],
|
"h5": ["font-size:10"],
|
||||||
"h6": ["font-size:20"],
|
"h6": ["font-size:10"],
|
||||||
"a": ["color:blue", "text-decoration:underline"],
|
"a": ["color:blue", "text-decoration:underline"],
|
||||||
"del": ["color:red", "text-decoration:line-through"],
|
"del": ["color:red", "text-decoration:line-through"],
|
||||||
"ins": ["color:green", "text-decoration:underline"]
|
"ins": ["color:green", "text-decoration:underline"]
|
||||||
@ -563,6 +532,8 @@ angular.module('OpenSlidesApp.core.pdf', [])
|
|||||||
case "h5":
|
case "h5":
|
||||||
case "h6":
|
case "h6":
|
||||||
currentParagraph = create("text");
|
currentParagraph = create("text");
|
||||||
|
currentParagraph.marginBottom = 4;
|
||||||
|
currentParagraph.marginTop = 10;
|
||||||
/* falls through */
|
/* falls through */
|
||||||
case "a":
|
case "a":
|
||||||
currentParagraph = parseChildren(alreadyConverted, element, currentParagraph, styles.concat(elementStyles[nodeName]), diff_mode);
|
currentParagraph = parseChildren(alreadyConverted, element, currentParagraph, styles.concat(elementStyles[nodeName]), diff_mode);
|
||||||
@ -666,6 +637,7 @@ angular.module('OpenSlidesApp.core.pdf', [])
|
|||||||
//in case of inline-line-numbers and the os-line-break class ignore the break
|
//in case of inline-line-numbers and the os-line-break class ignore the break
|
||||||
if (!(lineNumberMode == "inline" && element.getAttribute("class") == "os-line-break")) {
|
if (!(lineNumberMode == "inline" && element.getAttribute("class") == "os-line-break")) {
|
||||||
currentParagraph = create("text");
|
currentParagraph = create("text");
|
||||||
|
currentParagraph.lineHeight = 1.25;
|
||||||
alreadyConverted.push(currentParagraph);
|
alreadyConverted.push(currentParagraph);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -680,7 +652,8 @@ angular.module('OpenSlidesApp.core.pdf', [])
|
|||||||
break;
|
break;
|
||||||
case "p":
|
case "p":
|
||||||
currentParagraph = create("text");
|
currentParagraph = create("text");
|
||||||
currentParagraph.margin = [0,5];
|
currentParagraph.marginTop = 8;
|
||||||
|
currentParagraph.lineHeight = 1.25;
|
||||||
var stackP = create("stack");
|
var stackP = create("stack");
|
||||||
stackP.stack.push(currentParagraph);
|
stackP.stack.push(currentParagraph);
|
||||||
ComputeStyle(stackP, styles);
|
ComputeStyle(stackP, styles);
|
||||||
|
@ -40,7 +40,7 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
|
|||||||
metaTableBody.push([
|
metaTableBody.push([
|
||||||
{
|
{
|
||||||
text: gettextCatalog.getString('Submitters') + ':',
|
text: gettextCatalog.getString('Submitters') + ':',
|
||||||
style: ['bold', 'grey']
|
style: ['bold', 'grey'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: submitters,
|
text: submitters,
|
||||||
@ -79,8 +79,7 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
|
|||||||
metaTableBody.push([
|
metaTableBody.push([
|
||||||
{
|
{
|
||||||
text: gettextCatalog.getString('Category') + ':',
|
text: gettextCatalog.getString('Category') + ':',
|
||||||
style: ['bold', 'grey']
|
style: ['bold', 'grey'] },
|
||||||
},
|
|
||||||
{
|
{
|
||||||
text: motion.category.name,
|
text: motion.category.name,
|
||||||
style: 'grey'
|
style: 'grey'
|
||||||
@ -216,26 +215,17 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// build table
|
// build table
|
||||||
|
// Used placeholder for 'layout' functions whiche are
|
||||||
|
// replaced by lineWitdh/lineColor function in pfd-worker.js.
|
||||||
|
// TODO: Remove placeholder and us static values for LineWidth and LineColor
|
||||||
|
// if pdfmake has fixed this.
|
||||||
var metaTableJsonString = {
|
var metaTableJsonString = {
|
||||||
table: {
|
table: {
|
||||||
widths: ['30%','70%'],
|
widths: ['30%','70%'],
|
||||||
body: metaTableBody,
|
body: metaTableBody,
|
||||||
},
|
},
|
||||||
margin: [0, 0, 0, 20],
|
margin: [0, 0, 0, 20],
|
||||||
layout: {
|
layout: '{{motion-placeholder-to-insert-functions-here}}'
|
||||||
hLineWidth: function(i, node) {
|
|
||||||
return (i === 0 || i === node.table.body.length) ? 0 : 0.5;
|
|
||||||
},
|
|
||||||
vLineWidth: function(i, node) {
|
|
||||||
return (i === 0 || i === node.table.widths.length) ? 0 : 0;
|
|
||||||
},
|
|
||||||
hLineColor: function(i, node) {
|
|
||||||
return (i === 0 || i === node.table.body.length) ? '' : 'white';
|
|
||||||
},
|
|
||||||
vLineColor: function(i, node) {
|
|
||||||
return (i === 0 || i === node.table.widths.length) ? '' : 'white';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
return metaTableJsonString;
|
return metaTableJsonString;
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,7 @@ import bleach
|
|||||||
|
|
||||||
allowed_tags = [
|
allowed_tags = [
|
||||||
'a', 'img', # links and images
|
'a', 'img', # links and images
|
||||||
'p', 'span', 'blockquote', # text layout
|
'br', 'p', 'span', 'blockquote', # text layout
|
||||||
'strike', 'strong', 'u', 'em', 'sup', 'sub', 'pre', # text formatting
|
'strike', 'strong', 'u', 'em', 'sup', 'sub', 'pre', # text formatting
|
||||||
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', # headings
|
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', # headings
|
||||||
'ol', 'ul', 'li', # lists
|
'ol', 'ul', 'li', # lists
|
||||||
|
Loading…
Reference in New Issue
Block a user