1/* global mejs:false */ 2XA.component.playlist = (function($) { 3 4 var api = {}; 5 6 function Playlist(playlist, properties) { 7 this.properties = properties; 8 this.playlist = playlist; 9 this.activeVideo = 0; 10 this.playlistItems = 0; 11 } 12 13 Playlist.prototype.createNewSources = function(source, videoContainer) { 14 var newSource; 15 16 var sourceBuilder = function(path) { 17 var newSource = $("<source>"), 18 type; 19 20 if (path.match(/\.(mp4)$/)) { 21 type = "video/mp4"; 22 } else if (path.match(/\.(webm)$/)) { 23 type = "video/webm"; 24 } else if (path.match(/\.(ogv)$/)) { 25 type = "video/ogg"; 26 } else { 27 type = "video/youtube"; 28 } 29 30 newSource.attr({ 31 "type": type, 32 "src": path 33 }); 34 35 return newSource; 36 }; 37 38 if (source instanceof Array) { 39 for (var i = 0; i < source.length; i++) { 40 newSource = sourceBuilder(source[i]); 41 videoContainer.find("video").append(newSource); 42 } 43 } else { 44 newSource = sourceBuilder(source); 45 videoContainer.find("video").append(newSource); 46 } 47 }; 48 49 Playlist.prototype.replaceSource = function(itemIndex, loadFromEvent) { 50 var inst = this, 51 videoContainer, 52 videoClone, 53 newSrc = inst.properties.sources[itemIndex].src, 54 sources, 55 videoId, 56 videoContainerHeight = 0; 57 58 $(inst.properties.playlistId).each(function() { 59 videoContainer = $(this); 60 videoId = inst.properties.playlistId; 61 62 if ((videoContainer.is(videoId) && (newSrc.length))) { 63 videoContainer.addClass("show"); 64 65 sources = videoContainer.find("source"); 66 sources.remove(); 67 inst.createNewSources(newSrc, videoContainer); 68 videoContainer.find("video").attr({ 69 src: "" 70 }).show(); 71 72 var autoplayVideo = false; 73 if (loadFromEvent) { 74 if (inst.properties.autoPlaySelected) { 75 autoplayVideo = true; 76 } 77 } else { 78 if (inst.properties.autoPlay) { 79 autoplayVideo = true; 80 } 81 } 82 83 if (autoplayVideo) { 84 videoContainer.find("video").attr({ 85 autoplay: "" 86 }); 87 } 88 89 videoClone = videoContainer.find("video").clone(); 90 videoContainerHeight = videoContainer.height(); 91 videoContainer.css({ 92 "height": videoContainerHeight 93 }); 94 95 var id = videoContainer.find(".mejs-container").attr("id"); 96 if (id) { 97 $("#" + id).remove(); 98 delete mejs.players[id]; 99 videoContainer.find(".component-content").append(videoClone); 100 } 101 102 XA.component.video.initVideoFromPlaylist(videoContainer, inst.playlist); 103 videoContainer.css({ 104 "height": "auto" 105 }); 106 } 107 }); 108 }; 109 110 Playlist.prototype.loadPlaylistVideo = function() { 111 var inst = this, 112 playlistItems = $(inst.playlist).find(".playlist-item"), 113 activeListItem; 114 115 inst.playlistItems = playlistItems.length; 116 var loadVideoFromPlaylist = function(loadFromEvent) { 117 inst.replaceSource(inst.activeVideo, loadFromEvent); 118 activeListItem = playlistItems.eq(inst.activeVideo); 119 activeListItem.addClass("active"); 120 activeListItem.siblings().removeClass("active"); 121 } 122 123 loadVideoFromPlaylist(); 124 $(inst.playlist).on("change-video", function(event, properties) { 125 var loadNewVideo = false; 126 127 if (properties) { 128 if (properties.hasOwnProperty("back")) { 129 inst.activeVideo--; 130 if (inst.activeVideo < 0) { 131 inst.activeVideo = 0; 132 } else { 133 loadNewVideo = true; 134 } 135 } else { 136 inst.activeVideo++; 137 if (inst.activeVideo === inst.playlistItems) { 138 139 if (inst.properties.repeatAfterAll) { 140 inst.activeVideo = 0; 141 loadNewVideo = true 142 } else { 143 inst.activeVideo = inst.playlistItems - 1; 144 } 145 } else { 146 loadNewVideo = true; 147 } 148 } 149 150 } else { 151 if (inst.properties.playNext) { 152 if ((inst.activeVideo + 1) <= inst.playlistItems) { 153 inst.activeVideo++; 154 155 if (inst.activeVideo === inst.playlistItems) { 156 inst.activeVideo = 0; 157 158 if (inst.properties.repeatAfterAll) { 159 loadNewVideo = true; 160 } 161 } else { 162 inst.actiVideo--; 163 loadNewVideo = true; 164 } 165 } 166 } 167 } 168
169 if (loadNewVideo) { 170 loadVideoFromPlaylist(true); 171 } 172 }); 173 }; 174 175 Playlist.prototype.attachEvents = function() { 176 var inst = this, 177 link = $(inst.playlist).find(".playlist-section"), 178 navItems = $(inst.playlist).find(".playlist-nav a"), 179 playlistItem; 180 181 link.on("click", function(event) { 182 event.preventDefault(); 183 184 playlistItem = $(this).parents(".playlist-item"); 185 var itemIndex = playlistItem.index(); 186 187 if (itemIndex !== inst.activeVideo) { 188 playlistItem.addClass("active"); 189 playlistItem.siblings().removeClass("active"); 190 inst.replaceSource(itemIndex, true); 191 inst.activeVideo = itemIndex; 192 } 193 }); 194 195 navItems.on("click", function(event) { 196 event.preventDefault(); 197 var properties = {}; 198 199 if ($(this).parent().hasClass("playlist-prev")) { 200 properties.back = true; 201 } 202 203 $(inst.playlist).trigger("change-video", properties); 204 }); 205 206 }; 207 208 api.initInstance=function(component,prop) { 209 var playlist; 210 $(prop.playlistId).addClass("initialized"); //prevent video init in component-video.js 211 if (prop.sources.length) { 212 playlist = new Playlist(component, prop); 213 playlist.loadPlaylistVideo(); 214 playlist.attachEvents(); 215 } 216 } 217 218 api.init = function() { 219 var playlists = $(".playlist.component:not(.initialized)"), 220 properties; 221 222 playlists.each(function() { 223 properties = $(this).data("properties"); 224 api.initInstance(this,properties); 225 $(this).addClass("initialized"); 226 }); 227 }; 228 229 return api; 230}(jQuery, document)); 231 232XA.register("playlist", XA.component.playlist);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.