docs, gurt:// <a> url

This commit is contained in:
Face
2025-08-15 13:52:01 +03:00
parent c117e602fe
commit 5dae5a4868
25 changed files with 1640 additions and 390 deletions

View File

@@ -377,7 +377,7 @@ func apply_element_styles(node: Control, element: HTMLElement, parser: HTMLParse
var text = HTMLParser.get_bbcode_with_styles(element, styles, parser)
label.text = text
static func apply_element_bbcode_formatting(element: HTMLElement, styles: Dictionary, content: String) -> String:
static func apply_element_bbcode_formatting(element: HTMLElement, styles: Dictionary, content: String, parser: HTMLParser = null) -> String:
match element.tag_name:
"b":
if styles.has("font-bold") and styles["font-bold"]:
@@ -416,6 +416,7 @@ static func apply_element_bbcode_formatting(element: HTMLElement, styles: Dictio
else:
color = str(c)
if href.length() > 0:
# Pass raw href - URL resolution happens in handle_link_click
return "[color=%s][url=%s]%s[/url][/color]" % [color, href, content]
return content
@@ -429,10 +430,10 @@ static func get_bbcode_with_styles(element: HTMLElement, styles: Dictionary, par
if parser != null:
child_styles = parser.get_element_styles_with_inheritance(child, "", [])
var child_content = HTMLParser.get_bbcode_with_styles(child, child_styles, parser)
child_content = apply_element_bbcode_formatting(child, child_styles, child_content)
child_content = apply_element_bbcode_formatting(child, child_styles, child_content, parser)
text += child_content
# Apply formatting to the current element itself
text = apply_element_bbcode_formatting(element, styles, text)
text = apply_element_bbcode_formatting(element, styles, text, parser)
return text

View File

@@ -218,10 +218,10 @@ static func get_error_type(error_message: String) -> Dictionary:
else:
return {"code": "ERR_UNKNOWN", "title": "Something went wrong", "icon": ""}
static func create_error_page(error_message: String) -> String:
static func create_error_page(error_message: String) -> PackedByteArray:
var error_info = get_error_type(error_message)
return """<head>
return ("""<head>
<title>""" + error_info.title + """ - GURT</title>
<meta name="theme-color" content="#f8f9fa">
<style>
@@ -269,4 +269,4 @@ static func create_error_page(error_message: String) -> String:
<button style="retry-button" id="reload">Reload</button>
</div>
</body>"""
</body>""").to_utf8_buffer()

View File

@@ -70,6 +70,54 @@ func recalculate_percentage_elements(node: Node):
var current_domain = "" # Store current domain for display
func resolve_url(href: String) -> String:
if href.begins_with("http://") or href.begins_with("https://") or href.begins_with("gurt://"):
return href
if current_domain.is_empty():
return href
var clean_domain = current_domain.rstrip("/")
var current_parts = clean_domain.split("/")
var host = current_parts[0]
var current_path_parts = Array(current_parts.slice(1)) if current_parts.size() > 1 else []
var final_path_parts = []
if href.begins_with("/"):
var href_path = href.substr(1) if href.length() > 1 else ""
if not href_path.is_empty():
final_path_parts = href_path.split("/")
else:
final_path_parts = current_path_parts.duplicate()
var href_parts = href.split("/")
for part in href_parts:
if part == "..":
if final_path_parts.size() > 0:
final_path_parts.pop_back()
elif part == "." or part == "":
continue
else:
final_path_parts.append(part)
var result = "gurt://" + host
if final_path_parts.size() > 0:
result += "/" + "/".join(final_path_parts)
return result
func handle_link_click(meta: Variant) -> void:
var href = str(meta)
var resolved_url = resolve_url(href)
if GurtProtocol.is_gurt_domain(resolved_url):
_on_search_submitted(resolved_url)
else:
OS.shell_open(resolved_url)
func _on_search_submitted(url: String) -> void:
print("Search submitted: ", url)
@@ -88,12 +136,13 @@ func _on_search_submitted(url: String) -> void:
tab.set_icon(GLOBE_ICON)
var html_bytes = result.html
render_content(html_bytes)
if result.has("display_url"):
current_domain = result.display_url
if not search_bar.has_focus():
search_bar.text = current_domain
render_content(html_bytes)
else:
print("Non-GURT URL entered: ", url)
@@ -178,7 +227,7 @@ func render_content(html_bytes: PackedByteArray) -> void:
safe_add_child(hbox, inline_node)
# Handle hyperlinks for all inline elements
if contains_hyperlink(inline_element) and inline_node is RichTextLabel:
inline_node.meta_clicked.connect(func(meta): OS.shell_open(str(meta)))
inline_node.meta_clicked.connect(handle_link_click)
else:
print("Failed to create inline element node: ", inline_element.tag_name)
@@ -198,9 +247,9 @@ func render_content(html_bytes: PackedByteArray) -> void:
if contains_hyperlink(element):
if element_node is RichTextLabel:
element_node.meta_clicked.connect(func(meta): OS.shell_open(str(meta)))
element_node.meta_clicked.connect(handle_link_click)
elif element_node.has_method("get") and element_node.get("rich_text_label"):
element_node.rich_text_label.meta_clicked.connect(func(meta): OS.shell_open(str(meta)))
element_node.rich_text_label.meta_clicked.connect(handle_link_click)
else:
print("Couldn't parse unsupported HTML tag \"%s\"" % element.tag_name)
@@ -328,6 +377,12 @@ func create_element_node(element: HTMLParser.HTMLElement, parser: HTMLParser) ->
if child_element.tag_name not in ["input", "textarea", "select", "button", "audio"]:
parser.register_dom_node(child_element, child_node)
safe_add_child(container_for_children, child_node)
if contains_hyperlink(child_element):
if child_node is RichTextLabel:
child_node.meta_clicked.connect(handle_link_click)
elif child_node.has_method("get") and child_node.get("rich_text_label"):
child_node.rich_text_label.meta_clicked.connect(handle_link_click)
return final_node