Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,847 changes: 1,411 additions & 1,436 deletions projects/ngx-quill/src/lib/quill-editor.component.spec.ts

Large diffs are not rendered by default.

551 changes: 243 additions & 308 deletions projects/ngx-quill/src/lib/quill-editor.component.ts

Large diffs are not rendered by default.

98 changes: 21 additions & 77 deletions projects/ngx-quill/src/lib/quill-view-html.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,19 @@
import { Component, ViewChild } from '@angular/core'
import { inputBinding, signal, WritableSignal } from '@angular/core'
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { beforeEach, describe, expect, test } from 'vitest'
import { QuillViewHTMLComponent } from './quill-view-html.component'
import { QuillModule } from './quill.module'

vi.spyOn(window, 'alert').mockImplementation(() => { return })

describe('Basic QuillViewHTMLComponent', () => {
let fixture: ComponentFixture<QuillViewHTMLComponent>

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
QuillModule.forRoot()
],
providers: QuillModule.forRoot().providers
}).compileComponents()
})

beforeEach(() => {
fixture = TestBed.createComponent(QuillViewHTMLComponent)
})

test('should render and set default snow theme class', async () => {
const element = fixture.nativeElement
fixture.detectChanges()
await fixture.whenStable()

expect(element.querySelectorAll('.ql-editor').length).toBe(1)
expect(fixture.componentInstance.themeClass()).toBe('ql-snow')
Expand All @@ -35,74 +23,46 @@ describe('Basic QuillViewHTMLComponent', () => {
})

describe('QuillViewHTMLComponent - content', () => {
@Component({
imports: [QuillModule],
template: `
<quill-view-html [content]="content" [theme]="theme"></quill-view-html>
`
})
class HTMLComponent {
@ViewChild(QuillViewHTMLComponent, {
static: true
}) view: QuillViewHTMLComponent | undefined
content = '<p>Hallo</p>'
theme = 'snow'

}

let fixture: ComponentFixture<HTMLComponent>

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [],
imports: [QuillModule],
providers: QuillModule.forRoot().providers
}).compileComponents()
})
let fixture: ComponentFixture<QuillViewHTMLComponent>
let content: WritableSignal<any>
const theme = signal('snow')

beforeEach(() => {
fixture = TestBed.createComponent(HTMLComponent) as ComponentFixture<HTMLComponent>
fixture.detectChanges()
content = signal('<p>Hallo</p>')
fixture = TestBed.createComponent(QuillViewHTMLComponent, {
bindings: [inputBinding('content', content), inputBinding('theme', theme)]
}) as ComponentFixture<QuillViewHTMLComponent>
})

test('should be set html', async () => {
fixture.detectChanges()
const element = fixture.nativeElement

await fixture.whenStable()
const viewElement = element.querySelector('.ql-container.ql-snow.ngx-quill-view-html > .ql-editor')
expect(viewElement.innerHTML).toEqual('<p>Hallo</p>')
})

test('should update html', async () => {
const component = fixture.componentInstance
await fixture.whenStable()
component.content = '<p>test</p>'
content.set('<p>test</p>')
fixture.detectChanges()
await fixture.whenStable()

const element = fixture.nativeElement
const viewElement = element.querySelector('.ql-container.ql-snow.ngx-quill-view-html > .ql-editor')
expect(viewElement.innerHTML).toEqual('<p>test</p>')
})

test('should set default theme when not set', async () => {
const component = fixture.componentInstance
await fixture.whenStable()
component.theme = undefined
theme.set(undefined)
fixture.detectChanges()
await fixture.whenStable()

const element = fixture.nativeElement
const viewElement = element.querySelector('.ql-container.ql-snow.ngx-quill-view-html > .ql-editor')
expect(viewElement.innerHTML).toEqual('<p>Hallo</p>')
})

