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 | var rawVideoId = embed.getAttribute('data-video-id'); | ||
var | var videoId = sanitizeVideoId(rawVideoId); | ||
if (videoId) { | if (!videoId) { | ||
console.warn('Invalid video ID:', rawVideoId); | |||
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); | ||
} | } | ||
})(); | })(); | ||