Compare commits

...

5 Commits

26 changed files with 102 additions and 55 deletions
+9
View File
@@ -766,6 +766,8 @@ function E:StaticPopup_Resize(dialog, which)
height = height + 8 + editBox:GetHeight() height = height + 8 + editBox:GetHeight()
elseif info.hasMoneyFrame then elseif info.hasMoneyFrame then
height = height + 16 height = height + 16
elseif info.hasMoneyInputFrame then
height = height + 22
end end
if height > maxHeightSoFar then if height > maxHeightSoFar then
@@ -903,6 +905,13 @@ function E:StaticPopup_Show(which, text_arg1, text_arg2, data)
_G[name.."MoneyFrame"]:Hide() _G[name.."MoneyFrame"]:Hide()
end end
-- Show or hide money input frame
if info.hasMoneyInputFrame then
_G[name.."MoneyInputFrame"]:Show()
else
_G[name.."MoneyInputFrame"]:Hide()
end
-- Set the miscellaneous variables for the dialog -- Set the miscellaneous variables for the dialog
dialog.which = which dialog.which = which
dialog.timeleft = info.timeout dialog.timeleft = info.timeout
-1
View File
@@ -13,7 +13,6 @@ E.TutorialList = {
L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."], L["You can toggle the microbar by using your middle mouse button on the minimap you can also accomplish this by enabling the actual microbar located in the actionbar settings."],
L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under ElvUI and setting a keybind for the raid marker."], L["A raid marker feature is available by pressing Escape -> Keybinds scroll to the bottom under ElvUI and setting a keybind for the raid marker."],
L["You can set your keybinds quickly by typing /kb."], L["You can set your keybinds quickly by typing /kb."],
L["The focus unit can be set by typing /focus when you are targeting the unit you want to focus. It is recommended you make a macro to do this."],
L["ElvUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."], L["ElvUI has a dual spec feature which allows you to load different profiles based on your current spec on the fly. You can enable this from the profiles tab."],
L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."], L["You can access copy chat and chat menu functions by mouse over the top right corner of chat panel and left/right click on the button that will appear."],
L["If you are experiencing issues with ElvUI try disabling all your addons except ElvUI, remember ElvUI is a full UI replacement addon, you cannot run two addons that do the same thing."], L["If you are experiencing issues with ElvUI try disabling all your addons except ElvUI, remember ElvUI is a full UI replacement addon, you cannot run two addons that do the same thing."],
@@ -59,7 +59,7 @@ local function Update(self, event)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[ Override: AssistantIndicator.Override(self, event, ...) --[[ Override: AssistantIndicator.Override(self, event, ...)
Used to completely override the element's update process. Used to completely override the element's update process.
@@ -67,7 +67,7 @@ local function Path(self, ...)
* event - the event triggering the update (string) * event - the event triggering the update (string)
* ... - the arguments accompanying the event (string) * ... - the arguments accompanying the event (string)
--]] --]]
return (self.AssistantIndicator.Override or Update) (self, unpack(arg)) return (self.AssistantIndicator.Override or Update) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
+3 -3
View File
@@ -368,9 +368,9 @@ local function onUpdate(self, elapsed)
end end
end end
local function Update(self, ...) local function Update(self, event, a, b, c, d, e)
SPELLCAST_START(self, unpack(arg)) SPELLCAST_START(self, event, a, b, c, d, e)
return SPELLCAST_CHANNEL_START(self, unpack(arg)) return SPELLCAST_CHANNEL_START(self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
@@ -57,14 +57,14 @@ local function Update(self, event)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[ Override: CombatIndicator.Override(self, event) --[[ Override: CombatIndicator.Override(self, event)
Used to completely override the internal update function. Used to completely override the internal update function.
* self - the parent object * self - the parent object
* event - the event triggering the update (string) * event - the event triggering the update (string)
--]] --]]
return (self.CombatIndicator.Override or Update) (self, unpack(arg)) return (self.CombatIndicator.Override or Update) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
+2 -2
View File
@@ -67,7 +67,7 @@ local function Update(self, event)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[ Override: ComboPoints.Override(self, event, ...) --[[ Override: ComboPoints.Override(self, event, ...)
Used to completely override the internal update function. Used to completely override the internal update function.
@@ -75,7 +75,7 @@ local function Path(self, ...)
* event - the event triggering the update (string) * event - the event triggering the update (string)
* ... - the arguments accompanying the event * ... - the arguments accompanying the event
--]] --]]
return (self.ComboPoints.Override or Update) (self, unpack(arg)) return (self.ComboPoints.Override or Update) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
@@ -73,7 +73,7 @@ local function Update(self, event, unit)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[ Override: HappinessIndicator.Override(self, event, ...) --[[ Override: HappinessIndicator.Override(self, event, ...)
Used to completely override the internal update function. Used to completely override the internal update function.
@@ -81,7 +81,7 @@ local function Path(self, ...)
* event - the event triggering the update (string) * event - the event triggering the update (string)
* ... - the arguments accompanying the event * ... - the arguments accompanying the event
--]] --]]
return (self.HappinessIndicator.Override or Update) (self, unpack(arg)) return (self.HappinessIndicator.Override or Update) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
+2 -2
View File
@@ -187,7 +187,7 @@ local function Update(self, event, unit)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[ Override: Health.Override(self, event, unit) --[[ Override: Health.Override(self, event, unit)
Used to completely override the internal update function. Used to completely override the internal update function.
@@ -195,7 +195,7 @@ local function Path(self, ...)
* event - the event triggering the update (string) * event - the event triggering the update (string)
* unit - the unit accompanying the event (string) * unit - the unit accompanying the event (string)
--]] --]]
return (self.Health.Override or Update) (self, unpack(arg)) return (self.Health.Override or Update) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
@@ -60,7 +60,7 @@ local function Update(self, event)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[ Override: LeaderIndicator.Override(self, event, ...) --[[ Override: LeaderIndicator.Override(self, event, ...)
Used to completely override the internal update function. Used to completely override the internal update function.
@@ -68,7 +68,7 @@ local function Path(self, ...)
* event - the event triggering the update (string) * event - the event triggering the update (string)
* ... - the arguments accompanying the event * ... - the arguments accompanying the event
--]] --]]
return (self.LeaderIndicator.Override or Update) (self, unpack(arg)) return (self.LeaderIndicator.Override or Update) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
@@ -81,7 +81,7 @@ local function Update(self, event)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[ Override: MasterLooterIndicator.Override(self, event, ...) --[[ Override: MasterLooterIndicator.Override(self, event, ...)
Used to completely override the internal update function. Used to completely override the internal update function.
@@ -89,7 +89,7 @@ local function Path(self, ...)
* event - the event triggering the update (string) * event - the event triggering the update (string)
* ... - the arguments accompanying the event * ... - the arguments accompanying the event
--]] --]]
return (self.MasterLooterIndicator.Override or Update) (self, unpack(arg)) return (self.MasterLooterIndicator.Override or Update) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
+2 -2
View File
@@ -91,7 +91,7 @@ local function Update(self, event, unit)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[ Override: Portrait.Override(self, event, unit) --[[ Override: Portrait.Override(self, event, unit)
Used to completely override the internal update function. Used to completely override the internal update function.
@@ -99,7 +99,7 @@ local function Path(self, ...)
* event - the event triggering the update (string) * event - the event triggering the update (string)
* unit - the unit accompanying the event (string) * unit - the unit accompanying the event (string)
--]] --]]
return (self.Portrait.Override or Update) (self, unpack(arg)) return (self.Portrait.Override or Update) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
+2 -2
View File
@@ -202,7 +202,7 @@ local function Update(self, event, unit)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[ Override: Power.Override(self, event, unit, ...) --[[ Override: Power.Override(self, event, unit, ...)
Used to completely override the internal update function. Used to completely override the internal update function.
@@ -211,7 +211,7 @@ local function Path(self, ...)
* unit - the unit accompanying the event (string) * unit - the unit accompanying the event (string)
* ... - the arguments accompanying the event * ... - the arguments accompanying the event
--]] --]]
return (self.Power.Override or Update) (self, unpack(arg)) return (self.Power.Override or Update) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
@@ -79,7 +79,7 @@ local function Update(self, event, unit)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[Override: PvPIndicator.Override(self, event, ...) --[[Override: PvPIndicator.Override(self, event, ...)
Used to completely override the internal update function. Used to completely override the internal update function.
@@ -87,7 +87,7 @@ local function Path(self, ...)
* event - the event triggering the update (string) * event - the event triggering the update (string)
* ... - the arguments accompanying the event * ... - the arguments accompanying the event
--]] --]]
return (self.PvPIndicator.Override or Update) (self, unpack(arg)) return (self.PvPIndicator.Override or Update) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
@@ -59,14 +59,14 @@ local function Update(self, event)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[ Override: RaidTargetIndicator.Override(self, event) --[[ Override: RaidTargetIndicator.Override(self, event)
Used to completely override the internal update function. Used to completely override the internal update function.
* self - the parent object * self - the parent object
* event - the event triggering the update (string) * event - the event triggering the update (string)
--]] --]]
return (self.RaidTargetIndicator.Override or Update) (self, unpack(arg)) return (self.RaidTargetIndicator.Override or Update) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
+2 -2
View File
@@ -73,14 +73,14 @@ local function Update(self, event)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[ Override: Range.Override(self, event) --[[ Override: Range.Override(self, event)
Used to completely override the internal update function. Used to completely override the internal update function.
* self - the parent object * self - the parent object
* event - the event triggering the update (string) * event - the event triggering the update (string)
--]] --]]
return (self.Range.Override or Update) (self, unpack(arg)) return (self.Range.Override or Update) (self, event, a, b, c, d, e)
end end
-- Internal updating method -- Internal updating method
@@ -57,14 +57,14 @@ local function Update(self, event)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[ Override: RestingIndicator.Override(self, event) --[[ Override: RestingIndicator.Override(self, event)
Used to completely override the internal update function. Used to completely override the internal update function.
* self - the parent object * self - the parent object
* event - the event triggering the update (string) * event - the event triggering the update (string)
--]] --]]
return (self.RestingIndicator.Override or Update) (self, unpack(arg)) return (self.RestingIndicator.Override or Update) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
+2 -2
View File
@@ -22,9 +22,9 @@ local function onEvent()
end end
local event_metatable = { local event_metatable = {
__call = function(funcs, self, ...) __call = function(funcs, self, event, a, b, c, d, e)
for _, func in next, funcs do for _, func in next, funcs do
func(self, unpack(arg)) func(self, event, a, b, c, d, e)
end end
end, end,
} }
@@ -443,7 +443,7 @@ function lib:AddListener(tab, method)
error(format("Bad argument #3 to `AddListener'. Expected method, got %q.", type(tab[method])), 2) error(format("Bad argument #3 to `AddListener'. Expected method, got %q.", type(tab[method])), 2)
end end
func = function(...) func = function(...)
return tab[method](tab, unpack(arg)) return tab[method](tab, event, a, b, c, d, e)
end end
elseif type(tab) == "function" then elseif type(tab) == "function" then
func = tab func = tab
@@ -53,8 +53,8 @@ local function Update(self, event, unit, currMana, maxMana)
end end
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
return (self.DruidAltMana.Override or Update) (self, unpack(arg)) return (self.DruidAltMana.Override or Update) (self, event, a, b, c, d, e)
end end
local function ElementEnable(self) local function ElementEnable(self)
@@ -101,8 +101,8 @@ local function Visibility(self, event, unit)
end end
end end
local function VisibilityPath(self, ...) local function VisibilityPath(self, event, a, b, c, d, e)
return (self.DruidAltMana.OverrideVisibility or Visibility) (self, unpack(arg)) return (self.DruidAltMana.OverrideVisibility or Visibility) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
@@ -109,13 +109,8 @@ end
local function onUpdate(self, elapsed) local function onUpdate(self, elapsed)
self.elapsed = (self.elapsed or 0) + elapsed self.elapsed = (self.elapsed or 0) + elapsed
if self.elapsed >= 0.1 then if self.elapsed >= 0.1 then
local _, _, _, _, _, _, timeLeft = UnitDebuff(self.__owner.unit, self.index, "HARMFUL")
if timeLeft and timeLeft > 0 then
self.time:SetText(formatTime(timeLeft))
else
self:SetScript('OnUpdate', nil) self:SetScript('OnUpdate', nil)
self.time:Hide() self.time:Hide()
end
self.elapsed = 0 self.elapsed = 0
end end
end end
@@ -178,8 +173,9 @@ local function Update(self, event, unit)
local _stackThreshold = 0 local _stackThreshold = 0
for i = 1, 40 do for i = 1, 40 do
name, _, icon, count, debuffType, duration, expirationTime = UnitDebuff(unit, i, "HARMFUL") local texture, stackCount, dType = UnitDebuff(unit, i, "HARMFUL")
if not (name and icon) then break end name, icon, count, debuffType, duration, expirationTime = texture, texture, stackCount, dType, nil, nil
if not name then break end
if(addon.ShowDispellableDebuff and (element.showDispellableDebuff ~= false) and debuffType) then if(addon.ShowDispellableDebuff and (element.showDispellableDebuff ~= false) and debuffType) then
if(addon.FilterDispellableDebuff) then if(addon.FilterDispellableDebuff) then
@@ -225,7 +221,7 @@ local function Update(self, event, unit)
} }
end end
local function Path(self, ...) local function Path(self, event, a, b, c, d, e)
--[[ Override: RaidDebuffs.Override(self, event, ...) --[[ Override: RaidDebuffs.Override(self, event, ...)
Used to completely override the element's update process. Used to completely override the element's update process.
@@ -233,7 +229,7 @@ local function Path(self, ...)
* event - the event triggering the update (string) * event - the event triggering the update (string)
* ... - the arguments accompanying the event (string) * ... - the arguments accompanying the event (string)
--]] --]]
return (self.RaidDebuffs.Override or Update) (self, unpack(arg)) return (self.RaidDebuffs.Override or Update) (self, event, a, b, c, d, e)
end end
local function ForceUpdate(element) local function ForceUpdate(element)
+1 -1
View File
@@ -308,7 +308,7 @@ function A:ConfigureAuras(header, auraTable, weaponPosition)
top = max(top, button:GetTop() or -huge) top = max(top, button:GetTop() or -huge)
bottom = min(bottom, button:GetBottom() or huge) bottom = min(bottom, button:GetBottom() or huge)
end end
local deadIndex = (getn(auraTable) + numWeapon) + 1 local deadIndex = getn(auraTable) + 1
button = _G[headerName.."AuraButton"..deadIndex] button = _G[headerName.."AuraButton"..deadIndex]
while button do while button do
if button:IsShown() then button:Hide() end if button:IsShown() then button:Hide() end
+34
View File
@@ -7,6 +7,40 @@ local min = math.min
--WoW API / Variables --WoW API / Variables
local hooksecurefunc = hooksecurefunc local hooksecurefunc = hooksecurefunc
local GetScreenHeight = GetScreenHeight local GetScreenHeight = GetScreenHeight
local GetNumQuestWatches = GetNumQuestWatches
local GetQuestIndexForWatch = GetQuestIndexForWatch
local RemoveQuestWatch = RemoveQuestWatch
local AddQuestWatch = AddQuestWatch
local QuestWatch_Update = QuestWatch_Update
local original_QuestWatch_Update = QuestWatch_Update
function _G.QuestWatch_Update()
local watched = {}
local order = {}
local hasDuplicates = false
for i = 1, GetNumQuestWatches() do
local qIndex = GetQuestIndexForWatch(i)
if qIndex then
if watched[qIndex] then
hasDuplicates = true
else
watched[qIndex] = true
table.insert(order, qIndex)
end
end
end
if hasDuplicates then
for i = 1, table.getn(order) do
RemoveQuestWatch(order[i])
end
for i = 1, table.getn(order) do
AddQuestWatch(order[i])
end
end
original_QuestWatch_Update()
end
local WatchFrameHolder = CreateFrame("Frame", "WatchFrameHolder", E.UIParent) local WatchFrameHolder = CreateFrame("Frame", "WatchFrameHolder", E.UIParent)
WatchFrameHolder:SetWidth(150) WatchFrameHolder:SetWidth(150)
+1 -1
View File
@@ -421,7 +421,7 @@ function TT:SetHyperlink(tt, link, count)
end end
if tt:GetName() == "GameTooltip" then if tt:GetName() == "GameTooltip" then
if E.db.tooltip.spellID then if E.db.tooltip.spellID and id then
tt:AddLine(format("|cFFCA3C3C%s|r %d", ID, id)) tt:AddLine(format("|cFFCA3C3C%s|r %d", ID, id))
end end
end end
@@ -111,7 +111,8 @@ function UF:UpdateAuraWatch(frame, petOverride, db)
for i = 1, getn(buffs) do for i = 1, getn(buffs) do
if buffs[i].id then if buffs[i].id then
local name, _, image = UnitBuff(frame.unit, buffs[i].id) local image, count = UnitBuff(frame.unit, buffs[i].id)
local name = image
if name then if name then
local icon local icon
if not auras.icons[buffs[i].id] then if not auras.icons[buffs[i].id] then
@@ -942,18 +942,18 @@ local function BuildTabs(group, options, path, appName)
BuildSortedOptionsTable(group, keySort, opts, options, path, appName) BuildSortedOptionsTable(group, keySort, opts, options, path, appName)
for i = 1, #keySort do for i = 1, getn(keySort) do
local k = keySort[i] local k = keySort[i]
local v = opts[k] local v = opts[k]
if v.type == "group" then if v.type == "group" then
path[#path+1] = k path[getn(path)+1] = k
local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false) local inline = pickfirstset(v.dialogInline,v.guiInline,v.inline, false)
local hidden = CheckOptionHidden(v, options, path, appName) local hidden = CheckOptionHidden(v, options, path, appName)
if not inline and not hidden then if not inline and not hidden then
tinsert(tabs, k) tinsert(tabs, k)
text[k] = GetOptionsMemberValue("name", v, options, path, appName) text[k] = GetOptionsMemberValue("name", v, options, path, appName)
end end
path[#path] = nil path[getn(path)] = nil
end end
end end
+9 -1
View File
@@ -6,6 +6,14 @@
# This repository is actively being fixed and maintained by Bluewhale. # This repository is actively being fixed and maintained by Bluewhale.
## Changelog ## Changelog
- **Fix:** Fixed a Lua 5.0 syntax error in `AceConfigDialog-3.0.lua` where the `#` length operator was used instead of `table.getn`, preventing ElvUI_Config from loading.
- **Fix:** Fixed nil ID formatting crash in Tooltip's SetHyperlink.
- **Fix:** Removed implicit `arg` table memory leaks in high-frequency oUF element updates by replacing varargs (`...`) with static parameters.
- **Fix:** Corrected bug in `Auras.lua` where unused buff icons remained visible on screen due to improper `deadIndex` calculation.
- **Fix:** Fixed quest tracker duplicating entries by overriding `QuestWatch_Update` to deduplicate quests manually.
- **Fix:** Hid the unwanted `MoneyInputFrame` from appearing over `StaticPopup` dialogs (like the UI Reload prompt) by updating custom popup handling.
- **Fix:** Removed false tutorial text referencing a non-existent `/focus` command.
- **Fix:** Corrected Vanilla WoW (1.12) `UnitBuff` and `UnitDebuff` API parsing in `BuffIndicator` and `oUF_RaidDebuffs` to prevent missing textures and improper debuff filtering.
- **Fix:** Removed implicit `arg` table leak in `hooksecurefunc` (varargs `...` issue in Lua 5.0). - **Fix:** Removed implicit `arg` table leak in `hooksecurefunc` (varargs `...` issue in Lua 5.0).
- **Fix:** Stripped invisible UTF-8 BOM from `utf8data.lua` that caused Lua parser errors. - **Fix:** Stripped invisible UTF-8 BOM from `utf8data.lua` that caused Lua parser errors.
- **Fix:** Resolved tooltip crash with ShaguTweaks by reusing existing `backdrop` frames in `CreateBackdrop` instead of unconditionally overwriting them. - **Fix:** Resolved tooltip crash with ShaguTweaks by reusing existing `backdrop` frames in `CreateBackdrop` instead of unconditionally overwriting them.
@@ -13,7 +21,7 @@
- **Fix:** Added type safety checks to `SetOutside` and `SetInside` to prevent crashes when other addons overwrite frame globals with dummy functions. - **Fix:** Added type safety checks to `SetOutside` and `SetInside` to prevent crashes when other addons overwrite frame globals with dummy functions.
- **Fix:** Added type safety check before calling `SetTexture("")` on Blizzard header frames, preventing crashes when headers are modified by other addons or the custom client. - **Fix:** Added type safety check before calling `SetTexture("")` on Blizzard header frames, preventing crashes when headers are modified by other addons or the custom client.
- **Fix:** Wrapped `SetParent` in `pcall` within `CreateBackdrop` to prevent crashes on non-UI object dummy tables. - **Fix:** Wrapped `SetParent` in `pcall` within `CreateBackdrop` to prevent crashes on non-UI object dummy tables.
- **Fix:** Added graceful `nil` fallbacks to `E:Point`, `E:Size`, `E:Width`, and `E:Height` layout anchors, immunizing the UI against crashes when Turtle WoW or other addons delete elements. - **Fix:** Added graceful `nil` fallbacks to `E:Point`, `E:Size`, `E:Width`, and `E:Height` layout anchors, immunizing the UI against crashes when custom scripts or other addons delete elements.
- **Fix:** Rewrote `Misc.lua` options skinning loops using `pairs()` to resolve Lua 5.0 `attempt to call a nil value` crashes caused by missing options tabs/sliders/checkboxes. - **Fix:** Rewrote `Misc.lua` options skinning loops using `pairs()` to resolve Lua 5.0 `attempt to call a nil value` crashes caused by missing options tabs/sliders/checkboxes.
- **Fix:** Added element existence checks in `Skins.lua` `HandleButton` and `HandleRotateButton` to skip skinning gracefully instead of crashing on `nil`. - **Fix:** Added element existence checks in `Skins.lua` `HandleButton` and `HandleRotateButton` to skip skinning gracefully instead of crashing on `nil`.