Branding

Space script that applies Sneakycheese branding to this public site: swaps the favicon and pins the page title. Assets live in assets/branding/ (served under /.fs/).

The title is pinned with a MutationObserver because SilverBullet rewrites document.title itself on every page load and restore, which can land after our listeners fire.

-- priority: 100
local function setFavicon()
  local doc = js.window.document
  if doc.getElementById("sb-brand-favicon") ~= nil then
    return
  end
  local link = doc.createElement("link")
  link.id = "sb-brand-favicon"
  link.rel = "icon"
  link.type = "image/svg+xml"
  link.href = "/.fs/assets/branding/favicon.svg"
  doc.head.appendChild(link)
  local apple = doc.querySelector("link[rel=apple-touch-icon]")
  if apple ~= nil then
    apple.href = "/.fs/assets/branding/favicon-64.png"
  end
end

local function pinTitle()
  local doc = js.window.document
  if doc.title ~= "Sneakycheese" then
    doc.title = "Sneakycheese"
  end
end

local function applySneakycheeseBranding()
  local ok, err = pcall(function()
    setFavicon()
    pinTitle()
    if js.window.__sbBrandWatcher ~= true then
      js.window.__sbBrandWatcher = true
      -- re-pin whenever SilverBullet rewrites the title itself
      local observer = js.new(js.window.MutationObserver, function(_mutations)
        pinTitle()
      end)
      observer.observe(js.window.document.head, { childList = true })
      local titleEl = js.window.document.querySelector("title")
      if titleEl ~= nil then
        observer.observe(titleEl, { childList = true, characterData = true, subtree = true })
      end
      -- belt and braces: a few delayed re-applies
      for _, ms in ipairs({ 250, 1000, 3000 }) do
        js.window.setTimeout(function()
          setFavicon()
          pinTitle()
        end, ms)
      end
    end
  end)
  if not ok then
    js.log("branding failed: " .. tostring(err))
  end
end

event.listen { name = "editor:init", run = applySneakycheeseBranding }
event.listen { name = "editor:pageLoaded", run = applySneakycheeseBranding }