diff --git a/CHANGELOG.md b/CHANGELOG.md index 38a6cb0c2b..59068e1d46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Fixed issue with alignment in auto containers https://github.com/Textualize/textual/pull/5360 +- Fixed issue with markdown viewer link click crash https://github.com/Textualize/textual/pull/5223 ## [0.89.1] - 2024-12-05 diff --git a/src/textual/widgets/_markdown.py b/src/textual/widgets/_markdown.py index 839046014f..32a68ce70c 100644 --- a/src/textual/widgets/_markdown.py +++ b/src/textual/widgets/_markdown.py @@ -5,7 +5,7 @@ from functools import partial from pathlib import Path, PurePath from typing import Callable, Iterable, Optional -from urllib.parse import unquote +from urllib.parse import unquote, urlparse from markdown_it import MarkdownIt from markdown_it.token import Token @@ -820,6 +820,23 @@ def _watch_code_light_theme(self) -> None: for block in self.query(MarkdownFence): block._retheme() + @staticmethod + def is_external_link(link: str) -> bool: + """Given a markdown href [text](link), determine if the link references a local disk resource. + + Args: + link: The link to evaluate. + + Returns: + A bool value True if the link points to external resource, i.e. not local file or anchor + """ + parsed_url = urlparse(link) + if parsed_url.scheme == "file": + return False + if parsed_url.scheme: + return True + return False + @staticmethod def sanitize_location(location: str) -> tuple[Path, str]: """Given a location, break out the path and any anchor. @@ -1224,7 +1241,8 @@ async def forward(self) -> None: async def _on_markdown_link_clicked(self, message: Markdown.LinkClicked) -> None: message.stop() - await self.go(message.href) + if not self.document.is_external_link(message.href): + await self.go(message.href) def watch_show_table_of_contents(self, show_table_of_contents: bool) -> None: self.set_class(show_table_of_contents, "-show-table-of-contents")