Name the preload-required predicate

Compress the "do we need to load WP records?" condition into
`preload_required?(context)` so the call site reads as intent rather
than a tangle of two unrelated signals. The reasoning (semantic mode
needs row lookup; static-HTML output needs type/subject for the
anchor) moves to a comment on the predicate, where it belongs.
This commit is contained in:
Kabiru Mwenja
2026-05-26 14:22:25 +03:00
parent e70b9ab21c
commit 989dbf9da8
@@ -166,14 +166,9 @@ module OpenProject::TextFormatting
# Doc-level preload called by `PatternMatcherFilter`. Save/restores
# the cache so a nested `format_text` (e.g. custom-field formatter
# re-entering the pipeline) doesn't clobber the outer render.
# Fires when semantic identifiers need resolving or when a
# static-HTML channel needs the WP record to compose the
# type/subject/status anchor; other channels render `#N` from the
# matched id alone and the as-text path short-circuits on
# `text_only?` before consulting the cache.
def self.with_preloaded_resources(doc, context)
previous = RequestStore.store[CACHE_KEY]
return yield unless Setting::WorkPackageIdentifier.semantic? || context[:as_static_html]
return yield unless preload_required?(context)
identifiers = collect_work_package_identifiers(doc)
return yield if identifiers.empty?
@@ -184,6 +179,17 @@ module OpenProject::TextFormatting
RequestStore.store[CACHE_KEY] = previous
end
# Two channels need the WP record at render time: semantic mode (to
# resolve `PROJ-7` to a row) and static-HTML output (to compose the
# type/subject anchor of a quickinfo macro). Classic-mode rich HTML
# and the as-text channel both render from the matched id alone —
# the latter short-circuits on `text_only?` before consulting the
# cache.
def self.preload_required?(context)
Setting::WorkPackageIdentifier.semantic? || context[:as_static_html]
end
private_class_method :preload_required?
def self.collect_work_package_identifiers(doc)
identifiers = Set.new
doc.search(".//text()").each do |node|