Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9f39283

Browse filesBrowse files
authored
Fixed placeholder when using responsive lazy load (#256)
1 parent afa2047 commit 9f39283
Copy full SHA for 9f39283

File tree

Expand file treeCollapse file tree

3 files changed

+82
-11
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+82
-11
lines changed

‎projects/angular-cld/src/lib/cloudinary-image.component.spec.ts

Copy file name to clipboardExpand all lines: projects/angular-cld/src/lib/cloudinary-image.component.spec.ts
+62-3Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -824,8 +824,8 @@ describe('CloudinaryImage', () => {
824824
tick();
825825
fixture.detectChanges();
826826
const img = des[0].children[0].nativeElement as HTMLImageElement;
827-
expect(img.attributes.getNamedItem('src').value).toEqual('http://res.cloudinary.com/' +
828-
'@@fake_angular2_sdk@@/image/upload/c_fit,w_30/ar_1,b_auto,c_pad,w_iw_div_2/c_crop,g_north_east,h_10,w_10/c_fill,h_ih,w_iw/f_auto,q_auto/bear');
827+
expect(img.attributes.getNamedItem('src').value).toEqual('http://res.cloudinary.com/@@fake_angular2_sdk@@/image/' +
828+
'upload/c_fit,w_30/$currWidth_w,$currHeight_h/ar_1,b_auto,c_pad,w_iw_div_2/c_crop,g_north_east,h_10,w_10/c_fill,h_$currHeight,w_$currWidth/f_auto,q_auto/bear');
829829
}));
830830
});
831831
describe('placeholder type vectorize', () => {
@@ -977,5 +977,64 @@ describe('CloudinaryImage', () => {
977977
}
978978
});
979979
});
980-
});
980+
describe('cl-image with responsive and placeholder on lazy load', async () => {
981+
@Component({
982+
template: `<div class="startWindow"><cl-image loading="lazy" width="300" public-id="bear"></cl-image></div>
983+
<div style="margin-top: 700px"><cl-image loading="lazy" width="300" public-id="bear"></cl-image></div>
984+
<div style="margin-top: 700px"><cl-image loading="lazy" public-id="bear" responsive width="auto" crop="scale">
985+
<cl-placeholder></cl-placeholder>
986+
</cl-image></div>
987+
<div style="margin-top: 700px"><cl-image loading="lazy" width="300" public-id="bear"></cl-image></div>
988+
<div style="margin-top: 700px"><cl-image loading="lazy" width="300" public-id="bear"></cl-image></div>
989+
<div style="margin-top: 700px"><cl-image loading="lazy" width="300" public-id="bear"></cl-image></div>
990+
<div style="margin-top: 700px"><cl-image loading="lazy" width="300" public-id="bear"></cl-image></div>
991+
<div class="endWindow" style="margin-top: 700px"><cl-image loading="lazy" width="300" public-id="bear"></cl-image></div>`
992+
})
993+
class TestComponent {}
994+
995+
let fixture: ComponentFixture<TestComponent>;
996+
let des: DebugElement[]; // the elements w/ the directive
997+
let placeholder: DebugElement[];
998+
let testLocalCloudinary: Cloudinary = new Cloudinary(require('cloudinary-core'),
999+
{ cloud_name: '@@fake_angular2_sdk@@', client_hints: true } as CloudinaryConfiguration);
1000+
beforeEach(fakeAsync(() => {
1001+
fixture = TestBed.configureTestingModule({
1002+
declarations: [CloudinaryTransformationDirective, CloudinaryImage, TestComponent, LazyLoadDirective, CloudinaryPlaceHolder],
1003+
providers: [{ provide: Cloudinary, useValue: testLocalCloudinary }]
1004+
}).createComponent(TestComponent);
1005+
1006+
fixture.detectChanges(); // initial binding
1007+
// all elements with an attached CloudinaryImage
1008+
des = fixture.debugElement.queryAll(By.directive(CloudinaryImage));
1009+
placeholder = fixture.debugElement.queryAll(By.directive(CloudinaryPlaceHolder));
1010+
tick();
1011+
fixture.detectChanges();
1012+
}));
1013+
it('Placeholder width should equal img width on Firefox', async () => {
1014+
const placeholderimg = placeholder[0].children[0].nativeElement as HTMLImageElement;
1015+
const img = des[2].children[0].nativeElement as HTMLImageElement;
1016+
1017+
const delay = 300;
1018+
const wait = (ms) => new Promise(res => setTimeout(res, ms));
1019+
const count = async () => document.querySelectorAll('.startWindow').length;
1020+
const scrollDown = async () => {
1021+
document.querySelector('.endWindow')
1022+
.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'end' });
1023+
}
1024+
1025+
let preCount = 0;
1026+
let postCount = 0;
1027+
do {
1028+
preCount = await count();
1029+
await scrollDown();
1030+
await wait(delay);
1031+
postCount = await count();
1032+
} while (postCount > preCount);
1033+
await wait(delay);
9811034

1035+
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
1036+
expect(placeholderimg.attributes.getNamedItem('width')).toEqual(img.attributes.getNamedItem('width'));
1037+
}
1038+
});
1039+
});
1040+
});

