-
Notifications
You must be signed in to change notification settings - Fork 772
feat(srcset): add srcset directive to inject <source> elements to sup… #366
Conversation
@ThomasBurleson can you please review ? |
src/lib/flexbox/api/img-srcset.ts
Outdated
private _inputSourceEltMap: {[input: string]: any} = {}; | ||
|
||
/* tslint:disable */ | ||
@Input('srcset.xs') set srcsetXs(val) {this._cacheInput('srcsetXs', val);} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benbraou - you will need a selector and setter for [srcset]
also... to cache the default, static value. When the responsive breakpoint deactivates , it is possible that fallback static value (which is used to clear the deactivated value) will be used (if no other breakpoints activate). This means you must databind to srcset
and simply cache the value.
See example here: https://github.com/angular/flex-layout/blob/master/src/lib/flexbox/api/style.ts#L62-L66
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benbraou - if you want this in Beta.9, we must fix within the next 24 hours.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bloody hell.... HURRY MAN! 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ThomasBurleson :requested change is done. Thanks a lot for the explanation ^^
d65e00a
to
0680d15
Compare
src/lib/flexbox/api/img-srcset.ts
Outdated
* backward compatibility. | ||
*/ | ||
protected _injectSourceElements() { | ||
if (!this._mqActivation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to check angular/universal SSR.
let isBrowser = getDom().supportsDOMEvents();
if (!this._mqActivation || !isBrowser) {
return;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change done. PR will be updated shortly
src/lib/flexbox/api/img-srcset.ts
Outdated
|
||
/** Reference to injected source elements to be used when there is a need to update their | ||
* attributes. */ | ||
private _inputSourceEltMap: {[input: string]: any} = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change name to _registrySourceElements
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change done. PR will be updated shortly
srcset.md="https://dummyimage.com/500x200/76c720/fff.png&text=md" | ||
srcset.sm="https://dummyimage.com/400x200/b925c7/fff.png&text=sm" | ||
srcset.lt-sm="https://dummyimage.com/300x200/c7751e/fff.png&text=lt-sm" | ||
srcset.gt-md="https://dummyimage.com/700x200/258cc7/fff.png&text=gt-md" > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To test that the default is properly used as fallback, let's change srcset.gt-md
to:
srcset.gt-lg="https://dummyimage.com/700x200/258cc7/fff.png&text=gt-lg"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change done. PR will be updated shortly
Overall this looks very good. Nice work @benbraou. 🙌
Should we add to the example usage of <img
srcset="small.jpg 1x, large.jpg 2x"
srcset.xs="xsmall.jpg 1x, xsmallLg.jpg 2x"
src="small.jpg"
alt="A rad wolf" /> |
0680d15
to
9a7c5c3
Compare
@ThomasBurleson Thanks! <picture>
<img style="width:auto;"
src="https://dummyimage.com/400x200/c7c224/000.png&text=default"
srcset.md="https://dummyimage.com/500x200/76c720/fff.png&text=md"
srcset.sm="https://dummyimage.com/400x200/b925c7/fff.png&text=sm"
srcset.lt-sm="https://dummyimage.com/300x200/c7751e/fff.png&text=lt-sm(1x) 1x,
https://dummyimage.com/300x200/f0b16e/fff.png&text=lt-sm(2x) 2x,
https://dummyimage.com/300x200/f6ca9a/fff.png&text=lt-sm(3x) 3x"
srcset.gt-lg="https://dummyimage.com/700x200/258cc7/fff.png&text=gt-lg" >
</picture> In the demo, I have though about updating MediaQueryStatus component (or creating a new one) to display the devicePixelRatio window property, but I decided finally to just update the usage example as you requested. (It may be useful to add it in the future).
Do you have other ideas? |
@benbraou - Since the mediaActivationResponse will already tell use about MediaChange events, I think we should inject detect IE11 and update the imge.src value. img-srcset.tsconstructor(
elRef: ElementRef,
renderer: Renderer,
monitor: MediaMonitor,
@Inject(DOCUMENT) private _document:any ) {
super(monitor, elRef, renderer);
}
ngOnInit() {
const isIE = !!this._document['documentMode'];
this._listenForMediaQueryChanges('srcset', '', (change:MediaChange) => {
if (isIE) {
// IE11 does not support the <picture> element; so responsively change the <img src="">
// Normally, there is no need to subscribe to mediaQuery changes as it is
// up to the browser to use the relevant injected <source> element
this._updateImageSrc(change.mqAlias);
}
});
if ( !isIE ) {
this._injectSourceElements();
}
} |
Any consideration/question: What happens when the user does NOT wrap the Scenario #1: <img style="width:auto;"
src="https://dummyimage.com/400x200/c7c224/000.png&text=default"
srcset.md="https://dummyimage.com/500x200/76c720/fff.png&text=md"
srcset.sm="https://dummyimage.com/400x200/b925c7/fff.png&text=sm"
srcset.lt-sm="https://dummyimage.com/300x200/c7751e/fff.png&text=lt-sm"
srcset.gt-lg="https://dummyimage.com/700x200/258cc7/fff.png&text=gt-lg" > In this case ^ (#1), should we auto-wrap the dom element inside a Scenario #2: Use tries to use the <img style="width:auto;"
src="https://dummyimage.com/400x200/c7c224/000.png&text=default"
src.md="https://dummyimage.com/500x200/76c720/fff.png&text=md"
src.sm="https://dummyimage.com/400x200/b925c7/fff.png&text=sm"
src.lt-sm="https://dummyimage.com/300x200/c7751e/fff.png&text=lt-sm"
src.gt-lg="https://dummyimage.com/700x200/258cc7/fff.png&text=gt-lg" > In this case ^ (#2), should we responsively update the |
I went to sleep 😁 |
@benbraou - let's make two separate issue to enhance this current PR. These issues can be fixed for Beta.10.
|
9a7c5c3
to
9498e2c
Compare
Rebase done. So, no action items remaining on my side regarding this PR. |
@benbraou - superb. Thank you. LGTM |
src/lib/flexbox/api/img-srcset.ts
Outdated
@Input('srcset.gt-lg') set srcsetGtLg(val) {this._cacheInput('srcsetGtLg', val);}; | ||
|
||
/* tslint:enable */ | ||
constructor(elRef: ElementRef, renderer: Renderer, monitor: MediaMonitor) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. For this PR, I will inject Renderer2 instead of Renderer as you requested.
For the future 2 PRs, I will take the opportunity to replace getDom().insertBefore by Renderer2 methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went ahead and used renderer.insertBefore. Minor changes overall.
const sourceElt = this._renderer.createElement('source');
this._registrySourceElements[bpX.key] = sourceElt;
this._renderer.insertBefore(this.parentElement, sourceElt, this.nativeElement);
this._renderer.setAttribute(sourceElt, 'media', bpX.mediaQuery);
this._renderer.setAttribute(sourceElt, 'srcset', this._queryInput(bpX.key));
instead of
const sourceElt = this._renderer.createElement(this.parentElement, 'source');
this._registrySourceElements[bpX.key] = sourceElt;
getDom().insertBefore(this.parentElement, this.nativeElement, sourceElt);
this._renderer.setElementAttribute(sourceElt, 'media', bpX.mediaQuery);
this._renderer.setElementAttribute(sourceElt, 'srcset', this._queryInput(bpX.key));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice! Love your attention-to-detail. 👍
@benbraou - also please |
9498e2c
to
ebc9eb6
Compare
changes and rebase done |
conflicts solved |
@benbraou - regarding your comment 3 hours ago... did you change any source? What do you mean with the comment ^?
|
@ThomasBurleson there were conflicts in base.ts and custom-matchers.ts after the merge of #374 preventing my PR from being merged. So, I did a rebase and fixed those 2 conflicts. |
@benbraou - true, I fixed those in my local copy of your PR also. Stand-by for additional tests. |
@benbraou - see https://github.com/angular/flex-layout/tree/thomas/fix-img-srcset for changes to picture demo, |
* feat(api, img-src): add ImgSrcDirective for responsive API for img elements * add responsive API to img.src: src.md, src.lt-lg, src.gt-xs, etc. * repackage API classes to easily distinguish flexbox APIs and extended responsive APIs Closes #366, Fixes #376. * chore(release): fix package.json version
Support responsive image by introducing srcset.<breakpoint alias> directive. When used as <img> attributes where * where the <img> is a child of a <picture> container, this directive will injects a <source> element for every srcset.<breakpoint alias>. * where the <img> is NOT nested in a <picture> element, then the `img.src` property will be responsively updated. > Thanks to @benbraou for his initial PR submission (@see #366) Closes #81.
* add ImgSrcsetDirective * to inject <source> elements to support responsive images * Inject a <source> element for every srcset.<breakpoint alias> in the HTML markup of an <img> element contained in a <picture> elemen * support usages without `<picture>` parents * add responsive API to img.src: src.md, src.lt-lg, src.gt-xs, etc. * repackage API classes to easily distinguish flexbox APIs and extended responsive APIs Closes #366, Fixes #81, Fixes #376.
* add ImgSrcsetDirective * to inject <source> elements to support responsive images * Inject a <source> element for every srcset.<breakpoint alias> in the HTML markup of an <img> element contained in a <picture> elemen * support usages without `<picture>` parents * add responsive API to img.src: src.md, src.lt-lg, src.gt-xs, etc. * skip actions if responsive keys are not defined * without responsive keys (`src.<alias>`) defined, the ImgSrcDirective should *fall-through* and not change any attributes or properties on the `img` DOM element. The `img.src` attribute is dynamically set only when responsive keys are defined. * defaults to `src=""` if not explicitly assigned * responsive key activation will then assign the activated value to `img.src` attribute. Closes #366, Fixes #81, Fixes #376.
* add responsive API to img[src.md], img[src.lt-lg], img[src.gt-xs], etc. * skip actions if responsive keys are not defined * without responsive keys (`src.<alias>`) defined, the ImgSrcDirective should **fall-through** and not change any attributes or properties on the `img` DOM element. The `img.src` attribute is dynamically set only when responsive keys are defined. * defaults to `src=""` if not explicitly assigned * responsive key activation will then assign the activated value to `img.src` attribute. Closes #366, Fixes #81, Fixes #376.
* add responsive API to img[src.md], img[src.lt-lg], img[src.gt-xs], etc. * skip actions if responsive keys are not defined * without responsive keys (`src.<alias>`) defined, the ImgSrcDirective should **fall-through** and not change any attributes or properties on the `img` DOM element. The `img.src` attribute is dynamically set only when responsive keys are defined. * defaults to `src=""` if not explicitly assigned * responsive key activation will then assign the activated value to `img.src` attribute. Closes #366, Fixes #81, Fixes #376.
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Support responsive image by introducing srcset.<breakpoint alias> directive.
It Injects a <source> element for every srcset.<breakpoint alias> in the HTML markup of an <img> element contained in a <picture> element.
Closes #81.