Socket
Socket
Sign inDemoInstall

@frameright/image-display-control-web-component

Package Overview
Dependencies
1
Maintainers
2
Versions
20
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.2 to 1.1.3

2

dist/image-display-control.min.js

@@ -1,1 +0,1 @@

class e{constructor(t,i){this._id=t,this._level=e._toValue(i)}setLevel(t){this._level=e._toValue(t)}setId(e){this._id=e}debug(t){this._level>=e._DEBUG&&console.log(this._consoleText(t))}warn(t){this._level>=e._WARN&&console.warn(this._consoleText(t))}error(t){this._level>=e._ERROR&&console.error(this._consoleText(t))}static _toValue(t){const i=(t||"").toLowerCase();return"debug"===i||"trace"===i||"notice"===i?e._DEBUG:"info"===i?e._INFO:i.startsWith("warn")?e._WARN:i.startsWith("err")?e._ERROR:"fatal"===i?e._FATAL:e._OFF}_consoleText(e){return this._id?`[idc:${this._id}] ${e}`:`[idc] ${e}`}}e._OFF=0,e._FATAL=1,e._ERROR=2,e._WARN=3,e._INFO=4,e._DEBUG=5;class t{constructor(e,t){this.x=e,this.y=t}getRelativeCoord(e){return e.isUnknown()?new i:new i(this.x/e.getSafeWidth(),this.y/e.getSafeHeight())}toString(){return`{x=${this.x.toFixed(3)}px, y=${this.y.toFixed(3)}px}`}}class i{constructor(e,t){this._x=Math.max(Math.min(null!=e?e:0,1),0),this._y=Math.max(Math.min(null!=t?t:0,1),0)}getPositionInPixels(e){let i=0,s=0;return e.isUnknown()||(i=e.getWidth(),s=e.getHeight()),new t(this._x*i,this._y*s)}toString(){return`{x=${this._x.toFixed(3)}, y=${this._y.toFixed(3)}}`}}class s{constructor(e,t){this._width=Math.max(Math.min(null!=e?e:0,1),0),this._height=Math.max(Math.min(null!=t?t:0,1),0)}getSizeInPixels(e){let t=0,i=0;return e.isUnknown()||(t=e.getWidth(),i=e.getHeight()),new n(this._width*t,this._height*i)}toString(){return`{width=${this._width.toFixed(3)}, height=${this._height.toFixed(3)}}`}}class n{constructor(e,t){this._unknown=!0,this._width=0,this._height=0,null!=e&&null!=t&&(this._width=Math.max(e,0),this._height=Math.max(t,0),this._unknown=!1)}getWidth(){return this._width}getHeight(){return this._height}getSafeWidth(){return Math.max(this._width,1)}getSafeHeight(){return Math.max(this._height,1)}getSafeRatio(){return this.getSafeWidth()/this.getSafeHeight()}getScaled(e){if(this.isUnknown())return new n;const t=this._width*e,i=this._height*e;return new n(t,i)}isUnknown(){return this._unknown}setIfDifferent(e){return!this.equals(e)&&(this._unknown=e.isUnknown(),this._width=e.getWidth(),this._height=e.getHeight(),!0)}ratioDiffFactor(e){const t=this.getSafeRatio(),i=e.getSafeRatio();return t>=i?t/i:i/t}getRelativeCoord(e){return e.isUnknown()?new s:new s(this._width/e.getSafeWidth(),this._height/e.getSafeHeight())}toString(){return`{width=${this._width.toFixed(3)}px, height=${this._height.toFixed(3)}px}`}equals(e){return this._width===e.getWidth()&&this._height===e.getHeight()}}class o{static getTransformedImageSize(e,t){return e.getScaled(t.factor)}constructor(e,t,n){this.id=null!=e?e:"",this.position=null!=t?t:new i,this.size=null!=n?n:new s,this._unknown=!t||!n}setFields(e,o){var a,r;const l=e.shape?e.shape.toLowerCase():"rectangle";if("rectangle"!==l)return o.debug(`Region ${e.id} has unknown shape ${l}, skipping.`),void(this._unknown=!0);let h=null===(a=e.unit)||void 0===a?void 0:a.toLowerCase();if(h||(e.imageWidth&&e.imageHeight?h="pixel":e.imageWidth||e.imageHeight||(h="relative")),"relative"!==h&&"pixel"!==h)return o.debug(`Region ${e.id} has unknown unit ${h}, skipping.`),void(this._unknown=!0);let g=new n;if("pixel"===h){if(null==e.imageWidth||null==e.imageHeight)return o.warn(`Region ${e.id} has missing imageWidth or imageHeight, skipping.`),void(this._unknown=!0);g=new n(parseFloat(`${e.imageWidth}`),parseFloat(`${e.imageHeight}`))}if(null==e.x||null==e.y||null==e.width||null==e.height)return o.warn(`Region ${e.id} has missing x, y, width or height, skipping.`),void(this._unknown=!0);const d=parseFloat(`${e.x}`),_=parseFloat(`${e.y}`),u=parseFloat(`${e.width}`),c=parseFloat(`${e.height}`);return Number.isNaN(d)||Number.isNaN(_)||Number.isNaN(u)||Number.isNaN(c)?(o.warn(`Region ${e.id} has non-numeric x, y, width or height, skipping.`),void(this._unknown=!0)):d<0||_<0||u<=0||c<=0?(o.warn(`Region ${e.id} has negative/zero x, y, width or height, skipping.`),void(this._unknown=!0)):("relative"===h?(this.position=new i(d,_),this.size=new s(u,c)):(this.position=new t(d,_).getRelativeCoord(g),this.size=new n(u,c).getRelativeCoord(g)),this.id=null!==(r=e.id)&&void 0!==r?r:window.crypto.randomUUID(),void(this._unknown=!1))}isUnknown(){return this._unknown}getTransformation(e,i,s){const o=this.position.getPositionInPixels(i),a=this.size.getSizeInPixels(i),r=a.getSafeWidth(),l=a.getSafeHeight(),h=e.getSafeWidth(),g=e.getSafeHeight(),d=i.getWidth(),_=i.getHeight(),u=d-r-o.x,c=_-l-o.y;let m=0,b=0,p=1;if(e.getSafeRatio()<a.getSafeRatio()){p=h/r,b=(g/p-l)/2;(b-o.y>0||b-c>0)&&(b=Math.min(o.y,c),p=g/(2*b+l),m=(h/p-r)/2)}else{p=g/l,m=(h/p-r)/2;(m-o.x>0||m-u>0)&&(m=Math.min(o.x,u),p=h/(2*m+r),b=(g/p-l)/2)}const R=new t(o.x-m,o.y-b);return{origin:R,factor:p,insetClipFromTopLeft:new n(R.x,R.y),insetClipFromBottomRight:new n(u-m+s.getWidth(),c-b+s.getHeight())}}getBoundingBox(e,i,s){const n=new t(-s.origin.x*s.factor,-s.origin.y*s.factor),a=o.getTransformedImageSize(i,s),r=this.position.getPositionInPixels(a);return{position:new t(r.x+n.x,r.y+n.y),size:this.size.getSizeInPixels(a)}}}class a extends HTMLImageElement{constructor(){super(...arguments),this._rectangleImageRegions=[],this._sizeObserver=null,this._elementSize=new n,this._fittedImageSize=new n,this._fittedImageBottomRightMargin=new n,this._parentElement=null,this._parentCssContainToRestore=null,this._parentCssOverflowToRestore=null,this._sizesAttributeToRestore=null,this._sizesAttributeDebounceTimer=null,this._sizesAttributeLastSet=null,this._cssBorderToRestore=null,this._cssPaddingToRestore=null,this._logger=new e(this.id,this.dataset.loglevel),this._browserFeatures={cssInset:!1,resizeObserver:!1,cssContain:!1},this._debugRegionOverlayContainer=null,this._debugRegionOverlays=new Map,this._debugRegionOverlayStyles=["5px solid rgba(240, 69, 141, 0.7)","5px solid rgba(127, 15, 130, 0.7)","5px solid rgba(48, 0, 150, 0.7)"]}static get observedAttributes(){return["id","src","srcset","data-loglevel","data-disabled","data-image-regions","data-image-region-id","data-avoid-no-region","data-debug-draw-regions","data-css-contain-fallback"]}connectedCallback(){this._logger.debug("Connected"),this._registerImageLoadedLateCallback(),this._behaviorChanged()}disconnectedCallback(){this._logger.debug("Disconnected"),this._unregisterImageLoadedLateCallback(),this._restoreOriginalParentCssContainment()}attributeChangedCallback(e){switch(e){case"id":this._logger.setId(this.id);break;case"src":case"srcset":this._isDisabled()||(this._registerImageLoadedLateCallback(),this._populateFittedImageSize(),this._panAndZoomToBestRegion());break;case"data-loglevel":this._logger.setLevel(this.dataset.loglevel);break;case"data-disabled":case"data-debug-draw-regions":case"data-css-contain-fallback":this._behaviorChanged();break;case"data-image-regions":this._populateRectangleImageRegions(),this._isDisabled()||(this._resetDebugRegionOverlays(),this._panAndZoomToBestRegion());break;case"data-image-region-id":case"data-avoid-no-region":this._isDisabled()||this._panAndZoomToBestRegion();break;default:this._logger.warn(`Unexpected attribute mutation: ${e}`)}}_behaviorChanged(){this._populateBrowserFeatures(),this._isDisabled()?(this._unregisterImageLoadedLateCallback(),this._logger.debug("Disabled"),this._sizeObserver&&(this._sizeObserver.unobserve(this),this._sizeObserver=null),this._setDebounceSizesAttribute(),this._restoreOriginalBorderAndPadding(),this._removeDebugRegionOverlays(),this._setCssToMiddleCropOriginalImage(),this._restoreOriginalParentCssContainment()):(this._logger.debug("Enabled"),this._adaptParentCssContainment(),this._resetDebugRegionOverlays(),this._panAndZoomToBestRegion(),this._sizeObserver||(this._sizeObserver=new ResizeObserver(this._resizeCallback.bind(this)),this._sizeObserver.observe(this)))}_resizeCallback(e){if(this._isDisabled())return void this._logger.warn("Component disabled, spurious call to _resizeCallback()");const t=e.pop();if(!t)return void this._logger.warn("No ResizeObserverEntry, spurious call to _resizeCallback()");if(t.target!==this)return void this._logger.warn("Unexpected ResizeObserverEntry target");let i=new n;i=t.contentBoxSize?new n(t.contentBoxSize[0].inlineSize,t.contentBoxSize[0].blockSize):new n(t.contentRect.width,t.contentRect.height);this._elementSize.setIfDifferent(i)&&(this._logger.debug(`Element size: ${this._elementSize}`),this._populateFittedImageSize(),this._panAndZoomToBestRegion())}_imageLoadedLateCallback(){this._unregisterImageLoadedLateCallback(),this._logger.debug("Image loaded late"),this._populateFittedImageSize(),this._panAndZoomToBestRegion()}_registerImageLoadedLateCallback(){this.addEventListener("load",this._imageLoadedLateCallback)}_unregisterImageLoadedLateCallback(){this.removeEventListener("load",this._imageLoadedLateCallback)}_populateRectangleImageRegions(){this._logger.debug("Populating rectangle image regions..."),this._rectangleImageRegions=[];let e=[],t=!1;try{e=JSON.parse(this.dataset.imageRegions||"[]")}catch(e){t=!0}t||(t=!Array.isArray(e)),t&&(this._logger.warn("Invalid 'data-image-regions' attribute"),e=[]),e.forEach((e=>{const t=new o;t.setFields(e,this._logger),t.isUnknown()||(this._logger.debug(`Rectangle region found: id=${t.id}, position=${t.position}, size=${t.size}`),this._rectangleImageRegions.push(t))})),this._rectangleImageRegions.length||this._logger.debug("No rectangle image region found")}_populateFittedImageSize(){if(this.naturalWidth<=0&&this.naturalHeight<=0)return void this._logger.debug("Natural image size unknown, deferring.");const e=new n(this.naturalWidth,this.naturalHeight);let t=1;t=this._elementSize.getSafeRatio()<e.getSafeRatio()?this._elementSize.getSafeWidth()/e.getSafeWidth():this._elementSize.getSafeHeight()/e.getSafeHeight(),this._fittedImageSize=new n(this.naturalWidth*t,this.naturalHeight*t),this._fittedImageBottomRightMargin=new n(this._elementSize.getWidth()-this._fittedImageSize.getWidth(),this._elementSize.getHeight()-this._fittedImageSize.getHeight()),this._logger.debug(`Fitted image size: ${this._fittedImageSize}`),this._logger.debug(`Fitted image margin: ${this._fittedImageBottomRightMargin}`)}_panAndZoomToBestRegion(){if(this._logger.debug("Panning and zooming to best region..."),this._fittedImageSize.isUnknown())return void this._logger.debug("Fitted image size unknown, deferring.");let e=null;if(this.dataset.imageRegionId&&(e=this.dataset.imageRegionId===a._ORIGINAL_IMAGE_REGION.id?a._ORIGINAL_IMAGE_REGION:this._rectangleImageRegions.find((e=>e.id===this.dataset.imageRegionId))),e||(e=this._findBestRegion()),a._ORIGINAL_IMAGE_REGION.id!==e.id||this._debugRegionOverlayContainer){null===this._cssBorderToRestore&&(this._cssBorderToRestore=this.style.border,this.style.border="none"),null===this._cssPaddingToRestore&&(this._cssPaddingToRestore=this.style.padding,this.style.padding="0");const t=e.getTransformation(this._elementSize,this._fittedImageSize,this._fittedImageBottomRightMargin);if(this._setCssToPanAndZoomToRegion(t),this._debugRegionOverlayContainer&&this._drawDebugRegionOverlays(t),this.srcset.length>0&&this.sizes.length>0){const e=o.getTransformedImageSize(this._fittedImageSize,t).getWidth();this._setDebounceSizesAttribute(e)}}else this._setDebounceSizesAttribute(),this._restoreOriginalBorderAndPadding(),this._setCssToMiddleCropOriginalImage()}_findBestRegion(){let e=a._ORIGINAL_IMAGE_REGION,t=this._elementSize.ratioDiffFactor(this._fittedImageSize);return this._logger.debug(`Element ratio: ${this._elementSize.getSafeRatio().toFixed(3)}`),this._logger.debug(`Original image ratio: ${this._fittedImageSize.getSafeRatio().toFixed(3)}`),this.dataset.avoidNoRegion&&"off"===this.dataset.avoidNoRegion||(t=999),t>1.1&&this._rectangleImageRegions.forEach((i=>{const s=i.size.getSizeInPixels(this._fittedImageSize);this._logger.debug(`${i.id} region ratio: ${s.getSafeRatio().toFixed(3)}`);const n=this._elementSize.ratioDiffFactor(s);n<t&&(t=n,e=i)})),this._logger.debug(`Selected region: ${e.id}`),e}_adaptParentCssContainment(){const e=this._currentCssContainmentStrategy();"none"!==e?(this._parentElement=this.parentElement,this._parentElement&&("contain"===e?("paint"!==this._parentElement.style.contain&&"layout"!==this._parentElement.style.contain&&"content"!==this._parentElement.style.contain&&(null===this._parentCssContainToRestore&&(this._parentCssContainToRestore=this._parentElement.style.contain),this._parentElement.style.contain="paint"),this._restoreOriginalParentCssOverflow()):"overflow"===e&&("hidden"!==this._parentElement.style.overflow&&"clip"!==this._parentElement.style.overflow&&(null===this._parentCssOverflowToRestore&&(this._parentCssOverflowToRestore=this._parentElement.style.overflow),this._parentElement.style.overflow="hidden"),this._restoreOriginalParentCssContain()))):this._restoreOriginalParentCssContainment()}_restoreOriginalParentCssContainment(){this._restoreOriginalParentCssContain(),this._restoreOriginalParentCssOverflow()}_restoreOriginalParentCssContain(){this._parentElement&&null!==this._parentCssContainToRestore&&(this._parentElement.style.contain=this._parentCssContainToRestore,this._parentCssContainToRestore=null)}_restoreOriginalParentCssOverflow(){this._parentElement&&null!==this._parentCssOverflowToRestore&&(this._parentElement.style.overflow=this._parentCssOverflowToRestore,this._parentCssOverflowToRestore=null)}_setDebounceSizesAttribute(e){this._unregisterImageLoadedLateCallback(),null!==this._sizesAttributeDebounceTimer&&clearTimeout(this._sizesAttributeDebounceTimer);this._sizesAttributeDebounceTimer=void 0!==e?window.setTimeout((()=>{this._sizesAttributeDebounceTimer=null,null===this._sizesAttributeToRestore&&(this._sizesAttributeToRestore=this.sizes),(null===this._sizesAttributeLastSet||this._sizesAttributeLastSet<e)&&(this.sizes=`${Math.ceil(e)}px`,this._sizesAttributeLastSet=e)}),200):window.setTimeout((()=>{this._sizesAttributeDebounceTimer=null,null!==this._sizesAttributeToRestore&&(this.sizes=this._sizesAttributeToRestore,this._sizesAttributeToRestore=null),this._sizesAttributeLastSet=null}),200)}_restoreOriginalBorderAndPadding(){null!==this._cssBorderToRestore&&(this.style.border=this._cssBorderToRestore,this._cssBorderToRestore=null),null!==this._cssPaddingToRestore&&(this.style.padding=this._cssPaddingToRestore,this._cssPaddingToRestore=null)}_setCssToMiddleCropOriginalImage(){this.style.objectFit="cover",this.style.objectPosition="center",this.style.transformOrigin="0 0",this.style.transform="none",this.style.clipPath="none"}_setCssToPanAndZoomToRegion(e){this.style.objectFit="contain",this.style.objectPosition="top left",this.style.transformOrigin=`${e.origin.x.toFixed(3)}px ${e.origin.y.toFixed(3)}px`,this.style.transform=`translate(${-e.origin.x.toFixed(3)}px, ${-e.origin.y.toFixed(3)}px) scale(${e.factor.toFixed(3)})`,this.style.clipPath=`inset(${e.insetClipFromTopLeft.getHeight()}px ${e.insetClipFromBottomRight.getWidth()}px ${e.insetClipFromBottomRight.getHeight()}px ${e.insetClipFromTopLeft.getWidth()}px)`}_resetDebugRegionOverlays(){"on"===(this.dataset.debugDrawRegions||"off")?this._recreateEmptyDebugRegionOverlays():this._removeDebugRegionOverlays()}_recreateEmptyDebugRegionOverlays(){var e;this._debugRegionOverlayContainer&&this._removeDebugRegionOverlays(),this._debugRegionOverlayContainer=document.createElement("div"),this._debugRegionOverlayContainer.style.position="absolute",null===(e=this._parentElement)||void 0===e||e.insertBefore(this._debugRegionOverlayContainer,this)}_removeDebugRegionOverlays(){var e;this._debugRegionOverlayContainer&&(null===(e=this._parentElement)||void 0===e||e.removeChild(this._debugRegionOverlayContainer),this._debugRegionOverlayContainer=null),this._debugRegionOverlays.clear()}_drawDebugRegionOverlays(e){this._rectangleImageRegions.forEach((t=>{this._drawDebugRegionOverlay(t,e)}))}_drawDebugRegionOverlay(e,t){var i;let s=this._debugRegionOverlays.get(e.id);s||(s=document.createElement("div"),s.style.position="absolute",s.style.boxSizing="border-box",s.style.border=this._pickNextOvelayStyle(),s.style.zIndex="999",null===(i=this._debugRegionOverlayContainer)||void 0===i||i.appendChild(s),this._debugRegionOverlays.set(e.id,s));const n=e.getBoundingBox(this._elementSize,this._fittedImageSize,t);s.style.left=`${n.position.x}px`,s.style.top=`${n.position.y}px`,s.style.width=`${n.size.getWidth()}px`,s.style.height=`${n.size.getHeight()}px`}_pickNextOvelayStyle(){const e=this._debugRegionOverlayStyles.shift()||"5px solid rgba(255, 0, 0, 0.7)";return this._debugRegionOverlayStyles.push(e),e}_populateBrowserFeatures(){const e=CSS.supports("clip-path: inset(5px)");e||this._logger.error("CSS `clip-path: inset()` is not supported. Disabling the web component");const t="undefined"!=typeof ResizeObserver;t||this._logger.error("ResizeObserver is not supported. Disabling the web component. Consider using a polyfill like https://github.com/juggle/resize-observer");const i=CSS.supports("contain: paint");i||this.dataset.cssContainFallback||this._logger.warn("CSS containment is not supported. Consider using the `css-contain-fallback=` attribute"),this._browserFeatures={cssInset:e,resizeObserver:t,cssContain:i}}_cssContainFallbackStrategy(){return"disable-containment"===this.dataset.cssContainFallback||"overflow-hidden"===this.dataset.cssContainFallback||"force"===this.dataset.cssContainFallback?this.dataset.cssContainFallback:"disable-component"}_isDisabled(){return"all"===this.dataset.disabled||!this._browserFeatures.cssInset||!this._browserFeatures.resizeObserver||this._isCssContainUnsupportedOrDisabled()&&"disable-component"===this._cssContainFallbackStrategy()}_isCssContainUnsupportedOrDisabled(){return!this._browserFeatures.cssContain||"css-contain"===this.dataset.disabled}_currentCssContainmentStrategy(){if(this._isDisabled())return"none";if(!this._isCssContainUnsupportedOrDisabled())return"contain";const e=this._cssContainFallbackStrategy();return"overflow-hidden"===e?"overflow":"disable-containment"===e?"none":"contain"}}a._ORIGINAL_IMAGE_REGION=new o("<no region>",new i(0,0),new s(1,1)),window.customElements.define("image-display-control",a,{extends:"img"});
class e{constructor(t,i){this._id=t,this._level=e._toValue(i)}setLevel(t){this._level=e._toValue(t)}setId(e){this._id=e}debug(t){this._level>=e._DEBUG&&console.log(this._consoleText(t))}warn(t){this._level>=e._WARN&&console.warn(this._consoleText(t))}error(t){this._level>=e._ERROR&&console.error(this._consoleText(t))}static _toValue(t){const i=(t||"").toLowerCase();return"debug"===i||"trace"===i||"notice"===i?e._DEBUG:"info"===i?e._INFO:i.startsWith("warn")?e._WARN:i.startsWith("err")?e._ERROR:"fatal"===i?e._FATAL:e._OFF}_consoleText(e){return this._id?`[idc:${this._id}] ${e}`:`[idc] ${e}`}}e._OFF=0,e._FATAL=1,e._ERROR=2,e._WARN=3,e._INFO=4,e._DEBUG=5;class t{constructor(e,t){this.x=e,this.y=t}getRelativeCoord(e){return e.isUnknown()?new i:new i(this.x/e.getSafeWidth(),this.y/e.getSafeHeight())}toString(){return`{x=${this.x.toFixed(3)}px, y=${this.y.toFixed(3)}px}`}}class i{constructor(e,t){this._x=Math.max(Math.min(null!=e?e:0,1),0),this._y=Math.max(Math.min(null!=t?t:0,1),0)}getPositionInPixels(e){let i=0,s=0;return e.isUnknown()||(i=e.getWidth(),s=e.getHeight()),new t(this._x*i,this._y*s)}toString(){return`{x=${this._x.toFixed(3)}, y=${this._y.toFixed(3)}}`}}class s{constructor(e,t){this._width=Math.max(Math.min(null!=e?e:0,1),0),this._height=Math.max(Math.min(null!=t?t:0,1),0)}getSizeInPixels(e){let t=0,i=0;return e.isUnknown()||(t=e.getWidth(),i=e.getHeight()),new n(this._width*t,this._height*i)}toString(){return`{width=${this._width.toFixed(3)}, height=${this._height.toFixed(3)}}`}}class n{constructor(e,t){this._unknown=!0,this._width=0,this._height=0,null!=e&&null!=t&&(this._width=Math.max(e,0),this._height=Math.max(t,0),this._unknown=!1)}getWidth(){return this._width}getHeight(){return this._height}getSafeWidth(){return Math.max(this._width,1)}getSafeHeight(){return Math.max(this._height,1)}getSafeRatio(){return this.getSafeWidth()/this.getSafeHeight()}getScaled(e){if(this.isUnknown())return new n;const t=this._width*e,i=this._height*e;return new n(t,i)}isUnknown(){return this._unknown}setIfDifferent(e){return!this.equals(e)&&(this._unknown=e.isUnknown(),this._width=e.getWidth(),this._height=e.getHeight(),!0)}ratioDiffFactor(e){const t=this.getSafeRatio(),i=e.getSafeRatio();return t>=i?t/i:i/t}getRelativeCoord(e){return e.isUnknown()?new s:new s(this._width/e.getSafeWidth(),this._height/e.getSafeHeight())}toString(){return`{width=${this._width.toFixed(3)}px, height=${this._height.toFixed(3)}px}`}equals(e){return this._width===e.getWidth()&&this._height===e.getHeight()}}class o{static getTransformedImageSize(e,t){return e.getScaled(t.factor)}constructor(e,t,n){this.id=null!=e?e:"",this.position=null!=t?t:new i,this.size=null!=n?n:new s,this._unknown=!t||!n}setFields(e,o){var a,r;const l=e.shape?e.shape.toLowerCase():"rectangle";if("rectangle"!==l)return o.debug(`Region ${e.id} has unknown shape ${l}, skipping.`),void(this._unknown=!0);let g=null===(a=e.unit)||void 0===a?void 0:a.toLowerCase();if(g||(e.imageWidth&&e.imageHeight?g="pixel":e.imageWidth||e.imageHeight||(g="relative")),"relative"!==g&&"pixel"!==g)return o.debug(`Region ${e.id} has unknown unit ${g}, skipping.`),void(this._unknown=!0);let h=new n;if("pixel"===g){if(null==e.imageWidth||null==e.imageHeight)return o.warn(`Region ${e.id} has missing imageWidth or imageHeight, skipping.`),void(this._unknown=!0);h=new n(parseFloat(`${e.imageWidth}`),parseFloat(`${e.imageHeight}`))}if(null==e.x||null==e.y||null==e.width||null==e.height)return o.warn(`Region ${e.id} has missing x, y, width or height, skipping.`),void(this._unknown=!0);const d=parseFloat(`${e.x}`),_=parseFloat(`${e.y}`),u=parseFloat(`${e.width}`),c=parseFloat(`${e.height}`);return Number.isNaN(d)||Number.isNaN(_)||Number.isNaN(u)||Number.isNaN(c)?(o.warn(`Region ${e.id} has non-numeric x, y, width or height, skipping.`),void(this._unknown=!0)):d<0||_<0||u<=0||c<=0?(o.warn(`Region ${e.id} has negative/zero x, y, width or height, skipping.`),void(this._unknown=!0)):("relative"===g?(this.position=new i(d,_),this.size=new s(u,c)):(this.position=new t(d,_).getRelativeCoord(h),this.size=new n(u,c).getRelativeCoord(h)),this.id=null!==(r=e.id)&&void 0!==r?r:window.crypto.randomUUID(),void(this._unknown=!1))}isUnknown(){return this._unknown}getTransformation(e,i,s){const o=this.position.getPositionInPixels(i),a=this.size.getSizeInPixels(i),r=a.getSafeWidth(),l=a.getSafeHeight(),g=e.getSafeWidth(),h=e.getSafeHeight(),d=i.getWidth(),_=i.getHeight(),u=d-r-o.x,c=_-l-o.y;let b=0,m=0,p=1;if(e.getSafeRatio()<a.getSafeRatio()){p=g/r,m=(h/p-l)/2;(m-o.y>0||m-c>0)&&(m=Math.min(o.y,c),p=h/(2*m+l),b=(g/p-r)/2)}else{p=h/l,b=(g/p-r)/2;(b-o.x>0||b-u>0)&&(b=Math.min(o.x,u),p=g/(2*b+r),m=(h/p-l)/2)}const R=new t(o.x-b,o.y-m);return{origin:R,factor:p,insetClipFromTopLeft:new n(R.x,R.y),insetClipFromBottomRight:new n(u-b+s.getWidth(),c-m+s.getHeight())}}getBoundingBox(e,i,s){const n=new t(-s.origin.x*s.factor,-s.origin.y*s.factor),a=o.getTransformedImageSize(i,s),r=this.position.getPositionInPixels(a);return{position:new t(r.x+n.x,r.y+n.y),size:this.size.getSizeInPixels(a)}}}class a extends HTMLImageElement{constructor(){super(...arguments),this._rectangleImageRegions=[],this._sizeObserver=null,this._elementSize=new n,this._fittedImageSize=new n,this._fittedImageBottomRightMargin=new n,this._parentElement=null,this._parentCssContainToRestore=null,this._parentCssOverflowToRestore=null,this._sizesAttributeToRestore=null,this._sizesAttributeDebounceTimer=null,this._sizesAttributeLastSet=null,this._cssBorderToRestore=null,this._cssPaddingToRestore=null,this._logger=new e(this.id,this.dataset.loglevel),this._browserFeatures={cssInset:!1,resizeObserver:!1,cssContain:!1},this._debugRegionOverlayContainer=null,this._debugRegionOverlays=new Map,this._debugRegionOverlayStyles=["5px solid rgba(240, 69, 141, 0.7)","5px solid rgba(127, 15, 130, 0.7)","5px solid rgba(48, 0, 150, 0.7)"]}static get observedAttributes(){return["id","src","srcset","data-loglevel","data-disabled","data-image-regions","data-image-region-id","data-avoid-no-region","data-debug-draw-regions","data-css-contain-fallback"]}connectedCallback(){this._logger.debug("Connected"),this._registerImageLoadedLateCallback(),this._behaviorChanged()}disconnectedCallback(){this._logger.debug("Disconnected"),this._unregisterImageLoadedLateCallback(),this._restoreOriginalParentCssContainment()}attributeChangedCallback(e){switch(e){case"id":this._logger.setId(this.id);break;case"src":case"srcset":this._isDisabled()||(this._registerImageLoadedLateCallback(),this._populateFittedImageSize(),this._panAndZoomToBestRegion());break;case"data-loglevel":this._logger.setLevel(this.dataset.loglevel);break;case"data-disabled":case"data-debug-draw-regions":case"data-css-contain-fallback":this._behaviorChanged();break;case"data-image-regions":this._populateRectangleImageRegions(),this._isDisabled()||(this._resetDebugRegionOverlays(),this._panAndZoomToBestRegion());break;case"data-image-region-id":case"data-avoid-no-region":this._isDisabled()||this._panAndZoomToBestRegion();break;default:this._logger.warn(`Unexpected attribute mutation: ${e}`)}}_behaviorChanged(){this._populateBrowserFeatures(),this._isDisabled()?(this._unregisterImageLoadedLateCallback(),this._logger.debug("Disabled"),this._sizeObserver&&(this._sizeObserver.unobserve(this),this._sizeObserver=null),this._setDebounceSizesAttribute(),this._restoreOriginalBorderAndPadding(),this._removeDebugRegionOverlays(),this._setCssToMiddleCropOriginalImage(),this._restoreOriginalParentCssContainment()):(this._logger.debug("Enabled"),this._adaptParentCssContainment(),this._resetDebugRegionOverlays(),this._panAndZoomToBestRegion(),this._sizeObserver||(this._sizeObserver=new ResizeObserver(this._resizeCallback.bind(this)),this._sizeObserver.observe(this)))}_resizeCallback(e){if(this._isDisabled())return void this._logger.warn("Component disabled, spurious call to _resizeCallback()");const t=e.pop();if(!t)return void this._logger.warn("No ResizeObserverEntry, spurious call to _resizeCallback()");if(t.target!==this)return void this._logger.warn("Unexpected ResizeObserverEntry target");let i=new n;i=t.contentBoxSize?new n(t.contentBoxSize[0].inlineSize,t.contentBoxSize[0].blockSize):new n(t.contentRect.width,t.contentRect.height);this._elementSize.setIfDifferent(i)&&(this._logger.debug(`Element size: ${this._elementSize}`),this._populateFittedImageSize(),this._panAndZoomToBestRegion())}_imageLoadedLateCallback(){this._unregisterImageLoadedLateCallback(),this._logger.debug("Image loaded late"),this._populateFittedImageSize(),this._panAndZoomToBestRegion()}_registerImageLoadedLateCallback(){this._logger.debug('Registering "Image loaded late" callback...'),this.addEventListener("load",this._imageLoadedLateCallback)}_unregisterImageLoadedLateCallback(){this._logger.debug('Unregistering "Image loaded late" callback...'),this.removeEventListener("load",this._imageLoadedLateCallback)}_populateRectangleImageRegions(){this._logger.debug("Populating rectangle image regions..."),this._rectangleImageRegions=[];let e=[],t=!1;try{e=JSON.parse(this.dataset.imageRegions||"[]")}catch(e){t=!0}t||(t=!Array.isArray(e)),t&&(this._logger.warn("Invalid 'data-image-regions' attribute"),e=[]),e.forEach((e=>{const t=new o;t.setFields(e,this._logger),t.isUnknown()||(this._logger.debug(`Rectangle region found: id=${t.id}, position=${t.position}, size=${t.size}`),this._rectangleImageRegions.push(t))})),this._rectangleImageRegions.length||this._logger.debug("No rectangle image region found")}_populateFittedImageSize(){if(this.naturalWidth<=0&&this.naturalHeight<=0)return void this._logger.debug("Natural image size unknown, deferring.");const e=new n(this.naturalWidth,this.naturalHeight);let t=1;t=this._elementSize.getSafeRatio()<e.getSafeRatio()?this._elementSize.getSafeWidth()/e.getSafeWidth():this._elementSize.getSafeHeight()/e.getSafeHeight(),this._fittedImageSize=new n(this.naturalWidth*t,this.naturalHeight*t),this._fittedImageBottomRightMargin=new n(this._elementSize.getWidth()-this._fittedImageSize.getWidth(),this._elementSize.getHeight()-this._fittedImageSize.getHeight()),this._logger.debug(`Fitted image size: ${this._fittedImageSize}`),this._logger.debug(`Fitted image margin: ${this._fittedImageBottomRightMargin}`)}_panAndZoomToBestRegion(){if(this._logger.debug("Panning and zooming to best region..."),this._fittedImageSize.isUnknown())return void this._logger.debug("Fitted image size unknown, deferring.");let e=null;if(this.dataset.imageRegionId&&(e=this.dataset.imageRegionId===a._ORIGINAL_IMAGE_REGION.id?a._ORIGINAL_IMAGE_REGION:this._rectangleImageRegions.find((e=>e.id===this.dataset.imageRegionId))),e||(e=this._findBestRegion()),a._ORIGINAL_IMAGE_REGION.id!==e.id||this._debugRegionOverlayContainer){null===this._cssBorderToRestore&&(this._cssBorderToRestore=this.style.border,this.style.border="none"),null===this._cssPaddingToRestore&&(this._cssPaddingToRestore=this.style.padding,this.style.padding="0");const t=e.getTransformation(this._elementSize,this._fittedImageSize,this._fittedImageBottomRightMargin);if(this._setCssToPanAndZoomToRegion(t),this._debugRegionOverlayContainer&&this._drawDebugRegionOverlays(t),this.srcset.length>0&&this.sizes.length>0){const e=o.getTransformedImageSize(this._fittedImageSize,t).getWidth();this._setDebounceSizesAttribute(e)}}else this._setDebounceSizesAttribute(),this._restoreOriginalBorderAndPadding(),this._setCssToMiddleCropOriginalImage()}_findBestRegion(){let e=a._ORIGINAL_IMAGE_REGION,t=this._elementSize.ratioDiffFactor(this._fittedImageSize);return this._logger.debug(`Element ratio: ${this._elementSize.getSafeRatio().toFixed(3)}`),this._logger.debug(`Original image ratio: ${this._fittedImageSize.getSafeRatio().toFixed(3)}`),this.dataset.avoidNoRegion&&"off"===this.dataset.avoidNoRegion||(t=999),t>1.1&&this._rectangleImageRegions.forEach((i=>{const s=i.size.getSizeInPixels(this._fittedImageSize);this._logger.debug(`${i.id} region ratio: ${s.getSafeRatio().toFixed(3)}`);const n=this._elementSize.ratioDiffFactor(s);n<t&&(t=n,e=i)})),this._logger.debug(`Selected region: ${e.id}`),e}_adaptParentCssContainment(){const e=this._currentCssContainmentStrategy();"none"!==e?(this._parentElement=this.parentElement,this._parentElement&&("contain"===e?("paint"!==this._parentElement.style.contain&&"layout"!==this._parentElement.style.contain&&"content"!==this._parentElement.style.contain&&(null===this._parentCssContainToRestore&&(this._parentCssContainToRestore=this._parentElement.style.contain),this._parentElement.style.contain="paint"),this._restoreOriginalParentCssOverflow()):"overflow"===e&&("hidden"!==this._parentElement.style.overflow&&"clip"!==this._parentElement.style.overflow&&(null===this._parentCssOverflowToRestore&&(this._parentCssOverflowToRestore=this._parentElement.style.overflow),this._parentElement.style.overflow="hidden"),this._restoreOriginalParentCssContain()))):this._restoreOriginalParentCssContainment()}_restoreOriginalParentCssContainment(){this._restoreOriginalParentCssContain(),this._restoreOriginalParentCssOverflow()}_restoreOriginalParentCssContain(){this._parentElement&&null!==this._parentCssContainToRestore&&(this._parentElement.style.contain=this._parentCssContainToRestore,this._parentCssContainToRestore=null)}_restoreOriginalParentCssOverflow(){this._parentElement&&null!==this._parentCssOverflowToRestore&&(this._parentElement.style.overflow=this._parentCssOverflowToRestore,this._parentCssOverflowToRestore=null)}_setDebounceSizesAttribute(e){null!==this._sizesAttributeDebounceTimer&&clearTimeout(this._sizesAttributeDebounceTimer);this._sizesAttributeDebounceTimer=void 0!==e?window.setTimeout((()=>{if(this._sizesAttributeDebounceTimer=null,null===this._sizesAttributeToRestore&&(this._sizesAttributeToRestore=this.sizes),null===this._sizesAttributeLastSet||this._sizesAttributeLastSet<e){this._unregisterImageLoadedLateCallback();const t=`${Math.ceil(e)}px`;this._logger.debug(`Increasing sizes= to ${t}`),this.sizes=t,this._sizesAttributeLastSet=e}}),200):window.setTimeout((()=>{this._sizesAttributeDebounceTimer=null,null!==this._sizesAttributeToRestore&&(this._unregisterImageLoadedLateCallback(),this._logger.debug(`Resetting sizes= to ${this._sizesAttributeToRestore}`),this.sizes=this._sizesAttributeToRestore,this._sizesAttributeToRestore=null),this._sizesAttributeLastSet=null}),200)}_restoreOriginalBorderAndPadding(){null!==this._cssBorderToRestore&&(this.style.border=this._cssBorderToRestore,this._cssBorderToRestore=null),null!==this._cssPaddingToRestore&&(this.style.padding=this._cssPaddingToRestore,this._cssPaddingToRestore=null)}_setCssToMiddleCropOriginalImage(){this.style.objectFit="cover",this.style.objectPosition="center",this.style.transformOrigin="0 0",this.style.transform="none",this.style.clipPath="none"}_setCssToPanAndZoomToRegion(e){this.style.objectFit="contain",this.style.objectPosition="top left",this.style.transformOrigin=`${e.origin.x.toFixed(3)}px ${e.origin.y.toFixed(3)}px`,this.style.transform=`translate(${-e.origin.x.toFixed(3)}px, ${-e.origin.y.toFixed(3)}px) scale(${e.factor.toFixed(3)})`,this.style.clipPath=`inset(${e.insetClipFromTopLeft.getHeight()}px ${e.insetClipFromBottomRight.getWidth()}px ${e.insetClipFromBottomRight.getHeight()}px ${e.insetClipFromTopLeft.getWidth()}px)`}_resetDebugRegionOverlays(){"on"===(this.dataset.debugDrawRegions||"off")?this._recreateEmptyDebugRegionOverlays():this._removeDebugRegionOverlays()}_recreateEmptyDebugRegionOverlays(){var e;this._debugRegionOverlayContainer&&this._removeDebugRegionOverlays(),this._debugRegionOverlayContainer=document.createElement("div"),this._debugRegionOverlayContainer.style.position="absolute",null===(e=this._parentElement)||void 0===e||e.insertBefore(this._debugRegionOverlayContainer,this)}_removeDebugRegionOverlays(){var e;this._debugRegionOverlayContainer&&(null===(e=this._parentElement)||void 0===e||e.removeChild(this._debugRegionOverlayContainer),this._debugRegionOverlayContainer=null),this._debugRegionOverlays.clear()}_drawDebugRegionOverlays(e){this._rectangleImageRegions.forEach((t=>{this._drawDebugRegionOverlay(t,e)}))}_drawDebugRegionOverlay(e,t){var i;let s=this._debugRegionOverlays.get(e.id);s||(s=document.createElement("div"),s.style.position="absolute",s.style.boxSizing="border-box",s.style.border=this._pickNextOvelayStyle(),s.style.zIndex="999",null===(i=this._debugRegionOverlayContainer)||void 0===i||i.appendChild(s),this._debugRegionOverlays.set(e.id,s));const n=e.getBoundingBox(this._elementSize,this._fittedImageSize,t);s.style.left=`${n.position.x}px`,s.style.top=`${n.position.y}px`,s.style.width=`${n.size.getWidth()}px`,s.style.height=`${n.size.getHeight()}px`}_pickNextOvelayStyle(){const e=this._debugRegionOverlayStyles.shift()||"5px solid rgba(255, 0, 0, 0.7)";return this._debugRegionOverlayStyles.push(e),e}_populateBrowserFeatures(){const e=CSS.supports("clip-path: inset(5px)");e||this._logger.error("CSS `clip-path: inset()` is not supported. Disabling the web component");const t="undefined"!=typeof ResizeObserver;t||this._logger.error("ResizeObserver is not supported. Disabling the web component. Consider using a polyfill like https://github.com/juggle/resize-observer");const i=CSS.supports("contain: paint");i||this.dataset.cssContainFallback||this._logger.warn("CSS containment is not supported. Consider using the `css-contain-fallback=` attribute"),this._browserFeatures={cssInset:e,resizeObserver:t,cssContain:i}}_cssContainFallbackStrategy(){return"disable-containment"===this.dataset.cssContainFallback||"overflow-hidden"===this.dataset.cssContainFallback||"force"===this.dataset.cssContainFallback?this.dataset.cssContainFallback:"disable-component"}_isDisabled(){return"all"===this.dataset.disabled||!this._browserFeatures.cssInset||!this._browserFeatures.resizeObserver||this._isCssContainUnsupportedOrDisabled()&&"disable-component"===this._cssContainFallbackStrategy()}_isCssContainUnsupportedOrDisabled(){return!this._browserFeatures.cssContain||"css-contain"===this.dataset.disabled}_currentCssContainmentStrategy(){if(this._isDisabled())return"none";if(!this._isCssContainUnsupportedOrDisabled())return"contain";const e=this._cssContainFallbackStrategy();return"overflow-hidden"===e?"overflow":"disable-containment"===e?"none":"contain"}}a._ORIGINAL_IMAGE_REGION=new o("<no region>",new i(0,0),new s(1,1)),window.customElements.define("image-display-control",a,{extends:"img"});

