「Widget:Custom map」の版間の差分

提供:ロマサガ2リメイク 攻略Wiki(ロマンシング サガ2 リベンジオブザセブン)
移動先:案内検索
編集の要約なし
編集の要約なし
1行目: 1行目:
<includeonly>
<includeonly>
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
 
<script src="https://dq.h1g.jp/leaflet/leaflet.js" ></script>
<script src="https://dq.h1g.jp/img/dq10_offline/map/js/leaflet-easy-button.js"></script>
<script src="https://dq.h1g.jp/img/dq10_offline/map/js/leaflet-tag-filter-button.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
<script src="https://dq.h1g.jp/leaflet/custom-leaflet-draw-locale.js" ></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lightgallery/2.7.2/lightgallery.min.js"></script>
 
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"/>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/> 
<link rel="stylesheet" href="https://dq.h1g.jp/img/dq10_offline/map/css/leaflet-easy-button.css" />
<link rel="stylesheet" href="https://dq.h1g.jp/img/dq10_offline/map/css/leaflet-tag-filter-button.css" />
<link rel="stylesheet" href="https://dq.h1g.jp/img/marker-icon-img/editable-popup.css" />
<link rel="stylesheet" href="https://dq.h1g.jp/img/lightgallery.min.css"/>
 
 
<script type="text/javascript">
 
 
 
let map;
var drawnItems;
var drawControl;
var editMode = false;
 
 
// APIベースURLの設定を動的に行い、一度設定したら変更できないようにする
(function() {
    if (typeof window.API_BASE_URL === 'undefined') {
        const currentUrl = new URL(window.location.href);
        const baseUrl = currentUrl.origin + currentUrl.pathname.split('/').slice(0, -1).join('/');
       
        Object.defineProperty(window, 'API_BASE_URL', {
            value: baseUrl,
            writable: false,
            configurable: false,
            enumerable: true
        });
       
        console.log('API_BASE_URL set to:', baseUrl);
       
        // 初期化完了フラグを設定
        window.API_INITIALIZED = true;
    }
})();
 