test('should update theme', async () => {
const component = fixture.componentInstance
await fixture.whenStable()
component.theme = 'bubble'
theme.set('bubble')
fixture.detectChanges()
await fixture.whenStable()

const element = fixture.nativeElement
const viewElement = element.querySelector('.ql-container.ql-bubble.ngx-quill-view-html > .ql-editor')
Expand All @@ -111,29 +71,15 @@ describe('QuillViewHTMLComponent - content', () => {
})

describe('QuillViewHTMLComponent - sanitize', () => {
@Component({
imports: [QuillModule],
template: `
<quill-view-html [content]="content" [sanitize]="sanitize"></quill-view-html>
`
})
class HTMLComponent {
content = '<p>Hallo <img src="wroooong.jpg" onerror="window.alert(\'sanitize me\')"></p>'
sanitize = false
}

let fixture: ComponentFixture<HTMLComponent>

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [],
imports: [QuillModule],
providers: QuillModule.forRoot().providers
}).compileComponents()
})
let fixture: ComponentFixture<QuillViewHTMLComponent>
let content: WritableSignal<any>
const sanitize = signal(false)

beforeEach(() => {
fixture = TestBed.createComponent(HTMLComponent)
content = signal('<p>Hallo <img src="wroooong.jpg" onerror="window.alert(\'sanitize me\')"></p>')
fixture = TestBed.createComponent(QuillViewHTMLComponent, {
bindings: [inputBinding('content', content), inputBinding('sanitize', sanitize)]
}) as ComponentFixture<QuillViewHTMLComponent>
})

test('should NOT sanitize content when sanitize parameter is false', () => {
Expand All @@ -145,8 +91,7 @@ describe('QuillViewHTMLComponent - sanitize', () => {
})

test('should sanitize content when sanitize parameter is true', () => {
const component = fixture.componentInstance
component.sanitize = true
sanitize.set(true)
fixture.detectChanges()

const element = fixture.nativeElement
Expand All @@ -155,8 +100,7 @@ describe('QuillViewHTMLComponent - sanitize', () => {
})

test('should use default sanatize when not set', () => {
const component = fixture.componentInstance
component.sanitize = undefined
sanitize.set(undefined)
fixture.detectChanges()

const element = fixture.nativeElement
Expand Down
32 changes: 17 additions & 15 deletions projects/ngx-quill/src/lib/quill-view-html.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { QuillService } from './quill.service'

import {
Component,
OnChanges,
SimpleChanges,
ViewEncapsulation,
inject,
input,
signal
} from '@angular/core'
import { toObservable } from '@angular/core/rxjs-interop'
import { combineLatest } from 'rxjs'

@Component({
encapsulation: ViewEncapsulation.None,
Expand All @@ -26,7 +26,7 @@ import {
</div>
`
})
export class QuillViewHTMLComponent implements OnChanges {
export class QuillViewHTMLComponent {
readonly content = input('')
readonly theme = input<string | undefined>(undefined)
readonly sanitize = input<boolean | undefined>(undefined)
Expand All @@ -37,19 +37,21 @@ export class QuillViewHTMLComponent implements OnChanges {
private sanitizer = inject(DomSanitizer)
private service = inject(QuillService)

ngOnChanges(changes: SimpleChanges) {
if (changes.theme) {
const theme = changes.theme.currentValue || (this.service.config.theme ? this.service.config.theme : 'snow')
this.themeClass.set(`ql-${theme} ngx-quill-view-html`)
} else if (!this.theme()) {
const theme = this.service.config.theme ? this.service.config.theme : 'snow'
this.themeClass.set(`ql-${theme} ngx-quill-view-html`)
}
if (changes.content) {
const content = changes.content.currentValue
const sanitize = [true, false].includes(this.sanitize()) ? this.sanitize() : (this.service.config.sanitize || false)
constructor() {
toObservable(this.theme).subscribe((newTheme) => {
if (newTheme) {
const theme = newTheme || (this.service.config.theme ? this.service.config.theme : 'snow')
this.themeClass.set(`ql-${theme} ngx-quill-view-html`)
} else {
const theme = this.service.config.theme ? this.service.config.theme : 'snow'
this.themeClass.set(`ql-${theme} ngx-quill-view-html`)
}
})

combineLatest([toObservable(this.content), toObservable(this.sanitize)]).subscribe(([content, shouldSanitize]) => {
const sanitize = [true, false].includes(shouldSanitize) ? shouldSanitize : (this.service.config.sanitize || false)
const innerHTML = sanitize ? content : this.sanitizer.bypassSecurityTrustHtml(content)
this.innerHTML.set(innerHTML)
}
})
}
}
Loading