tinymce / tinymce-angular

Official TinyMCE Angular Component
MIT License
324 stars 93 forks source link

Private props/methods make it impossible to add custom features #205

Closed jbjhjm closed 3 years ago

jbjhjm commented 3 years ago

Most properties have been marked private. This is a stopper for everyone trying to add custom logic. Right now I need to work with a full local copy of the component to allow extending the component class.

Favoured solution: Properties should be protected instead of private.

I would be glad to see a fix for this. Thanks.

Edit: One more suggestion. By refactoring initialise() into two methods:

  public buildTinyMceConfig() {
    const finalInit = {
      ...this.init,
      target: this._element,
      inline: this.inline,
      readonly: this.disabled,
      plugins: mergePlugins(this.init && this.init.plugins, this.plugins),
      toolbar: this.toolbar || (this.init && this.init.toolbar),
      setup: (editor: any) => {
        this._editor = editor;
        editor.on('init', (e: Event) => {
        this.initEditor(editor);
        });
        bindHandlers(this, editor);

        if (this.init && typeof this.init.setup === 'function') {
        this.init.setup(editor);
        }
      }
    };
    return finalInit;

  }

  public initialise() {

    if (isTextarea(this._element)) {
      this._element.style.visibility = '';
    }

    this.ngZone.runOutsideAngular(() => {
      getTinymce().init(this.buildTinyMceConfig());
    });
  }

developers become able to modify the configuration object which would be impossible otherwise as it is immediately being passed to tinymce.init()

jscasca commented 3 years ago

Hi @jbjhjm

Out of curiosity, what kind of custom logic are you trying to implement? Why do you need to further modify the configuration? The init property of the wrapper should allow users to set any configuration already.

jbjhjm commented 3 years ago

Hey @jscasca ,

in my case I needed to use inline mode with a custom, already existing _element. Checking the code I found that there's no solution to modify it to my needs. The _element property itself is marked private. The only attack point for passing a different element to tinyMCE would have been initialise(). But it does not allow modifications and overriding the whole initialise() is problematic due to other private props and leads to hard to read code logic. Splitting initialise() logic into two methods allows to apply changes to the configuration without any exceptions.

Additionally I had to work around _elementRef being private by saving it to an additional property, which is not pretty.

    constructor(elementRef: ElementRef, ngZone: NgZone, @Inject(PLATFORM_ID) platformId: Object) {
        super(elementRef,ngZone,platformId);
        this._elementRef2 = elementRef;
    }

I ended up forking the repo and changing the properties to be protected as this was the only solution available.

jscasca commented 3 years ago

I'm glad you got it working. Unfortunately this is not something we are looking to support as it could lead to further issues down the track