From 2fa497df6506fecbb0e192fec5ee4fabbe307064 Mon Sep 17 00:00:00 2001 From: Huong Nguyen Date: Tue, 22 Mar 2022 11:33:06 +0700 Subject: [PATCH] MDL-74113 atto_media: Listen to play/pause events --- .../moodle-atto_media-button-debug.js | 43 +++++++++++++++++++ .../moodle-atto_media-button-min.js | 6 +-- .../moodle-atto_media-button.js | 43 +++++++++++++++++++ .../plugins/media/yui/src/button/js/button.js | 43 +++++++++++++++++++ 4 files changed, 132 insertions(+), 3 deletions(-) diff --git a/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-debug.js b/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-debug.js index 95a7a0a2135..d5fb43a6d0b 100644 --- a/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-debug.js +++ b/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-debug.js @@ -459,6 +459,12 @@ Y.namespace('M.atto_media').Button = Y.Base.create('button', Y.M.editor_atto.Edi this.editor.delegate('dblclick', this._displayDialogue, 'video', this); this.editor.delegate('click', this._handleClick, 'video', this); + // For some reason, clicking the video on Firefox does not trigger the click event, while in Chrome it does. + // We also need to handle the play/pause instead. + this._attachPlayPauseEvents(); + var changeHandler = this._attachPlayPauseEvents.bind(this); + this.get('host').on('change', changeHandler, null); + this.addButton({ icon: 'e/insert_edit_video', callback: this._displayDialogue, @@ -468,6 +474,26 @@ Y.namespace('M.atto_media').Button = Y.Base.create('button', Y.M.editor_atto.Edi } }, + /** + * Attaches Play/Pause events to the video nodes. + * + * @private + */ + _attachPlayPauseEvents: function() { + if (this._handlePlayEndBound === undefined) { + this._handlePlayEndBound = this._handlePlayEnd.bind(this); + } + var videos = this.editor.getDOMNode().querySelectorAll('video'); + videos.forEach(function(video) { + // Prevent duplicated event listeners. + video.removeEventListener('play', this._handlePlayEndBound); + video.removeEventListener('pause', this._handlePlayEndBound); + // Add event listeners. + video.addEventListener('play', this._handlePlayEndBound); + video.addEventListener('pause', this._handlePlayEndBound); + }.bind(this)); + }, + /** * Gets the root context for all templates, with extra supplied context. * @@ -503,6 +529,23 @@ Y.namespace('M.atto_media').Button = Y.Base.create('button', Y.M.editor_atto.Edi } }, + /** + * Handles a play/end on a media element. + * + * @method _handlePlayEnd + * @param {Event} e + * @private + */ + _handlePlayEnd: function(e) { + var medium = Y.one(e.target); + + var selection = this.get('host').getSelectionFromNode(medium); + if (this.get('host').getSelection() !== selection) { + this.get('host').setSelection(selection); + this.get('host')._hasSelectionChanged(e); + } + }, + /** * Display the media editing tool. * diff --git a/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-min.js b/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-min.js index 788f0c34966..696c40780ab 100644 --- a/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-min.js +++ b/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button-min.js @@ -1,5 +1,5 @@ -YUI.add("moodle-atto_media-button",function(l,e){var t="atto_media",i={LINK:"LINK",VIDEO:"VIDEO",AUDIO:"AUDIO"},a={SUBTITLES:"SUBTITLES",CAPTIONS:"CAPTIONS",DESCRIPTIONS:"DESCRIPTIONS",CHAPTERS:"CHAPTERS",METADATA:"METADATA"},o={SOURCE:"atto_media_source",TRACK:"atto_media_track",MEDIA_SOURCE:"atto_media_media_source",LINK_SOURCE:"atto_media_link_source",POSTER_SOURCE:"atto_media_poster_source",TRACK_SOURCE:"atto_media_track_source",DISPLAY_OPTIONS:"atto_media_display_options",NAME_INPUT:"atto_media_name_entry",TITLE_INPUT:"atto_media_title_entry",URL_INPUT:"atto_media_url_entry",POSTER_SIZE:"atto_media_poster_size",LINK_SIZE:"atto_media_link_size",WIDTH_INPUT:"atto_media_width_entry",HEIGHT_INPUT:"atto_media_height_entry",TRACK_KIND_INPUT:"atto_media_track_kind_entry",TRACK_LABEL_INPUT:"atto_media_track_label_entry",TRACK_LANG_INPUT:"atto_media_track_lang_entry",TRACK_DEFAULT_SELECT:"atto_media_track_default",MEDIA_CONTROLS_TOGGLE:"atto_media_controls",MEDIA_AUTOPLAY_TOGGLE:"atto_media_autoplay",MEDIA_MUTE_TOGGLE:"atto_media_mute",MEDIA_LOOP_TOGGLE:"atto_media_loop",ADVANCED_SETTINGS:"atto_media_advancedsettings",LINK:i.LINK.toLowerCase(),VIDEO:i.VIDEO.toLowerCase(),AUDIO:i.AUDIO.toLowerCase(),TRACK_SUBTITLES:a.SUBTITLES.toLowerCase(),TRACK_CAPTIONS:a.CAPTIONS.toLowerCase(),TRACK_DESCRIPTIONS:a.DESCRIPTIONS.toLowerCase(),TRACK_CHAPTERS:a.CHAPTERS.toLowerCase(),TRACK_METADATA:a.METADATA.toLowerCase()},s={SOURCE:"."+o.SOURCE,TRACK:"."+o.TRACK,MEDIA_SOURCE:"."+o.MEDIA_SOURCE,POSTER_SOURCE:"."+o.POSTER_SOURCE,TRACK_SOURCE:"."+o.TRACK_SOURCE,DISPLAY_OPTIONS:"."+o.DISPLAY_OPTIONS,NAME_INPUT:"."+o.NAME_INPUT,TITLE_INPUT:"."+o.TITLE_INPUT,URL_INPUT:"."+o.URL_INPUT,POSTER_SIZE:"."+o.POSTER_SIZE,LINK_SIZE:"."+o.LINK_SIZE,WIDTH_INPUT:"."+o.WIDTH_INPUT,HEIGHT_INPUT:"."+o.HEIGHT_INPUT,TRACK_KIND_INPUT:"."+o.TRACK_KIND_INPUT,TRACK_LABEL_INPUT:"."+o.TRACK_LABEL_INPUT,TRACK_LANG_INPUT:"."+o.TRACK_LANG_INPUT,TRACK_DEFAULT_SELECT:"."+o.TRACK_DEFAULT_SELECT,MEDIA_CONTROLS_TOGGLE:"."+o.MEDIA_CONTROLS_TOGGLE,MEDIA_AUTOPLAY_TOGGLE:"."+o.MEDIA_AUTOPLAY_TOGGLE,MEDIA_MUTE_TOGGLE:"."+o.MEDIA_MUTE_TOGGLE,MEDIA_LOOP_TOGGLE:"."+o.MEDIA_LOOP_TOGGLE,ADVANCED_SETTINGS:"."+o.ADVANCED_SETTINGS,LINK_TAB:'li[data-medium-type="'+o.LINK+'"]',LINK_PANE:'.tab-pane[data-medium-type="'+o.LINK+'"]',VIDEO_TAB:'li[data-medium-type="'+o.VIDEO+'"]',VIDEO_PANE:'.tab-pane[data-medium-type="'+o.VIDEO+'"]',AUDIO_TAB:'li[data-medium-type="'+o.AUDIO+'"]',AUDIO_PANE:'.tab-pane[data-medium-type="'+o.AUDIO+'"]',TRACK_SUBTITLES_TAB:'li[data-track-kind="'+o.TRACK_SUBTITLES+'"]',TRACK_SUBTITLES_PANE:'.tab-pane[data-track-kind="'+o.TRACK_SUBTITLES+'"]',TRACK_CAPTIONS_TAB:'li[data-track-kind="'+o.TRACK_CAPTIONS+'"]',TRACK_CAPTIONS_PANE:'.tab-pane[data-track-kind="'+o.TRACK_CAPTIONS+'"]',TRACK_DESCRIPTIONS_TAB:'li[data-track-kind="'+o.TRACK_DESCRIPTIONS+'"]',TRACK_DESCRIPTIONS_PANE:'.tab-pane[data-track-kind="'+o.TRACK_DESCRIPTIONS+'"]',TRACK_CHAPTERS_TAB:'li[data-track-kind="'+o.TRACK_CHAPTERS+'"]',TRACK_CHAPTERS_PANE:'.tab-pane[data-track-kind="'+o.TRACK_CHAPTERS+'"]',TRACK_METADATA_TAB:'li[data-track-kind="'+o.TRACK_METADATA+'"]',TRACK_METADATA_PANE:'.tab-pane[data-track-kind="'+o.TRACK_METADATA+'"]'},r={ROOT:'
{{> tab_panes.link}}
{{> tab_panes.video}}
{{> tab_panes.audio}}

',TAB_PANES:{LINK:'{{renderPartial "form_components.source" context=this id=CSS.LINK_SOURCE}}', +YUI.add("moodle-atto_media-button",function(l,e){var t="atto_media",i={LINK:"LINK",VIDEO:"VIDEO",AUDIO:"AUDIO"},a={SUBTITLES:"SUBTITLES",CAPTIONS:"CAPTIONS",DESCRIPTIONS:"DESCRIPTIONS",CHAPTERS:"CHAPTERS",METADATA:"METADATA"},o={SOURCE:"atto_media_source",TRACK:"atto_media_track",MEDIA_SOURCE:"atto_media_media_source",LINK_SOURCE:"atto_media_link_source",POSTER_SOURCE:"atto_media_poster_source",TRACK_SOURCE:"atto_media_track_source",DISPLAY_OPTIONS:"atto_media_display_options",NAME_INPUT:"atto_media_name_entry",TITLE_INPUT:"atto_media_title_entry",URL_INPUT:"atto_media_url_entry",POSTER_SIZE:"atto_media_poster_size",LINK_SIZE:"atto_media_link_size",WIDTH_INPUT:"atto_media_width_entry",HEIGHT_INPUT:"atto_media_height_entry",TRACK_KIND_INPUT:"atto_media_track_kind_entry",TRACK_LABEL_INPUT:"atto_media_track_label_entry",TRACK_LANG_INPUT:"atto_media_track_lang_entry",TRACK_DEFAULT_SELECT:"atto_media_track_default",MEDIA_CONTROLS_TOGGLE:"atto_media_controls",MEDIA_AUTOPLAY_TOGGLE:"atto_media_autoplay",MEDIA_MUTE_TOGGLE:"atto_media_mute",MEDIA_LOOP_TOGGLE:"atto_media_loop",ADVANCED_SETTINGS:"atto_media_advancedsettings",LINK:i.LINK.toLowerCase(),VIDEO:i.VIDEO.toLowerCase(),AUDIO:i.AUDIO.toLowerCase(),TRACK_SUBTITLES:a.SUBTITLES.toLowerCase(),TRACK_CAPTIONS:a.CAPTIONS.toLowerCase(),TRACK_DESCRIPTIONS:a.DESCRIPTIONS.toLowerCase(),TRACK_CHAPTERS:a.CHAPTERS.toLowerCase(),TRACK_METADATA:a.METADATA.toLowerCase()},s={SOURCE:"."+o.SOURCE,TRACK:"."+o.TRACK,MEDIA_SOURCE:"."+o.MEDIA_SOURCE,POSTER_SOURCE:"."+o.POSTER_SOURCE,TRACK_SOURCE:"."+o.TRACK_SOURCE,DISPLAY_OPTIONS:"."+o.DISPLAY_OPTIONS,NAME_INPUT:"."+o.NAME_INPUT,TITLE_INPUT:"."+o.TITLE_INPUT,URL_INPUT:"."+o.URL_INPUT,POSTER_SIZE:"."+o.POSTER_SIZE,LINK_SIZE:"."+o.LINK_SIZE,WIDTH_INPUT:"."+o.WIDTH_INPUT,HEIGHT_INPUT:"."+o.HEIGHT_INPUT,TRACK_KIND_INPUT:"."+o.TRACK_KIND_INPUT,TRACK_LABEL_INPUT:"."+o.TRACK_LABEL_INPUT,TRACK_LANG_INPUT:"."+o.TRACK_LANG_INPUT,TRACK_DEFAULT_SELECT:"."+o.TRACK_DEFAULT_SELECT,MEDIA_CONTROLS_TOGGLE:"."+o.MEDIA_CONTROLS_TOGGLE,MEDIA_AUTOPLAY_TOGGLE:"."+o.MEDIA_AUTOPLAY_TOGGLE,MEDIA_MUTE_TOGGLE:"."+o.MEDIA_MUTE_TOGGLE,MEDIA_LOOP_TOGGLE:"."+o.MEDIA_LOOP_TOGGLE,ADVANCED_SETTINGS:"."+o.ADVANCED_SETTINGS,LINK_TAB:'li[data-medium-type="'+o.LINK+'"]',LINK_PANE:'.tab-pane[data-medium-type="'+o.LINK+'"]',VIDEO_TAB:'li[data-medium-type="'+o.VIDEO+'"]',VIDEO_PANE:'.tab-pane[data-medium-type="'+o.VIDEO+'"]',AUDIO_TAB:'li[data-medium-type="'+o.AUDIO+'"]',AUDIO_PANE:'.tab-pane[data-medium-type="'+o.AUDIO+'"]',TRACK_SUBTITLES_TAB:'li[data-track-kind="'+o.TRACK_SUBTITLES+'"]',TRACK_SUBTITLES_PANE:'.tab-pane[data-track-kind="'+o.TRACK_SUBTITLES+'"]',TRACK_CAPTIONS_TAB:'li[data-track-kind="'+o.TRACK_CAPTIONS+'"]',TRACK_CAPTIONS_PANE:'.tab-pane[data-track-kind="'+o.TRACK_CAPTIONS+'"]',TRACK_DESCRIPTIONS_TAB:'li[data-track-kind="'+o.TRACK_DESCRIPTIONS+'"]',TRACK_DESCRIPTIONS_PANE:'.tab-pane[data-track-kind="'+o.TRACK_DESCRIPTIONS+'"]',TRACK_CHAPTERS_TAB:'li[data-track-kind="'+o.TRACK_CHAPTERS+'"]',TRACK_CHAPTERS_PANE:'.tab-pane[data-track-kind="'+o.TRACK_CHAPTERS+'"]',TRACK_METADATA_TAB:'li[data-track-kind="'+o.TRACK_METADATA+'"]',TRACK_METADATA_PANE:'.tab-pane[data-track-kind="'+o.TRACK_METADATA+'"]'},d={ROOT:'
{{> tab_panes.link}}
{{> tab_panes.video}}
{{> tab_panes.audio}}

',TAB_PANES:{LINK:'{{renderPartial "form_components.source" context=this id=CSS.LINK_SOURCE}}', VIDEO:'{{renderPartial "form_components.source" context=this id=CSS.MEDIA_SOURCE entersourcelabel="videosourcelabel" addcomponentlabel="addsource" multisource="true" addsourcehelp=helpStrings.addsource}}',AUDIO:'{{renderPartial "form_components.source" context=this id=CSS.MEDIA_SOURCE entersourcelabel="audiosourcelabel" addcomponentlabel="addsource" multisource="true" addsourcehelp=helpStrings.addsource}}'},FORM_COMPONENTS:{SOURCE:'
{{#multisource}}{{renderPartial "form_components.add_component" context=../this label=../addcomponentlabel help=../addsourcehelp}}{{/multisource}}
',ADD_COMPONENT:'
{{#label}}{{get_string ../label ../component}}{{/label}}{{^label}}{{get_string "add" ../component}}{{/label}}{{#help}}{{{../help}}}{{/help}}
',REMOVE_COMPONENT:'
{{#label}}{{get_string ../label ../component}}{{/label}}{{^label}}{{get_string "remove" ../component}}{{/label}}
',DISPLAY_OPTIONS:'
{{#mediatype_video}}
x
{{renderPartial "form_components.source" context=this id=CSS.POSTER_SOURCE entersourcelabel="poster"}}{{/mediatype_video}}
', ADVANCED_SETTINGS:'
',TRACK_TABS:'
{{{helpStrings.subtitles}}}
{{renderPartial "form_components.track" context=this sourcelabel="subtitlessourcelabel" addcomponentlabel="addsubtitlestrack"}}
{{{helpStrings.captions}}}
{{renderPartial "form_components.track" context=this sourcelabel="captionssourcelabel" addcomponentlabel="addcaptionstrack"}}
{{{helpStrings.descriptions}}}
{{renderPartial "form_components.track" context=this sourcelabel="descriptionssourcelabel" addcomponentlabel="adddescriptionstrack"}}
{{{helpStrings.chapters}}}
{{renderPartial "form_components.track" context=this sourcelabel="chapterssourcelabel" addcomponentlabel="addchapterstrack"}}
{{{helpStrings.metadata}}}
{{renderPartial "form_components.track" context=this sourcelabel="metadatasourcelabel" addcomponentlabel="addmetadatatrack"}}
',TRACK:'
{{renderPartial "form_components.source" context=this id=CSS.TRACK_SOURCE entersourcelabel=sourcelabel}}
{{renderPartial "form_components.add_component" context=this label=addcomponentlabel}}
',SECTION:'
{{#help}}{{{../help}}}{{/help}}
'},HTML_MEDIA:{ -VIDEO:'  ',AUDIO:'  ',LINK:'{{#name}}{{../name}}{{/name}}{{^name}}{{../url}}{{/name}}'}};l.namespace("M.atto_media").Button=l.Base.create("button",l.M.editor_atto.EditorPlugin,[],{initializer:function(){this.get("host").canShowFilepicker("media")&&(this.editor.delegate("dblclick",this._displayDialogue,"video",this),this.editor.delegate("click",this._handleClick,"video",this),this.addButton({icon:"e/insert_edit_video",callback:this._displayDialogue,tags:"video, audio",tagMatchRequiresAll:!1}))},_getContext:function(e){return l.merge({elementid:this.get("host").get("elementid"),component:t,langsinstalled:this.get("langs").installed,langsavailable:this.get("langs").available,helpStrings:this.get("help"),CSS:o},e)},_handleClick:function(e){e=e.target,e=this.get("host").getSelectionFromNode(e);this.get("host").getSelection()!==e&&this.get("host").setSelection(e)},_displayDialogue:function(){!1!==this.get("host").getSelection()&&("renderPartial"in l.Handlebars.helpers||(function i(a,e){l.each(e,function(e,t){a.push(t),"object"!=typeof e?l.Handlebars.registerPartial(a.join(".").toLowerCase(),e):i(a,e),a.pop()})}([],r),l.Handlebars.registerHelper("renderPartial",function(e,t){var a;return e?(e=l.Handlebars.partials[e],a=t.hash.context?l.clone(t.hash.context):{},delete(a=l.merge(a,t.hash)).context,e?new l.Handlebars.SafeString(l.Handlebars.compile(e)(a)):""):""})),this.getDialogue({headerContent:M.util.get_string("createmedia",t),focusAfterHide:!0,width:660,focusOnShowSelector:s.URL_INPUT}).set("bodyContent",this._getDialogueContent(this.get("host").getSelection())).show(),M.form.shortforms({formid:this.get("host").get("elementid")+"_atto_media_form"}))},_getDialogueContent:function(e){var t=l.Node.create(l.Handlebars.compile(r.ROOT)(this._getContext())),a=this.get("host").getSelectedNodes().filter("video,audio").shift(),a=!!a&&this._getMediumProperties(a);return this._attachEvents(this._applyMediumProperties(t,a),e)},_attachEvents:function(e,a){return e.delegate("click",function(e){e.preventDefault(),this._addMediaSourceComponent(e.currentTarget)},s.MEDIA_SOURCE+" .addcomponent",this),e.delegate("click",function(e){e.preventDefault(),this._addTrackComponent(e.currentTarget)},s.TRACK+" .addcomponent",this),e.delegate("click",function(e){var t,a=e.currentTarget;a.get("checked")&&(t=function(e){return this._getTrackTypeFromTabPane(e.ancestor(".tab-pane"))}.bind(this),a.ancestor(".root.tab-content").all(s.TRACK_DEFAULT_SELECT).each(function(e){e!==a&&t(a)===t(e)&&e.set("checked",!1)}))},s.TRACK_DEFAULT_SELECT,this),e.delegate("click",function(e){var t=e.currentTarget,a=(t.ancestor(s.POSTER_SOURCE)?"image":t.ancestor(s.TRACK_SOURCE)&&"subtitle")||"media";e.preventDefault(),this.get("host").showFilepicker(a,this._getFilepickerCallback(t,a),this)},".openmediabrowser",this),e.all(".nav-item").on("click",function(e){e.currentTarget.get("parentNode").all(".active").removeClass("active")}),e.one(".submit").on("click",function(e){e.preventDefault();var e=this._getMediaHTML(e.currentTarget.ancestor(".atto_form")),t=this.get("host");this.getDialogue({focusAfterHide:null}).hide(),e&&(t.setSelection(a),t.insertContentAtFocusPoint(e),this.markUpdated())},this),e},_applyMediumProperties:function(e,t){var i,n,a;return t&&(i=function(e,t){e.one(s.TRACK_SOURCE+" "+s.URL_INPUT).set("value",t.src),e.one(s.TRACK_LANG_INPUT).set("value",t.srclang),e.one(s.TRACK_LABEL_INPUT).set("value",t.label),e.one(s.TRACK_DEFAULT_SELECT).set("checked",t.defaultTrack)},(n=e.one(".root.tab-content > .tab-pane#"+this.get("host").get("elementid")+"_"+t.type.toLowerCase())).one(s.MEDIA_SOURCE+" "+s.URL_INPUT).set("value",t.sources[0]),l.Array.each(t.sources.slice(1),function(t){this._addMediaSourceComponent(n.one(s.MEDIA_SOURCE+" .addcomponent"),function(e){e.one(s.URL_INPUT).set("value",t)})},this),l.Object.each(t.tracks,function(e,t){var e=e.length?e:[{src:"",srclang:"",label:"",defaultTrack:!1}],a=s["TRACK_"+t.toUpperCase()+"_PANE"];i(n.one(a+" "+s.TRACK),e[0]),l.Array.each(e.slice(1),function(t){this._addTrackComponent(n.one(a+" "+s.TRACK+" .addcomponent"),function(e){i(e,t)})},this)},this),n.one(s.TITLE_INPUT).set("value",t.title),n.one(s.MEDIA_CONTROLS_TOGGLE).set("checked",t.controls),n.one(s.MEDIA_AUTOPLAY_TOGGLE).set("checked",t.autoplay),n.one(s.MEDIA_MUTE_TOGGLE).set("checked",t.muted),n.one(s.MEDIA_LOOP_TOGGLE).set("checked",t.loop),"video"===(a=this._getMediumTypeFromTabPane(n))&&(n.one(s.POSTER_SOURCE+" "+s.URL_INPUT).setAttribute("value",t.poster),n.one(s.WIDTH_INPUT).set("value",t.width),n.one(s.HEIGHT_INPUT).set("value",t.height)),n.siblings(".active").removeClass("active"),e.all(".root.nav-tabs .nav-item a").removeClass("active"),n.addClass("active"),e.one(s[a.toUpperCase()+"_TAB"]+" a").addClass("active")),e},_getMediumProperties:function(e){ -var t=function(e,t){return e.hasAttribute(t)&&(e.getAttribute(t)||""===e.getAttribute(t))},a={subtitles:[],captions:[],descriptions:[],chapters:[],metadata:[]};return e.all("track").each(function(e){a[e.getAttribute("kind")].push({src:e.getAttribute("src"),srclang:e.getAttribute("srclang"),label:e.getAttribute("label"),defaultTrack:t(e,"default")})}),{type:e.test("video")?i.VIDEO:i.AUDIO,sources:e.all("source").get("src"),poster:e.getAttribute("poster"),title:e.getAttribute("title"),width:e.getAttribute("width"),height:e.getAttribute("height"),autoplay:t(e,"autoplay"),loop:t(e,"loop"),muted:t(e,"muted"),controls:t(e,"controls"),tracks:a}},_addTrackComponent:function(e,t){var a=this._getTrackTypeFromTabPane(e.ancestor(".tab-pane")),a=this._getContext({sourcelabel:a+"sourcelabel",addcomponentlabel:"add"+a+"track"});this._addComponent(e,r.FORM_COMPONENTS.TRACK,s.TRACK,a,t)},_addMediaSourceComponent:function(e,t){var a=this._getMediumTypeFromTabPane(e.ancestor(".tab-pane")),a=this._getContext({multisource:!0,id:o.MEDIA_SOURCE,entersourcelabel:a+"sourcelabel",addcomponentlabel:"addsource",addsourcehelp:this.get("help").addsource});this._addComponent(e,r.FORM_COMPONENTS.SOURCE,s.MEDIA_SOURCE,a,t)},_addComponent:function(e,t,a,i,n){var o=e.ancestor(a),a=l.Node.create(l.Handlebars.compile(t)(i)),t=this._getContext(i);t.label="remove",(i=l.Node.create(l.Handlebars.compile(r.FORM_COMPONENTS.REMOVE_COMPONENT)(t))).one(".removecomponent").on("click",function(e){e.preventDefault(),o.remove(!0)}),o.insert(a,"after"),e.ancestor().insert(i,"after"),e.ancestor().remove(!0),n&&n.call(this,a)},_getFilepickerCallback:function(i,n){return function(e){var a,t;""!==e.url&&(t=i.ancestor(".tab-pane"),i.ancestor(s.SOURCE).one(s.URL_INPUT).set("value",e.url),t.get("id")===this.get("host").get("elementid")+"_"+o.LINK&&t.one(s.NAME_INPUT).set("value",e.file),"subtitle"===n&&(a=e.file.split(".vtt")[0].split("-").slice(-1)[0],(t=this.get("langs").available.reduce(function(e,t){return t.code===a?t:e},!1))&&(i.ancestor(s.TRACK).one(s.TRACK_LABEL_INPUT).set("value",t.lang.substr(0,t.lang.lastIndexOf(" "))),i.ancestor(s.TRACK).one(s.TRACK_LANG_INPUT).set("value",t.code))))}},_getMediumTypeFromTabPane:function(e){return e.getAttribute("data-medium-type")},_getTrackTypeFromTabPane:function(e){return e.getAttribute("data-track-kind")},_getMediaHTML:function(e){var t=this._getMediumTypeFromTabPane(e.one(".root.tab-content > .tab-pane.active")),e=e.one(s[t.toUpperCase()+"_PANE"]);return this["_getMediaHTML"+t[0].toUpperCase()+t.substr(1)](e)},_getMediaHTMLLink:function(e){e={url:e.one(s.URL_INPUT).get("value"),name:e.one(s.NAME_INPUT).get("value")||!1};return e.url?l.Handlebars.compile(r.HTML_MEDIA.LINK)(e):""},_getMediaHTMLVideo:function(e){var t=this._getContextForMediaHTML(e);return t.width=e.one(s.WIDTH_INPUT).get("value")||!1,t.height=e.one(s.HEIGHT_INPUT).get("value")||!1,t.poster=e.one(s.POSTER_SOURCE+" "+s.URL_INPUT).get("value")||!1,t.sources.length?l.Handlebars.compile(r.HTML_MEDIA.VIDEO)(t):""},_getMediaHTMLAudio:function(e){e=this._getContextForMediaHTML(e);return e.sources.length?l.Handlebars.compile(r.HTML_MEDIA.AUDIO)(e):""},_getContextForMediaHTML:function(e){var t=[];return e.all(s.TRACK).each(function(e){t.push({track:e.one(s.TRACK_SOURCE+" "+s.URL_INPUT).get("value"),kind:this._getTrackTypeFromTabPane(e.ancestor(".tab-pane")),label:e.one(s.TRACK_LABEL_INPUT).get("value")||e.one(s.TRACK_LANG_INPUT).get("value"),srclang:e.one(s.TRACK_LANG_INPUT).get("value"),defaultTrack:e.one(s.TRACK_DEFAULT_SELECT).get("checked")?"true":null})},this),{sources:e.all(s.MEDIA_SOURCE+" "+s.URL_INPUT).get("value").filter(function(e){return!!e}).map(function(e){return{source:e}}),description:e.one(s.MEDIA_SOURCE+" "+s.URL_INPUT).get("value")||!1,tracks:t.filter(function(e){return!!e.track}),showControls:e.one(s.MEDIA_CONTROLS_TOGGLE).get("checked"),autoplay:e.one(s.MEDIA_AUTOPLAY_TOGGLE).get("checked"),muted:e.one(s.MEDIA_MUTE_TOGGLE).get("checked"),loop:e.one(s.MEDIA_LOOP_TOGGLE).get("checked"),title:e.one(s.TITLE_INPUT).get("value")||!1}}},{ATTRS:{langs:{},help:{}}})},"@VERSION@",{requires:["moodle-editor_atto-plugin","moodle-form-shortforms"]}); \ No newline at end of file +VIDEO:'  ',AUDIO:'  ',LINK:'{{#name}}{{../name}}{{/name}}{{^name}}{{../url}}{{/name}}'}};l.namespace("M.atto_media").Button=l.Base.create("button",l.M.editor_atto.EditorPlugin,[],{initializer:function(){var e;this.get("host").canShowFilepicker("media")&&(this.editor.delegate("dblclick",this._displayDialogue,"video",this),this.editor.delegate("click",this._handleClick,"video",this),this._attachPlayPauseEvents(),e=this._attachPlayPauseEvents.bind(this),this.get("host").on("change",e,null),this.addButton({icon:"e/insert_edit_video",callback:this._displayDialogue,tags:"video, audio",tagMatchRequiresAll:!1}))},_attachPlayPauseEvents:function(){this._handlePlayEndBound===undefined&&(this._handlePlayEndBound=this._handlePlayEnd.bind(this)),this.editor.getDOMNode().querySelectorAll("video").forEach(function(e){e.removeEventListener("play",this._handlePlayEndBound),e.removeEventListener("pause",this._handlePlayEndBound),e.addEventListener("play",this._handlePlayEndBound),e.addEventListener("pause",this._handlePlayEndBound)}.bind(this))},_getContext:function(e){return l.merge({elementid:this.get("host").get("elementid"),component:t,langsinstalled:this.get("langs").installed,langsavailable:this.get("langs").available,helpStrings:this.get("help"),CSS:o},e)},_handleClick:function(e){e=e.target,e=this.get("host").getSelectionFromNode(e);this.get("host").getSelection()!==e&&this.get("host").setSelection(e)},_handlePlayEnd:function(e){var t=l.one(e.target),t=this.get("host").getSelectionFromNode(t);this.get("host").getSelection()!==t&&(this.get("host").setSelection(t),this.get("host")._hasSelectionChanged(e))},_displayDialogue:function(){!1!==this.get("host").getSelection()&&("renderPartial"in l.Handlebars.helpers||(function i(a,e){l.each(e,function(e,t){a.push(t),"object"!=typeof e?l.Handlebars.registerPartial(a.join(".").toLowerCase(),e):i(a,e),a.pop()})}([],d),l.Handlebars.registerHelper("renderPartial",function(e,t){var a;return e?(e=l.Handlebars.partials[e],a=t.hash.context?l.clone(t.hash.context):{},delete(a=l.merge(a,t.hash)).context,e?new l.Handlebars.SafeString(l.Handlebars.compile(e)(a)):""):""})),this.getDialogue({headerContent:M.util.get_string("createmedia",t),focusAfterHide:!0,width:660,focusOnShowSelector:s.URL_INPUT}).set("bodyContent",this._getDialogueContent(this.get("host").getSelection())).show(),M.form.shortforms({formid:this.get("host").get("elementid")+"_atto_media_form"}))},_getDialogueContent:function(e){var t=l.Node.create(l.Handlebars.compile(d.ROOT)(this._getContext())),a=this.get("host").getSelectedNodes().filter("video,audio").shift(),a=!!a&&this._getMediumProperties(a);return this._attachEvents(this._applyMediumProperties(t,a),e)},_attachEvents:function(e,a){return e.delegate("click",function(e){e.preventDefault(),this._addMediaSourceComponent(e.currentTarget)},s.MEDIA_SOURCE+" .addcomponent",this),e.delegate("click",function(e){e.preventDefault(),this._addTrackComponent(e.currentTarget)},s.TRACK+" .addcomponent",this),e.delegate("click",function(e){var t,a=e.currentTarget;a.get("checked")&&(t=function(e){return this._getTrackTypeFromTabPane(e.ancestor(".tab-pane"))}.bind(this),a.ancestor(".root.tab-content").all(s.TRACK_DEFAULT_SELECT).each(function(e){e!==a&&t(a)===t(e)&&e.set("checked",!1)}))},s.TRACK_DEFAULT_SELECT,this),e.delegate("click",function(e){var t=e.currentTarget,a=(t.ancestor(s.POSTER_SOURCE)?"image":t.ancestor(s.TRACK_SOURCE)&&"subtitle")||"media";e.preventDefault(),this.get("host").showFilepicker(a,this._getFilepickerCallback(t,a),this)},".openmediabrowser",this),e.all(".nav-item").on("click",function(e){e.currentTarget.get("parentNode").all(".active").removeClass("active")}),e.one(".submit").on("click",function(e){e.preventDefault();var e=this._getMediaHTML(e.currentTarget.ancestor(".atto_form")),t=this.get("host");this.getDialogue({focusAfterHide:null}).hide(),e&&(t.setSelection(a),t.insertContentAtFocusPoint(e),this.markUpdated())},this),e},_applyMediumProperties:function(e,t){var i,n,a;return t&&(i=function(e,t){e.one(s.TRACK_SOURCE+" "+s.URL_INPUT).set("value",t.src),e.one(s.TRACK_LANG_INPUT).set("value",t.srclang),e.one(s.TRACK_LABEL_INPUT).set("value",t.label),e.one(s.TRACK_DEFAULT_SELECT).set("checked",t.defaultTrack)},(n=e.one(".root.tab-content > .tab-pane#"+this.get("host").get("elementid")+"_"+t.type.toLowerCase())).one(s.MEDIA_SOURCE+" "+s.URL_INPUT).set("value",t.sources[0]),l.Array.each(t.sources.slice(1),function(t){this._addMediaSourceComponent(n.one(s.MEDIA_SOURCE+" .addcomponent"),function(e){e.one(s.URL_INPUT).set("value",t)})},this),l.Object.each(t.tracks,function(e,t){var e=e.length?e:[{src:"",srclang:"",label:"",defaultTrack:!1}],a=s["TRACK_"+t.toUpperCase()+"_PANE"];i(n.one(a+" "+s.TRACK),e[0]),l.Array.each(e.slice(1),function(t){this._addTrackComponent(n.one( +a+" "+s.TRACK+" .addcomponent"),function(e){i(e,t)})},this)},this),n.one(s.TITLE_INPUT).set("value",t.title),n.one(s.MEDIA_CONTROLS_TOGGLE).set("checked",t.controls),n.one(s.MEDIA_AUTOPLAY_TOGGLE).set("checked",t.autoplay),n.one(s.MEDIA_MUTE_TOGGLE).set("checked",t.muted),n.one(s.MEDIA_LOOP_TOGGLE).set("checked",t.loop),"video"===(a=this._getMediumTypeFromTabPane(n))&&(n.one(s.POSTER_SOURCE+" "+s.URL_INPUT).setAttribute("value",t.poster),n.one(s.WIDTH_INPUT).set("value",t.width),n.one(s.HEIGHT_INPUT).set("value",t.height)),n.siblings(".active").removeClass("active"),e.all(".root.nav-tabs .nav-item a").removeClass("active"),n.addClass("active"),e.one(s[a.toUpperCase()+"_TAB"]+" a").addClass("active")),e},_getMediumProperties:function(e){var t=function(e,t){return e.hasAttribute(t)&&(e.getAttribute(t)||""===e.getAttribute(t))},a={subtitles:[],captions:[],descriptions:[],chapters:[],metadata:[]};return e.all("track").each(function(e){a[e.getAttribute("kind")].push({src:e.getAttribute("src"),srclang:e.getAttribute("srclang"),label:e.getAttribute("label"),defaultTrack:t(e,"default")})}),{type:e.test("video")?i.VIDEO:i.AUDIO,sources:e.all("source").get("src"),poster:e.getAttribute("poster"),title:e.getAttribute("title"),width:e.getAttribute("width"),height:e.getAttribute("height"),autoplay:t(e,"autoplay"),loop:t(e,"loop"),muted:t(e,"muted"),controls:t(e,"controls"),tracks:a}},_addTrackComponent:function(e,t){var a=this._getTrackTypeFromTabPane(e.ancestor(".tab-pane")),a=this._getContext({sourcelabel:a+"sourcelabel",addcomponentlabel:"add"+a+"track"});this._addComponent(e,d.FORM_COMPONENTS.TRACK,s.TRACK,a,t)},_addMediaSourceComponent:function(e,t){var a=this._getMediumTypeFromTabPane(e.ancestor(".tab-pane")),a=this._getContext({multisource:!0,id:o.MEDIA_SOURCE,entersourcelabel:a+"sourcelabel",addcomponentlabel:"addsource",addsourcehelp:this.get("help").addsource});this._addComponent(e,d.FORM_COMPONENTS.SOURCE,s.MEDIA_SOURCE,a,t)},_addComponent:function(e,t,a,i,n){var o=e.ancestor(a),a=l.Node.create(l.Handlebars.compile(t)(i)),t=this._getContext(i);t.label="remove",(i=l.Node.create(l.Handlebars.compile(d.FORM_COMPONENTS.REMOVE_COMPONENT)(t))).one(".removecomponent").on("click",function(e){e.preventDefault(),o.remove(!0)}),o.insert(a,"after"),e.ancestor().insert(i,"after"),e.ancestor().remove(!0),n&&n.call(this,a)},_getFilepickerCallback:function(i,n){return function(e){var a,t;""!==e.url&&(t=i.ancestor(".tab-pane"),i.ancestor(s.SOURCE).one(s.URL_INPUT).set("value",e.url),t.get("id")===this.get("host").get("elementid")+"_"+o.LINK&&t.one(s.NAME_INPUT).set("value",e.file),"subtitle"===n&&(a=e.file.split(".vtt")[0].split("-").slice(-1)[0],(t=this.get("langs").available.reduce(function(e,t){return t.code===a?t:e},!1))&&(i.ancestor(s.TRACK).one(s.TRACK_LABEL_INPUT).set("value",t.lang.substr(0,t.lang.lastIndexOf(" "))),i.ancestor(s.TRACK).one(s.TRACK_LANG_INPUT).set("value",t.code))))}},_getMediumTypeFromTabPane:function(e){return e.getAttribute("data-medium-type")},_getTrackTypeFromTabPane:function(e){return e.getAttribute("data-track-kind")},_getMediaHTML:function(e){var t=this._getMediumTypeFromTabPane(e.one(".root.tab-content > .tab-pane.active")),e=e.one(s[t.toUpperCase()+"_PANE"]);return this["_getMediaHTML"+t[0].toUpperCase()+t.substr(1)](e)},_getMediaHTMLLink:function(e){e={url:e.one(s.URL_INPUT).get("value"),name:e.one(s.NAME_INPUT).get("value")||!1};return e.url?l.Handlebars.compile(d.HTML_MEDIA.LINK)(e):""},_getMediaHTMLVideo:function(e){var t=this._getContextForMediaHTML(e);return t.width=e.one(s.WIDTH_INPUT).get("value")||!1,t.height=e.one(s.HEIGHT_INPUT).get("value")||!1,t.poster=e.one(s.POSTER_SOURCE+" "+s.URL_INPUT).get("value")||!1,t.sources.length?l.Handlebars.compile(d.HTML_MEDIA.VIDEO)(t):""},_getMediaHTMLAudio:function(e){e=this._getContextForMediaHTML(e);return e.sources.length?l.Handlebars.compile(d.HTML_MEDIA.AUDIO)(e):""},_getContextForMediaHTML:function(e){var t=[];return e.all(s.TRACK).each(function(e){t.push({track:e.one(s.TRACK_SOURCE+" "+s.URL_INPUT).get("value"),kind:this._getTrackTypeFromTabPane(e.ancestor(".tab-pane")),label:e.one(s.TRACK_LABEL_INPUT).get("value")||e.one(s.TRACK_LANG_INPUT).get("value"),srclang:e.one(s.TRACK_LANG_INPUT).get("value"),defaultTrack:e.one(s.TRACK_DEFAULT_SELECT).get("checked")?"true":null})},this),{sources:e.all(s.MEDIA_SOURCE+" "+s.URL_INPUT).get("value").filter(function(e){return!!e}).map(function(e){return{source:e}}),description:e.one(s.MEDIA_SOURCE+" "+s.URL_INPUT).get("value")||!1,tracks:t.filter(function(e){return!!e.track}),showControls:e.one(s.MEDIA_CONTROLS_TOGGLE).get("checked"),autoplay:e.one(s.MEDIA_AUTOPLAY_TOGGLE).get("checked"),muted:e.one(s.MEDIA_MUTE_TOGGLE).get("checked"),loop:e.one(s.MEDIA_LOOP_TOGGLE).get("checked"),title:e.one(s.TITLE_INPUT).get("value")||!1}}},{ATTRS:{langs:{},help:{}}})},"@VERSION@",{requires:["moodle-editor_atto-plugin","moodle-form-shortforms"]}); \ No newline at end of file diff --git a/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button.js b/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button.js index 95a7a0a2135..d5fb43a6d0b 100644 --- a/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button.js +++ b/lib/editor/atto/plugins/media/yui/build/moodle-atto_media-button/moodle-atto_media-button.js @@ -459,6 +459,12 @@ Y.namespace('M.atto_media').Button = Y.Base.create('button', Y.M.editor_atto.Edi this.editor.delegate('dblclick', this._displayDialogue, 'video', this); this.editor.delegate('click', this._handleClick, 'video', this); + // For some reason, clicking the video on Firefox does not trigger the click event, while in Chrome it does. + // We also need to handle the play/pause instead. + this._attachPlayPauseEvents(); + var changeHandler = this._attachPlayPauseEvents.bind(this); + this.get('host').on('change', changeHandler, null); + this.addButton({ icon: 'e/insert_edit_video', callback: this._displayDialogue, @@ -468,6 +474,26 @@ Y.namespace('M.atto_media').Button = Y.Base.create('button', Y.M.editor_atto.Edi } }, + /** + * Attaches Play/Pause events to the video nodes. + * + * @private + */ + _attachPlayPauseEvents: function() { + if (this._handlePlayEndBound === undefined) { + this._handlePlayEndBound = this._handlePlayEnd.bind(this); + } + var videos = this.editor.getDOMNode().querySelectorAll('video'); + videos.forEach(function(video) { + // Prevent duplicated event listeners. + video.removeEventListener('play', this._handlePlayEndBound); + video.removeEventListener('pause', this._handlePlayEndBound); + // Add event listeners. + video.addEventListener('play', this._handlePlayEndBound); + video.addEventListener('pause', this._handlePlayEndBound); + }.bind(this)); + }, + /** * Gets the root context for all templates, with extra supplied context. * @@ -503,6 +529,23 @@ Y.namespace('M.atto_media').Button = Y.Base.create('button', Y.M.editor_atto.Edi } }, + /** + * Handles a play/end on a media element. + * + * @method _handlePlayEnd + * @param {Event} e + * @private + */ + _handlePlayEnd: function(e) { + var medium = Y.one(e.target); + + var selection = this.get('host').getSelectionFromNode(medium); + if (this.get('host').getSelection() !== selection) { + this.get('host').setSelection(selection); + this.get('host')._hasSelectionChanged(e); + } + }, + /** * Display the media editing tool. * diff --git a/lib/editor/atto/plugins/media/yui/src/button/js/button.js b/lib/editor/atto/plugins/media/yui/src/button/js/button.js index 44cb411bb31..c70079477b1 100644 --- a/lib/editor/atto/plugins/media/yui/src/button/js/button.js +++ b/lib/editor/atto/plugins/media/yui/src/button/js/button.js @@ -457,6 +457,12 @@ Y.namespace('M.atto_media').Button = Y.Base.create('button', Y.M.editor_atto.Edi this.editor.delegate('dblclick', this._displayDialogue, 'video', this); this.editor.delegate('click', this._handleClick, 'video', this); + // For some reason, clicking the video on Firefox does not trigger the click event, while in Chrome it does. + // We also need to handle the play/pause instead. + this._attachPlayPauseEvents(); + var changeHandler = this._attachPlayPauseEvents.bind(this); + this.get('host').on('change', changeHandler, null); + this.addButton({ icon: 'e/insert_edit_video', callback: this._displayDialogue, @@ -466,6 +472,26 @@ Y.namespace('M.atto_media').Button = Y.Base.create('button', Y.M.editor_atto.Edi } }, + /** + * Attaches Play/Pause events to the video nodes. + * + * @private + */ + _attachPlayPauseEvents: function() { + if (this._handlePlayEndBound === undefined) { + this._handlePlayEndBound = this._handlePlayEnd.bind(this); + } + var videos = this.editor.getDOMNode().querySelectorAll('video'); + videos.forEach(function(video) { + // Prevent duplicated event listeners. + video.removeEventListener('play', this._handlePlayEndBound); + video.removeEventListener('pause', this._handlePlayEndBound); + // Add event listeners. + video.addEventListener('play', this._handlePlayEndBound); + video.addEventListener('pause', this._handlePlayEndBound); + }.bind(this)); + }, + /** * Gets the root context for all templates, with extra supplied context. * @@ -501,6 +527,23 @@ Y.namespace('M.atto_media').Button = Y.Base.create('button', Y.M.editor_atto.Edi } }, + /** + * Handles a play/end on a media element. + * + * @method _handlePlayEnd + * @param {Event} e + * @private + */ + _handlePlayEnd: function(e) { + var medium = Y.one(e.target); + + var selection = this.get('host').getSelectionFromNode(medium); + if (this.get('host').getSelection() !== selection) { + this.get('host').setSelection(selection); + this.get('host')._hasSelectionChanged(e); + } + }, + /** * Display the media editing tool. *