lesson-title-config.component.ts 7.19 KB

import {
  Component,
  ElementRef,
  EventEmitter,
  Input,
  OnChanges,
  OnDestroy,
  OnInit,
  Output,
  ViewChild
} from '@angular/core';

const editorTpl = `<html lang="en"><head><meta charset="utf-8">
  <meta name="viewport"
          content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"/>
        <style>
@font-face{
  font-family: 'BRLNSDB';
  src: url("../../../assets/font/BRLNSDB.TTF") ;
}

@font-face{
  font-family: 'BRLNSB';
  src: url("../../../assets/font/BRLNSB.TTF") ;
}

@font-face{
  font-family: 'BRLNSR';
  src: url("../../../assets/font/BRLNSR.TTF") ;
}

@font-face{
  font-family: 'GOTHIC';
  src: url("../../../assets/font/GOTHIC.TTF") ;
}

@font-face{
  font-family: 'GOTHICB';
  src: url("../../../assets/font/GOTHICB.TTF") ;
}

@font-face{
  font-family: 'GOTHICBI';
  src: url("../../../assets/font/GOTHICBI.TTF") ;
}

@font-face{
  font-family: 'GOTHICI';
  src: url("../../../assets/font/GOTHICI.TTF") ;
}

@font-face{
  font-family: 'MMTextBook';
  src: url("../../../assets/font/MMTextBook.otf") ;
}

@font-face{
  font-family: 'MMTextBook-Bold';
  src: url("../../../assets/font/MMTextBook-Bold.otf") ;
}

@font-face{
  font-family: 'MMTextBook-BoldItalic';
  src: url("../../../assets/font/MMTextBook-BoldItalic.otf") ;
}

@font-face{
  font-family: 'MMTextBook-Italic';
  src: url("../../../assets/font/MMTextBook-Italic.otf") ;
}
html, body{
/*font-size: 30px;*/
}
body{
    height:48px;

  overflow: hidden;
  margin: 0;
  padding: 0 .5rem;
  font-family: 'BRLNSB, BRLNSDB, BRLNSR, GOTHIC, GOTHICB, MMTextBook';
  background: #FFF;
  line-height: 48px;
}
</style>
  </head>
  <body>{{content}}</body>
</html>`;

@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',
    'BRLNSB',
    'BRLNSDB',
    'BRLNSR',
    'GOTHIC',
    'GOTHICB',
    // "GOTHICBI",
    // "GOTHICI",
    'MMTextBook',
    // "MMTextBook-Bold",
    // "MMTextBook-Italic",
    // "MMTextBook-BoldItalic",
  ];



  colorList = [
    '#000000',
    '#ffffff',
    '#595959',
    '#0075c2',
    '#c61c1e',
    '#9cbc3a',
    '#008000',
    '#FF0000',
    '#D2691E',
  ];
  MIN_FONT_SIZE = 1;
  MAX_FONT_SIZE = 7;
  isShowFontColorPane = false;
  isShowBGColorPane = false;
  fontSizeRange = [
    // {name: '1号', value: 9},
    // {name: '2号', value: 13},
    // {name: '3号', value: 16},
    // {name: '4号', value: 18},
    // {name: '5号', value: 24},
    // {name: '6号', value: 32},

  ];

  editorContent = '';


  __fontFamily = 'Arial';
  __fontColor = '';
  __fontSize = 3;

  loopCnt = 0;
  maxLoops = 20;

  @ViewChild('titleEl', {static: true}) titleEl: ElementRef;
  titleEW = null;


  @Input()
  titleObj = {
    content: '',
    audio_url: ''
  };


  @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 = {
        content: '',
        audio_url: ''
      };
    } else {
      defObj = vars.titleObj.currentValue;
    }
    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 = {
        content: '',
        audio_url: ''
      };
    }
    this.titleObj.content = this.titleObj.content || '';
    this.titleObj.audio_url = this.titleObj.audio_url || '';

    this.editorContent = editorTpl.replace('{{content}}', this.titleObj.content) ;
    this.titleEW = this.titleEl.nativeElement.contentWindow;
    console.log('this.titleEW', this.titleEW);
    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, '&amp;')
      .replace(/\</ig, '&lt;')
      .replace(/\>/ig, '&gt;')
      .replace(/\"/ig, '&quot;');
  }

  htmlDecode(text) {
    if (!text) {
      return '';
    }
    return text.replace(/\&amp\;/ig, '&')
      .replace(/\&lt\;/ig, '<')
      .replace(/\&gt\;/ig, '>')
      .replace(/\&quot\;/ig, '"');
  }


  ngOnDestroy(): void {

  }

  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) {
    console.log('sssss');
    try {
      this.titleEW.focus();
      const result = this.titleEW.document.execCommand(command, false, option);
      console.log(result);
      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);
    this.titleObj.content = this.titleEW.document.body.innerHTML.trim();
    this.titleUpdated.emit(this.titleObj);
  }
}