From a174f2474ff25d614c8f7b748c59e0cb1f34682b Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Wed, 23 Nov 2016 16:17:15 +0800 Subject: [PATCH] MDL-57101 media_videojs: Set-up player on dynamically loaded content --- filter/mediaplugin/filter.php | 18 +++++++ media/classes/manager.php | 14 ++++++ media/classes/player.php | 11 +++++ media/player/videojs/amd/src/loader.js | 56 ++++++++++++++++++++++ media/player/videojs/classes/plugin.php | 64 ++++++++++--------------- 5 files changed, 125 insertions(+), 38 deletions(-) create mode 100644 media/player/videojs/amd/src/loader.js diff --git a/filter/mediaplugin/filter.php b/filter/mediaplugin/filter.php index 9e4ed55f600..e98f6d9d16e 100644 --- a/filter/mediaplugin/filter.php +++ b/filter/mediaplugin/filter.php @@ -43,6 +43,24 @@ class filter_mediaplugin extends moodle_text_filter { /** @var bool True if currently filtering trusted text */ private $trusted; + /** + * Setup page with filter requirements and other prepare stuff. + * + * @param moodle_page $page The page we are going to add requirements to. + * @param context $context The context which contents are going to be filtered. + */ + public function setup($page, $context) { + // This only requires execution once per request. + static $jsinitialised = false; + if ($jsinitialised) { + return; + } + $jsinitialised = true; + + $mediamanager = core_media_manager::instance(); + $mediamanager->setup($page); + } + public function filter($text, array $options = array()) { global $CFG, $PAGE; diff --git a/media/classes/manager.php b/media/classes/manager.php index 40e7777a2ec..e502d5f7bea 100644 --- a/media/classes/manager.php +++ b/media/classes/manager.php @@ -109,6 +109,20 @@ class core_media_manager { return self::$instance; } + /** + * Setup page requirements. + * + * This should must only be called once per page request. + * + * @param moodle_page $page The page we are going to add requirements to. + */ + public function setup($page) { + $players = $this->get_players(); + foreach ($players as $player) { + $player->setup($page); + } + } + /** * Resets cached singleton instance. To be used after $CFG->media_plugins_sortorder is modified */ diff --git a/media/classes/player.php b/media/classes/player.php index f7d50ada966..55cd8e35dd9 100644 --- a/media/classes/player.php +++ b/media/classes/player.php @@ -253,4 +253,15 @@ abstract class core_media_player { $height = $CFG->media_default_height; } } + + /** + * Setup page requirements. + * + * @param moodle_page $page The page we are going to add requirements to. + * @since Moodle 3.2 + */ + public function setup($page) { + // Override is need be. + } + } diff --git a/media/player/videojs/amd/src/loader.js b/media/player/videojs/amd/src/loader.js new file mode 100644 index 00000000000..c4a5f7cd426 --- /dev/null +++ b/media/player/videojs/amd/src/loader.js @@ -0,0 +1,56 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * Video JS loader. + * + * This takes care of applying the filter on content which was dynamically loaded. + * + * @package media_videojs + * @copyright 2016 Frédéric Massart - FMCorz.net + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define(['jquery', 'media_videojs/video'], function($, videojs) { + + /** + * Set-up. + * + * Adds the listener for the event to then notify video.js. + */ + var setUp = function() { + $(document).on(M.core.event.FILTER_CONTENT_UPDATED, notifyVideoJS); + }; + + /** + * Notify video.js of new nodes. + * + * @param {Event} e The event. + * @param {NodeList} nodes List of new nodes. + */ + var notifyVideoJS = function(e, nodes) { + nodes.find('.mediaplugin_videojs audio, .mediaplugin_videojs video') + .each(function() { + var id = $(this).attr('id'), + config = $(this).data('setup'); + + videojs(id, config); + }); + }; + + return { + setUp: setUp + }; + +}); diff --git a/media/player/videojs/classes/plugin.php b/media/player/videojs/classes/plugin.php index b9e0d2dd721..00ef6de2b0d 100644 --- a/media/player/videojs/classes/plugin.php +++ b/media/player/videojs/classes/plugin.php @@ -99,10 +99,7 @@ class media_videojs_plugin extends core_media_player_native { $title = $this->get_name($name, $urls); $title = preg_replace(['/&/', '/>/', '/</'], ['&', '>', '<'], $title); - // Ensure JS is loaded. This will also load language strings and populate $this->language with the current language. - $this->load_amd_module(); if ($this->youtube) { - $this->load_amd_module('Youtube'); $datasetup[] = '"techOrder": ["youtube"]'; $datasetup[] = '"sources": [{"type": "video/youtube", "src":"' . $urls[0] . '"}]'; $sources = ''; // Do not specify tags - it may confuse browser. @@ -132,10 +129,9 @@ class media_videojs_plugin extends core_media_player_native { } // Attributes for the video/audio tag. - static $playercounter = 1; $attributes = [ 'data-setup' => '{' . join(', ', $datasetup) . '}', - 'id' => 'id_videojs_' . ($playercounter++), + 'id' => 'id_videojs_' . uniqid(), 'class' => get_config('media_videojs', $isaudio ? 'audiocssclass' : 'videocssclass') ]; @@ -246,39 +242,6 @@ class media_videojs_plugin extends core_media_player_native { return 2000; } - /** - * Makes sure the player is loaded on the page and the language strings are set. - * We only need to do it once on a page. - * - * @param string $module module to load - */ - protected function load_amd_module($module = 'video') { - global $PAGE; - if (array_key_exists($module, $this->loadedonpage) && $PAGE === $this->loadedonpage[$module]) { - // This is exactly the same page object we used last time. - // Prevent from calling multiple times on the same page. - return; - } - - $contents = ''; - $alias = ''; - if ($module === 'video') { - $alias = 'videojs'; - $path = new moodle_url('/media/player/videojs/videojs/video-js.swf'); - $contents .= $alias . '.options.flash.swf = "' . $path . '";' . "\n"; - $contents .= $this->find_language(current_language()); - } - - $PAGE->requires->js_amd_inline(<<loadedonpage[$module] = $PAGE; - } - /** * Tries to match the current language to existing language files * @@ -354,4 +317,29 @@ EOT $middle = '([a-z0-9\-_]+)'; return $start . $middle . core_media_player_external::END_LINK_REGEX_PART; } + + /** + * Setup page requirements. + * + * @param moodle_page $page The page we are going to add requirements to. + */ + public function setup($page) { + + // Load core video JS. + $path = new moodle_url('/media/player/videojs/videojs/video-js.swf'); + $contents = 'videojs.options.flash.swf = "' . $path . '";' . "\n"; + $contents .= $this->find_language(current_language()); + $page->requires->js_amd_inline(<<requires->js_amd_inline('require(["media_videojs/Youtube"])'); + + // Load dynamic loader. + $page->requires->js_call_amd('media_videojs/loader', 'setUp'); + } }