Added HtmlHelper::video() for html5 video element generation. Extracted asset url generation code to new function Helper::assetUrl().

This commit is contained in:
ADmad 2012-02-05 20:19:12 +05:30
parent 12bf1348f5
commit 22220074f2
3 changed files with 158 additions and 22 deletions

View file

@ -1491,6 +1491,44 @@ class HtmlHelperTest extends CakeTestCase {
$this->assertTags($result, array('p' => array('class' => 'class-name'), '<text>', '/p'));
}
/**
* testVideo method
*
* @return void
*/
public function testVideo() {
$result = $this->Html->video('video.webm');
$expected = array('video' => array('src' => 'files/video.webm'));
$this->assertTags($result, $expected);
$result = $this->Html->video('video.webm', array(
'text' => 'Your browser does not support the HTML5 Video element.'
));
$expected = array('video' => array('src' => 'files/video.webm'), 'Your browser does not support the HTML5 Video element.', '/video');
$this->assertTags($result, $expected);
$result = $this->Html->video('video.webm', array('autoload', 'muted' => 'muted'));
$expected = array('video' => array(
'src' => 'files/video.webm',
'autoload' => 'autoload',
'muted' => 'muted'
));
$this->assertTags($result, $expected);
$result = $this->Html->video(
array('video.webm', array('src' => 'video.ogv', 'type' => "video/ogg; codecs='theora, vorbis'")),
array('pathPrefix' => 'videos/', 'poster' => 'poster.jpg', 'text' => 'Your browser does not support the HTML5 Video element.')
);
$expected = array(
'video' => array('poster' => IMAGES_URL . 'poster.jpg'),
array('source' => array('src' => 'videos/video.webm', 'type' => 'video/webm')),
array('source' => array('src' => 'videos/video.ogv', 'type' => 'video/ogg; codecs='theora, vorbis'')),
'Your browser does not support the HTML5 Video element.',
'/video'
);
$this->assertTags($result, $expected);
}
/**
* testCrumbList method
*

View file

@ -259,6 +259,34 @@ class Helper extends Object {
return $webPath . $asset[1];
}
/**
* Generate url for given asset file. Depending on options passed provides full url with domain name.
* Also calls Helper::assetTimestamp() to add timestamp to local files
*
* @param string|array Path string or url array
* @param array $options Options array. Possible keys:
* `fullBase` Return full url with domain name
* `pathPrefix` Path prefix for relative urls
* @return string Generated url
*/
public function assetUrl($path, array $options) {
if (is_array($path)) {
$path = $this->url($path);
} elseif (strpos($path, '://') === false) {
if (!empty($options['pathPrefix']) && $path[0] !== '/') {
$path = $options['pathPrefix'] . $path;
}
$path = $this->assetTimestamp($this->webroot($path));
}
if (!empty($options['fullBase'])) {
$path = $this->url('/', true) . $path;
unset($options['fullBase']);
}
return $path;
}
/**
* Adds a timestamp to a file based resource based on the value of `Asset.timestamp` in
* Configure. If Asset.timestamp is true and debug > 0, or Asset.timestamp == 'force'
@ -446,10 +474,10 @@ class Helper extends Object {
// 0.name, 0.created.month style inputs. Excludes inputs with the modelScope in them.
if (
$count >= 2 &&
is_numeric($parts[0]) &&
!is_numeric($parts[1]) &&
$this->_modelScope &&
$count >= 2 &&
is_numeric($parts[0]) &&
!is_numeric($parts[1]) &&
$this->_modelScope &&
strpos($entity, $this->_modelScope) === false
) {
$entity = $this->_modelScope . '.' . $entity;

View file

@ -18,6 +18,7 @@
*/
App::uses('AppHelper', 'View/Helper');
App::uses('CakeResponse', 'Network');
/**
* Html Helper class for easy use of HTML widgets.
@ -101,7 +102,8 @@ class HtmlHelper extends AppHelper {
*/
protected $_minimizedAttributes = array(
'compact', 'checked', 'declare', 'readonly', 'disabled', 'selected',
'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize'
'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize',
'autoplay', 'preload', 'controls', 'loop', 'muted'
);
/**
@ -566,13 +568,13 @@ class HtmlHelper extends AppHelper {
* ### Options
*
* - `safe` (boolean) Whether or not the $script should be wrapped in <![CDATA[ ]]>
* - `inline` (boolean) Whether or not the $script should be added to
* - `inline` (boolean) Whether or not the $script should be added to
* `$scripts_for_layout` / `script` block, or output inline. (Deprecated, use `block` instead)
* - `block` Which block you want this script block appended to.
* Defaults to `script`.
*
* @param string $script The script to wrap
* @param array $options The options to use. Options not listed above will be
* @param array $options The options to use. Options not listed above will be
* treated as HTML attributes.
* @return mixed string or null depending on the value of `$options['block']`
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::scriptBlock
@ -765,8 +767,7 @@ class HtmlHelper extends AppHelper {
*
* - `url` If provided an image link will be generated and the link will point at
* `$options['url']`.
* - `fullBase` If provided the src attribute will get a full addres (non-relative url) for
* the image file.
* - `fullBase` If true the src attribute will get a full address for the image file.
*
* @param string $path Path to the image file, relative to the app/webroot/img/ directory.
* @param array $options Array of HTML attributes. See above for special options.
@ -774,19 +775,8 @@ class HtmlHelper extends AppHelper {
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::image
*/
public function image($path, $options = array()) {
if (is_array($path)) {
$path = $this->url($path);
} elseif (strpos($path, '://') === false) {
if ($path[0] !== '/') {
$path = IMAGES_URL . $path;
}
$path = $this->assetTimestamp($this->webroot($path));
}
if (!empty($options['fullBase'])) {
$path = $this->url('/', true) . $path;
unset($options['fullBase']);
}
$path = $this->assetUrl($path, $options + array('pathPrefix' => IMAGES_URL));
$options = array_diff_key($options, array('fullBase' => '', 'pathPrefix' => ''));
if (!isset($options['alt'])) {
$options['alt'] = '';
@ -977,6 +967,86 @@ class HtmlHelper extends AppHelper {
return sprintf($this->_tags[$tag], $this->_parseAttributes($options, null, ' ', ''), $text);
}
/**
* Returns a VIDEO element
*
* ### Usage
*
* Using single video file:
*
* `echo $this->Html->video('video.mp4', array('fullBase' => true, 'text' => 'Fallback text'));`
*
* Outputs:
*
* `<video src="http://www.somehost.com/files/video.mp4">Fallback text</video>`
*
* Using multiple video files:
*
* {{{
* echo $this->Html->video(
* array('video.mp4', array('src' => 'video.ogg', 'type' => "video/ogg; codecs='theora, vorbis'")),
* array('autoplay')
* );
* }}}
*
* Outputs:
*
* {{{
* <video autoplay="autoplay">
* <source src="/files/video.mp4" type="video/mp4"/>
* <source src="/files/video.ogg" type="video/ogg; codecs='theora, vorbis'"/>
* </video>
* }}}
*
* ### Options
*
* - `text` Text to include inside the video tag
* - `pathPrefix` Path prefix to use for relative urls, defaults to 'files/'
* - `fullBase` If provided the src attribute will get a full address including domain name
*
* @param string|array $path Path to the video file, relative to the webroot/{$options['pathPrefix']} directory.
* Or an array where each item itself can be a path string or an associate array containing keys `src` and `type`
* @param array $options Array of HTML attributes, and special options above.
* @return string Generated video tag
*/
public function video($path, $options = array()) {
$options += array('pathPrefix' => 'files/', 'text' => '');
if (is_array($path)) {
$response = null;
$sourceTags = '';
foreach ($path as $source) {
if (is_string($source)) {
$source = array(
'src' => $source,
);
}
if (!isset($source['type'])) {
if ($response === null) {
$response = new CakeResponse();
}
$source['type'] = $response->getMimeType(pathinfo($source['src'], PATHINFO_EXTENSION));
}
$source['src'] = $this->assetUrl($source['src'], $options);
$sourceTags .= $this->useTag('tagselfclosing', 'source', $source);
}
$options['text'] = $sourceTags . $options['text'];
unset($options['fullBase']);
} else {
$path = $this->assetUrl($path, $options);
$options['src'] = $path;
}
if (isset($options['poster'])) {
$options['poster'] = $this->assetUrl($options['poster'], array('pathPrefix' => IMAGES_URL) + $options);
}
$text = $options['text'];
$options = array_diff_key($options, array('fullBase' => '', 'pathPrefix' => '', 'text' => ''));
return $this->tag('video', $text, $options);
}
/**
* Build a nested list (UL/OL) out of an associative array.
*