diff --git a/css/media_youtube.css b/css/media_youtube.css deleted file mode 100644 index bb5407a..0000000 --- a/css/media_youtube.css +++ /dev/null @@ -1,21 +0,0 @@ - -.media-youtube-preview-wrapper { - max-width: 100%; - min-height: 50px; - position: relative; -} - -.media-youtube-preview-wrapper object, -.media-youtube-preview-wrapper iframe { - max-width: 100%; - position: relative; -} - -.media-youtube-preview-wrapper .js-fallback { - left: 0; - margin-top: -0.5em; - position: absolute; - right: 0; - text-align: center; - top: 50%; -} diff --git a/css/media_youtube.wysiwyg.css b/css/media_youtube.wysiwyg.css index 8dc32f9..27279de 100644 --- a/css/media_youtube.wysiwyg.css +++ b/css/media_youtube.wysiwyg.css @@ -2,6 +2,10 @@ /** * @file * Overlay for YouTube thumbnails in the media library browser. + * + * @TODO: Is this all for the Media Browser Providers logos? If so, + * they've been removed in latest Media dev and this file can be removed. + * */ #media-browser .styles-container-media_youtube { /* Relative wrapper for the overlay. */ diff --git a/includes/media_youtube.formatters.inc b/includes/media_youtube.formatters.inc index b08b016..0842a58 100644 --- a/includes/media_youtube.formatters.inc +++ b/includes/media_youtube.formatters.inc @@ -15,9 +15,11 @@ function media_youtube_file_formatter_info() { 'view callback' => 'media_youtube_file_formatter_video_view', 'settings callback' => 'media_youtube_file_formatter_video_settings', ); - foreach (array('width', 'height', 'autoplay', 'related', 'hd', 'showsearch', 'modestbranding', 'showinfo', 'version', 'theme', 'fullscreen', 'wmode', 'chromeless') as $setting) { + + foreach (array('width', 'height', 'autohide', 'autoplay', 'color', 'controls', 'enablejsapi', 'loop', 'modestbranding', 'nocookie', 'origin', 'rel', 'showinfo','theme') as $setting) { $formatters['media_youtube_video']['default settings'][$setting] = media_youtube_variable_get($setting); } + $formatters['media_youtube_image'] = array( 'label' => t('YouTube Preview Image'), 'file types' => array('video'), @@ -42,7 +44,8 @@ function media_youtube_file_formatter_video_view($file, $display, $langcode) { '#uri' => $file->uri, '#options' => array(), ); - foreach (array('width', 'height', 'autoplay', 'related', 'hd', 'showsearch', 'modestbranding', 'showinfo', 'version', 'theme', 'fullscreen', 'wmode', 'chromeless') as $setting) { + + foreach (array('width', 'height', 'autohide', 'autoplay', 'color', 'controls', 'enablejsapi', 'loop', 'modestbranding', 'nocookie', 'origin', 'rel', 'showinfo', 'theme') as $setting) { $element['#options'][$setting] = isset($file->override[$setting]) ? $file->override[$setting] : $display['settings'][$setting]; } return $element; @@ -54,26 +57,6 @@ function media_youtube_file_formatter_video_view($file, $display, $langcode) { */ function media_youtube_file_formatter_video_settings($form, &$form_state, $settings) { $element = array(); - $options = array( - 0 => t('AS2'), - 3 => t('AS3'), - ); - $element['version'] = array( - '#title' => t('YouTube player version'), - '#type' => 'select', - '#options' => $options, - '#default_value' => $settings['version'], - ); - $options = array( - 'dark' => t('dark'), - 'light' => t('light'), - ); - $element['theme'] = array( - '#title' => t('YouTube player theme'), - '#type' => 'select', - '#options' => $options, - '#default_value' => $settings['theme'], - ); $element['width'] = array( '#title' => t('Width'), @@ -85,46 +68,100 @@ function media_youtube_file_formatter_video_settings($form, &$form_state, $setti '#type' => 'textfield', '#default_value' => $settings['height'], ); - $element['fullscreen'] = array( - '#title' => t('Allow the video to be played in full screen mode'), - '#type' => 'checkbox', - '#default_value' => $settings['fullscreen'], + + // @see https://developers.google.com/youtube/player_parameters#Parameters + + // Multiple options. + $element['theme'] = array( + '#title' => t('Player theme'), + '#type' => 'radios', + '#options' => array( + 'dark' => t('Dark'), + 'light' => t('Light'), + ), + '#default_value' => $settings['theme'], + ); + + $element['color'] = array( + '#title' => t('Progress bar color'), + '#type' => 'radios', + '#options' => array( + 'red' => t('Red'), + 'white' => t('White'), + ), + '#default_value' => $settings['color'], + ); + + $element['autohide'] = array( + '#title' => t('Controls during playback'), + '#type' => 'radios', + '#options' => array( + '0' => t('Keep progress bar and player controls on screen while playing'), + '2' => t('Hide progress bar while playing'), + '1' => t('Hide progress bar and player controls'), + ), + '#default_value' => $settings['autohide'], ); + + // Single Options. $element['autoplay'] = array( - '#title' => t('Autoplay'), + '#title' => t('Autoplay video on load'), '#type' => 'checkbox', '#default_value' => $settings['autoplay'], ); - $element['related'] = array( - '#title' => t('Show suggested videos when the video finishes'), + + $element['loop'] = array( + '#title' => t('Loop video'), '#type' => 'checkbox', - '#default_value' => $settings['related'], + '#default_value' => $settings['loop'], ); - $element['hd'] = array( - '#title' => t('Display the high quality version of the video when available'), + + // Note: make sure the positive/negitive language lines up with option + // processing in media_youtube.theme.inc. + $element['controls'] = array( + '#title' => t('Load player with controls hidden (chromeless player)'), '#type' => 'checkbox', - '#default_value' => $settings['hd'], + '#default_value' => $settings['controls'], ); - $element['showsearch'] = array( - '#title' => t('Allow users to search from the video'), + + $element['showinfo'] = array( + '#title' => t('Display video title and uploader'), '#type' => 'checkbox', - '#default_value' => $settings['showsearch'], + '#default_value' => $settings['showinfo'], ); + $element['modestbranding'] = array( - '#title' => t('Use modest YouTube branding (requires AS3 version player)'), + '#title' => t('Remove YouTube logo from the control bar'), '#type' => 'checkbox', '#default_value' => $settings['modestbranding'], ); - $element['showinfo'] = array( - '#title' => t('Display video title'), + + $element['rel'] = array( + '#title' => t('Show related videos when playback ends'), '#type' => 'checkbox', - '#default_value' => $settings['showinfo'], + '#default_value' => $settings['rel'], + ); + + $element['nocookie'] = array( + '#title' => t('Use privacy enhanced (no cookie) mode'), + '#type' => 'checkbox', + '#default_value' => $settings['nocookie'], ); - $element['chromeless'] = array( - '#title' => t('Use chromeless player'), + + // JS api. + $element['enablejsapi'] = array( + '#title' => t('Enable the Javascript API'), '#type' => 'checkbox', - '#default_value' => $settings['chromeless'], + '#default_value' => $settings['enablejsapi'], + ); + + $element['origin'] = array( + '#title' => t('Origin'), + '#type' => 'textfield', + '#description' => t('If the Javascript API is enabled, enter your site\'s domain for added security'), + '#default_value' => $settings['origin'], ); + return $element; } @@ -177,21 +214,24 @@ function media_youtube_file_default_displays() { // Default settings for displaying as a video. $default_video_settings = array( + + // @todo: Remove Large, rewrite default displays once + // http://drupal.org/node/1051090 goes through. 'media_large' => array( - 'width' => 480, - 'height' => 360, + 'width' => 560, + 'height' => 315, 'autoplay' => FALSE, ), + 'media_original' => array( 'width' => 640, - 'height' => 480, + 'height' => 360, 'autoplay' => media_youtube_variable_get('autoplay'), ), ); foreach ($default_video_settings as $view_mode => $settings) { $display_name = 'video__' . $view_mode . '__media_youtube_video'; $default_displays[$display_name] = (object) array( - 'api_version' => 1, 'name' => $display_name, 'status' => 1, 'weight' => 1, @@ -211,7 +251,7 @@ function media_youtube_file_default_displays() { foreach ($default_image_styles as $view_mode => $image_style) { $display_name = 'video__' . $view_mode . '__media_youtube_image'; $default_displays[$display_name] = (object) array( - 'api_version' => 1, + // 'api_version' => 1, 'name' => $display_name, 'status' => 1, 'weight' => 2, diff --git a/includes/media_youtube.variables.inc b/includes/media_youtube.variables.inc index 27949f6..30c628d 100644 --- a/includes/media_youtube.variables.inc +++ b/includes/media_youtube.variables.inc @@ -92,7 +92,7 @@ function media_youtube_variable_del($name) { * * @param string $name * Optional variable name to retrieve the default. Note that it has not yet - * been pre-pended with the MEDIA_YOUTUBE_NAMESPACE namespace at this time. + * been prepended with the MEDIA_YOUTUBE_NAMESPACE namespace at this time. * @return unknown * The default value of this variable, if it's been set, or NULL, unless * $name is NULL, in which case we return an array of all default values. @@ -106,20 +106,20 @@ function media_youtube_variable_default($name = NULL) { if (!isset($defaults)) { $defaults = array( - 'width' => 560, - 'height' =>340, + 'width' => 640, + 'height' => 360, + 'autohide' => 2, 'autoplay' => FALSE, - 'related' => TRUE, - 'hd' => FALSE, - 'showsearch' => TRUE, + 'color' => 'red', + 'controls' => TRUE, + 'enablejsapi' => FALSE, + 'loop' => FALSE, 'modestbranding' => FALSE, - 'showinfo'=> TRUE, - 'version' => 3, + 'nocookie' => FALSE, + 'origin' => '', + 'rel' => TRUE, + 'showinfo' => TRUE, 'theme' => 'dark', - 'fullscreen' => TRUE, - 'wmode' => 'transparent', - 'chromeless' => FALSE, - 'preview_uri' => 'youtube://v/-jubiv7QUco', ); } diff --git a/includes/themes/media-youtube-video.tpl.php b/includes/themes/media-youtube-video.tpl.php index 5e93033..4f4abaa 100644 --- a/includes/themes/media-youtube-video.tpl.php +++ b/includes/themes/media-youtube-video.tpl.php @@ -6,19 +6,17 @@ * Template file for theme('media_youtube_video'). * * Variables available: - * $uri - The uri to the YouTube video, such as youtube://v/xsy7x8c9. - * $video_id - The unique identifier of the YouTube video. - * $width - The width to render. - * $height - The height to render. - * $autoplay - If TRUE, then start the player automatically when displaying. - * $fullscreen - Whether to allow fullscreen playback. + * $uri - The media uri for the YouTube video (e.g., youtube://v/xsy7x8c9). + * $video_id - The unique identifier of the YouTube video (e.g., xsy7x8c9). + * $id - The file entity ID (fid). + * $url - The full url including query options for the Youtube iframe. + * $options - An array containing the Media Youtube formatter options. + * $width - The width value set in Media: Youtube file display options. + * $height - The height value set in Media: Youtube file display options. * - * Note that we set the width & height of the outer wrapper manually so that - * the JS will respect that when resizing later. */ + ?> -
-
- -
+
+
diff --git a/includes/themes/media_youtube.theme.inc b/includes/themes/media_youtube.theme.inc index dc53757..2f0930e 100644 --- a/includes/themes/media_youtube.theme.inc +++ b/includes/themes/media_youtube.theme.inc @@ -10,103 +10,87 @@ * Preprocess function for theme('media_youtube_video'). */ function media_youtube_preprocess_media_youtube_video(&$variables) { - // Build the URL for display. - $uri = $variables['uri']; - $wrapper = file_stream_wrapper_get_instance_by_uri($uri); + + // Build the URI. + $wrapper = file_stream_wrapper_get_instance_by_uri($variables['uri']); $parts = $wrapper->get_parameters(); $variables['video_id'] = check_plain($parts['v']); - $variables['query'] = array(); - // @see http://code.google.com/apis/youtube/player_parameters.html - foreach (array('width', 'height', 'autoplay', 'related', 'hd', 'showsearch', 'modestbranding', 'showinfo', 'version', 'theme', 'fullscreen', 'wmode', 'chromeless') as $option) { - // Set the option, either from the options array, or from the default value. - $variables[$option] = isset($variables[$option]) ? $variables[$option] : (isset($variables['options'][$option]) ? $variables['options'][$option] : media_youtube_variable_get($option)); - } + // Parse options and build the query string. Only add the option to the query + // array if the option value is not default. Be careful, depending on the + // wording in media_youtube.formatters.inc, TRUE may be query=0. + // @see https://developers.google.com/youtube/player_parameters#Parameters + $query = array(); - // We have to set fullscreen in the url query and as a parameter to the flash. - $variables['fs'] = $variables['fullscreen']; - $variables['fullscreen'] = $variables['fullscreen'] ? 'true' : 'false'; - - $variables['wrapper_id'] = 'media_youtube_' . $variables['video_id'] . '_' . $variables['id']; - - // Pass the settings to replace the object tag with an iframe. - $settings = array( - 'media_youtube' => array( - $variables['wrapper_id'] => array( - 'width' => $variables['width'], - 'height' => $variables['height'], - 'video_id' => $variables['video_id'], - 'fullscreen' => $variables['fullscreen'], - 'id' => $variables['wrapper_id'] .'_iframe', - ), - ), - ); - - // Set the version of the youtube api player. - if ($variables['version']) { - $variables['query']['version'] = $variables['version']; - // Note that the fs variable defaults to 1 with the AS3 player. - if (!$variables['fs']) { - $variables['query']['fs'] = 0; + // These queries default to 0. If the option is true, set value to 1. + foreach (array('autoplay', 'enablejsapi', 'loop', 'modestbranding') as $option) { + if ($variables['options'][$option]) { + $query[$option] = 1; } } - else if ($variables['fs']) { - // Note that the fs variable defaults to 0 with the AS2 player. - $variables['query']['fs'] = 1; + + // Currently, loop only works with a playlist. Make fake playlist out of a + // single video. + // @see https://developers.google.com/youtube/player_parameters#loop + if ($variables['options']['loop']) { + $query['playlist'] = $variables['video_id']; } - // These options default to 0. - foreach (array('modestbranding', 'autoplay', 'hd') as $variable) { - if ($variables[$variable]) { - $variables['query'][$variable] = 1; + // These queries default to 1. If the option is false, set value to 0. + foreach (array('rel', 'showinfo') as $option) { + if (!$variables['options'][$option]) { + $query[$option] = 0; } } - // These options default to 1. - foreach (array('showsearch', 'showinfo') as $variable) { - if (!$variables[$variable]) { - $variables['query'][$variable] = 0; - } + + // These queries default to 1. Option wording is reversed, so if the option + // is true, set value to 0. + if ($variables['options']['controls']) { + $query['controls'] = 0; } - if (!$variables['related']) { - $variables['query']['rel'] = 0; + // Reverse the reversed option so that it makes sense in the tpl. + if ($variables['options']['controls'] = 1) { + $variables['options']['controls'] = 0; } - if ($variables['theme'] != 'dark') { - $variables['query']['theme'] = $variables['theme']; + else { + $variables['options']['controls'] = 1; } - // Ensure that we pass the required query variables to the Iframe settings. - if (!empty($variables['query'])) { - $settings['media_youtube'][$variables['wrapper_id']]['options'] = $variables['query']; + // Strings. + if ($variables['options']['theme'] != 'dark') { + $query['theme'] = $variables['options']['theme']; + } + if ($variables['options']['color'] != 'red') { + $query['color'] = $variables['options']['color']; + } + if ($variables['options']['autohide'] != '2') { + $query['autohide'] = $variables['options']['autohide']; } - drupal_add_js($settings, 'setting'); - drupal_add_js(drupal_get_path('module', 'media_youtube') . '/js/media_youtube.js'); - drupal_add_css(drupal_get_path('module', 'media_youtube') . '/css/media_youtube.css'); - drupal_add_js(drupal_get_path('module', 'media_youtube') . '/js/flash_detect_min.js'); - - // The chromeless player requires a different url. - if ($variables['chromeless']) { - $variables['url_api'] = 'apiplayer'; - $variables['query']['video_id'] = $variables['video_id']; + // Non-query options. + if ($variables['options']['nocookie']) { + $url_base = 'youtube-nocookie.com'; } else { - $variables['url_api'] = 'v/' . $variables['video_id']; + $url_base = 'youtube.com'; + } + + // Add some options as their own template variables. + foreach (array('width', 'height') as $themevar) { + $variables[$themevar] = $variables['options'][$themevar]; } - $variables['url'] = url('http://www.youtube.com/' . $variables['url_api'], array('query' => $variables['query'], 'external' => TRUE, 'https' => TRUE)); - - // For users with JavaScript, these object and embed tags will be replaced - // by an iframe, so that we can support users without Flash. - $variables['output'] = << - - - - - -OUTPUT; + // Build the iframe URL with options query string. + // Use https as default protocol instead of relative protocol to maintain + // compatibility with content emails, rss, and https sites. + // @see http://drupal.org/node/1368818 + $variables['url'] = url('https://www.' . $url_base . '/embed/' . $variables['video_id'], array('query' => $query, 'external' => TRUE, 'https' => TRUE)); + } +/** + * Styles + */ function theme_media_youtube_field_formatter_styles($variables) { $element = $variables['element']; $style = $variables['style']; diff --git a/js/flash_detect_min.js b/js/flash_detect_min.js deleted file mode 100644 index ebdff92..0000000 --- a/js/flash_detect_min.js +++ /dev/null @@ -1,5 +0,0 @@ -//http://www.featureblend.com/license.txt -var FlashDetect=new function(){var self=this;self.installed=false;self.raw="";self.major=-1;self.minor=-1;self.revision=-1;self.revisionStr="";var activeXDetectRules=[{"name":"ShockwaveFlash.ShockwaveFlash.7","version":function(obj){return getActiveXVersion(obj);}},{"name":"ShockwaveFlash.ShockwaveFlash.6","version":function(obj){var version="6,0,21";try{obj.AllowScriptAccess="always";version=getActiveXVersion(obj);}catch(err){} -return version;}},{"name":"ShockwaveFlash.ShockwaveFlash","version":function(obj){return getActiveXVersion(obj);}}];var getActiveXVersion=function(activeXObj){var version=-1;try{version=activeXObj.GetVariable("$version");}catch(err){} -return version;};var getActiveXObject=function(name){var obj=-1;try{obj=new ActiveXObject(name);}catch(err){obj={activeXError:true};} -return obj;};var parseActiveXVersion=function(str){var versionArray=str.split(",");return{"raw":str,"major":parseInt(versionArray[0].split(" ")[1],10),"minor":parseInt(versionArray[1],10),"revision":parseInt(versionArray[2],10),"revisionStr":versionArray[2]};};var parseStandardVersion=function(str){var descParts=str.split(/ +/);var majorMinor=descParts[2].split(/\./);var revisionStr=descParts[3];return{"raw":str,"major":parseInt(majorMinor[0],10),"minor":parseInt(majorMinor[1],10),"revisionStr":revisionStr,"revision":parseRevisionStrToInt(revisionStr)};};var parseRevisionStrToInt=function(str){return parseInt(str.replace(/[a-zA-Z]/g,""),10)||self.revision;};self.majorAtLeast=function(version){return self.major>=version;};self.minorAtLeast=function(version){return self.minor>=version;};self.revisionAtLeast=function(version){return self.revision>=version;};self.versionAtLeast=function(major){var properties=[self.major,self.minor,self.revision];var len=Math.min(properties.length,arguments.length);for(i=0;i=arguments[i]){if(i+10){var type='application/x-shockwave-flash';var mimeTypes=navigator.mimeTypes;if(mimeTypes&&mimeTypes[type]&&mimeTypes[type].enabledPlugin&&mimeTypes[type].enabledPlugin.description){var version=mimeTypes[type].enabledPlugin.description;var versionObj=parseStandardVersion(version);self.raw=versionObj.raw;self.major=versionObj.major;self.minor=versionObj.minor;self.revisionStr=versionObj.revisionStr;self.revision=versionObj.revision;self.installed=true;}}else if(navigator.appVersion.indexOf("Mac")==-1&&window.execScript){var version=-1;for(var i=0;i' + Drupal.t('You need Flash to watch this video. Get Flash', {'@flash':'http://get.adobe.com/flashplayer'}) + '
'); - wrapper.height(wrapper.width() * hw); -}; - -Drupal.media_youtube.insertEmbed = function (embed_id) { - var videoWrapper = $('#' + embed_id + '.media-youtube-preview-wrapper'); - var settings = Drupal.settings.media_youtube[embed_id]; - - // Calculate the ratio of the dimensions of the embed. - settings.hw = settings.height / settings.width; - - // Replace the object embed with YouTube's iframe. This isn't done by the - // theme function because YouTube doesn't have a no-JS or no-Flash fallback. - var video = $(''); - var src = 'http://www.youtube.com/embed/' + settings.video_id; - - // Allow other modules to modify the video settings. - settings.options = settings.options || {}; - settings.options.wmode = 'opaque'; - $(window).trigger('media_youtube_load', settings); - - // Merge YouTube options (such as autoplay) into the source URL. - var query = $.param(settings.options); - if (query) { - src += '?' + query; - } - - // Set up the iframe with its contents and add it to the page. - video - .attr('id', settings.id) - .attr('width', settings.width) - .attr('height', settings.height) - .attr('src', src); - videoWrapper.html(video); - - // Bind a resize event to handle fluid layouts. - $(window).bind('resize', Drupal.media_youtube.resizeEmbeds); - - // For some reason Chrome does not properly size the container around the - // embed and it will just render the embed at full size unless we set this - // timeout. - if (!$('.lightbox-stack').length) { - setTimeout(Drupal.media_youtube.resizeEmbeds, 1); - } -}; - -Drupal.media_youtube.resizeEmbeds = function () { - $('.media-youtube-preview-wrapper').each(Drupal.media_youtube.resizeEmbed); -}; - -Drupal.media_youtube.resizeEmbed = function () { - var context = $(this).parent(); - var video = $(this).children(':first-child'); - var hw = Drupal.settings.media_youtube[$(this).attr('id')].hw; - // Change the height of the wrapper that was given a fixed height by the - // YouTube theming function. - $(this) - .height(context.width() * hw) - .width(context.width()); - - // Change the attributes on the embed to match the new size. - video - .height(context.width() * hw) - .width(context.width()); -}; - -})(jQuery); \ No newline at end of file diff --git a/media_youtube.module b/media_youtube.module index 995f95c..8629299 100644 --- a/media_youtube.module +++ b/media_youtube.module @@ -20,6 +20,8 @@ include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'media_youtube') . '/ // @todo Can save a little overhead for people without Styles module by wrapping // this inside a module_exists('styles'). However, is that safe to do in // global context? If not, is there any down side to doing it in hook_init()? +// @todo: Styles integration is no longer recommended. We can just take out all +// Styles module code. include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'media_youtube') . '/includes/media_youtube.styles.inc'; // Hooks and callbacks for integrating with File Entity module for display. @@ -66,9 +68,8 @@ function media_youtube_theme($existing, $type, $theme, $path) { 'file' => 'media_youtube.theme.inc', 'path' => $path . '/includes/themes', ), - // Note that all the variables after options are now deprecated. 'media_youtube_video' => array( - 'variables' => array('uri' => NULL, 'options' => array(), 'width' => NULL, 'height' => NULL, 'autoplay' => NULL, 'fullscreen' => NULL, 'related' => NULL), + 'variables' => array('uri' => NULL, 'options' => array()), 'file' => 'media_youtube.theme.inc', 'path' => $path . '/includes/themes', 'template' => 'media-youtube-video', @@ -153,7 +154,7 @@ function media_youtube_add($form, &$form_state = array()) { '#value' => t('Apply'), ); - // This is our ghetto pager. + // This is our half-assed pager. $page = isset($_GET['page-yt']) ? $_GET['page-yt'] : 0; if (isset($form_state['input']['search'])) { // Reset the pager when we press apply. @@ -282,7 +283,6 @@ function media_youtube_add_validate($form, &$form_state) { return; } - $validators = $form['#validators']; if ($validators) { // Check for errors. @see media_add_upload_validate calls file_save_upload(). @@ -370,6 +370,9 @@ function media_youtube_valid_id($id, $refresh = FALSE) { if (!$refresh && isset($ids[$id])) { return $ids[$id]; } + elseif (!$refresh && !isset($ids[$id])) { + return $id; + } elseif (!$refresh && $cache = cache_get('media_youtube:id:' . $id, 'cache_media_xml')) { $ids[$id] = $cache->data; return $ids[$id];