diff --git a/crates/benilla-ui/src/script/compat/classic_api/frame.rs b/crates/benilla-ui/src/script/compat/classic_api/frame.rs index 112c68e3..75138002 100644 --- a/crates/benilla-ui/src/script/compat/classic_api/frame.rs +++ b/crates/benilla-ui/src/script/compat/classic_api/frame.rs @@ -110,6 +110,38 @@ end end "#; +/// Goes on all three tables: `GetDebugName()` is the era's "what is this frame called" for logs +/// and error messages, and it answers for an **unnamed** frame too, which `GetName` cannot. An +/// addon that keeps a list of frames and reports on them reaches for it precisely because some of +/// them have no name — `Cinematic/Frames.lua:3734` is `entry.name or entry.frame:GetDebugName()`, +/// and with the method absent its `/cine debug frame ` raised on the first unnamed frame in +/// the list instead of printing the row the player asked for. +/// +/// Deviation, and it is in the unnamed leg only: the era walks the parent's own fields to find +/// the key the child is stored under and builds `Parent.key`; failing that it reports an index +/// among the parent's children. This walks the same fields — frames here are plain tables, so a +/// `parent.icon = tex` is visible — and falls back to `Parent.` rather than an index, +/// because an index here would be the creation order of a list this client does not keep and a +/// *wrong* number reads worse than an honest "no key". A frame with no parent answers +/// ``. +const DEBUG_NAME_DELEGATES: &str = r#" +return function(m) +function m.GetDebugName(self) + local name = self:GetName() + if name then return name end + local parent = self.GetParent and self:GetParent() + if not parent then return "" end + local base = parent.GetDebugName and parent:GetDebugName() or parent:GetName() or "" + for key, value in pairs(parent) do + if value == self and type(key) == "string" then + return base .. "." .. key + end + end + return base .. "." +end +end +"#; + /// Texture-only: `SetColorTexture(r, g, b[, a])` is the modern name for `SetTexture`'s colour arm, /// which 1.12 already has (`0x770360` makes the 8x8 solid surface, and our `region/paint.rs` arm /// defaults the alpha to 1 exactly as it does). Retail split the two spellings when `SetTexture` @@ -261,6 +293,7 @@ pub(super) fn install(lua: &Lua) -> mlua::Result<()> { delegate(lua, key, GEOMETRY_DELEGATES)?; delegate(lua, key, SHOWN_DELEGATES)?; delegate(lua, key, MOUSE_OVER_DELEGATES)?; + delegate(lua, key, DEBUG_NAME_DELEGATES)?; } delegate(lua, REG_TEXTURE_METHODS, TEXTURE_DELEGATES)?; delegate(lua, REG_FONTSTRING_METHODS, FONTSTRING_DELEGATES)?; diff --git a/crates/benilla-ui/src/script/tests/widget_surface.rs b/crates/benilla-ui/src/script/tests/widget_surface.rs index 45b26595..24a826b8 100644 --- a/crates/benilla-ui/src/script/tests/widget_surface.rs +++ b/crates/benilla-ui/src/script/tests/widget_surface.rs @@ -603,6 +603,21 @@ const ALLOWED_BEYOND: &[(&str, &str, &str)] = &[ addon writes this one — Cinematic/Options.lua:701 paints its list border with it and \ died at session start without it, and OpenMapClassic its map chrome", ), + ( + "GetDebugName", + "Button CheckButton ColorSelect DressUpModel EditBox FontString Frame GameTooltip \ + LootButton MessageFrame Minimap Model MovieFrame ScrollFrame ScrollingMessageFrame \ + SimpleHTML Slider StatusBar TabardModel Texture WorldFrame PlayerModel", + "ClassicAPI: the era's \"what is this frame called\" for a log line or an error message, \ + and the one that answers for an UNNAMED frame, which GetName cannot. An addon keeping a \ + list of frames reaches for it precisely because some of them have no name — \ + Cinematic/Frames.lua:3734 is `entry.name or entry.frame:GetDebugName()`, so /cine debug \ + frame raised on the first unnamed row instead of printing the one asked for. \ + Named frames answer their name, so a feature test on it learns nothing a 1.12 client \ + would answer differently; the unnamed leg deviates in its fallback only (Parent.key by \ + walking the parent's fields, else Parent., never the era's child index — a \ + wrong number reads worse than an honest absence)", + ), ( "SetEnabled", "Button CheckButton EditBox LootButton",