Files
LithosAnanke/site/colorlock.py
T
Claude c2ff10015f
Build / Image MILKV (push) Canceled after 0s
Build / Image PC (push) Canceled after 0s
Build / Image RASPI (push) Canceled after 0s
Build / v4 tests (32- and 64-bit cells) (push) Canceled after 0s
site: the design's colours over the wikis' high-contrast theme; .org inquiries
- site/colorlock.py: both XWikis force black and white with !important (a
  HIGH CONTRAST DARK THEME block in the skin's cssVariablesInit.css). On our
  pages only, the design's colours win: each inline colour made !important,
  and a stylesheet scoped to the page root (.ssos) for the rest. Used by
  site/com/build.py and site/org/build.py; the .com reinstalled with it.
- site/org/inquiries (Captain Bob, 2026-11-07): the .com's inquiries go to an
  admin-only master/detail on the .org -- Inquiries.WebHome (Live Data
  table), one page per inquiry under Inquiries.Entries with a sheet and a
  status, PublicInquiry (public) filing them with its author's rights and
  echoing nothing a visitor sends; a hidden trap field for robots. The .com
  form posts there. Installed and tested: a guest's inquiry filed and
  deleted; one whose name and message were script macros was stored as
  text, nothing ran.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GE3SDvQn5EoxdGufk84zz2
2026-11-07 13:47:37 +00:00

42 lines
2.1 KiB
Python

"""colorlock.py -- keep a page's own colours inside a wiki whose theme forces its own.
Both XWikis carry a high-contrast theme (skins/flamingo/cssVariablesInit.css on the server) that sets
every element black on white with !important. On our pages the design's colours win instead
(Captain Bob, 2026-11-07), and on those pages only; the rest of the wiki keeps the theme:
- every colour an element states in its style="" is made !important -- an inline !important beats
any stylesheet's;
- a stylesheet scoped to the page's root (class "ssos") covers the elements that state no colour:
".ssos *" outranks the theme's "*" (both !important, the more specific wins).
"""
import re
ROOT_CLASS = "ssos"
STYLE = """<style>
.ssos, .ssos *, .ssos *::before, .ssos *::after { background-color: transparent !important; color: inherit !important; border-color: #22324D !important; }
.ssos a, .ssos a * { color: #F5891F !important; }
.ssos a:hover { color: #FFB061 !important; }
.ssos input, .ssos textarea, .ssos select { background-color: #0A1222 !important; color: #EEF2F7 !important; border-color: #34486A !important; }
.ssos ::placeholder { color: #A3AEC2 !important; opacity: 1 !important; }
.ssos img { background-color: transparent !important; }
</style>"""
COLOUR_PROPS = re.compile(r"^\s*(color|background|background-color|border|border-(top|right|bottom|left)|"
r"border-color|border-(top|right|bottom|left)-color|accent-color|fill)\s*:", re.I)
def _lock_style(m):
decls = []
for d in m.group(1).split(";"):
if d.strip() and COLOUR_PROPS.match(d) and "!important" not in d:
d = d.rstrip() + " !important"
decls.append(d)
return 'style="%s"' % ";".join(decls)
def lock(html, root_marker):
"""root_marker: the opening text of the page's root element, e.g. '<div style="background: #0A1222'."""
assert html.count(root_marker) >= 1, root_marker
html = html.replace(root_marker, root_marker.replace("<div ", '<div class="%s" ' % ROOT_CLASS, 1), 1)
html = re.sub(r'style="([^"]*)"', _lock_style, html)
return STYLE + "\n" + html