diff --git a/.all-contributorsrc b/.all-contributorsrc deleted file mode 100644 index 2ebb8e5..0000000 --- a/.all-contributorsrc +++ /dev/null @@ -1,24 +0,0 @@ -{ - "files": [ - "README.md" - ], - "imageSize": 100, - "commit": false, - "contributors": [ - { - "login": "bbbenji", - "name": "Benji", - "avatar_url": "https://avatars.githubusercontent.com/u/1678118?v=4", - "profile": "https://github.com/bbbenji", - "contributions": [ - "code" - ] - } - ], - "contributorsPerLine": 7, - "projectName": "BetterViewer", - "projectOwner": "Ademking", - "repoType": "github", - "repoHost": "https://github.com", - "skipCi": true -} diff --git a/README.md b/README.md index 8a4cf2b..7648b87 100644 --- a/README.md +++ b/README.md @@ -62,19 +62,23 @@ - Edit in Photopea - Reverse Image Search - QR Code Scanner -- Settings to customize Toolbar +- Settings to customize Toolbar # Changelog +## [1.0.5] - 2022-09-14 +- Add "Zoom Ratio" option to Settings. (Thanks to @Metacor) + ## [1.0.4] - 2022-04-19 + - Add New Photo Editor [Filerobot Image Editor](https://scaleflex.github.io/filerobot-image-editor/) (Adjust, Draw, Watermark, Filters, Finetune, Resize, Export As PNG, JPEG, JPG, WEBP) - Fix a bug where Chrome/Edge adds a duplicate image (Thanks to @patrykdziurkowski) - Remove Photo Editor [Painterro](https://github.com/devforth/painterro) - ## [1.0.3] - 2022-02-10 + - Fix major bugs (Croppig issues, Going back issues, etc...) -- Add [Firefox](https://addons.mozilla.org/en-US/firefox/addon/betterviewer) Compatibilty +- Add [Firefox](https://addons.mozilla.org/en-US/firefox/addon/betterviewer) Compatibilty - Fix Cropping issues - Zoom In / Zoom Out is now smoother - Fix some UI issues @@ -85,6 +89,7 @@ - Add "Show/Hide all tools at the start" setting ## [1.0.2] - 2021-11-28 + - Fix minor bugs - Add "Reverse Image Search" - Add "QR Code Scanner" @@ -92,13 +97,16 @@ - Fix Shortcuts (Combo keys / Ctrl + Key ## [1.0.1] - 2021-11-20 + - Fix Crop problem - Fix random shutdown - Replace Imgur with ImgBB (Many users requested this) - Add "Edit with Photopea" - Add Contributors in About popup - Edit in Photopea (Thanks to @bbbenji) + ## [1.0.0] - 2021-11-10 + - First version ## Contributors ✨ @@ -112,6 +120,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Benji

💻
Patryk Dziurkowski

💻 +
Metacor

