[{"data":1,"prerenderedAt":285},["ShallowReactive",2],{"\u002Fprojects\u002Fyoutube-like-shortcut":3,"posts":218},{"id":4,"title":5,"body":6,"description":177,"extension":178,"featured":179,"images":180,"links":186,"meta":190,"navigation":179,"order":191,"path":192,"seo":193,"stack":194,"stats":201,"stem":214,"tag":215,"url":216,"__hash__":217},"projects\u002Fprojects\u002Fyoutube-like-shortcut.md","YouTube Like Shortcut",{"type":7,"value":8,"toc":165},"minimark",[9,14,63,67,72,88,92,106,110,113,117],[10,11,13],"h2",{"id":12},"qué-hace","Qué hace",[15,16,17,30,36,42,51,57],"ul",{},[18,19,20,24,25,29],"li",{},[21,22,23],"strong",{},"Like con una tecla."," Pulsas ",[26,27,28],"code",{},"L"," y la extensión da like al vídeo que estás viendo, sea un Short o un vídeo normal. Si ya le habías dado, lo quita.",[18,31,32,35],{},[21,33,34],{},"Atajo a tu gusto."," Cualquier tecla, con Ctrl, Shift o Alt si quieres. Se cambia desde el popup pulsando la tecla nueva.",[18,37,38,41],{},[21,39,40],{},"No molesta al escribir."," Mientras comentas o buscas, el atajo no hace nada.",[18,43,44,47,48,50],{},[21,45,46],{},"Solo Shorts, si lo prefieres."," Un interruptor para que en los vídeos normales ",[26,49,28],{}," siga avanzando 10 segundos, como siempre en YouTube.",[18,52,53,56],{},[21,54,55],{},"Confirmación opcional."," Un pequeño sonido y un corazón o pulgar flotando sobre el vídeo. Las dos cosas vienen desactivadas.",[18,58,59,62],{},[21,60,61],{},"15 idiomas"," y ningún dato recogido: no hay servidor, ni analítica, ni cuentas.",[10,64,66],{"id":65},"cómo-está-hecho","Cómo está hecho",[68,69,71],"h3",{"id":70},"un-content-script-y-un-popup","Un content script y un popup",[73,74,75,76,79,80,83,84,87],"p",{},"Es una extensión Manifest V3 hecha con ",[21,77,78],{},"WXT"," y TypeScript. Toda la lógica vive en un único content script que se carga en ",[26,81,82],{},"youtube.com",". El popup solo guarda las preferencias en ",[26,85,86],{},"chrome.storage.sync",", y el content script las escucha en vivo: un cambio se aplica sin recargar la pestaña y se sincroniza entre tus equipos.",[68,89,91],{"id":90},"llegar-antes-que-youtube","Llegar antes que YouTube",[73,93,94,95,97,98,101,102,105],{},"En los vídeos normales, ",[26,96,28],{}," ya significa algo en YouTube: avanzar 10 segundos. La extensión escucha el teclado en la ",[21,99,100],{},"fase de captura"," de ",[26,103,104],{},"window",", que va antes que cualquier manejador de la página, y detiene el evento para que el vídeo no salte.",[68,107,109],{"id":108},"encontrar-el-botón-correcto","Encontrar el botón correcto",[73,111,112],{},"YouTube cambia el componente del like según la versión de la interfaz y el ancho de la ventana, y deja en la página variantes ocultas del mismo botón. La extensión prueba cuatro estrategias en orden y solo pulsa un botón que tenga tamaño real en pantalla.",[10,114,116],{"id":115},"problemas-que-resolví","Problemas que resolví",[15,118,119,132,138,144],{},[18,120,121,124,125,128,129,131],{},[21,122,123],{},"El vídeo avanzaba además de recibir el like."," La primera versión escuchaba en ",[26,126,127],{},"document",", y el reproductor ya había avanzado cuando la extensión cancelaba el evento. Lo arreglé pasando a la fase de captura en ",[26,130,104],{},".",[18,133,134,137],{},[21,135,136],{},"Likes que no se registraban en vídeos normales."," Con la reproducción automática, YouTube reconstruye el botón entre vídeo y vídeo y durante un instante no responde. Ahora la extensión espera a que termine la navegación, comprueba después del clic que el like ha entrado y, si no, reintenta una vez.",[18,139,140,143],{},[21,141,142],{},"Un fallo que desaparecía al abrir DevTools."," Al acoplar las herramientas de desarrollo, la ventana se estrecha y YouTube cambia de interfaz. El fallo solo aparecía con cierto ancho, así que para depurarlo había que abrir DevTools en una ventana aparte.",[18,145,146,152,153,156,157,160,161,164],{},[21,147,148,151],{},[26,149,150],{},"offsetParent"," mentía."," Devuelve ",[26,154,155],{},"null"," en elementos con ",[26,158,159],{},"position: fixed",", y algunos layouts de YouTube los usan. Lo sustituí por ",[26,162,163],{},"getBoundingClientRect()",", que distingue también las variantes ocultas.",{"title":166,"searchDepth":167,"depth":167,"links":168},"",2,[169,170,176],{"id":12,"depth":167,"text":13},{"id":65,"depth":167,"text":66,"children":171},[172,174,175],{"id":70,"depth":173,"text":71},3,{"id":90,"depth":173,"text":91},{"id":108,"depth":173,"text":109},{"id":115,"depth":167,"text":116},"Extensión de Chrome que da like al vídeo o Short de YouTube que estás viendo con una tecla, como en TikTok. Atajo configurable con modificadores, modo solo Shorts, sonido y animación opcionales, en 15 idiomas y sin recoger ningún dato.","md",true,[181],{"src":182,"alt":183,"width":184,"height":185},"\u002Fimages\u002Fposts\u002Fyoutube-like-shortcut\u002Fportada.webp","El popup de opciones en tres estados, con la tecla L, con Shift + L recién guardado y con el aviso de reseña",1440,900,[187],{"label":188,"url":189},"Cómo se usa","\u002Fposts\u002Fyoutube-like-shortcut-like-con-una-tecla",{},4,"\u002Fprojects\u002Fyoutube-like-shortcut",{"title":5,"description":177},[78,195,196,197,198,199,200],"TypeScript","Manifest V3","Content Scripts","Chrome Storage (sync)","Web Audio API","Chrome i18n",[202,205,208,211],{"value":203,"label":204},"+240","usuarios",{"value":206,"label":207},"15","idiomas",{"value":209,"label":210},"4","formas de encontrar el botón",{"value":212,"label":213},"0","datos recogidos","projects\u002Fyoutube-like-shortcut","youtube-like-shortcut","https:\u002F\u002Fchromewebstore.google.com\u002Fdetail\u002Fyoutube-like-shortcut\u002Flcpkmnlnllegnfhanjoeeejmnhgpnclm","UkYRKG8LzN_RZ7FyF90kC87NtTvHnaZWvBxWfdGf1GI",[219,228,236,245,251,259,265,272,278],{"title":220,"description":221,"date":222,"path":189,"tags":223,"type":227},"YouTube Like Shortcut: da like con una tecla, como en TikTok","Una extensión de Chrome que da like al vídeo o Short de YouTube que estás viendo al pulsar la L. Cómo se instala, qué opciones tiene y por qué no se dispara mientras escribes.","2026-10-20",[215,224,225,226],"youtube","productividad","proyectos","guia",{"title":229,"description":230,"date":222,"path":231,"tags":232,"type":235},"YouTube Like Shortcut por dentro: pulsar un botón en una web que cambia sin avisar","Cómo una extensión de una sola función llega antes que el reproductor de YouTube, encuentra el botón de like entre variantes ocultas y layouts que cambian con el ancho de la ventana, y se asegura de que el like ha entrado aunque YouTube esté reconstruyendo la página.","\u002Fposts\u002Fyoutube-like-shortcut-por-dentro",[215,224,233,234],"arquitectura","typescript","tecnico",{"title":237,"description":238,"date":239,"path":240,"tags":241,"type":227},"AI Upscaler: amplía imágenes y quita fondos con IA, sin salir de tu navegador","Una extensión de Chrome que amplía imágenes ×2 o ×4 y elimina fondos con inteligencia artificial, todo en tu equipo. Sin subir nada a ningún servidor, sin cuentas y gratis. Qué hace y cómo se usa.","2026-10-19","\u002Fposts\u002Fai-upscaler-imagenes-con-ia-en-tu-navegador",[242,243,244,226],"ai-upscaler","ia","privacidad",{"title":246,"description":247,"date":239,"path":248,"tags":249,"type":235},"AI Upscaler por dentro: dos redes neuronales en una extensión de Chrome","Cómo ejecuta AI Upscaler Real-ESRGAN y U²-Net dentro del navegador con ONNX Runtime Web, por qué la imagen se procesa en mosaicos con margen, qué hubo que parchear en el modelo de quitar fondos y qué obstáculos pone una extensión Manifest V3 a los workers y al WebAssembly.","\u002Fposts\u002Fai-upscaler-por-dentro",[242,243,233,234,250],"vue",{"title":252,"description":253,"date":254,"path":255,"tags":256,"type":227},"ABR Cipher: cifrado seguro, completamente en tu navegador","Una suite de cifrado que no envía nada a ningún servidor. Cifrar textos y archivos, compartir secretos con un enlace que caduca, guardar contraseñas y destruir archivos. Qué hace y cómo se usa.","2026-10-18","\u002Fposts\u002Fabr-cipher-cifrado-en-tu-navegador",[257,258,244,226],"cipher","seguridad",{"title":260,"description":261,"date":254,"path":262,"tags":263,"type":235},"ABR Cipher por dentro: criptografía sin servidor, de la URL al disco","Por qué ABR Cipher solo usa la Web Crypto API, cómo viaja un secreto en el fragmento de una URL, cómo se cifra un archivo de varios GB en el navegador y qué hace falta para destruir un archivo de verdad, con un compañero en Rust que lee NTFS.","\u002Fposts\u002Fabr-cipher-por-dentro",[257,258,233,234,264],"rust",{"title":266,"description":267,"date":254,"path":268,"tags":269,"type":235},"ABReader por dentro: el lector que no encontré, construido a mi medida","Voces neuronales que se ejecutan en el navegador, sincronización entre dispositivos sin servidor y once formatos detrás de un mismo contrato. Las decisiones técnicas de ABReader y por qué las tomé.","\u002Fposts\u002Fabreader-por-dentro",[270,233,234,271],"abreader","nuxt",{"title":273,"description":274,"date":254,"path":275,"tags":276,"type":227},"ABReader: tu biblioteca de libros electrónicos en el navegador","Un lector de libros electrónicos que funciona en el navegador, sin cuentas ni servidores. Qué hace, cómo se usa y cómo probarlo en un minuto.","\u002Fposts\u002Fabreader-tu-biblioteca-en-el-navegador",[270,277,226],"lectura",{"title":279,"description":280,"date":254,"path":281,"tags":282,"type":235},"Cómo construí este blog: estático, sin servidor y sin coste de hosting","Por qué elegí Nuxt y Markdown en lugar de WordPress, cómo separo el código privado del sitio publicado y qué se rompió en el primer despliegue.","\u002Fposts\u002Farquitectura-de-este-blog",[271,250,283,284],"devops","meta",1792512646042]