// APIコールを行う前に必ずURLを検証
function validateAndCallApi(endpoint, options) {
    const currentUrl = new URL(window.location.href);
    const expectedDomain = currentUrl.origin;
      
      
     <script src="https://dq.h1g.jp/leaflet/leaflet.js" ></script>
     if (!window.API_BASE_URL.startsWith(expectedDomain)) {
    <script src="https://dq.h1g.jp/img/dq10_offline/map/js/leaflet-easy-button.js"></script>
        console.error('API URL mismatch detected');
    <script src="https://dq.h1g.jp/img/dq10_offline/map/js/leaflet-tag-filter-button.js"></script>
        return Promise.reject(new Error('Invalid API domain'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script>
    }
    <script src="https://dq.h1g.jp/leaflet/custom-leaflet-draw-locale.js" ></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lightgallery/2.7.2/lightgallery.min.js"></script>
   
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"/>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/> 
    <link rel="stylesheet" href="https://dq.h1g.jp/img/dq10_offline/map/css/leaflet-easy-button.css" />
    <link rel="stylesheet" href="https://dq.h1g.jp/img/dq10_offline/map/css/leaflet-tag-filter-button.css" />
    <link rel="stylesheet" href="https://dq.h1g.jp/img/marker-icon-img/editable-popup.css" />
    <link rel="stylesheet" href="https://dq.h1g.jp/img/lightgallery.min.css"/>
   
   
    <script type="text/javascript">
   
   
   
    let map;
    var drawnItems;
    var drawControl;
    var editMode = false;
    // APIベースURLを定数として定義
    const API_BASE_URL = Object.freeze('https://prd-h1g-elb-2067013247.ap-northeast-1.elb.amazonaws.com/rs2r');
      
      
     // 定数の保護
     // APIコールを実行
     Object.defineProperty(window, 'API_BASE_URL', {
     return $.ajax({
         value: API_BASE_URL,
         url: window.API_BASE_URL + endpoint,
         writable: false,
         ...options
        configurable: false
     });
     });
}
window.savePopupContent = savePopupContent;
// 表示する画像
var imageBase = {
  url: '<!--{$img}-->',
  width: <!--{$imgwidth}-->,          // 画像のサイズ
  height: <!--{$imgheight}-->
};
// 地図初期化
var imageBounds = L.latLngBounds(
  [0, 0],
  [imageBase.height, imageBase.width],
 
);
map = L.map('map', {
  crs: L.CRS.Simple,
  maxBounds: imageBounds.pad(0.5),
  minZoom: <!--{$minzoom}-->, // minZoomを0に設定
  maxZoom: <!--{$maxzoom}-->,


    window.savePopupContent = savePopupContent;
});
   
map.fitBounds(imageBounds);
    // 表示する画像
L.imageOverlay(imageBase.url, imageBounds,{
    var imageBase = {
  attribution: '<a href="https://h1g.jp/" target="_blank">【ヘイグ】</a>'
      url: '<!--{$img}-->',
}).addTo(map);
      width: <!--{$imgwidth}-->,         // 画像のサイズ
 
      height: <!--{$imgheight}-->
var drawnItems = new L.FeatureGroup();
    };
map.addLayer(drawnItems);
   
 
    // 地図初期化
 
     var imageBounds = L.latLngBounds(
// Leaflet.Draw
      [0, 0],
var drawnItems = new L.FeatureGroup();
      [imageBase.height, imageBase.width],
map.addLayer(drawnItems);
     
 
    );
drawControl = new L.Control.Draw({
      
    edit: {
     // マップ初期化前のクリーンアップ
        featureGroup: drawnItems,
     cleanupMap();
        poly: {
     cleanupLocalStorage();
            allowIntersection: false
     cleanupSessionCookies();
        }
    },
    draw: {
        polygon: false,
        polyline: false,
        rectangle: false,
        circle: true,
        marker: true,
        circlemarker: false
    }
});
map.addControl(drawControl);
 
// 初期状態では編集モードを無効にする
drawControl.remove();
 
map.on(L.Draw.Event.CREATED, function (event) {
     var layer = event.layer;
    if (layer instanceof L.Marker) {
        layer.setIcon(iconDefinitions.icon1);
        layer.options.popupData = {title: '', content: '', iconType: 'icon1'};
        var popupContent =
            '<div>' +
            '<textarea id="popup-title" cols="30" rows="1" placeholder="タイトル"></textarea>' +
            '<textarea id="popup-content" cols="30" rows="2" placeholder="内容"></textarea>' +
            '<select id="icon-type">' +
            '<option value="icon1" selected>アイコン1</option>' +
            '<option value="icon2">アイコン2</option>' +
            '<option value="icon3">アイコン3</option>' +
            '<option value="icon4">アイコン4</option>' +
            '<option value="icon5">アイコン5</option>' +
            '<option value="icon6">アイコン6</option>' +
            '</select>' +
            '<button onclick="savePopupContent(this)">保存</button>' +
            '</div>';
        layer.bindPopup(popupContent);
    } else {
        layer.bindPopup('No description');
     }
     createEditablePopup(layer);
     drawnItems.addLayer(layer);
     if (layer instanceof L.Marker) {
        layer.openPopup();
     }
});


     map = L.map('map', {
//////////////////権限を確認
      crs: L.CRS.Simple,
function checkUserGroup(group, callback) {
      maxBounds: imageBounds.pad(0.5),
     $.ajax({
      minZoom: <!--{$minzoom}-->, // minZoomを0に設定
        url: API_BASE_URL + '/api.php',
      maxZoom: <!--{$maxzoom}-->,
        data: {
   
            action: 'query',
    });
            meta: 'userinfo',
    map.fitBounds(imageBounds);
            uiprop: 'groups',
    L.imageOverlay(imageBase.url, imageBounds,{
            format: 'json'
      attribution: '<a href="https://h1g.jp/" target="_blank">【ヘイグ】</a>'
        },
    }).addTo(map);
        type: 'GET',
   
        success: function(data) {
    var drawnItems = new L.FeatureGroup();
            var userGroups = data.query.userinfo.groups;
    map.addLayer(drawnItems);
            var isInGroup = userGroups.indexOf(group) !== -1;
   
            callback(isInGroup);
   
    // Leaflet.Draw
    var drawnItems = new L.FeatureGroup();
    map.addLayer(drawnItems);
   
    drawControl = new L.Control.Draw({
        edit: {
            featureGroup: drawnItems,
            poly: {
                allowIntersection: false
            }
         },
         },
         draw: {
         error: function() {
             polygon: false,
             console.error('Failed to check user group');
             polyline: false,
             callback(false);
            rectangle: false,
            circle: true,
            marker: true,
            circlemarker: false
         }
         }
     });
     });
     map.addControl(drawControl);
}
      
//////////////////////////////////////////////////////////////
     // 初期状態では編集モードを無効にする
// アイコンの定義
     drawControl.remove();
var iconDefinitions = {
      
     icon1: L.icon({
     map.on(L.Draw.Event.CREATED, function (event) {
      iconUrl: '<!--{$icon1|default:'https://dq.h1g.jp/img/marker-icon-img/marker-icon-blue.png'}-->',
        var layer = event.layer;
      shadowUrl: 'https://dq.h1g.jp/img/marker-icon-img/marker-shadow.png',
         if (layer instanceof L.Marker) {
      iconSize: [25, 41],
             layer.setIcon(iconDefinitions.icon1);
      iconAnchor: [12, 41],
             layer.options.popupData = {title: '', content: '', iconType: 'icon1'};
      popupAnchor: [1, -41],
             var popupContent =  
      shadowSize: [41, 41]
    }),
    icon2: L.icon({
      iconUrl: '<!--{$icon2|default:'https://dq.h1g.jp/img/marker-icon-img/marker-icon-red.png'}-->',
      shadowUrl: 'https://dq.h1g.jp/img/marker-icon-img/marker-shadow.png',
      iconSize: [25, 41],
      iconAnchor: [12, 41],
      popupAnchor: [1, -41],
      shadowSize: [41, 41]
     }),
     icon3: L.icon({
      iconUrl: '<!--{$icon3|default:'https://dq.h1g.jp/img/marker-icon-img/marker-icon-violet.png'}-->',
      shadowUrl: 'https://dq.h1g.jp/img/marker-icon-img/marker-shadow.png',
      iconSize: [25, 41],
      iconAnchor: [12, 41],
      popupAnchor: [1, -41],
      shadowSize: [41, 41]
     }),
    icon4: L.icon({
      iconUrl: '<!--{$icon4|default:'https://dq.h1g.jp/img/marker-icon-img/marker-icon-green.png'}-->',
      shadowUrl: 'https://dq.h1g.jp/img/marker-icon-img/marker-shadow.png',
      iconSize: [25, 41],
      iconAnchor: [12, 41],
      popupAnchor: [1, -41],
      shadowSize: [41, 41]
    }),
    icon5: L.icon({
      iconUrl: '<!--{$icon5|default:'https://dq.h1g.jp/img/marker-icon-img/marker-icon-gold.png'}-->',
      shadowUrl: 'https://dq.h1g.jp/img/marker-icon-img/marker-shadow.png',
      iconSize: [25, 41],
      iconAnchor: [12, 41],
      popupAnchor: [1, -41],
      shadowSize: [41, 41]
     }),
     icon6: L.icon({
      iconUrl: '<!--{$icon6|default:'https://dq.h1g.jp/img/marker-icon-img/marker-icon-black.png'}-->',
      shadowUrl: 'https://dq.h1g.jp/img/marker-icon-img/marker-shadow.png',
      iconSize: [25, 41],
      iconAnchor: [12, 41],
      popupAnchor: [1, -41],
      shadowSize: [41, 41]
    })
};
 
 
// ポップアップの作成
function createEditablePopup(layer) {
    var popupData = layer.options.popupData || {};
    var title = popupData.title || '';
    var content = popupData.content || '';
    var iconType = popupData.iconType || 'icon1';
 
    layer.on('popupopen', function() {
        var popup = this.getPopup();
        var popupData = this.options.popupData || {};
        var title = popupData.title || '';
        var content = popupData.content || '';
        var iconType = popupData.iconType || 'icon1';
 
 
 
        // タイトルと内容が両方空の場合、ポップアップを表示しない
         if (!editMode && title === '' && content === '') {
             layer.closePopup();
            // カーソルをデフォルトに設定
             layer._icon.style.cursor = 'default';
            return;
        }
 
        if (editMode) { // 編集モードの場合のみtextareaを表示
            var iconSelector = '';
            if (layer instanceof L.Marker) {
                iconSelector = '<select id="icon-type">' +
                    '<option value="icon1"' + (iconType === 'icon1' ? ' selected' : '') + '>アイコン1</option>' +
                    '<option value="icon2"' + (iconType === 'icon2' ? ' selected' : '') + '>アイコン2</option>' +
                    '<option value="icon3"' + (iconType === 'icon3' ? ' selected' : '') + '>アイコン3</option>' +
                    '<option value="icon4"' + (iconType === 'icon4' ? ' selected' : '') + '>アイコン4</option>' +
                    '<option value="icon5"' + (iconType === 'icon5' ? ' selected' : '') + '>アイコン5</option>' +
                    '<option value="icon6"' + (iconType === 'icon6' ? ' selected' : '') + '>アイコン6</option>' +
                '</select>';
            }
 
             var editableContent =  
                 '<div>' +
                 '<div>' +
                 '<textarea id="popup-title" cols="30" rows="1" placeholder="タイトル"></textarea>' +
                 '<textarea id="popup-title" cols="60" rows="3" placeholder="タイトル">' + title + '</textarea>' +
                 '<textarea id="popup-content" cols="30" rows="2" placeholder="内容"></textarea>' +
                 '<textarea id="popup-content" cols="60" rows="10" placeholder="内容">' + content + '</textarea>' +
                '<select id="icon-type">' +
                 iconSelector +
                '<option value="icon1" selected>アイコン1</option>' +
                '<option value="icon2">アイコン2</option>' +
                '<option value="icon3">アイコン3</option>' +
                 '<option value="icon4">アイコン4</option>' +
                '<option value="icon5">アイコン5</option>' +
                '<option value="icon6">アイコン6</option>' +
                '</select>' +
                 '<button onclick="savePopupContent(this)">保存</button>' +
                 '<button onclick="savePopupContent(this)">保存</button>' +
                 '</div>';
                 '</div>';
             layer.bindPopup(popupContent);
             popup.setContent(editableContent);
         } else {
         } else {
             layer.bindPopup('No description');
             // 編集モードでない場合は表示用のコンテンツを設定
        }
            if (title === '' && content === '') {
        createEditablePopup(layer);
                layer.unbindPopup(); // タイトルと内容が空の場合はポップアップを表示しない
        drawnItems.addLayer(layer);
            } else {
        if (layer instanceof L.Marker) {
                var displayContent = '<strong>' + title + '</strong><br>' + content;
             layer.openPopup();
                var renderedContent = renderMediaWikiContent(displayContent);
                popup.setContent(renderedContent);
             }
         }
         }
     });
     });


     // クリーンアップ関数群を追加
     // 既にポップアップが設定されている場合に備え、再設定
function cleanupMap() {
     if (!(title === '' && content === '')) {
     if (map) {
        var displayContent = '<strong>' + title + '</strong><br>' + content;
        map.eachLayer((layer) => {
         var renderedContent = renderMediaWikiContent(displayContent);
            map.removeLayer(layer);
         layer.bindPopup(renderedContent);
        });
       
        for (let i in map._controlCorners) {
            map._controlCorners[i].innerHTML = '';
        }
       
        if (drawnItems) {
            drawnItems.clearLayers();
        }
       
        map.off();
       
        $('.leaflet-popup-content').each(function() {
            if ($(this).data('lightGallery')) {
                $(this).data('lightGallery').destroy(true);
            }
         });
          
        $('.lg-container').remove();
     }
     }
}
}


function cleanupLocalStorage() {
 
     Object.keys(localStorage).forEach(key => {
 
         if (key.includes('MediaWikiModuleStore')) {
 
             localStorage.removeItem(key);
// MediaWikiコンテンツのレンダリング
function renderMediaWikiContent(content) {
     var renderedContent = '';
    $.ajax({
        url: API_BASE_URL + '/api.php',
        data: {
            action: 'parse',
            text: content,
            format: 'json'
        },
         async: false,
        success: function(data) {
            renderedContent = data.parse.text['*'];
            // レンダリング後の画像処理
            setTimeout(function() {
                initLightGallery(renderedContent);
            }, 100);
        },
        error: function() {
             console.error('Failed to render MediaWiki content');
         }
         }
     });
     });
    return renderedContent;
}
}


function cleanupSessionCookies() {
 
     document.cookie.split(';').forEach(cookie => {
// LightGalleryの初期化を修正
        const name = cookie.split('=')[0].trim();
function initLightGallery(content) {
        if (name.includes('mwuser-sessionId')) {
     const popupContent = $('.leaflet-popup-content');
            document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
        }
    });
}
      
      
     //////////////////権限を確認
     // 既存のLightGalleryインスタンスを破棄
     function checkUserGroup(group, callback) {
     if (popupContent.data('lightGallery')) {
        $.ajax({
        popupContent.data('lightGallery').destroy(true);
            url: API_BASE_URL + '/api.php',
            data: {
                action: 'query',
                meta: 'userinfo',
                uiprop: 'groups',
                format: 'json'
            },
            type: 'GET',
            success: function(data) {
                var userGroups = data.query.userinfo.groups;
                var isInGroup = userGroups.indexOf(group) !== -1;
                callback(isInGroup);
            },
            error: function() {
                console.error('Failed to check user group');
                callback(false);
            }
        });
     }
     }
    //////////////////////////////////////////////////////////////
 
     // アイコンの定義
     // 既存のlg-containerを削除
     var iconDefinitions = {
     $('.lg-container').remove();
        icon1: L.icon({
          iconUrl: '<!--{$icon1|default:'https://dq.h1g.jp/img/marker-icon-img/marker-icon-blue.png'}-->',
          shadowUrl: 'https://dq.h1g.jp/img/marker-icon-img/marker-shadow.png',
          iconSize: [25, 41],
          iconAnchor: [12, 41],
          popupAnchor: [1, -41],
          shadowSize: [41, 41]
        }),
        icon2: L.icon({
          iconUrl: '<!--{$icon2|default:'https://dq.h1g.jp/img/marker-icon-img/marker-icon-red.png'}-->',
          shadowUrl: 'https://dq.h1g.jp/img/marker-icon-img/marker-shadow.png',
          iconSize: [25, 41],
          iconAnchor: [12, 41],
          popupAnchor: [1, -41],
          shadowSize: [41, 41]
        }),
        icon3: L.icon({
          iconUrl: '<!--{$icon3|default:'https://dq.h1g.jp/img/marker-icon-img/marker-icon-violet.png'}-->',
          shadowUrl: 'https://dq.h1g.jp/img/marker-icon-img/marker-shadow.png',
          iconSize: [25, 41],
          iconAnchor: [12, 41],
          popupAnchor: [1, -41],
          shadowSize: [41, 41]
        }),
        icon4: L.icon({
          iconUrl: '<!--{$icon4|default:'https://dq.h1g.jp/img/marker-icon-img/marker-icon-green.png'}-->',
          shadowUrl: 'https://dq.h1g.jp/img/marker-icon-img/marker-shadow.png',
          iconSize: [25, 41],
          iconAnchor: [12, 41],
          popupAnchor: [1, -41],
          shadowSize: [41, 41]
        }),
        icon5: L.icon({
          iconUrl: '<!--{$icon5|default:'https://dq.h1g.jp/img/marker-icon-img/marker-icon-gold.png'}-->',
          shadowUrl: 'https://dq.h1g.jp/img/marker-icon-img/marker-shadow.png',
          iconSize: [25, 41],
          iconAnchor: [12, 41],
          popupAnchor: [1, -41],
          shadowSize: [41, 41]
        }),
        icon6: L.icon({
          iconUrl: '<!--{$icon6|default:'https://dq.h1g.jp/img/marker-icon-img/marker-icon-black.png'}-->',
          shadowUrl: 'https://dq.h1g.jp/img/marker-icon-img/marker-shadow.png',
          iconSize: [25, 41],
          iconAnchor: [12, 41],
          popupAnchor: [1, -41],
          shadowSize: [41, 41]
        })
    };
      
      
      
     popupContent.find('img').each(function() {
    // ポップアップの作成
        const img = $(this);
    function createEditablePopup(layer) {
        // gallery-itemクラスを持つdivで既に囲まれていない場合のみ処理
        var popupData = layer.options.popupData || {};
        if (!img.parent().hasClass('gallery-item')) {
        var title = popupData.title || '';
            let fullSizeUrl = convertToFullSize(img.attr('src'));
        var content = popupData.content || '';
            img.wrap('<div class="gallery-item" data-src="' + fullSizeUrl + '"></div>');
        var iconType = popupData.iconType || 'icon1';
        }
   
    });
        layer.on('popupopen', function() {
 
            var popup = this.getPopup();
    // LightGalleryを初期化(ナビゲーション矢印を非表示に)
            var popupData = this.options.popupData || {};
    if (!popupContent.data('lightGallery')) {
            var title = popupData.title || '';
        lightGallery(popupContent[0], {
            var content = popupData.content || '';
            selector: '.gallery-item',
            var iconType = popupData.iconType || 'icon1';
            plugins: [],
   
            speed: 500,
   
            download: false,
   
            counter: false,
            // タイトルと内容が両方空の場合、ポップアップを表示しない
            enableDrag: false,
            if (!editMode && title === '' && content === '') {
            enableTouch: false,
                layer.closePopup();
            hideControlOnEnd: true,
                // カーソルをデフォルトに設定
            controls: false,
                layer._icon.style.cursor = 'default';
            prevHtml: '',
                return;
            nextHtml: '',
            }
             backdropDuration: 300,  // 背景のフェード時間
   
            if (editMode) {  // 編集モードの場合のみtextareaを表示
                var iconSelector = '';
                if (layer instanceof L.Marker) {
                    iconSelector = '<select id="icon-type">' +
                        '<option value="icon1"' + (iconType === 'icon1' ? ' selected' : '') + '>アイコン1</option>' +
                        '<option value="icon2"' + (iconType === 'icon2' ? ' selected' : '') + '>アイコン2</option>' +
                        '<option value="icon3"' + (iconType === 'icon3' ? ' selected' : '') + '>アイコン3</option>' +
                        '<option value="icon4"' + (iconType === 'icon4' ? ' selected' : '') + '>アイコン4</option>' +
                        '<option value="icon5"' + (iconType === 'icon5' ? ' selected' : '') + '>アイコン5</option>' +
                        '<option value="icon6"' + (iconType === 'icon6' ? ' selected' : '') + '>アイコン6</option>' +
                    '</select>';
                }
   
                var editableContent =
                    '<div>' +
                    '<textarea id="popup-title" cols="60" rows="3" placeholder="タイトル">' + title + '</textarea>' +
                    '<textarea id="popup-content" cols="60" rows="10" placeholder="内容">' + content + '</textarea>' +
                    iconSelector +
                    '<button onclick="savePopupContent(this)">保存</button>' +
                    '</div>';
                popup.setContent(editableContent);
            } else {
                // 編集モードでない場合は表示用のコンテンツを設定
                if (title === '' && content === '') {
                    layer.unbindPopup(); // タイトルと内容が空の場合はポップアップを表示しない
                } else {
                    var displayContent = '<strong>' + title + '</strong><br>' + content;
                    var renderedContent = renderMediaWikiContent(displayContent);
                    popup.setContent(renderedContent);
                }
             }
         });
         });
   
        // 既にポップアップが設定されている場合に備え、再設定
        if (!(title === '' && content === '')) {
            var displayContent = '<strong>' + title + '</strong><br>' + content;
            var renderedContent = renderMediaWikiContent(displayContent);
            layer.bindPopup(renderedContent);
        }
     }
     }
   
}
   
 
   
 
   
// ポップアップが閉じられたときの処理を追加
    // MediaWikiコンテンツのレンダリング
map.on('popupclose', function(e) {
    function renderMediaWikiContent(content) {
    const popupContent = $(e.popup.getContent());
        var renderedContent = '';
    if (popupContent.data('lightGallery')) {
        $.ajax({
        popupContent.data('lightGallery').destroy(true);
            url: API_BASE_URL + '/api.php',
            data: {
                action: 'parse',
                text: content,
                format: 'json'
            },
            async: false,
            success: function(data) {
                renderedContent = data.parse.text['*'];
                // レンダリング後の画像処理
                setTimeout(function() {
                    initLightGallery(renderedContent);
                }, 100);
            },
            error: function() {
                console.error('Failed to render MediaWiki content');
            }
        });
        return renderedContent;
     }
     }
   
});
   
 
    // LightGalleryの初期化を修正
// MediaWikiの画像URLを最大サイズに変換する関数
    function initLightGallery(content) {
function convertToFullSize(url) {
        const popupContent = $('.leaflet-popup-content');
    // MediaWikiのサムネイルURLをパースして最大サイズのURLに変換
       
    if (url.includes('/thumb/')) {
        // 既存のLightGalleryインスタンスを破棄
         // /thumb/を除去し、最後の/以降を削除して元のファイル名に戻す
        if (popupContent.data('lightGallery')) {
         return url.replace('/thumb/', '/')
            popupContent.data('lightGallery').destroy(true);
                .replace(/\/\d+px-[^/]+$/, '');
        }
   
         // 既存のlg-containerを削除
        $('.lg-container').remove();
       
         popupContent.find('img').each(function() {
            const img = $(this);
            // gallery-itemクラスを持つdivで既に囲まれていない場合のみ処理
            if (!img.parent().hasClass('gallery-item')) {
                let fullSizeUrl = convertToFullSize(img.attr('src'));
                img.wrap('<div class="gallery-item" data-src="' + fullSizeUrl + '"></div>');
            }
        });
   
        // LightGalleryを初期化(ナビゲーション矢印を非表示に)
        if (!popupContent.data('lightGallery')) {
            lightGallery(popupContent[0], {
                selector: '.gallery-item',
                plugins: [],
                speed: 500,
                download: false,
                counter: false,
                enableDrag: false,
                enableTouch: false,
                hideControlOnEnd: true,
                controls: false,
                prevHtml: '',
                nextHtml: '',
                backdropDuration: 300,  // 背景のフェード時間
            });
        }
     }
     }
      
     return url;
   
}
    // ポップアップが閉じられたときの処理を追加
 
    map.on('popupclose', function(e) {
// ポップアップが開かれたときのイベントを追加
         const popupContent = $(e.popup.getContent());
map.on('popupopen', function(e) {
         if (popupContent.data('lightGallery')) {
    setTimeout(function() {
             popupContent.data('lightGallery').destroy(true);
         initLightGallery(e.popup.getContent());
    }, 100);
});
 
 
// マップのクリーンアップ処理も追加
map.on('unload', function() {
    $('.lg-container').remove();
    $('.leaflet-popup-content').each(function() {
         if ($(this).data('lightGallery')) {
             $(this).data('lightGallery').destroy(true);
         }
         }
     });
     });
});
/// スタイルを更新
const styles = `
<style>
.gallery-item {
    cursor: pointer;
    display: inline-block;
}
.gallery-item img {
    max-width: 200px;
    height: auto;
    transition: transform 0.3s ease;
}
.gallery-item:hover img {
    transform: scale(1.05);
}
.lg-img-wrap {
    text-align: center;
}
.lg-img-wrap img {
    max-height: 90vh !important;
    max-width: 90vw !important;
    object-fit: contain;
}
/* ナビゲーション矢印を非表示 */
.lg-next, .lg-prev {
    display: none !important;
}
</style>
`;
// ポップアップの内容を保存
function savePopupContent(button) {
    var popup = button.closest('.leaflet-popup');
    var content = popup.querySelector('.leaflet-popup-content');
    var title = content.querySelector('#popup-title').value;
    var text = content.querySelector('#popup-content').value;
    var iconType = content.querySelector('#icon-type') ? content.querySelector('#icon-type').value : null;
      
      
     // MediaWikiの画像URLを最大サイズに変換する関数
     var layer = drawnItems.getLayers().find(function(layer) {
    function convertToFullSize(url) {
         return layer.getPopup() && layer.getPopup().getElement() === popup;
         // MediaWikiのサムネイルURLをパースして最大サイズのURLに変換
    });
        if (url.includes('/thumb/')) {
            // /thumb/を除去し、最後の/以降を削除して元のファイル名に戻す
            return url.replace('/thumb/', '/')
                    .replace(/\/\d+px-[^/]+$/, '');
        }
        return url;
    }
      
      
     // ポップアップが開かれたときのイベントを追加
     if (layer) {
    map.on('popupopen', function(e) {
        var savedContent = '<strong>' + title + '</strong><br>' + text;
        layer.setPopupContent(savedContent);
        layer.options.popupData = {title: title, content: text, iconType: iconType};
       
        // ポップアップを更新した後にLightGalleryを再初期化
         setTimeout(function() {
         setTimeout(function() {
             initLightGallery(e.popup.getContent());
             initLightGallery(savedContent);
         }, 100);
         }, 100);
       
        layer.closePopup();
        layer.openPopup();
    }
}
// 編集イベントのリスナーも追加
map.on(L.Draw.Event.EDITED, function (event) {
    var layers = event.layers;
    layers.eachLayer(function (layer) {
        drawnItems.addLayer(layer);
     });
     });
      
});
      
 
     // マップのクリーンアップ処理も追加
// 削除イベントのリスナーも追加
     map.on('unload', function() {
map.on(L.Draw.Event.DELETED, function (event) {
        $('.lg-container').remove();
     var layers = event.layers;
         $('.leaflet-popup-content').each(function() {
     layers.eachLayer(function (layer) {
            if ($(this).data('lightGallery')) {
        drawnItems.removeLayer(layer);
                 $(this).data('lightGallery').destroy(true);
     });
});
 
// 編集ボタン
var editButton = L.easyButton({
     states: [{
        stateName: 'enable-edit',
        icon: '<img src="https://dq.h1g.jp/img/marker-icon-img/edit-solid.svg">',
        title: 'マップを編集する',
        onClick: function(btn, map) {
//          checkUserGroup('map-edit-member', function(isInGroup) {
          checkUserGroup('sysop', function(isInGroup) {
//          checkUserGroup('internal-staff', function(isInGroup) {
            if (isInGroup) {
                    editMode = true;
                    map.addControl(drawControl);
                    btn.state('disable-edit');
                    updateAllPopups();
                    saveButton.addTo(map); // saveButtonを表示する
                } else {
//                    alert('あなたには編集権限がありません。\n攻略に参加することでマップが編集できるようになります。');
                    alert('あなたには編集権限がありません。');
                }
            });
         }
    }, {
        stateName: 'disable-edit',
        icon: '<img src="https://dq.h1g.jp/img/marker-icon-img/edit-solid.svg">',
        title: '編集の終了',
        onClick: function(btn, map) {
            editMode = false;
            drawControl.remove();
            btn.state('enable-edit');
            updateAllPopups();
            saveButton.remove(); // saveButtonを非表示にする
        }
    }]
}).addTo(map);
 
function updateAllPopups() {
    drawnItems.eachLayer(function(layer) {
        if (layer.getPopup()) {
            layer.closePopup();
            if (editMode) {
                 createEditablePopup(layer);
                layer.openPopup();
            } else if (!(layer.options.popupData && layer.options.popupData.title === '' && layer.options.popupData.content === '')) {
                layer.bindPopup(layer.options.popupData.title + "<br>" + layer.options.popupData.content);
             }
             }
         });
         }
     });
     });
   
}
    /// スタイルを更新
 
    const styles = `
// 保存ボタン
    <style>
var saveButton = L.easyButton('<img src="https://dq.h1g.jp/img/marker-icon-img/save-solid.svg">', function() {
    .gallery-item {
    if (editMode) {
        cursor: pointer;
         var geoJSONData = convertToGeoJSON(drawnItems);
        display: inline-block;
         if (geoJSONData) {
    }
//            console.log(geoJSONData);
    .gallery-item img {
            saveToWikiPage(geoJSONData);
        max-width: 200px;
             saveButton.remove(); // saveButtonを非表示にする
        height: auto;
         } else {
        transition: transform 0.3s ease;
             alert('Error: Invalid GeoJSON data');
    }
    .gallery-item:hover img {
        transform: scale(1.05);
    }
   
    .lg-img-wrap {
        text-align: center;
    }
    .lg-img-wrap img {
        max-height: 90vh !important;
        max-width: 90vw !important;
        object-fit: contain;
    }
    /* ナビゲーション矢印を非表示 */
    .lg-next, .lg-prev {
        display: none !important;
    }
    </style>
    `;
   
   
   
    // ポップアップの内容を保存
    function savePopupContent(button) {
        var popup = button.closest('.leaflet-popup');
         var content = popup.querySelector('.leaflet-popup-content');
         var title = content.querySelector('#popup-title').value;
        var text = content.querySelector('#popup-content').value;
        var iconType = content.querySelector('#icon-type') ? content.querySelector('#icon-type').value : null;
       
        var layer = drawnItems.getLayers().find(function(layer) {
             return layer.getPopup() && layer.getPopup().getElement() === popup;
         });
       
        if (layer) {
             var savedContent = '<strong>' + title + '</strong><br>' + text;
            layer.setPopupContent(savedContent);
            layer.options.popupData = {title: title, content: text, iconType: iconType};
           
            // ポップアップを更新した後にLightGalleryを再初期化
            setTimeout(function() {
                initLightGallery(savedContent);
            }, 100);
           
            layer.closePopup();
            layer.openPopup();
         }
         }
    } else {
        alert('Please enable edit mode before saving.');
     }
     }
   
}, '変更を保存');
   
 
    // 編集イベントのリスナーも追加
 
    map.on(L.Draw.Event.EDITED, function (event) {
 
        var layers = event.layers;
 
        layers.eachLayer(function (layer) {
function loadPinsFromWikiPage() {
            drawnItems.addLayer(layer);
     getMwToken()
        });
         .then(function(token) {
    });
             return validateAndCallApi('/api.php', {
   
                type: "GET",
    // 削除イベントのリスナーも追加
                data: {
     map.on(L.Draw.Event.DELETED, function (event) {
                    action: 'query',
        var layers = event.layers;
                    titles: "<!--{$geojson}-->",
         layers.eachLayer(function (layer) {
                     prop: 'revisions',
             drawnItems.removeLayer(layer);
                    rvprop: 'content',
        });
                    format: 'json',
    });
                    redirects: 0
   
                 },
    // 編集ボタン
                 headers: {
    var editButton = L.easyButton({
                     'Authorization': 'Bearer ' + token
        states: [{
            stateName: 'enable-edit',
            icon: '<img src="https://dq.h1g.jp/img/marker-icon-img/edit-solid.svg">',
            title: 'マップを編集する',
            onClick: function(btn, map) {
    //          checkUserGroup('map-edit-member', function(isInGroup) {
              checkUserGroup('sysop', function(isInGroup) {
    //          checkUserGroup('internal-staff', function(isInGroup) {
                if (isInGroup) {
                        editMode = true;
                        map.addControl(drawControl);
                        btn.state('disable-edit');
                        updateAllPopups();
                        saveButton.addTo(map); // saveButtonを表示する
                    } else {
    //                    alert('あなたには編集権限がありません。\n攻略に参加することでマップが編集できるようになります。');
                        alert('あなたには編集権限がありません。');
                     }
                });
            }
        }, {
            stateName: 'disable-edit',
            icon: '<img src="https://dq.h1g.jp/img/marker-icon-img/edit-solid.svg">',
            title: '編集の終了',
            onClick: function(btn, map) {
                editMode = false;
                 drawControl.remove();
                btn.state('enable-edit');
                updateAllPopups();
                saveButton.remove(); // saveButtonを非表示にする
            }
        }]
    }).addTo(map);
   
    function updateAllPopups() {
        drawnItems.eachLayer(function(layer) {
            if (layer.getPopup()) {
                 layer.closePopup();
                if (editMode) {
                     createEditablePopup(layer);
                    layer.openPopup();
                } else if (!(layer.options.popupData && layer.options.popupData.title === '' && layer.options.popupData.content === '')) {
                    layer.bindPopup(layer.options.popupData.title + "<br>" + layer.options.popupData.content);
                 }
                 }
            });
        })
        .then(function(response) {
            try {
                // レスポンスからページコンテンツを取得
                const pages = response.query.pages;
                const pageId = Object.keys(pages)[0];
                const content = pages[pageId].revisions[0]['*'];
               
                // GeoJSONデータを抽出して処理
                const geoJSONData = JSON.parse(content);
                processGeoJSONData(geoJSONData);
            } catch (error) {
                console.error("Error processing data:", error);
                throw error;
             }
             }
        })
        .catch(function(error) {
            console.error("Error loading data:", error);
            // より詳細なエラー情報を表示
            console.error('Detailed error:', {
                message: error.message,
                status: error.status,
                responseText: error.responseText
            });
         });
         });
    }
}
      
 
    // 保存ボタン
 
     var saveButton = L.easyButton('<img src="https://dq.h1g.jp/img/marker-icon-img/save-solid.svg">', function() {
function processGeoJSONData(geoJSON) {
         if (editMode) {
     drawnItems.clearLayers();
             var geoJSONData = convertToGeoJSON(drawnItems);
 
             if (geoJSONData) {
     L.geoJSON(geoJSON, {
    //            console.log(geoJSONData);
         pointToLayer: function (feature, latlng) {
                saveToWikiPage(geoJSONData);
             var iconType = feature.properties.iconType || 'icon1';
                 saveButton.remove(); // saveButtonを非表示にする
            var icon = iconDefinitions[iconType] || iconDefinitions.icon1;
           
             if (feature.properties.radius) {
                return L.circle(latlng, {
                    radius: feature.properties.radius,
                    tags: feature.properties.tags
                 });
             } else {
             } else {
                 alert('Error: Invalid GeoJSON data');
                 return L.marker(latlng, {
                    icon: icon,
                    tags: feature.properties.tags
                });
             }
             }
        },
        onEachFeature: function (feature, layer) {
            var popupContent = '<strong>' + feature.properties.title + '</strong><br>' + feature.properties.content;
            layer.bindPopup(popupContent);
            layer.options.popupData = {
                title: feature.properties.title,
                content: feature.properties.content,
                iconType: feature.properties.iconType,
                tags: feature.properties.tags
            };
            createEditablePopup(layer);
            drawnItems.addLayer(layer);
        }
    });
}
 
//////////////////////////////////////////////////////////////////////////////
function convertToGeoJSON(drawnItems) {
    var geoJSON = {
        "type": "FeatureCollection",
        "features": []
    };
    drawnItems.eachLayer(function(layer) {
        var feature = layer.toGeoJSON();
        var popupData = layer.options.popupData || {};
        feature.properties = {
            title: popupData.title || '',
            content: popupData.content || '',
            iconType: popupData.iconType || 'icon1',
            tags: popupData.tags || [getTagFromIconType(popupData.iconType || 'icon1')]
        };
        if (layer instanceof L.Circle) {
            feature.properties.radius = layer.getRadius();
            feature.geometry = {
                type: "Point",
                coordinates: [layer.getLatLng().lng, layer.getLatLng().lat]
            };
        } else if (layer instanceof L.Marker) {
            feature.geometry = {
                type: "Point",
                coordinates: [layer.getLatLng().lng, layer.getLatLng().lat]
            };
         } else {
         } else {
             alert('Please enable edit mode before saving.');
             // その他のタイプのレイヤーは無視する
            return;
         }
         }
     }, '変更を保存');
 
   
        geoJSON.features.push(feature);
      
     });
      
 
     
     // GeoJSONデータの有効性をチェック
     function loadPinsFromWikiPage() {
     try {
         getMwToken()
        JSON.parse(JSON.stringify(geoJSON));
            .then(function(token) {
     } catch (error) {
                var geojsonPage = "<!--{$geojson}-->";
         console.error("Invalid GeoJSON data:", error);
                var url = API_BASE_URL + '/api.php';
        return null;
                console.log('Request URL:', url);
    }
   
 
                return $.ajax({
    return JSON.stringify(geoJSON, null, 2); // 整形されたJSONを返す
                    type: "GET",
}
                    url: url,
 
                    data: {
 
                        action: 'query',
function getTagFromIconType(iconType) {
                        titles: geojsonPage,
    switch (iconType) {
                        prop: 'revisions',
        case 'icon1':
                        rvprop: 'content',
            return '<!--{$filter1|default:"分類1"}-->';
                        format: 'json',
        case 'icon2':
                        // 明示的にwikiを指定
            return '<!--{$filter2|default:"分類2"}-->';
                        redirects: 0  // リダイレクトを防ぐ
        case 'icon3':
                    },
            return '<!--{$filter3|default:"分類3"}-->';
                    headers: {
        case 'icon4':
                        'Authorization': 'Bearer ' + token
            return '<!--{$filter4|default:"分類4"}-->';
                    }
        case 'icon5':
                });
            return '<!--{$filter5|default:"分類5"}-->';
            })
        case 'icon6':
            .then(function(response) {
            return '<!--{$filter6|default:"分類6"}-->';
                try {
        default:
                    // レスポンスからページコンテンツを取得
            return '';
                    const pages = response.query.pages;
    }
                    const pageId = Object.keys(pages)[0];
}
                    const content = pages[pageId].revisions[0]['*'];
 
                   
  // フィルタボタンの定義
                    // GeoJSONデータを抽出して処理
 
                    const geoJSONData = JSON.parse(content);
// Leaflet.Control.TagFilterButton の設定
                    processGeoJSONData(geoJSONData);
L.control.tagFilterButton({
                } catch (error) {
    data: [
                    console.error("Error processing data:", error);
        '<!--{$filter1|default:"分類1"}-->',
                    throw error;
        '<!--{$filter2|default:"分類2"}-->',
                }
        '<!--{$filter3|default:"分類3"}-->',
            })
        '<!--{$filter4|default:"分類4"}-->',
            .catch(function(error) {
        '<!--{$filter5|default:"分類5"}-->',
                console.error("Error loading data:", error);
        '<!--{$filter6|default:"分類6"}-->'
                // より詳細なエラー情報を表示
    ],
                console.error('Detailed error:', {
    icon: '<img src="https://dq.h1g.jp/img/marker-icon-img/filter.png">',
                    message: error.message,
    filterOnEveryClick: true
                    status: error.status,
}).addTo(map);
                    responseText: error.responseText
 
                });
// トークンを取得する関数の前に追加
            });
function validateToken(token) {
    if (!token || typeof token !== 'string') {
        console.warn('Invalid token format');
        return false;
     }
     }
      
     return true;
   
}
    function processGeoJSONData(geoJSON) {
 
         drawnItems.clearLayers();
function getMwToken() {
   
    return new Promise((resolve, reject) => {
         L.geoJSON(geoJSON, {
        const apiUrl = API_BASE_URL + '/api.php';
             pointToLayer: function (feature, latlng) {
         console.log('Requesting token from:', apiUrl); // APIリクエストURLの確認
                 var iconType = feature.properties.iconType || 'icon1';
 
                var icon = iconDefinitions[iconType] || iconDefinitions.icon1;
         $.ajax({
            url: apiUrl,
            data: {
                action: 'query',
                meta: 'tokens',
                type: 'csrf',
                format: 'json'
            },
             type: 'GET',
            success: function(response) {
                 console.log('Token response:', response); // レスポンスの確認
                  
                  
                 if (feature.properties.radius) {
                 if (response.query && response.query.tokens && response.query.tokens.csrftoken) {
                     return L.circle(latlng, {
                     const token = response.query.tokens.csrftoken;
                        radius: feature.properties.radius,
                    // トークンの検証を一時的に緩和
                        tags: feature.properties.tags
                     resolve(token);
                     });
                 } else {
                 } else {
                     return L.marker(latlng, {
                     console.error('Invalid token response structure:', response);
                        icon: icon,
                     reject(new Error('Failed to get token'));
                        tags: feature.properties.tags
                     });
                 }
                 }
             },
             },
             onEachFeature: function (feature, layer) {
             error: function(xhr, status, error) {
                 var popupContent = '<strong>' + feature.properties.title + '</strong><br>' + feature.properties.content;
                 console.error('Token request failed:', {
                layer.bindPopup(popupContent);
                     status: status,
                layer.options.popupData = {
                     error: error,
                     title: feature.properties.title,
                     response: xhr.responseText
                    content: feature.properties.content,
                 });
                     iconType: feature.properties.iconType,
                 reject(error);
                     tags: feature.properties.tags
                 };
                createEditablePopup(layer);
   
                 drawnItems.addLayer(layer);
             }
             }
         });
         });
     }
     });
}
 
