classList:add, classList:remove, classList:toggle, style handling

This commit is contained in:
Face
2025-08-05 18:01:16 +03:00
parent 7f90dfb716
commit ba2f49559e
12 changed files with 589 additions and 150 deletions

View File

@@ -75,6 +75,16 @@ class CSSStylesheet:
func add_rule(rule: CSSRule):
rules.append(rule)
func find_rule_by_selector(selector: String) -> CSSRule:
for rule in rules:
if rule.selector == selector and rule.event_prefix == "":
return rule
for rule in rules:
if rule.selector == selector:
return rule
return null
func get_styles_for_element(tag_name: String, event: String = "", class_names: Array[String] = [], element: HTMLParser.HTMLElement = null) -> Dictionary:
var styles = {}
@@ -362,8 +372,13 @@ func parse_utility_class(rule: CSSRule, utility_name: String) -> void:
if utility_name.begins_with(prefix):
var actual_utility = utility_name.substr(prefix.length())
var pseudo_rule = CSSRule.new()
pseudo_rule.selector = rule.selector + ":" + pseudo
pseudo_rule.init(pseudo_rule.selector)
pseudo_rule.selector = rule.selector
pseudo_rule.event_prefix = pseudo
pseudo_rule.selector_type = "simple"
pseudo_rule.selector_parts = [rule.selector]
pseudo_rule.calculate_specificity()
parse_utility_class_internal(pseudo_rule, actual_utility)
stylesheet.add_rule(pseudo_rule)
return
@@ -374,10 +389,19 @@ func parse_utility_class(rule: CSSRule, utility_name: String) -> void:
# Parses a utility class (e.g. "text-red-500") and adds properties to the rule (e.g. "color: red")
# Used as a translation layer for Tailwind-like utility classes, as it becomes easier to manage these programmatically
static func parse_utility_class_internal(rule: CSSRule, utility_name: String) -> void:
# Handle color classes like text-[#ff0000]
# Handle font size classes like text-[16px] or color classes like text-[#ff0000]
if utility_name.begins_with("text-[") and utility_name.ends_with("]"):
var color_value = SizeUtils.extract_bracket_content(utility_name, 5) # after 'text-'
var parsed_color = ColorUtils.parse_color(color_value)
var bracket_content = SizeUtils.extract_bracket_content(utility_name, 5) # after 'text-'
# Check if it's a font size by looking for size units or being a valid number
if bracket_content.ends_with("px") or bracket_content.ends_with("em") or bracket_content.ends_with("rem") or bracket_content.is_valid_int() or bracket_content.is_valid_float():
var font_size_value = SizingUtils.parse_size_value(bracket_content)
if font_size_value != null and typeof(font_size_value) != TYPE_STRING:
rule.properties["font-size"] = font_size_value
return
# Parse as color
var parsed_color = ColorUtils.parse_color(bracket_content)
rule.properties["color"] = parsed_color
return

View File

@@ -200,12 +200,30 @@ func parse_inline_style_with_event(style_string: String, event: String = "") ->
CSSParser.parse_utility_class_internal(rule, actual_utility)
for property in rule.properties:
properties[property] = rule.properties[property]
else:
# Check if this is a CSS class that might have pseudo-class rules
if parse_result.css_parser and parse_result.css_parser.stylesheet:
var pseudo_styles = parse_result.css_parser.stylesheet.get_styles_for_element("", event, [utility_name], null)
if not pseudo_styles.is_empty():
for property in pseudo_styles:
properties[property] = pseudo_styles[property]
else:
if not utility_name.contains(":"):
var rule = CSSParser.CSSRule.new()
CSSParser.parse_utility_class_internal(rule, utility_name)
for property in rule.properties:
properties[property] = rule.properties[property]
if parse_result.css_parser and parse_result.css_parser.stylesheet:
var css_rule = parse_result.css_parser.stylesheet.find_rule_by_selector("." + utility_name)
if css_rule:
for property in css_rule.properties:
properties[property] = css_rule.properties[property]
else:
var rule = CSSParser.CSSRule.new()
CSSParser.parse_utility_class_internal(rule, utility_name)
for property in rule.properties:
properties[property] = rule.properties[property]
else:
var rule = CSSParser.CSSRule.new()
CSSParser.parse_utility_class_internal(rule, utility_name)
for property in rule.properties:
properties[property] = rule.properties[property]
return properties

View File

@@ -213,6 +213,25 @@ func _element_index_handler(vm: LuauVM) -> int:
vm.lua_rawseti(-2, index)
index += 1
return 1
"classList":
# Create classList object with add, remove, toggle methods
vm.lua_newtable()
# Add methods to classList using the utility class
vm.lua_pushcallable(_element_classlist_add_wrapper, "classList.add")
vm.lua_setfield(-2, "add")
vm.lua_pushcallable(_element_classlist_remove_wrapper, "classList.remove")
vm.lua_setfield(-2, "remove")
vm.lua_pushcallable(_element_classlist_toggle_wrapper, "classList.toggle")
vm.lua_setfield(-2, "toggle")
# Store element reference for the classList methods
vm.lua_getfield(1, "_element_id")
vm.lua_setfield(-2, "_element_id")
return 1
_:
# Fall back to checking the original table for methods
@@ -333,6 +352,15 @@ func _element_remove_handler(vm: LuauVM) -> int:
return 0
func _element_classlist_add_wrapper(vm: LuauVM) -> int:
return LuaClassListUtils.element_classlist_add_handler(vm, dom_parser)
func _element_classlist_remove_wrapper(vm: LuauVM) -> int:
return LuaClassListUtils.element_classlist_remove_handler(vm, dom_parser)
func _element_classlist_toggle_wrapper(vm: LuauVM) -> int:
return LuaClassListUtils.element_classlist_toggle_handler(vm, dom_parser)
func _render_new_element(element: HTMLParser.HTMLElement, parent_node: Node) -> void:
# Get reference to main scene for rendering
var main_scene = get_node("/root/Main")