Put filterElement logic completely into its own file

This commit is contained in:
Henrik Giesel 2021-03-24 21:18:16 +01:00 committed by Damien Elmes
parent 1d4d7fabec
commit d3d3720b39
2 changed files with 38 additions and 23 deletions

View file

@ -2,7 +2,7 @@
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */ * License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
import { nodeIsElement } from "./helpers"; import { nodeIsElement } from "./helpers";
import { tagsAllowedBasic, tagsAllowedExtended } from "./htmlFilterTagsAllowed"; import { filterElement } from "./htmlFilterElement";
////////////////////// //////////////////// //////////////////// ////////////////////// //////////////////// ////////////////////
@ -40,23 +40,10 @@ function filterNode(node: Node, extendedMode: boolean): void {
filterNode(child, extendedMode); filterNode(child, extendedMode);
} }
if (node.tagName === "ANKITOP") { filterElement(node, extendedMode);
return;
}
const tagsAllowed = extendedMode ? tagsAllowedExtended : tagsAllowedBasic;
if (tagsAllowed.hasOwnProperty(node.tagName)) {
tagsAllowed[node.tagName](node);
} else {
if (!node.innerHTML || node.tagName === "TITLE") {
node.parentNode.removeChild(node);
} else {
node.outerHTML = node.innerHTML;
}
}
} }
export function filterHTML( export function filterHTML(
html: string, html: string,
internal: boolean, internal: boolean,

View file

@ -1,10 +1,12 @@
import { filterSpan } from "./htmlFilterSpan"; import { filterSpan } from "./htmlFilterSpan";
interface TagsAllowed {
[tagName: string]: FilterMethod;
}
type FilterMethod = (element: Element) => void; type FilterMethod = (element: Element) => void;
interface TagsAllowed { function doNothing() {}
[key: string]: FilterMethod;
}
function filterOutAttributes( function filterOutAttributes(
attributePredicate: (attributeName: string) => boolean, attributePredicate: (attributeName: string) => boolean,
@ -19,6 +21,10 @@ function filterOutAttributes(
} }
} }
function blockAll(element: Element): void {
filterOutAttributes(() => true, element);
}
function blockExcept(attrs: string[]): FilterMethod { function blockExcept(attrs: string[]): FilterMethod {
return (element: Element) => return (element: Element) =>
filterOutAttributes( filterOutAttributes(
@ -27,20 +33,27 @@ function blockExcept(attrs: string[]): FilterMethod {
); );
} }
function blockAll(element: Element): void {
filterOutAttributes(() => true, element); function removeElement(element: Element): void {
element.parentNode?.removeChild(element);
} }
export const tagsAllowedBasic: TagsAllowed = { function unwrapElement(element: Element): void {
element.outerHTML = element.innerHTML;
}
const tagsAllowedBasic: TagsAllowed = {
ANKITOP: doNothing,
BR: blockAll, BR: blockAll,
IMG: blockExcept(["SRC"]), IMG: blockExcept(["SRC"]),
DIV: blockAll, DIV: blockAll,
P: blockAll, P: blockAll,
SUB: blockAll, SUB: blockAll,
SUP: blockAll, SUP: blockAll,
TITLE: removeElement,
}; };
export const tagsAllowedExtended: TagsAllowed = { const tagsAllowedExtended: TagsAllowed = {
...tagsAllowedBasic, ...tagsAllowedBasic,
A: blockExcept(["HREF"]), A: blockExcept(["HREF"]),
B: blockAll, B: blockAll,
@ -70,3 +83,18 @@ export const tagsAllowedExtended: TagsAllowed = {
U: blockAll, U: blockAll,
UL: blockAll, UL: blockAll,
}; };
export function filterElement(element: Element, extendedMode: boolean): void {
const tagName = element.tagName;
const tagsAllowed = extendedMode ? tagsAllowedExtended : tagsAllowedBasic;
if (tagsAllowed.hasOwnProperty(tagName)) {
tagsAllowed[tagName](element);
}
else if (element.innerHTML) {
removeElement(element);
}
else {
unwrapElement(element);
}
}