View file rusnet-interactive-map/assets/js/tinymce/plugin.js

File size: 48.84Kb
(function() {
    var script = document.createElement('script');
    var apikey = rusnetim_defaults['apikey_map_option'] || '';
    var apikeyexist = apikey !== '';
    var wp_locale = 'en_US';
    if (typeof tinymce !== 'undefined' && tinymce.util && tinymce.util.I18n) {
        wp_locale = tinymce.util.I18n.getCode();
    }
    if (wp_locale.length < 1) { wp_locale = "en_US"; }
    script.src = "https://api-maps.yandex.ru/2.1/?lang=" + encodeURIComponent(wp_locale) + (apikey ? "&apikey=" + encodeURIComponent(apikey) : "");
    script.setAttribute('type', 'text/javascript');
    document.getElementsByTagName('head')[0].appendChild(script);

    var mapselector = 'map0',
        activeplace = "",
        ym = {},
        editMapAction = false;
    var placemark = [];

    if (!editMapAction) {
        ym = {
            map0: {
                center: coordaprox(rusnetim_defaults['center_map_option']),
                controls: rusnetim_defaults['controls_map_option'],
                height: rusnetim_defaults['height_map_option'],
                zoom: rusnetim_defaults['zoom_map_option'],
                maptype: rusnetim_defaults['type_map_option'],
                scrollzoom: optionCheck('wheelzoom_map_option'),
                mobiledrag: optionCheck('mobiledrag_map_option'),
                cluster: (rusnetim_defaults['cluster_map_option'] === 'on' ? '1' : '0'),
                clustergrid: rusnetim_defaults['cluster_grid_option'] || '64',
                container: '',
                places: {}
            }
        };
    }

    function checkParam(param) {
        var checker = true;
        if (param === 'cluster') {
            checker = (ym.map0[param] === '1');
        } else {
            if (ym.map0[param] === "0") {
                checker = false;
            }
        }
        return checker;
    }

    function optionCheck(param) {
        var checker = "0";
        if (rusnetim_defaults[param] === 'on') {
            checker = "";
        }
        return checker;
    }

    function checkTitle() {
        return editMapAction ? rusnetim_object.EditMap : rusnetim_object.AddMap;
    }

    var coords = [],
        mapcenter = rusnetim_defaults['center_map_option'],
        mapzoom = rusnetim_defaults['zoom_map_option'],
        maptype = rusnetim_defaults['type_map_option'],
        markicon,
        markcount = 0,
        mapcount = 1;

    (function($) {
        parseShortcodes();
    })(jQuery);

    function iconselectchange() {
        if (activeplace !== '') {
            ym[mapselector].places[activeplace].icon = jQuery("#markericon-inp").val();
            iconname();
            ym[mapselector].places[activeplace].icon = jQuery("#markericon-inp").val();
        }
    }

    function coordaprox(fullcoord) {
        if (fullcoord.length !== 2) {
            fullcoord = fullcoord.split(',');
            if (fullcoord.length !== 2) {
                fullcoord = [0, 0];
            }
        }
        return [parseFloat(fullcoord[0]).toFixed(4), parseFloat(fullcoord[1]).toFixed(4)];
    }

    function markcoordchange() {
        jQuery("#markercoord").val(coordaprox(ym[mapselector].places[activeplace].coord));
    }

    function enablesinglefield(field) {
        jQuery(field).attr('disabled', false);
        jQuery(field).removeClass('mce-disabled');
        jQuery(field + '-l').removeClass('mce-disabled');
    }

    function disablesinglefield(field) {
        jQuery(field).attr('disabled', true);
        jQuery(field).addClass('mce-disabled');
        jQuery(field + '-l').addClass('mce-disabled');
    }

    function enablefields(fieldact = true) {
        if (fieldact) {
            enablesinglefield('#markercoord');
        } else {
            disablesinglefield('#markercoord');
        }
    }

    function checkcheckbox(param) {
        if (jQuery("#" + param).attr('aria-checked') != "undefined") {
            if (jQuery("#" + param).attr('aria-checked') == 'true') {
                ym[mapselector][param] = '1';
            } else ym[mapselector][param] = '0';
        }
    }

    function mapdatechange() {
        if (document.getElementById('mapcontrols')) {
            if (jQuery("#mapcontrols").val().trim().substr(-1) === ';')
                jQuery("#mapcontrols").val(jQuery("#mapcontrols").val().trim().slice(0, -1));
            ym[mapselector].controls = jQuery("#mapcontrols").val();
        }
        if (document.getElementById('mapheight')) {
            ym[mapselector].height = jQuery("#mapheight").val();
        }
        setTimeout(checkcheckbox, 200, 'scrollzoom');
        setTimeout(checkcheckbox, 200, 'mobiledrag');
        setTimeout(checkcheckbox, 200, 'cluster');
        if (document.getElementById('clustergrid')) {
            ym[mapselector].clustergrid = jQuery("#clustergrid").val();
        }
        if (document.getElementById('mapcontainer')) {
            if (jQuery("#mapcontainer").val() != "undefined") {
                ym.map0.container = jQuery("#mapcontainer").val();
            }
        }
    }

    function mapSave() {
        ym[mapselector].zoom = mapzoom;
        ym[mapselector].center = [coordaprox(mapcenter)];
        ym[mapselector].maptype = maptype;
    }

    function markchange() {
        if (activeplace !== '') {
            var markerName = jQuery("#markername").val().replace(/[&<>"']/g, function(m) {
                return {
                    '&': '&amp;',
                    '<': '&lt;',
                    '>': '&gt;',
                    '"': '&quot;',
                    "'": '&#039;'
                }[m];
            });
            ym[mapselector].places[activeplace].name = markerName;
            ym[mapselector].places[activeplace].coord = jQuery("#markercoord").val();
            ym[mapselector].places[activeplace].color = jQuery("#colorbox #colorbox-inp").val();
            ym[mapselector].places[activeplace].icon = jQuery("#markericon #markericon-inp").val();
            ym[mapselector].places[activeplace].category = jQuery("#markercategory #markercategory-inp").val();
            ym[mapselector].places[activeplace].image = jQuery("#markerimage").val();
            ym[mapselector].places[activeplace].description = jQuery("#markerdescription").val();

            var markerUrl = jQuery("#markerurl").val();
            if (markerUrl) {
                try {
                    markerUrl = encodeURI(markerUrl);
                } catch (e) {
                    markerUrl = '';
                }
            }
            ym[mapselector].places[activeplace].url = markerUrl;
        }
    }

    function markerfields() {
        if (typeof ym[mapselector].places[activeplace].name !== 'undefined') {
            jQuery("#markername").val(ym[mapselector].places[activeplace].name.replace(/(&quot;)/g, '"'));
        }
        jQuery("#markercoord").val(coordaprox(ym[mapselector].places[activeplace].coord));
        jQuery("#markericon #markericon-inp").val(ym[mapselector].places[activeplace].icon);
        jQuery("#colorbox #colorbox-inp").val(ym[mapselector].places[activeplace].color);
        jQuery("#colorbox #colorbox-open button i").css('background', ym[mapselector].places[activeplace].color);
        jQuery("#colorbox #colorbox-inp").trigger('change');
        jQuery("#markerurl").val(ym[mapselector].places[activeplace].url);
        jQuery("#markercategory #markercategory-inp").val(ym[mapselector].places[activeplace].category || 'all');
        jQuery("#markerimage").val(ym[mapselector].places[activeplace].image || '');
        jQuery("#markerdescription").val(ym[mapselector].places[activeplace].description || '');
    }

    function inactive() {
        jQuery("#markercoord").val(rusnetim_object.NoCoord);
        enablefields(false);
    }

    function iconname(place) {
        yacontent = "";
        if (activeplace !== '') {
            place = activeplace;
        }
        var markername = ym[mapselector].places[place].name;
        var markicon = ym[mapselector].places[place].icon;
        var yahint = "";

        markername = markername ? markername.replace(/[&<>"']/g, function(m) {
            return {
                '&': '&amp;',
                '<': '&lt;',
                '>': '&gt;',
                '"': '&quot;',
                "'": '&#039;'
            }[m];
        }) : '';

        if (markicon.indexOf("Stretchy") !== -1) {
            yahint = "";
            yacontent = markername;
        } else {
            if ((markicon === "islands#blueIcon") || (markicon === "islands#blueCircleIcon")) {
                yahint = markername;
                if ((yahint != "") && (yahint != undefined)) {
                    yacontent = yahint[0];
                }
            } else {
                yahint = markername;
                yacontent = "";
            }
        }

        if (place !== '') {
            placemark[place.replace('placemark', '')].properties.set('hintContent', yahint);
            placemark[place.replace('placemark', '')].properties.set('iconContent', yacontent);

            if (markicon.indexOf("http") === -1) {
                placemark[place.replace('placemark', '')].options.unset('iconLayout', 'default#image');
                placemark[place.replace('placemark', '')].options.unset('iconImageHref', markicon);
                placemark[place.replace('placemark', '')].options.set('preset', markicon);
            } else {
                placemark[place.replace('placemark', '')].options.unset('preset', markicon);
                placemark[place.replace('placemark', '')].options.set('iconLayout', 'default#image');
                markicon = encodeURI(markicon);
                placemark[place.replace('placemark', '')].options.set('iconImageHref', markicon);
            }
        }
    }

    function findPlaceMarks(found) {
        if (typeof found !== 'string') return;

        foundplace = found.match(/\[rusnetim_marker(.*?)\]/g);
        if (foundplace !== null) {
            for (var j = 0; j < foundplace.length; j++) {
                foundplacemark = foundplace[j].match(/([a-zA-Z]+)="([^"]+)+"/gi);
                ym['map0'].places['placemark' + j] = {};
                for (var k = 0; k < foundplacemark.length; k++) {
                    foundplacemark[k] = foundplacemark[k].split("&amp;").join("&");

                    placeparams = foundplacemark[k].split("=");
                    if (placeparams.length > 2) {
                        placeparams[1] = foundplacemark[k].replace(placeparams[0] + "=", "");
                    }
                    placeparams[1] = placeparams[1].replace(/\"|\'/g, '');

                    if (placeparams[0] === 'coord') {
                        var coords = placeparams[1].split(',');
                        if (coords.length === 2) {
                            var lat = parseFloat(coords[0]);
                            var lng = parseFloat(coords[1]);
                            if (!isNaN(lat) && !isNaN(lng) && lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180) {
                                ym['map0'].places['placemark' + j][placeparams[0]] = lat + ',' + lng;
                            } else {
                                ym['map0'].places['placemark' + j][placeparams[0]] = '53.334554,83.786980';
                            }
                        } else {
                            ym['map0'].places['placemark' + j][placeparams[0]] = '53.334554,83.786980';
                        }
                    } else if (placeparams[0] === 'url') {
                        try {
                            var url = decodeURI(placeparams[1]);
                            if (!isNaN(url)) {
                                ym['map0'].places['placemark' + j][placeparams[0]] = placeparams[1];
                            } else {
                                ym['map0'].places['placemark' + j][placeparams[0]] = encodeURI(url);
                            }
                        } catch (e) {
                            ym['map0'].places['placemark' + j][placeparams[0]] = '';
                        }
                    } else {
                        ym['map0'].places['placemark' + j][placeparams[0]] = placeparams[1];
                    }
                }
                if ( ! ym['map0'].places['placemark' + j].hasOwnProperty('image') ) {
                    ym['map0'].places['placemark' + j].image = '';
                }
                if ( ! ym['map0'].places['placemark' + j].hasOwnProperty('description') ) {
                    ym['map0'].places['placemark' + j].description = '';
                }
                if ( ! ym['map0'].places['placemark' + j].hasOwnProperty('cluster') ) {
                    ym['map0'].places['placemark' + j].cluster = '0';
                }
            }
        }
    }

    function parseShortcodes() {
        var media = wp.media,
            shortcode_string = 'rusnetim_map';
        markcount = 0;
        wp.mce = wp.mce || {};
        wp.mce.rusnetim = {
            shortcode_data: {},
            template: media.template('editor-rusnetim'),
            getContent: function() {
                var options = this.shortcode.attrs.named;
                options.text = this.text;
                options.plugin = rusnetim_object.PluginTitle;
                options.innercontent = this.shortcode.content;
                if (typeof ElementorConfig === 'undefined') {
                    return this.template(options);
                }
            },
            View: {
                template: media.template('editor-rusnetim'),
                postID: jQuery('#post_ID').val(),
                initialize: function(options) {
                    this.shortcode = options.shortcode;
                    wp.mce.rusnetim.shortcode_data = this.shortcode;
                },
                getHtml: function() {
                    var options = this.shortcode.attrs.named;
                    options.innercontent = this.shortcode.content;
                    return this.template(options);
                }
            },
            edit: function(data) {
                var shortcode_data = wp.shortcode.next(shortcode_string, data);
                var values = shortcode_data.shortcode.attrs.named;
                values.innercontent = shortcode_data.shortcode.content;
                wp.mce.rusnetim.popupwindow(tinyMCE.activeEditor, values);
            },
            popupwindow: function(editor, values, onsubmit_callback) {
                values = values || [];
                editMapAction = true;
                ym['map0'] = {};
                ym['map0'].places = {};
                for (var key in values) {
                    ym['map0'][key] = values[key];
                    delete ym['map0'].innercontent;
                    findPlaceMarks(values.innercontent);
                }
                mapcenter = ym.map0.center;
                mapzoom = ym.map0.zoom;
                tinymce.activeEditor.execCommand("rusnetim_command");
            }
        };
        wp.mce.views.register(shortcode_string, wp.mce.rusnetim);
    }

    jQuery(document).ready(function($) {
        if (typeof tinymce === 'undefined') {
            console.warn('Rusnetim: TinyMCE not loaded, skipping plugin initialization.');
            return;
        }

        var editor = tinymce.activeEditor;

        function markercolor(pcolor) {
            if (activeplace !== '') {
                placemark[activeplace.replace('placemark', '')].options.set('iconColor', pcolor);
                ym[mapselector].places[activeplace].color = jQuery("#colorbox #colorbox-inp").val();
            }
        }

        function createColorPickAction() {
            var colorPickerCallback = editor.settings.color_picker_callback;
            if (colorPickerCallback) {
                return function() {
                    var self = this;
                    colorPickerCallback.call(
                        editor,
                        function(value) {
                            self.value(value).fire('change');
                            markercolor(self.value());
                        },
                        self.value()
                    );
                };
            }
        }

        tinymce.create("tinymce.plugins.rusnetim_plugin", {
            init: function(ed, url) {
                ed.addButton("rusnetim", {
                    title: rusnetim_object.AddMap,
                    type: 'button',
                    plugins: 'colorpicker',
                    image: url + "/img/placeholder.svg",
                    onclick: function() {
                        editMapAction = false;
                        ed.execCommand("rusnetim_command");
                    }
                });

                ed.addCommand("rusnetim_command", function() {
                    activeplace = "";
                    markcount = 0;

                    jQuery(document).ready(function() {
                        if (!editMapAction) {
                            delete ym.map0.places;
                            ym.map0.places = {};
                        }
                        ymaps.ready(init);
                    });

                    function removeplacemark(map, place) {
                        map.geoObjects.remove(place);
                    }

                    function createplacemark(map, defcoord = [53.334554,83.786980]) {
                        var newmark = false;
                        enablefields();

                        if (!ym.map0.places.hasOwnProperty('placemark' + markcount)) {
                            newmark = true;
                            ym.map0['places']['placemark' + markcount] = {
                                name: '',
                                coord: defcoord,
                                icon: rusnetim_defaults['type_icon_option'],
                                color: jQuery("#colorbox #colorbox-inp").val(),
                                url: '',
                                category: 'all',
                                image: '',
                                description: ''
                            };
                            if (activeplace === '') {
                                activeplace = 'placemark' + markcount;
                                markchange();
                                ym.map0['places']['placemark' + markcount].coord = defcoord;
                            }
                            activeplace = 'placemark' + markcount;
                            markerfields();
                        }

                        placemark[markcount] = new ymaps.Placemark(defcoord, {
                            hintContent: "name",
                            id: 'placemark' + markcount,
                        }, {
                            draggable: true,
                            preset: ym.map0['places']['placemark' + markcount].icon,
                            iconColor: ym.map0['places']['placemark' + markcount].color,
                            zIndex: 1,
                        });

                        activeplace = 'placemark' + markcount;
                        iconname('placemark' + markcount);
                        activeplace = '';
                        coords = defcoord;

                        placemark[markcount].events.add("dragend", function(e) {
                            var trg = e.get('target');
                            var id = trg.properties.get('id');
                            var coords = this.geometry.getCoordinates();
                            console.log('dragend: id=' + id + ', new coords=' + coords);
                            ym.map0['places'][id].coord = coords;
                            activeplace = id;
                            enablefields(true);
                            markerfields();
                            console.log('dragend: после markerfields, coord в объекте=' + ym.map0.places[id].coord);
                        }, placemark[markcount]);

                        placemark[markcount].events.add("dragstart", function(e) {
                            var trg = e.get('target');
                            activeplace = trg.properties.get('id');
                            map.geoObjects.each(function(geoObject) {
                                if (geoObject.properties.get('id') == 'closesvg') {
                                    map.geoObjects.remove(geoObject);
                                }
                            });
                        }, placemark[markcount]);

                        placemark[markcount].events.add('click', function(e) {
                            var trg = e.get('target');
                            var plcoord = e.get('target').geometry.getCoordinates();
                            activeplace = trg.properties.get('id');
                            markerfields();
                            enablefields();

                            map.geoObjects.each(function(geoObject) {
                                if (geoObject.properties.get('id') == 'closesvg') {
                                    map.geoObjects.remove(geoObject);
                                }
                            });

                            var closePlacemark = new ymaps.Placemark(
                                plcoord, {
                                    hintContent: rusnetim_object.MarkerDelete,
                                    id: 'closesvg',
                                }, {
                                    iconLayout: 'default#image',
                                    iconImageHref: url + "/img/close.svg",
                                    iconImageSize: [16, 16],
                                    iconOffset: [-2, -30],
                                    iconImageOffset: [5, 10],
                                    zIndex: 999,
                                }
                            );

                            activeplace = trg.properties.get('id');
                            map.geoObjects.add(closePlacemark);

                            closePlacemark.events.add('click', function(e) {
                                removeplacemark(map, closePlacemark);
                                removeplacemark(map, trg);
                                activeplace = '';
                                inactive();
                                delete ym.map0['places'][trg.properties.get('id')];
                                if (Object.keys(ym.map0.places).length === 0) {
                                    jQuery('#markercoord').val(rusnetim_object.NoCoord);
                                    enablefields(false);
                                }
                            });

                            map.events.add('click', function(e) {
                                removeplacemark(map, closePlacemark);
                            });
                        });

                        map.geoObjects.add(placemark[markcount]);
                        if (newmark) placemark[markcount].events.fire('click');
                        markcount++;
                    }

                    function init() {
                        var myMap = [];
                        var controlsArr = ["zoomControl", "typeSelector"];
                        if (apikeyexist) controlsArr.push("searchControl");

                        mapcenter = ym.map0.center[0];
                        coords = ym.map0.center[0];

                        myMap[mapcount] = new ymaps.Map("yamap", {
                            center: ym.map0.center[0],
                            zoom: ym.map0.zoom,
                            type: ym.map0.maptype,
                            controls: controlsArr
                        }, {
                            suppressMapOpenBlock: true
                        });

                        function loadMap() {
                            if (ym.map0.height !== "undefined") jQuery('#mapheight').val(ym.map0.height);
                            if (ym.map0.controls !== "undefined") jQuery('#mapcontrols').val(ym.map0.controls);
                        }

                        function loadPlacemarks(map) {
                            for (var key in ym.map0['places']) {
                                activeplace = key;
                                createplacemark(myMap[mapcount], coordaprox(ym[map].places[key].coord));
                            }
                            activeplace = "";
                            enablefields(false);
                        }

                        if (editMapAction) {
                            loadPlacemarks('map0');
                            loadMap();
                        }

                        myMap[mapcount].events.add('click', function(e) {
                            createplacemark(myMap[mapcount], e.get('coords'));
                        });

                        if (apikeyexist) {
                            var searchControl = myMap[mapcount].controls.get('searchControl');
                            searchControl.events.add("resultshow", function(e) {
                                var index = e.get('index');
                                var results = searchControl.getResultsArray();
                                if (!results || !results[index]) return;
                                var coords = results[index].geometry.getCoordinates();
                                console.log('resultshow: coords from search =', coords);
                                searchControl.hideResult();

                                if (activeplace !== '') {
                                    var targetPlacemark = null;
                                    for (var i = 0; i < placemark.length; i++) {
                                        if (placemark[i] && placemark[i].properties.get('id') === activeplace) {
                                            targetPlacemark = placemark[i];
                                            break;
                                        }
                                    }
                                    if (targetPlacemark) {
                                        targetPlacemark.geometry.setCoordinates(coords);
                                        ym.map0.places[activeplace].coord = coords;
                                        console.log('resultshow: ym.map0.places[activeplace].coord после обновления =', ym.map0.places[activeplace].coord);
                                        markerfields();
                                        console.log('resultshow: после markerfields, поле coord =', jQuery("#markercoord").val());
                                    } else {
                                        createplacemark(myMap[mapcount], coords);
                                    }
                                } else {
                                    createplacemark(myMap[mapcount], coords);
                                }
                                mapSave();
                            });
                        }

                        myMap[mapcount].events.add('boundschange', function(event) {
                            if (event.get('newZoom') != event.get('oldZoom')) {
                                mapzoom = event.get('newZoom');
                                mapSave();
                            }
                            if (event.get('newCenter') != event.get('oldCenter')) {
                                mapcenter = event.get('newCenter');
                                mapSave();
                            }
                        });

                        maptype = myMap[mapcount].getType();

                        myMap[mapcount].events.add('typechange', function(event) {
                            maptype = myMap[mapcount].getType();
                            mapSave();
                        });

                        iconselectchange();

                        setTimeout(function() {
                            jQuery('#rusnetim_mce_upload_btn').off('click').on('click', function(e) {
                                e.preventDefault();
                                if (typeof wp !== 'undefined' && wp.media) {
                                    var frame = wp.media({
                                        title: 'Select image for marker',
                                        button: { text: 'Insert URL' },
                                        multiple: false,
                                        library: { type: 'image' }
                                    });
                                    frame.on('select', function() {
                                        var attachment = frame.state().get('selection').first().toJSON();
                                        jQuery('#markerimage').val(attachment.id);
                                    });
                                    frame.open();
                                } else {
                                    alert('WordPress media library is unavailable.');
                                }
                            });
                        }, 500);

                        jQuery("#mapheight, #mapcontrols").change(function() {
                            mapdatechange();
                        });

                        jQuery("#scrollzoom, #mobiledrag, #addcontrol a").click(function() {
                            mapdatechange();
                        });

                        jQuery("#cluster").click(function() {
                            mapdatechange();
                        });

                        jQuery("#markername, #markercoord, #markericon-inp, #markerurl, #markercategory-inp, #markerimage, #markerdescription").change(function() {
                            markchange();
                        });

                        jQuery("#markername").change(function() {
                            if (activeplace !== "") {
                                iconname();
                            }
                        });

                        jQuery("#markericon-inp").change(function() {
                            iconselectchange();
                        });

                        jQuery("#addcontrol a").click(function() {
                            if (jQuery("#mapcontrols").val().trim() != "") {
                                jQuery("#mapcontrols").val(jQuery("#mapcontrols").val() + ";");
                            }
                            jQuery("#mapcontrols").val(jQuery("#mapcontrols").val() + jQuery(this).data("control"));
                            mapdatechange();
                        });
                    }

                    function checkApiKeyForSearchField() {
                        if (apikeyexist) {
                            return '<a data-control="searchControl">' + rusnetim_object.search + '</a>, ';
                        } else return '';
                    }

                    var win = ed.windowManager.open({
                        title: checkTitle(),
                        width: 700,
                        height: 620,
                        buttons: [{
                            text: 'OK',
                            classes: 'btn primary',
                            onclick: 'submit',
                            id: 'insertButton'
                        }, {
                            text: 'Close',
                            onclick: 'close',
                            window: win,
                        }],
                        body: [{
                            type: 'container',
                            name: 'container',
                            id: 'yamapcontainer',
                            label: '',
                            html: '<div id="yamap" style="position: relative; min-height: 15rem; margin-bottom: 1rem; overflow: hidden"></div>'
                        }, {
                            layout: 'flow',
                            name: 'tabs',
                            type: 'tabpanel',
                            items: [{
                                type: 'panel',
                                title: rusnetim_object.MarkerTab,
                                items: [{
                                    type: 'form',
                                    name: 'form1',
                                    minWidth: 598,
                                    items: [{
                                        type: 'textbox',
                                        name: 'name',
                                        label: rusnetim_object.MarkerName,
                                        id: "markername",
                                        tooltip: rusnetim_object.MarkerNameTip,
                                        value: "",
                                    }, {
                                        type: 'textbox',
                                        name: 'coord',
                                        label: rusnetim_object.MarkerCoord,
                                        id: 'markercoord',
                                        disabled: true,
                                        value: rusnetim_object.NoCoord,
                                    }, {
                                        type: 'combobox',
                                        name: 'markertype',
                                        label: rusnetim_object.MarkerIcon,
                                        value: rusnetim_defaults['type_icon_option'],
                                        id: "markericon",
                                        onselect: function() {
                                            iconselectchange();
                                        },
                                        values: [{
                                            text: 'islands#blueDotIcon',
                                            value: 'islands#blueDotIcon'
                                        }, {
                                            text: 'islands#blueIcon',
                                            value: 'islands#blueIcon'
                                        }, {
                                            text: 'islands#blueStretchyIcon (' + rusnetim_object.BlueOnly + ')',
                                            value: 'islands#blueStretchyIcon'
                                        }, {
                                            text: 'islands#blueCircleDotIcon',
                                            value: 'islands#blueCircleDotIcon'
                                        }, {
                                            text: 'islands#blueCircleIcon',
                                            value: 'islands#blueCircleIcon'
                                        }],
                                    }, {
                                        type: 'colorbox',
                                        name: 'color',
                                        label: rusnetim_object.MarkerColor,
                                        value: rusnetim_defaults['color_icon_option'],
                                        id: 'colorbox',
                                        onaction: createColorPickAction(),
                                    }, {
                                        type: 'combobox',
                                        name: 'category',
                                        label: rusnetim_object.MarkerCategory || 'Category',
                                        value: 'all',
                                        id: "markercategory",
                                        onselect: function() {
                                            if (activeplace !== '') {
                                                ym[mapselector].places[activeplace].category = jQuery("#markercategory-inp").val();
                                            }
                                        },
                                        values: [{
                                            text: 'All',
                                            value: 'all'
                                        }, {
                                            text: 'Offices',
                                            value: 'offices'
                                        }, {
                                            text: 'Shops',
                                            value: 'shops'
                                        }, {
                                            text: 'Warehouses',
                                            value: 'warehouses'
                                        }, {
                                            text: 'Cafes',
                                            value: 'cafes'
                                        }, {
                                            text: 'Restaurants',
                                            value: 'restaurants'
                                        }, {
                                            text: 'Hotels',
                                            value: 'hotels'
                                        }, {
                                            text: 'ATMs',
                                            value: 'atms'
                                        }, {
                                            text: 'Gas Stations',
                                            value: 'gas-stations'
                                        }, {
                                            text: 'Custom',
                                            value: 'custom'
                                        }],
                                    }, {
                                        type: 'container',
                                        name: 'image_container',
                                        label: 'Image URL',
                                        html: '<div style="display: flex; align-items: center; gap: 4px;">' +
                                              '<input type="text" id="markerimage" name="image" value="" style="flex: 1;" placeholder="URL or ID" />' +
                                              '<button type="button" id="rusnetim_mce_upload_btn" class="button button-small">Select</button>' +
                                              '</div>',
                                        tooltip: 'Select image from WordPress media library',
                                    }, {
                                        type: 'textarea',
                                        name: 'description',
                                        label: 'Description',
                                        id: 'markerdescription',
                                        tooltip: 'HTML description',
                                        rows: 4,
                                    }, {
                                        type: 'textbox',
                                        name: 'url',
                                        label: rusnetim_object.MarkerUrl,
                                        id: 'markerurl',
                                        tooltip: rusnetim_object.MarkerUrlTip,
                                    }, {
                                        type: 'container',
                                        name: 'empty',
                                        minWidth: 598,
                                        html: '<div id="addcontrol2" style="text-align: right; width: 500px;">&nbsp;</div>'
                                    }]
                                }]
                            }, {
                                type: 'panel',
                                title: rusnetim_object.MapTab,
                                items: [{
                                    type: 'form',
                                    name: 'form2',
                                    minWidth: 598,
                                    items: [{
                                        type: 'textbox',
                                        name: 'mapheight',
                                        label: rusnetim_object.MapHeight,
                                        id: 'mapheight',
                                        value: ym[mapselector].height,
                                        maxLength: '10',
                                        tooltip: 'rem, em, px, vh',
                                        onaction: mapdatechange(),
                                    }, {
                                        type: 'textbox',
                                        name: 'controls',
                                        label: rusnetim_object.MapControls,
                                        id: 'mapcontrols',
                                        value: ym[mapselector].controls,
                                        tooltip: rusnetim_object.MapControlsTip,
                                        onaction: mapdatechange(),
                                    }, {
                                        type: 'container',
                                        name: 'addcontrol',
                                        id: 'ctrlhelper',
                                        minWidth: 598,
                                        html: '<div id="addcontrol" style="text-align: right;"><a data-control="typeSelector">' + rusnetim_object.type + '</a>, <a data-control="zoomControl">' + rusnetim_object.zoom + '</a>, ' + checkApiKeyForSearchField() + '<a data-control="routeButtonControl">' + rusnetim_object.route + '</a>, <a data-control="rulerControl">' + rusnetim_object.ruler + '</a>, <a data-control="trafficControl">' + rusnetim_object.traffic + '</a>, <a data-control="fullscreenControl">' + rusnetim_object.fullscreen + '</a>, <a data-control="geolocationControl">' + rusnetim_object.geolocation + '</a></div>'
                                    }, {
                                        type: 'checkbox',
                                        checked: checkParam('scrollzoom'),
                                        name: 'scrollZoom',
                                        label: rusnetim_object.ScrollZoom,
                                        id: 'scrollzoom',
                                        onaction: mapdatechange(),
                                    }, {
                                        type: 'checkbox',
                                        checked: checkParam('mobiledrag'),
                                        name: 'mobileDrag',
                                        label: rusnetim_object.MobileDrag,
                                        id: 'mobiledrag',
                                        onaction: mapdatechange(),
                                    }, {
                                        type: 'textbox',
                                        name: 'type',               
                                        label: 'Map type',
                                        id: 'maptype',
                                        value: ym[mapselector].maptype,
                                        tooltip: 'yandex#map, yandex#satellite, yandex#hybrid',
                                        onaction: mapdatechange(),
                                    }, {
                                        type: 'textbox',
                                        name: 'mapcontainer',
                                        label: rusnetim_object.MapContainerID,
                                        id: 'mapcontainer',
                                        value: ym.map0.container,
                                        tooltip: rusnetim_object.MapContainerIDTip,
                                        onaction: mapdatechange(),
                                    }]
                                }, ]
                            }, {
                                type: 'panel',
                                title: rusnetim_object.ClusterTab || 'Clustering',
                                items: [{
                                    type: 'form',
                                    name: 'formCluster',
                                    minWidth: 598,
                                    items: [{
                                        type: 'checkbox',
                                        checked: checkParam('cluster'),
                                        name: 'cluster',
                                        label: rusnetim_object.ClusterEnable || 'Enable clustering',
                                        id: 'cluster',
                                        onaction: mapdatechange(),
                                    }, {
                                        type: 'textbox',
                                        name: 'clustergrid',
                                        label: rusnetim_object.ClusterGrid || 'Cluster grid size (px)',
                                        id: 'clustergrid',
                                        value: ym[mapselector].clustergrid || '64',
                                        maxLength: '4',
                                        tooltip: '2, 4, 8, 16, 32, 64, 128, 256',
                                        onaction: mapdatechange(),
                                    }, {
                                        type: 'container',
                                        name: 'clusterinfo',
                                        minWidth: 598,
                                        html: '<div style="padding: 10px 0; color: #666;">' + (rusnetim_object.ClusterInfo || 'Clustering groups nearby markers into clusters.<br>The grid size determines how close markers need to be to form a cluster.') + '</div>'
                                    }, ]
                                }, ]
                            }, {
                                type: 'panel',
                                title: rusnetim_object.Extra,
                                items: [{
                                    type: 'form',
                                    name: 'form3',
                                    minWidth: 598,
                                    items: [{
                                        type: 'container',
                                        name: 'addcontrol',
                                        minWidth: 598,
                                        html: rusnetim_object.ExtraHTML,
                                    }, ]
                                }, ]
                            }]
                        }, ],
                        onsubmit: function(e) {
                            mapdatechange();
                            if (activeplace !== "") {
                                markchange();
                                iconname();
                            }
                            contentplacemarks = '';
                            yamapnumber = 'map0';
                            for (var key in ym.map0['places']) {
                                contentplacemarks = contentplacemarks + '[rusnetim_marker ';
                                for (var keyplace in ym.map0['places'][key]) {
                                    if (ym.map0['places'][key][keyplace] !== '') {
                                        contentplacemarks = contentplacemarks + ' ' + keyplace + '="' + ym.map0['places'][key][keyplace] + '"';
                                    }
                                }
                                contentplacemarks = contentplacemarks + ']';
                            }
                            var mapArgs = {
                                tag: 'rusnetim_map',
                                attrs: {
                                    center: ym[yamapnumber].center,
                                    height: ym[yamapnumber].height,
                                    controls: ym[yamapnumber].controls,
                                    zoom: ym[yamapnumber].zoom,
                                    type: ym[yamapnumber].maptype,
                                },
                                content: contentplacemarks,
                            };
                            if (ym[mapselector].container !== "") mapArgs.attrs.container = ym[mapselector].container;
                            if (ym[mapselector].scrollzoom === "0") mapArgs.attrs.scrollzoom = ym[mapselector].scrollzoom;
                            if (ym[mapselector].mobiledrag === "0") mapArgs.attrs.mobiledrag = ym[mapselector].mobiledrag;
                            
                            mapArgs.attrs.cluster = ym[mapselector].cluster;
                            
                            if (ym[mapselector].cluster === "1" && ym[mapselector].clustergrid && ym[mapselector].clustergrid !== "64") mapArgs.attrs.clustergrid = ym[mapselector].clustergrid;
                            if (ym[mapselector].controls !== "") mapArgs.attrs.controls = ym[yamapnumber].controls;
                            ed.insertContent(wp.shortcode.string(mapArgs));
                        }
                    });
                    mapdatechange();
                    mapSave();
                });
            },
            createControl: function(n, cm) {
                return null;
            },
            getInfo: function() {
                return {
                    longname: "Rusnet Interactive Map Plugin",
                    author: "ANO Rusnet",
                    version: "1.0"
                };
            }
        });
        tinymce.PluginManager.add("rusnetim_plugin", tinymce.plugins.rusnetim_plugin);
    });
})();