Search code examples
angularautocompleteckeditorckeditor4.x

How to solve 'Permission denied' error in IE/Edge when using ckeditor autocomplete plugin in Angular with ng2-ckeditor


I need to use the autocomplete CKEditor plugin in Angular. I'm using ng2-ckeditor for using CKEditor with Angular, Angular 6 and a custom local distribution of CKEditor 4.10 with the plugins I need (including autocomplete and textMatch). When the # character is inputed, a list of items should show for the autocomplete.

This is the html fragment for the ckeditor component

<ckeditor #myCKEditor formControlName="ckeditorControl" [config]="ckeditorConfig"
  debounce="500" (ready)="loadAutocomplete($event)">
</ckeditor>

And here is the relevant typescript code

import { CKEditorComponent } from 'ng2-ckeditor';
[...]
declare var CKEDITOR: any;
[...]
export class PlantillesAddComponent {
  @ViewChild('myCKEditor') myCKEditor: CKEditorComponent;
  model = MODEL; //List of elements that autocomplete should show
  ckeditorConfig = CKEDITORCONFIG ; // {extraPlugins: 'autocomplete,textmatch', [...]}
  [...]
  loadAutocomplete(event) {
    const config = {
      textTestCallback: this.textTestCallback,
      dataCallback: this.dataCallback,
      outputTemplate: '{value}'
    };
    const editor = event.editor;
    try {
      // This doesn't work in IE/EDGE
      new CKEDITOR.plugins.autocomplete(editor, config);
    } catch (e) {
      console.error('ERROR IN IE/EDGE');
      console.error(e); //'Permission denied error'
    }
  }

  textTestCallback = (range) => {
    if (!range.collapsed) {
      return null;
    }
    return CKEDITOR.plugins.textMatch.match(range, this.matchCallback);
  }

  matchCallback = (text, offset) => {
    const left = text.slice(0, offset),
      match = left.match(/#{1}/);
    if (!match) {
      return null;
    }
    return { start: match.index, end: offset };
  }

  dataCallback = (matchInfo, callback) => {
    const data = this.model.filter(function (item) {
      if (item.name.toLowerCase().indexOf(matchInfo.query.substring(1).toLowerCase()) === 0) {
        if (item.value == null) {
          item.value = '${' + item.name + '}';
        }
        return true;
      }
    });
    callback(data);
  }

}

In firefox and chrome, when the # is introduced in editor, the list of selectable elements is correctly shown; but in IE and Edge this doesn't work. Checking the javascript console, it seems the error comes from this line: new CKEDITOR.plugins.autocomplete(editor, config);, in which a 'Permission denied' error is thrown for both IE and EDGE explorers.


Solution

  • According to it's Readme, it seems that adding the divarea plugin solves many issues with ng2-ckeditor.

    For adding this new plugin, I used the CKEditor builder, so I also updated to the last actual version of CKEDitor 4.x (specifically 4.11.4).

    Now the autocomplete works in both IE and Edge, but I'm not absolutely sure about if the solution was the version upgrade or the addition of the divarea plugin.