Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manually hidden toolView shown after calling addTools in async mode #1445

Open
ialokim opened this issue Mar 17, 2021 · 2 comments
Open

Manually hidden toolView shown after calling addTools in async mode #1445

ialokim opened this issue Mar 17, 2021 · 2 comments
Labels

Comments

@ialokim
Copy link

ialokim commented Mar 17, 2021

I found another weird case similar to #1320 when using the asynchronous paper mode: After adding a toolsView to an element, I want to (conditionally) hide one of the toolViews (in this example the "Remove" button). This works as expected in the normal synchronous rendering mode, but fails if async: true is set in the paper options.

Here is a modified code from the Hello-world-example to reproduce the problem:

var graph = new joint.dia.Graph;

        var paper = new joint.dia.Paper({
            async: true,
            el: document.getElementById('myholder'),
            model: graph,
            width: 600,
            height: 100,
            gridSize: 1
        });

        var rect = new joint.shapes.standard.Rectangle();
        rect.position(100, 30);
        rect.resize(100, 40);
        rect.attr({
            body: {
                fill: 'blue'
            },
            label: {
                text: 'Hello',
                fill: 'white'
            }
        });
        rect.addTo(graph);

        var rect2 = rect.clone();
        rect2.translate(300, 0);
        rect2.attr('label/text', 'World!');
        rect2.addTo(graph);

        var link = new joint.shapes.standard.Link();
        link.source(rect);
        link.target(rect2);
        link.addTo(graph);

        const elementTools = new joint.dia.ToolsView({
            tools: [
                new joint.elementTools.Boundary({ focusOpacity: 0.5 }),
                new joint.elementTools.Remove({ offset: {x: -10, y: -10} })
            ]
        });

        paper.on('element:pointerdown', (elemView) => {
            elemView.addTools(elementTools);
            elementTools.tools[1].hide(); //only works with async: false
        });

In synchronous mode, the remove button is correctly hidden
grafik
whereas in asynchronous mode the results looks as follows
grafik

I've already looked into the code and suspect https://github.com/clientIO/joint/blob/master/src/dia/ToolsView.mjs#L60 or https://github.com/clientIO/joint/blob/master/src/dia/ToolsView.mjs#L52 to cause the problem as this code might get executed after the manual hiding. A solution might be to (re)set all _visible flags of the toolViews to true directly (synchronously) when calling addTools.

@ialokim ialokim changed the title Unconditionally shows manually hidden toolViews in async mode Manually hidden toolView shown after calling addTools in async mode Mar 17, 2021
@ialokim
Copy link
Author

ialokim commented May 4, 2021

I was able to fix this behavior (at least for my use-case) with the following monkey-patch:

joint.dia.ToolView.prototype.configure = function(view, toolsView) {
    this.relatedView = view;
    this.paper = view.paper;
    this.parentView = toolsView;
    this.simulateRelatedView(this.el);
    // Delegate events in case the ToolView was removed from the DOM and reused.
    this.delegateEvents();
    this.show(); //added
    return this;
};
joint.dia.ToolsView.prototype.update = function(opt) {
    opt || (opt = {});
    var tools = this.tools;
    if (!tools) return this;
    var isRendered = this.isRendered;
    for (var i = 0, n = tools.length; i < n; i++) {
        var tool = tools[i];
        if (!isRendered) {
            // First update executes render()
            tool.render();
        } else if (opt.tool !== tool.cid && tool.isVisible()) {
            tool.update();
        }
    }
    if (!isRendered) {
        this.mount();
        // Make sure tools are visible (if they were hidden and the tool removed)
        //this.blurTool(); //removed
        this.isRendered = true;
    }
    return this;
};

Not sure though if that could be a general-purpose solution as the asynchronous rendering scheme might be hurt by the additional call to this.show() inside configure().

@github-actions
Copy link

github-actions bot commented May 5, 2022

This issue is stale because it has been open 60 days with no activity. Please remove stale label or comment or this will be closed in 14 days.

@github-actions github-actions bot added the stale This issue/PR shows no activity for an extended period of time. label May 5, 2022
@kumilingus kumilingus added bug and removed stale This issue/PR shows no activity for an extended period of time. labels May 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants