<ul>, <ol>, <li>
This commit is contained in:
6
Scripts/Tags/li.gd
Normal file
6
Scripts/Tags/li.gd
Normal file
@@ -0,0 +1,6 @@
|
||||
extends Control
|
||||
|
||||
func init(element: HTMLParser.HTMLElement) -> void:
|
||||
# This is mainly for cases where <li> appears outside of <ul>/<ol>
|
||||
var label: RichTextLabel = $RichTextLabel
|
||||
label.text = "[font_size=24]%s[/font_size]" % element.get_bbcode_formatted_text()
|
||||
1
Scripts/Tags/li.gd.uid
Normal file
1
Scripts/Tags/li.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://ps8duq0aw3tu
|
||||
101
Scripts/Tags/ol.gd
Normal file
101
Scripts/Tags/ol.gd
Normal file
@@ -0,0 +1,101 @@
|
||||
extends VBoxContainer
|
||||
|
||||
const BROWSER_TEXT = preload("res://Scenes/Styles/BrowserText.tres")
|
||||
|
||||
func init(element: HTMLParser.HTMLElement) -> void:
|
||||
var list_type = element.get_attribute("type").to_lower()
|
||||
if list_type == "": list_type = "decimal" # Default
|
||||
|
||||
var item_count = 0
|
||||
for child_element in element.children:
|
||||
if child_element.tag_name == "li":
|
||||
item_count += 1
|
||||
|
||||
var marker_min_width = await calculate_marker_width(list_type, item_count)
|
||||
|
||||
var index = 1
|
||||
for child_element in element.children:
|
||||
if child_element.tag_name == "li":
|
||||
var li_node = create_li_node(child_element, list_type, index, marker_min_width)
|
||||
if li_node:
|
||||
add_child(li_node)
|
||||
index += 1
|
||||
|
||||
func calculate_marker_width(list_type: String, max_index: int) -> float:
|
||||
var temp_label = RichTextLabel.new()
|
||||
temp_label.bbcode_enabled = true
|
||||
temp_label.fit_content = true
|
||||
temp_label.scroll_active = false
|
||||
temp_label.theme = BROWSER_TEXT
|
||||
add_child(temp_label)
|
||||
|
||||
var marker_text = get_marker_for_type(list_type, max_index)
|
||||
temp_label.text = "[font_size=24]%s[/font_size]" % marker_text
|
||||
|
||||
await get_tree().process_frame
|
||||
|
||||
var width = temp_label.get_content_width() + 5
|
||||
|
||||
remove_child(temp_label)
|
||||
temp_label.queue_free()
|
||||
|
||||
return max(width, 30) # Minimum pixels
|
||||
|
||||
func create_li_node(element: HTMLParser.HTMLElement, list_type: String, index: int, marker_width: float = 30) -> Control:
|
||||
var li_container = HBoxContainer.new()
|
||||
|
||||
# Create number/letter marker
|
||||
var marker_label = RichTextLabel.new()
|
||||
marker_label.custom_minimum_size = Vector2(marker_width, 0)
|
||||
marker_label.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
||||
marker_label.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
marker_label.bbcode_enabled = true
|
||||
marker_label.fit_content = true
|
||||
marker_label.scroll_active = false
|
||||
marker_label.theme = BROWSER_TEXT
|
||||
|
||||
var marker_text = get_marker_for_type(list_type, index)
|
||||
marker_label.text = "[font_size=24]%s[/font_size]" % marker_text
|
||||
|
||||
# Create content
|
||||
var content_label = RichTextLabel.new()
|
||||
content_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
content_label.bbcode_enabled = true
|
||||
content_label.fit_content = true
|
||||
content_label.scroll_active = false
|
||||
content_label.theme = BROWSER_TEXT
|
||||
|
||||
content_label.text = "[font_size=24]%s[/font_size]" % element.get_bbcode_formatted_text()
|
||||
|
||||
li_container.add_theme_constant_override("separation", 0)
|
||||
li_container.add_child(marker_label)
|
||||
li_container.add_child(content_label)
|
||||
|
||||
return li_container
|
||||
|
||||
func get_marker_for_type(list_type: String, index: int) -> String:
|
||||
match list_type:
|
||||
"decimal":
|
||||
return str(index) + "."
|
||||
"zero-lead":
|
||||
return "%02d." % index
|
||||
"lower-alpha", "lower-roman":
|
||||
return char(96 + index) + "." if list_type == "lower-alpha" else int_to_roman(index).to_lower() + "."
|
||||
"upper-alpha", "upper-roman":
|
||||
return char(64 + index) + "." if list_type == "upper-alpha" else int_to_roman(index) + "."
|
||||
"none":
|
||||
return ""
|
||||
_:
|
||||
return str(index) + "." # Default to decimal
|
||||
|
||||
func int_to_roman(num: int) -> String:
|
||||
var values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
|
||||
var symbols = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"]
|
||||
var result = ""
|
||||
|
||||
for i in range(values.size()):
|
||||
while num >= values[i]:
|
||||
result += symbols[i]
|
||||
num -= values[i]
|
||||
|
||||
return result
|
||||
1
Scripts/Tags/ol.gd.uid
Normal file
1
Scripts/Tags/ol.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bbkebg4aihve3
|
||||
81
Scripts/Tags/ul.gd
Normal file
81
Scripts/Tags/ul.gd
Normal file
@@ -0,0 +1,81 @@
|
||||
extends VBoxContainer
|
||||
|
||||
const BROWSER_TEXT = preload("res://Scenes/Styles/BrowserText.tres")
|
||||
|
||||
func init(element: HTMLParser.HTMLElement) -> void:
|
||||
var list_type = element.get_attribute("type").to_lower()
|
||||
if list_type == "": list_type = "disc" # Default
|
||||
|
||||
var marker_min_width = await calculate_marker_width(list_type)
|
||||
|
||||
for child_element in element.children:
|
||||
if child_element.tag_name == "li":
|
||||
var li_node = create_li_node(child_element, list_type, marker_min_width)
|
||||
if li_node:
|
||||
add_child(li_node)
|
||||
|
||||
func calculate_marker_width(list_type: String) -> float:
|
||||
var temp_label = RichTextLabel.new()
|
||||
temp_label.bbcode_enabled = true
|
||||
temp_label.fit_content = true
|
||||
temp_label.scroll_active = false
|
||||
temp_label.theme = BROWSER_TEXT
|
||||
add_child(temp_label)
|
||||
|
||||
var bullet_text = get_bullet_for_type(list_type)
|
||||
temp_label.text = "[font_size=24]%s[/font_size]" % bullet_text
|
||||
|
||||
await get_tree().process_frame
|
||||
|
||||
var width = temp_label.get_content_width() + 5 # padding
|
||||
|
||||
remove_child(temp_label)
|
||||
temp_label.queue_free()
|
||||
|
||||
return max(width, 20) # Minimum pixels
|
||||
|
||||
func create_li_node(element: HTMLParser.HTMLElement, list_type: String, marker_width: float = 20) -> Control:
|
||||
var li_container = HBoxContainer.new()
|
||||
|
||||
# Create bullet point
|
||||
var bullet_label = RichTextLabel.new()
|
||||
bullet_label.custom_minimum_size = Vector2(marker_width, 0)
|
||||
bullet_label.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
||||
bullet_label.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
bullet_label.bbcode_enabled = true
|
||||
bullet_label.fit_content = true
|
||||
bullet_label.scroll_active = false
|
||||
bullet_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
bullet_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
bullet_label.theme = BROWSER_TEXT
|
||||
|
||||
var bullet_text = get_bullet_for_type(list_type)
|
||||
bullet_label.text = "[font_size=24]%s[/font_size]" % bullet_text
|
||||
|
||||
# Create content
|
||||
var content_label = RichTextLabel.new()
|
||||
content_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
content_label.bbcode_enabled = true
|
||||
content_label.fit_content = true
|
||||
content_label.theme = BROWSER_TEXT
|
||||
content_label.scroll_active = false
|
||||
content_label.text = "[font_size=24]%s[/font_size]" % element.get_bbcode_formatted_text()
|
||||
|
||||
li_container.add_theme_constant_override("separation", 0)
|
||||
li_container.add_child(bullet_label)
|
||||
li_container.add_child(content_label)
|
||||
|
||||
return li_container
|
||||
|
||||
func get_bullet_for_type(list_type: String) -> String:
|
||||
match list_type:
|
||||
"circle":
|
||||
return "◦"
|
||||
"disc":
|
||||
return "•"
|
||||
"square":
|
||||
return "■"
|
||||
"none":
|
||||
return " "
|
||||
_:
|
||||
return "•" # Default to disc
|
||||
1
Scripts/Tags/ul.gd.uid
Normal file
1
Scripts/Tags/ul.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cu1g4a1tv6ngw
|
||||
238
Scripts/main.gd
238
Scripts/main.gd
@@ -20,6 +20,9 @@ const H6 = preload("res://Scenes/Tags/h6.tscn")
|
||||
const FORM = preload("res://Scenes/Tags/form.tscn")
|
||||
const INPUT = preload("res://Scenes/Tags/input.tscn")
|
||||
const BUTTON = preload("res://Scenes/Tags/button.tscn")
|
||||
const UL = preload("res://Scenes/Tags/ul.tscn")
|
||||
const OL = preload("res://Scenes/Tags/ol.tscn")
|
||||
const LI = preload("res://Scenes/Tags/li.tscn")
|
||||
|
||||
const MIN_SIZE = Vector2i(750, 200)
|
||||
|
||||
@@ -106,11 +109,220 @@ line breaks
|
||||
|
||||
<input type=\"password\" placeholder=\"your password...\" />
|
||||
<button type=\"submit\">Submit</button>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
<separator direction=\"horizontal\" />
|
||||
# Ordered list
|
||||
<ol>
|
||||
<li>hello gang</li>
|
||||
<li>this</li>
|
||||
<li>is</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
<li>a test</li>
|
||||
</ol>
|
||||
|
||||
<ol type=\"zero-lead\">
|
||||
<li>hello gang</li>
|
||||
<li>this</li>
|
||||
<li>is</li>
|
||||
<li>a test</li>
|
||||
</ol>
|
||||
|
||||
<ol type=\"lower-alpha\">
|
||||
<li>hello gang</li>
|
||||
<li>this</li>
|
||||
<li>is</li>
|
||||
<li>a test</li>
|
||||
</ol>
|
||||
|
||||
<ol type=\"upper-alpha\">
|
||||
<li>hello gang</li>
|
||||
<li>this</li>
|
||||
<li>is</li>
|
||||
<li>a test</li>
|
||||
</ol>
|
||||
|
||||
|
||||
<ol type=\"lower-roman\">
|
||||
<li>hello gang</li>
|
||||
<li>this</li>
|
||||
<li>is</li>
|
||||
<li>a test</li>
|
||||
</ol>
|
||||
|
||||
<ol type=\"upper-roman\">
|
||||
<li>hello gang</li>
|
||||
<li>this</li>
|
||||
<li>is</li>
|
||||
<li>a test</li>
|
||||
</ol>
|
||||
|
||||
<ul>
|
||||
<li>hello gang</li>
|
||||
<li>this</li>
|
||||
<li>is</li>
|
||||
<li>a test</li>
|
||||
</ul>
|
||||
|
||||
<ul type=\"circle\">
|
||||
<li>hello gang</li>
|
||||
<li>this</li>
|
||||
<li>is</li>
|
||||
<li>a test</li>
|
||||
</ul>
|
||||
<ul type=\"none\">
|
||||
<li>hello gang</li>
|
||||
<li>this</li>
|
||||
<li>is</li>
|
||||
<li>a test</li>
|
||||
</ul>
|
||||
<ul type=\"square\">
|
||||
<li>hello gang</li>
|
||||
<li>this</li>
|
||||
<li>is</li>
|
||||
<li>a test</li>
|
||||
</ul>
|
||||
<img src=\"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQMNUPIKabszX0Js_c0kfa4cz_JQYKfGTuBUA&s\" />
|
||||
<separator direction=\"vertical\" />
|
||||
</body>".to_utf8_buffer()
|
||||
@@ -160,9 +372,12 @@ line breaks
|
||||
|
||||
continue
|
||||
|
||||
var element_node = create_element_node(element)
|
||||
var element_node = await create_element_node(element)
|
||||
if element_node:
|
||||
website_container.add_child(element_node)
|
||||
# ul/ol handle their own adding
|
||||
if element.tag_name != "ul" and element.tag_name != "ol":
|
||||
website_container.add_child(element_node)
|
||||
|
||||
# Handle hyperlinks for all elements
|
||||
if contains_hyperlink(element) and 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)))
|
||||
@@ -223,7 +438,7 @@ func create_element_node(element: HTMLParser.HTMLElement) -> Control:
|
||||
node.init(element)
|
||||
|
||||
for child_element in element.children:
|
||||
var child_node = create_element_node(child_element)
|
||||
var child_node = await create_element_node(child_element)
|
||||
if child_node:
|
||||
node.add_child(child_node)
|
||||
"input":
|
||||
@@ -235,6 +450,19 @@ func create_element_node(element: HTMLParser.HTMLElement) -> Control:
|
||||
"span":
|
||||
node = SPAN.instantiate()
|
||||
node.init(element)
|
||||
"ul":
|
||||
node = UL.instantiate()
|
||||
website_container.add_child(node) # Add to scene tree first
|
||||
await node.init(element)
|
||||
return node # Return early since we already added it
|
||||
"ol":
|
||||
node = OL.instantiate()
|
||||
website_container.add_child(node) # Add to scene tree first
|
||||
await node.init(element)
|
||||
return node # Return early since we already added it
|
||||
"li":
|
||||
node = LI.instantiate()
|
||||
node.init(element)
|
||||
_:
|
||||
return null
|
||||
|
||||
|
||||
Reference in New Issue
Block a user