GetmeUK / ContentTools

A JS library for building WYSIWYG editors for HTML content.
http://getcontenttools.com
MIT License
3.94k stars 393 forks source link

Hook into functions and events? #540

Closed axismu closed 5 years ago

axismu commented 5 years ago

I made this stack overflow question: https://stackoverflow.com/questions/56917026/hook-onto-property-dialog-style-events but I don't think alot of people check this subject.

I'm struggling hooking onto methods and events, and the documentation does not go into deep details. Here is my main issues:

1. Open properties dialog I need to open the properties dialog and be able to open the right tab (attributes, styles etc). So when someone clicks a edit icon that I added to the toolbox, the styles dialog pops up (I think that will be easier for the user to understand rather than clicking on the tag in the bottom corner).

2. Hook onto properties element click I need to hook onto the toggle of the styles tag that is registered at StyleUI.prototype._addDOMEventListeners but I can't seem to hook into it at all.

Maybe an enhancement could be to add more triggers and callbacks on all the mounts and events, sending the variables and the element so we have the ability to make more adjustments and special events. :)

For instance when I wanted to add a last element to the toolbox element I had to recreate the whole mount function just to add one more line of code. Is there maybe a better way to do this?

ContentTools.ToolboxUI.prototype.mount = function() {
        var coord, position, restore;
        this._domElement = this.constructor.createDiv(['ct-widget', 'ct-toolbox']);
        this.parent().domElement().appendChild(this._domElement);
        this._domGrip = this.constructor.createDiv(['ct-toolbox__grip', 'ct-grip']);
        this._domElement.appendChild(this._domGrip);
        $(this._domGrip).append('<div class="ct-grip__bump"></div><div class="ct-grip__bump"></div><div class="ct-grip__bump"></div>');
        this._domToolGroups = this.constructor.createDiv(['ct-tool-groups']);
        this._domElement.appendChild(this._domToolGroups);
        $(this._domElement).append('<div class="ct-tool-footer" id="entry_settings"><a class="button_link"> <i class="material-icons">settings</i> options </a> </div>');
        this.tools(this._tools);

        restore = window.localStorage.getItem('ct-toolbox-position');
        if (restore && /^\d+,\d+$/.test(restore)) {
            position = (function() {
                var _i, _len, _ref, _results;
                _ref = restore.split(',');
                _results = [];
                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                    coord = _ref[_i];
                    _results.push(parseInt(coord));
                }
                return _results;
            })();
            this._domElement.style.left = "" + position[0] + "px";
            this._domElement.style.top = "" + position[1] + "px";
            this._contain();
        }
        return this._addDOMEventListeners();
    };

I write in jquery not coffee script, maybe that's my problem?

axismu commented 5 years ago

Any answer to this would be greatly appreciated as I am completely stuck, since it seems like there is no way to even overwrite the StyleUI.prototype class. I get undefined when I try to overwrite it like the others.

anthonyjb commented 5 years ago

Hi @axismu,

So I think you might want StyleUI.constructor.prototype maybe?

Re. Your question regarding hooking into events for Elements take a look at https://github.com/GetmeUK/ContentTools/issues/6 as I think this still holds True.

Re. Yhe UI stuff that's a little more complex because the UI in CT is very basic - it's designed to be lightweight not a complete UI solution, often people integrating CT into a larger project heavily modify or even replace the very basic UI. However, if you're using JQuery one option is to bind to the relevant elements using the on method, that way when the dialog is opened you an capture events against the relevant buttons.

If you want a tool to open a dialog that should be be pretty straight forward, take a look at an existing tool that opens a dialog like the video too (https://github.com/GetmeUK/ContentTools/blob/master/src/scripts/tools.coffee#L1197) and the code that currently opens the properties dialog (https://github.com/GetmeUK/ContentTools/blob/master/src/scripts/ui/inspector.coffee#L202) and use them as a basis.

axismu commented 5 years ago

Hi! thank you for the answer!

  1. Yes I want the StyleUI.constructor.prototype my problem is that this shows up as undefined. Unlike ContentTools and ContentEdit that will show up in the console, the StyleUI does not "exist", so I can't overwrite it. Maybe I'm not calling it correctly? I've tried ContentTools.StyleUI and ContentEdit.StyleUI but neither works.

    1. Thanks the dialog now works! I did this and changed the local storage so it opened the right window!
      
      editor = ContentTools.EditorApp.get();

// put this in a function sending an element. modal = new ContentTools.ModalUI(); dialog = new ContentTools.PropertiesDialog(element); editor.attach(modal); editor.attach(dialog); window.localStorage.setItem('ct-properties-dialog-tab', 'attributes'); modal.show(); dialog.show(); // function end

axismu commented 5 years ago

Turns out since I made my own dialog I could now access the StyleUI from there. For anyone else stumbling upon this issue. After your dialog.show() you can then access dialog._styleUIs and loop through these to bind each element to a event.

In my case I had to overwrite the applied function.

$.each(dialog._styleUIs, function(i, styleInput){
      styleInput.applied = function(applied) {
          //  Your new function here 
          // (might want to copy the original and add onto it)
      });
});

Thanks again, I appreciate it!