2021-03-25 00:43:01 +01:00
|
|
|
import { isHTMLElement, isNightMode } from "./helpers";
|
|
|
|
import { removeNode as removeElement } from "./node";
|
2021-03-24 23:35:51 +01:00
|
|
|
import {
|
|
|
|
filterStylingNightMode,
|
|
|
|
filterStylingLightMode,
|
|
|
|
filterStylingInternal,
|
2021-03-25 00:43:01 +01:00
|
|
|
} from "./styling";
|
2021-03-24 21:04:12 +01:00
|
|
|
|
|
|
|
interface TagsAllowed {
|
2021-03-24 21:18:16 +01:00
|
|
|
[tagName: string]: FilterMethod;
|
2021-03-24 21:04:12 +01:00
|
|
|
}
|
|
|
|
|
2021-03-24 21:18:16 +01:00
|
|
|
type FilterMethod = (element: Element) => void;
|
|
|
|
|
2021-03-24 21:04:12 +01:00
|
|
|
function filterOutAttributes(
|
|
|
|
attributePredicate: (attributeName: string) => boolean,
|
|
|
|
element: Element
|
|
|
|
): void {
|
|
|
|
for (const attr of [...element.attributes]) {
|
|
|
|
const attrName = attr.name.toUpperCase();
|
|
|
|
|
|
|
|
if (attributePredicate(attrName)) {
|
|
|
|
element.removeAttributeNode(attr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-24 21:18:16 +01:00
|
|
|
function blockAll(element: Element): void {
|
|
|
|
filterOutAttributes(() => true, element);
|
|
|
|
}
|
|
|
|
|
2021-03-25 00:43:01 +01:00
|
|
|
const blockExcept = (attrs: string[]): FilterMethod => (element: Element): void =>
|
|
|
|
filterOutAttributes(
|
|
|
|
(attributeName: string) => !attrs.includes(attributeName),
|
|
|
|
element
|
|
|
|
);
|
2021-03-24 21:04:12 +01:00
|
|
|
|
2021-03-24 21:18:16 +01:00
|
|
|
function unwrapElement(element: Element): void {
|
|
|
|
element.outerHTML = element.innerHTML;
|
|
|
|
}
|
|
|
|
|
2021-03-24 23:35:51 +01:00
|
|
|
function filterSpan(element: Element): void {
|
|
|
|
const filterAttrs = blockExcept(["STYLE"]);
|
|
|
|
filterAttrs(element);
|
|
|
|
|
|
|
|
const filterStyle = isNightMode() ? filterStylingNightMode : filterStylingLightMode;
|
|
|
|
filterStyle(element as HTMLSpanElement);
|
|
|
|
}
|
|
|
|
|
2021-03-24 21:18:16 +01:00
|
|
|
const tagsAllowedBasic: TagsAllowed = {
|
2021-03-24 21:04:12 +01:00
|
|
|
BR: blockAll,
|
|
|
|
IMG: blockExcept(["SRC"]),
|
|
|
|
DIV: blockAll,
|
|
|
|
P: blockAll,
|
|
|
|
SUB: blockAll,
|
|
|
|
SUP: blockAll,
|
2021-03-24 21:18:16 +01:00
|
|
|
TITLE: removeElement,
|
2021-03-24 21:04:12 +01:00
|
|
|
};
|
|
|
|
|
2021-03-24 21:18:16 +01:00
|
|
|
const tagsAllowedExtended: TagsAllowed = {
|
2021-03-24 21:04:12 +01:00
|
|
|
...tagsAllowedBasic,
|
|
|
|
A: blockExcept(["HREF"]),
|
|
|
|
B: blockAll,
|
|
|
|
BLOCKQUOTE: blockAll,
|
|
|
|
CODE: blockAll,
|
|
|
|
DD: blockAll,
|
|
|
|
DL: blockAll,
|
|
|
|
DT: blockAll,
|
|
|
|
EM: blockAll,
|
|
|
|
FONT: blockExcept(["COLOR"]),
|
|
|
|
H1: blockAll,
|
|
|
|
H2: blockAll,
|
|
|
|
H3: blockAll,
|
|
|
|
I: blockAll,
|
|
|
|
LI: blockAll,
|
|
|
|
OL: blockAll,
|
|
|
|
PRE: blockAll,
|
|
|
|
RP: blockAll,
|
|
|
|
RT: blockAll,
|
|
|
|
RUBY: blockAll,
|
|
|
|
SPAN: filterSpan,
|
|
|
|
STRONG: blockAll,
|
|
|
|
TABLE: blockAll,
|
|
|
|
TD: blockExcept(["COLSPAN", "ROWSPAN"]),
|
|
|
|
TH: blockExcept(["COLSPAN", "ROWSPAN"]),
|
|
|
|
TR: blockExcept(["ROWSPAN"]),
|
|
|
|
U: blockAll,
|
|
|
|
UL: blockAll,
|
|
|
|
};
|
2021-03-24 21:18:16 +01:00
|
|
|
|
2021-03-24 23:35:51 +01:00
|
|
|
const filterElementTagsAllowed = (tagsAllowed: TagsAllowed) => (
|
|
|
|
element: Element
|
|
|
|
): void => {
|
2021-03-24 21:18:16 +01:00
|
|
|
const tagName = element.tagName;
|
|
|
|
|
2021-03-25 00:43:01 +01:00
|
|
|
if (Object.prototype.hasOwnProperty.call(tagsAllowed, tagName)) {
|
2021-03-24 21:18:16 +01:00
|
|
|
tagsAllowed[tagName](element);
|
2021-03-24 23:35:51 +01:00
|
|
|
} else if (element.innerHTML) {
|
2021-03-24 21:18:16 +01:00
|
|
|
removeElement(element);
|
2021-03-24 23:35:51 +01:00
|
|
|
} else {
|
2021-03-24 21:18:16 +01:00
|
|
|
unwrapElement(element);
|
|
|
|
}
|
2021-03-24 23:35:51 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
export const filterElementBasic = filterElementTagsAllowed(tagsAllowedBasic);
|
|
|
|
export const filterElementExtended = filterElementTagsAllowed(tagsAllowedExtended);
|
|
|
|
|
|
|
|
export function filterElementInternal(element: Element): void {
|
|
|
|
if (isHTMLElement(element)) {
|
|
|
|
filterStylingInternal(element);
|
|
|
|
}
|
2021-03-24 21:18:16 +01:00
|
|
|
}
|