Skip to content
Snippets Groups Projects
Unverified Commit 2d9b1a0f 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

(cherry picked from commit 3ab46e21)
parent a73bf047
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