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.