‎projects/angular-cld/src/lib/cloudinary-image.component.ts

Copy file name to clipboardExpand all lines: projects/angular-cld/src/lib/cloudinary-image.component.ts
+18-7Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ export class CloudinaryImage
126126
delete options['responsive'];
127127
}
128128
if (this.placeholderComponent) {
129-
this.placeholderHandler(options);
129+
this.placeholderHandler(options, image);
130130
}
131131
if (this.accessibility) {
132132
this.options = options;
@@ -148,12 +148,23 @@ export class CloudinaryImage
148148
});
149149
}
150150

151-
placeholderHandler(options) {
152-
const placeholderOptions = {};
153-
154-
Object.keys(options).forEach(name => {
155-
placeholderOptions[name] = (name === 'width' && !options[name].startsWith('auto') || name === 'height') ? Math.ceil(parseInt(options[name], 10) * 0.1) : options[name];
156-
});
151+
/**
152+
* Handles placeholder options
153+
* In case of responsive sets width from resize
154+
* In case width or height is known takes 10% of original dimension
155+
*/
156+
placeholderHandler(options, image) {
157+
const placeholderOptions = { ...options };
158+
if (placeholderOptions['width']) {
159+
if (placeholderOptions['width'] === 'auto') {
160+
placeholderOptions['width'] = image.getAttribute('data-width');
161+
} else {
162+
placeholderOptions['width'] = Math.ceil(parseInt(options['width'], 10) * 0.1);
163+
}
164+
}
165+
if (placeholderOptions['height']) {
166+
placeholderOptions['height'] = Math.ceil(parseInt(options['height'], 10) * 0.1);
167+
}
157168
this.placeholderComponent.options = placeholderOptions;
158169
}
159170

‎projects/angular-cld/src/lib/constants.ts

Copy file name to clipboardExpand all lines: projects/angular-cld/src/lib/constants.ts
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ export const predominantColorTransformPxl = [
1111
{fetch_format: 'auto', quality: 'auto'}];
1212

1313
export const predominantColorTransform = [
14+
{variables: [['$currWidth', 'w'], ['$currHeight', 'h']]},
1415
{width: 'iw_div_2', aspect_ratio: 1, crop: 'pad', background: 'auto'},
1516
{crop: 'crop', width: 10, height: 10, gravity: 'north_east'},
16-
{width: 'iw', height: 'ih', crop: 'fill'},
17+
{width: '$currWidth', height: '$currHeight', crop: 'fill'},
1718
{fetch_format: 'auto', quality: 'auto'}];
1819

1920
export const placeholderImageOptions = {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.