💻 diff --git a/dist/all.js b/dist/all.js index 1dca02b..dac99c4 100644 --- a/dist/all.js +++ b/dist/all.js @@ -4870,995 +4870,925 @@ g.resize=function(a,b,c){a||0===a?c||(this.width=a?a=T(a,K-this.left-this.right) // run when scripts and styles are loaded chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { - if (request.type == "injected") { - chrome.storage.sync.get('settings', function (settings) { - try { - if (settings.settings) { - init(settings); - } - } - catch (e) { - console.error('error while loading settings: ', e); - } - }); - } -}); - -let IS_PICKER_OPEN = false; -let IS_DETAILS_OPEN = false; -let IS_HELP_OPEN = false; -let IS_CROP_OPEN = false; - -let viewer; -let BACKGROUND_TYPE = "blurred"; -let ImgCanvas; -let isFlippedHorizontally = false; -let isFlippedVertically = false; -let IMGBB_TOKEN = '8be35a61597b285f9c95669fdc565b00'; -let isKeypressEnabled = false; -let WINBOX_CLASSES = [ - "no-scrollbar", - "no-max", - "no-min", - "no-full", - "no-resize", - "no-animation" -] + if (request.type == 'injected') { + chrome.storage.sync.get('settings', function (settings) { + try { + if (settings.settings) { + init(settings) + } + } catch (e) { + console.error('error while loading settings: ', e) + } + }) + } +}) + +let IS_PICKER_OPEN = false +let IS_DETAILS_OPEN = false +let IS_HELP_OPEN = false +let IS_CROP_OPEN = false + +let viewer +let BACKGROUND_TYPE = 'blurred' +let ImgCanvas +let isFlippedHorizontally = false +let isFlippedVertically = false +let IMGBB_TOKEN = '8be35a61597b285f9c95669fdc565b00' +let isKeypressEnabled = false +let WINBOX_CLASSES = ['no-scrollbar', 'no-max', 'no-min', 'no-full', 'no-resize', 'no-animation'] let ocrLangList = { - 'Afrikaans': 'afr', - 'Albanian': 'sqi', - 'Amharic': 'amh', - 'Arabic': 'ara', - 'Armenian': 'hye', - 'Azerbaijani': 'aze', - 'Basque': 'eus', - 'Belarusian': 'bel', - 'Bengali': 'ben', - 'Bosnian': 'bos', - 'Bulgarian': 'bul', - 'Burmese': 'mya', - 'Catalan': 'cat', - 'Cebuano': 'ceb', - 'Chinese Simplified': 'chi_sim', - 'Chinese Simplified (vertical)': 'chi_sim_vert', - 'Chinese Traditional': 'chi_tra', - 'Chinese Traditional (vertical)': 'chi_tra_vert', - 'Corsican': 'cos', - 'Croatian': 'hrv', - 'Czech': 'ces', - 'Danish': 'dan', - 'Dutch': 'nld', - 'English': 'eng', - 'Esperanto': 'epo', - 'Estonian': 'est', - 'Filipino': 'fil', - 'Finnish': 'fin', - 'French': 'fra', - 'Frisian': 'fry', - 'Galician': 'glg', - 'Georgian': 'kat', - 'German': 'deu', - 'Greek': 'ell', - 'Gujarati': 'guj', - 'Haitian': 'hat', - 'Hebrew': 'heb', - 'Hindi': 'hin', - 'Hungarian': 'hun', - 'Icelandic': 'isl', - 'Indonesian': 'ind', - 'Irish': 'gle', - 'Italian': 'ita', - 'Japanese': 'jpn', - 'Japanese (vertical)': 'jpn_vert', - 'Javanese': 'jav', - 'Kannada': 'kan', - 'Kazakh': 'kaz', - 'Khmer': 'khm', - 'Korean': 'kor', - 'Korean (vertical)': 'kor_vert', - 'Kurdish': 'kmr', - 'Lao': 'lao', - 'Latin': 'lat', - 'Latvian': 'lav', - 'Lithuanian': 'lit', - 'Luxembourgish': 'ltz', - 'Macedonian': 'mkd', - 'Malay': 'msa', - 'Malayalam': 'mal', - 'Maltese': 'mlt', - 'Maori': 'mri', - 'Marathi': 'mar', - 'Mongolian': 'mon', - 'Nepali': 'nep', - 'Norwegian': 'nor', - 'Persian': 'fas', - 'Polish': 'pol', - 'Portuguese': 'por', - 'Romanian': 'ron', - 'Russian': 'rus', - 'Scottish Gaelic': 'gla', - 'Serbian': 'srp', - 'Sindhi': 'snd', - 'Sinhala': 'sin', - 'Slovak': 'slk', - 'Slovenian': 'slv', - 'Spanish': 'spa', - 'Sundanese': 'sun', - 'Swahili': 'swa', - 'Swedish': 'swe', - 'Tajik': 'tgk', - 'Tamil': 'tam', - 'Telugu': 'tel', - 'Thai': 'tha', - 'Turkish': 'tur', - 'Ukrainian': 'ukr', - 'Urdu': 'urd', - 'Uzbek': 'uzb', - 'Vietnamese': 'vie', - 'Welsh': 'cym', - 'Yiddish': 'yid', - 'Yoruba': 'yor' -}; + Afrikaans: 'afr', + Albanian: 'sqi', + Amharic: 'amh', + Arabic: 'ara', + Armenian: 'hye', + Azerbaijani: 'aze', + Basque: 'eus', + Belarusian: 'bel', + Bengali: 'ben', + Bosnian: 'bos', + Bulgarian: 'bul', + Burmese: 'mya', + Catalan: 'cat', + Cebuano: 'ceb', + 'Chinese Simplified': 'chi_sim', + 'Chinese Simplified (vertical)': 'chi_sim_vert', + 'Chinese Traditional': 'chi_tra', + 'Chinese Traditional (vertical)': 'chi_tra_vert', + Corsican: 'cos', + Croatian: 'hrv', + Czech: 'ces', + Danish: 'dan', + Dutch: 'nld', + English: 'eng', + Esperanto: 'epo', + Estonian: 'est', + Filipino: 'fil', + Finnish: 'fin', + French: 'fra', + Frisian: 'fry', + Galician: 'glg', + Georgian: 'kat', + German: 'deu', + Greek: 'ell', + Gujarati: 'guj', + Haitian: 'hat', + Hebrew: 'heb', + Hindi: 'hin', + Hungarian: 'hun', + Icelandic: 'isl', + Indonesian: 'ind', + Irish: 'gle', + Italian: 'ita', + Japanese: 'jpn', + 'Japanese (vertical)': 'jpn_vert', + Javanese: 'jav', + Kannada: 'kan', + Kazakh: 'kaz', + Khmer: 'khm', + Korean: 'kor', + 'Korean (vertical)': 'kor_vert', + Kurdish: 'kmr', + Lao: 'lao', + Latin: 'lat', + Latvian: 'lav', + Lithuanian: 'lit', + Luxembourgish: 'ltz', + Macedonian: 'mkd', + Malay: 'msa', + Malayalam: 'mal', + Maltese: 'mlt', + Maori: 'mri', + Marathi: 'mar', + Mongolian: 'mon', + Nepali: 'nep', + Norwegian: 'nor', + Persian: 'fas', + Polish: 'pol', + Portuguese: 'por', + Romanian: 'ron', + Russian: 'rus', + 'Scottish Gaelic': 'gla', + Serbian: 'srp', + Sindhi: 'snd', + Sinhala: 'sin', + Slovak: 'slk', + Slovenian: 'slv', + Spanish: 'spa', + Sundanese: 'sun', + Swahili: 'swa', + Swedish: 'swe', + Tajik: 'tgk', + Tamil: 'tam', + Telugu: 'tel', + Thai: 'tha', + Turkish: 'tur', + Ukrainian: 'ukr', + Urdu: 'urd', + Uzbek: 'uzb', + Vietnamese: 'vie', + Welsh: 'cym', + Yiddish: 'yid', + Yoruba: 'yor' +} let tippyData = [ - { - type: 'zoom-in', - text: 'Zoom In' - }, - { - type: 'zoom-out', - text: 'Zoom Out' - }, - { - type: 'one-to-one', - text: '1:1' - }, - { - type: 'reset', - text: 'Reset' - }, - { - type: 'rotate-left', - text: 'Rotate Left', - }, - { - type: 'rotate-right', - text: 'Rotate Right', - }, - { - type: 'flip-horizontal', - text: 'Flip Horizontal', - }, - { - type: 'flip-vertical', - text: 'Flip Vertical', - }, - { - type: 'crop', - text: 'Crop Image', - }, - { - type: 'download', - text: 'Download', - }, - { - type: 'play', - text: 'Fullscreen', - }, - { - type: 'details', - text: 'Details', - }, - { - type: 'colorpicker', - text: 'Color Picker', - }, - { - type: 'paint', - text: 'Photo Editor', - }, - { - type: 'print', - text: 'Print image', - }, - { - type: 'help', - text: 'Help', - }, - { - type: 'theme', - text: 'Toggle Theme', - }, - { - type: 'exit', - text: 'Turn Off', - }, - { - type: 'upload', - text: 'Upload image to ImgBB', - }, - { - type: 'ocr', - text: 'Extract Text', - }, - { - type: 'photopea', - text: 'Edit in Photopea', - }, - { - type: 'tineye', - text: 'Reverse Image Search', - }, - { - type: 'about', - text: 'About', - }, - { - type: 'qr', - text: 'QR Code Scanner', - }, - { - type: 'settings', - text: 'Settings', - } + { + type: 'zoom-in', + text: 'Zoom In' + }, + { + type: 'zoom-out', + text: 'Zoom Out' + }, + { + type: 'one-to-one', + text: '1:1' + }, + { + type: 'reset', + text: 'Reset' + }, + { + type: 'rotate-left', + text: 'Rotate Left' + }, + { + type: 'rotate-right', + text: 'Rotate Right' + }, + { + type: 'flip-horizontal', + text: 'Flip Horizontal' + }, + { + type: 'flip-vertical', + text: 'Flip Vertical' + }, + { + type: 'crop', + text: 'Crop Image' + }, + { + type: 'download', + text: 'Download' + }, + { + type: 'play', + text: 'Fullscreen' + }, + { + type: 'details', + text: 'Details' + }, + { + type: 'colorpicker', + text: 'Color Picker' + }, + { + type: 'paint', + text: 'Photo Editor' + }, + { + type: 'print', + text: 'Print image' + }, + { + type: 'help', + text: 'Help' + }, + { + type: 'theme', + text: 'Toggle Theme' + }, + { + type: 'exit', + text: 'Turn Off' + }, + { + type: 'upload', + text: 'Upload image to ImgBB' + }, + { + type: 'ocr', + text: 'Extract Text' + }, + { + type: 'photopea', + text: 'Edit in Photopea' + }, + { + type: 'tineye', + text: 'Reverse Image Search' + }, + { + type: 'about', + text: 'About' + }, + { + type: 'qr', + text: 'QR Code Scanner' + }, + { + type: 'settings', + text: 'Settings' + } ] // Prevent default keyboard behavior (for example : ctrl + s or ctrl + f) // Except F11 (Suggestion from some users) document.addEventListener('keydown', function (e) { - if (!isKeypressEnabled) { - if (e.key !== 'F11') { // f11 is the only exception - e.preventDefault(); - } + if (!isKeypressEnabled) { + if (e.key !== 'F11') { + // f11 is the only exception + e.preventDefault() } - -}); + } +}) /** * NB: "mod" keyword same as "ctrl" - for cross-browser compatibility */ Mousetrap.bind('mod+0', () => { - document.getElementsByClassName('viewer-reset')[0].click(); -}); + document.getElementsByClassName('viewer-reset')[0].click() +}) Mousetrap.bind('mod+1', () => { - document.getElementsByClassName('viewer-one-to-one')[0].click(); -}); + document.getElementsByClassName('viewer-one-to-one')[0].click() +}) Mousetrap.bind('mod+s', () => { - document.getElementsByClassName('viewer-download')[0].click(); -}); + document.getElementsByClassName('viewer-download')[0].click() +}) Mousetrap.bind('mod++', () => { - document.getElementsByClassName('viewer-zoom-in')[0].click(); -}); + document.getElementsByClassName('viewer-zoom-in')[0].click() +}) Mousetrap.bind('mod+-', () => { - document.getElementsByClassName('viewer-zoom-out')[0].click(); -}); + document.getElementsByClassName('viewer-zoom-out')[0].click() +}) Mousetrap.bind('mod+left', () => { - document.getElementsByClassName('viewer-rotate-left')[0].click(); -}); + document.getElementsByClassName('viewer-rotate-left')[0].click() +}) Mousetrap.bind('mod+right', () => { - document.getElementsByClassName('viewer-rotate-right')[0].click(); -}); + document.getElementsByClassName('viewer-rotate-right')[0].click() +}) Mousetrap.bind('mod+a', () => { - document.getElementsByClassName('viewer-flip-horizontal')[0].click(); -}); + document.getElementsByClassName('viewer-flip-horizontal')[0].click() +}) Mousetrap.bind('mod+q', () => { - document.getElementsByClassName('viewer-flip-vertical')[0].click(); -}); + document.getElementsByClassName('viewer-flip-vertical')[0].click() +}) Mousetrap.bind('mod+x', () => { - document.getElementsByClassName('viewer-crop')[0].click(); -}); + document.getElementsByClassName('viewer-crop')[0].click() +}) Mousetrap.bind('mod+p', () => { - document.getElementsByClassName('viewer-paint')[0].click(); -}); + document.getElementsByClassName('viewer-paint')[0].click() +}) Mousetrap.bind('mod+c', () => { - document.getElementsByClassName('viewer-colorpicker')[0].click(); -}); + document.getElementsByClassName('viewer-colorpicker')[0].click() +}) Mousetrap.bind('mod+d', () => { - document.getElementsByClassName('viewer-details')[0].click(); -}); + document.getElementsByClassName('viewer-details')[0].click() +}) Mousetrap.bind('mod+h', () => { - document.getElementsByClassName('viewer-help')[0].click(); -}); + document.getElementsByClassName('viewer-help')[0].click() +}) Mousetrap.bind('mod+f', () => { - document.getElementsByClassName('viewer-play')[0].click(); -}); + document.getElementsByClassName('viewer-play')[0].click() +}) Mousetrap.bind('mod+m', () => { - document.getElementsByClassName('viewer-print')[0].click(); -}); + document.getElementsByClassName('viewer-print')[0].click() +}) Mousetrap.bind('mod+y', () => { - document.getElementsByClassName('viewer-theme')[0].click(); -}); + document.getElementsByClassName('viewer-theme')[0].click() +}) Mousetrap.bind('mod+e', () => { - document.getElementsByClassName('viewer-exit')[0].click(); -}); + document.getElementsByClassName('viewer-exit')[0].click() +}) Mousetrap.bind('mod+u', () => { - document.getElementsByClassName('viewer-upload')[0].click(); -}); + document.getElementsByClassName('viewer-upload')[0].click() +}) Mousetrap.bind('mod+g', () => { - document.getElementsByClassName('viewer-photopea')[0].click(); -}); + document.getElementsByClassName('viewer-photopea')[0].click() +}) Mousetrap.bind('mod+o', () => { - document.getElementsByClassName('viewer-ocr')[0].click(); -}); + document.getElementsByClassName('viewer-ocr')[0].click() +}) Mousetrap.bind('mod+j', () => { - document.getElementsByClassName('viewer-tineye')[0].click(); -}); - - + document.getElementsByClassName('viewer-tineye')[0].click() +}) /** * Initializes the extension */ function init(settings) { + BACKGROUND_TYPE = settings.settings.default_theme + + // checks the zoom setting - if it's nulled, then the default is set to 0.1 (10%) + settings.settings.zoom_ratio == null ? (settings.settings.zoom_ratio = 0.1) : (zoomSetting = settings.settings.zoom_ratio) + zoomSetting = settings.settings.zoom_ratio + + let imgElement = document.getElementsByTagName('img')[0] // get img element + // if img element is found + if (imgElement) { + let blurryDiv = document.createElement('div') // create blurry div + blurryDiv.setAttribute('class', 'blurry-bg') // add class to blurry div + imgElement.parentNode.insertBefore(blurryDiv, imgElement) // add before img element + + // init Viewer + viewer = new Viewer(imgElement, { + inline: false, + loading: false, + interval: 0, + zoomable: true, + transition: true, + navbar: false, + title: false, + keyboard: false, + backdrop: false, // prevent exit when click backdrop + zoomRatio: zoomSetting, + toolbar: { + next: false, + prev: false, + zoomIn: settings.settings.zoomIn && { + show: 1, + size: 'large' + }, + zoomOut: settings.settings.zoomOut && { + show: 1, + size: 'large' + }, + oneToOne: settings.settings.oneToOne && { + show: 1, + size: 'large' + }, + reset: settings.settings.reset && { + show: 1, + size: 'large', + click: function () { + viewer.image.src = window.location.href + viewer.reset() + setTimeout(() => { + if (settings.settings.toolbar_position === 'top') { + viewer.move(0, 50) + } + }, 100) + window.dispatchEvent(new Event('resize')) + } + }, + play: settings.settings.play && { + show: 1, + size: 'large', + click: function () { + viewer.image + .requestFullscreen() + .then(function () { + // console.log('requestFullscreen success'); + }) + .catch(function (error) { + console.error(error) + }) + } + }, + rotateLeft: settings.settings.rotateLeft && { + show: 1, + size: 'large' + }, + rotateRight: settings.settings.rotateRight && { + show: 1, + size: 'large' + }, + flipHorizontal: settings.settings.flipHorizontal && { + show: 1, + size: 'large' + }, + flipVertical: settings.settings.flipVertical && { + show: 1, + size: 'large' + }, + crop: settings.settings.crop && { + show: 1, + size: 'large', + click: function () { + if (!IS_CROP_OPEN) { + IS_CROP_OPEN = true + // reset viewer + //viewer.reset(); + let reset = viewer.reset() + setTimeout(() => { + if (settings.settings.toolbar_position === 'top') { + viewer.move(0, 50) + } + }, 100) + if (reset) { + crop(viewer, viewer.image.src, viewer.image.width, viewer.image.height) + } + } + } + }, + paint: settings.settings.paint && { + show: 1, + size: 'large', + click: function () { + isKeypressEnabled = true + // create new winbox + let winboxPaint = new WinBox('Photo Editor', { + class: ['no-scrollbar', 'no-min', 'no-animation'], + index: 9999, + x: 'center', + y: 'center', + width: '90%', + height: '90%', + background: 'rgba(0,0,0,0.9)', + html: `
` + }) + + winboxPaint.show() + + const config = { + theme: { + palette: { + 'txt-primary': '#ffffff', + 'txt-primary-invert': '#ffffff', + // 'txt-secondary': '#ffffff', + // 'txt-secondary-invert': '#ffffff', + // 'txt-placeholder': '#ffffff', + 'accent-primary': '#1E262C', + 'accent-primary-hover': '#000000', + 'accent-primary-active': '#000000', + // 'accent-primary-disabled': '#ffffff', + 'bg-primary': '#00000000' // canvas bg + //'bg-primary-hover': '#000000', + //'bg-primary-active': '#000000', + //'bg-primary-0-5-opacity': '#ffffff', + //'bg-secondary': '#ffffff', + //'icons-primary': '#ffffff', + //'icons-primary-opacity-0-6': '#ffffff', + //'icons-secondary': '#ffffff', + // 'btn-primary-text': '#ffffff', + // 'btn-disabled-text': '#ffffff', + // 'link-primary': '#ffffff', + // 'link-hover': '#ffffff', + // 'link-active': '#ffffff', + // 'borders-primary': '#ffffff', + // 'borders-secondary': '#ffffff', + // 'borders-strong': '#ffffff', + // 'borders-invert': '#ffffff', + // 'border-active-bottom': '#ffffff', + // 'active-secondary': '#ffffff', + // 'active-secondary-hover': '#ffffff', + // 'active-secondary-active': '#ffffff', + // 'tag': '#ffffff', + // 'error': '#ffffff', + // 'success': '#ffffff', + // 'warning': '#ffffff', + // 'info': '#ffffff', + // 'light-shadow': '#ffffff', + } + }, + onBeforeSave: function (imageFileInfo) { + // prevent default behavior + return false + }, + onSave: function (imageData, imageDesignState) { + console.log('~ imageDesignState', imageDesignState) + console.log('~ imageData', imageData) + let newImgBase64 = imageData.imageBase64 + let imgElements = document.getElementsByTagName('img') + for (let elem of imgElements) { + elem.src = newImgBase64 + } + // trigger resize event in setTimeout + setTimeout(function () { + window.dispatchEvent(new Event('resize')) + }, 100) + showNotification('💾 Image saved successfully', '#ffffff', '#000000', settings) + setTimeout(() => { + if (settings.settings.toolbar_position === 'top') { + viewer.move(0, 50) + } + }, 100) + winboxPaint.close() + }, + moreSaveOptions: [ + { + label: 'Save as new file', + onClick: (triggerSaveModal, triggerSave) => + triggerSaveModal((...args) => { + let a = document.createElement('a') + a.href = args[0].imageBase64 + a.download = args[0].fullName + a.click() + + showNotification('💾 Image downloaded successfully', '#ffffff', '#000000', settings) + }) + } + ], + source: viewer.image.src, + //onSave: (editedImageObject, designState) => console.log('saved', editedImageObject, designState), + annotationsCommon: { + fill: '#ff0000' + }, + Text: { text: 'Your Text Here...' }, + translations: { + profile: 'Profile', + coverPhoto: 'Cover photo', + facebook: 'Facebook', + socialMedia: 'Social Media', + fbProfileSize: '180x180px', + fbCoverPhotoSize: '820x312px' + }, + Crop: { + presetsItems: [ + { + titleKey: 'classicTv', + descriptionKey: '4:3', + ratio: 4 / 3 + // icon: CropClassicTv, // optional, CropClassicTv is a React Function component. Possible (React Function component, string or HTML Element) + }, + { + titleKey: 'cinemascope', + descriptionKey: '21:9', + ratio: 21 / 9 + // icon: CropCinemaScope, // optional, CropCinemaScope is a React Function component. Possible (React Function component, string or HTML Element) + } + ], + presetsFolders: [ + { + titleKey: 'socialMedia', // will be translated into Social Media as backend contains this translation key + // icon: Social, // optional, Social is a React Function component. Possible (React Function component, string or HTML Element) + groups: [ + { + titleKey: 'facebook', + items: [ + { + titleKey: 'profile', + width: 180, + height: 180, + descriptionKey: 'fbProfileSize' + }, + { + titleKey: 'coverPhoto', + width: 820, + height: 312, + descriptionKey: 'fbCoverPhotoSize' + } + ] + } + ] + } + ] + }, + tabsIds: [window.FilerobotImageEditor.TABS.ADJUST, window.FilerobotImageEditor.TABS.ANNOTATE, window.FilerobotImageEditor.TABS.WATERMARK, window.FilerobotImageEditor.TABS.FILTERS, window.FilerobotImageEditor.TABS.FINETUNE, window.FilerobotImageEditor.TABS.RESIZE], // or ['Adjust', 'Annotate', 'Watermark'] + defaultTabId: window.FilerobotImageEditor.TABS.ANNOTATE, // or 'Annotate' + defaultToolId: window.FilerobotImageEditor.TOOLS.TEXT // or 'Text' + } + console.log(window.FilerobotImageEditor.TABS) - BACKGROUND_TYPE = settings.settings.default_theme; - - // checks the zoom setting - if it's nulled, then the default is set to 0.1 (10%) - settings.settings.zoom_ratio == null ? settings.settings.zoom_ratio = 0.1 : zoomSetting = settings.settings.zoom_ratio; - zoomSetting = settings.settings.zoom_ratio; - - let imgElement = document.getElementsByTagName('img')[0]; // get img element - // if img element is found - if (imgElement) { - - let blurryDiv = document.createElement('div'); // create blurry div - blurryDiv.setAttribute('class', 'blurry-bg'); // add class to blurry div - imgElement.parentNode.insertBefore(blurryDiv, imgElement); // add before img element - - - // init Viewer - viewer = new Viewer(imgElement, { - inline: false, - loading: false, - interval: 0, - zoomable: true, - transition: true, - navbar: false, - title: false, - keyboard: false, - backdrop: false, // prevent exit when click backdrop - zoomRatio: zoomSetting, - toolbar: { - next: false, - prev: false, - zoomIn: settings.settings.zoomIn && { - show: 1, - size: 'large', - }, - zoomOut: settings.settings.zoomOut && { - show: 1, - size: 'large', - }, - oneToOne: settings.settings.oneToOne && { - show: 1, - size: 'large', - }, - reset: settings.settings.reset && { - show: 1, - size: 'large', - click: function () { - viewer.image.src = window.location.href; - viewer.reset(); - setTimeout(() => { - if (settings.settings.toolbar_position === 'top') { - viewer.move(0, 50); - } - }, 100) - window.dispatchEvent(new Event('resize')); - } - }, - play: settings.settings.play && { - show: 1, - size: 'large', - click: function () { - viewer.image.requestFullscreen() - .then(function () { - // console.log('requestFullscreen success'); - }) - .catch(function (error) { - console.error(error); - }); - } - }, - rotateLeft: settings.settings.rotateLeft && { - show: 1, - size: 'large', - }, - rotateRight: settings.settings.rotateRight && { - show: 1, - size: 'large', - }, - flipHorizontal: settings.settings.flipHorizontal && { - show: 1, - size: 'large', - }, - flipVertical: settings.settings.flipVertical && { - show: 1, - size: 'large', - }, - crop: settings.settings.crop && { - show: 1, - size: 'large', - click: function () { - if (!IS_CROP_OPEN) { - IS_CROP_OPEN = true; - // reset viewer - //viewer.reset(); - let reset = viewer.reset(); - setTimeout(() => { - if (settings.settings.toolbar_position === 'top') { - viewer.move(0, 50); - } - }, 100) - if (reset) { - crop(viewer, viewer.image.src, viewer.image.width, viewer.image.height); - } - - - } - - } - }, - paint: settings.settings.paint && { - show: 1, - size: 'large', - click: function () { - - isKeypressEnabled = true; - // create new winbox - let winboxPaint = new WinBox("Photo Editor", { - class: [ - "no-scrollbar", - "no-min", - "no-animation" - ], - index: 9999, - x: "center", - y: "center", - width: '90%', - height: '90%', - background: "rgba(0,0,0,0.9)", - html: `
`, - }); - - winboxPaint.show(); - - - const config = { - - theme: { - palette: { - 'txt-primary': '#ffffff', - 'txt-primary-invert': '#ffffff', - // 'txt-secondary': '#ffffff', - // 'txt-secondary-invert': '#ffffff', - // 'txt-placeholder': '#ffffff', - 'accent-primary': '#1E262C', - 'accent-primary-hover': '#000000', - 'accent-primary-active': '#000000', - // 'accent-primary-disabled': '#ffffff', - 'bg-primary': '#00000000', // canvas bg - //'bg-primary-hover': '#000000', - //'bg-primary-active': '#000000', - //'bg-primary-0-5-opacity': '#ffffff', - //'bg-secondary': '#ffffff', - //'icons-primary': '#ffffff', - //'icons-primary-opacity-0-6': '#ffffff', - //'icons-secondary': '#ffffff', - // 'btn-primary-text': '#ffffff', - // 'btn-disabled-text': '#ffffff', - // 'link-primary': '#ffffff', - // 'link-hover': '#ffffff', - // 'link-active': '#ffffff', - // 'borders-primary': '#ffffff', - // 'borders-secondary': '#ffffff', - // 'borders-strong': '#ffffff', - // 'borders-invert': '#ffffff', - // 'border-active-bottom': '#ffffff', - // 'active-secondary': '#ffffff', - // 'active-secondary-hover': '#ffffff', - // 'active-secondary-active': '#ffffff', - // 'tag': '#ffffff', - // 'error': '#ffffff', - // 'success': '#ffffff', - // 'warning': '#ffffff', - // 'info': '#ffffff', - // 'light-shadow': '#ffffff', - }, - - }, - onBeforeSave: function (imageFileInfo) { - // prevent default behavior - return false; - }, - onSave: function (imageData, imageDesignState) { - - console.log("~ imageDesignState", imageDesignState) - console.log("~ imageData", imageData) - let newImgBase64 = imageData.imageBase64; - let imgElements = document.getElementsByTagName('img'); - for (let elem of imgElements) { - elem.src = newImgBase64; - } - // trigger resize event in setTimeout - setTimeout(function () { - window.dispatchEvent(new Event('resize')); - }, 100); - showNotification('💾 Image saved successfully', '#ffffff', '#000000', settings); - setTimeout(() => { - if (settings.settings.toolbar_position === 'top') { - viewer.move(0, 50); - } - }, 100); - winboxPaint.close(); - - }, - moreSaveOptions: - [ - { - label: 'Save as new file', - onClick: (triggerSaveModal, triggerSave) => triggerSaveModal((...args) => { - - - - let a = document.createElement("a"); - a.href = args[0].imageBase64; - a.download = args[0].fullName - a.click(); - - showNotification('💾 Image downloaded successfully', '#ffffff', '#000000', settings); - - }), - }, - - - ] - , - source: viewer.image.src, - //onSave: (editedImageObject, designState) => console.log('saved', editedImageObject, designState), - annotationsCommon: { - fill: '#ff0000', - }, - Text: { text: 'Your Text Here...' }, - translations: { - profile: 'Profile', - coverPhoto: 'Cover photo', - facebook: 'Facebook', - socialMedia: 'Social Media', - fbProfileSize: '180x180px', - fbCoverPhotoSize: '820x312px', - }, - Crop: { - presetsItems: [ - { - titleKey: 'classicTv', - descriptionKey: '4:3', - ratio: 4 / 3, - // icon: CropClassicTv, // optional, CropClassicTv is a React Function component. Possible (React Function component, string or HTML Element) - }, - { - titleKey: 'cinemascope', - descriptionKey: '21:9', - ratio: 21 / 9, - // icon: CropCinemaScope, // optional, CropCinemaScope is a React Function component. Possible (React Function component, string or HTML Element) - }, - ], - presetsFolders: [ - { - titleKey: 'socialMedia', // will be translated into Social Media as backend contains this translation key - // icon: Social, // optional, Social is a React Function component. Possible (React Function component, string or HTML Element) - groups: [ - { - titleKey: 'facebook', - items: [ - { - titleKey: 'profile', - width: 180, - height: 180, - descriptionKey: 'fbProfileSize', - }, - { - titleKey: 'coverPhoto', - width: 820, - height: 312, - descriptionKey: 'fbCoverPhotoSize', - }, - ], - }, - ], - }, - ], - }, - tabsIds: [window.FilerobotImageEditor.TABS.ADJUST, - window.FilerobotImageEditor.TABS.ANNOTATE, - window.FilerobotImageEditor.TABS.WATERMARK, - window.FilerobotImageEditor.TABS.FILTERS, - window.FilerobotImageEditor.TABS.FINETUNE, - window.FilerobotImageEditor.TABS.RESIZE, - - - - ], // or ['Adjust', 'Annotate', 'Watermark'] - defaultTabId: window.FilerobotImageEditor.TABS.ANNOTATE, // or 'Annotate' - defaultToolId: window.FilerobotImageEditor.TOOLS.TEXT, // or 'Text' - }; - - console.log(window.FilerobotImageEditor.TABS) - - // Assuming we have a div with id="editor_container" - const filerobotImageEditor = new FilerobotImageEditor( - document.querySelector('#paint-wrapper'), - config - ); - - filerobotImageEditor.render({ - onClose: (closingReason) => { - console.log('Closing reason', closingReason); - filerobotImageEditor.terminate(); - } - }); - - - - - // window.p = Painterro({ - // hideByEsc: true, - // saveByEnter: true, - // hiddenTools: [ - // 'open', 'close', 'resize', 'eraser' - // ], - // id: 'paint-wrapper', - // availableLineWidths: [1, 2, 4, 8, 16, 64], - // availableEraserWidths: [1, 2, 4, 8, 16, 64], - // availableFontSizes: [1, 2, 4, 8, 16, 64], - // availableArrowLengths: [10, 20, 30, 40, 50, 60], - // defaultTool: 'brush', - // saveHandler: (image, done) => { - - // let newImgBase64 = image.asDataURL(); - - // let imgElements = document.getElementsByTagName('img'); - // // loop through all img elements - // // for (let i = 0; i < imgElements.length; i++) { - // // // replace image with cropped image - // // imgElements[i].src = newImgBase64; - // // } - - // for (let elem of imgElements) { - // elem.src = newImgBase64; - // } - - // // trigger resize event in setTimeout - // setTimeout(function () { - // window.dispatchEvent(new Event('resize')); - // }, 100); - - // showNotification('💾 Image saved successfully', '#ffffff', '#000000', settings); - // setTimeout(() => { - // if (settings.settings.toolbar_position === 'top') { - // viewer.move(0, 50); - // } - // }, 100); - - // winboxPaint.close(); - // done(true); - // } - // }).show(viewer.image.src); - } - }, - download: settings.settings.download && { - show: 1, - size: 'large', - click: function () { - download(viewer.image); - } - }, - upload: settings.settings.upload && { - show: 1, - size: 'large', - click: function () { - - let uriString = getBase64Image(viewer.image); - - // get base64 part from string - let base64 = uriString.split(',')[1]; - - // create html element with text - let x = document.createElement("div"); - // set flex - x.style.display = "flex"; - // set element inner html - x.innerHTML = ` Uploading image... Please wait`; - - Toastify({ - node: x, - duration: 999999, - newWindow: true, - close: false, - gravity: settings.settings.notification_gravity, // `top` or `bottom` - position: settings.settings.notification_position, // `left`, `center` or `right` - stopOnFocus: true, // Prevents dismissing of toast on hover - style: { - color: '#ffffff', - background: '#000000', - }, - //onClick: function () { } // Callback after click - }).showToast(); - - // upload image to imgur - // fetch('https://api.imgur.com/3/image', { - // method: 'POST', - // headers: { 'Authorization': `Client-ID ${IMGUR_TOKEN}` }, - // body: base64 - // }) - - // upload base64 to ImgBB - let formdata = new FormData(); - formdata.append("image", base64); - - let requestOptions = { - method: 'POST', - body: formdata, - redirect: 'follow' - }; - - fetch(`https://api.imgbb.com/1/upload?expiration=600&key=${IMGBB_TOKEN}`, requestOptions) - .then(res => res.json()) - .then((res) => { - - // remove toast - let toastifyElems = document.querySelectorAll('.toastify'); - toastifyElems.forEach(element => { - element.remove() - }); - - copyToClipboard(res.data.image.url); - showNotification('✔️ Image uploaded successfully', '#ffffff', '#000000', settings); - showNotification(`📋 URL copied to clipboard`, '#ffffff', '#000000', settings); - - }); - - } - }, - colorpicker: settings.settings.colorpicker && { - show: 1, - size: 'large', - click: async function () { - - if (!IS_PICKER_OPEN) { - IS_PICKER_OPEN = true; - - // change cursor to picker - viewer.image.style.cursor = 'crosshair'; - - + // Assuming we have a div with id="editor_container" + const filerobotImageEditor = new FilerobotImageEditor(document.querySelector('#paint-wrapper'), config) - let colorPickerBox = new WinBox("Color Preview", { - class: WINBOX_CLASSES, - background: "rgba(0,0,0,0.9)", - index: 9999, - width: '250px', - height: '250px', - y: "bottom", - x: "10px", - html: ` + filerobotImageEditor.render({ + onClose: closingReason => { + console.log('Closing reason', closingReason) + filerobotImageEditor.terminate() + } + }) + + // window.p = Painterro({ + // hideByEsc: true, + // saveByEnter: true, + // hiddenTools: [ + // 'open', 'close', 'resize', 'eraser' + // ], + // id: 'paint-wrapper', + // availableLineWidths: [1, 2, 4, 8, 16, 64], + // availableEraserWidths: [1, 2, 4, 8, 16, 64], + // availableFontSizes: [1, 2, 4, 8, 16, 64], + // availableArrowLengths: [10, 20, 30, 40, 50, 60], + // defaultTool: 'brush', + // saveHandler: (image, done) => { + + // let newImgBase64 = image.asDataURL(); + + // let imgElements = document.getElementsByTagName('img'); + // // loop through all img elements + // // for (let i = 0; i < imgElements.length; i++) { + // // // replace image with cropped image + // // imgElements[i].src = newImgBase64; + // // } + + // for (let elem of imgElements) { + // elem.src = newImgBase64; + // } + + // // trigger resize event in setTimeout + // setTimeout(function () { + // window.dispatchEvent(new Event('resize')); + // }, 100); + + // showNotification('💾 Image saved successfully', '#ffffff', '#000000', settings); + // setTimeout(() => { + // if (settings.settings.toolbar_position === 'top') { + // viewer.move(0, 50); + // } + // }, 100); + + // winboxPaint.close(); + // done(true); + // } + // }).show(viewer.image.src); + } + }, + download: settings.settings.download && { + show: 1, + size: 'large', + click: function () { + download(viewer.image) + } + }, + upload: settings.settings.upload && { + show: 1, + size: 'large', + click: function () { + let uriString = getBase64Image(viewer.image) + + // get base64 part from string + let base64 = uriString.split(',')[1] + + // create html element with text + let x = document.createElement('div') + // set flex + x.style.display = 'flex' + // set element inner html + x.innerHTML = ` Uploading image... Please wait` + + Toastify({ + node: x, + duration: 999999, + newWindow: true, + close: false, + gravity: settings.settings.notification_gravity, // `top` or `bottom` + position: settings.settings.notification_position, // `left`, `center` or `right` + stopOnFocus: true, // Prevents dismissing of toast on hover + style: { + color: '#ffffff', + background: '#000000' + } + //onClick: function () { } // Callback after click + }).showToast() + + // upload image to imgur + // fetch('https://api.imgur.com/3/image', { + // method: 'POST', + // headers: { 'Authorization': `Client-ID ${IMGUR_TOKEN}` }, + // body: base64 + // }) + + // upload base64 to ImgBB + let formdata = new FormData() + formdata.append('image', base64) + + let requestOptions = { + method: 'POST', + body: formdata, + redirect: 'follow' + } + + fetch(`https://api.imgbb.com/1/upload?expiration=600&key=${IMGBB_TOKEN}`, requestOptions) + .then(res => res.json()) + .then(res => { + // remove toast + let toastifyElems = document.querySelectorAll('.toastify') + toastifyElems.forEach(element => { + element.remove() + }) + + copyToClipboard(res.data.image.url) + showNotification('✔️ Image uploaded successfully', '#ffffff', '#000000', settings) + showNotification(`📋 URL copied to clipboard`, '#ffffff', '#000000', settings) + }) + } + }, + colorpicker: settings.settings.colorpicker && { + show: 1, + size: 'large', + click: async function () { + if (!IS_PICKER_OPEN) { + IS_PICKER_OPEN = true + + // change cursor to picker + viewer.image.style.cursor = 'crosshair' + + let colorPickerBox = new WinBox('Color Preview', { + class: WINBOX_CLASSES, + background: 'rgba(0,0,0,0.9)', + index: 9999, + width: '250px', + height: '250px', + y: 'bottom', + x: '10px', + html: `
`, - onclose: function () { - IS_PICKER_OPEN = false; - // change cursor back to default - viewer.image.style.cursor = 'default'; - viewer.image.click(); // trigger a click to remove the event listener - } - }); - - - // init color picker - const pickr = Pickr.create({ - el: '.color-picker', - inline: true, - showAlways: true, - theme: 'classic', // or 'monolith', or 'nano' - useAsButton: false, - autoReposition: true, - appClass: 'color-picker-app', - components: { - - // Main components - preview: true, - opacity: false, - hue: true, - - // Input / output Options - interaction: { - hex: true, - rgba: true, - hsla: true, - hsva: true, - cmyk: true, - input: true, - } - } - }); - - - - // auto size window - let contentWidth = document.getElementsByClassName('pcr-app')[0].getBoundingClientRect().width; - let contentHeight = document.getElementsByClassName('pcr-app')[0].getBoundingClientRect().height; - colorPickerBox.resize(contentWidth + 8, contentHeight + 35); // TODO: use better way to get content height and width - colorPickerBox.show(); - - // create new canvas - let canvas = document.createElement('canvas'); - canvas.style.display = 'none'; - - let x = '' - let y = ''; - - - // when image clicked - viewer.image.addEventListener('click', function (e) { - if (IS_PICKER_OPEN) { - handleImageClickOnPicker(e, viewer, canvas, pickr, x, y, settings); - } - else { - this.removeEventListener('click', arguments.callee); - } - - }, false); - - // when mouse move - viewer.image.addEventListener('mousemove', function (e) { - if (IS_PICKER_OPEN) { - handleMouseMoveOnPicker(e, viewer, canvas, pickr, x, y); - } - else { - this.removeEventListener('mousemove', arguments.callee); - } - - }, false); - } - else { - return; - } - } + onclose: function () { + IS_PICKER_OPEN = false + // change cursor back to default + viewer.image.style.cursor = 'default' + viewer.image.click() // trigger a click to remove the event listener + } + }) + + // init color picker + const pickr = Pickr.create({ + el: '.color-picker', + inline: true, + showAlways: true, + theme: 'classic', // or 'monolith', or 'nano' + useAsButton: false, + autoReposition: true, + appClass: 'color-picker-app', + components: { + // Main components + preview: true, + opacity: false, + hue: true, + + // Input / output Options + interaction: { + hex: true, + rgba: true, + hsla: true, + hsva: true, + cmyk: true, + input: true + } + } + }) + + // auto size window + let contentWidth = document.getElementsByClassName('pcr-app')[0].getBoundingClientRect().width + let contentHeight = document.getElementsByClassName('pcr-app')[0].getBoundingClientRect().height + colorPickerBox.resize(contentWidth + 8, contentHeight + 35) // TODO: use better way to get content height and width + colorPickerBox.show() + + // create new canvas + let canvas = document.createElement('canvas') + canvas.style.display = 'none' + + let x = '' + let y = '' + + // when image clicked + viewer.image.addEventListener( + 'click', + function (e) { + if (IS_PICKER_OPEN) { + handleImageClickOnPicker(e, viewer, canvas, pickr, x, y, settings) + } else { + this.removeEventListener('click', arguments.callee) + } }, - details: settings.settings.details && { - show: 1, - size: 'large', - click: async function () { - if (!IS_DETAILS_OPEN) { - IS_DETAILS_OPEN = true; - try { - new WinBox("Details", { - class: [ - //"no-scrollbar", - "no-max", - "no-min", - "no-full", - "no-resize", - "no-animation" - ], - index: 9999, - background: "rgba(0,0,0,0.9)", - x: "20px", - y: "20px", - width: '350px', - height: '40%', - html: `
`, - onclose: function () { - IS_DETAILS_OPEN = false; - } - }); - } catch (error) { - console.error(error); - } - } - - let img2 = viewer.image - - const fileImg = await fetch(img2.src).then(r => r.blob()); - let fileSizeMB = fileImg.size / 1024 / 1024; - - let imgDetails = { - width: img2.naturalWidth, - height: img2.naturalHeight, - filesize: fileSizeMB.toFixed(2) + " MB", - } - - EXIF.getData(img2, function () { - let allMetaData = EXIF.getAllTags(this); - // add all metadata to wrapper - // let wrapper = document.getElementById('details-wrapper'); - - delete allMetaData.ImageWidth; - delete allMetaData.ImageHeight; - delete allMetaData.thumbnail; - - - allMetaData = { Width: imgDetails.width + "px", Height: imgDetails.height + "px", "File size": imgDetails.filesize, ...allMetaData }; - - - - let el = document.querySelector('#details-wrapper'); - el.innerHTML = jsonViewer(allMetaData, true); - + false + ) + + // when mouse move + viewer.image.addEventListener( + 'mousemove', + function (e) { + if (IS_PICKER_OPEN) { + handleMouseMoveOnPicker(e, viewer, canvas, pickr, x, y) + } else { + this.removeEventListener('mousemove', arguments.callee) + } + }, + false + ) + } else { + return + } + } + }, + details: settings.settings.details && { + show: 1, + size: 'large', + click: async function () { + if (!IS_DETAILS_OPEN) { + IS_DETAILS_OPEN = true + try { + new WinBox('Details', { + class: [ + //"no-scrollbar", + 'no-max', + 'no-min', + 'no-full', + 'no-resize', + 'no-animation' + ], + index: 9999, + background: 'rgba(0,0,0,0.9)', + x: '20px', + y: '20px', + width: '350px', + height: '40%', + html: `
`, + onclose: function () { + IS_DETAILS_OPEN = false + } + }) + } catch (error) { + console.error(error) + } + } + let img2 = viewer.image - // convert to string - //let metaDataString = JSON.stringify(allMetaData, null, "\t"); + const fileImg = await fetch(img2.src).then(r => r.blob()) + let fileSizeMB = fileImg.size / 1024 / 1024 - // add string inside wrapper - //wrapper.innerHTML = metaDataString; + let imgDetails = { + width: img2.naturalWidth, + height: img2.naturalHeight, + filesize: fileSizeMB.toFixed(2) + ' MB' + } + EXIF.getData(img2, function () { + let allMetaData = EXIF.getAllTags(this) + // add all metadata to wrapper + // let wrapper = document.getElementById('details-wrapper'); + delete allMetaData.ImageWidth + delete allMetaData.ImageHeight + delete allMetaData.thumbnail - }); + allMetaData = { Width: imgDetails.width + 'px', Height: imgDetails.height + 'px', 'File size': imgDetails.filesize, ...allMetaData } - } - }, - theme: settings.settings.theme && { - show: 1, - size: 'large', - click: function () { - // blur --> light --> dark - changeTheme(viewer.image.src, settings); + let el = document.querySelector('#details-wrapper') + el.innerHTML = jsonViewer(allMetaData, true) - } - }, - print: settings.settings.print && { - show: 1, - size: 'large', - click: function () { - printImage(viewer.image); - } - }, - ocr: settings.settings.ocr && { - show: 1, - size: 'large', - click: function () { - - let v = viewer; - let url = viewer.image.src; - let width = viewer.image.width; - let height = viewer.image.height; - - - let ocrPreviewBox = new WinBox("Image To Text: Select Region", { - id: 'ocr-preview', - class: WINBOX_CLASSES, - modal: false, - index: 9999, - x: "center", - y: "center", - width: width + 7, - height: height + 40, - background: "rgba(0,0,0,0.9)", - html: `
`, - onclose: function () { - document.querySelector('#ocr-preview').remove(); - document.querySelector('#ocr-settings').remove(); - } + // convert to string + //let metaDataString = JSON.stringify(allMetaData, null, "\t"); - }); - ocrPreviewBox.show(); - let ocrControlBox = new WinBox("Image To Text: Settings", { - id: 'ocr-settings', - class: WINBOX_CLASSES, - modal: false, - index: 9999, - x: "10px", - y: "bottom", - top: '10px', - bottom: '10px', - right: '10px', - left: '10px', - width: '250px', - height: '160px', - background: "rgba(0,0,0,0.9)", - html: ` + // add string inside wrapper + //wrapper.innerHTML = metaDataString; + }) + } + }, + theme: settings.settings.theme && { + show: 1, + size: 'large', + click: function () { + // blur --> light --> dark + changeTheme(viewer.image.src, settings) + } + }, + print: settings.settings.print && { + show: 1, + size: 'large', + click: function () { + printImage(viewer.image) + } + }, + ocr: settings.settings.ocr && { + show: 1, + size: 'large', + click: function () { + let v = viewer + let url = viewer.image.src + let width = viewer.image.width + let height = viewer.image.height + + let ocrPreviewBox = new WinBox('Image To Text: Select Region', { + id: 'ocr-preview', + class: WINBOX_CLASSES, + modal: false, + index: 9999, + x: 'center', + y: 'center', + width: width + 7, + height: height + 40, + background: 'rgba(0,0,0,0.9)', + html: `
`, + onclose: function () { + document.querySelector('#ocr-preview').remove() + document.querySelector('#ocr-settings').remove() + } + }) + ocrPreviewBox.show() + let ocrControlBox = new WinBox('Image To Text: Settings', { + id: 'ocr-settings', + class: WINBOX_CLASSES, + modal: false, + index: 9999, + x: '10px', + y: 'bottom', + top: '10px', + bottom: '10px', + right: '10px', + left: '10px', + width: '250px', + height: '160px', + background: 'rgba(0,0,0,0.9)', + html: `
Select Language
@@ -5869,533 +5799,481 @@ function init(settings) {
`, - onclose: function () { - document.querySelector('#ocr-preview').remove(); - document.querySelector('#ocr-settings').remove(); - document.querySelector('#ocr-result-box').remove(); - } - }); - ocrControlBox.show(); - let imgCropper = tinycrop.create({ - parent: '#parent-crop', - image: url, - bounds: { - width: width, - height: height - }, - backgroundColors: ['#fff', '#f3f3f3'], - selection: { - color: '#212121CC', - activeColor: '#ff0000CC', - minWidth: 10, - minHeight: 10, - x: v.image.naturalWidth / 2 - width / 2, - y: v.image.naturalHeight / 2 - height / 2, - width: width, - height: height - }, - onInit: () => { console.log('Initialised') } - }); - - let region; // contains the cropped region - imgCropper.on('change', (r) => { - region = r; - }); - - Object.keys(ocrLangList).forEach(function (key) { - let option = document.createElement('option'); - option.value = ocrLangList[key]; - option.text = key; - if (key == 'English') { - option.selected = true; - } - document.querySelector('#ocr-languages').appendChild(option); - }); - // when btn-extract-text clicked - document.getElementById('btn-extract-text').addEventListener('click', function () { - - // get selected language - let selectedLang = document.querySelector('#ocr-languages').value; - - - - - const cropRect = region; - const canvas = document.createElement("canvas"); - const context = canvas.getContext("2d"); - const imageObj = new Image(); - canvas.width = cropRect.width; - canvas.height = cropRect.height; - imageObj.src = url; - - imageObj.onload = function () { - context.drawImage(imageObj, cropRect.x, cropRect.y, cropRect.width, cropRect.height, 0, 0, cropRect.width, cropRect.height); - let ImgUrl = canvas.toDataURL(); - - - console.log(ImgUrl); - - - // create html element with text - let x = document.createElement("div"); - // set flex - x.style.display = "flex"; - // set element inner html - x.innerHTML = ` Extracting Text`; - - - - Toastify({ - node: x, - duration: 999999, - newWindow: true, - close: false, - gravity: settings.settings.notification_gravity, // `top` or `bottom` - position: settings.settings.notification_position, // `left`, `center` or `right` - stopOnFocus: true, // Prevents dismissing of toast on hover - style: { - color: '#ffffff', - background: '#000000', - }, - }).showToast(); - - // tesseract to ocr - Tesseract.recognize( - ImgUrl, - selectedLang, - { logger: m => console.log(m) } - ).then(({ data: { text } }) => { - - // remove all toasts - let toastifyElems = document.querySelectorAll('.toastify'); - toastifyElems.forEach(element => { - element.remove() - }); - - let ocrResElem = document.querySelector('#ocr-textarea'); - if (ocrResElem) {// if exists, then update - ocrResElem.innerHTML = text; - } - else { // create new winbox - - document.querySelector('#ocr-preview').remove(); - document.querySelector('#ocr-settings').remove(); - - - let ocrResultBox = new WinBox("Result", { - id: 'ocr-result-box', - class: WINBOX_CLASSES, - index: 9999, - width: '500px', - height: '320px', - top: '10px', - bottom: '10px', - right: '10px', - left: '10px', - x: "center", - y: "center", - - background: "rgba(0,0,0,0.9)", - html: `
+ onclose: function () { + document.querySelector('#ocr-preview').remove() + document.querySelector('#ocr-settings').remove() + document.querySelector('#ocr-result-box').remove() + } + }) + ocrControlBox.show() + let imgCropper = tinycrop.create({ + parent: '#parent-crop', + image: url, + bounds: { + width: width, + height: height + }, + backgroundColors: ['#fff', '#f3f3f3'], + selection: { + color: '#212121CC', + activeColor: '#ff0000CC', + minWidth: 10, + minHeight: 10, + x: v.image.naturalWidth / 2 - width / 2, + y: v.image.naturalHeight / 2 - height / 2, + width: width, + height: height + }, + onInit: () => { + console.log('Initialised') + } + }) + + let region // contains the cropped region + imgCropper.on('change', r => { + region = r + }) + + Object.keys(ocrLangList).forEach(function (key) { + let option = document.createElement('option') + option.value = ocrLangList[key] + option.text = key + if (key == 'English') { + option.selected = true + } + document.querySelector('#ocr-languages').appendChild(option) + }) + // when btn-extract-text clicked + document.getElementById('btn-extract-text').addEventListener('click', function () { + // get selected language + let selectedLang = document.querySelector('#ocr-languages').value + + const cropRect = region + const canvas = document.createElement('canvas') + const context = canvas.getContext('2d') + const imageObj = new Image() + canvas.width = cropRect.width + canvas.height = cropRect.height + imageObj.src = url + + imageObj.onload = function () { + context.drawImage(imageObj, cropRect.x, cropRect.y, cropRect.width, cropRect.height, 0, 0, cropRect.width, cropRect.height) + let ImgUrl = canvas.toDataURL() + + console.log(ImgUrl) + + // create html element with text + let x = document.createElement('div') + // set flex + x.style.display = 'flex' + // set element inner html + x.innerHTML = ` Extracting Text` + + Toastify({ + node: x, + duration: 999999, + newWindow: true, + close: false, + gravity: settings.settings.notification_gravity, // `top` or `bottom` + position: settings.settings.notification_position, // `left`, `center` or `right` + stopOnFocus: true, // Prevents dismissing of toast on hover + style: { + color: '#ffffff', + background: '#000000' + } + }).showToast() + + // tesseract to ocr + Tesseract.recognize(ImgUrl, selectedLang, { logger: m => console.log(m) }).then(({ data: { text } }) => { + // remove all toasts + let toastifyElems = document.querySelectorAll('.toastify') + toastifyElems.forEach(element => { + element.remove() + }) + + let ocrResElem = document.querySelector('#ocr-textarea') + if (ocrResElem) { + // if exists, then update + ocrResElem.innerHTML = text + } else { + // create new winbox + + document.querySelector('#ocr-preview').remove() + document.querySelector('#ocr-settings').remove() + + let ocrResultBox = new WinBox('Result', { + id: 'ocr-result-box', + class: WINBOX_CLASSES, + index: 9999, + width: '500px', + height: '320px', + top: '10px', + bottom: '10px', + right: '10px', + left: '10px', + x: 'center', + y: 'center', + + background: 'rgba(0,0,0,0.9)', + html: `
-
`, - }); - - ocrResultBox.show(); - - // when btn-extract-text clicked - document.getElementById('btn-copytext').addEventListener('click', function () { - showNotification('📋 Copied to clipboard', '#ffffff', '#000000', settings); - copyToClipboard(document.querySelector('#ocr-textarea').value); - }); - - } - }) - } - +
` + }) - }); - try { + ocrResultBox.show() - } catch (error) { - console.error(error); - } + // when btn-extract-text clicked + document.getElementById('btn-copytext').addEventListener('click', function () { + showNotification('📋 Copied to clipboard', '#ffffff', '#000000', settings) + copyToClipboard(document.querySelector('#ocr-textarea').value) + }) + } + }) + } + }) + try { + } catch (error) { + console.error(error) + } - // // for each key in object ocr - // for (const [key, value] of Object.entries(ocrLangList)) { - // console.log(`${key}: ${value}`); - // } + // // for each key in object ocr + // for (const [key, value] of Object.entries(ocrLangList)) { + // console.log(`${key}: ${value}`); + // } + } + }, + photopea: settings.settings.photopea && { + show: 1, + size: 'large', + click: function () { + let currentUrl = window.location.href + // create html element with text + let x = document.createElement('div') + // set flex + x.style.display = 'flex' + // set element inner html + x.innerHTML = ` Opening in Photopea... Please wait` + + Toastify({ + node: x, + duration: 999999, + newWindow: true, + close: false, + gravity: settings.settings.notification_gravity, // `top` or `bottom` + position: settings.settings.notification_position, // `left`, `center` or `right` + stopOnFocus: true, // Prevents dismissing of toast on hover + style: { + color: '#ffffff', + background: '#000000' + } + }).showToast() + + // upload image to imgbb + // NB: expiration time is 60 seconds + fetch(`https://api.imgbb.com/1/upload?expiration=60&key=${IMGBB_TOKEN}&image=${encodeURIComponent(currentUrl)}`) + .then(res => res.json()) + .then(res => { + const uri = '{ "files" : [ "' + res.data.image.url + '" ] }' + const encoded = encodeURI(uri) + const urlEncoded = 'https://www.photopea.com/#' + encoded + // remove toast + let toastifyElems = document.querySelectorAll('.toastify') + toastifyElems.forEach(element => { + element.remove() + }) + + window.open(urlEncoded, '_blank').focus() + + showNotification(`📂 Image opened in Photopea successfully`, '#ffffff', '#000000', settings) + }) + } + }, + tineye: settings.settings.tineye && { + show: 1, + size: 'large', + click: function () { + // toastify + let x = document.createElement('div') + // set flex + x.style.display = 'flex' + // set element inner html + x.innerHTML = ` Opening in TinEye... Please wait` + + Toastify({ + node: x, + duration: 1000, + newWindow: true, + close: false, + gravity: settings.settings.notification_gravity, // `top` or `bottom` + position: settings.settings.notification_position, // `left`, `center` or `right` + stopOnFocus: true, // Prevents dismissing of toast on hover + style: { + color: '#ffffff', + background: '#000000' + } + }).showToast() - } - }, - photopea: settings.settings.photopea && { - show: 1, - size: 'large', - click: function () { - - let currentUrl = window.location.href; - // create html element with text - let x = document.createElement("div"); - // set flex - x.style.display = "flex"; - // set element inner html - x.innerHTML = ` Opening in Photopea... Please wait`; - - Toastify({ - node: x, - duration: 999999, - newWindow: true, - close: false, - gravity: settings.settings.notification_gravity, // `top` or `bottom` - position: settings.settings.notification_position, // `left`, `center` or `right` - stopOnFocus: true, // Prevents dismissing of toast on hover - style: { - color: '#ffffff', - background: '#000000', - }, - }).showToast(); - - - // upload image to imgbb - // NB: expiration time is 60 seconds - fetch(`https://api.imgbb.com/1/upload?expiration=60&key=${IMGBB_TOKEN}&image=${encodeURIComponent(currentUrl)}`) - - .then(res => res.json()) - .then((res) => { - - const uri = '{ "files" : [ "' + res.data.image.url + '" ] }'; - const encoded = encodeURI(uri); - const urlEncoded = 'https://www.photopea.com/#' + encoded; - // remove toast - let toastifyElems = document.querySelectorAll('.toastify'); - toastifyElems.forEach(element => { - element.remove() - }); - - window.open(urlEncoded, '_blank').focus(); - - showNotification(`📂 Image opened in Photopea successfully`, '#ffffff', '#000000', settings); - }); - } - }, - tineye: settings.settings.tineye && { - show: 1, - size: 'large', - click: function () { - - - // toastify - let x = document.createElement("div"); - // set flex - x.style.display = "flex"; - // set element inner html - x.innerHTML = ` Opening in TinEye... Please wait`; - - Toastify({ - node: x, - duration: 1000, - newWindow: true, - close: false, - gravity: settings.settings.notification_gravity, // `top` or `bottom` - position: settings.settings.notification_position, // `left`, `center` or `right` - stopOnFocus: true, // Prevents dismissing of toast on hover - style: { - color: '#ffffff', - background: '#000000', - }, - }).showToast(); - - setTimeout(function () { - let currentUrl = encodeURIComponent(window.location.href); - let action_url = 'http://tineye.com/search?url=' + currentUrl; - window.open(action_url, '_blank').focus(); - }, 1000); - } - }, - qr: settings.settings.qr && { - show: 1, - size: 'large', - click: function () { - - // show loading toast - let x = document.createElement("div"); - // set flex - x.style.display = "flex"; - // set element inner html - x.innerHTML = ` Scanning QR code... Please wait`; - - Toastify({ - node: x, - duration: 9999, - newWindow: true, - close: false, - gravity: settings.settings.notification_gravity, // `top` or `bottom` - position: settings.settings.notification_position, // `left`, `center` or `right` - stopOnFocus: true, // Prevents dismissing of toast on hover - style: { - color: '#ffffff', - background: '#000000', - }, - }).showToast(); - - // remove loading toast - setTimeout(function () { - let toastifyElems = document.querySelectorAll('.toastify'); - toastifyElems.forEach(element => { - element.remove() - }); + setTimeout(function () { + let currentUrl = encodeURIComponent(window.location.href) + let action_url = 'http://tineye.com/search?url=' + currentUrl + window.open(action_url, '_blank').focus() + }, 1000) + } + }, + qr: settings.settings.qr && { + show: 1, + size: 'large', + click: function () { + // show loading toast + let x = document.createElement('div') + // set flex + x.style.display = 'flex' + // set element inner html + x.innerHTML = ` Scanning QR code... Please wait` + + Toastify({ + node: x, + duration: 9999, + newWindow: true, + close: false, + gravity: settings.settings.notification_gravity, // `top` or `bottom` + position: settings.settings.notification_position, // `left`, `center` or `right` + stopOnFocus: true, // Prevents dismissing of toast on hover + style: { + color: '#ffffff', + background: '#000000' + } + }).showToast() - qrcode.callback = function (res) { - if (res instanceof Error) { - showNotification(`❌ No QR code found.`, '#ffffff', '#000000', settings); - } else { - //alert(res); - // show winbox - - - let ocrResultBox = new WinBox("QR Code Result", { - id: 'ocr-result-box', - class: WINBOX_CLASSES, - index: 9999, - width: '500px', - height: '165px', - top: '10px', - bottom: '10px', - right: '10px', - left: '10px', - x: "center", - y: "center", - background: "rgba(0,0,0,0.9)", - html: ` + // remove loading toast + setTimeout(function () { + let toastifyElems = document.querySelectorAll('.toastify') + toastifyElems.forEach(element => { + element.remove() + }) + + qrcode.callback = function (res) { + if (res instanceof Error) { + showNotification(`❌ No QR code found.`, '#ffffff', '#000000', settings) + } else { + //alert(res); + // show winbox + + let ocrResultBox = new WinBox('QR Code Result', { + id: 'ocr-result-box', + class: WINBOX_CLASSES, + index: 9999, + width: '500px', + height: '165px', + top: '10px', + bottom: '10px', + right: '10px', + left: '10px', + x: 'center', + y: 'center', + background: 'rgba(0,0,0,0.9)', + html: `
-
`, - }); - - ocrResultBox.show(); - - // when btn-extract-text clicked - document.getElementById('btn-copytext').addEventListener('click', function () { - showNotification('📋 Copied to clipboard', '#ffffff', '#000000', settings); - copyToClipboard(document.querySelector('#qr-textarea').value); - }); - - - } - }; - let b64Img = getBase64Image(viewer.image); - qrcode.decode(b64Img); - - }, 500); - - - } - }, - help: settings.settings.help && { - show: 1, - size: 'large', - click: function () { - - if (!IS_HELP_OPEN) { - IS_HELP_OPEN = true; - - try { - new WinBox("Help", { - class: WINBOX_CLASSES, - index: 9999, - x: "center", - y: "center", - top: '10px', - bottom: '10px', - right: '10px', - left: '10px', - width: '700px', - height: '423px', - background: "rgba(0,0,0,0.9)", - url: "https://www.youtube-nocookie.com/embed/3p7Jrdx2jOc?autoplay=1&color=white&controls=0&disablekb=1&loop=1&modestbranding=1&rel=0&mute=1", - onclose: function () { - IS_HELP_OPEN = false; - } - }) - - - new WinBox("Shortcuts", { - class: WINBOX_CLASSES, - index: 9999, - x: "right", - y: "center", - top: '10px', - bottom: '10px', - right: '10px', - left: '10px', - width: '300px', - height: '450px', - background: "rgba(0,0,0,0.9)", - url: chrome.runtime.getURL('pages/shortcuts.html'), - onclose: function () { - IS_HELP_OPEN = false; - } - }); - } catch (error) { - console.error(error); - } - } - - } - }, - settings: settings.settings.settings && { - show: 1, - size: 'large', - click: function () { - // open winbox - try { - new WinBox("Settings", { - class: WINBOX_CLASSES, - index: 9999, - x: "center", - y: "center", - top: '10px', - bottom: '10px', - right: '10px', - left: '10px', - width: '350px', - height: '400px', - background: "rgba(0,0,0,0.9)", - url: chrome.runtime.getURL('pages/settings.html'), - }) - } catch (error) { - console.error(error); - } - } - }, - about: settings.settings.about && { - show: 1, - size: 'large', - click: function () { - try { - new WinBox("About", { - class: WINBOX_CLASSES, - index: 9999, - x: "center", - y: "center", - width: '700px', - height: '500px', - background: "rgba(0,0,0,0.9)", - url: chrome.runtime.getURL('pages/about.html'), - }); - } catch (error) { - console.error(error); - } - } - }, - exit: settings.settings.exit && { - show: 1, - size: 'large', - click: function () { - let url = window.location.href; - viewer.destroy(); - document.querySelector('.blurry-bg').remove(); - document.querySelector('img').style.display = 'block'; - document.querySelectorAll('.winbox').forEach(function (el) { - el.remove(); - }); - // remove all style tags - let styleTags = document.querySelectorAll('style'); - styleTags.forEach(function (el) { - el.remove(); - }); - document.querySelector('img').src = url; - } - - }, - more: { - show: 1, - size: 'large', - click: function () { - - // get all viewer buttons - let viewerButtons = document.querySelectorAll('div.viewer-toolbar > ul > li'); - - let btnsExceptMore = Array.prototype.slice.call(viewerButtons).filter(function (el) { - return !el.classList.contains('viewer-more'); - }) +
` + }) - btnsExceptMore.forEach(btn => { - // toggle display of each button + ocrResultBox.show() - - let cssObj = window.getComputedStyle(btn, null); - let display = cssObj.getPropertyValue("display"); - - if (display === 'none') { - btn.style.display = 'list-item'; - btn.style.opacity = 1; - // append class - btn.classList.add('fade-in-right'); - } - else { - btn.style.display = 'none'; - btn.style.opacity = 0; - - } - - }) - } + // when btn-extract-text clicked + document.getElementById('btn-copytext').addEventListener('click', function () { + showNotification('📋 Copied to clipboard', '#ffffff', '#000000', settings) + copyToClipboard(document.querySelector('#qr-textarea').value) + }) } - - }, - ready() { - - - // hide all at start - if (settings.settings.hide_all_at_start) { - - // get all viewer buttons - let viewerButtons = document.querySelectorAll('div.viewer-toolbar > ul > li'); - - let btnsExceptMore = Array.prototype.slice.call(viewerButtons).filter(function (el) { - return !el.classList.contains('viewer-more'); - }) - - btnsExceptMore.forEach(btn => { - // toggle display of each button - - - let cssObj = window.getComputedStyle(btn, null); - let display = cssObj.getPropertyValue("display"); - - if (display === 'none') { - btn.style.display = 'list-item'; - btn.style.opacity = 1; - // append class - btn.classList.add('fade-in-right'); - } - else { - btn.style.display = 'none'; - btn.style.opacity = 0; - - } - - }) - - - } - - - setTimeout(() => { - if (settings.settings.toolbar_position === 'top') { - viewer.move(0, 50); - } - }, 100) + } + let b64Img = getBase64Image(viewer.image) + qrcode.decode(b64Img) + }, 500) + } + }, + help: settings.settings.help && { + show: 1, + size: 'large', + click: function () { + if (!IS_HELP_OPEN) { + IS_HELP_OPEN = true + + try { + new WinBox('Help', { + class: WINBOX_CLASSES, + index: 9999, + x: 'center', + y: 'center', + top: '10px', + bottom: '10px', + right: '10px', + left: '10px', + width: '700px', + height: '423px', + background: 'rgba(0,0,0,0.9)', + url: 'https://www.youtube-nocookie.com/embed/3p7Jrdx2jOc?autoplay=1&color=white&controls=0&disablekb=1&loop=1&modestbranding=1&rel=0&mute=1', + onclose: function () { + IS_HELP_OPEN = false + } + }) + + new WinBox('Shortcuts', { + class: WINBOX_CLASSES, + index: 9999, + x: 'right', + y: 'center', + top: '10px', + bottom: '10px', + right: '10px', + left: '10px', + width: '300px', + height: '450px', + background: 'rgba(0,0,0,0.9)', + url: chrome.runtime.getURL('pages/shortcuts.html'), + onclose: function () { + IS_HELP_OPEN = false + } + }) + } catch (error) { + console.error(error) + } } + } + }, + settings: settings.settings.settings && { + show: 1, + size: 'large', + click: function () { + // open winbox + try { + new WinBox('Settings', { + class: WINBOX_CLASSES, + index: 9999, + x: 'center', + y: 'center', + top: '10px', + bottom: '10px', + right: '10px', + left: '10px', + width: '350px', + height: '400px', + background: 'rgba(0,0,0,0.9)', + url: chrome.runtime.getURL('pages/settings.html') + }) + } catch (error) { + console.error(error) + } + } + }, + about: settings.settings.about && { + show: 1, + size: 'large', + click: function () { + try { + new WinBox('About', { + class: WINBOX_CLASSES, + index: 9999, + x: 'center', + y: 'center', + width: '700px', + height: '500px', + background: 'rgba(0,0,0,0.9)', + url: chrome.runtime.getURL('pages/about.html') + }) + } catch (error) { + console.error(error) + } + } + }, + exit: settings.settings.exit && { + show: 1, + size: 'large', + click: function () { + let url = window.location.href + viewer.destroy() + document.querySelector('.blurry-bg').remove() + document.querySelector('img').style.display = 'block' + document.querySelectorAll('.winbox').forEach(function (el) { + el.remove() + }) + // remove all style tags + let styleTags = document.querySelectorAll('style') + styleTags.forEach(function (el) { + el.remove() + }) + document.querySelector('img').src = url + } + }, + more: { + show: 1, + size: 'large', + click: function () { + // get all viewer buttons + let viewerButtons = document.querySelectorAll('div.viewer-toolbar > ul > li') + + let btnsExceptMore = Array.prototype.slice.call(viewerButtons).filter(function (el) { + return !el.classList.contains('viewer-more') + }) + + btnsExceptMore.forEach(btn => { + // toggle display of each button + + let cssObj = window.getComputedStyle(btn, null) + let display = cssObj.getPropertyValue('display') + + if (display === 'none') { + btn.style.display = 'list-item' + btn.style.opacity = 1 + // append class + btn.classList.add('fade-in-right') + } else { + btn.style.display = 'none' + btn.style.opacity = 0 + } + }) + } + } + }, + ready() { + // hide all at start + if (settings.settings.hide_all_at_start) { + // get all viewer buttons + let viewerButtons = document.querySelectorAll('div.viewer-toolbar > ul > li') + + let btnsExceptMore = Array.prototype.slice.call(viewerButtons).filter(function (el) { + return !el.classList.contains('viewer-more') + }) + + btnsExceptMore.forEach(btn => { + // toggle display of each button + + let cssObj = window.getComputedStyle(btn, null) + let display = cssObj.getPropertyValue('display') + + if (display === 'none') { + btn.style.display = 'list-item' + btn.style.opacity = 1 + // append class + btn.classList.add('fade-in-right') + } else { + btn.style.display = 'none' + btn.style.opacity = 0 + } + }) + } - }); - - + setTimeout(() => { + if (settings.settings.toolbar_position === 'top') { + viewer.move(0, 50) + } + }, 100) + } + }) - let lightTheme = ` + let lightTheme = ` transition: all 0.5s ease; background-image: none; background-color: #ffffff; @@ -6408,9 +6286,9 @@ function init(settings) { width: 100vw; height: 100vh; transform: scale(1.3); - `; + ` - let darktheme = ` + let darktheme = ` transition: all 0.5s ease; background-image: none; background-color: #0e1217; @@ -6426,7 +6304,7 @@ function init(settings) { opacity: 0; ` - let blurrytheme = ` + let blurrytheme = ` transition: none; background-image: url(${imgElement.src}); background-color: none; @@ -6442,18 +6320,17 @@ function init(settings) { opacity: 1; ` - let currentTheme = (bg) => { - if (bg === 'light') { - return lightTheme; - } else if (bg === 'dark') { - return darktheme; - } - return blurrytheme; - } - + let currentTheme = bg => { + if (bg === 'light') { + return lightTheme + } else if (bg === 'dark') { + return darktheme + } + return blurrytheme + } - // inject css - injectCSS(` + // inject css + injectCSS(` .blurry-bg { ${currentTheme(BACKGROUND_TYPE)} } @@ -6473,60 +6350,53 @@ function init(settings) { display: none } .viewer-footer { - bottom: ${(settings.settings.toolbar_position) === 'bottom' ? '0px' : 'unset'} !important; - top: ${(settings.settings.toolbar_position) === 'top' ? '10px' : 'unset'} !important; - } - `); - - - - // show the viewer - viewer.show(); - - - - setTippyText(tippyData); - - } - else { - // No img element, then... maybe it's a svg ? - // let svgElement = document.getElementsByTagName('svg')[0]; // get svg element - // if (svgElement) { - // // let base64 = svgToBase64(svgElement); - // // redirect to svg viewer - - // } - // else { - // // I don't know what it is, and I don't care about it - // } - } + bottom: ${settings.settings.toolbar_position === 'bottom' ? '0px' : 'unset'} !important; + top: ${settings.settings.toolbar_position === 'top' ? '10px' : 'unset'} !important; + } + `) + + // show the viewer + viewer.show() + + setTippyText(tippyData) + } else { + // No img element, then... maybe it's a svg ? + // let svgElement = document.getElementsByTagName('svg')[0]; // get svg element + // if (svgElement) { + // // let base64 = svgToBase64(svgElement); + // // redirect to svg viewer + // } + // else { + // // I don't know what it is, and I don't care about it + // } + } } /** * Helper function - converts an svg element to a base64 string * @param {svgElement} svgElement the svg element to convert - * @returns + * @returns */ function svgToBase64(svgElement) { - let svgString = new XMLSerializer().serializeToString(svgElement); - let decoded = unescape(encodeURIComponent(svgString)); - let base64 = btoa(decoded) - return `data:image/svg+xml;base64,${base64}`; + let svgString = new XMLSerializer().serializeToString(svgElement) + let decoded = unescape(encodeURIComponent(svgString)) + let base64 = btoa(decoded) + return `data:image/svg+xml;base64,${base64}` } /** * Injects css into the page * @param {string} css string to inject - * @returns + * @returns */ function injectCSS(css) { - let head = document.getElementsByTagName('head')[0]; - if (!head) { - return; - } - let style = document.createElement('style'); - style.innerHTML = DOMPurify.sanitize(css); - head.appendChild(style); + let head = document.getElementsByTagName('head')[0] + if (!head) { + return + } + let style = document.createElement('style') + style.innerHTML = DOMPurify.sanitize(css) + head.appendChild(style) } /** @@ -6534,20 +6404,17 @@ function injectCSS(css) { * @param {*} arrBtns array Of Buttons */ function setTippyText(arrBtns) { - - window.tippyInstances = []; - - - arrBtns.forEach(function (item) { - let instances = tippy(`#viewer0 > div.viewer-footer > div.viewer-toolbar > ul > li.viewer-${item.type}.viewer-large`, { - content: item.text, - inertia: true, - animation: 'scale', - theme: 'dark', - }) - window.tippyInstances = tippyInstances.concat(instances); - }); - + window.tippyInstances = [] + + arrBtns.forEach(function (item) { + let instances = tippy(`#viewer0 > div.viewer-footer > div.viewer-toolbar > ul > li.viewer-${item.type}.viewer-large`, { + content: item.text, + inertia: true, + animation: 'scale', + theme: 'dark' + }) + window.tippyInstances = tippyInstances.concat(instances) + }) } /** @@ -6555,245 +6422,225 @@ function setTippyText(arrBtns) { * @param {HTMLElement} image Viewer Image */ function download(image) { - const a = document.createElement('a'); - a.href = image.src; - a.download = image.alt; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); + const a = document.createElement('a') + a.href = image.src + a.download = image.alt + document.body.appendChild(a) + a.click() + document.body.removeChild(a) } /** - * - * @param {viewer} viewer - * @param {string} url - * @param {*} width - * @param {*} height + * + * @param {viewer} viewer + * @param {string} url + * @param {*} width + * @param {*} height */ function crop(v, url, width, height) { - - // create new winbox - let winbox = new WinBox("Crop Image", { - id: "winbox-crop-image", - class: WINBOX_CLASSES, - - width: width + 7, - // height + 10% - height: height + 40 + 36, - x: "center", - y: "center", - index: 9999, - background: "rgba(0,0,0,0.9)", - html: ` + // create new winbox + let winbox = new WinBox('Crop Image', { + id: 'winbox-crop-image', + class: WINBOX_CLASSES, + + width: width + 7, + // height + 10% + height: height + 40 + 36, + x: 'center', + y: 'center', + index: 9999, + background: 'rgba(0,0,0,0.9)', + html: `
`, - onclose: function () { - // reset viewer zoom - // v.zoom(0.5); - IS_CROP_OPEN = false; - } - }); - - - - - let imgCropper = tinycrop.create({ - parent: '#parent-crop', - image: url, - bounds: { - width: width, - height: height - }, - backgroundColors: ['#fff', '#f3f3f3'], - selection: { - color: '#212121CC', - activeColor: '#ff0000CC', - minWidth: 10, - minHeight: 10, - x: v.image.naturalWidth / 2 - width / 2, - y: v.image.naturalHeight / 2 - height / 2, - width: width, - height: height - }, - onInit: () => { console.log('Initialised') } - }); - - let region; // contains the cropped region - imgCropper.on('change', (r) => { - console.log('change', r); - region = r; - }); - - // const image = document.getElementById('crop-img'); - - - setTimeout(function () { - // get crop btn and add event listener - let cropBtn = document.getElementById('btn-crop-img'); - - cropBtn.addEventListener('click', function () { - - - const cropRect = region; - const canvas = document.createElement("canvas"); - const context = canvas.getContext("2d"); - const imageObj = new Image(); - canvas.width = cropRect.width; - canvas.height = cropRect.height; - imageObj.src = url; - imageObj.onload = function () { - context.drawImage(imageObj, cropRect.x, cropRect.y, cropRect.width, cropRect.height, 0, 0, cropRect.width, cropRect.height); - let ImgUrl = canvas.toDataURL(); - v.image.src = ImgUrl; - - switch (BACKGROUND_TYPE) { - case 'blurred': - injectCSS(` + onclose: function () { + // reset viewer zoom + // v.zoom(0.5); + IS_CROP_OPEN = false + } + }) + + let imgCropper = tinycrop.create({ + parent: '#parent-crop', + image: url, + bounds: { + width: width, + height: height + }, + backgroundColors: ['#fff', '#f3f3f3'], + selection: { + color: '#212121CC', + activeColor: '#ff0000CC', + minWidth: 10, + minHeight: 10, + x: v.image.naturalWidth / 2 - width / 2, + y: v.image.naturalHeight / 2 - height / 2, + width: width, + height: height + }, + onInit: () => { + console.log('Initialised') + } + }) + + let region // contains the cropped region + imgCropper.on('change', r => { + console.log('change', r) + region = r + }) + + // const image = document.getElementById('crop-img'); + + setTimeout(function () { + // get crop btn and add event listener + let cropBtn = document.getElementById('btn-crop-img') + + cropBtn.addEventListener('click', function () { + const cropRect = region + const canvas = document.createElement('canvas') + const context = canvas.getContext('2d') + const imageObj = new Image() + canvas.width = cropRect.width + canvas.height = cropRect.height + imageObj.src = url + imageObj.onload = function () { + context.drawImage(imageObj, cropRect.x, cropRect.y, cropRect.width, cropRect.height, 0, 0, cropRect.width, cropRect.height) + let ImgUrl = canvas.toDataURL() + v.image.src = ImgUrl + + switch (BACKGROUND_TYPE) { + case 'blurred': + injectCSS(` .blurry-bg { background-image: url("${ImgUrl}"); - }`); - break; - case 'light': - break; - case 'dark': - break; - default: - break; - } - - - setTimeout(function () { - window.dispatchEvent(new Event('resize')); - IS_CROP_OPEN = false; - winbox.close(); - }, 100); - - }; - - - - // image.addEventListener('load', () => { - - - - // console.log(image) - // context.drawImage( - // //croppr.imageEl, - // v.element, - // cropRect.x, - // cropRect.y, - // cropRect.width, - // cropRect.height, - // 0, - // 0, - // canvas.width, - // canvas.height, - // ); - // }); - - // - - - - - //v.image.src = ImgUrl; - - // switch (BACKGROUND_TYPE) { - // case 'blurred': - // injectCSS(` - // .blurry-bg { - // background-image: url("${ImgUrl}"); - // }`); - // break; - // case 'light': - // break; - // case 'dark': - // break; - // default: - // break; - // } - - // setTimeout(function () { - // v.zoom(0.5); - // window.dispatchEvent(new Event('resize')); - // }, 100); - - // //showNotification("Image cropped successfully", '#ffffff', '#000000', settings) - // IS_CROP_OPEN = false; - // winbox.close(); - - }); - }, 100); + }`) + break + case 'light': + break + case 'dark': + break + default: + break + } + setTimeout(function () { + window.dispatchEvent(new Event('resize')) + IS_CROP_OPEN = false + winbox.close() + }, 100) + } + + // image.addEventListener('load', () => { + + // console.log(image) + // context.drawImage( + // //croppr.imageEl, + // v.element, + // cropRect.x, + // cropRect.y, + // cropRect.width, + // cropRect.height, + // 0, + // 0, + // canvas.width, + // canvas.height, + // ); + // }); + + // + + //v.image.src = ImgUrl; + + // switch (BACKGROUND_TYPE) { + // case 'blurred': + // injectCSS(` + // .blurry-bg { + // background-image: url("${ImgUrl}"); + // }`); + // break; + // case 'light': + // break; + // case 'dark': + // break; + // default: + // break; + // } + + // setTimeout(function () { + // v.zoom(0.5); + // window.dispatchEvent(new Event('resize')); + // }, 100); + + // //showNotification("Image cropped successfully", '#ffffff', '#000000', settings) + // IS_CROP_OPEN = false; + // winbox.close(); + }) + }, 100) } // canvas function function useCanvas(el, image, callback) { - el.width = image.width; // img width - el.height = image.height; // img height - // draw image in canvas tag - el.getContext('2d').drawImage(image, 0, 0, image.width, image.height); - return callback(); + el.width = image.width // img width + el.height = image.height // img height + // draw image in canvas tag + el.getContext('2d').drawImage(image, 0, 0, image.width, image.height) + return callback() } function componentToHex(c) { - let hex = c.toString(16); - return hex.length == 1 ? "0" + hex : hex; + let hex = c.toString(16) + return hex.length == 1 ? '0' + hex : hex } function rgbToHex(r, g, b) { - return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b); + return '#' + componentToHex(r) + componentToHex(g) + componentToHex(b) } function findPos(obj) { - let curleft = 0, curtop = 0; - if (obj.offsetParent) { - do { - curleft += obj.offsetLeft; - curtop += obj.offsetTop; - } while (obj = obj.offsetParent); - return { x: curleft, y: curtop }; - } - return undefined; + let curleft = 0, + curtop = 0 + if (obj.offsetParent) { + do { + curleft += obj.offsetLeft + curtop += obj.offsetTop + } while ((obj = obj.offsetParent)) + return { x: curleft, y: curtop } + } + return undefined } function resetColorPicker(winboxPicker, v) { - //console.log(e); + //console.log(e); } const handleImageClickOnPicker = (e, v, canvas, pickr, x, y, settings) => { - - if (e.offsetX) { - x = e.offsetX; - y = e.offsetY; - } - - - console.log(settings); - - useCanvas(canvas, v.image, () => { - // get image data - let p = canvas.getContext('2d').getImageData(x, y, 1, 1).data; - // show info - pickr.setColor(rgbToHex(p[0], p[1], p[2])); - copyToClipboard(rgbToHex(p[0], p[1], p[2])); - showNotification(`${rgbToHex(p[0], p[1], p[2]).toUpperCase()} copied to clipboard`, getColorByBgColor(rgbToHex(p[0], p[1], p[2])), rgbToHex(p[0], p[1], p[2]), settings); - }); - + if (e.offsetX) { + x = e.offsetX + y = e.offsetY + } + + console.log(settings) + + useCanvas(canvas, v.image, () => { + // get image data + let p = canvas.getContext('2d').getImageData(x, y, 1, 1).data + // show info + pickr.setColor(rgbToHex(p[0], p[1], p[2])) + copyToClipboard(rgbToHex(p[0], p[1], p[2])) + showNotification(`${rgbToHex(p[0], p[1], p[2]).toUpperCase()} copied to clipboard`, getColorByBgColor(rgbToHex(p[0], p[1], p[2])), rgbToHex(p[0], p[1], p[2]), settings) + }) } const handleMouseMoveOnPicker = (e, v, canvas, pickr, x, y) => { - - if (e.offsetX) { - x = e.offsetX; - y = e.offsetY; - } - useCanvas(canvas, v.image, function () { - // get image data - let p = canvas.getContext('2d').getImageData(x, y, 1, 1).data; - pickr.setColor(rgbToHex(p[0], p[1], p[2])); - }); - + if (e.offsetX) { + x = e.offsetX + y = e.offsetY + } + useCanvas(canvas, v.image, function () { + // get image data + let p = canvas.getContext('2d').getImageData(x, y, 1, 1).data + pickr.setColor(rgbToHex(p[0], p[1], p[2])) + }) } /** @@ -6802,8 +6649,10 @@ const handleMouseMoveOnPicker = (e, v, canvas, pickr, x, y) => { * @returns {string} */ function getColorByBgColor(bgColor) { - if (!bgColor) { return ''; } - return (parseInt(bgColor.replace('#', ''), 16) > 0xffffff / 2) ? '#000' : '#fff'; + if (!bgColor) { + return '' + } + return parseInt(bgColor.replace('#', ''), 16) > 0xffffff / 2 ? '#000' : '#fff' } /** @@ -6811,60 +6660,57 @@ function getColorByBgColor(bgColor) { * @param {string} str - string to copy */ function copyToClipboard(textToCopy) { - // navigator clipboard api needs a secure context (https) - if (navigator.clipboard && window.isSecureContext) { - // navigator clipboard api method' - return navigator.clipboard.writeText(textToCopy); - } else { - // text area method - let textArea = document.createElement("textarea"); - textArea.value = textToCopy; - // make the textarea out of viewport - textArea.style.position = "fixed"; - textArea.style.left = "-999999px"; - textArea.style.top = "-999999px"; - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - return new Promise((res, rej) => { - // here the magic happens - document.execCommand('copy') ? res() : rej(); - textArea.remove(); - }); - } + // navigator clipboard api needs a secure context (https) + if (navigator.clipboard && window.isSecureContext) { + // navigator clipboard api method' + return navigator.clipboard.writeText(textToCopy) + } else { + // text area method + let textArea = document.createElement('textarea') + textArea.value = textToCopy + // make the textarea out of viewport + textArea.style.position = 'fixed' + textArea.style.left = '-999999px' + textArea.style.top = '-999999px' + document.body.appendChild(textArea) + textArea.focus() + textArea.select() + return new Promise((res, rej) => { + // here the magic happens + document.execCommand('copy') ? res() : rej() + textArea.remove() + }) + } } - function printImage(image) { - let strb64 = getBase64Image(image) - printJS(strb64, 'image') + let strb64 = getBase64Image(image) + printJS(strb64, 'image') } /** * Convert image to base64 * @param {*} img Image element - * @returns + * @returns */ function getBase64Image(img) { - let canvas = document.createElement("canvas"); - canvas.width = img.naturalWidth; - canvas.height = img.naturalHeight; - let ctx = canvas.getContext("2d"); - ctx.drawImage(img, 0, 0); - return canvas.toDataURL(); + let canvas = document.createElement('canvas') + canvas.width = img.naturalWidth + canvas.height = img.naturalHeight + let ctx = canvas.getContext('2d') + ctx.drawImage(img, 0, 0) + return canvas.toDataURL() } - function changeTheme(imgsrc, settings) { - - let lightTheme = `background-image: url("data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-sun'%3E%3Ccircle cx='12' cy='12' r='5'%3E%3C/circle%3E%3Cline x1='12' y1='1' x2='12' y2='3'%3E%3C/line%3E%3Cline x1='12' y1='21' x2='12' y2='23'%3E%3C/line%3E%3Cline x1='4.22' y1='4.22' x2='5.64' y2='5.64'%3E%3C/line%3E%3Cline x1='18.36' y1='18.36' x2='19.78' y2='19.78'%3E%3C/line%3E%3Cline x1='1' y1='12' x2='3' y2='12'%3E%3C/line%3E%3Cline x1='21' y1='12' x2='23' y2='12'%3E%3C/line%3E%3Cline x1='4.22' y1='19.78' x2='5.64' y2='18.36'%3E%3C/line%3E%3Cline x1='18.36' y1='5.64' x2='19.78' y2='4.22'%3E%3C/line%3E%3C/svg%3E");` - let darkTheme = `background-image: url("data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-moon'%3E%3Cpath d='M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z'%3E%3C/path%3E%3C/svg%3E");` - let blurTheme = `background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-droplet'%3E%3Cpath d='M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z'%3E%3C/path%3E%3C/svg%3E"); `; - - switch (BACKGROUND_TYPE) { - case 'blurred': - showNotification('☀️ Light Background', '#000000', '#ffffff', settings); - injectCSS(` + let lightTheme = `background-image: url("data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-sun'%3E%3Ccircle cx='12' cy='12' r='5'%3E%3C/circle%3E%3Cline x1='12' y1='1' x2='12' y2='3'%3E%3C/line%3E%3Cline x1='12' y1='21' x2='12' y2='23'%3E%3C/line%3E%3Cline x1='4.22' y1='4.22' x2='5.64' y2='5.64'%3E%3C/line%3E%3Cline x1='18.36' y1='18.36' x2='19.78' y2='19.78'%3E%3C/line%3E%3Cline x1='1' y1='12' x2='3' y2='12'%3E%3C/line%3E%3Cline x1='21' y1='12' x2='23' y2='12'%3E%3C/line%3E%3Cline x1='4.22' y1='19.78' x2='5.64' y2='18.36'%3E%3C/line%3E%3Cline x1='18.36' y1='5.64' x2='19.78' y2='4.22'%3E%3C/line%3E%3C/svg%3E");` + let darkTheme = `background-image: url("data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-moon'%3E%3Cpath d='M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z'%3E%3C/path%3E%3C/svg%3E");` + let blurTheme = `background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-droplet'%3E%3Cpath d='M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z'%3E%3C/path%3E%3C/svg%3E"); ` + + switch (BACKGROUND_TYPE) { + case 'blurred': + showNotification('☀️ Light Background', '#000000', '#ffffff', settings) + injectCSS(` .viewer-theme { ${darkTheme} } @@ -6886,12 +6732,12 @@ function changeTheme(imgsrc, settings) { opacity: 0; } - `); - BACKGROUND_TYPE = 'light'; - break; - case 'light': - showNotification('🌑 Dark Background', '#ffffff', '#000000', settings); - injectCSS(` + `) + BACKGROUND_TYPE = 'light' + break + case 'light': + showNotification('🌑 Dark Background', '#ffffff', '#000000', settings) + injectCSS(` .viewer-theme { ${blurTheme} } @@ -6913,13 +6759,13 @@ function changeTheme(imgsrc, settings) { .blurry-bg:before { opacity: 0; } - `); - BACKGROUND_TYPE = 'dark'; - break; - case 'dark': - // change to blurred - showNotification('💧 Blurred Background', '#ffffff', '#404040', settings); - injectCSS(` + `) + BACKGROUND_TYPE = 'dark' + break + case 'dark': + // change to blurred + showNotification('💧 Blurred Background', '#ffffff', '#404040', settings) + injectCSS(` .viewer-theme { ${lightTheme} } @@ -6940,128 +6786,123 @@ function changeTheme(imgsrc, settings) { } .blurry-bg:before { opacity: 0.5; - }`); - BACKGROUND_TYPE = 'blurred'; - break; - } + }`) + BACKGROUND_TYPE = 'blurred' + break + } } - function showNotification(text, textColor, bgColor, settings) { - - Toastify({ - text: `${text}`, - duration: 3000, - newWindow: true, - close: false, - gravity: settings.settings.notification_gravity, // `top` or `bottom` - position: settings.settings.notification_position, // `left`, `center` or `right` - stopOnFocus: true, // Prevents dismissing of toast on hover - style: { - color: textColor, - background: bgColor, - } - }).showToast(); + Toastify({ + text: `${text}`, + duration: 3000, + newWindow: true, + close: false, + gravity: settings.settings.notification_gravity, // `top` or `bottom` + position: settings.settings.notification_position, // `left`, `center` or `right` + stopOnFocus: true, // Prevents dismissing of toast on hover + style: { + color: textColor, + background: bgColor + } + }).showToast() } - function jsonViewer(json, collapsible = false) { - let TEMPLATES = { - item: '
%KEY%
%VALUE%
', - itemCollapsible: '', - itemCollapsibleOpen: '' - }; - - function createItem(key, value, type) { - let element = TEMPLATES.item.replace('%KEY%', key); - - if (type == 'string') { - element = element.replace('%VALUE%', '"' + value + '"'); - } else { - element = element.replace('%VALUE%', value); - } + let TEMPLATES = { + item: '
%KEY%
%VALUE%
', + itemCollapsible: '', + itemCollapsibleOpen: '' + } - element = element.replace('%TYPE%', type); + function createItem(key, value, type) { + let element = TEMPLATES.item.replace('%KEY%', key) - return element; + if (type == 'string') { + element = element.replace('%VALUE%', '"' + value + '"') + } else { + element = element.replace('%VALUE%', value) } - function createCollapsibleItem(key, value, type, children) { - let tpl = 'itemCollapsible'; - - if (collapsible) { - tpl = 'itemCollapsibleOpen'; - } + element = element.replace('%TYPE%', type) - let element = TEMPLATES[tpl].replace('%KEY%', key); + return element + } - element = element.replace('%VALUE%', type); - element = element.replace('%TYPE%', type); - element = element.replace('%CHILDREN%', children); + function createCollapsibleItem(key, value, type, children) { + let tpl = 'itemCollapsible' - return element; + if (collapsible) { + tpl = 'itemCollapsibleOpen' } - function handleChildren(key, value, type) { - let html = ''; + let element = TEMPLATES[tpl].replace('%KEY%', key) - for (let item in value) { - let _key = item, - _val = value[item]; + element = element.replace('%VALUE%', type) + element = element.replace('%TYPE%', type) + element = element.replace('%CHILDREN%', children) - html += handleItem(_key, _val); - } + return element + } - return createCollapsibleItem(key, value, type, html); - } - - function handleItem(key, value) { - let type = typeof value; + function handleChildren(key, value, type) { + let html = '' - if (typeof value === 'object') { - return handleChildren(key, value, type); - } + for (let item in value) { + let _key = item, + _val = value[item] - return createItem(key, value, type); + html += handleItem(_key, _val) } - function parseObject(obj) { - let _result = '
'; + return createCollapsibleItem(key, value, type, html) + } - for (let item in obj) { - let key = item, - value = obj[item]; + function handleItem(key, value) { + let type = typeof value - _result += handleItem(key, value); - } - - _result += '
'; - - return _result; + if (typeof value === 'object') { + return handleChildren(key, value, type) } - return parseObject(json); -} + return createItem(key, value, type) + } + function parseObject(obj) { + let _result = '
' -// listen to messages from iframe -window.addEventListener('message', function (message) { - if (message.data.type == "settings") { - let user_settings = message.data.settings - // save using chrome.storage - chrome.storage.sync.set({ - settings: user_settings - }, function () { - // Notify that we saved. - showNotification('💾 Settings saved successfully', '#ffffff', '#000000', message.data); - setTimeout(() => { - // reload window after saving - window.location.reload(); + for (let item in obj) { + let key = item, + value = obj[item] - }, 1000) - }); + _result += handleItem(key, value) } -}); + _result += '
' + + return _result + } + return parseObject(json) +} +// listen to messages from iframe +window.addEventListener('message', function (message) { + if (message.data.type == 'settings') { + let user_settings = message.data.settings + // save using chrome.storage + chrome.storage.sync.set( + { + settings: user_settings + }, + function () { + // Notify that we saved. + showNotification('💾 Settings saved successfully', '#ffffff', '#000000', message.data) + setTimeout(() => { + // reload window after saving + window.location.reload() + }, 1000) + } + ) + } +}) diff --git a/help/about.html b/help/about.html index bacf34f..e9a6c14 100644 --- a/help/about.html +++ b/help/about.html @@ -31,7 +31,8 @@

Let me know if you're using BetterViewer ! Also don't forget to give us a ⭐️

Contributors:
@bbbenji - @patrykdziurkowski + @patrykdziurkowski + @Metacor

diff --git a/js/app.js b/js/app.js index 080da7d..fa0f0cb 100644 --- a/js/app.js +++ b/js/app.js @@ -1,994 +1,924 @@ // run when scripts and styles are loaded chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { - if (request.type == "injected") { - chrome.storage.sync.get('settings', function (settings) { - try { - if (settings.settings) { - init(settings); - } - } - catch (e) { - console.error('error while loading settings: ', e); - } - }); - } -}); - -let IS_PICKER_OPEN = false; -let IS_DETAILS_OPEN = false; -let IS_HELP_OPEN = false; -let IS_CROP_OPEN = false; - -let viewer; -let BACKGROUND_TYPE = "blurred"; -let ImgCanvas; -let isFlippedHorizontally = false; -let isFlippedVertically = false; -let IMGBB_TOKEN = '8be35a61597b285f9c95669fdc565b00'; -let isKeypressEnabled = false; -let WINBOX_CLASSES = [ - "no-scrollbar", - "no-max", - "no-min", - "no-full", - "no-resize", - "no-animation" -] + if (request.type == 'injected') { + chrome.storage.sync.get('settings', function (settings) { + try { + if (settings.settings) { + init(settings) + } + } catch (e) { + console.error('error while loading settings: ', e) + } + }) + } +}) + +let IS_PICKER_OPEN = false +let IS_DETAILS_OPEN = false +let IS_HELP_OPEN = false +let IS_CROP_OPEN = false + +let viewer +let BACKGROUND_TYPE = 'blurred' +let ImgCanvas +let isFlippedHorizontally = false +let isFlippedVertically = false +let IMGBB_TOKEN = '8be35a61597b285f9c95669fdc565b00' +let isKeypressEnabled = false +let WINBOX_CLASSES = ['no-scrollbar', 'no-max', 'no-min', 'no-full', 'no-resize', 'no-animation'] let ocrLangList = { - 'Afrikaans': 'afr', - 'Albanian': 'sqi', - 'Amharic': 'amh', - 'Arabic': 'ara', - 'Armenian': 'hye', - 'Azerbaijani': 'aze', - 'Basque': 'eus', - 'Belarusian': 'bel', - 'Bengali': 'ben', - 'Bosnian': 'bos', - 'Bulgarian': 'bul', - 'Burmese': 'mya', - 'Catalan': 'cat', - 'Cebuano': 'ceb', - 'Chinese Simplified': 'chi_sim', - 'Chinese Simplified (vertical)': 'chi_sim_vert', - 'Chinese Traditional': 'chi_tra', - 'Chinese Traditional (vertical)': 'chi_tra_vert', - 'Corsican': 'cos', - 'Croatian': 'hrv', - 'Czech': 'ces', - 'Danish': 'dan', - 'Dutch': 'nld', - 'English': 'eng', - 'Esperanto': 'epo', - 'Estonian': 'est', - 'Filipino': 'fil', - 'Finnish': 'fin', - 'French': 'fra', - 'Frisian': 'fry', - 'Galician': 'glg', - 'Georgian': 'kat', - 'German': 'deu', - 'Greek': 'ell', - 'Gujarati': 'guj', - 'Haitian': 'hat', - 'Hebrew': 'heb', - 'Hindi': 'hin', - 'Hungarian': 'hun', - 'Icelandic': 'isl', - 'Indonesian': 'ind', - 'Irish': 'gle', - 'Italian': 'ita', - 'Japanese': 'jpn', - 'Japanese (vertical)': 'jpn_vert', - 'Javanese': 'jav', - 'Kannada': 'kan', - 'Kazakh': 'kaz', - 'Khmer': 'khm', - 'Korean': 'kor', - 'Korean (vertical)': 'kor_vert', - 'Kurdish': 'kmr', - 'Lao': 'lao', - 'Latin': 'lat', - 'Latvian': 'lav', - 'Lithuanian': 'lit', - 'Luxembourgish': 'ltz', - 'Macedonian': 'mkd', - 'Malay': 'msa', - 'Malayalam': 'mal', - 'Maltese': 'mlt', - 'Maori': 'mri', - 'Marathi': 'mar', - 'Mongolian': 'mon', - 'Nepali': 'nep', - 'Norwegian': 'nor', - 'Persian': 'fas', - 'Polish': 'pol', - 'Portuguese': 'por', - 'Romanian': 'ron', - 'Russian': 'rus', - 'Scottish Gaelic': 'gla', - 'Serbian': 'srp', - 'Sindhi': 'snd', - 'Sinhala': 'sin', - 'Slovak': 'slk', - 'Slovenian': 'slv', - 'Spanish': 'spa', - 'Sundanese': 'sun', - 'Swahili': 'swa', - 'Swedish': 'swe', - 'Tajik': 'tgk', - 'Tamil': 'tam', - 'Telugu': 'tel', - 'Thai': 'tha', - 'Turkish': 'tur', - 'Ukrainian': 'ukr', - 'Urdu': 'urd', - 'Uzbek': 'uzb', - 'Vietnamese': 'vie', - 'Welsh': 'cym', - 'Yiddish': 'yid', - 'Yoruba': 'yor' -}; + Afrikaans: 'afr', + Albanian: 'sqi', + Amharic: 'amh', + Arabic: 'ara', + Armenian: 'hye', + Azerbaijani: 'aze', + Basque: 'eus', + Belarusian: 'bel', + Bengali: 'ben', + Bosnian: 'bos', + Bulgarian: 'bul', + Burmese: 'mya', + Catalan: 'cat', + Cebuano: 'ceb', + 'Chinese Simplified': 'chi_sim', + 'Chinese Simplified (vertical)': 'chi_sim_vert', + 'Chinese Traditional': 'chi_tra', + 'Chinese Traditional (vertical)': 'chi_tra_vert', + Corsican: 'cos', + Croatian: 'hrv', + Czech: 'ces', + Danish: 'dan', + Dutch: 'nld', + English: 'eng', + Esperanto: 'epo', + Estonian: 'est', + Filipino: 'fil', + Finnish: 'fin', + French: 'fra', + Frisian: 'fry', + Galician: 'glg', + Georgian: 'kat', + German: 'deu', + Greek: 'ell', + Gujarati: 'guj', + Haitian: 'hat', + Hebrew: 'heb', + Hindi: 'hin', + Hungarian: 'hun', + Icelandic: 'isl', + Indonesian: 'ind', + Irish: 'gle', + Italian: 'ita', + Japanese: 'jpn', + 'Japanese (vertical)': 'jpn_vert', + Javanese: 'jav', + Kannada: 'kan', + Kazakh: 'kaz', + Khmer: 'khm', + Korean: 'kor', + 'Korean (vertical)': 'kor_vert', + Kurdish: 'kmr', + Lao: 'lao', + Latin: 'lat', + Latvian: 'lav', + Lithuanian: 'lit', + Luxembourgish: 'ltz', + Macedonian: 'mkd', + Malay: 'msa', + Malayalam: 'mal', + Maltese: 'mlt', + Maori: 'mri', + Marathi: 'mar', + Mongolian: 'mon', + Nepali: 'nep', + Norwegian: 'nor', + Persian: 'fas', + Polish: 'pol', + Portuguese: 'por', + Romanian: 'ron', + Russian: 'rus', + 'Scottish Gaelic': 'gla', + Serbian: 'srp', + Sindhi: 'snd', + Sinhala: 'sin', + Slovak: 'slk', + Slovenian: 'slv', + Spanish: 'spa', + Sundanese: 'sun', + Swahili: 'swa', + Swedish: 'swe', + Tajik: 'tgk', + Tamil: 'tam', + Telugu: 'tel', + Thai: 'tha', + Turkish: 'tur', + Ukrainian: 'ukr', + Urdu: 'urd', + Uzbek: 'uzb', + Vietnamese: 'vie', + Welsh: 'cym', + Yiddish: 'yid', + Yoruba: 'yor' +} let tippyData = [ - { - type: 'zoom-in', - text: 'Zoom In' - }, - { - type: 'zoom-out', - text: 'Zoom Out' - }, - { - type: 'one-to-one', - text: '1:1' - }, - { - type: 'reset', - text: 'Reset' - }, - { - type: 'rotate-left', - text: 'Rotate Left', - }, - { - type: 'rotate-right', - text: 'Rotate Right', - }, - { - type: 'flip-horizontal', - text: 'Flip Horizontal', - }, - { - type: 'flip-vertical', - text: 'Flip Vertical', - }, - { - type: 'crop', - text: 'Crop Image', - }, - { - type: 'download', - text: 'Download', - }, - { - type: 'play', - text: 'Fullscreen', - }, - { - type: 'details', - text: 'Details', - }, - { - type: 'colorpicker', - text: 'Color Picker', - }, - { - type: 'paint', - text: 'Photo Editor', - }, - { - type: 'print', - text: 'Print image', - }, - { - type: 'help', - text: 'Help', - }, - { - type: 'theme', - text: 'Toggle Theme', - }, - { - type: 'exit', - text: 'Turn Off', - }, - { - type: 'upload', - text: 'Upload image to ImgBB', - }, - { - type: 'ocr', - text: 'Extract Text', - }, - { - type: 'photopea', - text: 'Edit in Photopea', - }, - { - type: 'tineye', - text: 'Reverse Image Search', - }, - { - type: 'about', - text: 'About', - }, - { - type: 'qr', - text: 'QR Code Scanner', - }, - { - type: 'settings', - text: 'Settings', - } + { + type: 'zoom-in', + text: 'Zoom In' + }, + { + type: 'zoom-out', + text: 'Zoom Out' + }, + { + type: 'one-to-one', + text: '1:1' + }, + { + type: 'reset', + text: 'Reset' + }, + { + type: 'rotate-left', + text: 'Rotate Left' + }, + { + type: 'rotate-right', + text: 'Rotate Right' + }, + { + type: 'flip-horizontal', + text: 'Flip Horizontal' + }, + { + type: 'flip-vertical', + text: 'Flip Vertical' + }, + { + type: 'crop', + text: 'Crop Image' + }, + { + type: 'download', + text: 'Download' + }, + { + type: 'play', + text: 'Fullscreen' + }, + { + type: 'details', + text: 'Details' + }, + { + type: 'colorpicker', + text: 'Color Picker' + }, + { + type: 'paint', + text: 'Photo Editor' + }, + { + type: 'print', + text: 'Print image' + }, + { + type: 'help', + text: 'Help' + }, + { + type: 'theme', + text: 'Toggle Theme' + }, + { + type: 'exit', + text: 'Turn Off' + }, + { + type: 'upload', + text: 'Upload image to ImgBB' + }, + { + type: 'ocr', + text: 'Extract Text' + }, + { + type: 'photopea', + text: 'Edit in Photopea' + }, + { + type: 'tineye', + text: 'Reverse Image Search' + }, + { + type: 'about', + text: 'About' + }, + { + type: 'qr', + text: 'QR Code Scanner' + }, + { + type: 'settings', + text: 'Settings' + } ] // Prevent default keyboard behavior (for example : ctrl + s or ctrl + f) // Except F11 (Suggestion from some users) document.addEventListener('keydown', function (e) { - if (!isKeypressEnabled) { - if (e.key !== 'F11') { // f11 is the only exception - e.preventDefault(); - } + if (!isKeypressEnabled) { + if (e.key !== 'F11') { + // f11 is the only exception + e.preventDefault() } - -}); + } +}) /** * NB: "mod" keyword same as "ctrl" - for cross-browser compatibility */ Mousetrap.bind('mod+0', () => { - document.getElementsByClassName('viewer-reset')[0].click(); -}); + document.getElementsByClassName('viewer-reset')[0].click() +}) Mousetrap.bind('mod+1', () => { - document.getElementsByClassName('viewer-one-to-one')[0].click(); -}); + document.getElementsByClassName('viewer-one-to-one')[0].click() +}) Mousetrap.bind('mod+s', () => { - document.getElementsByClassName('viewer-download')[0].click(); -}); + document.getElementsByClassName('viewer-download')[0].click() +}) Mousetrap.bind('mod++', () => { - document.getElementsByClassName('viewer-zoom-in')[0].click(); -}); + document.getElementsByClassName('viewer-zoom-in')[0].click() +}) Mousetrap.bind('mod+-', () => { - document.getElementsByClassName('viewer-zoom-out')[0].click(); -}); + document.getElementsByClassName('viewer-zoom-out')[0].click() +}) Mousetrap.bind('mod+left', () => { - document.getElementsByClassName('viewer-rotate-left')[0].click(); -}); + document.getElementsByClassName('viewer-rotate-left')[0].click() +}) Mousetrap.bind('mod+right', () => { - document.getElementsByClassName('viewer-rotate-right')[0].click(); -}); + document.getElementsByClassName('viewer-rotate-right')[0].click() +}) Mousetrap.bind('mod+a', () => { - document.getElementsByClassName('viewer-flip-horizontal')[0].click(); -}); + document.getElementsByClassName('viewer-flip-horizontal')[0].click() +}) Mousetrap.bind('mod+q', () => { - document.getElementsByClassName('viewer-flip-vertical')[0].click(); -}); + document.getElementsByClassName('viewer-flip-vertical')[0].click() +}) Mousetrap.bind('mod+x', () => { - document.getElementsByClassName('viewer-crop')[0].click(); -}); + document.getElementsByClassName('viewer-crop')[0].click() +}) Mousetrap.bind('mod+p', () => { - document.getElementsByClassName('viewer-paint')[0].click(); -}); + document.getElementsByClassName('viewer-paint')[0].click() +}) Mousetrap.bind('mod+c', () => { - document.getElementsByClassName('viewer-colorpicker')[0].click(); -}); + document.getElementsByClassName('viewer-colorpicker')[0].click() +}) Mousetrap.bind('mod+d', () => { - document.getElementsByClassName('viewer-details')[0].click(); -}); + document.getElementsByClassName('viewer-details')[0].click() +}) Mousetrap.bind('mod+h', () => { - document.getElementsByClassName('viewer-help')[0].click(); -}); + document.getElementsByClassName('viewer-help')[0].click() +}) Mousetrap.bind('mod+f', () => { - document.getElementsByClassName('viewer-play')[0].click(); -}); + document.getElementsByClassName('viewer-play')[0].click() +}) Mousetrap.bind('mod+m', () => { - document.getElementsByClassName('viewer-print')[0].click(); -}); + document.getElementsByClassName('viewer-print')[0].click() +}) Mousetrap.bind('mod+y', () => { - document.getElementsByClassName('viewer-theme')[0].click(); -}); + document.getElementsByClassName('viewer-theme')[0].click() +}) Mousetrap.bind('mod+e', () => { - document.getElementsByClassName('viewer-exit')[0].click(); -}); + document.getElementsByClassName('viewer-exit')[0].click() +}) Mousetrap.bind('mod+u', () => { - document.getElementsByClassName('viewer-upload')[0].click(); -}); + document.getElementsByClassName('viewer-upload')[0].click() +}) Mousetrap.bind('mod+g', () => { - document.getElementsByClassName('viewer-photopea')[0].click(); -}); + document.getElementsByClassName('viewer-photopea')[0].click() +}) Mousetrap.bind('mod+o', () => { - document.getElementsByClassName('viewer-ocr')[0].click(); -}); + document.getElementsByClassName('viewer-ocr')[0].click() +}) Mousetrap.bind('mod+j', () => { - document.getElementsByClassName('viewer-tineye')[0].click(); -}); - - + document.getElementsByClassName('viewer-tineye')[0].click() +}) /** * Initializes the extension */ function init(settings) { + BACKGROUND_TYPE = settings.settings.default_theme + + // checks the zoom setting - if it's nulled, then the default is set to 0.1 (10%) + settings.settings.zoom_ratio == null ? (settings.settings.zoom_ratio = 0.1) : (zoomSetting = settings.settings.zoom_ratio) + zoomSetting = settings.settings.zoom_ratio + + let imgElement = document.getElementsByTagName('img')[0] // get img element + // if img element is found + if (imgElement) { + let blurryDiv = document.createElement('div') // create blurry div + blurryDiv.setAttribute('class', 'blurry-bg') // add class to blurry div + imgElement.parentNode.insertBefore(blurryDiv, imgElement) // add before img element + + // init Viewer + viewer = new Viewer(imgElement, { + inline: false, + loading: false, + interval: 0, + zoomable: true, + transition: true, + navbar: false, + title: false, + keyboard: false, + backdrop: false, // prevent exit when click backdrop + zoomRatio: zoomSetting, + toolbar: { + next: false, + prev: false, + zoomIn: settings.settings.zoomIn && { + show: 1, + size: 'large' + }, + zoomOut: settings.settings.zoomOut && { + show: 1, + size: 'large' + }, + oneToOne: settings.settings.oneToOne && { + show: 1, + size: 'large' + }, + reset: settings.settings.reset && { + show: 1, + size: 'large', + click: function () { + viewer.image.src = window.location.href + viewer.reset() + setTimeout(() => { + if (settings.settings.toolbar_position === 'top') { + viewer.move(0, 50) + } + }, 100) + window.dispatchEvent(new Event('resize')) + } + }, + play: settings.settings.play && { + show: 1, + size: 'large', + click: function () { + viewer.image + .requestFullscreen() + .then(function () { + // console.log('requestFullscreen success'); + }) + .catch(function (error) { + console.error(error) + }) + } + }, + rotateLeft: settings.settings.rotateLeft && { + show: 1, + size: 'large' + }, + rotateRight: settings.settings.rotateRight && { + show: 1, + size: 'large' + }, + flipHorizontal: settings.settings.flipHorizontal && { + show: 1, + size: 'large' + }, + flipVertical: settings.settings.flipVertical && { + show: 1, + size: 'large' + }, + crop: settings.settings.crop && { + show: 1, + size: 'large', + click: function () { + if (!IS_CROP_OPEN) { + IS_CROP_OPEN = true + // reset viewer + //viewer.reset(); + let reset = viewer.reset() + setTimeout(() => { + if (settings.settings.toolbar_position === 'top') { + viewer.move(0, 50) + } + }, 100) + if (reset) { + crop(viewer, viewer.image.src, viewer.image.width, viewer.image.height) + } + } + } + }, + paint: settings.settings.paint && { + show: 1, + size: 'large', + click: function () { + isKeypressEnabled = true + // create new winbox + let winboxPaint = new WinBox('Photo Editor', { + class: ['no-scrollbar', 'no-min', 'no-animation'], + index: 9999, + x: 'center', + y: 'center', + width: '90%', + height: '90%', + background: 'rgba(0,0,0,0.9)', + html: `
` + }) + + winboxPaint.show() + + const config = { + theme: { + palette: { + 'txt-primary': '#ffffff', + 'txt-primary-invert': '#ffffff', + // 'txt-secondary': '#ffffff', + // 'txt-secondary-invert': '#ffffff', + // 'txt-placeholder': '#ffffff', + 'accent-primary': '#1E262C', + 'accent-primary-hover': '#000000', + 'accent-primary-active': '#000000', + // 'accent-primary-disabled': '#ffffff', + 'bg-primary': '#00000000' // canvas bg + //'bg-primary-hover': '#000000', + //'bg-primary-active': '#000000', + //'bg-primary-0-5-opacity': '#ffffff', + //'bg-secondary': '#ffffff', + //'icons-primary': '#ffffff', + //'icons-primary-opacity-0-6': '#ffffff', + //'icons-secondary': '#ffffff', + // 'btn-primary-text': '#ffffff', + // 'btn-disabled-text': '#ffffff', + // 'link-primary': '#ffffff', + // 'link-hover': '#ffffff', + // 'link-active': '#ffffff', + // 'borders-primary': '#ffffff', + // 'borders-secondary': '#ffffff', + // 'borders-strong': '#ffffff', + // 'borders-invert': '#ffffff', + // 'border-active-bottom': '#ffffff', + // 'active-secondary': '#ffffff', + // 'active-secondary-hover': '#ffffff', + // 'active-secondary-active': '#ffffff', + // 'tag': '#ffffff', + // 'error': '#ffffff', + // 'success': '#ffffff', + // 'warning': '#ffffff', + // 'info': '#ffffff', + // 'light-shadow': '#ffffff', + } + }, + onBeforeSave: function (imageFileInfo) { + // prevent default behavior + return false + }, + onSave: function (imageData, imageDesignState) { + console.log('~ imageDesignState', imageDesignState) + console.log('~ imageData', imageData) + let newImgBase64 = imageData.imageBase64 + let imgElements = document.getElementsByTagName('img') + for (let elem of imgElements) { + elem.src = newImgBase64 + } + // trigger resize event in setTimeout + setTimeout(function () { + window.dispatchEvent(new Event('resize')) + }, 100) + showNotification('💾 Image saved successfully', '#ffffff', '#000000', settings) + setTimeout(() => { + if (settings.settings.toolbar_position === 'top') { + viewer.move(0, 50) + } + }, 100) + winboxPaint.close() + }, + moreSaveOptions: [ + { + label: 'Save as new file', + onClick: (triggerSaveModal, triggerSave) => + triggerSaveModal((...args) => { + let a = document.createElement('a') + a.href = args[0].imageBase64 + a.download = args[0].fullName + a.click() + + showNotification('💾 Image downloaded successfully', '#ffffff', '#000000', settings) + }) + } + ], + source: viewer.image.src, + //onSave: (editedImageObject, designState) => console.log('saved', editedImageObject, designState), + annotationsCommon: { + fill: '#ff0000' + }, + Text: { text: 'Your Text Here...' }, + translations: { + profile: 'Profile', + coverPhoto: 'Cover photo', + facebook: 'Facebook', + socialMedia: 'Social Media', + fbProfileSize: '180x180px', + fbCoverPhotoSize: '820x312px' + }, + Crop: { + presetsItems: [ + { + titleKey: 'classicTv', + descriptionKey: '4:3', + ratio: 4 / 3 + // icon: CropClassicTv, // optional, CropClassicTv is a React Function component. Possible (React Function component, string or HTML Element) + }, + { + titleKey: 'cinemascope', + descriptionKey: '21:9', + ratio: 21 / 9 + // icon: CropCinemaScope, // optional, CropCinemaScope is a React Function component. Possible (React Function component, string or HTML Element) + } + ], + presetsFolders: [ + { + titleKey: 'socialMedia', // will be translated into Social Media as backend contains this translation key + // icon: Social, // optional, Social is a React Function component. Possible (React Function component, string or HTML Element) + groups: [ + { + titleKey: 'facebook', + items: [ + { + titleKey: 'profile', + width: 180, + height: 180, + descriptionKey: 'fbProfileSize' + }, + { + titleKey: 'coverPhoto', + width: 820, + height: 312, + descriptionKey: 'fbCoverPhotoSize' + } + ] + } + ] + } + ] + }, + tabsIds: [window.FilerobotImageEditor.TABS.ADJUST, window.FilerobotImageEditor.TABS.ANNOTATE, window.FilerobotImageEditor.TABS.WATERMARK, window.FilerobotImageEditor.TABS.FILTERS, window.FilerobotImageEditor.TABS.FINETUNE, window.FilerobotImageEditor.TABS.RESIZE], // or ['Adjust', 'Annotate', 'Watermark'] + defaultTabId: window.FilerobotImageEditor.TABS.ANNOTATE, // or 'Annotate' + defaultToolId: window.FilerobotImageEditor.TOOLS.TEXT // or 'Text' + } + console.log(window.FilerobotImageEditor.TABS) + + // Assuming we have a div with id="editor_container" + const filerobotImageEditor = new FilerobotImageEditor(document.querySelector('#paint-wrapper'), config) + + filerobotImageEditor.render({ + onClose: closingReason => { + console.log('Closing reason', closingReason) + filerobotImageEditor.terminate() + } + }) + + // window.p = Painterro({ + // hideByEsc: true, + // saveByEnter: true, + // hiddenTools: [ + // 'open', 'close', 'resize', 'eraser' + // ], + // id: 'paint-wrapper', + // availableLineWidths: [1, 2, 4, 8, 16, 64], + // availableEraserWidths: [1, 2, 4, 8, 16, 64], + // availableFontSizes: [1, 2, 4, 8, 16, 64], + // availableArrowLengths: [10, 20, 30, 40, 50, 60], + // defaultTool: 'brush', + // saveHandler: (image, done) => { + + // let newImgBase64 = image.asDataURL(); + + // let imgElements = document.getElementsByTagName('img'); + // // loop through all img elements + // // for (let i = 0; i < imgElements.length; i++) { + // // // replace image with cropped image + // // imgElements[i].src = newImgBase64; + // // } + + // for (let elem of imgElements) { + // elem.src = newImgBase64; + // } + + // // trigger resize event in setTimeout + // setTimeout(function () { + // window.dispatchEvent(new Event('resize')); + // }, 100); + + // showNotification('💾 Image saved successfully', '#ffffff', '#000000', settings); + // setTimeout(() => { + // if (settings.settings.toolbar_position === 'top') { + // viewer.move(0, 50); + // } + // }, 100); + + // winboxPaint.close(); + // done(true); + // } + // }).show(viewer.image.src); + } + }, + download: settings.settings.download && { + show: 1, + size: 'large', + click: function () { + download(viewer.image) + } + }, + upload: settings.settings.upload && { + show: 1, + size: 'large', + click: function () { + let uriString = getBase64Image(viewer.image) + + // get base64 part from string + let base64 = uriString.split(',')[1] + + // create html element with text + let x = document.createElement('div') + // set flex + x.style.display = 'flex' + // set element inner html + x.innerHTML = ` Uploading image... Please wait` + + Toastify({ + node: x, + duration: 999999, + newWindow: true, + close: false, + gravity: settings.settings.notification_gravity, // `top` or `bottom` + position: settings.settings.notification_position, // `left`, `center` or `right` + stopOnFocus: true, // Prevents dismissing of toast on hover + style: { + color: '#ffffff', + background: '#000000' + } + //onClick: function () { } // Callback after click + }).showToast() + + // upload image to imgur + // fetch('https://api.imgur.com/3/image', { + // method: 'POST', + // headers: { 'Authorization': `Client-ID ${IMGUR_TOKEN}` }, + // body: base64 + // }) + + // upload base64 to ImgBB + let formdata = new FormData() + formdata.append('image', base64) + + let requestOptions = { + method: 'POST', + body: formdata, + redirect: 'follow' + } - BACKGROUND_TYPE = settings.settings.default_theme; - - // checks the zoom setting - if it's nulled, then the default is set to 0.1 (10%) - settings.settings.zoom_ratio == null ? settings.settings.zoom_ratio = 0.1 : zoomSetting = settings.settings.zoom_ratio; - zoomSetting = settings.settings.zoom_ratio; - - let imgElement = document.getElementsByTagName('img')[0]; // get img element - // if img element is found - if (imgElement) { - - let blurryDiv = document.createElement('div'); // create blurry div - blurryDiv.setAttribute('class', 'blurry-bg'); // add class to blurry div - imgElement.parentNode.insertBefore(blurryDiv, imgElement); // add before img element - - - // init Viewer - viewer = new Viewer(imgElement, { - inline: false, - loading: false, - interval: 0, - zoomable: true, - transition: true, - navbar: false, - title: false, - keyboard: false, - backdrop: false, // prevent exit when click backdrop - zoomRatio: zoomSetting, - toolbar: { - next: false, - prev: false, - zoomIn: settings.settings.zoomIn && { - show: 1, - size: 'large', - }, - zoomOut: settings.settings.zoomOut && { - show: 1, - size: 'large', - }, - oneToOne: settings.settings.oneToOne && { - show: 1, - size: 'large', - }, - reset: settings.settings.reset && { - show: 1, - size: 'large', - click: function () { - viewer.image.src = window.location.href; - viewer.reset(); - setTimeout(() => { - if (settings.settings.toolbar_position === 'top') { - viewer.move(0, 50); - } - }, 100) - window.dispatchEvent(new Event('resize')); - } - }, - play: settings.settings.play && { - show: 1, - size: 'large', - click: function () { - viewer.image.requestFullscreen() - .then(function () { - // console.log('requestFullscreen success'); - }) - .catch(function (error) { - console.error(error); - }); - } - }, - rotateLeft: settings.settings.rotateLeft && { - show: 1, - size: 'large', - }, - rotateRight: settings.settings.rotateRight && { - show: 1, - size: 'large', - }, - flipHorizontal: settings.settings.flipHorizontal && { - show: 1, - size: 'large', - }, - flipVertical: settings.settings.flipVertical && { - show: 1, - size: 'large', - }, - crop: settings.settings.crop && { - show: 1, - size: 'large', - click: function () { - if (!IS_CROP_OPEN) { - IS_CROP_OPEN = true; - // reset viewer - //viewer.reset(); - let reset = viewer.reset(); - setTimeout(() => { - if (settings.settings.toolbar_position === 'top') { - viewer.move(0, 50); - } - }, 100) - if (reset) { - crop(viewer, viewer.image.src, viewer.image.width, viewer.image.height); - } - - - } - - } - }, - paint: settings.settings.paint && { - show: 1, - size: 'large', - click: function () { - - isKeypressEnabled = true; - // create new winbox - let winboxPaint = new WinBox("Photo Editor", { - class: [ - "no-scrollbar", - "no-min", - "no-animation" - ], - index: 9999, - x: "center", - y: "center", - width: '90%', - height: '90%', - background: "rgba(0,0,0,0.9)", - html: `
`, - }); - - winboxPaint.show(); - - - const config = { - - theme: { - palette: { - 'txt-primary': '#ffffff', - 'txt-primary-invert': '#ffffff', - // 'txt-secondary': '#ffffff', - // 'txt-secondary-invert': '#ffffff', - // 'txt-placeholder': '#ffffff', - 'accent-primary': '#1E262C', - 'accent-primary-hover': '#000000', - 'accent-primary-active': '#000000', - // 'accent-primary-disabled': '#ffffff', - 'bg-primary': '#00000000', // canvas bg - //'bg-primary-hover': '#000000', - //'bg-primary-active': '#000000', - //'bg-primary-0-5-opacity': '#ffffff', - //'bg-secondary': '#ffffff', - //'icons-primary': '#ffffff', - //'icons-primary-opacity-0-6': '#ffffff', - //'icons-secondary': '#ffffff', - // 'btn-primary-text': '#ffffff', - // 'btn-disabled-text': '#ffffff', - // 'link-primary': '#ffffff', - // 'link-hover': '#ffffff', - // 'link-active': '#ffffff', - // 'borders-primary': '#ffffff', - // 'borders-secondary': '#ffffff', - // 'borders-strong': '#ffffff', - // 'borders-invert': '#ffffff', - // 'border-active-bottom': '#ffffff', - // 'active-secondary': '#ffffff', - // 'active-secondary-hover': '#ffffff', - // 'active-secondary-active': '#ffffff', - // 'tag': '#ffffff', - // 'error': '#ffffff', - // 'success': '#ffffff', - // 'warning': '#ffffff', - // 'info': '#ffffff', - // 'light-shadow': '#ffffff', - }, - - }, - onBeforeSave: function (imageFileInfo) { - // prevent default behavior - return false; - }, - onSave: function (imageData, imageDesignState) { - - console.log("~ imageDesignState", imageDesignState) - console.log("~ imageData", imageData) - let newImgBase64 = imageData.imageBase64; - let imgElements = document.getElementsByTagName('img'); - for (let elem of imgElements) { - elem.src = newImgBase64; - } - // trigger resize event in setTimeout - setTimeout(function () { - window.dispatchEvent(new Event('resize')); - }, 100); - showNotification('💾 Image saved successfully', '#ffffff', '#000000', settings); - setTimeout(() => { - if (settings.settings.toolbar_position === 'top') { - viewer.move(0, 50); - } - }, 100); - winboxPaint.close(); - - }, - moreSaveOptions: - [ - { - label: 'Save as new file', - onClick: (triggerSaveModal, triggerSave) => triggerSaveModal((...args) => { - - - - let a = document.createElement("a"); - a.href = args[0].imageBase64; - a.download = args[0].fullName - a.click(); - - showNotification('💾 Image downloaded successfully', '#ffffff', '#000000', settings); - - }), - }, - - - ] - , - source: viewer.image.src, - //onSave: (editedImageObject, designState) => console.log('saved', editedImageObject, designState), - annotationsCommon: { - fill: '#ff0000', - }, - Text: { text: 'Your Text Here...' }, - translations: { - profile: 'Profile', - coverPhoto: 'Cover photo', - facebook: 'Facebook', - socialMedia: 'Social Media', - fbProfileSize: '180x180px', - fbCoverPhotoSize: '820x312px', - }, - Crop: { - presetsItems: [ - { - titleKey: 'classicTv', - descriptionKey: '4:3', - ratio: 4 / 3, - // icon: CropClassicTv, // optional, CropClassicTv is a React Function component. Possible (React Function component, string or HTML Element) - }, - { - titleKey: 'cinemascope', - descriptionKey: '21:9', - ratio: 21 / 9, - // icon: CropCinemaScope, // optional, CropCinemaScope is a React Function component. Possible (React Function component, string or HTML Element) - }, - ], - presetsFolders: [ - { - titleKey: 'socialMedia', // will be translated into Social Media as backend contains this translation key - // icon: Social, // optional, Social is a React Function component. Possible (React Function component, string or HTML Element) - groups: [ - { - titleKey: 'facebook', - items: [ - { - titleKey: 'profile', - width: 180, - height: 180, - descriptionKey: 'fbProfileSize', - }, - { - titleKey: 'coverPhoto', - width: 820, - height: 312, - descriptionKey: 'fbCoverPhotoSize', - }, - ], - }, - ], - }, - ], - }, - tabsIds: [window.FilerobotImageEditor.TABS.ADJUST, - window.FilerobotImageEditor.TABS.ANNOTATE, - window.FilerobotImageEditor.TABS.WATERMARK, - window.FilerobotImageEditor.TABS.FILTERS, - window.FilerobotImageEditor.TABS.FINETUNE, - window.FilerobotImageEditor.TABS.RESIZE, - - - - ], // or ['Adjust', 'Annotate', 'Watermark'] - defaultTabId: window.FilerobotImageEditor.TABS.ANNOTATE, // or 'Annotate' - defaultToolId: window.FilerobotImageEditor.TOOLS.TEXT, // or 'Text' - }; - - console.log(window.FilerobotImageEditor.TABS) - - // Assuming we have a div with id="editor_container" - const filerobotImageEditor = new FilerobotImageEditor( - document.querySelector('#paint-wrapper'), - config - ); - - filerobotImageEditor.render({ - onClose: (closingReason) => { - console.log('Closing reason', closingReason); - filerobotImageEditor.terminate(); - } - }); - - - - - // window.p = Painterro({ - // hideByEsc: true, - // saveByEnter: true, - // hiddenTools: [ - // 'open', 'close', 'resize', 'eraser' - // ], - // id: 'paint-wrapper', - // availableLineWidths: [1, 2, 4, 8, 16, 64], - // availableEraserWidths: [1, 2, 4, 8, 16, 64], - // availableFontSizes: [1, 2, 4, 8, 16, 64], - // availableArrowLengths: [10, 20, 30, 40, 50, 60], - // defaultTool: 'brush', - // saveHandler: (image, done) => { - - // let newImgBase64 = image.asDataURL(); - - // let imgElements = document.getElementsByTagName('img'); - // // loop through all img elements - // // for (let i = 0; i < imgElements.length; i++) { - // // // replace image with cropped image - // // imgElements[i].src = newImgBase64; - // // } - - // for (let elem of imgElements) { - // elem.src = newImgBase64; - // } - - // // trigger resize event in setTimeout - // setTimeout(function () { - // window.dispatchEvent(new Event('resize')); - // }, 100); - - // showNotification('💾 Image saved successfully', '#ffffff', '#000000', settings); - // setTimeout(() => { - // if (settings.settings.toolbar_position === 'top') { - // viewer.move(0, 50); - // } - // }, 100); - - // winboxPaint.close(); - // done(true); - // } - // }).show(viewer.image.src); - } - }, - download: settings.settings.download && { - show: 1, - size: 'large', - click: function () { - download(viewer.image); - } - }, - upload: settings.settings.upload && { - show: 1, - size: 'large', - click: function () { - - let uriString = getBase64Image(viewer.image); - - // get base64 part from string - let base64 = uriString.split(',')[1]; - - // create html element with text - let x = document.createElement("div"); - // set flex - x.style.display = "flex"; - // set element inner html - x.innerHTML = ` Uploading image... Please wait`; - - Toastify({ - node: x, - duration: 999999, - newWindow: true, - close: false, - gravity: settings.settings.notification_gravity, // `top` or `bottom` - position: settings.settings.notification_position, // `left`, `center` or `right` - stopOnFocus: true, // Prevents dismissing of toast on hover - style: { - color: '#ffffff', - background: '#000000', - }, - //onClick: function () { } // Callback after click - }).showToast(); - - // upload image to imgur - // fetch('https://api.imgur.com/3/image', { - // method: 'POST', - // headers: { 'Authorization': `Client-ID ${IMGUR_TOKEN}` }, - // body: base64 - // }) - - // upload base64 to ImgBB - let formdata = new FormData(); - formdata.append("image", base64); - - let requestOptions = { - method: 'POST', - body: formdata, - redirect: 'follow' - }; - - fetch(`https://api.imgbb.com/1/upload?expiration=600&key=${IMGBB_TOKEN}`, requestOptions) - .then(res => res.json()) - .then((res) => { - - // remove toast - let toastifyElems = document.querySelectorAll('.toastify'); - toastifyElems.forEach(element => { - element.remove() - }); - - copyToClipboard(res.data.image.url); - showNotification('✔️ Image uploaded successfully', '#ffffff', '#000000', settings); - showNotification(`📋 URL copied to clipboard`, '#ffffff', '#000000', settings); - - }); - - } - }, - colorpicker: settings.settings.colorpicker && { - show: 1, - size: 'large', - click: async function () { - - if (!IS_PICKER_OPEN) { - IS_PICKER_OPEN = true; - - // change cursor to picker - viewer.image.style.cursor = 'crosshair'; - - - - let colorPickerBox = new WinBox("Color Preview", { - class: WINBOX_CLASSES, - background: "rgba(0,0,0,0.9)", - index: 9999, - width: '250px', - height: '250px', - y: "bottom", - x: "10px", - html: ` + fetch(`https://api.imgbb.com/1/upload?expiration=600&key=${IMGBB_TOKEN}`, requestOptions) + .then(res => res.json()) + .then(res => { + // remove toast + let toastifyElems = document.querySelectorAll('.toastify') + toastifyElems.forEach(element => { + element.remove() + }) + + copyToClipboard(res.data.image.url) + showNotification('✔️ Image uploaded successfully', '#ffffff', '#000000', settings) + showNotification(`📋 URL copied to clipboard`, '#ffffff', '#000000', settings) + }) + } + }, + colorpicker: settings.settings.colorpicker && { + show: 1, + size: 'large', + click: async function () { + if (!IS_PICKER_OPEN) { + IS_PICKER_OPEN = true + + // change cursor to picker + viewer.image.style.cursor = 'crosshair' + + let colorPickerBox = new WinBox('Color Preview', { + class: WINBOX_CLASSES, + background: 'rgba(0,0,0,0.9)', + index: 9999, + width: '250px', + height: '250px', + y: 'bottom', + x: '10px', + html: `
`, - onclose: function () { - IS_PICKER_OPEN = false; - // change cursor back to default - viewer.image.style.cursor = 'default'; - viewer.image.click(); // trigger a click to remove the event listener - } - }); - - - // init color picker - const pickr = Pickr.create({ - el: '.color-picker', - inline: true, - showAlways: true, - theme: 'classic', // or 'monolith', or 'nano' - useAsButton: false, - autoReposition: true, - appClass: 'color-picker-app', - components: { - - // Main components - preview: true, - opacity: false, - hue: true, - - // Input / output Options - interaction: { - hex: true, - rgba: true, - hsla: true, - hsva: true, - cmyk: true, - input: true, - } - } - }); - - - - // auto size window - let contentWidth = document.getElementsByClassName('pcr-app')[0].getBoundingClientRect().width; - let contentHeight = document.getElementsByClassName('pcr-app')[0].getBoundingClientRect().height; - colorPickerBox.resize(contentWidth + 8, contentHeight + 35); // TODO: use better way to get content height and width - colorPickerBox.show(); - - // create new canvas - let canvas = document.createElement('canvas'); - canvas.style.display = 'none'; - - let x = '' - let y = ''; - - - // when image clicked - viewer.image.addEventListener('click', function (e) { - if (IS_PICKER_OPEN) { - handleImageClickOnPicker(e, viewer, canvas, pickr, x, y, settings); - } - else { - this.removeEventListener('click', arguments.callee); - } - - }, false); - - // when mouse move - viewer.image.addEventListener('mousemove', function (e) { - if (IS_PICKER_OPEN) { - handleMouseMoveOnPicker(e, viewer, canvas, pickr, x, y); - } - else { - this.removeEventListener('mousemove', arguments.callee); - } - - }, false); - } - else { - return; - } - } + onclose: function () { + IS_PICKER_OPEN = false + // change cursor back to default + viewer.image.style.cursor = 'default' + viewer.image.click() // trigger a click to remove the event listener + } + }) + + // init color picker + const pickr = Pickr.create({ + el: '.color-picker', + inline: true, + showAlways: true, + theme: 'classic', // or 'monolith', or 'nano' + useAsButton: false, + autoReposition: true, + appClass: 'color-picker-app', + components: { + // Main components + preview: true, + opacity: false, + hue: true, + + // Input / output Options + interaction: { + hex: true, + rgba: true, + hsla: true, + hsva: true, + cmyk: true, + input: true + } + } + }) + + // auto size window + let contentWidth = document.getElementsByClassName('pcr-app')[0].getBoundingClientRect().width + let contentHeight = document.getElementsByClassName('pcr-app')[0].getBoundingClientRect().height + colorPickerBox.resize(contentWidth + 8, contentHeight + 35) // TODO: use better way to get content height and width + colorPickerBox.show() + + // create new canvas + let canvas = document.createElement('canvas') + canvas.style.display = 'none' + + let x = '' + let y = '' + + // when image clicked + viewer.image.addEventListener( + 'click', + function (e) { + if (IS_PICKER_OPEN) { + handleImageClickOnPicker(e, viewer, canvas, pickr, x, y, settings) + } else { + this.removeEventListener('click', arguments.callee) + } }, - details: settings.settings.details && { - show: 1, - size: 'large', - click: async function () { - if (!IS_DETAILS_OPEN) { - IS_DETAILS_OPEN = true; - try { - new WinBox("Details", { - class: [ - //"no-scrollbar", - "no-max", - "no-min", - "no-full", - "no-resize", - "no-animation" - ], - index: 9999, - background: "rgba(0,0,0,0.9)", - x: "20px", - y: "20px", - width: '350px', - height: '40%', - html: `
`, - onclose: function () { - IS_DETAILS_OPEN = false; - } - }); - } catch (error) { - console.error(error); - } - } - - let img2 = viewer.image - - const fileImg = await fetch(img2.src).then(r => r.blob()); - let fileSizeMB = fileImg.size / 1024 / 1024; - - let imgDetails = { - width: img2.naturalWidth, - height: img2.naturalHeight, - filesize: fileSizeMB.toFixed(2) + " MB", - } - - EXIF.getData(img2, function () { - let allMetaData = EXIF.getAllTags(this); - // add all metadata to wrapper - // let wrapper = document.getElementById('details-wrapper'); - - delete allMetaData.ImageWidth; - delete allMetaData.ImageHeight; - delete allMetaData.thumbnail; - - - allMetaData = { Width: imgDetails.width + "px", Height: imgDetails.height + "px", "File size": imgDetails.filesize, ...allMetaData }; - - + false + ) + + // when mouse move + viewer.image.addEventListener( + 'mousemove', + function (e) { + if (IS_PICKER_OPEN) { + handleMouseMoveOnPicker(e, viewer, canvas, pickr, x, y) + } else { + this.removeEventListener('mousemove', arguments.callee) + } + }, + false + ) + } else { + return + } + } + }, + details: settings.settings.details && { + show: 1, + size: 'large', + click: async function () { + if (!IS_DETAILS_OPEN) { + IS_DETAILS_OPEN = true + try { + new WinBox('Details', { + class: [ + //"no-scrollbar", + 'no-max', + 'no-min', + 'no-full', + 'no-resize', + 'no-animation' + ], + index: 9999, + background: 'rgba(0,0,0,0.9)', + x: '20px', + y: '20px', + width: '350px', + height: '40%', + html: `
`, + onclose: function () { + IS_DETAILS_OPEN = false + } + }) + } catch (error) { + console.error(error) + } + } - let el = document.querySelector('#details-wrapper'); - el.innerHTML = jsonViewer(allMetaData, true); + let img2 = viewer.image + const fileImg = await fetch(img2.src).then(r => r.blob()) + let fileSizeMB = fileImg.size / 1024 / 1024 + let imgDetails = { + width: img2.naturalWidth, + height: img2.naturalHeight, + filesize: fileSizeMB.toFixed(2) + ' MB' + } - // convert to string - //let metaDataString = JSON.stringify(allMetaData, null, "\t"); + EXIF.getData(img2, function () { + let allMetaData = EXIF.getAllTags(this) + // add all metadata to wrapper + // let wrapper = document.getElementById('details-wrapper'); - // add string inside wrapper - //wrapper.innerHTML = metaDataString; + delete allMetaData.ImageWidth + delete allMetaData.ImageHeight + delete allMetaData.thumbnail + allMetaData = { Width: imgDetails.width + 'px', Height: imgDetails.height + 'px', 'File size': imgDetails.filesize, ...allMetaData } + let el = document.querySelector('#details-wrapper') + el.innerHTML = jsonViewer(allMetaData, true) - }); + // convert to string + //let metaDataString = JSON.stringify(allMetaData, null, "\t"); - } - }, - theme: settings.settings.theme && { - show: 1, - size: 'large', - click: function () { - // blur --> light --> dark - changeTheme(viewer.image.src, settings); - - } - }, - print: settings.settings.print && { - show: 1, - size: 'large', - click: function () { - printImage(viewer.image); - } - }, - ocr: settings.settings.ocr && { - show: 1, - size: 'large', - click: function () { - - let v = viewer; - let url = viewer.image.src; - let width = viewer.image.width; - let height = viewer.image.height; - - - let ocrPreviewBox = new WinBox("Image To Text: Select Region", { - id: 'ocr-preview', - class: WINBOX_CLASSES, - modal: false, - index: 9999, - x: "center", - y: "center", - width: width + 7, - height: height + 40, - background: "rgba(0,0,0,0.9)", - html: `
`, - onclose: function () { - document.querySelector('#ocr-preview').remove(); - document.querySelector('#ocr-settings').remove(); - } - - }); - ocrPreviewBox.show(); - let ocrControlBox = new WinBox("Image To Text: Settings", { - id: 'ocr-settings', - class: WINBOX_CLASSES, - modal: false, - index: 9999, - x: "10px", - y: "bottom", - top: '10px', - bottom: '10px', - right: '10px', - left: '10px', - width: '250px', - height: '160px', - background: "rgba(0,0,0,0.9)", - html: ` + // add string inside wrapper + //wrapper.innerHTML = metaDataString; + }) + } + }, + theme: settings.settings.theme && { + show: 1, + size: 'large', + click: function () { + // blur --> light --> dark + changeTheme(viewer.image.src, settings) + } + }, + print: settings.settings.print && { + show: 1, + size: 'large', + click: function () { + printImage(viewer.image) + } + }, + ocr: settings.settings.ocr && { + show: 1, + size: 'large', + click: function () { + let v = viewer + let url = viewer.image.src + let width = viewer.image.width + let height = viewer.image.height + + let ocrPreviewBox = new WinBox('Image To Text: Select Region', { + id: 'ocr-preview', + class: WINBOX_CLASSES, + modal: false, + index: 9999, + x: 'center', + y: 'center', + width: width + 7, + height: height + 40, + background: 'rgba(0,0,0,0.9)', + html: `
`, + onclose: function () { + document.querySelector('#ocr-preview').remove() + document.querySelector('#ocr-settings').remove() + } + }) + ocrPreviewBox.show() + let ocrControlBox = new WinBox('Image To Text: Settings', { + id: 'ocr-settings', + class: WINBOX_CLASSES, + modal: false, + index: 9999, + x: '10px', + y: 'bottom', + top: '10px', + bottom: '10px', + right: '10px', + left: '10px', + width: '250px', + height: '160px', + background: 'rgba(0,0,0,0.9)', + html: `
Select Language
@@ -999,533 +929,481 @@ function init(settings) {
`, - onclose: function () { - document.querySelector('#ocr-preview').remove(); - document.querySelector('#ocr-settings').remove(); - document.querySelector('#ocr-result-box').remove(); - } - }); - ocrControlBox.show(); - let imgCropper = tinycrop.create({ - parent: '#parent-crop', - image: url, - bounds: { - width: width, - height: height - }, - backgroundColors: ['#fff', '#f3f3f3'], - selection: { - color: '#212121CC', - activeColor: '#ff0000CC', - minWidth: 10, - minHeight: 10, - x: v.image.naturalWidth / 2 - width / 2, - y: v.image.naturalHeight / 2 - height / 2, - width: width, - height: height - }, - onInit: () => { console.log('Initialised') } - }); - - let region; // contains the cropped region - imgCropper.on('change', (r) => { - region = r; - }); - - Object.keys(ocrLangList).forEach(function (key) { - let option = document.createElement('option'); - option.value = ocrLangList[key]; - option.text = key; - if (key == 'English') { - option.selected = true; - } - document.querySelector('#ocr-languages').appendChild(option); - }); - // when btn-extract-text clicked - document.getElementById('btn-extract-text').addEventListener('click', function () { - - // get selected language - let selectedLang = document.querySelector('#ocr-languages').value; - - - - - const cropRect = region; - const canvas = document.createElement("canvas"); - const context = canvas.getContext("2d"); - const imageObj = new Image(); - canvas.width = cropRect.width; - canvas.height = cropRect.height; - imageObj.src = url; - - imageObj.onload = function () { - context.drawImage(imageObj, cropRect.x, cropRect.y, cropRect.width, cropRect.height, 0, 0, cropRect.width, cropRect.height); - let ImgUrl = canvas.toDataURL(); - - - console.log(ImgUrl); - - - // create html element with text - let x = document.createElement("div"); - // set flex - x.style.display = "flex"; - // set element inner html - x.innerHTML = ` Extracting Text`; - - - - Toastify({ - node: x, - duration: 999999, - newWindow: true, - close: false, - gravity: settings.settings.notification_gravity, // `top` or `bottom` - position: settings.settings.notification_position, // `left`, `center` or `right` - stopOnFocus: true, // Prevents dismissing of toast on hover - style: { - color: '#ffffff', - background: '#000000', - }, - }).showToast(); - - // tesseract to ocr - Tesseract.recognize( - ImgUrl, - selectedLang, - { logger: m => console.log(m) } - ).then(({ data: { text } }) => { - - // remove all toasts - let toastifyElems = document.querySelectorAll('.toastify'); - toastifyElems.forEach(element => { - element.remove() - }); - - let ocrResElem = document.querySelector('#ocr-textarea'); - if (ocrResElem) {// if exists, then update - ocrResElem.innerHTML = text; - } - else { // create new winbox - - document.querySelector('#ocr-preview').remove(); - document.querySelector('#ocr-settings').remove(); - - - let ocrResultBox = new WinBox("Result", { - id: 'ocr-result-box', - class: WINBOX_CLASSES, - index: 9999, - width: '500px', - height: '320px', - top: '10px', - bottom: '10px', - right: '10px', - left: '10px', - x: "center", - y: "center", - - background: "rgba(0,0,0,0.9)", - html: `
+ onclose: function () { + document.querySelector('#ocr-preview').remove() + document.querySelector('#ocr-settings').remove() + document.querySelector('#ocr-result-box').remove() + } + }) + ocrControlBox.show() + let imgCropper = tinycrop.create({ + parent: '#parent-crop', + image: url, + bounds: { + width: width, + height: height + }, + backgroundColors: ['#fff', '#f3f3f3'], + selection: { + color: '#212121CC', + activeColor: '#ff0000CC', + minWidth: 10, + minHeight: 10, + x: v.image.naturalWidth / 2 - width / 2, + y: v.image.naturalHeight / 2 - height / 2, + width: width, + height: height + }, + onInit: () => { + console.log('Initialised') + } + }) + + let region // contains the cropped region + imgCropper.on('change', r => { + region = r + }) + + Object.keys(ocrLangList).forEach(function (key) { + let option = document.createElement('option') + option.value = ocrLangList[key] + option.text = key + if (key == 'English') { + option.selected = true + } + document.querySelector('#ocr-languages').appendChild(option) + }) + // when btn-extract-text clicked + document.getElementById('btn-extract-text').addEventListener('click', function () { + // get selected language + let selectedLang = document.querySelector('#ocr-languages').value + + const cropRect = region + const canvas = document.createElement('canvas') + const context = canvas.getContext('2d') + const imageObj = new Image() + canvas.width = cropRect.width + canvas.height = cropRect.height + imageObj.src = url + + imageObj.onload = function () { + context.drawImage(imageObj, cropRect.x, cropRect.y, cropRect.width, cropRect.height, 0, 0, cropRect.width, cropRect.height) + let ImgUrl = canvas.toDataURL() + + console.log(ImgUrl) + + // create html element with text + let x = document.createElement('div') + // set flex + x.style.display = 'flex' + // set element inner html + x.innerHTML = ` Extracting Text` + + Toastify({ + node: x, + duration: 999999, + newWindow: true, + close: false, + gravity: settings.settings.notification_gravity, // `top` or `bottom` + position: settings.settings.notification_position, // `left`, `center` or `right` + stopOnFocus: true, // Prevents dismissing of toast on hover + style: { + color: '#ffffff', + background: '#000000' + } + }).showToast() + + // tesseract to ocr + Tesseract.recognize(ImgUrl, selectedLang, { logger: m => console.log(m) }).then(({ data: { text } }) => { + // remove all toasts + let toastifyElems = document.querySelectorAll('.toastify') + toastifyElems.forEach(element => { + element.remove() + }) + + let ocrResElem = document.querySelector('#ocr-textarea') + if (ocrResElem) { + // if exists, then update + ocrResElem.innerHTML = text + } else { + // create new winbox + + document.querySelector('#ocr-preview').remove() + document.querySelector('#ocr-settings').remove() + + let ocrResultBox = new WinBox('Result', { + id: 'ocr-result-box', + class: WINBOX_CLASSES, + index: 9999, + width: '500px', + height: '320px', + top: '10px', + bottom: '10px', + right: '10px', + left: '10px', + x: 'center', + y: 'center', + + background: 'rgba(0,0,0,0.9)', + html: `
-
`, - }); - - ocrResultBox.show(); - - // when btn-extract-text clicked - document.getElementById('btn-copytext').addEventListener('click', function () { - showNotification('📋 Copied to clipboard', '#ffffff', '#000000', settings); - copyToClipboard(document.querySelector('#ocr-textarea').value); - }); - - } - }) - } - - - }); - try { +
` + }) - } catch (error) { - console.error(error); - } + ocrResultBox.show() - // // for each key in object ocr - // for (const [key, value] of Object.entries(ocrLangList)) { - // console.log(`${key}: ${value}`); - // } + // when btn-extract-text clicked + document.getElementById('btn-copytext').addEventListener('click', function () { + showNotification('📋 Copied to clipboard', '#ffffff', '#000000', settings) + copyToClipboard(document.querySelector('#ocr-textarea').value) + }) + } + }) + } + }) + try { + } catch (error) { + console.error(error) + } - } - }, - photopea: settings.settings.photopea && { - show: 1, - size: 'large', - click: function () { - - let currentUrl = window.location.href; - // create html element with text - let x = document.createElement("div"); - // set flex - x.style.display = "flex"; - // set element inner html - x.innerHTML = ` Opening in Photopea... Please wait`; - - Toastify({ - node: x, - duration: 999999, - newWindow: true, - close: false, - gravity: settings.settings.notification_gravity, // `top` or `bottom` - position: settings.settings.notification_position, // `left`, `center` or `right` - stopOnFocus: true, // Prevents dismissing of toast on hover - style: { - color: '#ffffff', - background: '#000000', - }, - }).showToast(); - - - // upload image to imgbb - // NB: expiration time is 60 seconds - fetch(`https://api.imgbb.com/1/upload?expiration=60&key=${IMGBB_TOKEN}&image=${encodeURIComponent(currentUrl)}`) - - .then(res => res.json()) - .then((res) => { - - const uri = '{ "files" : [ "' + res.data.image.url + '" ] }'; - const encoded = encodeURI(uri); - const urlEncoded = 'https://www.photopea.com/#' + encoded; - // remove toast - let toastifyElems = document.querySelectorAll('.toastify'); - toastifyElems.forEach(element => { - element.remove() - }); - - window.open(urlEncoded, '_blank').focus(); - - showNotification(`📂 Image opened in Photopea successfully`, '#ffffff', '#000000', settings); - }); - } - }, - tineye: settings.settings.tineye && { - show: 1, - size: 'large', - click: function () { - - - // toastify - let x = document.createElement("div"); - // set flex - x.style.display = "flex"; - // set element inner html - x.innerHTML = ` Opening in TinEye... Please wait`; - - Toastify({ - node: x, - duration: 1000, - newWindow: true, - close: false, - gravity: settings.settings.notification_gravity, // `top` or `bottom` - position: settings.settings.notification_position, // `left`, `center` or `right` - stopOnFocus: true, // Prevents dismissing of toast on hover - style: { - color: '#ffffff', - background: '#000000', - }, - }).showToast(); - - setTimeout(function () { - let currentUrl = encodeURIComponent(window.location.href); - let action_url = 'http://tineye.com/search?url=' + currentUrl; - window.open(action_url, '_blank').focus(); - }, 1000); - } - }, - qr: settings.settings.qr && { - show: 1, - size: 'large', - click: function () { - - // show loading toast - let x = document.createElement("div"); - // set flex - x.style.display = "flex"; - // set element inner html - x.innerHTML = ` Scanning QR code... Please wait`; - - Toastify({ - node: x, - duration: 9999, - newWindow: true, - close: false, - gravity: settings.settings.notification_gravity, // `top` or `bottom` - position: settings.settings.notification_position, // `left`, `center` or `right` - stopOnFocus: true, // Prevents dismissing of toast on hover - style: { - color: '#ffffff', - background: '#000000', - }, - }).showToast(); - - // remove loading toast - setTimeout(function () { - let toastifyElems = document.querySelectorAll('.toastify'); - toastifyElems.forEach(element => { - element.remove() - }); - - qrcode.callback = function (res) { - if (res instanceof Error) { - showNotification(`❌ No QR code found.`, '#ffffff', '#000000', settings); - } else { - //alert(res); - // show winbox - - - let ocrResultBox = new WinBox("QR Code Result", { - id: 'ocr-result-box', - class: WINBOX_CLASSES, - index: 9999, - width: '500px', - height: '165px', - top: '10px', - bottom: '10px', - right: '10px', - left: '10px', - x: "center", - y: "center", - background: "rgba(0,0,0,0.9)", - html: ` + // // for each key in object ocr + // for (const [key, value] of Object.entries(ocrLangList)) { + // console.log(`${key}: ${value}`); + // } + } + }, + photopea: settings.settings.photopea && { + show: 1, + size: 'large', + click: function () { + let currentUrl = window.location.href + // create html element with text + let x = document.createElement('div') + // set flex + x.style.display = 'flex' + // set element inner html + x.innerHTML = ` Opening in Photopea... Please wait` + + Toastify({ + node: x, + duration: 999999, + newWindow: true, + close: false, + gravity: settings.settings.notification_gravity, // `top` or `bottom` + position: settings.settings.notification_position, // `left`, `center` or `right` + stopOnFocus: true, // Prevents dismissing of toast on hover + style: { + color: '#ffffff', + background: '#000000' + } + }).showToast() + + // upload image to imgbb + // NB: expiration time is 60 seconds + fetch(`https://api.imgbb.com/1/upload?expiration=60&key=${IMGBB_TOKEN}&image=${encodeURIComponent(currentUrl)}`) + .then(res => res.json()) + .then(res => { + const uri = '{ "files" : [ "' + res.data.image.url + '" ] }' + const encoded = encodeURI(uri) + const urlEncoded = 'https://www.photopea.com/#' + encoded + // remove toast + let toastifyElems = document.querySelectorAll('.toastify') + toastifyElems.forEach(element => { + element.remove() + }) + + window.open(urlEncoded, '_blank').focus() + + showNotification(`📂 Image opened in Photopea successfully`, '#ffffff', '#000000', settings) + }) + } + }, + tineye: settings.settings.tineye && { + show: 1, + size: 'large', + click: function () { + // toastify + let x = document.createElement('div') + // set flex + x.style.display = 'flex' + // set element inner html + x.innerHTML = ` Opening in TinEye... Please wait` + + Toastify({ + node: x, + duration: 1000, + newWindow: true, + close: false, + gravity: settings.settings.notification_gravity, // `top` or `bottom` + position: settings.settings.notification_position, // `left`, `center` or `right` + stopOnFocus: true, // Prevents dismissing of toast on hover + style: { + color: '#ffffff', + background: '#000000' + } + }).showToast() + + setTimeout(function () { + let currentUrl = encodeURIComponent(window.location.href) + let action_url = 'http://tineye.com/search?url=' + currentUrl + window.open(action_url, '_blank').focus() + }, 1000) + } + }, + qr: settings.settings.qr && { + show: 1, + size: 'large', + click: function () { + // show loading toast + let x = document.createElement('div') + // set flex + x.style.display = 'flex' + // set element inner html + x.innerHTML = ` Scanning QR code... Please wait` + + Toastify({ + node: x, + duration: 9999, + newWindow: true, + close: false, + gravity: settings.settings.notification_gravity, // `top` or `bottom` + position: settings.settings.notification_position, // `left`, `center` or `right` + stopOnFocus: true, // Prevents dismissing of toast on hover + style: { + color: '#ffffff', + background: '#000000' + } + }).showToast() + + // remove loading toast + setTimeout(function () { + let toastifyElems = document.querySelectorAll('.toastify') + toastifyElems.forEach(element => { + element.remove() + }) + + qrcode.callback = function (res) { + if (res instanceof Error) { + showNotification(`❌ No QR code found.`, '#ffffff', '#000000', settings) + } else { + //alert(res); + // show winbox + + let ocrResultBox = new WinBox('QR Code Result', { + id: 'ocr-result-box', + class: WINBOX_CLASSES, + index: 9999, + width: '500px', + height: '165px', + top: '10px', + bottom: '10px', + right: '10px', + left: '10px', + x: 'center', + y: 'center', + background: 'rgba(0,0,0,0.9)', + html: `
-
`, - }); - - ocrResultBox.show(); - - // when btn-extract-text clicked - document.getElementById('btn-copytext').addEventListener('click', function () { - showNotification('📋 Copied to clipboard', '#ffffff', '#000000', settings); - copyToClipboard(document.querySelector('#qr-textarea').value); - }); - - - } - }; - let b64Img = getBase64Image(viewer.image); - qrcode.decode(b64Img); - - }, 500); - - - } - }, - help: settings.settings.help && { - show: 1, - size: 'large', - click: function () { - - if (!IS_HELP_OPEN) { - IS_HELP_OPEN = true; - - try { - new WinBox("Help", { - class: WINBOX_CLASSES, - index: 9999, - x: "center", - y: "center", - top: '10px', - bottom: '10px', - right: '10px', - left: '10px', - width: '700px', - height: '423px', - background: "rgba(0,0,0,0.9)", - url: "https://www.youtube-nocookie.com/embed/3p7Jrdx2jOc?autoplay=1&color=white&controls=0&disablekb=1&loop=1&modestbranding=1&rel=0&mute=1", - onclose: function () { - IS_HELP_OPEN = false; - } - }) - - - new WinBox("Shortcuts", { - class: WINBOX_CLASSES, - index: 9999, - x: "right", - y: "center", - top: '10px', - bottom: '10px', - right: '10px', - left: '10px', - width: '300px', - height: '450px', - background: "rgba(0,0,0,0.9)", - url: chrome.runtime.getURL('pages/shortcuts.html'), - onclose: function () { - IS_HELP_OPEN = false; - } - }); - } catch (error) { - console.error(error); - } - } - - } - }, - settings: settings.settings.settings && { - show: 1, - size: 'large', - click: function () { - // open winbox - try { - new WinBox("Settings", { - class: WINBOX_CLASSES, - index: 9999, - x: "center", - y: "center", - top: '10px', - bottom: '10px', - right: '10px', - left: '10px', - width: '350px', - height: '400px', - background: "rgba(0,0,0,0.9)", - url: chrome.runtime.getURL('pages/settings.html'), - }) - } catch (error) { - console.error(error); - } - } - }, - about: settings.settings.about && { - show: 1, - size: 'large', - click: function () { - try { - new WinBox("About", { - class: WINBOX_CLASSES, - index: 9999, - x: "center", - y: "center", - width: '700px', - height: '500px', - background: "rgba(0,0,0,0.9)", - url: chrome.runtime.getURL('pages/about.html'), - }); - } catch (error) { - console.error(error); - } - } - }, - exit: settings.settings.exit && { - show: 1, - size: 'large', - click: function () { - let url = window.location.href; - viewer.destroy(); - document.querySelector('.blurry-bg').remove(); - document.querySelector('img').style.display = 'block'; - document.querySelectorAll('.winbox').forEach(function (el) { - el.remove(); - }); - // remove all style tags - let styleTags = document.querySelectorAll('style'); - styleTags.forEach(function (el) { - el.remove(); - }); - document.querySelector('img').src = url; - } - - }, - more: { - show: 1, - size: 'large', - click: function () { - - // get all viewer buttons - let viewerButtons = document.querySelectorAll('div.viewer-toolbar > ul > li'); - - let btnsExceptMore = Array.prototype.slice.call(viewerButtons).filter(function (el) { - return !el.classList.contains('viewer-more'); - }) - - btnsExceptMore.forEach(btn => { - // toggle display of each button - - - let cssObj = window.getComputedStyle(btn, null); - let display = cssObj.getPropertyValue("display"); - - if (display === 'none') { - btn.style.display = 'list-item'; - btn.style.opacity = 1; - // append class - btn.classList.add('fade-in-right'); - } - else { - btn.style.display = 'none'; - btn.style.opacity = 0; - - } - - }) - } - } - - }, - ready() { - - - // hide all at start - if (settings.settings.hide_all_at_start) { - - // get all viewer buttons - let viewerButtons = document.querySelectorAll('div.viewer-toolbar > ul > li'); - - let btnsExceptMore = Array.prototype.slice.call(viewerButtons).filter(function (el) { - return !el.classList.contains('viewer-more'); - }) - - btnsExceptMore.forEach(btn => { - // toggle display of each button - - - let cssObj = window.getComputedStyle(btn, null); - let display = cssObj.getPropertyValue("display"); - - if (display === 'none') { - btn.style.display = 'list-item'; - btn.style.opacity = 1; - // append class - btn.classList.add('fade-in-right'); - } - else { - btn.style.display = 'none'; - btn.style.opacity = 0; - - } - - }) +
` + }) + ocrResultBox.show() + // when btn-extract-text clicked + document.getElementById('btn-copytext').addEventListener('click', function () { + showNotification('📋 Copied to clipboard', '#ffffff', '#000000', settings) + copyToClipboard(document.querySelector('#qr-textarea').value) + }) } - - - setTimeout(() => { - if (settings.settings.toolbar_position === 'top') { - viewer.move(0, 50); - } - }, 100) + } + let b64Img = getBase64Image(viewer.image) + qrcode.decode(b64Img) + }, 500) + } + }, + help: settings.settings.help && { + show: 1, + size: 'large', + click: function () { + if (!IS_HELP_OPEN) { + IS_HELP_OPEN = true + + try { + new WinBox('Help', { + class: WINBOX_CLASSES, + index: 9999, + x: 'center', + y: 'center', + top: '10px', + bottom: '10px', + right: '10px', + left: '10px', + width: '700px', + height: '423px', + background: 'rgba(0,0,0,0.9)', + url: 'https://www.youtube-nocookie.com/embed/3p7Jrdx2jOc?autoplay=1&color=white&controls=0&disablekb=1&loop=1&modestbranding=1&rel=0&mute=1', + onclose: function () { + IS_HELP_OPEN = false + } + }) + + new WinBox('Shortcuts', { + class: WINBOX_CLASSES, + index: 9999, + x: 'right', + y: 'center', + top: '10px', + bottom: '10px', + right: '10px', + left: '10px', + width: '300px', + height: '450px', + background: 'rgba(0,0,0,0.9)', + url: chrome.runtime.getURL('pages/shortcuts.html'), + onclose: function () { + IS_HELP_OPEN = false + } + }) + } catch (error) { + console.error(error) + } } + } + }, + settings: settings.settings.settings && { + show: 1, + size: 'large', + click: function () { + // open winbox + try { + new WinBox('Settings', { + class: WINBOX_CLASSES, + index: 9999, + x: 'center', + y: 'center', + top: '10px', + bottom: '10px', + right: '10px', + left: '10px', + width: '350px', + height: '400px', + background: 'rgba(0,0,0,0.9)', + url: chrome.runtime.getURL('pages/settings.html') + }) + } catch (error) { + console.error(error) + } + } + }, + about: settings.settings.about && { + show: 1, + size: 'large', + click: function () { + try { + new WinBox('About', { + class: WINBOX_CLASSES, + index: 9999, + x: 'center', + y: 'center', + width: '700px', + height: '500px', + background: 'rgba(0,0,0,0.9)', + url: chrome.runtime.getURL('pages/about.html') + }) + } catch (error) { + console.error(error) + } + } + }, + exit: settings.settings.exit && { + show: 1, + size: 'large', + click: function () { + let url = window.location.href + viewer.destroy() + document.querySelector('.blurry-bg').remove() + document.querySelector('img').style.display = 'block' + document.querySelectorAll('.winbox').forEach(function (el) { + el.remove() + }) + // remove all style tags + let styleTags = document.querySelectorAll('style') + styleTags.forEach(function (el) { + el.remove() + }) + document.querySelector('img').src = url + } + }, + more: { + show: 1, + size: 'large', + click: function () { + // get all viewer buttons + let viewerButtons = document.querySelectorAll('div.viewer-toolbar > ul > li') + + let btnsExceptMore = Array.prototype.slice.call(viewerButtons).filter(function (el) { + return !el.classList.contains('viewer-more') + }) + + btnsExceptMore.forEach(btn => { + // toggle display of each button + + let cssObj = window.getComputedStyle(btn, null) + let display = cssObj.getPropertyValue('display') + + if (display === 'none') { + btn.style.display = 'list-item' + btn.style.opacity = 1 + // append class + btn.classList.add('fade-in-right') + } else { + btn.style.display = 'none' + btn.style.opacity = 0 + } + }) + } + } + }, + ready() { + // hide all at start + if (settings.settings.hide_all_at_start) { + // get all viewer buttons + let viewerButtons = document.querySelectorAll('div.viewer-toolbar > ul > li') + + let btnsExceptMore = Array.prototype.slice.call(viewerButtons).filter(function (el) { + return !el.classList.contains('viewer-more') + }) + + btnsExceptMore.forEach(btn => { + // toggle display of each button + + let cssObj = window.getComputedStyle(btn, null) + let display = cssObj.getPropertyValue('display') + + if (display === 'none') { + btn.style.display = 'list-item' + btn.style.opacity = 1 + // append class + btn.classList.add('fade-in-right') + } else { + btn.style.display = 'none' + btn.style.opacity = 0 + } + }) + } - }); - - + setTimeout(() => { + if (settings.settings.toolbar_position === 'top') { + viewer.move(0, 50) + } + }, 100) + } + }) - let lightTheme = ` + let lightTheme = ` transition: all 0.5s ease; background-image: none; background-color: #ffffff; @@ -1538,9 +1416,9 @@ function init(settings) { width: 100vw; height: 100vh; transform: scale(1.3); - `; + ` - let darktheme = ` + let darktheme = ` transition: all 0.5s ease; background-image: none; background-color: #0e1217; @@ -1556,7 +1434,7 @@ function init(settings) { opacity: 0; ` - let blurrytheme = ` + let blurrytheme = ` transition: none; background-image: url(${imgElement.src}); background-color: none; @@ -1572,18 +1450,17 @@ function init(settings) { opacity: 1; ` - let currentTheme = (bg) => { - if (bg === 'light') { - return lightTheme; - } else if (bg === 'dark') { - return darktheme; - } - return blurrytheme; - } - + let currentTheme = bg => { + if (bg === 'light') { + return lightTheme + } else if (bg === 'dark') { + return darktheme + } + return blurrytheme + } - // inject css - injectCSS(` + // inject css + injectCSS(` .blurry-bg { ${currentTheme(BACKGROUND_TYPE)} } @@ -1603,60 +1480,53 @@ function init(settings) { display: none } .viewer-footer { - bottom: ${(settings.settings.toolbar_position) === 'bottom' ? '0px' : 'unset'} !important; - top: ${(settings.settings.toolbar_position) === 'top' ? '10px' : 'unset'} !important; + bottom: ${settings.settings.toolbar_position === 'bottom' ? '0px' : 'unset'} !important; + top: ${settings.settings.toolbar_position === 'top' ? '10px' : 'unset'} !important; } - `); - - - - // show the viewer - viewer.show(); - - - - setTippyText(tippyData); - - } - else { - // No img element, then... maybe it's a svg ? - // let svgElement = document.getElementsByTagName('svg')[0]; // get svg element - // if (svgElement) { - // // let base64 = svgToBase64(svgElement); - // // redirect to svg viewer - - // } - // else { - // // I don't know what it is, and I don't care about it - // } - } + `) + + // show the viewer + viewer.show() + + setTippyText(tippyData) + } else { + // No img element, then... maybe it's a svg ? + // let svgElement = document.getElementsByTagName('svg')[0]; // get svg element + // if (svgElement) { + // // let base64 = svgToBase64(svgElement); + // // redirect to svg viewer + // } + // else { + // // I don't know what it is, and I don't care about it + // } + } } /** * Helper function - converts an svg element to a base64 string * @param {svgElement} svgElement the svg element to convert - * @returns + * @returns */ function svgToBase64(svgElement) { - let svgString = new XMLSerializer().serializeToString(svgElement); - let decoded = unescape(encodeURIComponent(svgString)); - let base64 = btoa(decoded) - return `data:image/svg+xml;base64,${base64}`; + let svgString = new XMLSerializer().serializeToString(svgElement) + let decoded = unescape(encodeURIComponent(svgString)) + let base64 = btoa(decoded) + return `data:image/svg+xml;base64,${base64}` } /** * Injects css into the page * @param {string} css string to inject - * @returns + * @returns */ function injectCSS(css) { - let head = document.getElementsByTagName('head')[0]; - if (!head) { - return; - } - let style = document.createElement('style'); - style.innerHTML = DOMPurify.sanitize(css); - head.appendChild(style); + let head = document.getElementsByTagName('head')[0] + if (!head) { + return + } + let style = document.createElement('style') + style.innerHTML = DOMPurify.sanitize(css) + head.appendChild(style) } /** @@ -1664,20 +1534,17 @@ function injectCSS(css) { * @param {*} arrBtns array Of Buttons */ function setTippyText(arrBtns) { - - window.tippyInstances = []; - - - arrBtns.forEach(function (item) { - let instances = tippy(`#viewer0 > div.viewer-footer > div.viewer-toolbar > ul > li.viewer-${item.type}.viewer-large`, { - content: item.text, - inertia: true, - animation: 'scale', - theme: 'dark', - }) - window.tippyInstances = tippyInstances.concat(instances); - }); - + window.tippyInstances = [] + + arrBtns.forEach(function (item) { + let instances = tippy(`#viewer0 > div.viewer-footer > div.viewer-toolbar > ul > li.viewer-${item.type}.viewer-large`, { + content: item.text, + inertia: true, + animation: 'scale', + theme: 'dark' + }) + window.tippyInstances = tippyInstances.concat(instances) + }) } /** @@ -1685,245 +1552,225 @@ function setTippyText(arrBtns) { * @param {HTMLElement} image Viewer Image */ function download(image) { - const a = document.createElement('a'); - a.href = image.src; - a.download = image.alt; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); + const a = document.createElement('a') + a.href = image.src + a.download = image.alt + document.body.appendChild(a) + a.click() + document.body.removeChild(a) } /** - * - * @param {viewer} viewer - * @param {string} url - * @param {*} width - * @param {*} height + * + * @param {viewer} viewer + * @param {string} url + * @param {*} width + * @param {*} height */ function crop(v, url, width, height) { - - // create new winbox - let winbox = new WinBox("Crop Image", { - id: "winbox-crop-image", - class: WINBOX_CLASSES, - - width: width + 7, - // height + 10% - height: height + 40 + 36, - x: "center", - y: "center", - index: 9999, - background: "rgba(0,0,0,0.9)", - html: ` + // create new winbox + let winbox = new WinBox('Crop Image', { + id: 'winbox-crop-image', + class: WINBOX_CLASSES, + + width: width + 7, + // height + 10% + height: height + 40 + 36, + x: 'center', + y: 'center', + index: 9999, + background: 'rgba(0,0,0,0.9)', + html: `
`, - onclose: function () { - // reset viewer zoom - // v.zoom(0.5); - IS_CROP_OPEN = false; - } - }); - - - - - let imgCropper = tinycrop.create({ - parent: '#parent-crop', - image: url, - bounds: { - width: width, - height: height - }, - backgroundColors: ['#fff', '#f3f3f3'], - selection: { - color: '#212121CC', - activeColor: '#ff0000CC', - minWidth: 10, - minHeight: 10, - x: v.image.naturalWidth / 2 - width / 2, - y: v.image.naturalHeight / 2 - height / 2, - width: width, - height: height - }, - onInit: () => { console.log('Initialised') } - }); - - let region; // contains the cropped region - imgCropper.on('change', (r) => { - console.log('change', r); - region = r; - }); - - // const image = document.getElementById('crop-img'); - - - setTimeout(function () { - // get crop btn and add event listener - let cropBtn = document.getElementById('btn-crop-img'); - - cropBtn.addEventListener('click', function () { - - - const cropRect = region; - const canvas = document.createElement("canvas"); - const context = canvas.getContext("2d"); - const imageObj = new Image(); - canvas.width = cropRect.width; - canvas.height = cropRect.height; - imageObj.src = url; - imageObj.onload = function () { - context.drawImage(imageObj, cropRect.x, cropRect.y, cropRect.width, cropRect.height, 0, 0, cropRect.width, cropRect.height); - let ImgUrl = canvas.toDataURL(); - v.image.src = ImgUrl; - - switch (BACKGROUND_TYPE) { - case 'blurred': - injectCSS(` + onclose: function () { + // reset viewer zoom + // v.zoom(0.5); + IS_CROP_OPEN = false + } + }) + + let imgCropper = tinycrop.create({ + parent: '#parent-crop', + image: url, + bounds: { + width: width, + height: height + }, + backgroundColors: ['#fff', '#f3f3f3'], + selection: { + color: '#212121CC', + activeColor: '#ff0000CC', + minWidth: 10, + minHeight: 10, + x: v.image.naturalWidth / 2 - width / 2, + y: v.image.naturalHeight / 2 - height / 2, + width: width, + height: height + }, + onInit: () => { + console.log('Initialised') + } + }) + + let region // contains the cropped region + imgCropper.on('change', r => { + console.log('change', r) + region = r + }) + + // const image = document.getElementById('crop-img'); + + setTimeout(function () { + // get crop btn and add event listener + let cropBtn = document.getElementById('btn-crop-img') + + cropBtn.addEventListener('click', function () { + const cropRect = region + const canvas = document.createElement('canvas') + const context = canvas.getContext('2d') + const imageObj = new Image() + canvas.width = cropRect.width + canvas.height = cropRect.height + imageObj.src = url + imageObj.onload = function () { + context.drawImage(imageObj, cropRect.x, cropRect.y, cropRect.width, cropRect.height, 0, 0, cropRect.width, cropRect.height) + let ImgUrl = canvas.toDataURL() + v.image.src = ImgUrl + + switch (BACKGROUND_TYPE) { + case 'blurred': + injectCSS(` .blurry-bg { background-image: url("${ImgUrl}"); - }`); - break; - case 'light': - break; - case 'dark': - break; - default: - break; - } - - - setTimeout(function () { - window.dispatchEvent(new Event('resize')); - IS_CROP_OPEN = false; - winbox.close(); - }, 100); - - }; - - - - // image.addEventListener('load', () => { - - - - // console.log(image) - // context.drawImage( - // //croppr.imageEl, - // v.element, - // cropRect.x, - // cropRect.y, - // cropRect.width, - // cropRect.height, - // 0, - // 0, - // canvas.width, - // canvas.height, - // ); - // }); - - // - - - - - //v.image.src = ImgUrl; - - // switch (BACKGROUND_TYPE) { - // case 'blurred': - // injectCSS(` - // .blurry-bg { - // background-image: url("${ImgUrl}"); - // }`); - // break; - // case 'light': - // break; - // case 'dark': - // break; - // default: - // break; - // } - - // setTimeout(function () { - // v.zoom(0.5); - // window.dispatchEvent(new Event('resize')); - // }, 100); - - // //showNotification("Image cropped successfully", '#ffffff', '#000000', settings) - // IS_CROP_OPEN = false; - // winbox.close(); - - }); - }, 100); + }`) + break + case 'light': + break + case 'dark': + break + default: + break + } + setTimeout(function () { + window.dispatchEvent(new Event('resize')) + IS_CROP_OPEN = false + winbox.close() + }, 100) + } + + // image.addEventListener('load', () => { + + // console.log(image) + // context.drawImage( + // //croppr.imageEl, + // v.element, + // cropRect.x, + // cropRect.y, + // cropRect.width, + // cropRect.height, + // 0, + // 0, + // canvas.width, + // canvas.height, + // ); + // }); + + // + + //v.image.src = ImgUrl; + + // switch (BACKGROUND_TYPE) { + // case 'blurred': + // injectCSS(` + // .blurry-bg { + // background-image: url("${ImgUrl}"); + // }`); + // break; + // case 'light': + // break; + // case 'dark': + // break; + // default: + // break; + // } + + // setTimeout(function () { + // v.zoom(0.5); + // window.dispatchEvent(new Event('resize')); + // }, 100); + + // //showNotification("Image cropped successfully", '#ffffff', '#000000', settings) + // IS_CROP_OPEN = false; + // winbox.close(); + }) + }, 100) } // canvas function function useCanvas(el, image, callback) { - el.width = image.width; // img width - el.height = image.height; // img height - // draw image in canvas tag - el.getContext('2d').drawImage(image, 0, 0, image.width, image.height); - return callback(); + el.width = image.width // img width + el.height = image.height // img height + // draw image in canvas tag + el.getContext('2d').drawImage(image, 0, 0, image.width, image.height) + return callback() } function componentToHex(c) { - let hex = c.toString(16); - return hex.length == 1 ? "0" + hex : hex; + let hex = c.toString(16) + return hex.length == 1 ? '0' + hex : hex } function rgbToHex(r, g, b) { - return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b); + return '#' + componentToHex(r) + componentToHex(g) + componentToHex(b) } function findPos(obj) { - let curleft = 0, curtop = 0; - if (obj.offsetParent) { - do { - curleft += obj.offsetLeft; - curtop += obj.offsetTop; - } while (obj = obj.offsetParent); - return { x: curleft, y: curtop }; - } - return undefined; + let curleft = 0, + curtop = 0 + if (obj.offsetParent) { + do { + curleft += obj.offsetLeft + curtop += obj.offsetTop + } while ((obj = obj.offsetParent)) + return { x: curleft, y: curtop } + } + return undefined } function resetColorPicker(winboxPicker, v) { - //console.log(e); + //console.log(e); } const handleImageClickOnPicker = (e, v, canvas, pickr, x, y, settings) => { - - if (e.offsetX) { - x = e.offsetX; - y = e.offsetY; - } - - - console.log(settings); - - useCanvas(canvas, v.image, () => { - // get image data - let p = canvas.getContext('2d').getImageData(x, y, 1, 1).data; - // show info - pickr.setColor(rgbToHex(p[0], p[1], p[2])); - copyToClipboard(rgbToHex(p[0], p[1], p[2])); - showNotification(`${rgbToHex(p[0], p[1], p[2]).toUpperCase()} copied to clipboard`, getColorByBgColor(rgbToHex(p[0], p[1], p[2])), rgbToHex(p[0], p[1], p[2]), settings); - }); - + if (e.offsetX) { + x = e.offsetX + y = e.offsetY + } + + console.log(settings) + + useCanvas(canvas, v.image, () => { + // get image data + let p = canvas.getContext('2d').getImageData(x, y, 1, 1).data + // show info + pickr.setColor(rgbToHex(p[0], p[1], p[2])) + copyToClipboard(rgbToHex(p[0], p[1], p[2])) + showNotification(`${rgbToHex(p[0], p[1], p[2]).toUpperCase()} copied to clipboard`, getColorByBgColor(rgbToHex(p[0], p[1], p[2])), rgbToHex(p[0], p[1], p[2]), settings) + }) } const handleMouseMoveOnPicker = (e, v, canvas, pickr, x, y) => { - - if (e.offsetX) { - x = e.offsetX; - y = e.offsetY; - } - useCanvas(canvas, v.image, function () { - // get image data - let p = canvas.getContext('2d').getImageData(x, y, 1, 1).data; - pickr.setColor(rgbToHex(p[0], p[1], p[2])); - }); - + if (e.offsetX) { + x = e.offsetX + y = e.offsetY + } + useCanvas(canvas, v.image, function () { + // get image data + let p = canvas.getContext('2d').getImageData(x, y, 1, 1).data + pickr.setColor(rgbToHex(p[0], p[1], p[2])) + }) } /** @@ -1932,8 +1779,10 @@ const handleMouseMoveOnPicker = (e, v, canvas, pickr, x, y) => { * @returns {string} */ function getColorByBgColor(bgColor) { - if (!bgColor) { return ''; } - return (parseInt(bgColor.replace('#', ''), 16) > 0xffffff / 2) ? '#000' : '#fff'; + if (!bgColor) { + return '' + } + return parseInt(bgColor.replace('#', ''), 16) > 0xffffff / 2 ? '#000' : '#fff' } /** @@ -1941,60 +1790,57 @@ function getColorByBgColor(bgColor) { * @param {string} str - string to copy */ function copyToClipboard(textToCopy) { - // navigator clipboard api needs a secure context (https) - if (navigator.clipboard && window.isSecureContext) { - // navigator clipboard api method' - return navigator.clipboard.writeText(textToCopy); - } else { - // text area method - let textArea = document.createElement("textarea"); - textArea.value = textToCopy; - // make the textarea out of viewport - textArea.style.position = "fixed"; - textArea.style.left = "-999999px"; - textArea.style.top = "-999999px"; - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - return new Promise((res, rej) => { - // here the magic happens - document.execCommand('copy') ? res() : rej(); - textArea.remove(); - }); - } + // navigator clipboard api needs a secure context (https) + if (navigator.clipboard && window.isSecureContext) { + // navigator clipboard api method' + return navigator.clipboard.writeText(textToCopy) + } else { + // text area method + let textArea = document.createElement('textarea') + textArea.value = textToCopy + // make the textarea out of viewport + textArea.style.position = 'fixed' + textArea.style.left = '-999999px' + textArea.style.top = '-999999px' + document.body.appendChild(textArea) + textArea.focus() + textArea.select() + return new Promise((res, rej) => { + // here the magic happens + document.execCommand('copy') ? res() : rej() + textArea.remove() + }) + } } - function printImage(image) { - let strb64 = getBase64Image(image) - printJS(strb64, 'image') + let strb64 = getBase64Image(image) + printJS(strb64, 'image') } /** * Convert image to base64 * @param {*} img Image element - * @returns + * @returns */ function getBase64Image(img) { - let canvas = document.createElement("canvas"); - canvas.width = img.naturalWidth; - canvas.height = img.naturalHeight; - let ctx = canvas.getContext("2d"); - ctx.drawImage(img, 0, 0); - return canvas.toDataURL(); + let canvas = document.createElement('canvas') + canvas.width = img.naturalWidth + canvas.height = img.naturalHeight + let ctx = canvas.getContext('2d') + ctx.drawImage(img, 0, 0) + return canvas.toDataURL() } - function changeTheme(imgsrc, settings) { - - let lightTheme = `background-image: url("data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-sun'%3E%3Ccircle cx='12' cy='12' r='5'%3E%3C/circle%3E%3Cline x1='12' y1='1' x2='12' y2='3'%3E%3C/line%3E%3Cline x1='12' y1='21' x2='12' y2='23'%3E%3C/line%3E%3Cline x1='4.22' y1='4.22' x2='5.64' y2='5.64'%3E%3C/line%3E%3Cline x1='18.36' y1='18.36' x2='19.78' y2='19.78'%3E%3C/line%3E%3Cline x1='1' y1='12' x2='3' y2='12'%3E%3C/line%3E%3Cline x1='21' y1='12' x2='23' y2='12'%3E%3C/line%3E%3Cline x1='4.22' y1='19.78' x2='5.64' y2='18.36'%3E%3C/line%3E%3Cline x1='18.36' y1='5.64' x2='19.78' y2='4.22'%3E%3C/line%3E%3C/svg%3E");` - let darkTheme = `background-image: url("data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-moon'%3E%3Cpath d='M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z'%3E%3C/path%3E%3C/svg%3E");` - let blurTheme = `background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-droplet'%3E%3Cpath d='M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z'%3E%3C/path%3E%3C/svg%3E"); `; - - switch (BACKGROUND_TYPE) { - case 'blurred': - showNotification('☀️ Light Background', '#000000', '#ffffff', settings); - injectCSS(` + let lightTheme = `background-image: url("data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-sun'%3E%3Ccircle cx='12' cy='12' r='5'%3E%3C/circle%3E%3Cline x1='12' y1='1' x2='12' y2='3'%3E%3C/line%3E%3Cline x1='12' y1='21' x2='12' y2='23'%3E%3C/line%3E%3Cline x1='4.22' y1='4.22' x2='5.64' y2='5.64'%3E%3C/line%3E%3Cline x1='18.36' y1='18.36' x2='19.78' y2='19.78'%3E%3C/line%3E%3Cline x1='1' y1='12' x2='3' y2='12'%3E%3C/line%3E%3Cline x1='21' y1='12' x2='23' y2='12'%3E%3C/line%3E%3Cline x1='4.22' y1='19.78' x2='5.64' y2='18.36'%3E%3C/line%3E%3Cline x1='18.36' y1='5.64' x2='19.78' y2='4.22'%3E%3C/line%3E%3C/svg%3E");` + let darkTheme = `background-image: url("data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-moon'%3E%3Cpath d='M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z'%3E%3C/path%3E%3C/svg%3E");` + let blurTheme = `background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-droplet'%3E%3Cpath d='M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z'%3E%3C/path%3E%3C/svg%3E"); ` + + switch (BACKGROUND_TYPE) { + case 'blurred': + showNotification('☀️ Light Background', '#000000', '#ffffff', settings) + injectCSS(` .viewer-theme { ${darkTheme} } @@ -2016,12 +1862,12 @@ function changeTheme(imgsrc, settings) { opacity: 0; } - `); - BACKGROUND_TYPE = 'light'; - break; - case 'light': - showNotification('🌑 Dark Background', '#ffffff', '#000000', settings); - injectCSS(` + `) + BACKGROUND_TYPE = 'light' + break + case 'light': + showNotification('🌑 Dark Background', '#ffffff', '#000000', settings) + injectCSS(` .viewer-theme { ${blurTheme} } @@ -2043,13 +1889,13 @@ function changeTheme(imgsrc, settings) { .blurry-bg:before { opacity: 0; } - `); - BACKGROUND_TYPE = 'dark'; - break; - case 'dark': - // change to blurred - showNotification('💧 Blurred Background', '#ffffff', '#404040', settings); - injectCSS(` + `) + BACKGROUND_TYPE = 'dark' + break + case 'dark': + // change to blurred + showNotification('💧 Blurred Background', '#ffffff', '#404040', settings) + injectCSS(` .viewer-theme { ${lightTheme} } @@ -2070,128 +1916,123 @@ function changeTheme(imgsrc, settings) { } .blurry-bg:before { opacity: 0.5; - }`); - BACKGROUND_TYPE = 'blurred'; - break; - } + }`) + BACKGROUND_TYPE = 'blurred' + break + } } - function showNotification(text, textColor, bgColor, settings) { - - Toastify({ - text: `${text}`, - duration: 3000, - newWindow: true, - close: false, - gravity: settings.settings.notification_gravity, // `top` or `bottom` - position: settings.settings.notification_position, // `left`, `center` or `right` - stopOnFocus: true, // Prevents dismissing of toast on hover - style: { - color: textColor, - background: bgColor, - } - }).showToast(); + Toastify({ + text: `${text}`, + duration: 3000, + newWindow: true, + close: false, + gravity: settings.settings.notification_gravity, // `top` or `bottom` + position: settings.settings.notification_position, // `left`, `center` or `right` + stopOnFocus: true, // Prevents dismissing of toast on hover + style: { + color: textColor, + background: bgColor + } + }).showToast() } - function jsonViewer(json, collapsible = false) { - let TEMPLATES = { - item: '
%KEY%
%VALUE%
', - itemCollapsible: '', - itemCollapsibleOpen: '' - }; - - function createItem(key, value, type) { - let element = TEMPLATES.item.replace('%KEY%', key); - - if (type == 'string') { - element = element.replace('%VALUE%', '"' + value + '"'); - } else { - element = element.replace('%VALUE%', value); - } + let TEMPLATES = { + item: '
%KEY%
%VALUE%
', + itemCollapsible: '', + itemCollapsibleOpen: '' + } - element = element.replace('%TYPE%', type); + function createItem(key, value, type) { + let element = TEMPLATES.item.replace('%KEY%', key) - return element; + if (type == 'string') { + element = element.replace('%VALUE%', '"' + value + '"') + } else { + element = element.replace('%VALUE%', value) } - function createCollapsibleItem(key, value, type, children) { - let tpl = 'itemCollapsible'; + element = element.replace('%TYPE%', type) - if (collapsible) { - tpl = 'itemCollapsibleOpen'; - } + return element + } - let element = TEMPLATES[tpl].replace('%KEY%', key); + function createCollapsibleItem(key, value, type, children) { + let tpl = 'itemCollapsible' - element = element.replace('%VALUE%', type); - element = element.replace('%TYPE%', type); - element = element.replace('%CHILDREN%', children); - - return element; + if (collapsible) { + tpl = 'itemCollapsibleOpen' } - function handleChildren(key, value, type) { - let html = ''; + let element = TEMPLATES[tpl].replace('%KEY%', key) - for (let item in value) { - let _key = item, - _val = value[item]; + element = element.replace('%VALUE%', type) + element = element.replace('%TYPE%', type) + element = element.replace('%CHILDREN%', children) - html += handleItem(_key, _val); - } + return element + } - return createCollapsibleItem(key, value, type, html); - } + function handleChildren(key, value, type) { + let html = '' - function handleItem(key, value) { - let type = typeof value; - - if (typeof value === 'object') { - return handleChildren(key, value, type); - } + for (let item in value) { + let _key = item, + _val = value[item] - return createItem(key, value, type); + html += handleItem(_key, _val) } - function parseObject(obj) { - let _result = '
'; + return createCollapsibleItem(key, value, type, html) + } - for (let item in obj) { - let key = item, - value = obj[item]; + function handleItem(key, value) { + let type = typeof value - _result += handleItem(key, value); - } - - _result += '
'; - - return _result; + if (typeof value === 'object') { + return handleChildren(key, value, type) } - return parseObject(json); -} + return createItem(key, value, type) + } + function parseObject(obj) { + let _result = '
' -// listen to messages from iframe -window.addEventListener('message', function (message) { - if (message.data.type == "settings") { - let user_settings = message.data.settings - // save using chrome.storage - chrome.storage.sync.set({ - settings: user_settings - }, function () { - // Notify that we saved. - showNotification('💾 Settings saved successfully', '#ffffff', '#000000', message.data); - setTimeout(() => { - // reload window after saving - window.location.reload(); + for (let item in obj) { + let key = item, + value = obj[item] - }, 1000) - }); + _result += handleItem(key, value) } -}); + _result += '
' + return _result + } + return parseObject(json) +} + +// listen to messages from iframe +window.addEventListener('message', function (message) { + if (message.data.type == 'settings') { + let user_settings = message.data.settings + // save using chrome.storage + chrome.storage.sync.set( + { + settings: user_settings + }, + function () { + // Notify that we saved. + showNotification('💾 Settings saved successfully', '#ffffff', '#000000', message.data) + setTimeout(() => { + // reload window after saving + window.location.reload() + }, 1000) + } + ) + } +}) diff --git a/manifest-firefox.json b/manifest-firefox.json index 4b6cceb..a0a9c02 100644 --- a/manifest-firefox.json +++ b/manifest-firefox.json @@ -1,6 +1,6 @@ { "name": "BetterViewer", - "version": "1.0.4", + "version": "1.0.5", "manifest_version": 2, "background": { "scripts": [ diff --git a/manifest.json b/manifest.json index 3230d7e..2050a68 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "name": "BetterViewer", - "version": "1.0.4", + "version": "1.0.5", "manifest_version": 2, "background": { "scripts": [ diff --git a/package.json b/package.json index 7e97d5d..05948fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "BetterViewer", - "version": "1.0.4", + "version": "1.0.5", "description": "A browser extension for better image viewing experience", "main": "background.js", "scripts": { diff --git a/pages/about.html b/pages/about.html index afbd50a..1c24d95 100644 --- a/pages/about.html +++ b/pages/about.html @@ -31,7 +31,8 @@

Let me know if you're using BetterViewer ! Also don't forget to give us a ⭐️

Contributors:
@bbbenji - @patrykdziurkowski + @patrykdziurkowski + @Metacor