Skip to content
This repository has been archived by the owner on Oct 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #348 from serlo/fix/resizing-of-edusharing-images
Browse files Browse the repository at this point in the history
fix(images): Pixabay image resizing does not overflow
  • Loading branch information
CodingDive authored Mar 1, 2024
2 parents 4fa9ce8 + 14c4333 commit 21ccbcd
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 23 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@serlo/serlo-editor-for-edusharing",
"version": "2.1.4",
"version": "2.1.5",
"private": true,
"bugs": {
"url": "https://github.com/serlo/serlo-editor-for-edusharing/issues"
Expand Down
92 changes: 70 additions & 22 deletions src/frontend/plugins/edusharing-asset/renderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,18 +104,31 @@ export function EdusharingAssetRenderer(props: {
'edusharing_rendering_content_footer { display: none;',
)

if (
content?.mimeType === 'image/jpeg' &&
const parser = new DOMParser()
const htmlDocument = parser.parseFromString(detailsSnippet, 'text/html')

const image = getImageOrUndefined(htmlDocument)

const isPixabayImage =
hasImageMimeType(content?.mimeType || '') &&
content?.node?.remote?.repository?.repositoryType === 'PIXABAY'
) {
// Positions the button to the right, makes it smaller and removes bg
// color + padding
if (isPixabayImage) {
const imageSnippet = buildImageSnippet(image)

// fetch the src link of the image (usually says "Zur Originalseite
// springen"). Note that not all pixabay images contain a source link.
const sourceLink = htmlDocument.querySelector<HTMLAnchorElement>(
'#edusharing_rendering_content_href',
)

// Positions the button to the left, makes it smaller and removes bg
// color + padding.
const shrinkPixabaySourceButton = `
<style>
#edusharing_rendering_content_href {
margin-left: 0px !important;
text-align: left !important;
margin-top: 10px !important;
margin-top: 5px !important;
display: block !important;
width: fit-content !important;
background-color: transparent !important;
Expand All @@ -126,32 +139,22 @@ export function EdusharingAssetRenderer(props: {
</style>
`

const emptyStringOrJumpToSource = sourceLink
? sourceLink.outerHTML + shrinkPixabaySourceButton
: ''

return {
html: detailsSnippet + shrinkPixabaySourceButton,
html: imageSnippet + emptyStringOrJumpToSource,
renderMethod: 'dangerously-set-inner-html',
defineContainerHeight: false,
}
}

const parser = new DOMParser()
const htmlDocument = parser.parseFromString(detailsSnippet, 'text/html')

// Image
const image = htmlDocument.querySelector<HTMLImageElement>(
'.edusharing_rendering_content_wrapper > img',
)

const isImageSnippet =
image && !image.classList.contains('edusharing_rendering_content_preview')
if (isImageSnippet) {
// Create completely new <img> element because patching the existing one is more work/error-prone
const imageSnippet = `
<img style="width: 100%; object-fit: contain;" src="${image.getAttribute(
'src',
)}" alt="${image.getAttribute('alt')}" title="${image.getAttribute(
'title',
)}" />
`
const imageSnippet = buildImageSnippet(image)
return {
html: imageSnippet,
renderMethod: 'dangerously-set-inner-html',
Expand Down Expand Up @@ -256,6 +259,9 @@ export function EdusharingAssetRenderer(props: {
return (
<div
className={`not-prose overflow-auto max-w-full`}
// className={`not-prose overflow-auto max-w-full !w-[${
// contentWidth ? contentWidth : '100%'
// }]`}
style={{
width: contentWidth ? contentWidth : '100%',
aspectRatio: defineContainerHeight ? '16/9' : undefined,
Expand Down Expand Up @@ -304,6 +310,48 @@ export function EdusharingAssetRenderer(props: {
}
}

function getImageOrUndefined(
htmlDocument: Document,
): HTMLImageElement | undefined {
const image =
htmlDocument.querySelector<HTMLImageElement>(
'.edusharing_rendering_content_wrapper > img',
) ??
htmlDocument.querySelector<HTMLImageElement>(
'.edusharing_rendering_content',
)

if (image && image.nodeName !== 'IMG') {
return undefined
}

return image
}

function buildImageSnippet(image: HTMLImageElement): string {
return `
<img style="width: 100%; object-fit: contain;" src="${image.getAttribute(
'src',
)}" alt="${image.getAttribute('alt')}" title="${image.getAttribute(
'title',
)}" />
`
}

const imageMimeTypes = [
'image/jpeg',
'image/png',
'image/gif',
'image/webp',
'image/svg+xml',
'image/bmp',
'image/tiff',
]

function hasImageMimeType(mimeType: string): boolean {
return imageMimeTypes.includes(mimeType)
}

// Only re-render if `srcDoc` prop changed. We do not want to re-render the Iframe every time when EdusharingAssetRenderer is re-rendered because the state within the iframe is lost.
const MemoizedIframeResizer = memo(
IframeResizer,
Expand Down

0 comments on commit 21ccbcd

Please sign in to comment.