Skip to content

Commit 972c275

Browse files
committed
Revert to dumb script for links
1 parent afa8c83 commit 972c275

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

src/js/src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ export function History({ onHistoryChange }) {
4444
return null;
4545
}
4646

47+
// FIXME: The Link component is unused due to a ReactPy core rendering bug
48+
// which causes duplicate rendering (and thus duplicate event listeners).
49+
// https://github.com/reactive-python/reactpy/pull/1224
4750
export function Link({ onClick, linkClass }) {
4851
// This component is not the actual anchor link.
4952
// It is an event listener for the link component created by ReactPy.

src/reactpy_router/components.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
from pathlib import Path
44
from typing import Any
5+
from urllib.parse import urljoin
56
from uuid import uuid4
67

7-
from reactpy import component, html
8+
from reactpy import component, event, html, use_connection
89
from reactpy.backend.types import Location
910
from reactpy.core.component import Component
1011
from reactpy.core.types import VdomDict
@@ -25,6 +26,8 @@
2526
)
2627
"""Client-side portion of link handling"""
2728

29+
link_js_content = (Path(__file__).parent / "static" / "link.js").read_text(encoding="utf-8")
30+
2831

2932
def link(attributes: dict[str, Any], *children: Any) -> Component:
3033
"""Create a link with the given attributes and children."""
@@ -55,10 +58,42 @@ def _link(attributes: dict[str, Any], *children: Any) -> VdomDict:
5558
"className": class_name,
5659
}
5760

61+
# FIXME: This component currently works in a "dumb" way by trusting that ReactPy's script tag \
62+
# properly sets the location due to bugs in ReactPy rendering.
63+
# https://github.com/reactive-python/reactpy/pull/1224
64+
current_path = use_connection().location.pathname
65+
66+
@event(prevent_default=True)
5867
def on_click(_event: dict[str, Any]) -> None:
59-
set_location(Location(**_event))
68+
pathname, search = to.split("?", 1) if "?" in to else (to, "")
69+
if search:
70+
search = f"?{search}"
71+
72+
# Resolve relative paths that match `../foo`
73+
if pathname.startswith("../"):
74+
pathname = urljoin(current_path, pathname)
75+
76+
# Resolve relative paths that match `foo`
77+
if not pathname.startswith("/"):
78+
pathname = urljoin(current_path, pathname)
79+
80+
# Resolve relative paths that match `/foo/../bar`
81+
while "/../" in pathname:
82+
part_1, part_2 = pathname.split("/../", 1)
83+
pathname = urljoin(f"{part_1}/", f"../{part_2}")
84+
85+
# Resolve relative paths that match `foo/./bar`
86+
pathname = pathname.replace("/./", "/")
87+
88+
set_location(Location(pathname, search))
89+
90+
attrs["onClick"] = on_click
91+
92+
return html._(html.a(attrs, *children), html.script(link_js_content.replace("UUID", uuid_string)))
6093

61-
return html._(html.a(attrs, *children), Link({"onClick": on_click, "linkClass": uuid_string}))
94+
# def on_click(_event: dict[str, Any]) -> None:
95+
# set_location(Location(**_event))
96+
# return html._(html.a(attrs, *children), Link({"onClick": on_click, "linkClass": uuid_string}))
6297

6398

6499
def route(path: str, element: Any | None, *routes: Route) -> Route:

src/reactpy_router/static/link.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
document.querySelector(".UUID").addEventListener(
2+
"click",
3+
(event) => {
4+
let to = event.target.getAttribute("href");
5+
window.history.pushState({}, to, new URL(to, window.location));
6+
},
7+
{ once: true },
8+
);

0 commit comments

Comments
 (0)