mirror of
https://git.proxmox.com/git/proxmox-widget-toolkit
synced 2025-04-30 23:58:31 +00:00
integrate marked as markdown parser
Define our own, rather minimal interface so that we change the parser under the hood if ever needed, I already did so once during evaluating this, as first I checked out Snarkdown[0], which is really nice for the few lines of code it needs, but is a bit to limited for the use case. Currently marked[1] is used, provided by the libjs-marked Debian package. For now statically link the marked parser in on built time to avoid the need to add new directories to serve in our pve/pmg/pbs proxies. This is a bit ugly but can be cleaned up afterwards transparently too. We sanitize the produced HTML ourselves (most MD JS parser/renderer don't do that) by creating a real, but not active, DOM tree and recursively prune bad nodes/attrs from it and let it spit out HTML again at the end. While a tad inefficient it really won't matter for our use case, as the notes/comments we render are only a few KiB of text and it's done on the client side anyway. Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
parent
00cbb47e09
commit
51a2f11c6b
1
debian/control
vendored
1
debian/control
vendored
@ -3,6 +3,7 @@ Section: web
|
|||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Proxmox Support Team <support@proxmox.com>
|
Maintainer: Proxmox Support Team <support@proxmox.com>
|
||||||
Build-Depends: debhelper (>= 12~),
|
Build-Depends: debhelper (>= 12~),
|
||||||
|
libjs-marked,
|
||||||
pve-eslint (>= 7.12.1-1),
|
pve-eslint (>= 7.12.1-1),
|
||||||
Standards-Version: 4.5.1
|
Standards-Version: 4.5.1
|
||||||
Homepage: https://www.proxmox.com
|
Homepage: https://www.proxmox.com
|
||||||
|
9
debian/copyright
vendored
9
debian/copyright
vendored
@ -15,3 +15,12 @@ License: AGPLv3
|
|||||||
.
|
.
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Marked:
|
||||||
|
The Marked JavaScript library is shipped through linkage from the Debian
|
||||||
|
package unmodified alongside proxmox-widget-toolkit.
|
||||||
|
|
||||||
|
Copyright (c) 2018+, MarkedJS (https://github.com/markedjs/) Copyright (c)
|
||||||
|
2011-2018, Christopher Jeffrey (https://github.com/chjj/)
|
||||||
|
|
||||||
|
For the license and copyright details see `/usr/share/doc/libjs-marked/copyright`
|
||||||
|
@ -2,10 +2,15 @@ include defines.mk
|
|||||||
|
|
||||||
SUBDIRS= css images
|
SUBDIRS= css images
|
||||||
|
|
||||||
|
# bundle it for now from the libjs-marked debian package to avoid touching our proxies file mapper,
|
||||||
|
# we could also just ship a link to the packages file and load from same path as the widget-toolkit
|
||||||
|
MARKEDJS=/usr/share/javascript/marked/marked.min.js
|
||||||
|
|
||||||
JSSRC= \
|
JSSRC= \
|
||||||
Utils.js \
|
Utils.js \
|
||||||
Toolkit.js \
|
Toolkit.js \
|
||||||
Logo.js \
|
Logo.js \
|
||||||
|
Parser.js \
|
||||||
mixin/CBind.js \
|
mixin/CBind.js \
|
||||||
data/reader/JsonObject.js \
|
data/reader/JsonObject.js \
|
||||||
data/ProxmoxProxy.js \
|
data/ProxmoxProxy.js \
|
||||||
@ -94,7 +99,7 @@ lint: ${JSSRC}
|
|||||||
proxmoxlib.js: .lint-incremental ${JSSRC}
|
proxmoxlib.js: .lint-incremental ${JSSRC}
|
||||||
# add the version as comment in the file
|
# add the version as comment in the file
|
||||||
echo "// ${DEB_VERSION_UPSTREAM_REVISION}" > $@.tmp
|
echo "// ${DEB_VERSION_UPSTREAM_REVISION}" > $@.tmp
|
||||||
cat ${JSSRC} >> $@.tmp
|
cat ${JSSRC} ${MARKEDJS} >> $@.tmp
|
||||||
mv $@.tmp $@
|
mv $@.tmp $@
|
||||||
|
|
||||||
install: proxmoxlib.js
|
install: proxmoxlib.js
|
||||||
|
45
src/Parser.js
Normal file
45
src/Parser.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// NOTE: just relays parsing to markedjs parser
|
||||||
|
Ext.define('Proxmox.Markdown', {
|
||||||
|
alternateClassName: 'Px.Markdown', // just trying out something, do NOT copy this line
|
||||||
|
singleton: true,
|
||||||
|
|
||||||
|
// transforms HTML to a DOM tree and recursively descends and prunes every branch with a
|
||||||
|
// "bad" node.type and drops "bad" attributes from the remaining nodes.
|
||||||
|
// "bad" means anything which can do XSS or break the layout of the outer page
|
||||||
|
sanitizeHTML: function(input) {
|
||||||
|
if (!input) {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
let _sanitize;
|
||||||
|
_sanitize = (node) => {
|
||||||
|
if (node.nodeType === 3) return;
|
||||||
|
if (node.nodeType !== 1 || /^(script|iframe|object|embed|svg)$/i.test(node.tagName)) {
|
||||||
|
node.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let i=node.attributes.length; i--;) {
|
||||||
|
const name = node.attributes[i].name;
|
||||||
|
// TODO: we may want to also disallow class and id attrs
|
||||||
|
if (!/^(class|id|name|href|src|alt|align|valign)$/i.test(name)) {
|
||||||
|
node.attributes.removeNamedItem(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i=node.childNodes.length; i--;) _sanitize(node.childNodes[i]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const doc = new DOMParser().parseFromString(`<!DOCTYPE html><html><body>${input}`, 'text/html');
|
||||||
|
doc.normalize();
|
||||||
|
|
||||||
|
_sanitize(doc.body);
|
||||||
|
|
||||||
|
return doc.body.innerHTML;
|
||||||
|
},
|
||||||
|
|
||||||
|
parse: function(markdown) {
|
||||||
|
/*global marked*/
|
||||||
|
let unsafeHTML = marked(markdown);
|
||||||
|
|
||||||
|
return `<div class="pmx-md">${this.sanitizeHTML(unsafeHTML)}</div>`;
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
@ -127,3 +127,20 @@ div.right-aligned {
|
|||||||
.x-legend-inner {
|
.x-legend-inner {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* rules for the markdown content, prefix with the .pmx-md class */
|
||||||
|
.pmx-md code {
|
||||||
|
white-space: pre;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pmx-md pre code {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 5px;
|
||||||
|
border-left: 3px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pmx-md strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user