function saveToWikiPage(geoJSONData) {
    var formattedData = geoJSONData;
      
      
      
     // 保存前に新しいトークンを取得
     
     getMwToken()
   
         .then(function(token) {
   
             return $.ajax({
    //////////////////////////////////////////////////////////////////////////////
                 type: "POST",
     function convertToGeoJSON(drawnItems) {
        var geoJSON = {
            "type": "FeatureCollection",
            "features": []
        };
   
         drawnItems.eachLayer(function(layer) {
             var feature = layer.toGeoJSON();
            var popupData = layer.options.popupData || {};
            feature.properties = {
                 title: popupData.title || '',
                content: popupData.content || '',
                iconType: popupData.iconType || 'icon1',
                tags: popupData.tags || [getTagFromIconType(popupData.iconType || 'icon1')]
            };
   
            if (layer instanceof L.Circle) {
                feature.properties.radius = layer.getRadius();
                feature.geometry = {
                    type: "Point",
                    coordinates: [layer.getLatLng().lng, layer.getLatLng().lat]
                };
            } else if (layer instanceof L.Marker) {
                feature.geometry = {
                    type: "Point",
                    coordinates: [layer.getLatLng().lng, layer.getLatLng().lat]
                };
            } else {
                // その他のタイプのレイヤーは無視する
                return;
            }
   
            geoJSON.features.push(feature);
        });
   
        // GeoJSONデータの有効性をチェック
        try {
            JSON.parse(JSON.stringify(geoJSON));
        } catch (error) {
            console.error("Invalid GeoJSON data:", error);
            return null;
        }
   
        return JSON.stringify(geoJSON, null, 2); // 整形されたJSONを返す
    }
   
   
    function getTagFromIconType(iconType) {
        switch (iconType) {
            case 'icon1':
                return '<!--{$filter1|default:"分類1"}-->';
            case 'icon2':
                return '<!--{$filter2|default:"分類2"}-->';
            case 'icon3':
                return '<!--{$filter3|default:"分類3"}-->';
            case 'icon4':
                return '<!--{$filter4|default:"分類4"}-->';
            case 'icon5':
                return '<!--{$filter5|default:"分類5"}-->';
            case 'icon6':
                return '<!--{$filter6|default:"分類6"}-->';
            default:
                return '';
        }
    }
   
      // フィルタボタンの定義
   
    // Leaflet.Control.TagFilterButton の設定
    L.control.tagFilterButton({
        data: [
            '<!--{$filter1|default:"分類1"}-->',
            '<!--{$filter2|default:"分類2"}-->',
            '<!--{$filter3|default:"分類3"}-->',
            '<!--{$filter4|default:"分類4"}-->',
            '<!--{$filter5|default:"分類5"}-->',
            '<!--{$filter6|default:"分類6"}-->'
        ],
        icon: '<img src="https://dq.h1g.jp/img/marker-icon-img/filter.png">',
        filterOnEveryClick: true
    }).addTo(map);
   
   
    // トークンを取得する関数
    function getMwToken() {
        return new Promise((resolve, reject) => {
            $.ajax({
                 url: API_BASE_URL + '/api.php',
                 url: API_BASE_URL + '/api.php',
                 data: {
                 data: {
                     action: 'query',
                     action: 'edit',
                     meta: 'tokens',
                     title: '<!--{$geojson}-->',
                     type: 'csrf',
                     text: formattedData,
                    token: token,
                     format: 'json'
                     format: 'json'
                },
                type: 'GET',
                success: function(response) {
                    if (response.query && response.query.tokens && response.query.tokens.csrftoken) {
                        resolve(response.query.tokens.csrftoken);
                    } else {
                        reject(new Error('Failed to get token'));
                    }
                },
                error: function(xhr, status, error) {
                    reject(error);
                 }
                 }
             });
             });
        })
        .then(function(response) {
            if (response.edit && response.edit.result === 'Success') {
                alert('データは正常に保存されました');
                editMode = false;
                drawControl.remove();
                editButton.state('enable-edit');
                saveButton.remove();
               
                // 保存成功後、新しいトークンで再読み込み
                getMwToken()
                    .then(function(newToken) {
                        loadPinsFromWikiPage(newToken);
                    })
                    .catch(function(error) {
                        console.error("Failed to get token for reload:", error);
                    });
            } else {
                throw new Error('保存に失敗しました');
            }
        })
        .catch(function(error) {
            console.error("Save error:", error);
            alert('データの保存に失敗しました: ' + error.message);
         });
         });
}
map.on(L.Draw.Event.CREATED, function (event) {
    var layer = event.layer;
    if (layer instanceof L.Marker) {
        layer.setIcon(iconDefinitions.icon1);
        layer.options.popupData = {title: '', content: '', iconType: 'icon1'};
     }
     }
      
     createEditablePopup(layer);
    function saveToWikiPage(geoJSONData) {
    drawnItems.addLayer(layer);
        var formattedData = geoJSONData;
});
       
 
        // 保存前に新しいトークンを取得
        getMwToken()
            .then(function(token) {
                return $.ajax({
                    type: "POST",
                    url: API_BASE_URL + '/api.php',
                    data: {
                        action: 'edit',
                        title: '<!--{$geojson}-->',
                        text: formattedData,
                        token: token,
                        format: 'json'
                    }
                });
            })
            .then(function(response) {
                if (response.edit && response.edit.result === 'Success') {
                    alert('データは正常に保存されました');
                    editMode = false;
                    drawControl.remove();
                    editButton.state('enable-edit');
                    saveButton.remove();
                   
                    // 保存成功後、新しいトークンで再読み込み
                    getMwToken()
                        .then(function(newToken) {
                            loadPinsFromWikiPage(newToken);
                        })
                        .catch(function(error) {
                            console.error("Failed to get token for reload:", error);
                        });
                } else {
                    throw new Error('保存に失敗しました');
                }
            })
            .catch(function(error) {
                console.error("Save error:", error);
                alert('データの保存に失敗しました: ' + error.message);
            });
    }
   
   
   
   
    map.on(L.Draw.Event.CREATED, function (event) {
        var layer = event.layer;
        if (layer instanceof L.Marker) {
            layer.setIcon(iconDefinitions.icon1);
            layer.options.popupData = {title: '', content: '', iconType: 'icon1'};
        }
        createEditablePopup(layer);
        drawnItems.addLayer(layer);
    });
   
   
    ////////////////////////////////////////////////////
    $(document).ready(function() {
    // ページ離脱時のクリーンアップ処理を追加
    window.addEventListener('beforeunload', () => {
        cleanupMap();
        cleanupLocalStorage();
        cleanupSessionCookies();
    });


////////////////////////////////////////////////////
// ページ読み込み時にデータを読み込む
$(document).ready(function() {
     setTimeout(function() {
     setTimeout(function() {
         map.invalidateSize();
         map.invalidateSize();
        // 初期読み込み時にトークンを取得してからデータを読み込む
         getMwToken()
         getMwToken()
             .then(function(token) {
             .then(function(token) {
                 console.log('Initial token obtained');
                 console.log('Initial token obtained');
                 loadPinsFromWikiPage(token);
                 loadPinsFromWikiPage(token);
               
             })
             })
             .catch(function(error) {
             .catch(function(error) {
846行目: 837行目:
     }, 500);
     }, 500);
});
});
     </script>
 
   
// エラーハンドリングの改善
    </includeonly>
function handleApiError(error) {
    console.error('API Error:', error);
    if (error.status === 403) {
        alert('アクセス権限がありません。再度ログインしてください。');
    } else if (error.status === 404) {
        alert('リソースが見つかりません。');
    } else {
        alert('エラーが発生しました。ページを更新してください。');
     }
}
</script>
 
</includeonly>

2024年11月10日 (日) 17:53時点における版