mirror of https://github.com/xwiki-labs/cryptpad
use diffdom for sanitation and better redraws
This commit is contained in:
parent
c62d064ee9
commit
18ea61dc9a
|
@ -1,8 +1,10 @@
|
|||
define([
|
||||
'/bower_components/marked/marked.min.js',
|
||||
'/bower_components/diff-dom/diffDOM.js',
|
||||
'/bower_components/jquery/dist/jquery.min.js',
|
||||
],function (Marked) {
|
||||
var $ = window.jQuery;
|
||||
var DiffDOM = window.diffDOM;
|
||||
|
||||
var truthy = function (x) { return x; };
|
||||
|
||||
|
@ -17,13 +19,78 @@ define([
|
|||
$modal = Slide.$modal = $m;
|
||||
$content = Slide.$content = $c;
|
||||
};
|
||||
|
||||
var forbiddenTags = Slide.forbiddenTags = [
|
||||
'SCRIPT',
|
||||
'IFRAME',
|
||||
'OBJECT',
|
||||
'APPLET',
|
||||
'VIDEO',
|
||||
'AUDIO',
|
||||
];
|
||||
var unsafeTag = function (info) {
|
||||
if (['addAttribute', 'modifyAttribute'].indexOf(info.diff.action) !== -1) {
|
||||
if (/^on/.test(info.diff.name)) {
|
||||
console.log("Rejecting forbidden element attribute with name", info.diff.element.nodeName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (['addElement', 'replaceElement'].indexOf(info.diff.action) !== -1) {
|
||||
var msg = "Rejecting forbidden tag of type (%s)";
|
||||
if (info.diff.element && forbiddenTags.indexOf(info.diff.element.nodeName) !== -1) {
|
||||
console.log(msg, info.diff.element.nodeName);
|
||||
return true;
|
||||
} else if (info.diff.newValue && forbiddenTags.indexOf(info.diff.newValue.nodeName) !== -1) {
|
||||
console.log("Replacing restricted element type (%s) with PRE", info.diff.newValue.nodeName);
|
||||
info.diff.newValue.nodeName = 'PRE';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var domFromHTML = Slide.domFromHTML = function (html) {
|
||||
return new DOMParser().parseFromString(html, "text/html");
|
||||
};
|
||||
|
||||
var DD = new DiffDOM({
|
||||
preDiffApply: function (info) {
|
||||
if (unsafeTag(info)) { return true; }
|
||||
}
|
||||
});
|
||||
|
||||
var makeDiff = function (A, B) {
|
||||
var Err;
|
||||
var Els = [A, B].map(function (frag) {
|
||||
if (typeof(frag) === 'object') {
|
||||
if (!frag && frag.body) {
|
||||
Err = "No body";
|
||||
return;
|
||||
}
|
||||
var els = frag.body.querySelectorAll('#content');
|
||||
if (els.length) {
|
||||
return els[0];
|
||||
}
|
||||
}
|
||||
Err = 'No candidate found';
|
||||
});
|
||||
if (Err) { return Err; }
|
||||
var patch = DD.diff(Els[0], Els[1]);
|
||||
return patch;
|
||||
};
|
||||
|
||||
var draw = Slide.draw = function (i) {
|
||||
console.log("Trying to draw slide #%s", i);
|
||||
if (typeof(Slide.content[i]) !== 'string') { return; }
|
||||
|
||||
var c = Slide.content[i];
|
||||
console.log(c);
|
||||
$content.html(Marked(c));
|
||||
var Dom = domFromHTML('<div id="content">' + Marked(c) + '</div>');
|
||||
var patch = makeDiff(domFromHTML($content[0].outerHTML), Dom);
|
||||
|
||||
if (typeof(patch) === 'string') {
|
||||
$content.html(Marked(c));
|
||||
return;
|
||||
} else {
|
||||
DD.apply($content[0], patch);
|
||||
}
|
||||
};
|
||||
|
||||
var show = Slide.show = function (bool, content) {
|
||||
|
@ -39,9 +106,11 @@ define([
|
|||
|
||||
var update = Slide.update = function (content) {
|
||||
if (!Slide.shown) { return; }
|
||||
console.log(content);
|
||||
var old = Slide.content[Slide.index];
|
||||
Slide.content = content.split(/\n\s*\-\-\-\s*\n/).filter(truthy);
|
||||
draw(Slide.index);
|
||||
if (old !== Slide.content[Slide.index]) {
|
||||
draw(Slide.index);
|
||||
}
|
||||
};
|
||||
|
||||
var left = Slide.left = function () {
|
||||
|
|
Loading…
Reference in New Issue