Merge pull request #2436 from tsiegleauq/issue2433-PdfInvalidHTML

Repairs invalid HTML during PDF generation (fixes #2433)
This commit is contained in:
Norman Jäckel 2016-09-26 20:51:04 +02:00 committed by GitHub
commit 8398e3abf0
2 changed files with 35 additions and 7 deletions

View File

@ -23,6 +23,29 @@ angular.module('OpenSlidesApp.core.site', [
// Can be used to find out if the projector or the side is used // Can be used to find out if the projector or the side is used
.constant('REALM', 'site') .constant('REALM', 'site')
//for global usage
.factory('HTMLValidizer', function() {
var HTMLValidizer = {};
//checks if str is valid HTML. Returns valid HTML if not,
//return emptystring if empty
HTMLValidizer.validize = function(str) {
if (str) {
var a = document.createElement('div');
a.innerHTML = str;
angular.forEach(a.childNodes, function (child) {
if (child.nodeType == 1) {
return str;
}
});
return "<p>" + str + "</p>";
} else {
return ""; //needed for blank "reaons" field
}
};
return HTMLValidizer;
})
.factory('PdfMakeDocumentProvider', [ .factory('PdfMakeDocumentProvider', [
'gettextCatalog', 'gettextCatalog',
'Config', 'Config',
@ -116,7 +139,9 @@ angular.module('OpenSlidesApp.core.site', [
}; };
} }
]) ])
.factory('PdfMakeConverter', function() { .factory('PdfMakeConverter', [
'HTMLValidizer',
function(HTMLValidizer) {
/** /**
* Converter component for HTML->JSON for pdfMake * Converter component for HTML->JSON for pdfMake
* @constructor * @constructor
@ -471,7 +496,8 @@ angular.module('OpenSlidesApp.core.site', [
* @param {object} htmlText - * @param {object} htmlText -
*/ */
ParseHtml = function(converted, htmlText) { ParseHtml = function(converted, htmlText) {
var html = $(htmlText.replace(/\t/g, "").replace(/\n/g, "")); var html = HTMLValidizer.validize(htmlText);
html = $(html.replace(/\t/g, "").replace(/\n/g, ""));
var emptyParagraph = create("text"); var emptyParagraph = create("text");
slice(html).forEach(function(element) { slice(html).forEach(function(element) {
ParseElement(converted, element); ParseElement(converted, element);
@ -509,7 +535,7 @@ angular.module('OpenSlidesApp.core.site', [
return { return {
createInstance: createInstance createInstance: createInstance
}; };
}) }])
// Provider to register entries for the main menu. // Provider to register entries for the main menu.
.provider('mainMenu', [ .provider('mainMenu', [

View File

@ -916,9 +916,10 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
'PdfMakeConverter', 'PdfMakeConverter',
'PdfMakeDocumentProvider', 'PdfMakeDocumentProvider',
'gettextCatalog', 'gettextCatalog',
'HTMLValidizer',
function($scope, $state, $http, ngDialog, MotionForm, Motion, Category, Tag, Workflow, User, Agenda, MotionDocxExport, function($scope, $state, $http, ngDialog, MotionForm, Motion, Category, Tag, Workflow, User, Agenda, MotionDocxExport,
MotionContentProvider, MotionCatalogContentProvider, PdfMakeConverter, MotionContentProvider, MotionCatalogContentProvider, PdfMakeConverter,
PdfMakeDocumentProvider, gettextCatalog) { PdfMakeDocumentProvider, gettextCatalog, HTMLValidizer) {
Motion.bindAll({}, $scope, 'motions'); Motion.bindAll({}, $scope, 'motions');
Category.bindAll({}, $scope, 'categories'); Category.bindAll({}, $scope, 'categories');
Tag.bindAll({}, $scope, 'tags'); Tag.bindAll({}, $scope, 'tags');
@ -1084,7 +1085,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
//save the arrays of the filtered motions to an array //save the arrays of the filtered motions to an array
angular.forEach($scope.motionsFiltered, function (motion) { angular.forEach($scope.motionsFiltered, function (motion) {
var content = motion.getText() + motion.getReason(); var content = HTMLValidizer.validize(motion.getText($scope.version)) + HTMLValidizer.validize(motion.getReason($scope.version));
var map = Function.prototype.call.bind([].map); var map = Function.prototype.call.bind([].map);
var tmp_image_sources = map($(content).find("img"), function(element) { var tmp_image_sources = map($(content).find("img"), function(element) {
return element.getAttribute("src"); return element.getAttribute("src");
@ -1190,9 +1191,10 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
'MotionInlineEditing', 'MotionInlineEditing',
'gettextCatalog', 'gettextCatalog',
'Projector', 'Projector',
'HTMLValidizer',
function($scope, $http, ngDialog, MotionForm, Motion, Category, Mediafile, Tag, User, Workflow, Config, function($scope, $http, ngDialog, MotionForm, Motion, Category, Mediafile, Tag, User, Workflow, Config,
motion, MotionContentProvider, PollContentProvider, motion, MotionContentProvider, PollContentProvider,
PdfMakeConverter, PdfMakeDocumentProvider, MotionInlineEditing, gettextCatalog, Projector) { PdfMakeConverter, PdfMakeDocumentProvider, MotionInlineEditing, gettextCatalog, Projector, HTMLValidizer) {
Motion.bindOne(motion.id, $scope, 'motion'); Motion.bindOne(motion.id, $scope, 'motion');
Category.bindAll({}, $scope, 'categories'); Category.bindAll({}, $scope, 'categories');
Mediafile.bindAll({}, $scope, 'mediafiles'); Mediafile.bindAll({}, $scope, 'mediafiles');
@ -1242,7 +1244,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
}; };
$scope.makePDF = function() { $scope.makePDF = function() {
var content = motion.getText() + motion.getReason(); var content = HTMLValidizer.validize(motion.getText($scope.version)) + HTMLValidizer.validize(motion.getReason($scope.version));
var map = Function.prototype.call.bind([].map); var map = Function.prototype.call.bind([].map);
var image_sources = map($(content).find("img"), function(element) { var image_sources = map($(content).find("img"), function(element) {
return element.getAttribute("src"); return element.getAttribute("src");