diff --git a/package.json b/package.json index c0dd3a4..9579062 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,8 @@ "babel-loader": "^8.0.5", "babel-preset-env": "^1.7.0", "image-focus": "^1.0.3", + "ts-loader": "^5.3.3", + "typescript": "^3.3.3", "uglifyjs-webpack-plugin": "^2.1.1", "webpack": "^4.29.0", "webpack-cli": "^3.2.1", @@ -22,6 +24,6 @@ "builddev": "webpack --config webpack.dev.js", "watch": "webpack --watch --config webpack.dev.js", "watchprod": "webpack --watch --config webpack.prod.js", - "fix-cs": "prettier --write 'src/js/**/*.+(js)' && prettier --write 'src/bundle/Resources/public/js/scripts/**/*.+(js)'" + "fix-cs": "prettier --write 'src/js/**/*.+(js|ts)' && prettier --write 'src/bundle/Resources/public/js/scripts/**/*.+(js|ts)'" } } diff --git a/src/bundle/Resources/public/js/focuspoint.js b/src/bundle/Resources/public/js/focuspoint.js index b43f43e..53404c4 100644 --- a/src/bundle/Resources/public/js/focuspoint.js +++ b/src/bundle/Resources/public/js/focuspoint.js @@ -1,11 +1 @@ -!function(t){var e={};function i(n){if(e[n])return e[n].exports;var s=e[n]={i:n,l:!1,exports:{}};return t[n].call(s.exports,s,s.exports,i),s.l=!0,s.exports}i.m=t,i.c=e,i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var s in t)i.d(n,s,function(e){return t[e]}.bind(null,s));return n},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=0)}([function(t,e,i){"use strict";function n(t){for(var e=[],i=1;i - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZEnhancedImageAssetBundle/blob/master/LICENSE - * - */var g,p,m,v,y,b,S=function(){function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.sources=new Map,this.element=e,this.currentSrc=null}var e,i;return e=t,(i=[{key:"addSource",value:function(t,e){var i={url:new URL(t,location),focusPoint:e};this.sources.set(i.url.pathname,i)}},{key:"getSource",value:function(t){return this.sources.get(t.pathname)}},{key:"updateFocusPoint",value:function(t){if(this.currentSrc===this.element.currentSrc&&!0!==t)return!1;var e=this.getSource(new URL(this.element.currentSrc,location));if(!e)return!1;new l(this.element,e.focusPoint),this.element.classList.add("focused"),this.currentSrc=this.element.currentSrc}}])&&f(e.prototype,i),t}(),I=(p=function(){for(var t,e=g,i=e.length,n=0;n - * @copyright 2018 Novactive - * @license https://github.com/Novactive/NovaeZEnhancedImageAssetBundle/blob/master/LICENSE - * - */ - -import { FocusedImage } from 'image-focus/dist/image-focus.es5'; +import { Focus } from 'image-focus/dist/types/interfaces.d'; +import { FocusedImage } from 'image-focus'; const CONTAINER_SELECTOR = 'enhancedimage--wrapper'; const IMAGE_SELECTOR = 'enhancedimage--img'; const THROTTLE_DELAY = 125; -let elements; +let elements: HTMLCollection; + +interface ImageElement extends HTMLImageElement { + _image?: Image; +} +interface Source { + url: URL; + focusPoint: Focus; +} class Image { - constructor(element) { + sources: Map; + element: HTMLImageElement; + currentSrc: string; + constructor(element: HTMLImageElement) { this.sources = new Map(); this.element = element; this.currentSrc = null; } - /** - * @param {string} urlString - * @param {Focus} focusPoint - */ - addSource(urlString, focusPoint) { - const source = { url: new URL(urlString, location), focusPoint: focusPoint }; + addSource(urlString: string, focusPoint: Focus) { + const url = new URL(urlString, window.location.toString()); + const source = { url: url, focusPoint: focusPoint }; this.sources.set(source.url.pathname, source); } - getSource(url) { + getSource(url: URL): Source | undefined { return this.sources.get(url.pathname); } - updateFocusPoint(forceUpdate) { + updateFocusPoint(forceUpdate?: boolean) { if (this.currentSrc === this.element.currentSrc && forceUpdate !== true) return false; - const currentSource = this.getSource(new URL(this.element.currentSrc, location)); + const currentSource = this.getSource(new URL(this.element.currentSrc, window.location.toString())); if (!currentSource) return false; new FocusedImage(this.element, currentSource.focusPoint); @@ -47,8 +45,8 @@ class Image { } } -const throttle = (func) => { - let inThrottle; +const throttle = (func: Function) => { + let inThrottle = false; return function() { const args = arguments; const context = this; @@ -71,15 +69,15 @@ const checkElements = function() { continue; } - const imageElement = loadedElements[i].getElementsByClassName(IMAGE_SELECTOR)[0]; + const imageElement = (loadedElements[i].getElementsByClassName(IMAGE_SELECTOR)[0]) as ImageElement; let image = imageElement._image; if (!image) { image = new Image(imageElement); image.addSource(imageElement.getAttribute('srcset'), { - x: imageElement.getAttribute('data-focus-x'), - y: imageElement.getAttribute('data-focus-y'), + x: parseFloat(imageElement.getAttribute('data-focus-x')), + y: parseFloat(imageElement.getAttribute('data-focus-y')), }); const sources = loadedElements[i].getElementsByTagName('source'); @@ -91,8 +89,8 @@ const checkElements = function() { } const source = sources[j]; image.addSource(source.getAttribute('srcset'), { - x: source.getAttribute('data-focus-x'), - y: source.getAttribute('data-focus-y'), + x: parseFloat(source.getAttribute('data-focus-x')), + y: parseFloat(source.getAttribute('data-focus-y')), }); } imageElement._image = image; @@ -109,7 +107,7 @@ const throttledCheckElements = throttle(checkElements); elements = document.getElementsByClassName(CONTAINER_SELECTOR); addEventListener('resize', throttledCheckElements, true); - if (window.MutationObserver) { + if (window && MutationObserver) { new MutationObserver(throttledCheckElements).observe(docElem, { childList: true, subtree: true, attributes: true }); } else { docElem['addEventListener']('DOMNodeInserted', throttledCheckElements, true); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c2e5763 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "outDir": "./dist/", + "sourceMap": true, + "noImplicitAny": true, + "module": "es6", + "lib": ["es5", "es6", "dom"], + "target": "es5", + "jsx": "react", + "allowJs": true + } +} diff --git a/webpack.common.js b/webpack.common.js index da27bee..fe493b8 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -13,7 +13,7 @@ const path = require('path'); module.exports = { entry: { - focuspoint: './src/js/focuspoint.js', + focuspoint: './src/js/focuspoint.ts', }, output: { filename: '[name].js', @@ -25,7 +25,15 @@ module.exports = { test: /\.js$/, exclude: /node_modules/, use: 'babel-loader', + }, + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/ } ], }, + resolve: { + extensions: [ '.tsx', '.ts', '.js' ] + }, };