MediaWiki:Common.js: различия между версиями
Пока нет Метка: ручная отмена |
Для Rutube |
||
| Строка 113: | Строка 113: | ||
}; | }; | ||
/* Запускаем после загрузки ВК-видео DOM */ | /* Запускаем после загрузки ВК-видео DOM */ | ||
if (document.readyState === 'loading') { | if (document.readyState === 'loading') { | ||
document.addEventListener('DOMContentLoaded', window.vkVideoInit); | document.addEventListener('DOMContentLoaded', window.vkVideoInit); | ||
| Строка 119: | Строка 119: | ||
window.vkVideoInit(); | window.vkVideoInit(); | ||
} | } | ||
/* Функция для вставки Rutube-видео на страницу для шаблона Rutube */ | |||
$(document).ready(function() { | |||
'use strict'; | |||
function RutubePlayerManager() { | |||
this.players = []; | |||
this.init(); | |||
} | |||
RutubePlayerManager.prototype = { | |||
init: function() { | |||
this.findPlayers(); | |||
this.setupEventListeners(); | |||
this.loadPreviewImages(); | |||
}, | |||
findPlayers: function() { | |||
var playerElements = document.querySelectorAll('.rutube-player'); | |||
playerElements.forEach(function(element) { | |||
var player = { | |||
element: element, | |||
videoId: element.dataset.videoId, | |||
width: element.dataset.width || '560', | |||
height: element.dataset.height || '315', | |||
state: 'initial' // initial, loading, playing, error | |||
}; | |||
this.players.push(player); | |||
this.setupPlayer(player); | |||
}.bind(this)); | |||
}, | |||
setupPlayer: function(player) { | |||
var preview = player.element.querySelector('.rutube-preview'); | |||
var playButton = player.element.querySelector('.rutube-play-button'); | |||
if (preview && playButton) { | |||
preview.addEventListener('click', function(e) { | |||
if (e.target !== playButton) { | |||
this.activatePlayer(player); | |||
} | |||
}.bind(this)); | |||
playButton.addEventListener('click', function(e) { | |||
e.stopPropagation(); | |||
this.activatePlayer(player); | |||
}.bind(this)); | |||
} | |||
}, | |||
loadPreviewImages: function() { | |||
this.players.forEach(function(player) { | |||
this.loadPreviewImage(player); | |||
}.bind(this)); | |||
}, | |||
loadPreviewImage: function(player) { | |||
var img = player.element.querySelector('.rutube-preview-image'); | |||
if (!img) return; | |||
// пытаемся получить превью через oEmbed или аналогичный метод | |||
var previewUrl = this.getPreviewUrl(player.videoId); | |||
if (previewUrl) { | |||
img.src = previewUrl; | |||
img.onload = function() { | |||
player.element.classList.add('preview-loaded'); | |||
}; | |||
img.onerror = function() { | |||
this.fallbackToPlaceholder(player); | |||
}.bind(this); | |||
} else { | |||
this.fallbackToPlaceholder(player); | |||
} | |||
}, | |||
getPreviewUrl: function(videoId) { | |||
// у Rutube нет стабильного API для превью | |||
// поэтому используем заглушку или юзаем через oEmbed | |||
return ''; // оставляем пустым или делаем свой placeholder | |||
}, | |||
fallbackToPlaceholder: function(player) { | |||
var preview = player.element.querySelector('.rutube-preview'); | |||
if (preview) { | |||
preview.style.display = 'none'; | |||
} | |||
player.element.classList.add('preview-failed'); | |||
}, | |||
activatePlayer: function(player) { | |||
if (player.state === 'playing') return; | |||
player.state = 'loading'; | |||
player.element.classList.add('loading'); | |||
this.createEmbedFrame(player); | |||
}, | |||
createEmbedFrame: function(player) { | |||
var embedContainer = player.element.querySelector('.rutube-player-embed'); | |||
if (!embedContainer) return; | |||
var iframe = document.createElement('iframe'); | |||
iframe.src = 'https://rutube.ru/play/embed/' + player.videoId; | |||
iframe.width = '100%'; | |||
iframe.height = '100%'; | |||
iframe.frameBorder = '0'; | |||
iframe.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture'; | |||
iframe.allowFullscreen = true; | |||
iframe.loading = 'lazy'; | |||
iframe.onload = function() { | |||
player.state = 'playing'; | |||
player.element.classList.remove('loading'); | |||
player.element.classList.add('playing'); | |||
this.onPlayerReady(player); | |||
}.bind(this); | |||
iframe.onerror = function() { | |||
this.handlePlayerError(player); | |||
}.bind(this); | |||
embedContainer.appendChild(iframe); | |||
embedContainer.style.display = 'block'; | |||
}, | |||
onPlayerReady: function(player) { | |||
console.log('Rutube player ready:', player.videoId); | |||
// можно добавить дополнительные действия после загрузки | |||
}, | |||
handlePlayerError: function(player) { | |||
player.state = 'error'; | |||
player.element.classList.remove('loading'); | |||
var errorHtml = '<div class="rutube-error">' + | |||
'<p>Не удалось загрузить видео</p>' + | |||
'<a href="https://rutube.ru/video/' + player.videoId + '/" target="_blank">' + | |||
'Открыть на Rutube</a>' + | |||
'</div>'; | |||
player.element.innerHTML = errorHtml; | |||
}, | |||
setupEventListeners: function() { | |||
// глобальные обработчики, если нужны | |||
} | |||
}; | |||
/* Инициализация при загрузке DOM */ | |||
document.addEventListener('DOMContentLoaded', function() { | |||
window.rutubeManager = new RutubePlayerManager(); | |||
}); | |||
/ * Интеграция с MediaWiki для динамического контента */ | |||
if (typeof mw !== 'undefined') { | |||
mw.hook('wikipage.content').add(function($content) { | |||
if ($content.find('.rutube-player').length && window.rutubeManager) { | |||
window.rutubeManager.init(); | |||
} | |||
}); | |||
} | |||
/* Fallback для очень старых браузеров */ | |||
if (!document.querySelectorAll) { | |||
var players = document.getElementsByClassName('rutube-player'); | |||
for (var i = 0; i < players.length; i++) { | |||
var link = document.createElement('a'); | |||
link.href = 'https://rutube.ru/video/' + players[i].dataset.videoId + '/'; | |||
link.textContent = 'Смотреть видео на Rutube'; | |||
link.style.display = 'block'; | |||
link.style.padding = '20px'; | |||
link.style.textAlign = 'center'; | |||
players[i].innerHTML = ''; | |||
players[i].appendChild(link); | |||
} | |||
} | |||
}); | |||