Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

42678 adaptive image resolution #710

Merged
merged 32 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d11c0aa
42678 adaptive image resolution
yeneastgate Dec 28, 2023
9fdd269
42678 update unit test
yeneastgate Dec 28, 2023
7821c29
42678 refactor code
yeneastgate Dec 29, 2023
a983cf2
Merge branch 'master' into 42678-adaptive-image-resolution
yeneastgate Jan 3, 2024
8ad4d12
Merge branch 'master' into 42678-adaptive-image-resolution
yeneastgate Apr 23, 2024
c6d1c90
Merge branch 'master' into 42678-adaptive-image-resolution
fredericalpers May 8, 2024
f139de8
Merge branch 'master' into 42678-adaptive-image-resolution
yeneastgate May 16, 2024
c7ba1f0
refactor and fix output for responsive image sources
andernath May 23, 2024
b09d572
Merge remote-tracking branch 'origin/42678-adaptive-image-resolution'…
andernath May 23, 2024
77456a8
fix unit test
andernath May 23, 2024
0ee616f
fix unit test
andernath May 27, 2024
d783150
fix unit test
andernath May 27, 2024
65f7c97
fix unit test
andernath May 27, 2024
c527e1c
fix unit test
andernath May 27, 2024
3ac8b6b
fix unit test
andernath May 27, 2024
92f54c0
fix unit test
andernath May 27, 2024
d0e4447
fix smoketest for <=PHP7.2
andernath May 27, 2024
2137c0f
fix width and height dimensions
andernath May 28, 2024
3cad47c
fix unittests
andernath May 29, 2024
5419dd8
Remove unused params
andernath May 29, 2024
45a91a2
Fix missing styling
andernath May 29, 2024
db9841a
adapt image sizes
pospisk Jun 12, 2024
56c352e
renamed variable
pospisk Jun 12, 2024
2500006
adapt image sizes
pospisk Jun 12, 2024
b1d807d
adapt image sizes
pospisk Jun 12, 2024
c5c98ec
fix unit test
pospisk Jun 12, 2024
bdb074d
fix unit test
pospisk Jun 12, 2024
33b7366
revert
pospisk Jun 12, 2024
bb8808b
fix unit test
pospisk Jun 12, 2024
3801d29
fix unit test
pospisk Jun 12, 2024
2c356bb
revert width sizes to a value with the best possible compatibility wi…
andernath Jun 18, 2024
dc9bcca
Change image width on mobile to fit for lighthouse testing
andernath Jun 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions css/onoffice-default.css
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,21 @@ div.multiselect[data-values=""] > input[type=button] {
opacity: 0.7;
}

.oo-picture {
display: block;
height: 100%;
width: 100%;
line-height: 0;
overflow: hidden;
}

.oo-responsive-image {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center center;
}

