MediaWiki:Common.js: различия между версиями

Нет описания правки
Метка: ручная отмена
попытка оптимизации
Строка 121: Строка 121:
(function() {
(function() {
     'use strict';
     'use strict';
    function sanitizeVideoId(videoId) {
        if (typeof videoId !== 'string') return null;
        // Разрешаем только буквы, цифры и дефисы/подчеркивания
        return videoId.match(/^[a-zA-Z0-9_-]+$/) ? videoId : null;
    }
   
    function sanitizeDimension(dim, defaultValue, maxValue) {
        if (typeof dim !== 'string') return defaultValue;
        const cleanDim = dim.match(/^(100|\d{1,2})%$|^\d+$/) ? dim : defaultValue;
       
        if (cleanDim.match(/^\d+$/)) {
            const numValue = parseInt(cleanDim, 10);
            return numValue <= maxValue ? cleanDim : defaultValue;
        }
       
        return cleanDim;
    }
      
      
     function initRutubeEmbeds() {
     function initRutubeEmbeds() {
Строка 126: Строка 144:
          
          
         embeds.forEach(function(embed) {
         embeds.forEach(function(embed) {
             var videoId = embed.getAttribute('data-video-id');
             var rawVideoId = embed.getAttribute('data-video-id');
             var width = embed.getAttribute('data-width') || '560';
             var videoId = sanitizeVideoId(rawVideoId);
            var height = embed.getAttribute('data-height') || '315';
              
              
             if (videoId) {
             if (!videoId) {
                 var iframe = document.createElement('iframe');
                 console.warn('Invalid video ID:', rawVideoId);
                iframe.src = 'https://rutube.ru/play/embed/' + videoId;
                iframe.width = width;
                iframe.height = height;
                iframe.frameBorder = '0';
                iframe.allow = 'autoplay; fullscreen; picture-in-picture';
                iframe.allowFullscreen = true;
                iframe.style.border = 'none';
                iframe.style.display = 'block';
                iframe.style.maxWidth = '100%';
               
                embed.appendChild(iframe);
                 embed.setAttribute('data-processed', 'true');
                 embed.setAttribute('data-processed', 'true');
                return;
            }
           
            var width = sanitizeDimension(embed.getAttribute('data-width'), '560', 2000);
            var height = sanitizeDimension(embed.getAttribute('data-height'), '315', 2000);
           
            var iframe = document.createElement('iframe');
           
            iframe.src = 'https://rutube.ru/play/embed/' + encodeURIComponent(videoId);
            iframe.width = width;
            iframe.height = height;
            iframe.frameBorder = '0';
            iframe.allow = 'autoplay; fullscreen; picture-in-picture';
            iframe.allowFullscreen = true;
            iframe.style.border = 'none';
            iframe.style.display = 'block';
            iframe.style.maxWidth = '100%';
           
            iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-presentation allow-popups');
            iframe.setAttribute('referrerpolicy', 'strict-origin-when-cross-origin');
           
            while (embed.firstChild) {
                embed.removeChild(embed.firstChild);
             }
             }
           
            embed.appendChild(iframe);
            embed.setAttribute('data-processed', 'true');
         });
         });
     }
     }
   
 
     if (document.readyState === 'loading') {
     if (document.readyState === 'loading') {
         document.addEventListener('DOMContentLoaded', initRutubeEmbeds);
         document.addEventListener('DOMContentLoaded', initRutubeEmbeds);
Строка 153: Строка 185:
         initRutubeEmbeds();
         initRutubeEmbeds();
     }
     }
 
   
     if (typeof mw !== 'undefined' && mw.hook) {
     if (typeof mw !== 'undefined' && mw.hook) {
         mw.hook('wikipage.content').add(initRutubeEmbeds);
         mw.hook('wikipage.content').add(initRutubeEmbeds);
     }
     }
   
})();
})();