Files

230 lines
8.6 KiB
Lua

local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local gfind = string.gmatch or string.gfind
local GetUnitData = ShaguTweaks.GetUnitData
local GetExpansion = ShaguTweaks.GetExpansion
local cmatch = ShaguTweaks.cmatch
local rgbhex = ShaguTweaks.rgbhex
local strsplit = ShaguTweaks.strsplit
local module = ShaguTweaks:register({
title = T["Chat Hyperlinks"],
description = T["Copy website URLs from the chat, transforms CLINKs into real items and handles quest and player links."],
expansions = { ["vanilla"] = true, ["tbc"] = true },
category = T["Social & Chat"],
enabled = true,
})
local URLPattern = {
WWW = {
["rx"]=" (www%d-)%.([_A-Za-z0-9-]+)%.(%S+)%s?",
["fm"]="%s.%s.%s"},
PROTOCOL = {
["rx"]=" (%a+)://(%S+)%s?",
["fm"]="%s://%s"},
EMAIL = {
["rx"]=" ([_A-Za-z0-9-%.:]+)@([_A-Za-z0-9-]+)(%.)([_A-Za-z0-9-]+%.?[_A-Za-z0-9-]*)%s?",
["fm"]="%s@%s%s%s"},
PORTIP = {
["rx"]=" (%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?):(%d%d?%d?%d?%d?)%s?",
["fm"]="%s.%s.%s.%s:%s"},
IP = {
["rx"]=" (%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%s?",
["fm"]="%s.%s.%s.%s"},
SHORTURL = {
["rx"]=" (%a+)%.(%a+)/(%S+)%s?",
["fm"]="%s.%s/%s"},
URLIP = {
["rx"]=" ([_A-Za-z0-9-]+)%.([_A-Za-z0-9-]+)%.(%S+)%:([_0-9-]+)%s?",
["fm"]="%s.%s.%s:%s"},
URL = {
["rx"]=" ([_A-Za-z0-9-]+)%.([_A-Za-z0-9-]+)%.(%S+)%s?",
["fm"]="%s.%s.%s"},
}
local function FormatLink(formatter,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
if not (formatter and a1) then return end
local newtext = string.format(formatter,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
-- check the last capture index for consecutive trailing dots (invalid top level domain)
local invalidtld
for _, arg in pairs({a10,a9,a8,a7,a6,a5,a4,a3,a2,a1}) do
if arg then
invalidtld = string.find(arg, "(%.%.)$")
break
end
end
if (invalidtld) then return newtext end
if formatter == URLPattern.EMAIL.fm then -- email parser
local colon = string.find(a1,":")
if (colon) and string.len(a1) > colon then
if not (string.sub(a1,1,6) == "mailto") then
local prefix,address = string.sub(newtext,1,colon),string.sub(newtext,colon+1)
return string.format(" %s|cffccccff|Hurl:%s|h[%s]|h|r ",prefix,address,address)
end
end
end
return " |cffccccff|Hurl:" .. newtext .. "|h[" .. newtext .. "]|h|r "
end
local URLFuncs = {
["WWW"] = function(a1,a2,a3) return FormatLink(URLPattern.WWW.fm,a1,a2,a3) end,
["PROTOCOL"] = function(a1,a2) return FormatLink(URLPattern.PROTOCOL.fm,a1,a2) end,
["EMAIL"] = function(a1,a2,a3,a4) return FormatLink(URLPattern.EMAIL.fm,a1,a2,a3,a4) end,
["PORTIP"] = function(a1,a2,a3,a4,a5) return FormatLink(URLPattern.PORTIP.fm,a1,a2,a3,a4,a5) end,
["IP"] = function(a1,a2,a3,a4) return FormatLink(URLPattern.IP.fm,a1,a2,a3,a4) end,
["SHORTURL"] = function(a1,a2,a3) return FormatLink(URLPattern.SHORTURL.fm,a1,a2,a3) end,
["URLIP"] = function(a1,a2,a3,a4) return FormatLink(URLPattern.URLIP.fm,a1,a2,a3,a4) end,
["URL"] = function(a1,a2,a3) return FormatLink(URLPattern.URL.fm,a1,a2,a3) end,
}
local function HandleLink(text)
local URLPattern = URLPattern
text = string.gsub (text, URLPattern.WWW.rx, URLFuncs.WWW)
text = string.gsub (text, URLPattern.PROTOCOL.rx, URLFuncs.PROTOCOL)
text = string.gsub (text, URLPattern.EMAIL.rx, URLFuncs.EMAIL)
text = string.gsub (text, URLPattern.PORTIP.rx, URLFuncs.PORTIP)
text = string.gsub (text, URLPattern.IP.rx, URLFuncs.IP)
text = string.gsub (text, URLPattern.SHORTURL.rx, URLFuncs.SHORTURL)
text = string.gsub (text, URLPattern.URLIP.rx, URLFuncs.URLIP)
text = string.gsub (text, URLPattern.URL.rx, URLFuncs.URL)
return text
end
local CopyLinkDialog = CreateFrame("Frame", "ShaguTweaksURLCopy", UIParent)
CopyLinkDialog:Hide()
CopyLinkDialog:SetWidth(300)
CopyLinkDialog:SetHeight(90)
CopyLinkDialog:SetFrameStrata("FULLSCREEN")
CopyLinkDialog:SetPoint("CENTER", 0, 0)
CopyLinkDialog:SetBackdrop({
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true, tileSize = 32, edgeSize = 32,
insets = { left = 11, right = 12, top = 12, bottom = 11 }
})
CopyLinkDialog:SetScript("OnShow", function()
this.text:HighlightText()
end)
CopyLinkDialog.text = CreateFrame("EditBox", "ShaguTweaksURLCopyEditBox", CopyLinkDialog)
CopyLinkDialog.text:SetTextColor(1,.8,0)
CopyLinkDialog.text:SetJustifyH("CENTER")
CopyLinkDialog.text:SetBackdrop({
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 16, edgeSize = 16,
insets = { left = 3, right = 3, top = 3, bottom = 3 }
})
CopyLinkDialog.text:SetBackdropColor(0,0,0,.8)
CopyLinkDialog.text:SetBackdropBorderColor(.8,.8,.8,1)
CopyLinkDialog.text:SetWidth(260)
CopyLinkDialog.text:SetHeight(25)
CopyLinkDialog.text:SetPoint("TOP", CopyLinkDialog, "TOP", 0, -20)
CopyLinkDialog.text:SetFontObject(GameFontNormal)
CopyLinkDialog.text:SetScript("OnEscapePressed", function(self)
CopyLinkDialog:Hide()
end)
CopyLinkDialog.text:SetScript("OnEditFocusLost", function(self)
CopyLinkDialog:Hide()
end)
CopyLinkDialog.close = CreateFrame("Button", "ShaguTweaksURLCopyClose", CopyLinkDialog, "UIPanelButtonTemplate")
CopyLinkDialog.close:SetPoint("BOTTOMRIGHT", CopyLinkDialog, "BOTTOMRIGHT", -20, 20)
CopyLinkDialog.close:SetWidth(70)
CopyLinkDialog.close:SetHeight(18)
CopyLinkDialog.close:SetText(CLOSE)
CopyLinkDialog.close:SetScript("OnClick", function()
CopyLinkDialog:Hide()
end)
CopyLinkDialog.CopyText = function(text)
CopyLinkDialog.text:SetText(text)
CopyLinkDialog:Show()
end
module.enable = function(self)
local HookSetItemRef = SetItemRef
function _G.SetItemRef(link, text, button)
local questlink, _, quest_id = string.find(link, "quest:(%d+):.*")
local playerlink = strsub(link, 1, 6) == "player"
-- don't overwrite other addons questlink hook
if ShaguQuest or pfQuest or Questie then questlink = nil end
if (strsub(link, 1, 3) == "url") then
if string.len(link) > 4 and string.sub(link,1,4) == "url:" then
CopyLinkDialog.CopyText(string.sub(link,5, string.len(link)))
end
return
elseif questlink then
local _, _, quest_title = string.find(text, ".*|h%[(.*)%]|h.*")
if quest_title then
HideUIPanel(ItemRefTooltip)
ShowUIPanel(ItemRefTooltip)
ItemRefTooltip:SetOwner(UIParent, "ANCHOR_PRESERVE")
ItemRefTooltip:AddLine(quest_title, 1,1,0)
ItemRefTooltip:AddDoubleLine("Quest ID", quest_id, .6, .6, .6, 1, 1, 1)
ItemRefTooltip:Show()
end
return
elseif playerlink then
local name = strsub(link, 8)
if ( name and (strlen(name) > 0) ) then
local name, _ = strsplit(":", name)
name = gsub(name, "([^%s]*)%s+([^%s]*)%s+([^%s]*)", "%3")
name = gsub(name, "([^%s]*)%s+([^%s]*)", "%2")
if IsShiftKeyDown() and ChatFrameEditBox:IsVisible() then
ChatFrameEditBox:Insert("|cffffffff|Hplayer:"..name.."|h["..name.."]|h|r")
return
end
end
end
HookSetItemRef(link, text, button)
end
do -- add class colors to chat
for i=1,NUM_CHAT_WINDOWS do
local isCombat = 0
if _G["ChatFrame"..i] and _G["ChatFrame"..i].messageTypeList then
for _, msg in pairs(_G["ChatFrame"..i].messageTypeList) do
if strfind(msg, "SPELL", 1) or strfind(msg, "COMBAT", 1) then
isCombat = isCombat + 1
end
end
end
if _G["ChatFrame"..i] and not _G["ChatFrame"..i].HookAddMessage and isCombat < 5 then
_G["ChatFrame"..i].HookAddMessage = _G["ChatFrame"..i].AddMessage
_G["ChatFrame"..i].AddMessage = function(frame, text, a1, a2, a3, a4, a5)
if text then
-- Remove prat CLINKs
text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r") -- tbc
text = gsub(text, "{CLINK:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r") -- vanilla
-- Remove chatter CLINKs
text = gsub(text, "{CLINK:item:(%x+):([%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-:[%d-]-):([^}]-)}", "|c%1|Hitem:%2|h[%3]|h|r")
text = gsub(text, "{CLINK:enchant:(%x+):([%d-]-):([^}]-)}", "|c%1|Henchant:%2|h[%3]|h|r")
text = gsub(text, "{CLINK:spell:(%x+):([%d-]-):([^}]-)}", "|c%1|Hspell:%2|h[%3]|h|r")
text = gsub(text, "{CLINK:quest:(%x+):([%d-]-):([%d-]-):([^}]-)}", "|c%1|Hquest:%2:%3|h[%4]|h|r")
-- Detect URLs
text = HandleLink(text)
end
_G["ChatFrame"..i].HookAddMessage(frame, text, a1, a2, a3, a4, a5)
end
end
end
end
end