@keyframes rotating {
from {
transform: rotate(0deg);
Expand Down
18 changes: 18 additions & 0 deletions plugin/EstateList.php
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,24 @@ public function getEstatePictureTitle($imageId)
return $this->_pEstateFiles->getEstatePictureTitle($imageId, $currentEstate);
}

/**
* @param int $imageId
* @param int $breakPoint
* @param float|null $width
* @param float|null $height
* @param bool $maxWidth
* @return string
*/
public function getResponsiveImageSource(int $imageId, int $breakPoint, float $width = null, float $height = null, bool $maxWidth = false) {
$imageUrl = $this->getEstatePictureUrl( $imageId, ['width'=> $width, 'height'=>$height]);
$sourceTag = '<source media="(' . ($maxWidth ? 'max-width:' : 'min-width:') . $breakPoint . 'px)" srcset="';
return $sourceTag .
$imageUrl . (isset($width) ? '&w=' . $width : '') . (isset($height) ? '&h=' . $height : '') . ' 1x,' .
$imageUrl . (isset($width) ? '&w=' . $width * 1.5 : '') . (isset($height) ? '&h=' . $height * 1.5 : '') . ' 1.5x,' .
$imageUrl . (isset($width) ? '&w=' . $width * 2 : '') . (isset($height) ? '&h=' . $height * 2 : '') . ' 2x,' .
$imageUrl . (isset($width) ? '&w=' . $width * 3 : '') . (isset($height) ? '&h=' . $height * 3 : '') . ' 3x">';
}

/**
* @param int $imageId
* @return string
Expand Down
78 changes: 76 additions & 2 deletions templates.dist/estate/default.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,58 @@

$dontEcho = array("objekttitel", "objektbeschreibung", "lage", "ausstatt_beschr", "sonstige_angaben", "MPAreaButlerUrlWithAddress", "MPAreaButlerUrlNoAddress");

// picture properties
$image_width_xs = 539;
$image_width_sm = 508;
$image_width_md = 690;
$image_width_lg = 444;
$image_width_xl = 540;
$image_width_xxl = 412;
$image_width_xxxl = 456;
$dimensions = [
'575' => [
'w' => $image_width_xs,
'h' => round(
($image_width_xs * 2) / 3,
),
],
'1600' => [
'w' => $image_width_xxxl,
'h' => round(
($image_width_xxxl * 2) / 3,
),
],
'1400' => [
'w' => $image_width_xxl,
'h' => round(
($image_width_xxl * 2) / 3,
),
],
'1200' => [
'w' => $image_width_xl,
'h' => round(
($image_width_xl * 2) / 3,
),
],
'992' => [
'w' => $image_width_lg,
'h' => round(
($image_width_lg * 2) / 3,
),
],
'768' => [
'w' => $image_width_md,
'h' => round(
($image_width_md * 2) / 3,
),
],
'576' => [
'w' => $image_width_sm,
'h' => round(
($image_width_sm * 2) / 3,
),
]
];
?>

<style>
Expand Down Expand Up @@ -84,10 +136,32 @@
$pictureValues = $pEstatesClone->getEstatePictureValues( $id );

if ( $referenz === "1" && $pEstatesClone->getViewRestrict() ) {
echo '<div style="background-image: url(' . esc_url( $pEstatesClone->getEstatePictureUrl( $id, [ 'height' => 350 ] ) ) . ');" class="oo-listimage estate-status">';
echo '<div class="oo-listimage estate-status">';
} else {
echo '<a href="' . esc_url( $pEstatesClone->getEstateLink() ) . '" style="background-image: url(' . esc_url( $pEstatesClone->getEstatePictureUrl( $id, [ 'height' => 350 ] ) ) . ');" class="oo-listimage estate-status">';
echo '<a class="oo-listimage estate-status" href="' . esc_url($pEstatesClone->getEstateLink()) . '">';
}
echo '<picture class="oo-picture">';
/**
* getResponsiveImageSource(
* @param int $imageId
* @param int $mediaBreakPoint
* @param float|null $imageWidth for media breakpoint, optional
* @param float|null $imageHeight for media breakpoint, optional
* @param bool $maxWidth, default = false)
* @return string for image source on various media
*/
echo $pEstatesClone->getResponsiveImageSource($id, 575, $dimensions['575']['w'], $dimensions['575']['h'], true);
echo $pEstatesClone->getResponsiveImageSource($id, 1600, $dimensions['1600']['w'], $dimensions['1600']['h']);
echo $pEstatesClone->getResponsiveImageSource($id, 1400, $dimensions['1400']['w'], $dimensions['1400']['h']);
echo $pEstatesClone->getResponsiveImageSource($id, 1200, $dimensions['1200']['w'], $dimensions['1200']['h']);
echo $pEstatesClone->getResponsiveImageSource($id, 992, $dimensions['992']['w'], $dimensions['992']['h']);
echo $pEstatesClone->getResponsiveImageSource($id, 768, $dimensions['768']['w'], $dimensions['768']['h']);
echo $pEstatesClone->getResponsiveImageSource($id, 576, $dimensions['576']['w'], $dimensions['576']['h']);
echo '<img class="oo-responsive-image estate-status" ' .
'src="' . esc_url($pEstatesClone->getEstatePictureUrl($id, ['width'=> $dimensions['1600']['w'], 'height'=>$dimensions['1600']['h']])) . '" ' .
'alt="' . esc_html($pEstatesClone->getEstatePictureTitle($id)?? __('Image of property', 'onoffice-for-wp-websites')) . '" ' .
'loading="lazy"/>';
echo '</picture>';
if ($pictureValues['type'] === \onOffice\WPlugin\Types\ImageTypes::TITLE && $marketingStatus != '') {
echo '<span>'.esc_html($marketingStatus).'</span>';
}
Expand Down
61 changes: 57 additions & 4 deletions templates.dist/estate/default_detail.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,39 @@

$dontEcho = array("objekttitel", "objektbeschreibung", "lage", "ausstatt_beschr", "sonstige_angaben", "MPAreaButlerUrlWithAddress", "MPAreaButlerUrlNoAddress");
/** @var EstateDetail $pEstates */

// picture properties
$image_height_xs = 400;
$image_height_sm = 400;
$image_height_md = 400;
$image_height_lg = 400;
$image_height_xl = 400;
$image_height_xxl = 400;
$image_height_xxxl = 400;

$dimensions = [
'575' => [
'h' => $image_height_xs,
],
'1600' => [
'h' => $image_height_xxxl,
],
'1400' => [
'h' => $image_height_xxl,
],
'1200' => [
'h' => $image_height_xl,
],
'992' => [
'h' => $image_height_lg,
],
'768' => [
'h' => $image_height_md,
],
'576' => [
'h' => $image_height_sm,
]
];
pospisk marked this conversation as resolved.
Show resolved Hide resolved
?>
<style>
ul.oo-listparking {
Expand All @@ -55,10 +88,30 @@
<?php
$estatePictures = $pEstates->getEstatePictures();
foreach ($estatePictures as $id) {
printf(
'<div class="oo-detailspicture" style="background-image: url(\'%s\');"></div>' . "\n",
esc_url($pEstates->getEstatePictureUrl($id))
);
echo '<div class="oo-detailspicture">';
echo '<picture class="oo-picture">';
/**
* getResponsiveImageSource(
* @param int $imageId
* @param int $mediaBreakPoint
* @param float|null $imageWidth for media breakpoint, optional
* @param float|null $imageHeight for media breakpoint, optional
* @param bool $maxWidth, default = false)
* @return string for image source on various media
*/
echo $pEstates->getResponsiveImageSource($id, 575, $dimensions['575']['w'], $dimensions['575']['h'], true);
echo $pEstates->getResponsiveImageSource($id, 1600, $dimensions['1600']['w'], $dimensions['1600']['h']);
echo $pEstates->getResponsiveImageSource($id, 1400, $dimensions['1400']['w'], $dimensions['1400']['h']);
echo $pEstates->getResponsiveImageSource($id, 1200, $dimensions['1200']['w'], $dimensions['1200']['h']);
echo $pEstates->getResponsiveImageSource($id, 992, $dimensions['992']['w'], $dimensions['992']['h']);
echo $pEstates->getResponsiveImageSource($id, 768, $dimensions['768']['w'], $dimensions['768']['h']);
echo $pEstates->getResponsiveImageSource($id, 576, $dimensions['576']['w'], $dimensions['576']['h']);
echo '<img class="oo-responsive-image estate-status" ' .
'src="' . esc_url($pEstates->getEstatePictureUrl($id, ['width'=> $dimensions['1600']['w'], 'height'=>$dimensions['1600']['h']])) . '" ' .
pospisk marked this conversation as resolved.
Show resolved Hide resolved
'alt="' . esc_html($pEstates->getEstatePictureTitle($id) ?? __('Image of property', 'onoffice-for-wp-websites')) . '" ' .
'loading="lazy"/>';
echo '</picture>';;
echo '</div>';
}
?>
</div>
Expand Down
82 changes: 79 additions & 3 deletions templates.dist/estate/similar_estates.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,58 @@
<?php $dontEcho = array("objekttitel", "objektbeschreibung", "lage", "ausstatt_beschr", "sonstige_angaben", "MPAreaButlerUrlWithAddress", "MPAreaButlerUrlNoAddress"); ?>
<?php $dontEcho = array("objekttitel", "objektbeschreibung", "lage", "ausstatt_beschr", "sonstige_angaben", "MPAreaButlerUrlWithAddress", "MPAreaButlerUrlNoAddress");
,
// picture properties
$image_width_xs = 539;
$image_width_sm = 508;
$image_width_md = 690;
$image_width_lg = 444;
$image_width_xl = 540;
$image_width_xxl = 412;
$image_width_xxxl = 456;
$dimensions = [
'575' => [
'w' => $image_width_xs,
'h' => round(
($image_width_xs * 2) / 3,
),
],
'1600' => [
'w' => $image_width_xxxl,
'h' => round(
($image_width_xxxl * 2) / 3,
),
],
'1400' => [
'w' => $image_width_xxl,
'h' => round(
($image_width_xxl * 2) / 3,
),
],
'1200' => [
'w' => $image_width_xl,
'h' => round(
($image_width_xl * 2) / 3,
),
],
'992' => [
'w' => $image_width_lg,
'h' => round(
($image_width_lg * 2) / 3,
),
],
'768' => [
'w' => $image_width_md,
'h' => round(
($image_width_md * 2) / 3,
),
],
'576' => [
'w' => $image_width_sm,
'h' => round(
($image_width_sm * 2) / 3,
),
]
];
?>

<style>
.oo-details-btn:focus {
Expand Down Expand Up @@ -27,10 +81,32 @@
foreach ( $estatePictures as $id ) {
$pictureValues = $pEstates->getEstatePictureValues( $id );
if ( $referenz === "1" && $pEstates->getViewRestrict() ) {
echo 'div style="background-image: url('.esc_url($pEstates->getEstatePictureUrl( $id )).');" class="oo-listimage">';
echo '<div class="oo-listimage">';
} else {
echo '<a href="'.$pEstates->getEstateLink().'" style="background-image: url('.esc_url($pEstates->getEstatePictureUrl( $id )).');" class="oo-listimage">';
echo '<a class="oo-listimage estate-status" href="' . esc_url($pEstates->getEstateLink()) . '">';
}
echo '<picture class="oo-picture">';
/**
* getResponsiveImageSource(
* @param int $imageId
* @param int $mediaBreakPoint
* @param float|null $imageWidth for media breakpoint, optional
* @param float|null $imageHeight for media breakpoint, optional
* @param bool $maxWidth, default = false)
* @return string for image source on various media
*/
echo $pEstates->getResponsiveImageSource($id, 575, $dimensions['575']['w'], $dimensions['575']['h'], true);
echo $pEstates->getResponsiveImageSource($id, 1600, $dimensions['1600']['w'], $dimensions['1600']['h']);
echo $pEstates->getResponsiveImageSource($id, 1400, $dimensions['1400']['w'], $dimensions['1400']['h']);
echo $pEstates->getResponsiveImageSource($id, 1200, $dimensions['1200']['w'], $dimensions['1200']['h']);
echo $pEstates->getResponsiveImageSource($id, 992, $dimensions['992']['w'], $dimensions['992']['h']);
echo $pEstates->getResponsiveImageSource($id, 768, $dimensions['768']['w'], $dimensions['768']['h']);
echo $pEstates->getResponsiveImageSource($id, 576, $dimensions['576']['w'], $dimensions['576']['h']);
echo '<img class="oo-responsive-image estate-status" ' .
'src="' . esc_url($pEstates->getEstatePictureUrl($id, ['width'=> $dimensions['1600']['w'], 'height'=>$dimensions['1600']['h']])) . '" ' .
'alt="' . esc_html($pEstates->getEstatePictureTitle($id) ?? __('Image of property', 'onoffice-for-wp-websites')) . '" ' .
'loading="lazy"/>';
echo '</picture>';
if ($pictureValues['type'] === \onOffice\WPlugin\Types\ImageTypes::TITLE && $marketingStatus != '') {
echo '<span>'.esc_html($marketingStatus).'</span>';
}
Expand Down
51 changes: 51 additions & 0 deletions tests/TestClassEstateList.php
Original file line number Diff line number Diff line change
Expand Up @@ -1043,4 +1043,55 @@ public function getEstateFieldsData() {
}
return $fieldsCollection;
}

/**
*
*/
public function getResponsiveImageSource()
{
$this->_pEstateList->loadEstates();
$this->_pEstateList->estateIterator();
ob_start();
$this->_pEstateList->getResponsiveImageSource(2, 1600, 456, round((456* 2) / 3));
$output = ob_get_clean();
$this->assertEquals($output,
'<source media="(min-width:1600px)" srcset="https://test.url/image/2.jpg@456x304&w=456&h=304 1x, https://test.url/image/2.jpg@456x304&w=684&h=456 1.5x, https://test.url/image/2.jpg@456x304&w=912&h=608 2x, https://test.url/image/2.jpg@456x304&w=1368&h=912 3x" />'
);
}

public function getResponsiveImageSourceForMobile()
{
$this->_pEstateList->loadEstates();
$this->_pEstateList->estateIterator();
ob_start();
$this->_pEstateList->getResponsiveImageSource(2, 575, 456, round((456* 2) / 3), true);
$output = ob_get_clean();
$this->assertEquals($output,
'<source media="(max-width:575px)" srcset="https://test.url/image/2.jpg@456x304&w=456&h=304 1x, https://test.url/image/2.jpg@456x304&w=684&h=456 1.5x, https://test.url/image/2.jpg@456x304&w=912&h=608 2x, https://test.url/image/2.jpg@456x304&w=1368&h=912 3x" />'
);
}

public function getResponsiveImageSourceWithoutWidth()
{
$this->_pEstateList->loadEstates();
$this->_pEstateList->estateIterator();
ob_start();
$this->_pEstateList->getResponsiveImageSource(2, 1600, null, 400);
$output = ob_get_clean();
$this->assertEquals($output,
'<source media="(min-width:1600px)" srcset="https://test.url/image/2.jpg@400&h=400 1x, https://test.url/image/2.jpg@400&h=600 1.5x, https://test.url/image/2.jpg@400&h=800 2x, https://test.url/image/2.jpg@400&h=1200 3x" />'
);
}

public function getResponsiveImageSourceWithoutHeight()
{
$this->_pEstateList->loadEstates();
$this->_pEstateList->estateIterator();
ob_start();
$this->_pEstateList->getResponsiveImageSource(2, 1600, 456);
$output = ob_get_clean();
$this->assertEquals($output,
'<source media="(min-width:1600px)" srcset="https://test.url/image/2.jpg@456&w=456 1x, https://test.url/image/2.jpg@456&w=684 1.5x, https://test.url/image/2.jpg@456&w=912 2x, https://test.url/image/2.jpg@456&w=1368 3x" />'
);
}
}
3 changes: 1 addition & 2 deletions tests/resources/templates/output_default_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ <h1>flach begrüntes Grundstück</h1>
</div>
<div class="oo-details-main">
<div class="oo-detailsgallery" id="oo-galleryslide">
<div class="oo-detailspicture" style="background-image: url('https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg');"></div>
</div>
<div class="oo-detailspicture"><picture class="oo-picture"><source media="(min-width:1600px)" srcset="https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1.5x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 2x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 3x" /><source media="(min-width:1400px)" srcset="https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1.5x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 2x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 3x" /><source media="(min-width:1200px)" srcset="https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1.5x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 2x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 3x" /><source media="(min-width:992px)" srcset="https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1.5x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 2x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 3x" /><source media="(min-width:768px)" srcset="https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1.5x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 2x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 3x" /><source media="(min-width:576px)" srcset="https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1.5x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 2x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 3x" /><source media="(max-width:575px)" srcset="https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 1.5x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 2x, https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg 3x" /><img class="oo-responsive-image estate-status" src="https://image.onoffice.de/smart25/Objekte/index.php?kunde=Ivanova&#038;datensatz=52&#038;filename=Titelbild_362.jpg" alt="" loading="lazy"/></picture></div> </div>
<div class="oo-detailstable">
<div class="oo-detailslisttd">label-objektart</div>
<div class="oo-detailslisttd">Grundstück</div>
Expand Down
Loading