jQuery-contextMenu icon indicating copy to clipboard operation
jQuery-contextMenu copied to clipboard

Not usable with webcomponents (because of ShadowDom?)

Open jogibear9988 opened this issue 9 years ago • 18 comments

I will use the Menu in a web-component (Polymer), but that does not work!

I think it's because of the Dom encapsulation (I can give only a selector, not a list of elements to wich the menu should apply, and the selector does not work cause of shadow dom)

jogibear9988 avatar Dec 17 '15 14:12 jogibear9988

Hmm, i dont really have much handon experience with polymer, so i can't really help you right now. I might be able to help you if you have a page somewhere where i can look.

bbrala avatar Dec 17 '15 20:12 bbrala

The problem is Polymer (or Webcomponents) uses ShadowDom to encapsulate Elements, so you can't access it's children via jquery and a selector. So it would be cool, if you have a Extra Method to wich I can supply my selected Elements to wich the Context Menu should be applied!

jogibear9988 avatar Dec 17 '15 21:12 jogibear9988

Maybe we can also enhance your Polyfill, so that already when I add the Script to the Page "menu" elements are polyfilled (so work the most polyfills), without calling a method! And also Menu Elemnts in ShadowDom should be polyfilled (don't know how this will be possible)

jogibear9988 avatar Dec 17 '15 21:12 jogibear9988

The menu elements can be polyfilled automaticly, (see http://swisnl.github.io/jQuery-contextMenu/docs/html5-polyfill.html). But this might indeed nog be the case for the ShadowDom elements.

Again tho, would you be able to put of a small test page where i can check and test?

bbrala avatar Dec 18 '15 08:12 bbrala

yes they can, but they were not if i I use "

" in a webcomponent! And also many other polyfills require only to include the javascript and will then work, yours need to be called after the page with "" was loaded (if I'm correct..)

I'd look to create a Example in JSFiddle

jogibear9988 avatar Dec 18 '15 08:12 jogibear9988

look at https://jsfiddle.net/tpw7to3b/3/ - when you change from "shady" to "shadow" the menu does not work any more (you need to test in chrome, the other browsers will ship shadowDom in the next releases)

jogibear9988 avatar Dec 18 '15 09:12 jogibear9988

And one with the HTML5 Polyfill https://jsfiddle.net/qok36dab/1/ (also, use Chrome)

jogibear9988 avatar Dec 18 '15 09:12 jogibear9988

I've been looking into this, and adding support for shadow DOM is kind of hard at the moment. The plugin is made to be as fast as possible because it doesn't bind on single elements. This created the problem is listens to the root document and opens on the elements that fit the selector.

The problem with the shadow root is since it is isolated the plugin would need to bind to the first html element in the shadowdom, in order to do this there is quite a lot of code that needs rewriting.

Another problem is that jQuery positioning currently doesn't really support the shadowdom that well, which is a problem if you try to position the menu on the proper clicked element.

Conclusion is that i currently dont see how i can implement this in a reasonable amount of time.

bbrala avatar Dec 23 '15 16:12 bbrala

I'm looking into this in the first weeks of next year, cause we need it for a customer site! Maybe I get a good idea and then I will write here again!

jogibear9988 avatar Dec 27 '15 09:12 jogibear9988

I've found this: http://stackoverflow.com/a/28028150/579623 maybe this helps?

jogibear9988 avatar Dec 27 '15 09:12 jogibear9988

But of cause this should not only be fixed for polymer this should be fixed for all libraries wich are using webcomponents

jogibear9988 avatar Dec 27 '15 09:12 jogibear9988

I've don a few changes:

line 1414 from

    if (!o.context || !o.context.length) {
        o.context = document;
    } else {

to

    if (!o.context) {
        o.context = document;
    } else {

line 1450 from

                $document
                    .on({

to

                $context
                    .on({

and line 1473 from

            $context
                .on('contextmenu' + o.ns, o.selector, o, handle.contextmenu);

to

            $context
                .on('contextmenu', o.selector, o, handle.contextmenu);

but it does not work ;-(

the context menu now is added correctly to the dom of my component when I use it like this:

        $.contextMenu({
            selector: '.mfc-place-context-menu',
            callback: function (key, options) {
                var m = "clicked: " + key;
                window.console && console.log(m) || alert(m);
            },
            appendTo: self.$.rpdiv,
            context: self.shadowRoot,
            items: {
                "edit": { name: "Edit", icon: "edit" },
                "cut": { name: "Cut", icon: "cut" },
                copy: { name: "Copy", icon: "copy" },
                "paste": { name: "Paste", icon: "paste" },
                "delete": { name: "Delete", icon: "delete" },
                "sep1": "---------",
                "quit": {
                    name: "Quit", icon: function () {
                        return 'context-menu-icon context-menu-icon-quit';
                    }
                }
            }
        });

as you see, i set the context to self.shadowroot, but the menu is not opened... any help?

jogibear9988 avatar Dec 28 '15 08:12 jogibear9988

Yeah i tried the same, there is also a few places where $(document) is called. These would need to change also.

Another thing i read is that the positioning of an element in a shadow root can't be calculated correctly, but i didnt double check that so that might not be an issue.

bbrala avatar Dec 28 '15 08:12 bbrala

But do you have an Idea why it would not open?

jogibear9988 avatar Dec 28 '15 08:12 jogibear9988

I've also created a fiddle with my changes: https://jsfiddle.net/bz6774nj/4/

jogibear9988 avatar Dec 28 '15 09:12 jogibear9988

Not sure, but i would guess it would be the click handler is on the parent document, and not somewhere in the shadowroot.

bbrala avatar Dec 29 '15 12:12 bbrala

I'm currently trying to do the same thing. the shadowRoot does not have the "contextmenu" event. I've had success using the element itself as the context to put the event on. The issue that I'm running into right now is that the "currentTarget" property of the MouseEvent is always null. This library attempts to get the current target and set it as the trigger.

My next test will be to iterate through the event's "path" array until' I find an item that matches the selector then use that as the trigger

EliteScientist avatar May 05 '20 21:05 EliteScientist

Hey folks! Great stuff the component... we've been using it heavily in GRIDNET OS (https://gridnet.org) still.. we just ran into a serious problem... it does not handle Shadow DOM.. which is of extreme importance in UI dApps.... It would die right here when doing initialization.. during the 'create' event.... effectively no contextmenu events are bound.. preventing the menu from being opened... also.. seems like the 'appendTo' option is broken when in ShadowDom.. as under the hood the plugin seemingly attempts to convert passed object to an identifier... which doesn't exist. anyway it dies right here

// engage native contextmenu event $context.on('contextmenu' + o.ns, o.selector, o, handle.contextmenu);

rafalsk avatar Jul 05 '22 10:07 rafalsk