@@ -250,2 +250,3 @@ import { Logger } from './Logger.js';

_registerImageLoadedLateCallback() {
this._logger.debug('Registering "Image loaded late" callback...');
this.addEventListener('load', this._imageLoadedLateCallback);

@@ -258,2 +259,3 @@ }

_unregisterImageLoadedLateCallback() {
this._logger.debug('Unregistering "Image loaded late" callback...');
this.removeEventListener('load', this._imageLoadedLateCallback);

@@ -472,3 +474,2 @@ }

_setDebounceSizesAttribute(newValuePx) {
this._unregisterImageLoadedLateCallback();
if (this._sizesAttributeDebounceTimer !== null) {

@@ -486,3 +487,6 @@ clearTimeout(this._sizesAttributeDebounceTimer);

this._sizesAttributeLastSet < newValuePx) {
this.sizes = `${Math.ceil(newValuePx)}px`;
this._unregisterImageLoadedLateCallback();
const newValuePxStr = `${Math.ceil(newValuePx)}px`;
this._logger.debug(`Increasing sizes= to ${newValuePxStr}`);
this.sizes = newValuePxStr;
this._sizesAttributeLastSet = newValuePx;

@@ -496,2 +500,4 @@ }

if (this._sizesAttributeToRestore !== null) {
this._unregisterImageLoadedLateCallback();
this._logger.debug(`Resetting sizes= to ${this._sizesAttributeToRestore}`);
this.sizes = this._sizesAttributeToRestore;

@@ -498,0 +504,0 @@ this._sizesAttributeToRestore = null;

@@ -69,3 +69,3 @@ # Importing in your project

type="module"
src="https://cdn.jsdelivr.net/npm/@frameright/image-display-control-web-component@1.1.2/dist/image-display-control.min.js"
src="https://cdn.jsdelivr.net/npm/@frameright/image-display-control-web-component@1.1.3/dist/image-display-control.min.js"
></script>

@@ -72,0 +72,0 @@ </body>

@@ -25,3 +25,3 @@ {

},
"version": "1.1.2",
"version": "1.1.3",
"main": "dist/src/index.js",

@@ -28,0 +28,0 @@ "module": "dist/src/index.js",

@@ -171,3 +171,3 @@ [<img src="https://avatars.githubusercontent.com/u/35964478?s=200&v=4" align="right" width="64" height="64">](https://frameright.io)

type="module"
src="https://cdn.jsdelivr.net/npm/@frameright/image-display-control-web-component@1.1.2/dist/image-display-control.min.js"
src="https://cdn.jsdelivr.net/npm/@frameright/image-display-control-web-component@1.1.3/dist/image-display-control.min.js"
></script>

@@ -255,2 +255,6 @@ ```

**1.1.3** (2023-05-10):
* Fixed bug where the web component would not always re-assess the new image
size after changing the `src=` attribute.
**1.1.2** (2023-05-09):

@@ -257,0 +261,0 @@ * Fixed bug where the web component would not re-assess the new image size

@@ -196,2 +196,3 @@ import { Logger } from './Logger.js';

private _registerImageLoadedLateCallback() {
this._logger.debug('Registering "Image loaded late" callback...');
this.addEventListener('load', this._imageLoadedLateCallback);

@@ -205,2 +206,3 @@ }

private _unregisterImageLoadedLateCallback() {
this._logger.debug('Unregistering "Image loaded late" callback...');
this.removeEventListener('load', this._imageLoadedLateCallback);

@@ -478,4 +480,2 @@ }

private _setDebounceSizesAttribute(newValuePx?: number) {
this._unregisterImageLoadedLateCallback();
if (this._sizesAttributeDebounceTimer !== null) {

@@ -498,3 +498,6 @@ clearTimeout(this._sizesAttributeDebounceTimer);

) {
this.sizes = `${Math.ceil(newValuePx)}px`;
this._unregisterImageLoadedLateCallback();
const newValuePxStr = `${Math.ceil(newValuePx)}px`;
this._logger.debug(`Increasing sizes= to ${newValuePxStr}`);
this.sizes = newValuePxStr;
this._sizesAttributeLastSet = newValuePx;

@@ -508,2 +511,6 @@ }

if (this._sizesAttributeToRestore !== null) {
this._unregisterImageLoadedLateCallback();
this._logger.debug(
`Resetting sizes= to ${this._sizesAttributeToRestore}`
);
this.sizes = this._sizesAttributeToRestore;

@@ -510,0 +517,0 @@ this._sizesAttributeToRestore = null;

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc