Fix filter/map tag disambiguation inside SVG context without keyword attrs
(filter (feTurbulence ...)) inside (svg ...) has no keyword first arg, so the keyword-only check dispatched it as a HO function. Now also check SVG/MathML context (ns in client, _svg_context in server). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1288,9 +1288,9 @@
|
|||||||
if (name.indexOf("html:") === 0) return renderElement(name.substring(5), expr.slice(1), env, ns);
|
if (name.indexOf("html:") === 0) return renderElement(name.substring(5), expr.slice(1), env, ns);
|
||||||
|
|
||||||
// Render-aware special forms
|
// Render-aware special forms
|
||||||
// If name is also an HTML tag and first arg is Keyword → tag call
|
// If name is also an HTML tag and (keyword arg or SVG/MathML ns) → tag call
|
||||||
if (RENDER_FORMS[name]) {
|
if (RENDER_FORMS[name]) {
|
||||||
if (HTML_TAGS[name] && expr.length > 1 && isKw(expr[1])) return renderElement(name, expr.slice(1), env, ns);
|
if (HTML_TAGS[name] && ((expr.length > 1 && isKw(expr[1])) || ns)) return renderElement(name, expr.slice(1), env, ns);
|
||||||
return RENDER_FORMS[name](expr, env, ns);
|
return RENDER_FORMS[name](expr, env, ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -648,10 +648,13 @@ async def _arender_list(expr: list, env: dict[str, Any], ctx: RequestContext) ->
|
|||||||
return await _arender_element(name[5:], expr[1:], env, ctx)
|
return await _arender_element(name[5:], expr[1:], env, ctx)
|
||||||
|
|
||||||
# Render-aware special forms
|
# Render-aware special forms
|
||||||
# If name is also an HTML tag and first arg is Keyword → tag call
|
# If name is also an HTML tag and (keyword arg or SVG context) → tag call
|
||||||
arsf = _ASYNC_RENDER_FORMS.get(name)
|
arsf = _ASYNC_RENDER_FORMS.get(name)
|
||||||
if arsf is not None:
|
if arsf is not None:
|
||||||
if name in HTML_TAGS and len(expr) > 1 and isinstance(expr[1], Keyword):
|
if name in HTML_TAGS and (
|
||||||
|
(len(expr) > 1 and isinstance(expr[1], Keyword))
|
||||||
|
or _svg_context.get(False)
|
||||||
|
):
|
||||||
return await _arender_element(name, expr[1:], env, ctx)
|
return await _arender_element(name, expr[1:], env, ctx)
|
||||||
return await arsf(expr, env, ctx)
|
return await arsf(expr, env, ctx)
|
||||||
|
|
||||||
@@ -1098,10 +1101,13 @@ async def _aser(expr: Any, env: dict[str, Any], ctx: RequestContext) -> Any:
|
|||||||
|
|
||||||
# Serialize-mode special/HO forms (checked BEFORE HTML_TAGS
|
# Serialize-mode special/HO forms (checked BEFORE HTML_TAGS
|
||||||
# because some names like "map" are both HTML tags and sx forms).
|
# because some names like "map" are both HTML tags and sx forms).
|
||||||
# If name is also an HTML tag and first arg is Keyword → tag call.
|
# If name is also an HTML tag and (keyword arg or SVG context) → tag call.
|
||||||
sf = _ASER_FORMS.get(name)
|
sf = _ASER_FORMS.get(name)
|
||||||
if sf is not None:
|
if sf is not None:
|
||||||
if name in HTML_TAGS and len(expr) > 1 and isinstance(expr[1], Keyword):
|
if name in HTML_TAGS and (
|
||||||
|
(len(expr) > 1 and isinstance(expr[1], Keyword))
|
||||||
|
or _svg_context.get(False)
|
||||||
|
):
|
||||||
return await _aser_call(name, expr[1:], env, ctx)
|
return await _aser_call(name, expr[1:], env, ctx)
|
||||||
return await sf(expr, env, ctx)
|
return await sf(expr, env, ctx)
|
||||||
|
|
||||||
|
|||||||
@@ -442,11 +442,14 @@ def _render_list(expr: list, env: dict[str, Any]) -> str:
|
|||||||
|
|
||||||
# --- Render-aware special forms --------------------------------------
|
# --- Render-aware special forms --------------------------------------
|
||||||
# Check BEFORE HTML_TAGS because some names overlap (e.g. `map`).
|
# Check BEFORE HTML_TAGS because some names overlap (e.g. `map`).
|
||||||
# But if the name is ALSO an HTML tag and first arg is a Keyword,
|
# But if the name is ALSO an HTML tag and (a) first arg is a Keyword
|
||||||
# it's a tag call (e.g. (filter :id "x" ...)), not a HO function.
|
# or (b) we're inside SVG/MathML context, it's a tag call.
|
||||||
rsf = _RENDER_FORMS.get(name)
|
rsf = _RENDER_FORMS.get(name)
|
||||||
if rsf is not None:
|
if rsf is not None:
|
||||||
if name in HTML_TAGS and len(expr) > 1 and isinstance(expr[1], Keyword):
|
if name in HTML_TAGS and (
|
||||||
|
(len(expr) > 1 and isinstance(expr[1], Keyword))
|
||||||
|
or _svg_context.get(False)
|
||||||
|
):
|
||||||
return _render_element(name, expr[1:], env)
|
return _render_element(name, expr[1:], env)
|
||||||
return rsf(expr, env)
|
return rsf(expr, env)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user