Files
ClassicAPI/AddOns/!!!ClassicAPI/APIDocumentation/APIDocumentation_Bootstrap.lua
T
Brues 108a91a843 feat(api): describe the API in the code, browse it with /classicapi
docs/API.md is 18.7k lines and its anchors are signature slugs, so editing a
signature breaks the 281 internal and 88 README links into it. Blizzard
solved the same problem by shipping the API as data plus a browser addon,
and warcraft.wiki.gg renders those same tables. One set of descriptors can
feed all three.

Each registration now carries one next to it: typed arguments and returns,
nilability, defaults, and a sentence. Events, enumerations and returned table
shapes are described the same way. No Script_* body changed.

Game.h gains namespace Game::Doc (Field with Req/Opt/Vararg, FieldList,
Function, Method, Structure, Event) and a trailing descriptor argument on all
six Game::Lua::Register* plus Event::Custom::AutoReserve.

api/Documentation.cpp records every registration on the first pass of each
Lua state and seals it, so /reload re-registers but records nothing and the
environment comes from which pass saw the name. Export is lazy: nothing is
materialized until C_APIDocumentation.GetSystem asks for one system, because
eager export would build thousands of tables per reload for a slash command.
_classicapi_UndocumentedAPI lists what still has no descriptor.

AddOns/!!!ClassicAPI/APIDocumentation/ ports Blizzard_APIDocumentation's eight
files. Named /classicapi, not /api: the browser holds only what ClassicAPI
adds, so /api would have implied the whole 1.12 surface. Two deliberate
differences from the retail source, both noted in the file headers: a system
search also matches its namespace, since that is the name people type; and an
undocumented function says so, because an empty signature otherwise reads as
a real one.

LinkUtil gains the SetItemRef to LinkUtil.ProcessLink dispatch. That handler
registry was dead code; a new link type now registers a handler instead of
stacking another SetItemRef override. Also defines assertsafe there, which
was undefined and only mattered once the function went live.

Documented: the C_Spell and C_SpellBook surface, the spell globals, both
spellbook enumerations, the 13 UNIT_SPELLCAST_* events, GameTooltip as the
widget-method example and C_Glue as the glue and mixed-environment example.
66 of 692 function registrations. tools/New-ApiDocSkeletons.ps1 emits
paste-ready skeletons to make the rest of the sweep tractable.

Verified in game: the browser lists, searches, and prints detail; links
render and click through; right-click copies and shift-click dumps.
2026-09-12 23:20:46 -05:00

67 lines
2.5 KiB
Lua

-- Backport of Blizzard_APIDocumentation/Blizzard_APIDocumentation_Bootstrap.lua
-- to vanilla 1.12 / Lua 5.0, plus the `/api` command and `api` link handler
-- that retail keeps in Blizzard_ChatFrameBase and Blizzard_UIPanels_Game.
--
-- Implementation differences from the retail source:
-- - Retail loads a generated data addon on demand
-- (LoadAddOnWithErrorHandling). ClassicAPI keeps the documentation in the
-- DLL instead, so APIDocumentation_LoadUI reads it through
-- C_APIDocumentation and feeds each system to AddDocumentationTable. The
-- load still happens on first use, so a session that never types /api
-- builds no tables at all.
-- - IsModifiedClick does not exist on this client. CHATLINK is Shift by
-- default, so a shift-click stands in for it.
-- - Lua 5.0 has no length operator (#); table.getn(t) gives the count.
local loaded = false;
-- Fetches every documented system from the DLL. Returns true once the
-- documentation is in place, false when the DLL is absent (the addon can be
-- installed on its own).
function APIDocumentation_LoadUI()
if loaded then
return true;
end
-- Latch BEFORE the fetch: a system table the browser chokes on must not
-- raise the same error on every later /api.
loaded = true;
if not C_APIDocumentation then
APIDocumentation:WriteLine("API documentation is not available (C_APIDocumentation is missing).");
return false;
end
-- ipairs, not a length call: it walks 1..nil whatever the table's internal
-- shape, which is how every other consumer reads an array the DLL built.
for i, name in ipairs(C_APIDocumentation.GetSystems()) do
local system = C_APIDocumentation.GetSystem(name);
if system then
APIDocumentation:AddDocumentationTable(system);
end
end
return true;
end
-- Retail calls this `/api`. Here the browser holds only what ClassicAPI adds,
-- not the 1.12 API the client already ships, so it is named for what it
-- documents. `/capi` is the short form.
SLASH_CLASSICAPI1 = "/classicapi";
SLASH_CLASSICAPI2 = "/capi";
SlashCmdList["CLASSICAPI"] = function(msg)
APIDocumentation_LoadUI();
APIDocumentation:HandleSlashCommand(msg or "");
end
LinkUtil.RegisterLinkHandler(LinkTypes.APIDocumentation, function(link, text, linkData, contextData)
APIDocumentation_LoadUI();
local command = APIDocumentation.Commands.Default;
if contextData and contextData.button == "RightButton" then
command = APIDocumentation.Commands.CopyAPI;
elseif IsShiftKeyDown() then
command = APIDocumentation.Commands.OpenDump;
end
APIDocumentation:HandleAPILink(link, command);
end);