-
Notifications
You must be signed in to change notification settings - Fork 0
/
sanitizer.js
105 lines (86 loc) · 2.27 KB
/
sanitizer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
'use strict';
const jsdom = require('jsdom'),
jquery = require('jquery'),
url = require('url');
function relative(uri) {
return !url.parse(uri || '').host;
}
function fullUrl(uri, baseUrl) {
return (uri && relative(uri)) ? url.resolve(baseUrl, uri) : uri;
}
function removeIframes($doc) {
$doc.find('iframe').remove();
}
function removeScriptTags($doc) {
$doc.find('script').remove();
}
function removeStylesheets($doc) {
$doc.find('link[rel=stylesheet]').remove();
$doc.find('style').remove();
}
function fixImgUrlAttribute($doc, $, baseUrl, name) {
$doc.find('img')
.filter((_, el) => relative($(el).attr(name)))
.each((_, el) => {
const $el = $(el),
attr = $el.attr(name);
$el.attr(name, fullUrl(attr, baseUrl));
});
}
function fixImages($doc, $, baseUrl) {
fixImgUrlAttribute($doc, $, baseUrl, 'src');
fixImgUrlAttribute($doc, $, baseUrl, 'srcset');
}
function fixRelativeUrls($doc, $, baseUrl) {
$doc.find('a').each((_, el) => {
const link = $(el),
href = link.attr('href');
link.attr('href', fullUrl(href, baseUrl));
});
}
function removeShareLinks($doc) {
$doc.find('div.feedflare').remove();
}
function removeEmptyLinks($doc, $) {
$doc.find('a')
.filter((_, el) => $(el).html().trim().length === 0)
.remove();
}
module.exports = (html, postUrl, cb) => {
const opts = {
FetchExternalResources: false,
ProcessExternalResources: false,
MutationEvents: false,
QuerySelector: false
};
if (!postUrl) {
return cb(new Error(`Invalid post url ${postUrl}`));
}
function process(err, window) {
if (err) { return cb(err, html); }
const $ = jquery(window),
$doc = $(window.document);
removeIframes($doc, $, postUrl);
removeScriptTags($doc, $, postUrl);
removeStylesheets($doc, $, postUrl);
fixImages($doc, $, postUrl);
fixRelativeUrls($doc, $, postUrl);
removeShareLinks($doc, $, postUrl);
removeEmptyLinks($doc, $, postUrl);
if (window.document.body) {
cb(null, window.document.body.innerHTML);
} else {
cb(null, window.document.innerHTML);
}
}
try {
jsdom.env({
features: opts,
html,
done: process,
url: postUrl
});
} catch (jsdomErr) {
cb(jsdomErr, html);
}
};