Jul 24 - Update Rich-text editor to enhance table editor

This commit is contained in:
2026-07-24 10:42:22 -04:00
parent 10a8658b67
commit db2d1795b4
10 changed files with 125 additions and 85 deletions
+26 -9
View File
@@ -4,6 +4,7 @@ from datetime import datetime
from logging.handlers import RotatingFileHandler
import bleach
from bleach.css_sanitizer import CSSSanitizer
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import CSRFProtect
@@ -93,30 +94,46 @@ ALLOWED_TAGS = [
"ul", "ol", "li", "a", "h2", "h3", "blockquote",
# images (inserted via the /admin/upload endpoint or a URL)
"img",
# tables (Quill 2 built-in table module)
# tables (quill-table-better: resizable cols, aligned/styled cells)
"table", "thead", "tbody", "tr", "td", "th", "col", "colgroup",
]
# quill-table-better carries column widths, alignment, borders and background
# as inline `style` on the table/cell tags, plus data-* bookkeeping attributes.
_TABLE_CELL_ATTRS = [
"data-row", "data-cell", "data-class", "colspan", "rowspan",
"width", "height", "style",
]
ALLOWED_ATTRS = {
"a": ["href", "title", "target", "rel"],
"img": ["src", "alt", "width", "height"],
# Quill 2 tags cells/rows with data-row; keep the standard span attrs too.
"table": ["class"],
"td": ["data-row", "colspan", "rowspan"],
"th": ["data-row", "colspan", "rowspan"],
"tr": ["data-row"],
"col": ["width"],
"table": ["class", "style", "align", "width", "height", "data-class"],
"colgroup": ["style"],
"col": ["width", "span", "style"],
"tr": ["data-row", "style"],
"td": _TABLE_CELL_ATTRS,
"th": _TABLE_CELL_ATTRS,
}
# Only these CSS properties survive on a `style` attribute — enough for the
# table editor's sizing/alignment/borders, nothing that can smuggle script.
ALLOWED_CSS_PROPS = [
"width", "height", "min-width", "padding", "text-align", "vertical-align",
"background-color", "border", "border-style", "border-color",
"border-width", "border-collapse",
]
_css_sanitizer = CSSSanitizer(allowed_css_properties=ALLOWED_CSS_PROPS)
def sanitize_html(raw):
"""Clean editor HTML against the allowlist. Returns None for empty content
so blank bodies stay NULL. bleach also restricts URL protocols to
http/https/mailto for both links and images, blocking javascript: and
data: URLs (uploaded images are served from a relative /static path)."""
data: URLs (uploaded images are served from a relative /static path). Inline
`style` is filtered to the ALLOWED_CSS_PROPS allowlist via CSSSanitizer."""
if not raw:
return None
cleaned = bleach.clean(
raw, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRS, strip=True
raw, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRS, strip=True,
css_sanitizer=_css_sanitizer,
).strip()
# Quill leaves an empty paragraph for a blank editor.
if cleaned in ("", "<p></p>", "<p><br></p>"):