Skip to content

Commit

Permalink
HTMLTextDocument() now preserves the order of serialized dependenci…
Browse files Browse the repository at this point in the history
…es (#95)

* Update unit test to check for order of dependencies

* Preserve order of dependencies when deduping

* Update changelog
  • Loading branch information
cpsievert authored Sep 18, 2024
1 parent 3005d6a commit 1857415
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 8 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [UNRELEASED]


* Fixed an issue with `HTMLTextDocument()` returning extracted `HTMLDependency()`s in a non-determistic order. (#95)

## [0.5.3] 2024-07-18

Expand Down
13 changes: 9 additions & 4 deletions htmltools/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1215,19 +1215,24 @@ def _static_extract_serialized_html_deps(
# HTMLdependency.get_tag_representation()
pattern = r'<script type="application/json" data-html-dependency="">((?:.|\r|\n)*?)</script>'
dep_strs = re.findall(pattern, html)
# Deduplicate dependencies. htmltools normally would dedupe dependencies, but
# with HTMLTextDocuments, the input HTML would usually have been generated by
# something else (like Quarto) and may not have the dependencies deduped.
dep_strs = list(set(dep_strs))

# Remove the serialized HTML dependencies from the HTML string
html = re.sub(pattern, "", html)

# Reconstitute the HTMLDependency objects
#
# Note: htmltools normally would dedupe dependencies, but
# with HTMLTextDocuments, the input HTML would usually have been generated by
# something else (like Quarto) and may not have the dependencies deduped.
seen_deps: set[str] = set()
deps: list[HTMLDependency] = []
for dep_str in dep_strs:
if dep_str in seen_deps:
continue
args = json.loads(dep_str)
dep = HTMLDependency(**args)
deps.append(dep)
seen_deps.add(dep_str)

return (html, deps)

Expand Down
6 changes: 3 additions & 3 deletions tests/test_html_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,9 @@ def test_json_roundtrip():
x_str, deps_replace_pattern='<meta data-foo="">'
).render()

# Make sure both deps are present.
assert "testdep" in [d.name for d in rendered["dependencies"]]
assert "testdep2" in [d.name for d in rendered["dependencies"]]
# Make sure both deps are present and in the order they appear in x_str.
assert "testdep2" == rendered["dependencies"][0].name
assert "testdep" == rendered["dependencies"][1].name

# Make sure testdep was deduplicated by HTMLTextDocument().render().
assert rendered["dependencies"].count(testdep) == 1
Expand Down

0 comments on commit 1857415

Please sign in to comment.