Files
leonwww/flumi/Scripts/Utils/Lua/Class.gd
2025-08-08 16:51:21 +03:00

272 lines
9.4 KiB
GDScript

extends RefCounted
class_name LuaClassListUtils
static func element_classlist_add_handler(vm: LuauVM, dom_parser: HTMLParser) -> int:
vm.luaL_checktype(1, vm.LUA_TTABLE)
var css_class: String = vm.luaL_checkstring(2)
vm.lua_getfield(1, "_element_id")
var element_id: String = vm.lua_tostring(-1)
vm.lua_pop(1)
# Find the element
var element = dom_parser.find_by_id(element_id)
if not element:
print("DEBUG: Element not found!")
return 0
# Get classes
var classes_to_add = [css_class]
var current_style = element.get_attribute("style", "")
var style_classes = CSSParser.smart_split_utility_classes(current_style) if current_style.length() > 0 else []
# Add new css_class if not already present
var changed = false
for class_to_add in classes_to_add:
if class_to_add not in style_classes:
style_classes.append(class_to_add)
changed = true
if changed:
var new_style_attr = " ".join(style_classes)
element.set_attribute("style", new_style_attr)
trigger_element_restyle(element, dom_parser)
return 0
static func element_classlist_remove_handler(vm: LuauVM, dom_parser: HTMLParser) -> int:
vm.luaL_checktype(1, vm.LUA_TTABLE)
var css_class: String = vm.luaL_checkstring(2)
vm.lua_getfield(1, "_element_id")
var element_id: String = vm.lua_tostring(-1)
vm.lua_pop(1)
# Find the element
var element = dom_parser.find_by_id(element_id)
if not element:
return 0
var classes_to_remove = [css_class]
var current_style = element.get_attribute("style", "")
var style_classes = CSSParser.smart_split_utility_classes(current_style) if current_style.length() > 0 else []
# Remove classes if present
var changed = false
for class_to_remove in classes_to_remove:
if class_to_remove in style_classes:
style_classes.erase(class_to_remove)
changed = true
if changed:
var new_style_attr = " ".join(style_classes) if style_classes.size() > 0 else ""
if new_style_attr.length() > 0:
element.set_attribute("style", new_style_attr)
else:
element.attributes.erase("style")
trigger_element_restyle(element, dom_parser)
return 0
static func element_classlist_toggle_handler(vm: LuauVM, dom_parser: HTMLParser) -> int:
vm.luaL_checktype(1, vm.LUA_TTABLE)
var css_class: String = vm.luaL_checkstring(2)
vm.lua_getfield(1, "_element_id")
var element_id: String = vm.lua_tostring(-1)
vm.lua_pop(1)
# Find the element
var element = dom_parser.find_by_id(element_id)
if not element:
vm.lua_pushboolean(false)
return 1
var utility_classes = [css_class]
var current_style = element.get_attribute("style", "")
var style_classes = CSSParser.smart_split_utility_classes(current_style) if current_style.length() > 0 else []
var has_all_classes = true
for utility_class in utility_classes:
if utility_class not in style_classes:
has_all_classes = false
break
if has_all_classes:
# Remove all utility classes
for utility_class in utility_classes:
style_classes.erase(utility_class)
vm.lua_pushboolean(false)
else:
for utility_class in utility_classes:
if utility_class not in style_classes:
style_classes.append(utility_class)
vm.lua_pushboolean(true)
if style_classes.size() > 0:
var new_style_attr = " ".join(style_classes)
element.set_attribute("style", new_style_attr)
else:
element.attributes.erase("style")
trigger_element_restyle(element, dom_parser)
return 1
# DOM operation handlers for class management
static func handle_add_class(operation: Dictionary, dom_parser: HTMLParser) -> void:
var element_id: String = operation.element_id
var cls: String = operation.class_name
var element = dom_parser.find_by_id(element_id) if element_id != "body" else dom_parser.find_first("body")
if element:
# Use the original working logic from LuaClassListUtils
var current_style = element.get_attribute("style", "")
var style_classes = CSSParser.smart_split_utility_classes(current_style) if current_style.length() > 0 else []
# Add new class if not already present
if cls not in style_classes:
style_classes.append(cls)
var new_style_attr = " ".join(style_classes)
element.set_attribute("style", new_style_attr)
trigger_element_restyle(element, dom_parser)
static func handle_remove_class(operation: Dictionary, dom_parser: HTMLParser) -> void:
var element_id: String = operation.element_id
var cls: String = operation.class_name
var element = dom_parser.find_by_id(element_id) if element_id != "body" else dom_parser.find_first("body")
if element:
# Use the original working logic from LuaClassListUtils
var current_style = element.get_attribute("style", "")
if current_style.length() == 0:
return
var style_classes = CSSParser.smart_split_utility_classes(current_style)
var clean_classes = []
for style_cls in style_classes:
if style_cls != cls:
clean_classes.append(style_cls)
# Update style attribute
if clean_classes.size() > 0:
var new_style_attr = " ".join(clean_classes)
element.set_attribute("style", new_style_attr)
else:
element.attributes.erase("style")
trigger_element_restyle(element, dom_parser)
static func handle_toggle_class(operation: Dictionary, dom_parser: HTMLParser) -> void:
var element_id: String = operation.element_id
var cls: String = operation.class_name
var element = dom_parser.find_by_id(element_id) if element_id != "body" else dom_parser.find_first("body")
if element:
# Use the original working logic from LuaClassListUtils
var current_style = element.get_attribute("style", "")
var style_classes = CSSParser.smart_split_utility_classes(current_style) if current_style.length() > 0 else []
var has_class = cls in style_classes
if has_class:
# Remove class
var new_classes = []
for style_cls in style_classes:
if style_cls != cls:
new_classes.append(style_cls)
if new_classes.size() > 0:
element.set_attribute("style", " ".join(new_classes))
else:
element.attributes.erase("style")
else:
# Add class
style_classes.append(cls)
element.set_attribute("style", " ".join(style_classes))
trigger_element_restyle(element, dom_parser)
static func trigger_element_restyle(element: HTMLParser.HTMLElement, dom_parser: HTMLParser) -> void:
# Find DOM node for element
var element_id = element.get_attribute("id")
var dom_node = dom_parser.parse_result.dom_nodes.get(element_id, null)
if not dom_node:
return
# margins, wrappers, etc.
var updated_dom_node = StyleManager.apply_element_styles(dom_node, element, dom_parser)
# If the node was wrapped/unwrapped by margin handling, update DOM registration
if updated_dom_node != dom_node:
dom_parser.parse_result.dom_nodes[element_id] = updated_dom_node
dom_node = updated_dom_node
# Find node
var actual_element_node = dom_node
if dom_node is MarginContainer and dom_node.name.begins_with("MarginWrapper_"):
if dom_node.get_child_count() > 0:
actual_element_node = dom_node.get_child(0)
if actual_element_node is HTMLButton:
actual_element_node.apply_button_styles(element, dom_parser)
elif element.tag_name == "div":
update_div_hover_styles(actual_element_node, element, dom_parser)
else:
update_element_text_content(actual_element_node, element, dom_parser)
if actual_element_node.has_method("init"):
actual_element_node.init(element, dom_parser)
static func update_element_text_content(dom_node: Control, element: HTMLParser.HTMLElement, dom_parser: HTMLParser) -> void:
# Get node
var content_node = dom_node
if dom_node is MarginContainer and dom_node.name.begins_with("MarginWrapper_"):
if dom_node.get_child_count() > 0:
content_node = dom_node.get_child(0)
# Handle RichTextLabel elements (p, span, etc.)
if content_node is RichTextLabel:
var styles = dom_parser.get_element_styles_with_inheritance(element, "", [])
StyleManager.apply_styles_to_label(content_node, styles, element, dom_parser)
return
# Handle div elements that might contain RichTextLabel children
if element.tag_name == "div":
update_text_labels_recursive(content_node, element, dom_parser)
return
static func update_text_labels_recursive(node: Node, element: HTMLParser.HTMLElement, dom_parser: HTMLParser) -> void:
if node is RichTextLabel:
var styles = dom_parser.get_element_styles_with_inheritance(element, "", [])
StyleManager.apply_styles_to_label(node, styles, element, dom_parser)
return
for child in node.get_children():
update_text_labels_recursive(child, element, dom_parser)
static func update_div_hover_styles(dom_node: Control, element: HTMLParser.HTMLElement, dom_parser: HTMLParser) -> void:
var styles = dom_parser.get_element_styles_with_inheritance(element, "", [])
var hover_styles = dom_parser.get_element_styles_with_inheritance(element, "hover", [])
if dom_node is PanelContainer:
var normal_stylebox = BackgroundUtils.create_stylebox_from_styles(styles)
dom_node.add_theme_stylebox_override("panel", normal_stylebox)
if hover_styles.size() > 0:
BackgroundUtils.setup_panel_hover_support(dom_node, styles, hover_styles)
else:
if dom_node.has_meta("normal_stylebox"):
dom_node.remove_meta("normal_stylebox")
if dom_node.has_meta("hover_stylebox"):
dom_node.remove_meta("hover_stylebox")
if dom_node.mouse_entered.is_connected(BackgroundUtils._on_panel_mouse_entered):
dom_node.mouse_entered.disconnect(BackgroundUtils._on_panel_mouse_entered)
if dom_node.mouse_exited.is_connected(BackgroundUtils._on_panel_mouse_exited):
dom_node.mouse_exited.disconnect(BackgroundUtils._on_panel_mouse_exited)
update_element_text_content(dom_node, element, dom_parser)