Chandra

 view release on metacpan or  search on metacpan

xs/contextmenu.xs  view on Meta::CPAN

                            PUSHMARK(SP);
                            XPUSHs(*app_svp);
                            XPUSHs(show_js);
                            PUTBACK;
                            call_method("eval", G_DISCARD);
                            FREETMPS; LEAVE;
                        }
                    }
                    SvREFCNT_dec(show_js);
                }
                SvREFCNT_dec(dyn_items);
            }
        } else {
            /* Static menu - show via JS */
            SV *show_js = newSVpvf("window.__chandraCtxShow(%g,%g);", x, y);
            SV **app_svp = hv_fetchs(hv, "app", 0);
            if (app_svp && SvOK(*app_svp)) {
                dSP;
                ENTER; SAVETMPS;
                PUSHMARK(SP);
                XPUSHs(*app_svp);
                XPUSHs(show_js);
                PUTBACK;
                call_method("eval", G_DISCARD);
                FREETMPS; LEAVE;
            }
            SvREFCNT_dec(show_js);
        }
    }

    SvREFCNT_dec(event_sv);
}

 # ---- inject() - bind dispatch + inject JS ----

SV *
inject(self)
    SV *self
CODE:
{
    HV *hv = (HV *)SvRV(self);
    SV **injected_svp;

    injected_svp = hv_fetchs(hv, "_injected", 0);
    if (injected_svp && SvTRUE(*injected_svp)) {
        RETVAL = SvREFCNT_inc(self);
    } else {
        SV *js;

        (void)hv_stores(hv, "_injected", newSViv(1));

        /* Bind __chandraContextMenuBridge dispatch if not already done */
        {
            SV **db_svp = hv_fetchs(hv, "_dispatch_bound", 0);
            if (!db_svp || !SvTRUE(*db_svp)) {
                SV **app_svp = hv_fetchs(hv, "app", 0);
                if (app_svp && SvOK(*app_svp)) {
                    SV *cm_self_ref = newSVsv(self);
                    CV *wrapper_cv;

                    sv_rvweaken(cm_self_ref);
                    wrapper_cv = newXS(NULL, XS_Chandra__ContextMenu__dispatch_trampoline, __FILE__);
                    CvXSUBANY(wrapper_cv).any_ptr = (void *)cm_self_ref;
                    {
                        dSP;
                        ENTER; SAVETMPS;
                        PUSHMARK(SP);
                        XPUSHs(*app_svp);
                        XPUSHs(sv_2mortal(newSVpvs("__chandraContextMenuBridge")));
                        XPUSHs(sv_2mortal(newRV_noinc((SV *)wrapper_cv)));
                        PUTBACK;
                        call_method("bind", G_DISCARD);
                        FREETMPS; LEAVE;
                    }
                    (void)hv_stores(hv, "_dispatch_bound", newSViv(1));
                }
            }
        }

        /* Get JS code */
        {
            dSP;
            int count;
            ENTER; SAVETMPS;
            PUSHMARK(SP);
            XPUSHs(self);
            PUTBACK;
            count = call_method("js_code", G_SCALAR);
            SPAGAIN;
            js = (count > 0) ? newSVsv(POPs) : newSVpvs("");
            PUTBACK;
            FREETMPS; LEAVE;
        }

        /* Call $self->{app}->eval($js) */
        {
            SV **app_svp = hv_fetchs(hv, "app", 0);
            if (app_svp && SvOK(*app_svp)) {
                dSP;
                ENTER; SAVETMPS;
                PUSHMARK(SP);
                XPUSHs(*app_svp);
                XPUSHs(sv_2mortal(js));
                PUTBACK;
                call_method("eval", G_DISCARD);
                FREETMPS; LEAVE;
            } else {
                SvREFCNT_dec(js);
            }
        }

        RETVAL = SvREFCNT_inc(self);
    }
}
OUTPUT:
    RETVAL



( run in 0.641 second using v1.01-cache-2.11-cpan-364913b4093 )