From ec364adf0becdba7db9efc6cf41f6776e8964a34 Mon Sep 17 00:00:00 2001 From: Mark Magyarodi Date: Sat, 26 Nov 2022 16:20:36 +0100 Subject: [PATCH] standalone components --- .prettierrc | 4 ++ .vscode/settings.json | 3 ++ package-lock.json | 44 +++++++++++++++---- package.json | 4 +- .../src/lib/image-to-data-url.directive.ts | 39 ++++++++-------- .../src/lib/image-to-data-url.module.ts | 8 ---- .../ngx-image2dataurl/src/lib/interfaces.ts | 2 +- projects/ngx-image2dataurl/src/lib/utils.ts | 20 ++++----- projects/ngx-image2dataurl/src/public_api.ts | 1 - projects/ngx-image2dataurl/src/test.ts | 22 ---------- src/app/app.component.html | 5 +-- src/app/app.component.ts | 21 ++++++--- src/app/app.module.ts | 23 ---------- src/app/rotate-image-file-processor.ts | 37 ++++++++-------- src/environments/environment.prod.ts | 2 +- src/environments/environment.ts | 2 +- src/index.html | 15 ++++--- src/main.ts | 7 ++- src/polyfills.ts | 15 +++---- src/test.ts | 20 --------- 20 files changed, 129 insertions(+), 165 deletions(-) create mode 100644 .prettierrc create mode 100644 .vscode/settings.json delete mode 100644 projects/ngx-image2dataurl/src/lib/image-to-data-url.module.ts delete mode 100644 projects/ngx-image2dataurl/src/test.ts delete mode 100644 src/app/app.module.ts delete mode 100644 src/test.ts diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..6c70cb2 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "printWidth": 140, + "singleQuote": true +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cac0e10 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.formatOnSave": true +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 013c9db..1ce1d2e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7254,6 +7254,22 @@ } } }, + "node_modules/ng-packagr/node_modules/rollup": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.4.0.tgz", + "integrity": "sha512-4g8ZrEFK7UbDvy3JF+d5bLiC8UKkS3n/27/cnVeESwB1LVPl6MoPL32/6+SCQ1vHTp6Mvp2veIHtwELhi+uXEw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/nice-napi": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz", @@ -8914,16 +8930,16 @@ } }, "node_modules/rollup": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.4.0.tgz", - "integrity": "sha512-4g8ZrEFK7UbDvy3JF+d5bLiC8UKkS3n/27/cnVeESwB1LVPl6MoPL32/6+SCQ1vHTp6Mvp2veIHtwELhi+uXEw==", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, + "peer": true, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" + "node": ">=10.0.0" }, "optionalDependencies": { "fsevents": "~2.3.2" @@ -15925,6 +15941,17 @@ "rollup-plugin-sourcemaps": "^0.6.3", "rxjs": "^7.5.6", "sass": "^1.55.0" + }, + "dependencies": { + "rollup": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.4.0.tgz", + "integrity": "sha512-4g8ZrEFK7UbDvy3JF+d5bLiC8UKkS3n/27/cnVeESwB1LVPl6MoPL32/6+SCQ1vHTp6Mvp2veIHtwELhi+uXEw==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + } } }, "nice-napi": { @@ -17176,10 +17203,11 @@ } }, "rollup": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.4.0.tgz", - "integrity": "sha512-4g8ZrEFK7UbDvy3JF+d5bLiC8UKkS3n/27/cnVeESwB1LVPl6MoPL32/6+SCQ1vHTp6Mvp2veIHtwELhi+uXEw==", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "dev": true, + "peer": true, "requires": { "fsevents": "~2.3.2" } diff --git a/package.json b/package.json index 20fea4b..0ab0aa7 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "ng": "ng", "start": "ng serve", "build": "ng build", - "build:prod": "ng build --configuration production" + "watch": "ng build --watch --configuration development" }, "private": true, "dependencies": { @@ -38,4 +38,4 @@ "ts-node": "~10.9.0", "typescript": "~4.8.4" } -} \ No newline at end of file +} diff --git a/projects/ngx-image2dataurl/src/lib/image-to-data-url.directive.ts b/projects/ngx-image2dataurl/src/lib/image-to-data-url.directive.ts index b0b79a1..1f4f6c2 100644 --- a/projects/ngx-image2dataurl/src/lib/image-to-data-url.directive.ts +++ b/projects/ngx-image2dataurl/src/lib/image-to-data-url.directive.ts @@ -1,45 +1,51 @@ -import { Directive, EventEmitter, HostListener, Inject, InjectionToken, Input, OnChanges, Optional, Output, SimpleChanges } from '@angular/core'; +import { Directive, EventEmitter, HostListener, Inject, InjectionToken, Input, OnChanges, Optional, Output } from '@angular/core'; import { ImageFileProcessor, ImageResult, Options, ResizeOptions } from './interfaces'; import { fileToDataURL, getImageTypeFromDataUrl, resizeImage } from './utils'; - export const IMAGE_FILE_PROCESSOR = new InjectionToken('ImageFileProcessor'); @Directive({ - selector: 'input[type=file][imageToDataUrl]' + selector: 'input[type=file][imageToDataUrl]', + standalone: true, }) export class ImageToDataUrlDirective implements OnChanges { - @Output() imageSelected = new EventEmitter(); @Input('imageToDataUrl') options: Options = {}; - constructor(@Optional() @Inject(IMAGE_FILE_PROCESSOR) private imageFileProcessors: ImageFileProcessor[]) { + constructor( + @Optional() + @Inject(IMAGE_FILE_PROCESSOR) + private imageFileProcessors: ImageFileProcessor[] + ) { this.imageFileProcessors = imageFileProcessors || []; } - ngOnChanges(changes: SimpleChanges): void { + ngOnChanges() { if (!this.options) { this.options = {}; } if (this.options.allowedExtensions) { - this.options.allowedExtensions = this.options.allowedExtensions.map(ext => ext.toLowerCase()); + this.options.allowedExtensions = this.options.allowedExtensions.map((ext) => ext.toLowerCase()); } } @HostListener('change', ['$event']) - async readFiles(event) { - for (let file of event.target.files as File[]) { + async readFiles(event: Event) { + for (let file of Array.from((event.target as HTMLInputElement).files)) { const result: ImageResult = { file, - url: URL.createObjectURL(file) + url: URL.createObjectURL(file), }; let ext: string = file.name.split('.').pop(); ext = ext && ext.toLowerCase(); - if (ext && this.options.allowedExtensions - && this.options.allowedExtensions.length - && this.options.allowedExtensions.indexOf(ext) === -1) { + if ( + ext && + this.options.allowedExtensions && + this.options.allowedExtensions.length && + this.options.allowedExtensions.indexOf(ext) === -1 + ) { result.error = new Error('Extension Not Allowed'); } else { try { @@ -56,15 +62,12 @@ export class ImageToDataUrlDirective implements OnChanges { } } - private async resize(dataURL: string, options: ResizeOptions): Promise<{ dataURL: string, type: string }> { + private async resize(dataURL: string, options: ResizeOptions): Promise<{ dataURL: string; type: string }> { if (!options) return null; const resisedDataUrl = await resizeImage(dataURL, options); return { dataURL: resisedDataUrl, - type: getImageTypeFromDataUrl(resisedDataUrl) + type: getImageTypeFromDataUrl(resisedDataUrl), }; } - } - - diff --git a/projects/ngx-image2dataurl/src/lib/image-to-data-url.module.ts b/projects/ngx-image2dataurl/src/lib/image-to-data-url.module.ts deleted file mode 100644 index 299bbc7..0000000 --- a/projects/ngx-image2dataurl/src/lib/image-to-data-url.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { NgModule } from '@angular/core'; -import { ImageToDataUrlDirective } from './image-to-data-url.directive'; - -@NgModule({ - declarations: [ImageToDataUrlDirective], - exports: [ImageToDataUrlDirective] -}) -export class ImageToDataUrlModule { } diff --git a/projects/ngx-image2dataurl/src/lib/interfaces.ts b/projects/ngx-image2dataurl/src/lib/interfaces.ts index c314f9e..b612487 100644 --- a/projects/ngx-image2dataurl/src/lib/interfaces.ts +++ b/projects/ngx-image2dataurl/src/lib/interfaces.ts @@ -6,7 +6,7 @@ export interface ImageResult { resized?: { dataURL: string; type: string; - } + }; } export interface ResizeOptions { diff --git a/projects/ngx-image2dataurl/src/lib/utils.ts b/projects/ngx-image2dataurl/src/lib/utils.ts index 3fc0faf..bb1a4c9 100644 --- a/projects/ngx-image2dataurl/src/lib/utils.ts +++ b/projects/ngx-image2dataurl/src/lib/utils.ts @@ -9,14 +9,10 @@ export function createImageFromDataUrl(dataURL: string) { }); } -export async function resizeImage(dataURL: string, { - bgColor, - maxHeight, - maxWidth, - quality = 0.7, - type = getImageTypeFromDataUrl(dataURL) -}: ResizeOptions = {}) { - +export async function resizeImage( + dataURL: string, + { bgColor, maxHeight, maxWidth, quality = 0.7, type = getImageTypeFromDataUrl(dataURL) }: ResizeOptions = {} +) { const image = await createImageFromDataUrl(dataURL); if (!document) throw new Error('Work only in browser, document not defined'); @@ -26,12 +22,12 @@ export async function resizeImage(dataURL: string, { let width = image.width; if (width > maxWidth) { - height = Math.round(height * maxWidth / width); + height = Math.round((height * maxWidth) / width); width = maxWidth; } if (height > maxHeight) { - width = Math.round(width * maxHeight / height); + width = Math.round((width * maxHeight) / height); height = maxHeight; } @@ -39,7 +35,7 @@ export async function resizeImage(dataURL: string, { canvas.height = height; //draw image on canvas - const ctx = canvas.getContext("2d"); + const ctx = canvas.getContext('2d'); if (bgColor) { ctx.fillStyle = bgColor; @@ -65,5 +61,5 @@ export function fileToDataURL(file: File): Promise { const typeRE = /^data:([^,;]+)/; export function getImageTypeFromDataUrl(dataURL: string): string { let matches = dataURL.match(typeRE); - return matches && matches[1] || undefined; + return (matches && matches[1]) || undefined; } diff --git a/projects/ngx-image2dataurl/src/public_api.ts b/projects/ngx-image2dataurl/src/public_api.ts index 4ef47f0..2baae54 100644 --- a/projects/ngx-image2dataurl/src/public_api.ts +++ b/projects/ngx-image2dataurl/src/public_api.ts @@ -3,5 +3,4 @@ */ export * from './lib/interfaces'; export { createImageFromDataUrl, getImageTypeFromDataUrl } from './lib/utils'; -export * from './lib/image-to-data-url.module'; export * from './lib/image-to-data-url.directive'; diff --git a/projects/ngx-image2dataurl/src/test.ts b/projects/ngx-image2dataurl/src/test.ts deleted file mode 100644 index b1cc186..0000000 --- a/projects/ngx-image2dataurl/src/test.ts +++ /dev/null @@ -1,22 +0,0 @@ -// This file is required by karma.conf.js and loads recursively all the .spec and framework files - -import 'core-js/es7/reflect'; -import 'zone.js'; -import 'zone.js/testing'; -import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; - -declare const require: any; - -// First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); -// Then we find all the tests. -const context = require.context('./', true, /\.spec\.ts$/); -// And load the modules. -context.keys().map(context); diff --git a/src/app/app.component.html b/src/app/app.component.html index e82afbb..79e22df 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,3 +1,2 @@ -
- +
+ \ No newline at end of file diff --git a/src/app/app.component.ts b/src/app/app.component.ts index b9dabad..958cce6 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,10 +1,21 @@ +import { NgIf } from '@angular/common'; import { Component } from '@angular/core'; -import { ImageResult, Options } from "ngx-image2dataurl"; +import { ImageResult, ImageToDataUrlDirective, IMAGE_FILE_PROCESSOR, Options } from 'ngx-image2dataurl'; +import { RotateImageFileProcessor } from './rotate-image-file-processor'; @Component({ selector: 'app-root', + standalone: true, + imports: [ImageToDataUrlDirective, NgIf], + providers: [ + { + provide: IMAGE_FILE_PROCESSOR, + useClass: RotateImageFileProcessor, + multi: true, + }, + ], templateUrl: './app.component.html', - styleUrls: ['./app.component.css'] + styleUrls: ['./app.component.css'], }) export class AppComponent { src: string = null; @@ -13,13 +24,11 @@ export class AppComponent { maxHeight: 128, maxWidth: 128, }, - allowedExtensions: ['JPG', 'PnG'] + allowedExtensions: ['JPG', 'PnG'], }; selected(imageResult: ImageResult) { if (imageResult.error) alert(imageResult.error); - this.src = imageResult.resized - && imageResult.resized.dataURL - || imageResult.dataURL; + this.src = (imageResult.resized && imageResult.resized.dataURL) || imageResult.dataURL; } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts deleted file mode 100644 index e7f6826..0000000 --- a/src/app/app.module.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { ImageToDataUrlModule, IMAGE_FILE_PROCESSOR } from 'ngx-image2dataurl'; -import { AppComponent } from './app.component'; -import { RotateImageFileProcessor } from './rotate-image-file-processor'; - - -@NgModule({ - declarations: [ - AppComponent - ], - imports: [ - BrowserModule, - ImageToDataUrlModule - ], - providers: [ - { - provide: IMAGE_FILE_PROCESSOR, useClass: RotateImageFileProcessor, multi: true - } - ], - bootstrap: [AppComponent] -}) -export class AppModule { } diff --git a/src/app/rotate-image-file-processor.ts b/src/app/rotate-image-file-processor.ts index 90b1949..c1709a7 100644 --- a/src/app/rotate-image-file-processor.ts +++ b/src/app/rotate-image-file-processor.ts @@ -1,20 +1,19 @@ -import { createImageFromDataUrl, getImageTypeFromDataUrl, ImageFileProcessor } from "ngx-image2dataurl"; -import { Injectable } from "@angular/core"; - +import { createImageFromDataUrl, getImageTypeFromDataUrl, ImageFileProcessor } from 'ngx-image2dataurl'; +import { Injectable } from '@angular/core'; + @Injectable() -export class RotateImageFileProcessor implements ImageFileProcessor { - async process(dataURL: string): Promise { - const canvas = document.createElement('canvas'); - const image = await createImageFromDataUrl(dataURL); - canvas.width = image.height; - canvas.height = image.width; - const ctx = canvas.getContext("2d"); - //ctx.save(); - ctx.translate(canvas.width / 2, canvas.height / 2); - ctx.rotate(Math.PI / 2); - ctx.drawImage(image, -image.width / 2, -image.height / 2); - //ctx.restore(); - return canvas.toDataURL(getImageTypeFromDataUrl(dataURL)); - } - -} \ No newline at end of file +export class RotateImageFileProcessor implements ImageFileProcessor { + async process(dataURL: string): Promise { + const canvas = document.createElement('canvas'); + const image = await createImageFromDataUrl(dataURL); + canvas.width = image.height; + canvas.height = image.width; + const ctx = canvas.getContext('2d'); + //ctx.save(); + ctx.translate(canvas.width / 2, canvas.height / 2); + ctx.rotate(Math.PI / 2); + ctx.drawImage(image, -image.width / 2, -image.height / 2); + //ctx.restore(); + return canvas.toDataURL(getImageTypeFromDataUrl(dataURL)); + } +} diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 3612073..c966979 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -1,3 +1,3 @@ export const environment = { - production: true + production: true, }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 72cd639..85db3ca 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -3,7 +3,7 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, }; /* diff --git a/src/index.html b/src/index.html index 6d2e215..3914506 100644 --- a/src/index.html +++ b/src/index.html @@ -1,14 +1,17 @@ - + + - + NgxImage2dataurlApp - + - - + + + - + + \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 91ec6da..88710e6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,11 @@ import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { AppComponent } from './app/app.component'; -import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.log(err)); +bootstrapApplication(AppComponent).catch((err) => console.log(err)); diff --git a/src/polyfills.ts b/src/polyfills.ts index 3f98c22..761600d 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -1,16 +1,13 @@ - - - /** * By default, zone.js will patch all possible macroTask and DomEvents * user can disable parts of macroTask/DomEvents patch by setting following flags */ - // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame - // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick - // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames +// (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame +// (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick +// (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames - /* +/* * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js * with the following flag, it will bypass `zone.js` patch for IE/Edge */ @@ -19,9 +16,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js'; // Included with Angular CLI. - - +import 'zone.js'; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/src/test.ts b/src/test.ts deleted file mode 100644 index a6f15af..0000000 --- a/src/test.ts +++ /dev/null @@ -1,20 +0,0 @@ -// This file is required by karma.conf.js and loads recursively all the .spec and framework files - -import 'zone.js/testing'; -import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; - -declare const require: any; - -// First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); -// Then we find all the tests. -const context = require.context('./', true, /\.spec\.ts$/); -// And load the modules. -context.keys().map(context);