Skip to content

Commit

Permalink
Merge pull request #200 from stevermeister/paste-service
Browse files Browse the repository at this point in the history
make possible to filter content that is provided to editor (for example via copy-paste)
  • Loading branch information
stevermeister authored Feb 22, 2024
2 parents 9370930 + a9a49cd commit b0ec4ea
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 4 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ it's just an attribute directive for textarea:
Please check an example here
https://stackblitz.com/edit/ngx-wig-sample-plugins?file=src/app.ts


### Filtering/removing extra styles on paste

Please check an example here
https://stackblitz.com/edit/ngx-wig-sample-plugins?file=src/app.ts



## Development

To generate all `*.js`, `*.d.ts` and `*.metadata.json` files:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.0.0",
"scripts": {
"lib-build": "ng build ngx-wig",
"start": "(ng build ngx-wig --watch ) && sleep 10 && ng serve",
"start": "(ng build ngx-wig --watch ) & sleep 10 && ng serve",
"build": "ng build ngx-wig --configuration production",
"test": "ng test ngx-wig --browsers=ChromeHeadless --watch=false",
"lint": "ng lint ngx-wig",
Expand Down
2 changes: 1 addition & 1 deletion projects/ngx-wig/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ngx-wig",
"version": "17.0.0",
"version": "17.0.2",
"description": "Light-weight WYSIWYG Editor for Angular",
"keywords": [
"Angular",
Expand Down
1 change: 1 addition & 0 deletions projects/ngx-wig/src/lib/ngx-wig-component.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
class="nw-editor__res"
[attr.contenteditable]="!disabled"
[ngClass]="{ disabled: disabled}"
(paste)="onPaste($event)"
(focus)="hasFocus = true"
(blur)="onBlur()"
(input)="onContentChange(ngWigEditable.innerHTML)"><!--
Expand Down
31 changes: 31 additions & 0 deletions projects/ngx-wig/src/lib/ngx-wig-filter-styles.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { NgxWigFilterStylesService } from './ngx-wig-filter-styles.service';

describe('NgxWigFilterStylesService', () => {
let service: NgxWigFilterStylesService;

beforeEach(() => {
service = new NgxWigFilterStylesService();
});

it('should create an instance', () => {
expect(service).toBeTruthy();
});

it('should remove style attributes from HTML string', () => {
const htmlString = '<div style="color: red;">Hello, world!</div>';
const expectedOutput = '<div>Hello, world!</div>';
expect(service.filter(htmlString)).toEqual(expectedOutput);
});

it('should remove style elements from HTML string', () => {
const htmlString = '<style>.red { color: red; }</style><div>Hello, world!</div>';
const expectedOutput = '<div>Hello, world!</div>';
expect(service.filter(htmlString)).toEqual(expectedOutput);
});

it('should handle empty HTML string', () => {
const htmlString = '';
const expectedOutput = '';
expect(service.filter(htmlString)).toEqual(expectedOutput);
});
});
30 changes: 30 additions & 0 deletions projects/ngx-wig/src/lib/ngx-wig-filter-styles.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Injectable } from "@angular/core";

@Injectable({
providedIn: "root",
})
export class NgxWigFilterStylesService {
constructor() {}
public filter(htmlString: string): string {
// Parse the HTML string into a DOM object
const parser: DOMParser = new DOMParser();
const doc: Document = parser.parseFromString(htmlString, "text/html");

// Remove all style attributes from all elements
const elementsWithStyle: NodeListOf<Element> =
doc.querySelectorAll("[style]");
elementsWithStyle.forEach((el: Element) => el.removeAttribute("style"));

// Remove all <style> elements
const styleElements: NodeListOf<HTMLStyleElement> =
doc.querySelectorAll("style");
styleElements.forEach((el: HTMLStyleElement) =>
el.parentNode?.removeChild(el)
);

// Get the inner HTML of the body element
const bodyInnerHTML: string = doc.body.innerHTML;

return bodyInnerHTML;
}
}
18 changes: 18 additions & 0 deletions projects/ngx-wig/src/lib/ngx-wig-filter.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { NgxWigFilterService } from './ngx-wig-filter.service';

describe('NgxWigFilterService', () => {
let service: NgxWigFilterService;

beforeEach(() => {
service = new NgxWigFilterService();
});

it('should create an instance', () => {
expect(service).toBeTruthy();
});

it('should return the same content when filtering', () => {
const content = 'Hello, world!';
expect(service.filter(content)).toEqual(content);
});
});
11 changes: 11 additions & 0 deletions projects/ngx-wig/src/lib/ngx-wig-filter.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Injectable } from '@angular/core';

@Injectable({
providedIn: 'root'
})
export class NgxWigFilterService {
constructor() {}
public filter(content: string): string {
return content;
}
}
22 changes: 20 additions & 2 deletions projects/ngx-wig/src/lib/ngx-wig.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import {
forwardRef,
Inject,
OnDestroy,
Optional,
} from '@angular/core';

import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { NgxWigToolbarService } from './ngx-wig-toolbar.service';
import { DOCUMENT } from '@angular/common';
import { TButton, CommandFunction } from './config';
import { NgxWigFilterService } from './ngx-wig-filter.service';

/** @dynamic */
@Component({
Expand All @@ -30,7 +32,7 @@ import { TButton, CommandFunction } from './config';
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgxWigComponent),
multi: true,
},
}
],
encapsulation: ViewEncapsulation.None,
})
Expand Down Expand Up @@ -63,6 +65,7 @@ export class NgxWigComponent

public constructor(
private _ngWigToolbarService: NgxWigToolbarService,
@Optional() private _filterService: NgxWigFilterService,
@Inject(DOCUMENT) private document: any, // cannot set Document here - Angular issue - https://github.com/angular/angular/issues/20351
@Inject('WINDOW') private window
) {}
Expand Down Expand Up @@ -145,7 +148,22 @@ export class NgxWigComponent
this.container.innerHTML = '';

// add the new content
this.pasteHtmlAtCaret(changes['content'].currentValue);
if (this._filterService){
this.pasteHtmlAtCaret(this._filterService.filter(changes['content'].currentValue));
} else {
this.pasteHtmlAtCaret(changes['content'].currentValue);
}

}
}

onPaste(event: ClipboardEvent) {
event.preventDefault();
const text = event.clipboardData?.getData('text/plain') ?? '';
if (this._filterService){
this.pasteHtmlAtCaret(this._filterService.filter(text));
} else {
this.pasteHtmlAtCaret(text);
}
}

Expand Down
2 changes: 2 additions & 0 deletions projects/ngx-wig/src/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*/

export * from './lib/ngx-wig-toolbar.service';
export * from './lib/ngx-wig-filter.service';
export * from './lib/ngx-wig-filter-styles.service';
export * from './lib/ngx-wig.component';
export * from './lib/ngx-wig.module';
export * from './lib/config';

0 comments on commit b0ec4ea

Please sign in to comment.