|
|
|
@ -5,11 +5,17 @@ |
|
|
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|
|
|
*/ |
|
|
|
|
|
|
|
// tslint:disable:prefer-for-of
|
|
|
|
|
|
|
|
import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, OnDestroy, Output, ViewChild } from '@angular/core'; |
|
|
|
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; |
|
|
|
|
|
|
|
import { |
|
|
|
AppsState, |
|
|
|
AssetDto, |
|
|
|
AssetsService, |
|
|
|
AuthService, |
|
|
|
DateTime, |
|
|
|
DialogModel, |
|
|
|
ResourceLoaderService, |
|
|
|
Types |
|
|
|
@ -21,6 +27,13 @@ export const SQX_RICH_EDITOR_CONTROL_VALUE_ACCESSOR: any = { |
|
|
|
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RichEditorComponent), multi: true |
|
|
|
}; |
|
|
|
|
|
|
|
const ImageTypes = [ |
|
|
|
'image/jpeg', |
|
|
|
'image/png', |
|
|
|
'image/jpg', |
|
|
|
'image/gif' |
|
|
|
]; |
|
|
|
|
|
|
|
@Component({ |
|
|
|
selector: 'sqx-rich-editor', |
|
|
|
styleUrls: ['./rich-editor.component.scss'], |
|
|
|
@ -45,6 +58,9 @@ export class RichEditorComponent implements ControlValueAccessor, AfterViewInit, |
|
|
|
public assetPluginClicked = new EventEmitter<any>(); |
|
|
|
|
|
|
|
constructor( |
|
|
|
private readonly appsState: AppsState, |
|
|
|
private readonly assetsService: AssetsService, |
|
|
|
private readonly authState: AuthService, |
|
|
|
private readonly changeDetector: ChangeDetectorRef, |
|
|
|
private readonly resourceLoader: ResourceLoaderService |
|
|
|
) { |
|
|
|
@ -59,7 +75,7 @@ export class RichEditorComponent implements ControlValueAccessor, AfterViewInit, |
|
|
|
public ngAfterViewInit() { |
|
|
|
const self = this; |
|
|
|
|
|
|
|
this.resourceLoader.loadScript('https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.5.4/tinymce.min.js').then(() => { |
|
|
|
this.resourceLoader.loadScript('https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.9.3/tinymce.min.js').then(() => { |
|
|
|
tinymce.init(self.getEditorOptions()); |
|
|
|
}); |
|
|
|
} |
|
|
|
@ -76,10 +92,9 @@ export class RichEditorComponent implements ControlValueAccessor, AfterViewInit, |
|
|
|
return { |
|
|
|
convert_fonts_to_spans: true, |
|
|
|
convert_urls: false, |
|
|
|
plugins: 'code image media link lists advlist', |
|
|
|
plugins: 'code image media link lists advlist paste', |
|
|
|
removed_menuitems: 'newdocument', |
|
|
|
resize: true, |
|
|
|
theme: 'modern', |
|
|
|
toolbar: 'undo redo | styleselect | bold italic | alignleft aligncenter | bullist numlist outdent indent | link image media | assets', |
|
|
|
setup: (editor: any) => { |
|
|
|
self.tinyEditor = editor; |
|
|
|
@ -102,6 +117,15 @@ export class RichEditorComponent implements ControlValueAccessor, AfterViewInit, |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
self.tinyEditor.on('paste', (event: ClipboardEvent) => { |
|
|
|
for (let i = 0; i < event.clipboardData.items.length; i++) { |
|
|
|
const file = event.clipboardData.items[i].getAsFile(); |
|
|
|
|
|
|
|
if (file && ImageTypes.indexOf(file.type) >= 0) { |
|
|
|
self.uploadFile(file); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
self.tinyEditor.on('blur', () => { |
|
|
|
self.callTouched(); |
|
|
|
}); |
|
|
|
@ -153,4 +177,31 @@ export class RichEditorComponent implements ControlValueAccessor, AfterViewInit, |
|
|
|
|
|
|
|
this.assetsDialog.hide(); |
|
|
|
} |
|
|
|
|
|
|
|
public insertFiles(files: File[]) { |
|
|
|
for (let file of files) { |
|
|
|
this.uploadFile(file); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private uploadFile(file: File) { |
|
|
|
const uploadText = `[Uploading file...${new Date()}]`; |
|
|
|
|
|
|
|
this.tinyEditor.execCommand('mceInsertContent', false, uploadText); |
|
|
|
|
|
|
|
const replaceText = (replacement: string) => { |
|
|
|
const content = this.tinyEditor.getContent().replace(uploadText, replacement); |
|
|
|
|
|
|
|
this.tinyEditor.setContent(content); |
|
|
|
}; |
|
|
|
|
|
|
|
this.assetsService.uploadFile(this.appsState.appName, file, this.authState.user!.token, DateTime.now()) |
|
|
|
.subscribe(asset => { |
|
|
|
if (Types.is(asset, AssetDto)) { |
|
|
|
replaceText(`<img src="${asset.url}" alt="${asset.fileName}" />`); |
|
|
|
} |
|
|
|
}, () => { |
|
|
|
replaceText('FAILED'); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |