Skip to content
Snippets Groups Projects
Unverified Commit 3ab46e21 authored by Lauri Timmanee's avatar Lauri Timmanee
Browse files

Issue #2998091 by phenaproxima, RajabNatshah, Niklan, Wim Leers, starshaped,...

Issue #2998091 by phenaproxima, RajabNatshah, Niklan, Wim Leers, starshaped, lauriii, maseyuk, seanB, Kasey_MK: Remote videos overflow their containing element
parent 406f483f
No related branches found
No related tags found
No related merge requests found
Showing
with 93 additions and 7 deletions
.media-oembed-content {
max-width: 100%;
}
iframe {
position: absolute;
left: 0;
top: 0;
margin: 0;
width: 100%;
height: 100%;
}
......@@ -11,3 +11,15 @@ type_form:
js/type_form.js: {}
dependencies:
- core/drupal.form
oembed.formatter:
version: VERSION
css:
component:
css/oembed.formatter.css: {}
oembed.frame:
version: VERSION
css:
component:
css/oembed.frame.css: {}
......@@ -77,6 +77,7 @@ function media_theme() {
'media_oembed_iframe' => [
'variables' => [
'media' => NULL,
'placeholder_token' => '',
],
],
];
......
......@@ -4,8 +4,8 @@
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Cache\CacheableResponse;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Render\HtmlResponse;
use Drupal\Core\Render\RenderContext;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Url;
......@@ -132,13 +132,15 @@ public function render(Request $request) {
// Return a response instead of a render array so that the frame content
// will not have all the blocks and page elements normally rendered by
// Drupal.
$response = new CacheableResponse();
$response = new HtmlResponse();
$response->addCacheableDependency(Url::createFromRequest($request));
try {
$resource_url = $this->urlResolver->getResourceUrl($url, $max_width, $max_height);
$resource = $this->resourceFetcher->fetchResource($resource_url);
$placeholder_token = Crypt::randomBytesBase64(55);
// Render the content in a new render context so that the cacheability
// metadata of the rendered HTML will be captured correctly.
$element = [
......@@ -153,12 +155,22 @@ public function render(Request $request) {
// \Drupal\Core\Render\MainContent\HtmlRenderer::renderResponse().
'tags' => ['rendered'],
],
'#attached' => [
'html_response_attachment_placeholders' => [
'styles' => '<css-placeholder token="' . $placeholder_token . '">',
],
'library' => [
'media/oembed.frame',
],
],
'#placeholder_token' => $placeholder_token,
];
$content = $this->renderer->executeInRenderContext(new RenderContext(), function () use ($resource, $element) {
return $this->renderer->render($element);
});
$response
->setContent($content)
->setAttachments($element['#attached'])
->addCacheableDependency($resource)
->addCacheableDependency(CacheableMetadata::createFromRenderArray($element));
}
......
......@@ -220,6 +220,12 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
'allowtransparency' => TRUE,
'width' => $max_width ?: $resource->getWidth(),
'height' => $max_height ?: $resource->getHeight(),
'class' => ['media-oembed-content'],
],
'#attached' => [
'library' => [
'media/oembed.formatter',
],
],
];
......
......@@ -8,6 +8,9 @@
#}
<!DOCTYPE html>
<html>
<head>
<css-placeholder token="{{ placeholder_token }}">
</head>
<body style="margin: 0">
{{ media|raw }}
</body>
......
......@@ -6,7 +6,7 @@
"title": "Drupal Rap Video - Schipulcon09",
"author_name": "Tendenci - The Open Source AMS",
"author_url": "https:\/\/vimeo.com\/schipul",
"html": "<h1>By the power of Greyskull, Vimeo works!</h1>",
"html": "<iframe width=\"480\">By the power of Greyskull, Vimeo works!</iframe>",
"width": 480,
"height": 360,
"description": "Special thanks to Tendenci, formerly Schipul for sponsoring this video with training, equipment and time. The open source way. All creative however was self directed by the individuals - A. Hughes (www.schipul.com\/ahughes) featuring QCait (www.schipul.com\/qcait) - Hands On Drupal\n\nDrupal is a free software package that allows an individual or a community of users to easily publish, manage and organize a wide variety of content on a website.\n\nNeed a little Drupal help or just want to geek out with us? Visit our www.schipul.com\/drupal for more info - we'd love to connect!\n\nGo here for Drupal Common Terms and Suggested Modules : http:\/\/schipul.com\/en\/helpfiles\/v\/229",
......
......@@ -91,6 +91,16 @@ public function testMediaOEmbedVideoSource() {
$assert_session->selectExists('field_map[author_name]')->setValue('field_string_author_name');
$assert_session->buttonExists('Save')->press();
// Configure the iframe to be narrower than the actual video, so we can
// verify that the video scales correctly.
$display = entity_get_display('media', $media_type_id, 'default');
$this->assertFalse($display->isNew());
$component = $display->getComponent('field_media_oembed_video');
$this->assertInternalType('array', $component);
$component['settings']['max_width'] = 240;
$display->setComponent('field_media_oembed_video', $component);
$this->assertSame(SAVED_UPDATED, $display->save());
$this->hijackProviderEndpoints();
$video_url = 'https://vimeo.com/7073899';
ResourceController::setResourceUrl($video_url, $this->getFixturesDirectory() . '/video_vimeo.json');
......@@ -112,16 +122,24 @@ public function testMediaOEmbedVideoSource() {
$thumbnail = $media->getSource()->getMetadata($media, 'thumbnail_uri');
$this->assertFileExists($thumbnail);
// Ensure the iframe exists and that its src attribute contains a coherent
// URL with the query parameters we expect.
$iframe_url = $assert_session->elementExists('css', 'iframe')->getAttribute('src');
$iframe_url = parse_url($iframe_url);
// Ensure the iframe exists and has the expected CSS class, and that its src
// attribute contains a coherent URL with the query parameters we expect.
$iframe = $assert_session->elementExists('css', 'iframe.media-oembed-content');
$iframe_url = parse_url($iframe->getAttribute('src'));
$this->assertStringEndsWith('/media/oembed', $iframe_url['path']);
$this->assertNotEmpty($iframe_url['query']);
$query = [];
parse_str($iframe_url['query'], $query);
$this->assertSame($video_url, $query['url']);
$this->assertNotEmpty($query['hash']);
// Ensure that the outer iframe's width respects the formatter settings.
$this->assertSame('240', $iframe->getAttribute('width'));
// Check the inner iframe to make sure that CSS has been applied to scale it
// correctly, regardless of whatever its width attribute may be (the fixture
// hard-codes it to 480).
$inner_frame = 'frames[0].document.querySelector("iframe")';
$this->assertSame('480', $session->evaluateScript("$inner_frame.getAttribute('width')"));
$this->assertLessThanOrEqual(240, $session->evaluateScript("$inner_frame.clientWidth"));
// Make sure the thumbnail is displayed from uploaded image.
$assert_session->elementAttributeContains('css', '.image-style-thumbnail', 'src', '/oembed_thumbnails/' . basename($thumbnail));
......
.media-oembed-content {
max-width: 100%;
}
iframe {
position: absolute;
left: 0;
top: 0;
margin: 0;
width: 100%;
height: 100%;
}
......@@ -139,6 +139,15 @@ libraries-override:
component:
css/locale.admin.css: css/locale/locale.admin.css
media/oembed.formatter:
css:
component:
css/oembed.formatter.css: css/media/oembed.formatter.css
media/oembed.frame:
css:
component:
css/oembed.frame.css: css/media/oembed.frame.css
menu_ui/drupal.menu_ui.adminforms:
css:
theme:
......
......@@ -8,6 +8,9 @@
#}
<!DOCTYPE html>
<html>
<head>
<css-placeholder token="{{ placeholder_token }}">
</head>
<body style="margin: 0">
{{ media|raw }}
</body>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment