From 975f5f23d18b62f890b5415562d4eef82fc6ee70 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Wed, 9 Nov 2022 00:13:20 -0800
Subject: [PATCH 01/26] Insert head content into html_to_vdom
---
src/idom/utils.py | 31 ++++++++++++++++++-------------
tests/test_utils.py | 24 ++++++++++++++++++++++++
2 files changed, 42 insertions(+), 13 deletions(-)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index e176da660..92ad7db53 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -2,7 +2,7 @@
from typing import Any, Callable, Generic, Iterable, List, TypeVar, Union
from lxml import etree
-from lxml.html import fragments_fromstring
+from lxml.html import document_fromstring
import idom
from idom.core.types import VdomDict
@@ -77,16 +77,20 @@ def html_to_vdom(
raise TypeError(f"Expected html to be a string, not {type(html).__name__}")
# If the user provided a string, convert it to a list of lxml.etree nodes
- parser = etree.HTMLParser(
- remove_comments=True,
- remove_pis=True,
- remove_blank_text=True,
- recover=not strict,
- )
try:
- nodes: list[etree._Element] = fragments_fromstring(
- html, no_leading_text=True, parser=parser
+ parsed_document = document_fromstring(
+ html.strip(),
+ ensure_head_body=True,
+ parser=etree.HTMLParser(
+ remove_comments=True,
+ remove_pis=True,
+ remove_blank_text=True,
+ recover=not strict,
+ ),
)
+ nodes: List = parsed_document.find("body")
+ for element in reversed(parsed_document.find("head")):
+ nodes.insert(0, element)
except etree.XMLSyntaxError as e:
if not strict:
raise e # pragma: no cover
@@ -102,8 +106,9 @@ def html_to_vdom(
# Find or create a root node
if has_root_node:
root_node = nodes[0]
+
+ # etree.Element requires a non-empty tag name. The tag name `TEMP` is deleted below.
else:
- # etree.Element requires a non-empty tag - we correct this below
root_node = etree.Element("TEMP", None, None)
for child in nodes:
root_node.append(child)
@@ -111,7 +116,7 @@ def html_to_vdom(
# Convert the lxml node to a VDOM dict
vdom = _etree_to_vdom(root_node, transforms)
- # Change the artificially created root node to a React Fragment, instead of a div
+ # Change the artificially `TEMP` root node to a React Fragment
if not has_root_node:
vdom["tagName"] = ""
@@ -121,7 +126,7 @@ def html_to_vdom(
def _etree_to_vdom(
node: etree._Element, transforms: Iterable[_ModelTransform]
) -> VdomDict:
- """Recusively transform an lxml etree node into a DOM model
+ """Transform an lxml etree node into a DOM model
Parameters:
source:
@@ -136,7 +141,7 @@ def _etree_to_vdom(
f"Expected node to be a etree._Element, not {type(node).__name__}"
)
- # This will recursively call _etree_to_vdom() on all children
+ # Recursively call _etree_to_vdom() on all children
children = _generate_vdom_children(node, transforms)
# Convert the lxml node to a VDOM dict
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 861fc315d..fa6d50a8a 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -149,3 +149,27 @@ def test_html_to_vdom_with_no_parent_node():
}
assert html_to_vdom(source) == expected
+
+def test_html_to_vdom_with_html_body_head():
+ source = """
+
+
+
+
+ My Title
+
+
+ Hello World
+
+
+ """
+
+ expected = {
+ "tagName": "",
+ "children": [
+ {"tagName": "title", "children": ["My Title"]},
+ {"tagName": "h1", "children": ["Hello World"]},
+ ],
+ }
+
+ assert html_to_vdom(source) == expected
From 77270a28cb8e68e53e93d41ebb508f27f2f943ad Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Wed, 9 Nov 2022 00:25:20 -0800
Subject: [PATCH 02/26] more efficient node appending
---
src/idom/utils.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index 92ad7db53..969720b72 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -88,9 +88,8 @@ def html_to_vdom(
recover=not strict,
),
)
- nodes: List = parsed_document.find("body")
- for element in reversed(parsed_document.find("head")):
- nodes.insert(0, element)
+ nodes: etree._Element = parsed_document.find("head")
+ nodes.extend(parsed_document.find("body"))
except etree.XMLSyntaxError as e:
if not strict:
raise e # pragma: no cover
From a815efc051f9ad22f0773f26b3b61325ffb92563 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Wed, 9 Nov 2022 00:32:31 -0800
Subject: [PATCH 03/26] add changelog
---
docs/source/about/changelog.rst | 4 +++-
tests/test_utils.py | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/docs/source/about/changelog.rst b/docs/source/about/changelog.rst
index 415a16699..594a4afa1 100644
--- a/docs/source/about/changelog.rst
+++ b/docs/source/about/changelog.rst
@@ -23,7 +23,9 @@ more info, see the :ref:`Contributor Guide `.
Unreleased
----------
-No changes.
+**Fixed**
+
+- :issue:`832` - Fix ``html_to_vdom`` improperly handling ```` children
v0.41.0
diff --git a/tests/test_utils.py b/tests/test_utils.py
index fa6d50a8a..4c822e5bf 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -150,6 +150,7 @@ def test_html_to_vdom_with_no_parent_node():
assert html_to_vdom(source) == expected
+
def test_html_to_vdom_with_html_body_head():
source = """
From 745a537d012ab5ee4afb2e2d6f6ceb8e16c599e9 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Wed, 9 Nov 2022 00:44:26 -0800
Subject: [PATCH 04/26] nodes -> body node
---
src/idom/utils.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index 969720b72..1c36561d9 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -88,8 +88,8 @@ def html_to_vdom(
recover=not strict,
),
)
- nodes: etree._Element = parsed_document.find("head")
- nodes.extend(parsed_document.find("body"))
+ body_node: etree._Element = parsed_document.find("head")
+ body_node.extend(parsed_document.find("body"))
except etree.XMLSyntaxError as e:
if not strict:
raise e # pragma: no cover
@@ -100,16 +100,16 @@ def html_to_vdom(
"you can disable the strict parameter on html_to_vdom().\n"
"Otherwise, repair your broken HTML and try again."
) from e
- has_root_node = len(nodes) == 1
+ has_root_node = len(body_node) == 1
# Find or create a root node
if has_root_node:
- root_node = nodes[0]
+ root_node = body_node[0]
# etree.Element requires a non-empty tag name. The tag name `TEMP` is deleted below.
else:
root_node = etree.Element("TEMP", None, None)
- for child in nodes:
+ for child in body_node:
root_node.append(child)
# Convert the lxml node to a VDOM dict
From ac7d94803b2309e19b6c0b6c1c4572ce7a747349 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Wed, 9 Nov 2022 00:47:27 -0800
Subject: [PATCH 05/26] parsed_document -> html_node
---
src/idom/utils.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index 1c36561d9..193f620d5 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -78,7 +78,7 @@ def html_to_vdom(
# If the user provided a string, convert it to a list of lxml.etree nodes
try:
- parsed_document = document_fromstring(
+ html_node: etree._Element = document_fromstring(
html.strip(),
ensure_head_body=True,
parser=etree.HTMLParser(
@@ -88,8 +88,8 @@ def html_to_vdom(
recover=not strict,
),
)
- body_node: etree._Element = parsed_document.find("head")
- body_node.extend(parsed_document.find("body"))
+ body_node: etree._Element = html_node.find("head")
+ body_node.extend(html_node.find("body"))
except etree.XMLSyntaxError as e:
if not strict:
raise e # pragma: no cover
From 025a42dfeb24fc4df8aebbd95b1780b082626aab Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Wed, 9 Nov 2022 00:48:36 -0800
Subject: [PATCH 06/26] remove useless has_root_node variable
---
src/idom/utils.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index 193f620d5..ae72b15b4 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -100,10 +100,9 @@ def html_to_vdom(
"you can disable the strict parameter on html_to_vdom().\n"
"Otherwise, repair your broken HTML and try again."
) from e
- has_root_node = len(body_node) == 1
# Find or create a root node
- if has_root_node:
+ if len(body_node) == 1:
root_node = body_node[0]
# etree.Element requires a non-empty tag name. The tag name `TEMP` is deleted below.
@@ -116,7 +115,7 @@ def html_to_vdom(
vdom = _etree_to_vdom(root_node, transforms)
# Change the artificially `TEMP` root node to a React Fragment
- if not has_root_node:
+ if vdom["tagName"] == "TEMP":
vdom["tagName"] = ""
return vdom
From a4a076f30ef3016ce72f22b77930c80442b8a2ca Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Wed, 9 Nov 2022 01:08:40 -0800
Subject: [PATCH 07/26] fix comment
---
src/idom/utils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index ae72b15b4..cd94902ae 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -114,7 +114,7 @@ def html_to_vdom(
# Convert the lxml node to a VDOM dict
vdom = _etree_to_vdom(root_node, transforms)
- # Change the artificially `TEMP` root node to a React Fragment
+ # Change the `TEMP` root node to a React Fragment
if vdom["tagName"] == "TEMP":
vdom["tagName"] = ""
From a70ddfa8a5a63aa370c9688716e26c2928a3190f Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sat, 12 Nov 2022 17:17:21 -0800
Subject: [PATCH 08/26] del_html_body_transform
---
docs/source/_custom_js/package-lock.json | 2 +-
src/idom/utils.py | 64 ++++++++++++++----------
tests/test_utils.py | 23 +++++++--
3 files changed, 58 insertions(+), 31 deletions(-)
diff --git a/docs/source/_custom_js/package-lock.json b/docs/source/_custom_js/package-lock.json
index b648d4992..8632d1665 100644
--- a/docs/source/_custom_js/package-lock.json
+++ b/docs/source/_custom_js/package-lock.json
@@ -19,7 +19,7 @@
}
},
"../../../src/client/packages/idom-client-react": {
- "version": "0.40.2",
+ "version": "0.41.0",
"integrity": "sha512-pIK5eNwFSHKXg7ClpASWFVKyZDYxz59MSFpVaX/OqJFkrJaAxBuhKGXNTMXmuyWOL5Iyvb/ErwwDRxQRzMNkfQ==",
"license": "MIT",
"dependencies": {
diff --git a/src/idom/utils.py b/src/idom/utils.py
index cd94902ae..481bdbc80 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -2,7 +2,7 @@
from typing import Any, Callable, Generic, Iterable, List, TypeVar, Union
from lxml import etree
-from lxml.html import document_fromstring
+from lxml.html import fromstring
import idom
from idom.core.types import VdomDict
@@ -78,9 +78,8 @@ def html_to_vdom(
# If the user provided a string, convert it to a list of lxml.etree nodes
try:
- html_node: etree._Element = document_fromstring(
+ root_node: etree._Element = fromstring(
html.strip(),
- ensure_head_body=True,
parser=etree.HTMLParser(
remove_comments=True,
remove_pis=True,
@@ -88,8 +87,6 @@ def html_to_vdom(
recover=not strict,
),
)
- body_node: etree._Element = html_node.find("head")
- body_node.extend(html_node.find("body"))
except etree.XMLSyntaxError as e:
if not strict:
raise e # pragma: no cover
@@ -101,24 +98,7 @@ def html_to_vdom(
"Otherwise, repair your broken HTML and try again."
) from e
- # Find or create a root node
- if len(body_node) == 1:
- root_node = body_node[0]
-
- # etree.Element requires a non-empty tag name. The tag name `TEMP` is deleted below.
- else:
- root_node = etree.Element("TEMP", None, None)
- for child in body_node:
- root_node.append(child)
-
- # Convert the lxml node to a VDOM dict
- vdom = _etree_to_vdom(root_node, transforms)
-
- # Change the `TEMP` root node to a React Fragment
- if vdom["tagName"] == "TEMP":
- vdom["tagName"] = ""
-
- return vdom
+ return _etree_to_vdom(root_node, transforms)
def _etree_to_vdom(
@@ -146,11 +126,10 @@ def _etree_to_vdom(
attributes = dict(node.items())
key = attributes.pop("key", None)
- vdom: VdomDict
if hasattr(idom.html, node.tag):
- vdom = getattr(idom.html, node.tag)(attributes, *children, key=key)
+ vdom: VdomDict = getattr(idom.html, node.tag)(attributes, *children, key=key)
else:
- vdom = {"tagName": node.tag}
+ vdom: VdomDict = {"tagName": node.tag}
if children:
vdom["children"] = children
if attributes:
@@ -226,3 +205,36 @@ def _hypen_to_camel_case(string: str) -> str:
class HTMLParseError(etree.LxmlSyntaxError): # type: ignore[misc]
"""Raised when an HTML document cannot be parsed using strict parsing."""
+
+
+def del_html_body_transform(vdom: VdomDict):
+ """Transform intended for use with `html_to_vdom`.
+
+ Removes `` and `` while preserving `` children.
+ """
+ if vdom["tagName"] == "html":
+ vdom["tagName"] = ""
+
+ # Remove all fields from `` except for `children` and `tagName`
+ for key in list(vdom.keys()):
+ if key not in ("children", "tagName"):
+ del vdom[key]
+
+ # Preserve `` children and remove the `` tag
+ head_and_body_children = []
+ for child in vdom.get("children", []):
+ # Add `` children to the list
+ if child["tagName"] == "head":
+ head_and_body_children.extend(child.get("children", []))
+
+ # Add `` children to the list, then remove `` and ``
+ if child.get("tagName", None) == "body":
+ head_and_body_children.extend(child.get("children", []))
+ vdom["children"] = head_and_body_children
+ break
+
+ # Set vdom to the first child if there's only one child
+ if len(vdom.get("children", [])) == 1:
+ vdom = vdom["children"][0]
+
+ return vdom
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 4c822e5bf..9d1df4a8c 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -1,7 +1,7 @@
import pytest
import idom
-from idom.utils import HTMLParseError, html_to_vdom
+from idom.utils import HTMLParseError, html_to_vdom, del_html_body_transform
def test_basic_ref_behavior():
@@ -141,7 +141,7 @@ def test_html_to_vdom_with_no_parent_node():
source = "Hello
World
"
expected = {
- "tagName": "",
+ "tagName": "div",
"children": [
{"tagName": "p", "children": ["Hello"]},
{"tagName": "div", "children": ["World"]},
@@ -151,7 +151,7 @@ def test_html_to_vdom_with_no_parent_node():
assert html_to_vdom(source) == expected
-def test_html_to_vdom_with_html_body_head():
+def test_del_html_body_transform():
source = """
@@ -173,4 +173,19 @@ def test_html_to_vdom_with_html_body_head():
],
}
- assert html_to_vdom(source) == expected
+ assert html_to_vdom(source, del_html_body_transform) == expected
+
+
+def test_del_html_body_transform_no_head():
+ source = """
+
+
+
+ Hello World
+
+
+ """
+
+ expected = {"tagName": "h1", "children": ["Hello World"]}
+
+ assert html_to_vdom(source, del_html_body_transform) == expected
From bc890a458562f8bf1bc5ebaa001c42e8df66436b Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sat, 12 Nov 2022 18:22:06 -0800
Subject: [PATCH 09/26] fix type hint errors
---
src/idom/utils.py | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index 481bdbc80..6853c6c0c 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -126,10 +126,11 @@ def _etree_to_vdom(
attributes = dict(node.items())
key = attributes.pop("key", None)
+ vdom: VdomDict
if hasattr(idom.html, node.tag):
- vdom: VdomDict = getattr(idom.html, node.tag)(attributes, *children, key=key)
+ vdom = getattr(idom.html, node.tag)(attributes, *children, key=key)
else:
- vdom: VdomDict = {"tagName": node.tag}
+ vdom = {"tagName": node.tag}
if children:
vdom["children"] = children
if attributes:
@@ -203,11 +204,11 @@ def _hypen_to_camel_case(string: str) -> str:
return first.lower() + remainder.title().replace("-", "")
-class HTMLParseError(etree.LxmlSyntaxError): # type: ignore[misc]
+class HTMLParseError(etree.LxmlSyntaxError):
"""Raised when an HTML document cannot be parsed using strict parsing."""
-def del_html_body_transform(vdom: VdomDict):
+def del_html_body_transform(vdom: dict) -> dict:
"""Transform intended for use with `html_to_vdom`.
Removes `` and `` while preserving `` children.
From 763ef8e8ba166a668efe096266314e26879319c6 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sat, 12 Nov 2022 20:33:17 -0800
Subject: [PATCH 10/26] type hint fixes 2
---
src/idom/utils.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index 6853c6c0c..6fc664cf6 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -204,11 +204,11 @@ def _hypen_to_camel_case(string: str) -> str:
return first.lower() + remainder.title().replace("-", "")
-class HTMLParseError(etree.LxmlSyntaxError):
+class HTMLParseError(etree.LxmlSyntaxError): # type: ignore[misc]
"""Raised when an HTML document cannot be parsed using strict parsing."""
-def del_html_body_transform(vdom: dict) -> dict:
+def del_html_body_transform(vdom: dict[str, Any]) -> dict[str, Any]:
"""Transform intended for use with `html_to_vdom`.
Removes `` and `` while preserving `` children.
From 0e8cbf76c5596eb29e991c47bac1bd8861e452ea Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sat, 12 Nov 2022 22:01:06 -0800
Subject: [PATCH 11/26] remove unusable head and body tags
---
docs/source/about/changelog.rst | 12 +++++++++++-
src/idom/html.py | 4 ----
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/docs/source/about/changelog.rst b/docs/source/about/changelog.rst
index 594a4afa1..f945c2e0d 100644
--- a/docs/source/about/changelog.rst
+++ b/docs/source/about/changelog.rst
@@ -23,10 +23,20 @@ more info, see the :ref:`Contributor Guide `.
Unreleased
----------
+**Added**
+
+- :issue:`832` - ``del_html_body_transform`` to strip out ````, ````,
+and ```` tags if needed.
+
+
**Fixed**
-- :issue:`832` - Fix ``html_to_vdom`` improperly handling ```` children
+- :issue:`832` - Fix ``html_to_vdom`` improperly ````, ````, and ````.
+
+**Removed**
+- :issue:`832` - Removed ``idom.html.body`` and ``idom.html.head``, as they are
+technologically unusable and thus not needed.
v0.41.0
-------
diff --git a/src/idom/html.py b/src/idom/html.py
index 45db97463..0451d9f3c 100644
--- a/src/idom/html.py
+++ b/src/idom/html.py
@@ -6,7 +6,6 @@
**Dcument metadata**
- :func:`base`
-- :func:`head`
- :func:`link`
- :func:`meta`
- :func:`style`
@@ -14,7 +13,6 @@
**Content sectioning**
-- :func:`body`
- :func:`address`
- :func:`article`
- :func:`aside`
@@ -182,14 +180,12 @@ def _(*children: Any, key: Key | None = None) -> VdomDict:
# Dcument metadata
base = make_vdom_constructor("base")
-head = make_vdom_constructor("head")
link = make_vdom_constructor("link")
meta = make_vdom_constructor("meta")
style = make_vdom_constructor("style")
title = make_vdom_constructor("title")
# Content sectioning
-body = make_vdom_constructor("body")
address = make_vdom_constructor("address")
article = make_vdom_constructor("article")
aside = make_vdom_constructor("aside")
From 45b3c2e3ca273962a5f8a8945820068e00febcd4 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sun, 13 Nov 2022 02:01:43 -0800
Subject: [PATCH 12/26] uno mas
---
docs/source/about/changelog.rst | 5 +++--
tests/test_utils.py | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/docs/source/about/changelog.rst b/docs/source/about/changelog.rst
index f945c2e0d..5ce1bb46a 100644
--- a/docs/source/about/changelog.rst
+++ b/docs/source/about/changelog.rst
@@ -35,8 +35,9 @@ and ```` tags if needed.
**Removed**
-- :issue:`832` - Removed ``idom.html.body`` and ``idom.html.head``, as they are
-technologically unusable and thus not needed.
+- :issue:`832` - Removed ``idom.html.body`` and ``idom.html.head`` as they are
+currently unusable due to technological limitations, and thus not needed.
+
v0.41.0
-------
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 9d1df4a8c..8f51322ff 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -1,7 +1,7 @@
import pytest
import idom
-from idom.utils import HTMLParseError, html_to_vdom, del_html_body_transform
+from idom.utils import HTMLParseError, del_html_body_transform, html_to_vdom
def test_basic_ref_behavior():
From 9e740e850e69c3eec49421ef981f3b015d1bb7df Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sun, 13 Nov 2022 02:08:05 -0800
Subject: [PATCH 13/26] import future annotations
---
src/idom/utils.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index 6fc664cf6..a3f99720c 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
from itertools import chain
from typing import Any, Callable, Generic, Iterable, List, TypeVar, Union
From 24a788d3c1f51ee3aa26f693f14630981e9dfd9a Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sun, 13 Nov 2022 02:14:21 -0800
Subject: [PATCH 14/26] fix docs warnings
---
docs/source/about/changelog.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/source/about/changelog.rst b/docs/source/about/changelog.rst
index 5ce1bb46a..99b0d3e0d 100644
--- a/docs/source/about/changelog.rst
+++ b/docs/source/about/changelog.rst
@@ -26,7 +26,7 @@ Unreleased
**Added**
- :issue:`832` - ``del_html_body_transform`` to strip out ````, ````,
-and ```` tags if needed.
+ and ```` tags if needed.
**Fixed**
@@ -36,7 +36,7 @@ and ```` tags if needed.
**Removed**
- :issue:`832` - Removed ``idom.html.body`` and ``idom.html.head`` as they are
-currently unusable due to technological limitations, and thus not needed.
+ currently unusable due to technological limitations, and thus not needed.
v0.41.0
From ab3cb04fab8688ca48194a6936ae6c179b69e1df Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sun, 13 Nov 2022 02:45:46 -0800
Subject: [PATCH 15/26] clean up last warning
---
docs/source/about/changelog.rst | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/docs/source/about/changelog.rst b/docs/source/about/changelog.rst
index 99b0d3e0d..f5aff6bf7 100644
--- a/docs/source/about/changelog.rst
+++ b/docs/source/about/changelog.rst
@@ -25,18 +25,14 @@ Unreleased
**Added**
-- :issue:`832` - ``del_html_body_transform`` to strip out ````, ````,
- and ```` tags if needed.
-
+- :issue:`832` - ``del_html_body_transform`` to strip out ````, ````, and ```` tags if needed.
**Fixed**
- :issue:`832` - Fix ``html_to_vdom`` improperly ````, ````, and ````.
-
**Removed**
-- :issue:`832` - Removed ``idom.html.body`` and ``idom.html.head`` as they are
- currently unusable due to technological limitations, and thus not needed.
+- :issue:`832` - Removed ``idom.html.body`` and ``idom.html.head`` as they are currently unusable due to technological limitations, and thus not needed.
v0.41.0
From ce2c9724a7a33b21ffab5c8b61296f92d359c7ad Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sun, 13 Nov 2022 03:46:28 -0800
Subject: [PATCH 16/26] fix docstrings
---
src/idom/utils.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index a3f99720c..71739db3d 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -65,7 +65,7 @@ def html_to_vdom(
using a ``key=...`` attribute within your HTML tag.
Parameters:
- source:
+ html:
The raw HTML as a string
transforms:
Functions of the form ``transform(old) -> new`` where ``old`` is a VDOM
@@ -109,7 +109,7 @@ def _etree_to_vdom(
"""Transform an lxml etree node into a DOM model
Parameters:
- source:
+ node:
The ``lxml.etree._Element`` node
transforms:
Functions of the form ``transform(old) -> new`` where ``old`` is a VDOM
From e5aba039ea6242f0ea7ebb880e732d98fe838e27 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sun, 13 Nov 2022 04:06:14 -0800
Subject: [PATCH 17/26] del_html_body_transform docstrings
---
src/idom/utils.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index 71739db3d..f17771c12 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -214,6 +214,10 @@ def del_html_body_transform(vdom: dict[str, Any]) -> dict[str, Any]:
"""Transform intended for use with `html_to_vdom`.
Removes `` and `` while preserving `` children.
+
+ Parameters:
+ vdom:
+ The VDOM dictionary to transform.
"""
if vdom["tagName"] == "html":
vdom["tagName"] = ""
From a348a98b1481e3a5b78607724091df45fccdbe16 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sun, 13 Nov 2022 20:32:47 -0800
Subject: [PATCH 18/26] re-add head API
---
docs/source/about/changelog.rst | 2 +-
src/idom/html.py | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/docs/source/about/changelog.rst b/docs/source/about/changelog.rst
index f5aff6bf7..9dbe17fb9 100644
--- a/docs/source/about/changelog.rst
+++ b/docs/source/about/changelog.rst
@@ -32,7 +32,7 @@ Unreleased
- :issue:`832` - Fix ``html_to_vdom`` improperly ````, ````, and ````.
**Removed**
-- :issue:`832` - Removed ``idom.html.body`` and ``idom.html.head`` as they are currently unusable due to technological limitations, and thus not needed.
+- :issue:`832` - Removed ``idom.html.body`` as it is currently unusable due to technological limitations, and thus not needed.
v0.41.0
diff --git a/src/idom/html.py b/src/idom/html.py
index 0451d9f3c..7421e2f2a 100644
--- a/src/idom/html.py
+++ b/src/idom/html.py
@@ -6,6 +6,7 @@
**Dcument metadata**
- :func:`base`
+- :func:`head`
- :func:`link`
- :func:`meta`
- :func:`style`
@@ -180,6 +181,7 @@ def _(*children: Any, key: Key | None = None) -> VdomDict:
# Dcument metadata
base = make_vdom_constructor("base")
+head = make_vdom_constructor("head")
link = make_vdom_constructor("link")
meta = make_vdom_constructor("meta")
style = make_vdom_constructor("style")
From a0407d0b2ce13c1831de1ccc1145eee678af5e9b Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Mon, 14 Nov 2022 12:39:31 -0800
Subject: [PATCH 19/26] fix changelog PR links
---
docs/source/about/changelog.rst | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/source/about/changelog.rst b/docs/source/about/changelog.rst
index 9dbe17fb9..a65f8bf8d 100644
--- a/docs/source/about/changelog.rst
+++ b/docs/source/about/changelog.rst
@@ -25,14 +25,14 @@ Unreleased
**Added**
-- :issue:`832` - ``del_html_body_transform`` to strip out ````, ````, and ```` tags if needed.
+- :pull:`832` - ``del_html_body_transform`` to strip out ````, ````, and ```` tags if needed.
**Fixed**
-- :issue:`832` - Fix ``html_to_vdom`` improperly ````, ````, and ````.
+- :pull:`832` - Fix ``html_to_vdom`` improperly handling ````, ````, and ````.
**Removed**
-- :issue:`832` - Removed ``idom.html.body`` as it is currently unusable due to technological limitations, and thus not needed.
+- :pull:`832` - Removed ``idom.html.body`` as it is currently unusable due to technological limitations, and thus not needed.
v0.41.0
From 16285ff8e933b277f9f00e501eb97412f464b311 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Mon, 14 Nov 2022 15:53:10 -0800
Subject: [PATCH 20/26] docstring cleanup
---
docs/source/about/changelog.rst | 4 ++--
src/idom/utils.py | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/source/about/changelog.rst b/docs/source/about/changelog.rst
index a65f8bf8d..c5ac453a8 100644
--- a/docs/source/about/changelog.rst
+++ b/docs/source/about/changelog.rst
@@ -25,11 +25,11 @@ Unreleased
**Added**
-- :pull:`832` - ``del_html_body_transform`` to strip out ````, ````, and ```` tags if needed.
+- :pull:`832` - ``del_html_body_transform`` to remove ````, ````, and ```` while preserving ```` and ```` children.
**Fixed**
-- :pull:`832` - Fix ``html_to_vdom`` improperly handling ````, ````, and ````.
+- :pull:`832` - Fix ``html_to_vdom`` improperly handling ````, ````, and ````.
**Removed**
- :pull:`832` - Removed ``idom.html.body`` as it is currently unusable due to technological limitations, and thus not needed.
diff --git a/src/idom/utils.py b/src/idom/utils.py
index f17771c12..453f55099 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -213,7 +213,7 @@ class HTMLParseError(etree.LxmlSyntaxError): # type: ignore[misc]
def del_html_body_transform(vdom: dict[str, Any]) -> dict[str, Any]:
"""Transform intended for use with `html_to_vdom`.
- Removes `` and `` while preserving `` children.
+ Removes ``, ``, and `` while preserving `` and `` children.
Parameters:
vdom:
From d78afdb99eb6e6a71df31515c0e50c7e7224537a Mon Sep 17 00:00:00 2001
From: Ryan Morshead
Date: Sat, 19 Nov 2022 15:34:08 -0800
Subject: [PATCH 21/26] Better type hint
---
src/idom/utils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index 453f55099..bf3e0ac44 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -210,7 +210,7 @@ class HTMLParseError(etree.LxmlSyntaxError): # type: ignore[misc]
"""Raised when an HTML document cannot be parsed using strict parsing."""
-def del_html_body_transform(vdom: dict[str, Any]) -> dict[str, Any]:
+def del_html_body_transform(vdom: VdomDict) -> VdomDict:
"""Transform intended for use with `html_to_vdom`.
Removes ``, ``, and `` while preserving `` and `` children.
From 18e781b57a921cf4ce8307f65866383fea7eca5b Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Wed, 23 Nov 2022 00:52:00 -0800
Subject: [PATCH 22/26] Revert "Better type hint"
This reverts commit d78afdb99eb6e6a71df31515c0e50c7e7224537a.
---
src/idom/utils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index bf3e0ac44..453f55099 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -210,7 +210,7 @@ class HTMLParseError(etree.LxmlSyntaxError): # type: ignore[misc]
"""Raised when an HTML document cannot be parsed using strict parsing."""
-def del_html_body_transform(vdom: VdomDict) -> VdomDict:
+def del_html_body_transform(vdom: dict[str, Any]) -> dict[str, Any]:
"""Transform intended for use with `html_to_vdom`.
Removes ``, ``, and `` while preserving `` and `` children.
From 2a9d2e220e925ba322b7a16e424ba6853ef9b4ac Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Tue, 29 Nov 2022 22:12:39 -0800
Subject: [PATCH 23/26] more concise transform implementation
---
docs/source/about/changelog.rst | 4 ++--
src/idom/utils.py | 31 ++++---------------------------
tests/test_utils.py | 29 ++++++++++-------------------
3 files changed, 16 insertions(+), 48 deletions(-)
diff --git a/docs/source/about/changelog.rst b/docs/source/about/changelog.rst
index 40d9df5eb..fcd192b16 100644
--- a/docs/source/about/changelog.rst
+++ b/docs/source/about/changelog.rst
@@ -25,11 +25,11 @@ Unreleased
**Added**
-- :pull:`832` - ``del_html_body_transform`` to remove ````, ````, and ```` while preserving ```` and ```` children.
+- :pull:`832` - ``del_html_head_body_transform`` to remove ````, ````, and ```` while preserving children.
**Fixed**
-- :pull:`832` - Fix ``html_to_vdom`` improperly handling ````, ````, and ````.
+- :pull:`832` - Fix ``html_to_vdom`` improperly removing ````, ````, and ```` nodes.
**Removed**
- :pull:`832` - Removed ``idom.html.body`` as it is currently unusable due to technological limitations, and thus not needed.
diff --git a/src/idom/utils.py b/src/idom/utils.py
index 453f55099..b72bf6756 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -210,38 +210,15 @@ class HTMLParseError(etree.LxmlSyntaxError): # type: ignore[misc]
"""Raised when an HTML document cannot be parsed using strict parsing."""
-def del_html_body_transform(vdom: dict[str, Any]) -> dict[str, Any]:
+def del_html_head_body_transform(vdom: dict[str, Any]) -> dict[str, Any]:
"""Transform intended for use with `html_to_vdom`.
- Removes ``, ``, and `` while preserving `` and `` children.
+ Removes ``, ``, and `` while preserving their children.
Parameters:
vdom:
The VDOM dictionary to transform.
"""
- if vdom["tagName"] == "html":
- vdom["tagName"] = ""
-
- # Remove all fields from `` except for `children` and `tagName`
- for key in list(vdom.keys()):
- if key not in ("children", "tagName"):
- del vdom[key]
-
- # Preserve `` children and remove the `` tag
- head_and_body_children = []
- for child in vdom.get("children", []):
- # Add `` children to the list
- if child["tagName"] == "head":
- head_and_body_children.extend(child.get("children", []))
-
- # Add `` children to the list, then remove `` and ``
- if child.get("tagName", None) == "body":
- head_and_body_children.extend(child.get("children", []))
- vdom["children"] = head_and_body_children
- break
-
- # Set vdom to the first child if there's only one child
- if len(vdom.get("children", [])) == 1:
- vdom = vdom["children"][0]
-
+ if vdom["tagName"] in {"html", "body", "head"}:
+ return {"tagName": "", "children": vdom["children"]}
return vdom
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 8f51322ff..875137c04 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -1,7 +1,7 @@
import pytest
import idom
-from idom.utils import HTMLParseError, del_html_body_transform, html_to_vdom
+from idom.utils import HTMLParseError, del_html_head_body_transform, html_to_vdom
def test_basic_ref_behavior():
@@ -168,24 +168,15 @@ def test_del_html_body_transform():
expected = {
"tagName": "",
"children": [
- {"tagName": "title", "children": ["My Title"]},
- {"tagName": "h1", "children": ["Hello World"]},
+ {
+ "tagName": "",
+ "children": [{"tagName": "title", "children": ["My Title"]}],
+ },
+ {
+ "tagName": "",
+ "children": [{"tagName": "h1", "children": ["Hello World"]}],
+ },
],
}
- assert html_to_vdom(source, del_html_body_transform) == expected
-
-
-def test_del_html_body_transform_no_head():
- source = """
-
-
-
- Hello World
-
-
- """
-
- expected = {"tagName": "h1", "children": ["Hello World"]}
-
- assert html_to_vdom(source, del_html_body_transform) == expected
+ assert html_to_vdom(source, del_html_head_body_transform) == expected
From dcec0269cda31250e852f02a48db637e0a2052a1 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Tue, 29 Nov 2022 22:22:15 -0800
Subject: [PATCH 24/26] fix merge error
---
src/idom/utils.py | 4 ----
1 file changed, 4 deletions(-)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index 4878d0da9..e5a521557 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -272,10 +272,6 @@ def _hypen_to_camel_case(string: str) -> str:
return first.lower() + remainder.title().replace("-", "")
-class HTMLParseError(etree.LxmlSyntaxError): # type: ignore[misc]
- """Raised when an HTML document cannot be parsed using strict parsing."""
-
-
def del_html_head_body_transform(vdom: dict[str, Any]) -> dict[str, Any]:
"""Transform intended for use with `html_to_vdom`.
From bdd5f16f2990e0321730a7e78fd5ffff4f6e855b Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Tue, 29 Nov 2022 22:32:34 -0800
Subject: [PATCH 25/26] merge changelog better
---
docs/source/about/changelog.rst | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/docs/source/about/changelog.rst b/docs/source/about/changelog.rst
index 63ddb2066..3710f3c7e 100644
--- a/docs/source/about/changelog.rst
+++ b/docs/source/about/changelog.rst
@@ -25,10 +25,14 @@ Unreleased
**Added**
+- :pull:`835` - ability to customize the ```` element of IDOM's built-in client.
+- :pull:`835` - ``vdom_to_html`` utility function.
+- :pull:`843` - Ability to subscribe to changes that are made to mutable options.
- :pull:`832` - ``del_html_head_body_transform`` to remove ````, ````, and ```` while preserving children.
**Fixed**
+- :issue:`582` - ``IDOM_DEBUG_MODE`` is now mutable and can be changed at runtime
- :pull:`832` - Fix ``html_to_vdom`` improperly removing ````, ````, and ```` nodes.
**Removed**
@@ -36,16 +40,6 @@ Unreleased
- :pull:`840` - remove ``IDOM_FEATURE_INDEX_AS_DEFAULT_KEY`` option
- :pull:`835` - ``serve_static_files`` option from backend configuration
-**Added**
-
-- :pull:`835` - ability to customize the ```` element of IDOM's built-in client.
-- :pull:`835` - ``vdom_to_html`` utility function.
-- :pull:`843` - Ability to subscribe to changes that are made to mutable options.
-
-**Fixed**
-
-- :issue:`582` - ``IDOM_DEBUG_MODE`` is now mutable and can be changed at runtime
-
v0.41.0
-------
From e4267a52025fb0e6978b65f119aa5a54f58dc64a Mon Sep 17 00:00:00 2001
From: Ryan Morshead
Date: Thu, 1 Dec 2022 10:58:01 -0800
Subject: [PATCH 26/26] annotate as VdomDict
---
src/idom/utils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/idom/utils.py b/src/idom/utils.py
index e5a521557..1deab122d 100644
--- a/src/idom/utils.py
+++ b/src/idom/utils.py
@@ -272,7 +272,7 @@ def _hypen_to_camel_case(string: str) -> str:
return first.lower() + remainder.title().replace("-", "")
-def del_html_head_body_transform(vdom: dict[str, Any]) -> dict[str, Any]:
+def del_html_head_body_transform(vdom: VdomDict) -> VdomDict:
"""Transform intended for use with `html_to_vdom`.
Removes ``, ``, and `` while preserving their children.