Foro: permitir enlaces de wowhead en los posts (tooltip, color, icono)
Al escribir un post se puede pegar un enlace de wowhead y sale con su tooltip, color por calidad e icono, igual que en el resto de la web (lo pinta el script global tooltips.js del layout, que actúa sobre los enlaces a wowhead.com y sobre data-wowhead). El saneador de posts (lib/forum-sanitize.ts) lo impedía; ahora: - conserva data-wowhead (en <a> y <span>) y class, que el tooltip necesita; - normaliza los enlaces de wowhead a la rama /wotlk/ manteniendo el subdominio (www=inglés, es=español…), que es lo que fija el idioma del tooltip. Así un enlace pegado en retail muestra igualmente el tooltip de WotLK; - abre esos enlaces en pestaña nueva, como los del resto del sitio. Los enlaces que no son de wowhead se quedan igual. Verificado en producción: un enlace retail pegado en un post se guarda como .../wotlk/item=… y la página del tema carga tooltips.js. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,25 @@
|
|||||||
import sanitizeHtml from 'sanitize-html'
|
import sanitizeHtml from 'sanitize-html'
|
||||||
|
|
||||||
|
// Tipos de entidad de wowhead que aceptan tooltip (para normalizar el enlace).
|
||||||
|
const WOWHEAD_TYPES = 'item|spell|quest|npc|achievement|object|faction|currency|itemset|title'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normaliza un enlace de wowhead para que el tooltip salga en la rama WotLK.
|
||||||
|
* - Mantiene el subdominio (www=inglés, es=español…), que es lo que fija el idioma
|
||||||
|
* del tooltip cuando no hay data-wowhead.
|
||||||
|
* - Fuerza el segmento `/wotlk/` (si el usuario pega un enlace retail, el tooltip
|
||||||
|
* saldría de retail; así siempre es WotLK).
|
||||||
|
* Devuelve el href tal cual si no reconoce un `<tipo>=<id>`.
|
||||||
|
*/
|
||||||
|
function normalizeWowheadHref(href: string): string {
|
||||||
|
const m = /^https?:\/\/([a-z]+)\.wowhead\.com\/.*?\b(?:wotlk\/)?(?:(item|spell|quest|npc|achievement|object|faction|currency|itemset|title)=(\d+))/i.exec(
|
||||||
|
href,
|
||||||
|
)
|
||||||
|
if (!m) return href
|
||||||
|
const [, sub, type, id] = m
|
||||||
|
return `https://${sub}.wowhead.com/wotlk/${type.toLowerCase()}=${id}`
|
||||||
|
}
|
||||||
|
|
||||||
// Misma allowlist que forum/sanitize.py (nh3) para el HTML de los mensajes.
|
// Misma allowlist que forum/sanitize.py (nh3) para el HTML de los mensajes.
|
||||||
export function cleanPostHtml(html: string): string {
|
export function cleanPostHtml(html: string): string {
|
||||||
if (!html) return ''
|
if (!html) return ''
|
||||||
@@ -13,16 +33,26 @@ export function cleanPostHtml(html: string): string {
|
|||||||
'table', 'thead', 'tbody', 'tr', 'th', 'td',
|
'table', 'thead', 'tbody', 'tr', 'th', 'td',
|
||||||
],
|
],
|
||||||
allowedAttributes: {
|
allowedAttributes: {
|
||||||
a: ['href', 'title', 'target'],
|
// data-wowhead + class dejan que los enlaces de wowhead muestren tooltip,
|
||||||
|
// color por calidad e icono (los pinta el script global tooltips.js del layout).
|
||||||
|
a: ['href', 'title', 'target', 'data-wowhead', 'class'],
|
||||||
img: ['src', 'alt', 'title', 'width', 'height'],
|
img: ['src', 'alt', 'title', 'width', 'height'],
|
||||||
span: ['style'],
|
span: ['style', 'data-wowhead'],
|
||||||
div: ['style'],
|
div: ['style'],
|
||||||
td: ['colspan', 'rowspan'],
|
td: ['colspan', 'rowspan'],
|
||||||
th: ['colspan', 'rowspan'],
|
th: ['colspan', 'rowspan'],
|
||||||
},
|
},
|
||||||
allowedSchemes: ['http', 'https', 'mailto'],
|
allowedSchemes: ['http', 'https', 'mailto'],
|
||||||
transformTags: {
|
transformTags: {
|
||||||
a: sanitizeHtml.simpleTransform('a', { rel: 'noopener noreferrer nofollow' }),
|
a: (tagName, attribs) => {
|
||||||
|
const out: Record<string, string> = { ...attribs, rel: 'noopener noreferrer nofollow' }
|
||||||
|
if (out.href && /\.wowhead\.com\//i.test(out.href)) {
|
||||||
|
out.href = normalizeWowheadHref(out.href)
|
||||||
|
// abrir en pestaña nueva, como los enlaces de wowhead del resto del sitio
|
||||||
|
out.target = '_blank'
|
||||||
|
}
|
||||||
|
return { tagName, attribs: out }
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user