+
+
+
+
+
\ No newline at end of file
diff --git a/docs/scripts/global.js b/docs/scripts/global.js
new file mode 100644
index 0000000..4599321
--- /dev/null
+++ b/docs/scripts/global.js
@@ -0,0 +1,144 @@
+// utilities
+let get = function (selector, scope) {
+ scope = scope ? scope : document;
+ return scope.querySelector(selector);
+};
+
+let getAll = function (selector, scope) {
+ scope = scope ? scope : document;
+ return scope.querySelectorAll(selector);
+};
+
+// toggle tabs on codeblock
+window.addEventListener("load", function () {
+ // get all tab_containers in the document
+ let tabContainers = getAll(".tab__container");
+
+ // bind click event to each tab container
+ for (let i = 0; i < tabContainers.length; i++) {
+ const tab_menu = get('.tab__menu', tabContainers[i])
+ get('.tab__menu', tabContainers[i]).addEventListener("click", tabClick);
+ // console.log(tab_menu, tab_menu.classList, tab_menu.classList.contains("function"))
+
+ // if (tab_menu.classList.contains("function")) tab_menu.addEventListener("click", tabFunctionClick);
+ // else tab_menu.addEventListener("click", tabClick);
+ }
+
+ // each click event is scoped to the tab_container
+ function tabClick(event) {
+ let scope = event.currentTarget.parentNode;
+ let clickedTab = event.target;
+ let tabs = getAll('.tab', scope);
+ let panes = getAll('.tab__pane', scope);
+ let activePane = get(`.${clickedTab.getAttribute('data-tab')}`, scope);
+
+ // remove all active tab classes
+ for (let i = 0; i < tabs.length; i++) {
+ tabs[i].classList.remove('active');
+ }
+
+ // remove all active pane classes
+ for (let i = 0; i < panes.length; i++) {
+ panes[i].classList.remove('active');
+ }
+
+ // apply active classes on desired tab and pane
+ clickedTab.classList.add('active');
+
+ if (clickedTab.classList.contains("function")) {
+ let functionString = clickedTab.getAttribute('data-function')
+ let functionArgsString = clickedTab.getAttribute('data-function-arguments')
+
+ if (window[functionString] && typeof(window[functionString]) === "function") window[functionString].apply({}, JSON.parse(functionArgsString || "[]"))
+ } else {
+ activePane.classList.add('active');
+ }
+ }
+});
+
+//in page scrolling for documentaiton page
+let btns = getAll('.js-btn');
+let sections = getAll('.js-section');
+
+function setActiveLink(event) {
+ // remove all active tab classes
+ for (let i = 0; i < btns.length; i++) {
+ btns[i].classList.remove('selected');
+ }
+
+ event.target.classList.add('selected');
+}
+
+function smoothScrollTo(i, event) {
+ let element = sections[i];
+ setActiveLink(event);
+
+ window.scrollTo({
+ 'behavior': 'smooth',
+ 'top': element.offsetTop - 20,
+ 'left': 0
+ });
+}
+
+function triggerClick(elemID) {
+ const element = document.getElementById(elemID)
+ if (element) element.click()
+}
+
+if (btns.length && sections.length > 0) {
+ for (let i = 0; i < btns.length; i++) {
+ btns[i].addEventListener('click', smoothScrollTo.bind(this, i));
+ }
+}
+
+// fix menu to page-top once user starts scrolling
+window.addEventListener('scroll', function () {
+ let docNav = get('.doc__nav > ul');
+
+ if (docNav) {
+ if (window.pageYOffset > 63) {
+ docNav.classList.add('fixed');
+ } else {
+ docNav.classList.remove('fixed');
+ }
+ }
+});
+
+// responsive navigation
+let topNav = get('.menu');
+let icon = get('.toggle');
+
+window.addEventListener('load', function () {
+ function showNav() {
+ if (topNav.className === 'menu') {
+ topNav.className += ' responsive';
+ icon.className += ' open';
+ } else {
+ topNav.className = 'menu';
+ icon.classList.remove('open');
+ }
+ }
+ icon.addEventListener('click', showNav);
+});
+
+function changeMdFormatter(id, formatter) {
+ const mdTag = document.getElementById(id)
+ const term = mdTag.parentElement
+
+ switch (formatter) {
+ case "github": {
+ term.style.backgroundColor = "var(--bg-color)"
+ break;
+ }
+ // case "marked":
+ // case "commonmark": {
+ // term.style.backgroundColor = "#605F5F"
+ // break;
+ // }
+ default: {
+ term.style.backgroundColor = "var(--medium-gray-color)"//"#605F5F" //"#232323"
+ }
+ }
+
+ if (mdTag) mdTag.setAttribute("flavor", formatter)
+}
\ No newline at end of file
diff --git a/docs/stylesheets/docs.css b/docs/stylesheets/docs.css
new file mode 100644
index 0000000..0d22525
--- /dev/null
+++ b/docs/stylesheets/docs.css
@@ -0,0 +1,125 @@
+html,
+body {
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+}
+
+a {
+ color: var(--accent-color);
+}
+
+/* layout */
+.header {
+ border-bottom: 1px solid var(--code-bg-color);
+ grid-template-columns: 1fr 150px 60% 1fr;
+}
+
+.wrapper {
+ display: flex;
+ flex-grow: 1;
+}
+
+/* logo */
+.logo {
+ font-weight: 900;
+ color: var(--primary-color);
+ font-size: 1.4em;
+ grid-column: 2;
+}
+
+.logo__thin {
+ font-weight: 300;
+}
+
+/* menu */
+.menu {
+ grid-template-columns: 1fr 180px 60% 1fr;
+}
+
+.menu__item {
+ padding: 1.5rem 1rem;
+}
+
+/* doc */
+.doc__bg {
+ position: fixed;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ width: 28%;
+ background-color: var(--bg-color);
+ z-index: -1;
+}
+
+.doc__nav {
+ flex-basis: 20%;
+ font-weight: 200;
+}
+
+.doc__nav ul {
+ list-style: none;
+ padding-left: 0;
+ line-height: 1.8;
+}
+
+.doc__nav ul.fixed {
+ position: fixed;
+ top: 2rem;
+}
+
+.doc__nav li:hover {
+ color: var(--primary-color-light);
+ cursor: pointer;
+ transition: color .3s ease-in-out;
+}
+
+.doc__nav .selected {
+ color: var(--accent-color);
+ position: relative;
+}
+
+.doc__nav .selected:after {
+ position: absolute;
+ content: "";
+ width: 1rem;
+ height: 1rem;
+ background-color: var(--accent-color);
+ left: -1.5rem;
+ top: 0.3rem;
+}
+
+.doc__content {
+ flex-basis: 80%;
+ padding: 0 0 5rem 1rem;
+}
+
+@media (max-width: 750px) {
+ .wrapper {
+ flex-direction: column;
+ }
+
+ .doc__content {
+ padding-left: 0;
+ }
+
+ .doc__nav ul {
+ border-bottom: 1px solid var(--code-bg-color);
+ padding-bottom: 0.5rem;
+ }
+
+ .doc__nav ul.fixed {
+ /* nutralized the fixed menu for mobile*/
+ position: relative;
+ top: 0;
+ }
+
+ .doc__nav li {
+ display: inline-block;
+ padding-right: 1rem;
+ }
+
+ .doc__nav .selected:after {
+ display: none;
+ }
+}
\ No newline at end of file
diff --git a/docs/stylesheets/global.css b/docs/stylesheets/global.css
new file mode 100644
index 0000000..1be3d14
--- /dev/null
+++ b/docs/stylesheets/global.css
@@ -0,0 +1,333 @@
+/* css variables*/
+:root {
+ --primary-color: #432E30;
+ --primary-color-light: #8E7474;
+ --accent-color: #FE6A6B;
+ --accent-color-light: #FFE4E4;
+ --accent-color-dark: #B94B4C;
+ --white-color: #FAFBFC;
+ --light-gray-color: #C6CBD1;
+ --medium-gray-color: #959DA5;
+ --dark-gray-color: #444D56;
+ --bg-color: #F8F8FA;
+ --code-bg-color: #F0E8E8;
+ --scrollbar-bg: rgb(201 201 201);
+ --scrollbar-thumb: rgb(133 133 133);
+}
+
+/* Scrollbar */
+*::-webkit-scrollbar {
+ width: 12px; /* width of the entire scrollbar */
+}
+*::-webkit-scrollbar-track {
+ background: var(--scrollbar-bg); /* color of the tracking area */
+}
+*::-webkit-scrollbar-thumb {
+ background-color: var(--scrollbar-thumb); /* color of the scroll thumb */
+ border-radius: 20px; /* roundness of the scroll thumb */
+ border: 3px solid var(--scrollbar-bg); /* creates padding around scroll thumb */
+}
+
+
+/* normalized */
+html,
+body {
+ padding: 0;
+ margin: 0;
+ font-family: 'Nunito Sans', sans-serif;
+ background-color: white;
+}
+
+p {
+ font-weight: 300;
+ color: #4A4A4A;
+}
+
+a,
+a:hover {
+ text-decoration: none;
+ color: var(--primary-color);
+}
+
+hr {
+ padding: 1rem 0;
+ border: 0;
+ border-bottom: 1px solid var(--bg-color);
+}
+
+* {
+ box-sizing: border-box;
+}
+
+/* global components */
+
+/* typography */
+.section__title {
+ color: var(--primary-color);
+}
+
+/* tabs */
+.tab__container {
+ position: relative;
+}
+
+.tab__container>ul {
+ position: absolute;
+ list-style: none;
+ margin: 0;
+ right: 1rem;
+ top: -2rem;
+ padding-left: 0;
+}
+
+.tab__container .code {
+ white-space: normal;
+ padding: 1rem 1.5rem;
+}
+
+.tab {
+ display: inline-block;
+ padding: 0.3rem 0.5rem;
+ font-weight: 200;
+ cursor: pointer;
+}
+
+.tab.active {
+ border-bottom: 1px solid var(--primary-color);
+ font-weight: 700;
+ display: inline-block;
+}
+
+.tab__pane {
+ display: none;
+}
+
+.tab__pane.active {
+ display: block;
+}
+
+/* code */
+.code {
+ border-radius: 3px;
+ font-family: Space Mono, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
+ background: var(--bg-color);
+ border: 1px solid var(--code-bg-color);
+ color: var(--primary-color-light);
+}
+
+.code--block {
+ white-space: pre-line;
+ padding: 0 1.5rem;
+}
+
+.code--inline {
+ padding: 3px 6px;
+ font-size: 80%;
+}
+
+/* buttons */
+.button--primary {
+ padding: 10px 22px;
+ background-color: var(--accent-color);
+ color: white;
+ position: relative;
+ text-decoration: none;
+ border: 0;
+ transition: all .3s ease-out;
+}
+
+.button--primary:after {
+ position: absolute;
+ content: "";
+ width: 1rem;
+ height: 1rem;
+ background-color: var(--accent-color-light);
+ right: -0.4rem;
+ top: -0.4rem;
+ transition: all 0.3s ease-out;
+}
+
+.button--primary:hover {
+ text-shadow: 0px 1px 1px var(--accent-color-dark);
+ color: white;
+ transform: translate3D(0, -3px, 0);
+}
+
+.button--primary:hover::after {
+ transform: rotate(90deg);
+}
+
+.button--secondary {
+ padding: 10px 22px;
+ border: 2px solid var(--primary-color);
+ transition: all 0.5s ease-out;
+}
+
+.button--secondary:hover {
+ border-color: var(--accent-color);
+ color: var(--accent-color);
+}
+
+/* links */
+.link {
+ text-decoration: none;
+ transition: all 0.3s ease-out;
+}
+
+.link:hover {
+ color: var(--accent-color);
+}
+
+.link--dark {
+ color: var(--primary-color);
+}
+
+.link--light {
+ color: var(--accent-color);
+}
+
+/* menu */
+nav {
+ display: grid;
+ grid-template-columns: 70px auto;
+}
+
+.menu {
+ margin: 0;
+ text-align: right;
+ overflow: hidden;
+ list-style: none;
+}
+
+.toggle {
+ display: none;
+ position: relative;
+}
+
+.toggle span,
+.toggle span:before,
+.toggle span:after {
+ content: '';
+ position: absolute;
+ height: 2px;
+ width: 18px;
+ border-radius: 2px;
+ background: var(--primary-color);
+ display: block;
+ cursor: pointer;
+ transition: all 0.3s ease-in-out;
+ right: 0;
+}
+
+.toggle span:before {
+ top: -6px;
+}
+
+.toggle span:after {
+ bottom: -6px;
+}
+
+.toggle.open span {
+ background-color: transparent;
+}
+
+.toggle.open span:before,
+.toggle.open span:after {
+ top: 0;
+}
+
+.toggle.open span:before {
+ transform: rotate(45deg);
+}
+
+.toggle.open span:after {
+ transform: rotate(-45deg);
+}
+
+.menu__item {
+ padding: 1rem;
+ display: inline-block;
+}
+
+.menu__item.toggle {
+ display: none;
+}
+
+/* table */
+table {
+ border-collapse: collapse;
+ width: 100%;
+ transition: color .3s ease-out;
+ margin-bottom: 2rem;
+}
+
+table td,
+table th {
+ border: 1px solid var(--code-bg-color);
+ padding: 0.8rem;
+ font-weight: 300;
+}
+
+table th {
+ text-align: left;
+ background-color: white;
+ border-color: white;
+ border-bottom-color: var(--code-bg-color);
+}
+
+table td:first-child {
+ background-color: var(--bg-color);
+ font-weight: 600;
+}
+
+@media screen and (max-width: 600px) {
+ nav {
+ grid-template-columns: 70px auto;
+ }
+
+ .menu__item {
+ display: none;
+ }
+
+ .menu__item.toggle {
+ display: inline-block;
+ }
+
+ .menu {
+ text-align: right;
+ padding: 0.5rem 1rem;
+ }
+
+ .toggle {
+ display: block;
+ }
+
+ .menu.responsive .menu__item:not(:first-child) {
+ display: block;
+ padding: 0 0 0.5rem 0;
+ }
+}
+
+/* layout */
+.wrapper {
+ margin: 0 auto;
+ width: 70%;
+}
+
+.footer {
+ text-align: center;
+ background-color: var(--primary-color);
+ padding: 2rem;
+ color: white;
+}
+
+@keyframes fadeUp {
+ 0% {
+ opacity: 0;
+ transform: translate3d(0, 30px, 0);
+ }
+
+ 100% {
+ transform: translate3d(0, 0, 0);
+ }
+}
\ No newline at end of file
diff --git a/docs/stylesheets/landing.css b/docs/stylesheets/landing.css
new file mode 100644
index 0000000..472e6c1
--- /dev/null
+++ b/docs/stylesheets/landing.css
@@ -0,0 +1,193 @@
+/* nav specialized to landing page */
+.logo {
+ background: url('../svg/logo.svg') no-repeat;
+ background-size: contain;
+ margin: 1rem 0 0 1rem;
+}
+
+nav {
+ background-color: var(--bg-color);
+}
+
+/* hero section */
+.hero {
+ text-align: center;
+ background-color: var(--bg-color);
+ padding: 2rem 0 10rem 0;
+}
+
+.hero__title {
+ font-weight: 900;
+ color: var(--primary-color);
+}
+
+.hero__description {
+ margin: -1rem auto 2rem auto;
+}
+
+/* @keyframes fadeUp { from { opacity: 0; } to { opacity: 1; }} */
+@keyframes fadeUp {
+ from {
+ transform: translate3d(0,40px,0);
+ opacity: 0;
+ }
+
+ to {
+ transform: translate3d(0,0,0);
+ opacity: 1
+ }
+}
+.hero__terminal {
+ margin-top: 1px !important;
+ width: 60%;
+ margin: -11rem auto 3rem auto;
+ text-align: left;
+ color: white;
+ padding: 0 1rem;
+ border-radius: 4px;
+ background-color: #605F5F;
+ min-height: 285px;
+ animation: fadeUp 2s;
+ box-shadow: 0px 12px 36.8px 9.2px rgba(0, 0, 0, 0.1);
+ opacity: 0;
+ animation-fill-mode: forwards;
+}
+
+.hero__image {
+ width: 60%;
+ margin: -11rem auto 3rem auto;
+ text-align: center;
+ color: white;
+ padding: 0 1rem;
+ border-radius: 4px;
+ background-color: transparent;
+ min-height: 285px;
+ animation: fadeUp 2s;
+ box-shadow: 0px 12px 36.8px 9.2px rgba(0, 0, 0, 0.1);
+ display: flex;
+ justify-content: center;
+}
+
+.hero__image img {
+ display: block;
+ /* max-width:230px;
+ max-height:95px; */
+ width: auto;
+ height: auto;
+}
+
+.hero__image pre {
+ background-color: transparent;
+ white-space: pre-line;
+ padding-top: 1rem;
+}
+
+.hero__terminal pre {
+ white-space: pre-line;
+ padding-top: 1rem;
+}
+
+/* feature section */
+.feature {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ justify-content: center;
+}
+
+.feature__item {
+ max-width: calc(33% - 20px);
+ margin: 0 20px 0 0;
+}
+
+.feature__item .section__title {
+ margin-bottom: 0;
+}
+
+.feature__item p {
+ margin-top: 0.5rem;
+}
+
+/* callout section */
+.callout {
+ text-align: center;
+ padding: 1rem 0 3rem 0;
+}
+
+.callout .button--primary {
+ display: inline-block;
+ margin-top: 0.5rem;
+}
+
+/* changelog section */
+.changelog {
+ background-color: var(--bg-color);
+ padding: 2rem 0;
+}
+
+.changelog__item {
+ display: flex;
+}
+
+.changelog__meta {
+ flex-basis: 25%;
+}
+
+.changelog__meta small {
+ color: var(--primary-color-light);
+ font-weight: 200;
+ letter-spacing: 1px;
+}
+
+.changelog__title {
+ margin-bottom: 0;
+}
+
+.changelog__callout {
+ margin: 3rem auto 2rem auto;
+ text-align: center;
+}
+
+@media (max-width: 750px) {
+ .hero__terminal {
+ width: 70%;
+ }
+
+ .hero__terminal pre .hero__terminal {
+ margin-left: 0;
+ margin-right: 0;
+ }
+
+ .hero__terminal .tab__container {
+ left: 70% !important;
+ }
+
+ .hero__image {
+ width: 70%;
+ }
+
+ .hero__image img {
+ /* width: 70%; */
+ transform: scale(0.5, 0.5);
+ }
+
+ .tab__container>ul {
+ right: auto;
+ left: 0;
+ padding-left: 0;
+ }
+
+ .tab__container .code {
+ margin-top: 2rem;
+ }
+
+ .feature,
+ .changelog__item {
+ flex-direction: column;
+ }
+
+ .feature__item {
+ max-width: 100%;
+ margin: 0;
+ }
+}
\ No newline at end of file
diff --git a/docs/svg/logo.svg b/docs/svg/logo.svg
new file mode 100644
index 0000000..171ea25
--- /dev/null
+++ b/docs/svg/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/markdown-tag-wc.js b/markdown-tag-wc.js
new file mode 100644
index 0000000..2ac9dae
--- /dev/null
+++ b/markdown-tag-wc.js
@@ -0,0 +1,433 @@
+/*! (c) Andrea Giammarchi (https://github.com/WebReflection/html-parsed-element) - ISC */
+const HTMLParsedElement = (() => {
+ const DCL = 'DOMContentLoaded';
+ const init = new WeakMap;
+ const queue = [];
+ const isParsed = el => {
+ do {
+ if (el.nextSibling)
+ return true;
+ } while (el = el.parentNode);
+ return false;
+ };
+ const upgrade = () => {
+ queue.splice(0).forEach(info => {
+ if (init.get(info[0]) !== true) {
+ init.set(info[0], true);
+ info[0][info[1]]();
+ }
+ });
+ };
+ document.addEventListener(DCL, upgrade);
+ class HTMLParsedElement extends HTMLElement {//HTMLTextAreaElement
+ static withParsedCallback(Class, name = 'parsed') {
+ const {
+ prototype
+ } = Class;
+ const {
+ connectedCallback
+ } = prototype;
+ const method = name + 'Callback';
+ const cleanUp = (el, observer, ownerDocument, onDCL) => {
+ observer.disconnect();
+ ownerDocument.removeEventListener(DCL, onDCL);
+ parsedCallback(el);
+ };
+ const parsedCallback = el => {
+ if (!queue.length)
+ requestAnimationFrame(upgrade);
+ queue.push([el, method]);
+ };
+ Object.defineProperties(
+ prototype, {
+ connectedCallback: {
+ configurable: true,
+ writable: true,
+ value() {
+ if (connectedCallback)
+ connectedCallback.apply(this, arguments);
+ if (method in this && !init.has(this)) {
+ const self = this;
+ const {
+ ownerDocument
+ } = self;
+ init.set(self, false);
+ if (ownerDocument.readyState === 'complete' || isParsed(self))
+ parsedCallback(self);
+ else {
+ const onDCL = () => cleanUp(self, observer, ownerDocument, onDCL);
+ ownerDocument.addEventListener(DCL, onDCL);
+ const observer = new MutationObserver(() => {
+ /* istanbul ignore else */
+ if (isParsed(self))
+ cleanUp(self, observer, ownerDocument, onDCL);
+ });
+ observer.observe(self.parentNode, {
+ childList: true,
+ subtree: true
+ });
+ }
+ }
+ }
+ },
+ [name]: {
+ configurable: true,
+ get() {
+ return init.get(this) === true;
+ }
+ }
+ }
+ );
+ return Class;
+ }
+ }
+ return HTMLParsedElement.withParsedCallback(HTMLParsedElement);
+})();
+
+// WIP: Extend BuiltIn Element to prevent script injection
+// const ClassMixin = (baseClass, ...mixins) => {
+// class base extends baseClass {
+// constructor (...args) {
+// super(...args);
+// mixins.forEach((mixin) => {
+// copyProps(this,(new mixin));
+// });
+// }
+// }
+// let copyProps = (target, source) => { // this function copies all properties and symbols, filtering out some special ones
+// Object.getOwnPropertyNames(source)
+// .concat(Object.getOwnPropertySymbols(source))
+// .forEach((prop) => {
+// if (!prop.match(/^(?:constructor|prototype|arguments|caller|name|bind|call|apply|toString|length)$/))
+// Object.defineProperty(target, prop, Object.getOwnPropertyDescriptor(source, prop));
+// })
+// }
+// mixins.forEach((mixin) => { // outside contructor() to allow aggregation(A,B,C).staticFunction() to be called etc.
+// copyProps(base.prototype, mixin.prototype);
+// copyProps(base, mixin);
+// });
+// return base;
+// }
+
+/**
+ * Markdown Tag Web Component Script
+ * By: DarkenLM
+ */
+
+function mdt_wc_init() {
+ class MDTag extends HTMLParsedElement {// ClassMixin(HTMLTextAreaElement, HTMLParsedElement) WIP: Extend BuiltIn Element to prevent script injection
+ constructor() {
+ super();
+ this.generated = false
+ this.defaultFlavor = "showdown"
+ this.defaultParserRoot = "./"
+ this.flavors = [
+ "commonmark",
+ "github",
+ "marked",
+ "showdown"
+ ]
+
+ this.shadow = this.attachShadow({mode: 'open'});
+ this.headID = `md-tag-head-${Date.now()}${Math.floor(Math.random() * 999) + 1}`
+
+ const shadowHead = document.createElement("head")
+ shadowHead.id = this.headID
+ this.shadow.appendChild(shadowHead)
+ this.contentObserver = null
+ }
+
+ get parserRoot() {
+ return this.hasAttribute("parser_root") ? this.getAttribute("parser_root") : this.defaultParserRoot;
+ }
+
+ set parserRoot(val) {
+ if (val && typeof(val) === "string") {
+ this.setAttribute("parser_root", val);
+ } else this.setAttribute("parser_root", this.defaultParserRoot)
+ }
+
+ get flavor() {
+ return this.hasAttribute("flavor") ? this.flavors.includes(this.getAttribute("flavor")) ? this.getAttribute("flavor") : this.defaultFlavor: this.defaultFlavor;
+ }
+
+ set flavor(val) {
+ if (val && typeof(val) === "string") {
+ if (this.flavors.includes(val)) {
+ this.setAttribute("flavor", val);
+ } else this.setAttribute("flavor", this.defaultFlavor);
+ } else this.setAttribute("flavor", this.defaultFlavor);
+ }
+
+ get raw() {
+ const contentDiv = this.shadow.querySelector("div[md-tag-role='raw']")
+ if (contentDiv) {
+ return contentDiv.innerHTML
+ }
+ }
+
+ set raw(val) {
+ const contentDiv = this.shadow.querySelector("div[md-tag-role='raw']")
+ if (contentDiv) {
+ contentDiv.innerHTML = val
+ this.generateMarkdown()
+ return;
+ }
+ }
+
+ addCss(url) {
+ const head = this.shadow.querySelector(`#${this.headID}`)
+ const link = document.createElement("link");
+
+ link.id = `md-style-${Date.now()}${Math.floor(Math.random() * 999) + 1}`
+ link.type = "text/css";
+ link.rel = "stylesheet";
+ link.href = url;
+
+ head.appendChild(link);
+ }
+
+ assertStyleSheet(url) {
+ const ss = this.shadow.styleSheets
+ for (let i = 0, max = ss.length; i < max; i++) {
+ if (ss[i].href === url) return true;
+ }
+
+ return false
+ }
+
+ addJs(url) {
+ return new Promise((resolve, reject) => {
+ try {
+ const head = document.head;
+ const script = document.createElement("script");
+
+ script.id = `md-script-${Date.now()}${Math.floor(Math.random() * 999) + 1}`
+ script.type = "text/javascript";
+ script.src = url;
+
+ script.addEventListener("load", () => {
+ resolve()
+ })
+
+ head.appendChild(script);
+ } catch(e) {
+ reject(e)
+ }
+ })
+ }
+
+ removeScriptTagWithURL(url) {
+ const head = document.head;
+ const script = document.querySelector(`script[src="${url}"]`)
+
+ if (script) {
+ head.removeChild(script)
+ return true
+ } else return false
+ }
+
+ async ensureMarkdownParser(parser) {
+ if (parser) {
+ switch (parser) {
+ case "showdown": {
+ if (!window.hasOwnProperty("showdown")) {
+ try {
+ await this.addJs(`${this.parserRoot.endsWith("/") ? this.parserRoot.slice(0, -1) : this.parserRoot}/showdown/showdown.min.js`).catch(e => { throw e })
+ } catch(e) {
+ if (!window.hasOwnProperty("showdown")) {
+ await this.addJs("https://cdn.jsdelivr.net/npm/showdown@2.1.0/dist/showdown.min.js")
+ } else return true
+
+ if (!window.hasOwnProperty("showdown")) {
+ console.error(`Unable to load markdown parser "showdown": ${e}`)
+ return false
+ }
+ }
+ }
+ break;
+ }
+ case "commonmark": {
+ if (!window.hasOwnProperty("md")) {
+ try {
+ await this.addJs(`${this.parserRoot.endsWith("/") ? this.parserRoot.slice(0, -1) : this.parserRoot}/commonmark/markdown-it.min.js`).catch(e => { throw e })
+ } catch(e) {
+ if (!window.hasOwnProperty("md")) {
+ await this.addJs("https://cdn.jsdelivr.net/npm/markdown-it@13.0.1/dist/markdown-it.min.js")
+ } else return true
+
+ if (!window.hasOwnProperty("md")) {
+ console.error(`Unable to load markdown parser "markdown-it": ${e}`)
+ return false
+ }
+ }
+ }
+ break;
+ }
+ case "marked": {
+ if (!window.hasOwnProperty("marked")) {
+ try {
+ await this.addJs(`${this.parserRoot.endsWith("/") ? this.parserRoot.slice(0, -1) : this.parserRoot}/marked/marked.min.js`).catch(e => { throw e })
+ } catch(e) {
+ if (!window.hasOwnProperty("marked")) {
+ await this.addJs("https://cdn.jsdelivr.net/npm/marked/marked.min.js")
+ } else return true
+
+ if (!window.hasOwnProperty("marked")) {
+ console.error(`Unable to load markdown parser "marked": ${e}`)
+ return false
+ }
+ }
+ }
+ break;
+ }
+ case "DOMPurify": {
+ if (!window.hasOwnProperty("DOMPurify")) {
+ try {
+ await this.addJs(`${this.parserRoot.endsWith("/") ? this.parserRoot.slice(0, -1) : this.parserRoot}/DOMPurify/purify.min.js`).catch(e => { throw e })
+ } catch(e) {
+ if (!window.hasOwnProperty("DOMPurify")) {
+ await this.addJs("https://cdn.jsdelivr.net/npm/dompurify@2.3.8/dist/purify.min.js")
+ } else return true
+
+ if (!window.hasOwnProperty("DOMPurify")) {
+ console.error(`Unable to load markdown parser addon "DOMPurify": ${e}`)
+ return false
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ sanitizeHTML(html) {
+ let sanitized = DOMPurify.sanitize(html)
+ return sanitized
+ }
+
+ async generateMarkdown() {
+ const flavor = this.flavor
+ let contentDiv = this.shadow.querySelector("div[md-tag-role='raw']")
+ let displayDiv = this.shadow.querySelector("div[md-tag-role='display']")
+
+ if (!contentDiv || !displayDiv) this.generateFields()
+ contentDiv = this.shadow.querySelector("div[md-tag-role='raw']")
+ displayDiv = this.shadow.querySelector("div[md-tag-role='display']")
+
+ await this.ensureMarkdownParser("DOMPurify")
+
+ switch (flavor) {
+ case "commonmark": {
+ await this.ensureMarkdownParser("commonmark")
+ const md = window.markdownit()
+ displayDiv.innerHTML = md.render(this.sanitizeHTML(contentDiv.innerHTML))
+ break;
+ }
+ case "marked": {
+ await this.ensureMarkdownParser("marked")
+ displayDiv.innerHTML = window.marked.parse(this.sanitizeHTML(contentDiv.innerText))
+ break;
+ }
+ case "github": {
+ const css = "https://cdn.jsdelivr.net/gh/MarketingPipeline/Markdown-Elements/stylesheets/github_md.css"
+ if (!this.assertStyleSheet(css)) this.addCss(css)
+ await this.ensureMarkdownParser("showdown")
+
+ const converter = new window.showdown.Converter()
+ converter.setOption('tables', 'on')
+ converter.setOption('emoji', 'on')
+ converter.setOption('strikethrough', 'on');
+ converter.setOption('tasklists', 'true');
+ converter.setOption('ghMentions', 'true');
+ converter.setOption('simplifiedAutoLink', 'true');
+
+ const githubMDTag = document.createElement("github-md")
+ githubMDTag.innerHTML = converter.makeHtml(this.sanitizeHTML(contentDiv.innerText))
+
+ displayDiv.innerHTML = ""
+ displayDiv.appendChild(githubMDTag)
+ break;
+ }
+ case "showdown":
+ default: {
+ await this.ensureMarkdownParser("showdown")
+
+ const converter = new window.showdown.Converter()
+ converter.setOption('tables', 'on')
+ converter.setOption('emoji', 'on')
+ converter.setOption('strikethrough', 'on');
+ converter.setOption('tasklists', 'true');
+ converter.setOption('ghMentions', 'true');
+ converter.setOption('simplifiedAutoLink', 'true');
+
+ displayDiv.innerHTML = converter.makeHtml(this.sanitizeHTML(contentDiv.innerText))
+ }
+ }
+ }
+
+ generateFields() {
+ const _contentDiv = this.shadow.querySelector("div[md-tag-role='raw']")
+ const _displayDiv = this.shadow.querySelector("div[md-tag-role='display']")
+
+ if (_contentDiv && _displayDiv) return;
+
+ let contentDiv = document.createElement("div")
+ if (!_contentDiv) {
+ contentDiv.setAttribute("md-tag-role", "raw")
+ contentDiv.style.display = "none"
+ contentDiv.innerHTML = _contentDiv?.innerHTML || this.innerHTML
+ }
+
+ let displayDiv = document.createElement("div")
+ if (!_displayDiv) {
+ displayDiv.setAttribute("md-tag-role", "display")
+ displayDiv.style.display = "block"
+ }
+
+ if (!_contentDiv) this.shadow.appendChild(contentDiv)
+ if (!_displayDiv) this.shadow.appendChild(displayDiv)
+ }
+
+ // Spec-defined Methods
+
+ parsedCallback() {
+ this.contentObserver = new MutationObserver((mutations, observer) => {
+ this.raw = this.innerHTML
+ });
+
+ this.contentObserver.observe(this, {
+ characterData: true,
+ subtree: true
+ });
+
+ this.generateFields()
+ this.generateMarkdown()
+ this.generated = true
+ }
+
+ attributeChangedCallback(attrName, oldVal, newVal) {
+ if (!this.generated) return;
+ if (oldVal == newVal) return;
+
+ switch (attrName) {
+ case "flavor": {
+ this.flavor = newVal
+ this.generateMarkdown()
+ break;
+ }
+ }
+ }
+
+ static get observedAttributes() {
+ return [
+ "flavor"
+ ];
+ }
+ }
+
+ window.customElements.define("md-tag", MDTag, { extends: "textarea" });
+}
+
+mdt_wc_init()
\ No newline at end of file
diff --git a/parsers/DOMPurify/purify.min.js b/parsers/DOMPurify/purify.min.js
new file mode 100644
index 0000000..2790f5b
--- /dev/null
+++ b/parsers/DOMPurify/purify.min.js
@@ -0,0 +1,3 @@
+/*! @license DOMPurify 2.3.8 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.8/LICENSE */
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).DOMPurify=t()}(this,(function(){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}function t(e,n){return(t=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,n)}function n(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function r(e,o,a){return(r=n()?Reflect.construct:function(e,n,r){var o=[null];o.push.apply(o,n);var a=new(Function.bind.apply(e,o));return r&&t(a,r.prototype),a}).apply(null,arguments)}function o(e){return function(e){if(Array.isArray(e))return a(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return a(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return a(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n1?n-1:0),o=1;o/gm),q=f(/^data-[\-\w.\u00B7-\uFFFF]/),Y=f(/^aria-[\-\w]+$/),K=f(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),V=f(/^(?:\w+script|data):/i),$=f(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),X=f(/^html$/i),Z=function(){return"undefined"==typeof window?null:window},J=function(t,n){if("object"!==e(t)||"function"!=typeof t.createPolicy)return null;var r=null,o="data-tt-policy-suffix";n.currentScript&&n.currentScript.hasAttribute(o)&&(r=n.currentScript.getAttribute(o));var a="dompurify"+(r?"#"+r:"");try{return t.createPolicy(a,{createHTML:function(e){return e}})}catch(e){return console.warn("TrustedTypes policy "+a+" could not be created."),null}};return function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Z(),r=function(e){return t(e)};if(r.version="2.3.8",r.removed=[],!n||!n.document||9!==n.document.nodeType)return r.isSupported=!1,r;var a=n.document,i=n.document,l=n.DocumentFragment,c=n.HTMLTemplateElement,u=n.Node,s=n.Element,f=n.NodeFilter,p=n.NamedNodeMap,d=void 0===p?n.NamedNodeMap||n.MozNamedAttrMap:p,h=n.HTMLFormElement,g=n.DOMParser,y=n.trustedTypes,_=s.prototype,Q=C(_,"cloneNode"),ee=C(_,"nextSibling"),te=C(_,"childNodes"),ne=C(_,"parentNode");if("function"==typeof c){var re=i.createElement("template");re.content&&re.content.ownerDocument&&(i=re.content.ownerDocument)}var oe=J(y,a),ae=oe?oe.createHTML(""):"",ie=i,le=ie.implementation,ce=ie.createNodeIterator,ue=ie.createDocumentFragment,se=ie.getElementsByTagName,me=a.importNode,fe={};try{fe=D(i).documentMode?i.documentMode:{}}catch(e){}var pe={};r.isSupported="function"==typeof ne&&le&&void 0!==le.createHTMLDocument&&9!==fe;var de,he,ge=G,ye=W,be=q,ve=Y,Te=V,Ne=$,Ee=K,Ae=null,we=O({},[].concat(o(M),o(R),o(L),o(F),o(U))),xe=null,ke=O({},[].concat(o(z),o(B),o(j),o(P))),Se=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),_e=null,Oe=null,De=!0,Ce=!0,Me=!1,Re=!1,Le=!1,Ie=!1,Fe=!1,He=!1,Ue=!1,ze=!1,Be=!0,je=!0,Pe=!1,Ge={},We=null,qe=O({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),Ye=null,Ke=O({},["audio","video","img","source","image","track"]),Ve=null,$e=O({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Xe="http://www.w3.org/1998/Math/MathML",Ze="http://www.w3.org/2000/svg",Je="http://www.w3.org/1999/xhtml",Qe=Je,et=!1,tt=["application/xhtml+xml","text/html"],nt="text/html",rt=null,ot=i.createElement("form"),at=function(e){return e instanceof RegExp||e instanceof Function},it=function(t){rt&&rt===t||(t&&"object"===e(t)||(t={}),t=D(t),Ae="ALLOWED_TAGS"in t?O({},t.ALLOWED_TAGS):we,xe="ALLOWED_ATTR"in t?O({},t.ALLOWED_ATTR):ke,Ve="ADD_URI_SAFE_ATTR"in t?O(D($e),t.ADD_URI_SAFE_ATTR):$e,Ye="ADD_DATA_URI_TAGS"in t?O(D(Ke),t.ADD_DATA_URI_TAGS):Ke,We="FORBID_CONTENTS"in t?O({},t.FORBID_CONTENTS):qe,_e="FORBID_TAGS"in t?O({},t.FORBID_TAGS):{},Oe="FORBID_ATTR"in t?O({},t.FORBID_ATTR):{},Ge="USE_PROFILES"in t&&t.USE_PROFILES,De=!1!==t.ALLOW_ARIA_ATTR,Ce=!1!==t.ALLOW_DATA_ATTR,Me=t.ALLOW_UNKNOWN_PROTOCOLS||!1,Re=t.SAFE_FOR_TEMPLATES||!1,Le=t.WHOLE_DOCUMENT||!1,He=t.RETURN_DOM||!1,Ue=t.RETURN_DOM_FRAGMENT||!1,ze=t.RETURN_TRUSTED_TYPE||!1,Fe=t.FORCE_BODY||!1,Be=!1!==t.SANITIZE_DOM,je=!1!==t.KEEP_CONTENT,Pe=t.IN_PLACE||!1,Ee=t.ALLOWED_URI_REGEXP||Ee,Qe=t.NAMESPACE||Je,t.CUSTOM_ELEMENT_HANDLING&&at(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Se.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&at(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Se.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(Se.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),de=de=-1===tt.indexOf(t.PARSER_MEDIA_TYPE)?nt:t.PARSER_MEDIA_TYPE,he="application/xhtml+xml"===de?function(e){return e}:N,Re&&(Ce=!1),Ue&&(He=!0),Ge&&(Ae=O({},o(U)),xe=[],!0===Ge.html&&(O(Ae,M),O(xe,z)),!0===Ge.svg&&(O(Ae,R),O(xe,B),O(xe,P)),!0===Ge.svgFilters&&(O(Ae,L),O(xe,B),O(xe,P)),!0===Ge.mathMl&&(O(Ae,F),O(xe,j),O(xe,P))),t.ADD_TAGS&&(Ae===we&&(Ae=D(Ae)),O(Ae,t.ADD_TAGS)),t.ADD_ATTR&&(xe===ke&&(xe=D(xe)),O(xe,t.ADD_ATTR)),t.ADD_URI_SAFE_ATTR&&O(Ve,t.ADD_URI_SAFE_ATTR),t.FORBID_CONTENTS&&(We===qe&&(We=D(We)),O(We,t.FORBID_CONTENTS)),je&&(Ae["#text"]=!0),Le&&O(Ae,["html","head","body"]),Ae.table&&(O(Ae,["tbody"]),delete _e.tbody),m&&m(t),rt=t)},lt=O({},["mi","mo","mn","ms","mtext"]),ct=O({},["foreignobject","desc","title","annotation-xml"]),ut=O({},["title","style","font","a","script"]),st=O({},R);O(st,L),O(st,I);var mt=O({},F);O(mt,H);var ft=function(e){var t=ne(e);t&&t.tagName||(t={namespaceURI:Je,tagName:"template"});var n=N(e.tagName),r=N(t.tagName);return e.namespaceURI===Ze?t.namespaceURI===Je?"svg"===n:t.namespaceURI===Xe?"svg"===n&&("annotation-xml"===r||lt[r]):Boolean(st[n]):e.namespaceURI===Xe?t.namespaceURI===Je?"math"===n:t.namespaceURI===Ze?"math"===n&&ct[r]:Boolean(mt[n]):e.namespaceURI===Je&&(!(t.namespaceURI===Ze&&!ct[r])&&(!(t.namespaceURI===Xe&&!lt[r])&&(!mt[n]&&(ut[n]||!st[n]))))},pt=function(e){T(r.removed,{element:e});try{e.parentNode.removeChild(e)}catch(t){try{e.outerHTML=ae}catch(t){e.remove()}}},dt=function(e,t){try{T(r.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){T(r.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e&&!xe[e])if(He||Ue)try{pt(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},ht=function(e){var t,n;if(Fe)e=""+e;else{var r=E(e,/^[\r\n\t ]+/);n=r&&r[0]}"application/xhtml+xml"===de&&(e=''+e+"");var o=oe?oe.createHTML(e):e;if(Qe===Je)try{t=(new g).parseFromString(o,de)}catch(e){}if(!t||!t.documentElement){t=le.createDocument(Qe,"template",null);try{t.documentElement.innerHTML=et?"":o}catch(e){}}var a=t.body||t.documentElement;return e&&n&&a.insertBefore(i.createTextNode(n),a.childNodes[0]||null),Qe===Je?se.call(t,Le?"html":"body")[0]:Le?t.documentElement:a},gt=function(e){return ce.call(e.ownerDocument||e,e,f.SHOW_ELEMENT|f.SHOW_COMMENT|f.SHOW_TEXT,null,!1)},yt=function(e){return e instanceof h&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof d)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore)},bt=function(t){return"object"===e(u)?t instanceof u:t&&"object"===e(t)&&"number"==typeof t.nodeType&&"string"==typeof t.nodeName},vt=function(e,t,n){pe[e]&&b(pe[e],(function(e){e.call(r,t,n,rt)}))},Tt=function(e){var t;if(vt("beforeSanitizeElements",e,null),yt(e))return pt(e),!0;if(k(/[\u0080-\uFFFF]/,e.nodeName))return pt(e),!0;var n=he(e.nodeName);if(vt("uponSanitizeElement",e,{tagName:n,allowedTags:Ae}),e.hasChildNodes()&&!bt(e.firstElementChild)&&(!bt(e.content)||!bt(e.content.firstElementChild))&&k(/<[/\w]/g,e.innerHTML)&&k(/<[/\w]/g,e.textContent))return pt(e),!0;if("select"===n&&k(/=0;--i)o.insertBefore(Q(a[i],!0),ee(e))}return pt(e),!0}return e instanceof s&&!ft(e)?(pt(e),!0):"noscript"!==n&&"noembed"!==n||!k(/<\/no(script|embed)/i,e.innerHTML)?(Re&&3===e.nodeType&&(t=e.textContent,t=A(t,ge," "),t=A(t,ye," "),e.textContent!==t&&(T(r.removed,{element:e.cloneNode()}),e.textContent=t)),vt("afterSanitizeElements",e,null),!1):(pt(e),!0)},Nt=function(e,t,n){if(Be&&("id"===t||"name"===t)&&(n in i||n in ot))return!1;if(Ce&&!Oe[t]&&k(be,t));else if(De&&k(ve,t));else if(!xe[t]||Oe[t]){if(!(Et(e)&&(Se.tagNameCheck instanceof RegExp&&k(Se.tagNameCheck,e)||Se.tagNameCheck instanceof Function&&Se.tagNameCheck(e))&&(Se.attributeNameCheck instanceof RegExp&&k(Se.attributeNameCheck,t)||Se.attributeNameCheck instanceof Function&&Se.attributeNameCheck(t))||"is"===t&&Se.allowCustomizedBuiltInElements&&(Se.tagNameCheck instanceof RegExp&&k(Se.tagNameCheck,n)||Se.tagNameCheck instanceof Function&&Se.tagNameCheck(n))))return!1}else if(Ve[t]);else if(k(Ee,A(n,Ne,"")));else if("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==w(n,"data:")||!Ye[e]){if(Me&&!k(Te,A(n,Ne,"")));else if(n)return!1}else;return!0},Et=function(e){return e.indexOf("-")>0},At=function(e){var t,n,o,a;vt("beforeSanitizeAttributes",e,null);var i=e.attributes;if(i){var l={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:xe};for(a=i.length;a--;){var c=t=i[a],u=c.name,s=c.namespaceURI;if(n="value"===u?t.value:x(t.value),o=he(u),l.attrName=o,l.attrValue=n,l.keepAttr=!0,l.forceKeepAttr=void 0,vt("uponSanitizeAttribute",e,l),n=l.attrValue,!l.forceKeepAttr&&(dt(u,e),l.keepAttr))if(k(/\/>/i,n))dt(u,e);else{Re&&(n=A(n,ge," "),n=A(n,ye," "));var m=he(e.nodeName);if(Nt(m,o,n))try{s?e.setAttributeNS(s,u,n):e.setAttribute(u,n),v(r.removed)}catch(e){}}}vt("afterSanitizeAttributes",e,null)}},wt=function e(t){var n,r=gt(t);for(vt("beforeSanitizeShadowDOM",t,null);n=r.nextNode();)vt("uponSanitizeShadowNode",n,null),Tt(n)||(n.content instanceof l&&e(n.content),At(n));vt("afterSanitizeShadowDOM",t,null)};return r.sanitize=function(t,o){var i,c,s,m,f;if((et=!t)&&(t="\x3c!--\x3e"),"string"!=typeof t&&!bt(t)){if("function"!=typeof t.toString)throw S("toString is not a function");if("string"!=typeof(t=t.toString()))throw S("dirty is not a string, aborting")}if(!r.isSupported){if("object"===e(n.toStaticHTML)||"function"==typeof n.toStaticHTML){if("string"==typeof t)return n.toStaticHTML(t);if(bt(t))return n.toStaticHTML(t.outerHTML)}return t}if(Ie||it(o),r.removed=[],"string"==typeof t&&(Pe=!1),Pe){if(t.nodeName){var p=he(t.nodeName);if(!Ae[p]||_e[p])throw S("root node is forbidden and cannot be sanitized in-place")}}else if(t instanceof u)1===(c=(i=ht("\x3c!----\x3e")).ownerDocument.importNode(t,!0)).nodeType&&"BODY"===c.nodeName||"HTML"===c.nodeName?i=c:i.appendChild(c);else{if(!He&&!Re&&!Le&&-1===t.indexOf("<"))return oe&&ze?oe.createHTML(t):t;if(!(i=ht(t)))return He?null:ze?ae:""}i&&Fe&&pt(i.firstChild);for(var d=gt(Pe?t:i);s=d.nextNode();)3===s.nodeType&&s===m||Tt(s)||(s.content instanceof l&&wt(s.content),At(s),m=s);if(m=null,Pe)return t;if(He){if(Ue)for(f=ue.call(i.ownerDocument);i.firstChild;)f.appendChild(i.firstChild);else f=i;return xe.shadowroot&&(f=me.call(a,f,!0)),f}var h=Le?i.outerHTML:i.innerHTML;return Le&&Ae["!doctype"]&&i.ownerDocument&&i.ownerDocument.doctype&&i.ownerDocument.doctype.name&&k(X,i.ownerDocument.doctype.name)&&(h="\n"+h),Re&&(h=A(h,ge," "),h=A(h,ye," ")),oe&&ze?oe.createHTML(h):h},r.setConfig=function(e){it(e),Ie=!0},r.clearConfig=function(){rt=null,Ie=!1},r.isValidAttribute=function(e,t,n){rt||it({});var r=he(e),o=he(t);return Nt(r,o,n)},r.addHook=function(e,t){"function"==typeof t&&(pe[e]=pe[e]||[],T(pe[e],t))},r.removeHook=function(e){if(pe[e])return v(pe[e])},r.removeHooks=function(e){pe[e]&&(pe[e]=[])},r.removeAllHooks=function(){pe={}},r}()}));
+//# sourceMappingURL=purify.min.js.map
diff --git a/parsers/DOMPurify/purify.min.js.map b/parsers/DOMPurify/purify.min.js.map
new file mode 100644
index 0000000..5781ba9
--- /dev/null
+++ b/parsers/DOMPurify/purify.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"purify.min.js","sources":["../src/utils.js","../src/tags.js","../src/attrs.js","../src/regexp.js","../src/purify.js"],"sourcesContent":["const {\n hasOwnProperty,\n setPrototypeOf,\n isFrozen,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n} = Object;\n\nlet { freeze, seal, create } = Object; // eslint-disable-line import/no-mutable-exports\nlet { apply, construct } = typeof Reflect !== 'undefined' && Reflect;\n\nif (!apply) {\n apply = function (fun, thisValue, args) {\n return fun.apply(thisValue, args);\n };\n}\n\nif (!freeze) {\n freeze = function (x) {\n return x;\n };\n}\n\nif (!seal) {\n seal = function (x) {\n return x;\n };\n}\n\nif (!construct) {\n construct = function (Func, args) {\n return new Func(...args);\n };\n}\n\nconst arrayForEach = unapply(Array.prototype.forEach);\nconst arrayIndexOf = unapply(Array.prototype.indexOf);\nconst arrayPop = unapply(Array.prototype.pop);\nconst arrayPush = unapply(Array.prototype.push);\nconst arraySlice = unapply(Array.prototype.slice);\n\nconst stringToLowerCase = unapply(String.prototype.toLowerCase);\nconst stringMatch = unapply(String.prototype.match);\nconst stringReplace = unapply(String.prototype.replace);\nconst stringIndexOf = unapply(String.prototype.indexOf);\nconst stringTrim = unapply(String.prototype.trim);\n\nconst regExpTest = unapply(RegExp.prototype.test);\n\nconst typeErrorCreate = unconstruct(TypeError);\n\nexport function unapply(func) {\n return (thisArg, ...args) => apply(func, thisArg, args);\n}\n\nexport function unconstruct(func) {\n return (...args) => construct(func, args);\n}\n\n/* Add properties to a lookup table */\nexport function addToSet(set, array) {\n if (setPrototypeOf) {\n // Make 'in' and truthy checks like Boolean(set.constructor)\n // independent of any properties defined on Object.prototype.\n // Prevent prototype setters from intercepting set as a this value.\n setPrototypeOf(set, null);\n }\n\n let l = array.length;\n while (l--) {\n let element = array[l];\n if (typeof element === 'string') {\n const lcElement = stringToLowerCase(element);\n if (lcElement !== element) {\n // Config presets (e.g. tags.js, attrs.js) are immutable.\n if (!isFrozen(array)) {\n array[l] = lcElement;\n }\n\n element = lcElement;\n }\n }\n\n set[element] = true;\n }\n\n return set;\n}\n\n/* Shallow clone an object */\nexport function clone(object) {\n const newObject = create(null);\n\n let property;\n for (property in object) {\n if (apply(hasOwnProperty, object, [property])) {\n newObject[property] = object[property];\n }\n }\n\n return newObject;\n}\n\n/* IE10 doesn't support __lookupGetter__ so lets'\n * simulate it. It also automatically checks\n * if the prop is function or getter and behaves\n * accordingly. */\nfunction lookupGetter(object, prop) {\n while (object !== null) {\n const desc = getOwnPropertyDescriptor(object, prop);\n if (desc) {\n if (desc.get) {\n return unapply(desc.get);\n }\n\n if (typeof desc.value === 'function') {\n return unapply(desc.value);\n }\n }\n\n object = getPrototypeOf(object);\n }\n\n function fallbackValue(element) {\n console.warn('fallback value for', element);\n return null;\n }\n\n return fallbackValue;\n}\n\nexport {\n // Array\n arrayForEach,\n arrayIndexOf,\n arrayPop,\n arrayPush,\n arraySlice,\n // Object\n freeze,\n getPrototypeOf,\n getOwnPropertyDescriptor,\n hasOwnProperty,\n isFrozen,\n setPrototypeOf,\n seal,\n // RegExp\n regExpTest,\n // String\n stringIndexOf,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringTrim,\n // Errors\n typeErrorCreate,\n // Other\n lookupGetter,\n};\n","import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'a',\n 'abbr',\n 'acronym',\n 'address',\n 'area',\n 'article',\n 'aside',\n 'audio',\n 'b',\n 'bdi',\n 'bdo',\n 'big',\n 'blink',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'center',\n 'cite',\n 'code',\n 'col',\n 'colgroup',\n 'content',\n 'data',\n 'datalist',\n 'dd',\n 'decorator',\n 'del',\n 'details',\n 'dfn',\n 'dialog',\n 'dir',\n 'div',\n 'dl',\n 'dt',\n 'element',\n 'em',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'font',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'head',\n 'header',\n 'hgroup',\n 'hr',\n 'html',\n 'i',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'map',\n 'mark',\n 'marquee',\n 'menu',\n 'menuitem',\n 'meter',\n 'nav',\n 'nobr',\n 'ol',\n 'optgroup',\n 'option',\n 'output',\n 'p',\n 'picture',\n 'pre',\n 'progress',\n 'q',\n 'rp',\n 'rt',\n 'ruby',\n 's',\n 'samp',\n 'section',\n 'select',\n 'shadow',\n 'small',\n 'source',\n 'spacer',\n 'span',\n 'strike',\n 'strong',\n 'style',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'template',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'track',\n 'tt',\n 'u',\n 'ul',\n 'var',\n 'video',\n 'wbr',\n]);\n\n// SVG\nexport const svg = freeze([\n 'svg',\n 'a',\n 'altglyph',\n 'altglyphdef',\n 'altglyphitem',\n 'animatecolor',\n 'animatemotion',\n 'animatetransform',\n 'circle',\n 'clippath',\n 'defs',\n 'desc',\n 'ellipse',\n 'filter',\n 'font',\n 'g',\n 'glyph',\n 'glyphref',\n 'hkern',\n 'image',\n 'line',\n 'lineargradient',\n 'marker',\n 'mask',\n 'metadata',\n 'mpath',\n 'path',\n 'pattern',\n 'polygon',\n 'polyline',\n 'radialgradient',\n 'rect',\n 'stop',\n 'style',\n 'switch',\n 'symbol',\n 'text',\n 'textpath',\n 'title',\n 'tref',\n 'tspan',\n 'view',\n 'vkern',\n]);\n\nexport const svgFilters = freeze([\n 'feBlend',\n 'feColorMatrix',\n 'feComponentTransfer',\n 'feComposite',\n 'feConvolveMatrix',\n 'feDiffuseLighting',\n 'feDisplacementMap',\n 'feDistantLight',\n 'feFlood',\n 'feFuncA',\n 'feFuncB',\n 'feFuncG',\n 'feFuncR',\n 'feGaussianBlur',\n 'feImage',\n 'feMerge',\n 'feMergeNode',\n 'feMorphology',\n 'feOffset',\n 'fePointLight',\n 'feSpecularLighting',\n 'feSpotLight',\n 'feTile',\n 'feTurbulence',\n]);\n\n// List of SVG elements that are disallowed by default.\n// We still need to know them so that we can do namespace\n// checks properly in case one wants to add them to\n// allow-list.\nexport const svgDisallowed = freeze([\n 'animate',\n 'color-profile',\n 'cursor',\n 'discard',\n 'fedropshadow',\n 'font-face',\n 'font-face-format',\n 'font-face-name',\n 'font-face-src',\n 'font-face-uri',\n 'foreignobject',\n 'hatch',\n 'hatchpath',\n 'mesh',\n 'meshgradient',\n 'meshpatch',\n 'meshrow',\n 'missing-glyph',\n 'script',\n 'set',\n 'solidcolor',\n 'unknown',\n 'use',\n]);\n\nexport const mathMl = freeze([\n 'math',\n 'menclose',\n 'merror',\n 'mfenced',\n 'mfrac',\n 'mglyph',\n 'mi',\n 'mlabeledtr',\n 'mmultiscripts',\n 'mn',\n 'mo',\n 'mover',\n 'mpadded',\n 'mphantom',\n 'mroot',\n 'mrow',\n 'ms',\n 'mspace',\n 'msqrt',\n 'mstyle',\n 'msub',\n 'msup',\n 'msubsup',\n 'mtable',\n 'mtd',\n 'mtext',\n 'mtr',\n 'munder',\n 'munderover',\n]);\n\n// Similarly to SVG, we want to know all MathML elements,\n// even those that we disallow by default.\nexport const mathMlDisallowed = freeze([\n 'maction',\n 'maligngroup',\n 'malignmark',\n 'mlongdiv',\n 'mscarries',\n 'mscarry',\n 'msgroup',\n 'mstack',\n 'msline',\n 'msrow',\n 'semantics',\n 'annotation',\n 'annotation-xml',\n 'mprescripts',\n 'none',\n]);\n\nexport const text = freeze(['#text']);\n","import { freeze } from './utils.js';\n\nexport const html = freeze([\n 'accept',\n 'action',\n 'align',\n 'alt',\n 'autocapitalize',\n 'autocomplete',\n 'autopictureinpicture',\n 'autoplay',\n 'background',\n 'bgcolor',\n 'border',\n 'capture',\n 'cellpadding',\n 'cellspacing',\n 'checked',\n 'cite',\n 'class',\n 'clear',\n 'color',\n 'cols',\n 'colspan',\n 'controls',\n 'controlslist',\n 'coords',\n 'crossorigin',\n 'datetime',\n 'decoding',\n 'default',\n 'dir',\n 'disabled',\n 'disablepictureinpicture',\n 'disableremoteplayback',\n 'download',\n 'draggable',\n 'enctype',\n 'enterkeyhint',\n 'face',\n 'for',\n 'headers',\n 'height',\n 'hidden',\n 'high',\n 'href',\n 'hreflang',\n 'id',\n 'inputmode',\n 'integrity',\n 'ismap',\n 'kind',\n 'label',\n 'lang',\n 'list',\n 'loading',\n 'loop',\n 'low',\n 'max',\n 'maxlength',\n 'media',\n 'method',\n 'min',\n 'minlength',\n 'multiple',\n 'muted',\n 'name',\n 'nonce',\n 'noshade',\n 'novalidate',\n 'nowrap',\n 'open',\n 'optimum',\n 'pattern',\n 'placeholder',\n 'playsinline',\n 'poster',\n 'preload',\n 'pubdate',\n 'radiogroup',\n 'readonly',\n 'rel',\n 'required',\n 'rev',\n 'reversed',\n 'role',\n 'rows',\n 'rowspan',\n 'spellcheck',\n 'scope',\n 'selected',\n 'shape',\n 'size',\n 'sizes',\n 'span',\n 'srclang',\n 'start',\n 'src',\n 'srcset',\n 'step',\n 'style',\n 'summary',\n 'tabindex',\n 'title',\n 'translate',\n 'type',\n 'usemap',\n 'valign',\n 'value',\n 'width',\n 'xmlns',\n 'slot',\n]);\n\nexport const svg = freeze([\n 'accent-height',\n 'accumulate',\n 'additive',\n 'alignment-baseline',\n 'ascent',\n 'attributename',\n 'attributetype',\n 'azimuth',\n 'basefrequency',\n 'baseline-shift',\n 'begin',\n 'bias',\n 'by',\n 'class',\n 'clip',\n 'clippathunits',\n 'clip-path',\n 'clip-rule',\n 'color',\n 'color-interpolation',\n 'color-interpolation-filters',\n 'color-profile',\n 'color-rendering',\n 'cx',\n 'cy',\n 'd',\n 'dx',\n 'dy',\n 'diffuseconstant',\n 'direction',\n 'display',\n 'divisor',\n 'dur',\n 'edgemode',\n 'elevation',\n 'end',\n 'fill',\n 'fill-opacity',\n 'fill-rule',\n 'filter',\n 'filterunits',\n 'flood-color',\n 'flood-opacity',\n 'font-family',\n 'font-size',\n 'font-size-adjust',\n 'font-stretch',\n 'font-style',\n 'font-variant',\n 'font-weight',\n 'fx',\n 'fy',\n 'g1',\n 'g2',\n 'glyph-name',\n 'glyphref',\n 'gradientunits',\n 'gradienttransform',\n 'height',\n 'href',\n 'id',\n 'image-rendering',\n 'in',\n 'in2',\n 'k',\n 'k1',\n 'k2',\n 'k3',\n 'k4',\n 'kerning',\n 'keypoints',\n 'keysplines',\n 'keytimes',\n 'lang',\n 'lengthadjust',\n 'letter-spacing',\n 'kernelmatrix',\n 'kernelunitlength',\n 'lighting-color',\n 'local',\n 'marker-end',\n 'marker-mid',\n 'marker-start',\n 'markerheight',\n 'markerunits',\n 'markerwidth',\n 'maskcontentunits',\n 'maskunits',\n 'max',\n 'mask',\n 'media',\n 'method',\n 'mode',\n 'min',\n 'name',\n 'numoctaves',\n 'offset',\n 'operator',\n 'opacity',\n 'order',\n 'orient',\n 'orientation',\n 'origin',\n 'overflow',\n 'paint-order',\n 'path',\n 'pathlength',\n 'patterncontentunits',\n 'patterntransform',\n 'patternunits',\n 'points',\n 'preservealpha',\n 'preserveaspectratio',\n 'primitiveunits',\n 'r',\n 'rx',\n 'ry',\n 'radius',\n 'refx',\n 'refy',\n 'repeatcount',\n 'repeatdur',\n 'restart',\n 'result',\n 'rotate',\n 'scale',\n 'seed',\n 'shape-rendering',\n 'specularconstant',\n 'specularexponent',\n 'spreadmethod',\n 'startoffset',\n 'stddeviation',\n 'stitchtiles',\n 'stop-color',\n 'stop-opacity',\n 'stroke-dasharray',\n 'stroke-dashoffset',\n 'stroke-linecap',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke',\n 'stroke-width',\n 'style',\n 'surfacescale',\n 'systemlanguage',\n 'tabindex',\n 'targetx',\n 'targety',\n 'transform',\n 'transform-origin',\n 'text-anchor',\n 'text-decoration',\n 'text-rendering',\n 'textlength',\n 'type',\n 'u1',\n 'u2',\n 'unicode',\n 'values',\n 'viewbox',\n 'visibility',\n 'version',\n 'vert-adv-y',\n 'vert-origin-x',\n 'vert-origin-y',\n 'width',\n 'word-spacing',\n 'wrap',\n 'writing-mode',\n 'xchannelselector',\n 'ychannelselector',\n 'x',\n 'x1',\n 'x2',\n 'xmlns',\n 'y',\n 'y1',\n 'y2',\n 'z',\n 'zoomandpan',\n]);\n\nexport const mathMl = freeze([\n 'accent',\n 'accentunder',\n 'align',\n 'bevelled',\n 'close',\n 'columnsalign',\n 'columnlines',\n 'columnspan',\n 'denomalign',\n 'depth',\n 'dir',\n 'display',\n 'displaystyle',\n 'encoding',\n 'fence',\n 'frame',\n 'height',\n 'href',\n 'id',\n 'largeop',\n 'length',\n 'linethickness',\n 'lspace',\n 'lquote',\n 'mathbackground',\n 'mathcolor',\n 'mathsize',\n 'mathvariant',\n 'maxsize',\n 'minsize',\n 'movablelimits',\n 'notation',\n 'numalign',\n 'open',\n 'rowalign',\n 'rowlines',\n 'rowspacing',\n 'rowspan',\n 'rspace',\n 'rquote',\n 'scriptlevel',\n 'scriptminsize',\n 'scriptsizemultiplier',\n 'selection',\n 'separator',\n 'separators',\n 'stretchy',\n 'subscriptshift',\n 'supscriptshift',\n 'symmetric',\n 'voffset',\n 'width',\n 'xmlns',\n]);\n\nexport const xml = freeze([\n 'xlink:href',\n 'xml:id',\n 'xlink:title',\n 'xml:space',\n 'xmlns:xlink',\n]);\n","import { seal } from './utils.js';\n\n// eslint-disable-next-line unicorn/better-regex\nexport const MUSTACHE_EXPR = seal(/\\{\\{[\\w\\W]*|[\\w\\W]*\\}\\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode\nexport const ERB_EXPR = seal(/<%[\\w\\W]*|[\\w\\W]*%>/gm);\nexport const DATA_ATTR = seal(/^data-[\\-\\w.\\u00B7-\\uFFFF]/); // eslint-disable-line no-useless-escape\nexport const ARIA_ATTR = seal(/^aria-[\\-\\w]+$/); // eslint-disable-line no-useless-escape\nexport const IS_ALLOWED_URI = seal(\n /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i // eslint-disable-line no-useless-escape\n);\nexport const IS_SCRIPT_OR_DATA = seal(/^(?:\\w+script|data):/i);\nexport const ATTR_WHITESPACE = seal(\n /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205F\\u3000]/g // eslint-disable-line no-control-regex\n);\nexport const DOCTYPE_NAME = seal(/^html$/i);\n","import * as TAGS from './tags.js';\nimport * as ATTRS from './attrs.js';\nimport * as EXPRESSIONS from './regexp.js';\nimport {\n addToSet,\n clone,\n freeze,\n arrayForEach,\n arrayPop,\n arrayPush,\n stringMatch,\n stringReplace,\n stringToLowerCase,\n stringIndexOf,\n stringTrim,\n regExpTest,\n typeErrorCreate,\n lookupGetter,\n} from './utils.js';\n\nconst getGlobal = () => (typeof window === 'undefined' ? null : window);\n\n/**\n * Creates a no-op policy for internal use only.\n * Don't export this function outside this module!\n * @param {?TrustedTypePolicyFactory} trustedTypes The policy factory.\n * @param {Document} document The document object (to determine policy name suffix)\n * @return {?TrustedTypePolicy} The policy created (or null, if Trusted Types\n * are not supported).\n */\nconst _createTrustedTypesPolicy = function (trustedTypes, document) {\n if (\n typeof trustedTypes !== 'object' ||\n typeof trustedTypes.createPolicy !== 'function'\n ) {\n return null;\n }\n\n // Allow the callers to control the unique policy name\n // by adding a data-tt-policy-suffix to the script element with the DOMPurify.\n // Policy creation with duplicate names throws in Trusted Types.\n let suffix = null;\n const ATTR_NAME = 'data-tt-policy-suffix';\n if (\n document.currentScript &&\n document.currentScript.hasAttribute(ATTR_NAME)\n ) {\n suffix = document.currentScript.getAttribute(ATTR_NAME);\n }\n\n const policyName = 'dompurify' + (suffix ? '#' + suffix : '');\n\n try {\n return trustedTypes.createPolicy(policyName, {\n createHTML(html) {\n return html;\n },\n });\n } catch (_) {\n // Policy creation failed (most likely another DOMPurify script has\n // already run). Skip creating the policy, as this will only cause errors\n // if TT are enforced.\n console.warn(\n 'TrustedTypes policy ' + policyName + ' could not be created.'\n );\n return null;\n }\n};\n\nfunction createDOMPurify(window = getGlobal()) {\n const DOMPurify = (root) => createDOMPurify(root);\n\n /**\n * Version label, exposed for easier checks\n * if DOMPurify is up to date or not\n */\n DOMPurify.version = VERSION;\n\n /**\n * Array of elements that DOMPurify removed during sanitation.\n * Empty if nothing was removed.\n */\n DOMPurify.removed = [];\n\n if (!window || !window.document || window.document.nodeType !== 9) {\n // Not running in a browser, provide a factory function\n // so that you can pass your own Window\n DOMPurify.isSupported = false;\n\n return DOMPurify;\n }\n\n const originalDocument = window.document;\n\n let { document } = window;\n const {\n DocumentFragment,\n HTMLTemplateElement,\n Node,\n Element,\n NodeFilter,\n NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap,\n HTMLFormElement,\n DOMParser,\n trustedTypes,\n } = window;\n\n const ElementPrototype = Element.prototype;\n\n const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');\n const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');\n const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');\n const getParentNode = lookupGetter(ElementPrototype, 'parentNode');\n\n // As per issue #47, the web-components registry is inherited by a\n // new document created via createHTMLDocument. As per the spec\n // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)\n // a new empty registry is used when creating a template contents owner\n // document, so we use that as our parent document to ensure nothing\n // is inherited.\n if (typeof HTMLTemplateElement === 'function') {\n const template = document.createElement('template');\n if (template.content && template.content.ownerDocument) {\n document = template.content.ownerDocument;\n }\n }\n\n const trustedTypesPolicy = _createTrustedTypesPolicy(\n trustedTypes,\n originalDocument\n );\n const emptyHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML('') : '';\n\n const {\n implementation,\n createNodeIterator,\n createDocumentFragment,\n getElementsByTagName,\n } = document;\n const { importNode } = originalDocument;\n\n let documentMode = {};\n try {\n documentMode = clone(document).documentMode ? document.documentMode : {};\n } catch (_) {}\n\n let hooks = {};\n\n /**\n * Expose whether this browser supports running the full DOMPurify.\n */\n DOMPurify.isSupported =\n typeof getParentNode === 'function' &&\n implementation &&\n typeof implementation.createHTMLDocument !== 'undefined' &&\n documentMode !== 9;\n\n const {\n MUSTACHE_EXPR,\n ERB_EXPR,\n DATA_ATTR,\n ARIA_ATTR,\n IS_SCRIPT_OR_DATA,\n ATTR_WHITESPACE,\n } = EXPRESSIONS;\n\n let { IS_ALLOWED_URI } = EXPRESSIONS;\n\n /**\n * We consider the elements and attributes below to be safe. Ideally\n * don't add any new ones but feel free to remove unwanted ones.\n */\n\n /* allowed element names */\n let ALLOWED_TAGS = null;\n const DEFAULT_ALLOWED_TAGS = addToSet({}, [\n ...TAGS.html,\n ...TAGS.svg,\n ...TAGS.svgFilters,\n ...TAGS.mathMl,\n ...TAGS.text,\n ]);\n\n /* Allowed attribute names */\n let ALLOWED_ATTR = null;\n const DEFAULT_ALLOWED_ATTR = addToSet({}, [\n ...ATTRS.html,\n ...ATTRS.svg,\n ...ATTRS.mathMl,\n ...ATTRS.xml,\n ]);\n\n /*\n * Configure how DOMPUrify should handle custom elements and their attributes as well as customized built-in elements.\n * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)\n * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)\n * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.\n */\n const CUSTOM_ELEMENT_HANDLING = Object.seal(\n Object.create(null, {\n tagNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n attributeNameCheck: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: null,\n },\n allowCustomizedBuiltInElements: {\n writable: true,\n configurable: false,\n enumerable: true,\n value: false,\n },\n })\n );\n\n /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */\n let FORBID_TAGS = null;\n\n /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */\n let FORBID_ATTR = null;\n\n /* Decide if ARIA attributes are okay */\n let ALLOW_ARIA_ATTR = true;\n\n /* Decide if custom data attributes are okay */\n let ALLOW_DATA_ATTR = true;\n\n /* Decide if unknown protocols are okay */\n let ALLOW_UNKNOWN_PROTOCOLS = false;\n\n /* Output should be safe for common template engines.\n * This means, DOMPurify removes data attributes, mustaches and ERB\n */\n let SAFE_FOR_TEMPLATES = false;\n\n /* Decide if document with ... should be returned */\n let WHOLE_DOCUMENT = false;\n\n /* Track whether config is already set on this instance of DOMPurify. */\n let SET_CONFIG = false;\n\n /* Decide if all elements (e.g. style, script) must be children of\n * document.body. By default, browsers might move them to document.head */\n let FORCE_BODY = false;\n\n /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported).\n * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead\n */\n let RETURN_DOM = false;\n\n /* Decide if a DOM `DocumentFragment` should be returned, instead of a html\n * string (or a TrustedHTML object if Trusted Types are supported) */\n let RETURN_DOM_FRAGMENT = false;\n\n /* Try to return a Trusted Type object instead of a string, return a string in\n * case Trusted Types are not supported */\n let RETURN_TRUSTED_TYPE = false;\n\n /* Output should be free from DOM clobbering attacks? */\n let SANITIZE_DOM = true;\n\n /* Keep element content when removing element? */\n let KEEP_CONTENT = true;\n\n /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead\n * of importing it into a new Document and returning a sanitized copy */\n let IN_PLACE = false;\n\n /* Allow usage of profiles like html, svg and mathMl */\n let USE_PROFILES = {};\n\n /* Tags to ignore content of when KEEP_CONTENT is true */\n let FORBID_CONTENTS = null;\n const DEFAULT_FORBID_CONTENTS = addToSet({}, [\n 'annotation-xml',\n 'audio',\n 'colgroup',\n 'desc',\n 'foreignobject',\n 'head',\n 'iframe',\n 'math',\n 'mi',\n 'mn',\n 'mo',\n 'ms',\n 'mtext',\n 'noembed',\n 'noframes',\n 'noscript',\n 'plaintext',\n 'script',\n 'style',\n 'svg',\n 'template',\n 'thead',\n 'title',\n 'video',\n 'xmp',\n ]);\n\n /* Tags that are safe for data: URIs */\n let DATA_URI_TAGS = null;\n const DEFAULT_DATA_URI_TAGS = addToSet({}, [\n 'audio',\n 'video',\n 'img',\n 'source',\n 'image',\n 'track',\n ]);\n\n /* Attributes safe for values like \"javascript:\" */\n let URI_SAFE_ATTRIBUTES = null;\n const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, [\n 'alt',\n 'class',\n 'for',\n 'id',\n 'label',\n 'name',\n 'pattern',\n 'placeholder',\n 'role',\n 'summary',\n 'title',\n 'value',\n 'style',\n 'xmlns',\n ]);\n\n const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n /* Document namespace */\n let NAMESPACE = HTML_NAMESPACE;\n let IS_EMPTY_INPUT = false;\n\n /* Parsing of strict XHTML documents */\n let PARSER_MEDIA_TYPE;\n const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];\n const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';\n let transformCaseFunc;\n\n /* Keep a reference to config to pass to hooks */\n let CONFIG = null;\n\n /* Ideally, do not touch anything below this line */\n /* ______________________________________________ */\n\n const formElement = document.createElement('form');\n\n const isRegexOrFunction = function (testValue) {\n return testValue instanceof RegExp || testValue instanceof Function;\n };\n\n /**\n * _parseConfig\n *\n * @param {Object} cfg optional config literal\n */\n // eslint-disable-next-line complexity\n const _parseConfig = function (cfg) {\n if (CONFIG && CONFIG === cfg) {\n return;\n }\n\n /* Shield configuration object from tampering */\n if (!cfg || typeof cfg !== 'object') {\n cfg = {};\n }\n\n /* Shield configuration object from prototype pollution */\n cfg = clone(cfg);\n\n /* Set configuration parameters */\n ALLOWED_TAGS =\n 'ALLOWED_TAGS' in cfg\n ? addToSet({}, cfg.ALLOWED_TAGS)\n : DEFAULT_ALLOWED_TAGS;\n ALLOWED_ATTR =\n 'ALLOWED_ATTR' in cfg\n ? addToSet({}, cfg.ALLOWED_ATTR)\n : DEFAULT_ALLOWED_ATTR;\n URI_SAFE_ATTRIBUTES =\n 'ADD_URI_SAFE_ATTR' in cfg\n ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR)\n : DEFAULT_URI_SAFE_ATTRIBUTES;\n DATA_URI_TAGS =\n 'ADD_DATA_URI_TAGS' in cfg\n ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS)\n : DEFAULT_DATA_URI_TAGS;\n FORBID_CONTENTS =\n 'FORBID_CONTENTS' in cfg\n ? addToSet({}, cfg.FORBID_CONTENTS)\n : DEFAULT_FORBID_CONTENTS;\n FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS) : {};\n FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR) : {};\n USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;\n ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true\n ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true\n ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false\n SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false\n WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false\n RETURN_DOM = cfg.RETURN_DOM || false; // Default false\n RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false\n RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false\n FORCE_BODY = cfg.FORCE_BODY || false; // Default false\n SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true\n KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true\n IN_PLACE = cfg.IN_PLACE || false; // Default false\n IS_ALLOWED_URI = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI;\n NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE;\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.tagNameCheck =\n cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck;\n }\n\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)\n ) {\n CUSTOM_ELEMENT_HANDLING.attributeNameCheck =\n cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck;\n }\n\n if (\n cfg.CUSTOM_ELEMENT_HANDLING &&\n typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements ===\n 'boolean'\n ) {\n CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements =\n cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements;\n }\n\n PARSER_MEDIA_TYPE =\n // eslint-disable-next-line unicorn/prefer-includes\n SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1\n ? (PARSER_MEDIA_TYPE = DEFAULT_PARSER_MEDIA_TYPE)\n : (PARSER_MEDIA_TYPE = cfg.PARSER_MEDIA_TYPE);\n\n // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.\n transformCaseFunc =\n PARSER_MEDIA_TYPE === 'application/xhtml+xml'\n ? (x) => x\n : stringToLowerCase;\n\n if (SAFE_FOR_TEMPLATES) {\n ALLOW_DATA_ATTR = false;\n }\n\n if (RETURN_DOM_FRAGMENT) {\n RETURN_DOM = true;\n }\n\n /* Parse profile info */\n if (USE_PROFILES) {\n ALLOWED_TAGS = addToSet({}, [...TAGS.text]);\n ALLOWED_ATTR = [];\n if (USE_PROFILES.html === true) {\n addToSet(ALLOWED_TAGS, TAGS.html);\n addToSet(ALLOWED_ATTR, ATTRS.html);\n }\n\n if (USE_PROFILES.svg === true) {\n addToSet(ALLOWED_TAGS, TAGS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.svgFilters === true) {\n addToSet(ALLOWED_TAGS, TAGS.svgFilters);\n addToSet(ALLOWED_ATTR, ATTRS.svg);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n\n if (USE_PROFILES.mathMl === true) {\n addToSet(ALLOWED_TAGS, TAGS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.mathMl);\n addToSet(ALLOWED_ATTR, ATTRS.xml);\n }\n }\n\n /* Merge configuration parameters */\n if (cfg.ADD_TAGS) {\n if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {\n ALLOWED_TAGS = clone(ALLOWED_TAGS);\n }\n\n addToSet(ALLOWED_TAGS, cfg.ADD_TAGS);\n }\n\n if (cfg.ADD_ATTR) {\n if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {\n ALLOWED_ATTR = clone(ALLOWED_ATTR);\n }\n\n addToSet(ALLOWED_ATTR, cfg.ADD_ATTR);\n }\n\n if (cfg.ADD_URI_SAFE_ATTR) {\n addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR);\n }\n\n if (cfg.FORBID_CONTENTS) {\n if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {\n FORBID_CONTENTS = clone(FORBID_CONTENTS);\n }\n\n addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS);\n }\n\n /* Add #text in case KEEP_CONTENT is set to true */\n if (KEEP_CONTENT) {\n ALLOWED_TAGS['#text'] = true;\n }\n\n /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */\n if (WHOLE_DOCUMENT) {\n addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);\n }\n\n /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */\n if (ALLOWED_TAGS.table) {\n addToSet(ALLOWED_TAGS, ['tbody']);\n delete FORBID_TAGS.tbody;\n }\n\n // Prevent further manipulation of configuration.\n // Not available in IE8, Safari 5, etc.\n if (freeze) {\n freeze(cfg);\n }\n\n CONFIG = cfg;\n };\n\n const MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, [\n 'mi',\n 'mo',\n 'mn',\n 'ms',\n 'mtext',\n ]);\n\n const HTML_INTEGRATION_POINTS = addToSet({}, [\n 'foreignobject',\n 'desc',\n 'title',\n 'annotation-xml',\n ]);\n\n // Certain elements are allowed in both SVG and HTML\n // namespace. We need to specify them explicitly\n // so that they don't get erroneously deleted from\n // HTML namespace.\n const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, [\n 'title',\n 'style',\n 'font',\n 'a',\n 'script',\n ]);\n\n /* Keep track of all possible SVG and MathML tags\n * so that we can perform the namespace checks\n * correctly. */\n const ALL_SVG_TAGS = addToSet({}, TAGS.svg);\n addToSet(ALL_SVG_TAGS, TAGS.svgFilters);\n addToSet(ALL_SVG_TAGS, TAGS.svgDisallowed);\n\n const ALL_MATHML_TAGS = addToSet({}, TAGS.mathMl);\n addToSet(ALL_MATHML_TAGS, TAGS.mathMlDisallowed);\n\n /**\n *\n *\n * @param {Element} element a DOM element whose namespace is being checked\n * @returns {boolean} Return false if the element has a\n * namespace that a spec-compliant parser would never\n * return. Return true otherwise.\n */\n const _checkValidNamespace = function (element) {\n let parent = getParentNode(element);\n\n // In JSDOM, if we're inside shadow DOM, then parentNode\n // can be null. We just simulate parent in this case.\n if (!parent || !parent.tagName) {\n parent = {\n namespaceURI: HTML_NAMESPACE,\n tagName: 'template',\n };\n }\n\n const tagName = stringToLowerCase(element.tagName);\n const parentTagName = stringToLowerCase(parent.tagName);\n\n if (element.namespaceURI === SVG_NAMESPACE) {\n // The only way to switch from HTML namespace to SVG\n // is via
"+D(e.message+"",!0)+"
";throw e}},I.Parser=R,I.parser=R.parse,I.Renderer=$,I.TextRenderer=S,I.Lexer=z,I.lexer=z.lex,I.Tokenizer=w,I.Slugger=T;var A=(I.parse=I).options,P=I.setOptions,Q=I.use,U=I.walkTokens,M=I.parseInline,N=I,X=R.parse,G=z.lex;r.Lexer=z,r.Parser=R,r.Renderer=$,r.Slugger=T,r.TextRenderer=S,r.Tokenizer=w,r.getDefaults=e,r.lexer=G,r.marked=I,r.options=A,r.parse=N,r.parseInline=M,r.parser=X,r.setOptions=P,r.use=Q,r.walkTokens=U,Object.defineProperty(r,"__esModule",{value:!0})});
\ No newline at end of file
diff --git a/parsers/showdown/showdown.min.js b/parsers/showdown/showdown.min.js
new file mode 100644
index 0000000..cf721d9
--- /dev/null
+++ b/parsers/showdown/showdown.min.js
@@ -0,0 +1,3 @@
+/*! showdown v 2.1.0 - 21-04-2022 */
+!function(){function a(e){"use strict";var r={omitExtraWLInCodeBlocks:{defaultValue:!1,describe:"Omit the default extra whiteline added to code blocks",type:"boolean"},noHeaderId:{defaultValue:!1,describe:"Turn on/off generated header id",type:"boolean"},prefixHeaderId:{defaultValue:!1,describe:"Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic 'section-' prefix",type:"string"},rawPrefixHeaderId:{defaultValue:!1,describe:'Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix)',type:"boolean"},ghCompatibleHeaderId:{defaultValue:!1,describe:"Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)",type:"boolean"},rawHeaderId:{defaultValue:!1,describe:"Remove only spaces, ' and \" from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids",type:"boolean"},headerLevelStart:{defaultValue:!1,describe:"The header blocks level start",type:"integer"},parseImgDimensions:{defaultValue:!1,describe:"Turn on/off image dimension parsing",type:"boolean"},simplifiedAutoLink:{defaultValue:!1,describe:"Turn on/off GFM autolink style",type:"boolean"},excludeTrailingPunctuationFromURLs:{defaultValue:!1,describe:"Excludes trailing punctuation from links generated with autoLinking",type:"boolean"},literalMidWordUnderscores:{defaultValue:!1,describe:"Parse midword underscores as literal underscores",type:"boolean"},literalMidWordAsterisks:{defaultValue:!1,describe:"Parse midword asterisks as literal asterisks",type:"boolean"},strikethrough:{defaultValue:!1,describe:"Turn on/off strikethrough support",type:"boolean"},tables:{defaultValue:!1,describe:"Turn on/off tables support",type:"boolean"},tablesHeaderId:{defaultValue:!1,describe:"Add an id to table headers",type:"boolean"},ghCodeBlocks:{defaultValue:!0,describe:"Turn on/off GFM fenced code blocks support",type:"boolean"},tasklists:{defaultValue:!1,describe:"Turn on/off GFM tasklist support",type:"boolean"},smoothLivePreview:{defaultValue:!1,describe:"Prevents weird effects in live previews due to incomplete input",type:"boolean"},smartIndentationFix:{defaultValue:!1,describe:"Tries to smartly fix indentation in es6 strings",type:"boolean"},disableForced4SpacesIndentedSublists:{defaultValue:!1,describe:"Disables the requirement of indenting nested sublists by 4 spaces",type:"boolean"},simpleLineBreaks:{defaultValue:!1,describe:"Parses simple line breaks as (GFM Style)",type:"boolean"},requireSpaceBeforeHeadingText:{defaultValue:!1,describe:"Makes adding a space between `#` and the header text mandatory (GFM Style)",type:"boolean"},ghMentions:{defaultValue:!1,describe:"Enables github @mentions",type:"boolean"},ghMentionsLink:{defaultValue:"https://github.com/{u}",describe:"Changes the link generated by @mentions. Only applies if ghMentions option is enabled.",type:"string"},encodeEmails:{defaultValue:!0,describe:"Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities",type:"boolean"},openLinksInNewWindow:{defaultValue:!1,describe:"Open all links in new windows",type:"boolean"},backslashEscapesHTMLTags:{defaultValue:!1,describe:"Support for HTML Tag escaping. ex:
- The easiest way to add Markdown support to your website!
-
-
- Show your support!
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ The easiest way to add Markdown support to your website!
+
+ Show your support!
+
+
+
+
+
+
+
+
+
+
+## Documentation
+You can view the Documentation for Markdown Tag [here](https://marketingpipeline.github.io/Markdown-Tag/docs/landing) or by viewing the html file at `docs/landing`.
## Example and usage
-
-You can view a demo of Markdown Tag in use [here.](https://marketingpipeline.github.io/Markdown-Tag)
-
-
-How to use Markdown Tag:
-
- Add support to any website to use markdown ANYWHERE with a simple tag! Like so -
-
-
- # Markdown Support
- Awesomeness
-
-
+You can view a demo of Markdown Tag in use [here](https://marketingpipeline.github.io/Markdown-Tag).
- include this [script](https://github.com/MarketingPipeline/Markdown-Tag/blob/main/markdown-tag.js) at the bottom of your HTML document.
-
-
+### Instalation
+Include this [script](https://github.com/MarketingPipeline/Markdown-Tag/blob/main/markdown-tag-wc.js) anywhere in your HTML document.
+```html
+
+```
+### How to use Markdown Tag:
+Add support to any website to use markdown ANYWHERE with a simple tag! Like so -
+```html
+
+# Markdown Support
+Awesomeness
+
+```
-
+> As of v1.0.0, indentation is interpreted, and as such, the content of the HTML element is required to have no indentation.
-How to use Markdown Tag with GitHub Styling:
-
-Instead of using a <md> tag use
-
- # Example
+### How to use Markdown Tag with GitHub Styling:
+Simply add the flavor you want to your tag:
+```html
+
+# Github Styled Markdown
+
+```
## Syntax
- This script uses Showdown to render Markdown - to read about the Showdown's Markdown syntax style click [here](https://github.com/showdownjs/showdown/wiki/Showdown's-Markdown-syntax)
-
-How to use CommonMark Syntax:
-
- If you wish to use [CommonMark](https://spec.commonmark.org/current/) syntax instead of Showdown's use this [script](https://github.com/MarketingPipeline/Markdown-Tag/blob/main/markdown-tag-commonmark.js) instead of the one above at the bottom of your HTML document.
-
-
-
-How to use GitHub Flavored Markdown Syntax:
-
- If you wish to use [GitHub Flavored Markdown Spec](https://github.github.com/gfm/) syntax use this [script](https://github.com/MarketingPipeline/Markdown-Tag/blob/main/markdown-tag-Github.js) instead of the other script's above at the bottom of your HTML document.
-
-
-
-
-
- Note: This options includes - Tables, GitHub Mentions & More.
+### Showdown
+This script uses Showdown by default to render Markdown - to read about the Showdown's Markdown syntax style click [here](https://github.com/showdownjs/showdown/wiki/Showdown's-Markdown-syntax)
+
+### CommonMark
+If you wish to use [CommonMark](https://spec.commonmark.org/current/) syntax instead of Showdown's, simply modify the flavor of your HTML element:
+```html
+
+# Github Styled Markdown
+
+```
+
+### Marked
+If you wish to use [Marked](https://marked.js.org/) syntax instead of Showdown's, simply modify the flavor of your HTML element:
+```html
+
+# Github Styled Markdown
+
+```
+
+## XSS Vulnerabilities
+Last test: Sun May 29 2022 16:34:25 GMT+0100
+
+Last Results:
+```
+=============================================
+ XSS Pentesting Tester Results
+ ---------------------------------------
+ ----- < PAYLOAD > -----
+ - Payload Key: BASIC
+ - ✔ IMMUNE - Application is not vulnerable to this payload.
+ -----------------------
+ ----- < PAYLOAD > -----
+ - Payload Key: TAGBYPASS
+ - ✔ IMMUNE - Application is not vulnerable to this payload.
+ -----------------------
+ ----- < PAYLOAD > -----
+ - Payload Key: BYPASS
+ - ✔ IMMUNE - Application is not vulnerable to this payload.
+ -----------------------
+ ----- < PAYLOAD > -----
+ - Payload Key: ENCODED
+ - ✔ IMMUNE - Application is not vulnerable to this payload.
+ -----------------------
+ ----- < PAYLOAD > -----
+ - Payload Key: POLYGLOTS
+ - ✔ IMMUNE - Application is not vulnerable to this payload.
+ -----------------------
+=============================================
+```
## Known Issues
- [ ] GitHub Flavored Markdown Syntax is not correct 100%
- [ ] GitHub Syntax Needs HTML Decoding Fixed
-- [ ] XSS Vunerability Fix
-
-
-
-
-
+- [X] XSS Vunerability Fix
## Contributing ![GitHub](https://img.shields.io/github/contributors/MarketingPipeline/Markdown-Tag)
diff --git a/docs/1.0.0.html b/docs/1.0.0.html
new file mode 100644
index 0000000..d5b49d1
--- /dev/null
+++ b/docs/1.0.0.html
@@ -0,0 +1,347 @@
+
+
+
+
+
+
+ MarkdownTag Documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Get Started
+
Here's how to quickly install and setup MarkdownTag, no chit-chat involved.
To configure MarkdownTag, edit the attributes on every md-tag you wish to configure.
+
+
+
Attribute
+
Meaning
+
Default
+
+
+
flavor
+
The parser to render the markdown with. Can be one of showdown, github, commonmark or marked
+
showdown
+
+
+
parser_root
+
The root of the remote directory where the parsers are located, if any. Refer to Parser Directory Structure for more information.
+
./
+
+
+
debug
+
Whenever the debugger is enabled for this particular MarkdownTag. Refer to Debugger for more information.
+
false
+
+
+
Editing any md-tag attribute will cause the md-tag to update the render.
+
+
+
+
+
Usage
+
On Load
+
A MarkdownTag accepts an initial input, by simply placing it on the body of the element:
+
+
+
+ <md-tag>
+ # Hello
+ </md-tag>
+
+
+
+
+
Warning: The indentation of the content inside the element will not be stripped and will be interpreted by the Markdown Parsers.
+
+
+
+
+
Danger: The content inserted directly into the element will not be sanitized, due to limitations due to the DOM's functioning. To ensure safety of the input, use the API:
+
+
+ const element = document.querySelector("md-tag") // Use your preferred method of fetching your element
+ element.setInput("# Hello")
+
+
+
+
+
+
Anytime
+
A MarkdownTag's content can be modified at any point, by accessing the element's API:
+
+
+
+ const element = document.querySelector("md-tag") // Use your preferred method of fetching your element
+ element.setInput("# Hello")
+
+
+ Each MarkdownTag element comes packed with a debugger, which logs all information about the current MarkdownTag in real time.
+
+
+
+
Info: The Debugger requires a separated debug script accessible via adding this line BEFORE THE MAIN SCRIPT:
+
+ <script src="https://cdn.jsdelivr.net/gh/MarketingPipeline/Markdown-Tag/markdown-tag-wc-debug.js"></script>
+
+
+
+
Warning: The Debugger will only log messages triggered since the debugger was turned on.
+
+
+ To turn on the Debugger, simply set the debug attribute on the element to "true" (See Configuration) or programically set the debugEnabled property to true.
+
+
+ Each MarkdownTag element can be accessed programatically via an exposed API. To access the API, simply get a handle to the element using getElementById, querySelector or your preferred method of fetching elements.
+
+
+
+
Warning: Only the documented API methods were tested. Any internal calls were not tested against being called from the outside and no support will be provided if you attempt to do so.
+ Gathers, formats, and compiles the logs into a JSON string.
+
Parameters
+
+
+
clipboard: Boolean - Whenever the logs should be automatically copied to the user's clipboard. If set to true, function will return true, else function will return a JSON string containing the logs.
+
+
+
Returns: String|Boolean A JSON string containing the registered logs, or true if clipboard is set to true.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatum consequuntur laboriosam eos alias aspernatur, ea excepturi, quos sequi cumque hic sit, praesentium iusto! Debitis cumque est architecto deleniti quo dolore.
+
+
+
+
+
Success Alert Message
+
+
+
+
+
Danger Alert Message
+
+
+
+
+
Warning Alert Message
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/markdown-tag-GitHub.js b/markdown-tag-GitHub.js
deleted file mode 100644
index 098caa4..0000000
--- a/markdown-tag-GitHub.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/*! showdown v 2.1.0 - 21-04-2022 */
-!function(){function a(e){"use strict";var r={omitExtraWLInCodeBlocks:{defaultValue:!1,describe:"Omit the default extra whiteline added to code blocks",type:"boolean"},noHeaderId:{defaultValue:!1,describe:"Turn on/off generated header id",type:"boolean"},prefixHeaderId:{defaultValue:!1,describe:"Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic 'section-' prefix",type:"string"},rawPrefixHeaderId:{defaultValue:!1,describe:'Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix)',type:"boolean"},ghCompatibleHeaderId:{defaultValue:!1,describe:"Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)",type:"boolean"},rawHeaderId:{defaultValue:!1,describe:"Remove only spaces, ' and \" from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids",type:"boolean"},headerLevelStart:{defaultValue:!1,describe:"The header blocks level start",type:"integer"},parseImgDimensions:{defaultValue:!1,describe:"Turn on/off image dimension parsing",type:"boolean"},simplifiedAutoLink:{defaultValue:!1,describe:"Turn on/off GFM autolink style",type:"boolean"},excludeTrailingPunctuationFromURLs:{defaultValue:!1,describe:"Excludes trailing punctuation from links generated with autoLinking",type:"boolean"},literalMidWordUnderscores:{defaultValue:!1,describe:"Parse midword underscores as literal underscores",type:"boolean"},literalMidWordAsterisks:{defaultValue:!1,describe:"Parse midword asterisks as literal asterisks",type:"boolean"},strikethrough:{defaultValue:!1,describe:"Turn on/off strikethrough support",type:"boolean"},tables:{defaultValue:!1,describe:"Turn on/off tables support",type:"boolean"},tablesHeaderId:{defaultValue:!1,describe:"Add an id to table headers",type:"boolean"},ghCodeBlocks:{defaultValue:!0,describe:"Turn on/off GFM fenced code blocks support",type:"boolean"},tasklists:{defaultValue:!1,describe:"Turn on/off GFM tasklist support",type:"boolean"},smoothLivePreview:{defaultValue:!1,describe:"Prevents weird effects in live previews due to incomplete input",type:"boolean"},smartIndentationFix:{defaultValue:!1,describe:"Tries to smartly fix indentation in es6 strings",type:"boolean"},disableForced4SpacesIndentedSublists:{defaultValue:!1,describe:"Disables the requirement of indenting nested sublists by 4 spaces",type:"boolean"},simpleLineBreaks:{defaultValue:!1,describe:"Parses simple line breaks as (GFM Style)",type:"boolean"},requireSpaceBeforeHeadingText:{defaultValue:!1,describe:"Makes adding a space between `#` and the header text mandatory (GFM Style)",type:"boolean"},ghMentions:{defaultValue:!1,describe:"Enables github @mentions",type:"boolean"},ghMentionsLink:{defaultValue:"https://github.com/{u}",describe:"Changes the link generated by @mentions. Only applies if ghMentions option is enabled.",type:"string"},encodeEmails:{defaultValue:!0,describe:"Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities",type:"boolean"},openLinksInNewWindow:{defaultValue:!1,describe:"Open all links in new windows",type:"boolean"},backslashEscapesHTMLTags:{defaultValue:!1,describe:"Support for HTML Tag escaping. ex: