import { Component, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'; @Component({ selector: 'app-lesson-title-config', templateUrl: './lesson-title-config.component.html', styleUrls: ['./lesson-title-config.component.scss'] }) export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy, OnChanges { fontFamilyList = [ 'Arial', 'ARBLI' ]; colorList = [ '#111111', '#ffffff', '#595959', '#0075c2', '#c61c1e', '#9cbc3a' ]; MIN_FONT_SIZE = 1; MAX_FONT_SIZE = 7; isShowFontColorPane = false; isShowBGColorPane = false; fontSizeRange: number[]; editorContent = ''; __fontFamily = 'Arial'; __fontColor = ''; __fontSize = 3; loopCnt = 0; maxLoops = 20; groupIconsCount = { a: Array.from(Array(11).keys()), b: Array.from(Array(8).keys()), c: Array.from(Array(8).keys()), }; prevIcons = []; prevType = ''; @ViewChild('titleEl') titleEl: ElementRef; titleEW = null; @Input() titleObj = { type: 'a', content: '', icons: [], audio_url: '' }; @Input() withIcon = true; @Output() titleUpdated = new EventEmitter(); constructor() { this.fontSizeRange = []; for (let i = this.MIN_FONT_SIZE; i <= this.MAX_FONT_SIZE; ++i) { this.fontSizeRange.push(i); } this.__fontSize = 3; this.__fontColor = this.colorList[0]; } ngOnChanges(vars) { if (!vars.titleObj.previousValue) {// 初始化,内容是空 return; } let defObj = this.titleObj; if (!vars.titleObj.currentValue) { defObj = { type: 'a', content: '', icons: [], audio_url: '' }; } else { defObj = vars.titleObj.currentValue; } this.titleObj.icons = defObj.icons || []; this.titleObj.type = defObj.type || 'a'; this.titleObj.content = defObj.content || ''; this.titleObj.audio_url = defObj.audio_url || ''; this.titleEW.document.body.innerHTML = this.titleObj.content; } ngOnInit() { if (!this.titleObj) { this.titleObj = { type: 'a', content: '', icons: [], audio_url: '' }; } this.titleObj.icons = this.titleObj.icons || []; this.titleObj.type = this.titleObj.type || 'a'; this.titleObj.content = this.titleObj.content || ''; this.titleObj.audio_url = this.titleObj.audio_url || ''; this.editorContent = `
${this.titleObj.content} `; this.titleEW = this.titleEl.nativeElement.contentWindow; const tdoc = this.titleEW.document; tdoc.designMode = "on"; tdoc.open('text/html', 'replace'); tdoc.write(this.editorContent); tdoc.close(); tdoc.addEventListener("keypress", this.keyPress, true); tdoc.addEventListener("blur", () => { if (this.titleObj.content === this.titleEW.document.body.innerHTML.trim()) { return; } this.shouldSave(); }, true); } htmlEncode(text) { if (!text) { return ''; } return text.replace(/\&/ig, '&') .replace(/\/ig, '>') .replace(/\"/ig, '"'); } htmlDecode(text) { if (!text) { return ''; } return text.replace(/\&\;/ig, '&') .replace(/\<\;/ig, '<') .replace(/\>\;/ig, '>') .replace(/\"\;/ig, '"'); } ngOnDestroy(): void { } iconsChanges(val) { let a = this.titleObj.icons; let b = val; if (a.length > b.length) { const diff = a.filter(x => !b.includes(x)); const ti = [...this.titleObj.icons]; for (let i = 0; i < diff.length; i++) { const d = diff[i]; const idx = ti.indexOf(d); ti.splice(idx, 1); } this.titleObj.icons = ti; } else { const diff = b.filter(x => !a.includes(x)); this.titleObj.icons = [...this.titleObj.icons, ...diff]; } this.shouldSave(); } typeChange(val) { this.titleObj.icons = []; this.shouldSave(); } keyPress(evt) { try { if (evt.charCode === 13) { evt.preventDefault(); evt.stopPropagation(); return; } if (evt.ctrlKey) { const key = String.fromCharCode(evt.charCode).toLowerCase(); let cmd = ''; switch (key) { case 'b': cmd = "bold"; break; case 'i': cmd = "italic"; break; case 'u': cmd = "underline"; break; } if (cmd) { this.execEditorCommand(cmd); // stop the event bubble evt.preventDefault(); evt.stopPropagation(); } } } catch (e) { console.log(1, e); alert(e); } } execEditorCommand(command, option?: any) { try { this.titleEW.focus(); this.titleEW.document.execCommand(command, false, option); this.loopCnt = 0; return false; } catch (e) { alert(e); if (this.loopCnt < this.maxLoops) { setTimeout(() => { this.execEditorCommand(command, option); }, 100); this.loopCnt += 1; } else { alert("Error executing command."); } } } onSelectColor(color) { this.execEditorCommand('forecolor', color); this.__fontColor = color; } onChangeFontColor(val) { this.execEditorCommand('forecolor', this.__fontColor); } onChangeFontFamily(font) { this.execEditorCommand('fontname', font); } onChangeFontSize(size?: any) { if (size) { size += this.__fontSize; } else { size = this.__fontSize; } size = Math.max(this.MIN_FONT_SIZE, size); size = Math.min(this.MAX_FONT_SIZE, size); this.execEditorCommand('fontsize', size); } onChangeBold() { this.execEditorCommand('bold'); } onChangeItalic() { this.execEditorCommand('italic'); } onChangeUnderline() { this.execEditorCommand('underline'); } onChangeStrikethrough() { this.execEditorCommand('strikethrough'); } titleAudioUploaded(res) { this.titleObj.audio_url = res.url; this.titleUpdated.emit(this.titleObj); } shouldSave = () => { console.log('title shouldSave'); this.titleObj.content = this.titleEW.document.body.innerHTML.trim(); this.titleUpdated.emit(this.titleObj); } }