(function(){ // 后台媒体选择交互脚本 用于在设置页选择媒体项目 function initAdminMedia(){ // 将后台资源映射注入到前端设置对象 以便 shapes 脚本复用 if (typeof window !== 'undefined'){ // 条件判断 如果前端设置对象不存在则创建 window.YooneSnowSettings = window.YooneSnowSettings || {}; // 条件判断 若未设置 assetsMap 且后台提供则注入 if (!window.YooneSnowSettings.assetsMap && window.YooneSnowAdmin && window.YooneSnowAdmin.assetsMap){ window.YooneSnowSettings.assetsMap = window.YooneSnowAdmin.assetsMap; } } // 条件判断 如果没有媒体按钮则不执行 var addMediaUnifiedButton = document.getElementById('yooneSnowAddMediaUnified'); var listContainer = null; var emojiListContainer = null; var emojiInput = document.getElementById('yooneSnowAddEmojiInput'); var emojiAddButton = null; var emojiSuggestBox = document.getElementById('yooneSnowEmojiSuggest'); var shapeListContainer = document.getElementById('yooneSnowShapeList'); var shapeAddSelect = document.getElementById('yooneSnowAddShapeSelect'); var shapeLabelPreviewHost = document.getElementById('yooneSnowAddShapeLabelPreview'); var shapeNativeOverlay = document.getElementById('yooneSnowShapeNativeOverlay'); var shapeAddButton = null; var emojiSelect = document.getElementById('yooneSnowEmojiSelect'); var typeSelect = document.getElementById('yooneSnowAddTypeSelect'); var paneDefault = document.getElementById('yooneSnowAddDefaultPane'); var paneEmoji = document.getElementById('yooneSnowAddEmojiPane'); var paneMedia = document.getElementById('yooneSnowAddMediaPane'); var unifiedAddCard = document.getElementById('yooneSnowAddUnified'); var paneText = document.getElementById('yooneSnowAddTextPane'); var textInput = document.getElementById('yooneSnowAddTextInput'); // 统一列表容器为形状列表容器 旧容器不再使用 listContainer = shapeListContainer; emojiListContainer = shapeListContainer; if (!shapeListContainer) { return; } // 权重输入已整合到卡片内部 旧容器不再使用 // 形状标签映射用于显示友好名称 var shapeLabelsMap = (typeof window !== 'undefined' && window.YooneSnowAdmin && window.YooneSnowAdmin.shapeLabels) ? window.YooneSnowAdmin.shapeLabels : { dot: 'Dot', flake: 'Snowflake', yuanbao: 'Yuanbao', coin: 'Coin', santa_hat: 'Santa Hat', candy_cane: 'Candy Cane', christmas_sock: 'Christmas Sock', christmas_tree: 'Christmas Tree', reindeer: 'Reindeer', christmas_berry: 'Christmas Berry' }; // 创建形状预览元素 直接复用 shapes 渲染器 实现一致预览 function createShapePreviewElement(shapeKey){ var registry = (typeof window !== 'undefined' && window.YooneSnowShapeRenderers) ? window.YooneSnowShapeRenderers : {}; var renderer = registry[shapeKey]; // 条件判断 如果找到渲染器则使用 canvas 调用渲染函数 if (typeof renderer === 'function'){ var canvas = document.createElement('canvas'); canvas.width = 32; canvas.height = 32; canvas.style.marginRight = '6px'; // 使用中性灰色背景提升可读性 canvas.style.backgroundColor = '#e6e6e6'; canvas.style.border = '1px solid #ddd'; canvas.style.borderRadius = '4px'; var ctx = canvas.getContext('2d'); // 根据形状选择更合适的基础尺寸 保证预览清晰 var previewBaseSizeMap = { dot: 6, flake: 6, yuanbao: 3, coin: 3.5, santa_hat: 2.8, candy_cane: 2.8, christmas_sock: 2.8, christmas_tree: 2.8, reindeer: 2.8, christmas_berry: 2.8 }; var baseSize = previewBaseSizeMap[shapeKey] || 3.2; // 调用渲染器 使用画布中心作为位置 try { renderer(ctx, 16, 16, baseSize); } catch(e){} // 对基于图像的形状进行补绘 当图像加载完成时重试一次 var assets = (window.YooneSnowSettings && window.YooneSnowSettings.assetsMap) ? window.YooneSnowSettings.assetsMap : {}; var url = assets[shapeKey]; if (url && typeof window.YooneSnowGetOrLoadImage === 'function'){ var record = window.YooneSnowGetOrLoadImage(url); if (!record || !record.ready){ var tries = 0; var timer = setInterval(function(){ tries++; var check = window.YooneSnowGetOrLoadImage(url); if (check && check.ready){ try { ctx.clearRect(0,0,canvas.width,canvas.height); renderer(ctx, 16, 16, 2.5); } catch(err){} clearInterval(timer); } if (tries > 50){ clearInterval(timer); } }, 100); } } return canvas; } // 条件判断 若无渲染器则回退为资源图预览 保证可见性 if (typeof window !== 'undefined' && window.YooneSnowAdmin && window.YooneSnowAdmin.assetsMap && window.YooneSnowAdmin.assetsMap[shapeKey]){ var img = document.createElement('img'); img.src = String(window.YooneSnowAdmin.assetsMap[shapeKey]); img.alt = shapeKey; img.style.width = '28px'; img.style.height = '28px'; img.style.objectFit = 'contain'; img.style.marginRight = '6px'; img.style.backgroundColor = '#e6e6e6'; img.style.border = '1px solid #ddd'; img.style.borderRadius = '4px'; return img; } // 默认降级 使用文本首字母表示 var fallback = document.createElement('canvas'); fallback.width = 32; fallback.height = 32; fallback.style.marginRight = '6px'; var fctx = fallback.getContext('2d'); // 使用中性灰色背景提升可读性 fallback.style.backgroundColor = '#e6e6e6'; fallback.style.border = '1px solid #ddd'; fallback.style.borderRadius = '4px'; fctx.fillStyle = '#555'; fctx.font = '12px system-ui'; fctx.textAlign = 'center'; fctx.textBaseline = 'middle'; var txt = (shapeKey || 'S').substring(0, 1).toUpperCase(); fctx.fillText(txt, 16, 16); return fallback; } // 初始化时为现有卡片补齐预览 // 为现有形状卡片填充预览 保证刷新页面后仍可见 function renderExistingShapeCardPreviews(){ if (!shapeListContainer) { return; } var items = shapeListContainer.querySelectorAll('.yoone-snow-shape-item'); items.forEach(function(item){ var key = item.getAttribute('data-shape-key'); var host = item.querySelector('.yoone-snow-shape-preview'); if (!host) { return; } // 条件判断 若已有内容则跳过 避免重复渲染 if (host.childNodes && host.childNodes.length > 0) { return; } var previewEl = createShapePreviewElement(key); if (previewEl) { host.appendChild(previewEl); } }); } renderExistingShapeCardPreviews(); // 添加形状卡片 并插入预览与隐藏输入 用于保存选择 function addShapeBox(shapeKey){ if (!shapeListContainer) { return; } var key = String(shapeKey); if (key.trim() === '') { return; } var exist = shapeListContainer.querySelector('.yoone-snow-shape-item[data-shape-key="' + key + '"]'); if (exist) { return; } var wrapper = document.createElement('div'); wrapper.className = 'yoone-snow-shape-item'; wrapper.setAttribute('data-shape-key', key); wrapper.style.border = '1px solid #ddd'; wrapper.style.padding = '8px'; wrapper.style.display = 'flex'; wrapper.style.flexDirection = 'column'; wrapper.style.alignItems = 'center'; wrapper.style.minWidth = '96px'; var previewHost = document.createElement('div'); previewHost.className = 'yoone-snow-shape-preview'; previewHost.style.width = '32px'; previewHost.style.height = '32px'; previewHost.style.marginBottom = '6px'; previewHost.style.backgroundColor = '#e6e6e6'; previewHost.style.border = '1px solid #ddd'; previewHost.style.borderRadius = '4px'; var nameSpan = document.createElement('span'); nameSpan.textContent = shapeLabelsMap[key] || key; var weightInput = document.createElement('input'); weightInput.type = 'number'; weightInput.min = '0'; weightInput.name = 'yoone_snow_shape_weights[' + key + ']'; weightInput.value = '1'; weightInput.style.width = '120px'; weightInput.style.marginTop = '6px'; var input = document.createElement('input'); input.type = 'hidden'; input.name = 'yoone_snow_mixed_items[]'; input.value = key; var cancelBtn = document.createElement('button'); cancelBtn.type = 'button'; cancelBtn.className = 'button yoone-snow-cancel-shape'; cancelBtn.textContent = t('cancel', 'Cancel'); cancelBtn.style.marginTop = '6px'; wrapper.appendChild(previewHost); wrapper.appendChild(nameSpan); wrapper.appendChild(weightInput); wrapper.appendChild(input); wrapper.appendChild(cancelBtn); if (unifiedAddCard && unifiedAddCard.parentNode === shapeListContainer){ shapeListContainer.insertBefore(wrapper, unifiedAddCard); } else { shapeListContainer.appendChild(wrapper); } var previewEl = createShapePreviewElement(key); if (previewEl) { previewHost.appendChild(previewEl); } } // 绑定移除按钮事件 使用事件委托处理动态元素 shapeListContainer.addEventListener('click', function(event){ // 条件判断 如果点击的是移除按钮则执行删除 var target = event.target; if (target && target.classList.contains('yoone-snow-remove-media')){ var item = target.closest('.yoone-snow-media-item'); if (item) { var aidStr = item.getAttribute('data-attachment-id'); item.remove(); // 媒体权重输入已在卡片内 无需额外删除 } } }); // 绑定移除 emoji 按钮事件 使用事件委托处理动态元素 if (shapeListContainer){ shapeListContainer.addEventListener('click', function(event){ var target = event.target; if (target && target.classList.contains('yoone-snow-remove-emoji')){ var item = target.closest('.yoone-snow-emoji-item'); if (item){ var ch = item.getAttribute('data-emoji-char'); item.remove(); // Emoji 权重输入已在卡片内 无需额外删除 } } }); } // 打开媒体选择器 支持多选 图片和 SVG if (addMediaUnifiedButton){ addMediaUnifiedButton.addEventListener('click', function(){ // 条件判断 如果 wp.media 不可用则终止 if (typeof wp === 'undefined' || !wp.media) { return; } var frame = wp.media({ title: t('select_images_or_svg', 'Select images or SVG'), multiple: true, library: { type: [ 'image', 'image/svg+xml' ] } }); frame.on('select', function(){ var selection = frame.state().get('selection'); selection.each(function(attachment){ var data = attachment.toJSON(); var id = data.id; var url = data.sizes && data.sizes.thumbnail ? data.sizes.thumbnail.url : data.url; // 创建预览项与隐藏输入 保存附件 ID var wrapper = document.createElement('div'); wrapper.className = 'yoone-snow-media-item'; wrapper.setAttribute('data-attachment-id', String(id)); wrapper.style.border = '1px solid #ddd'; wrapper.style.padding = '8px'; wrapper.style.display = 'flex'; wrapper.style.flexDirection = 'column'; wrapper.style.alignItems = 'center'; var img = document.createElement('img'); img.src = url; img.alt = 'media'; img.style.width = '72px'; img.style.height = '72px'; img.style.objectFit = 'contain'; var weightInput = document.createElement('input'); weightInput.type = 'number'; weightInput.min = '0'; weightInput.name = 'yoone_snow_media_weights[' + String(id) + ']'; weightInput.value = '1'; weightInput.style.width = '120px'; weightInput.style.marginTop = '6px'; var input = document.createElement('input'); input.type = 'hidden'; input.name = 'yoone_snow_media_items[]'; input.value = String(id); var removeBtn = document.createElement('button'); removeBtn.type = 'button'; removeBtn.className = 'button yoone-snow-remove-media'; removeBtn.textContent = t('remove', 'Remove'); removeBtn.style.marginTop = '6px'; wrapper.appendChild(img); wrapper.appendChild(weightInput); wrapper.appendChild(input); wrapper.appendChild(removeBtn); if (unifiedAddCard && unifiedAddCard.parentNode === listContainer){ listContainer.insertBefore(wrapper, unifiedAddCard); } else { listContainer.appendChild(wrapper); } }); }); frame.open(); }); } // Emoji 别名映射 用于文本搜索到 emoji 字符 var emojiAliasMap = { smile: '🙂', happy: '😊', grin: '😁', laugh: '😂', joy: '😂', wink: '😉', blush: '☺️', heart: '❤️', love: '❤️', star: '⭐', fire: '🔥', cool: '😎', cry: '😢', sad: '🙁', angry: '😠', thumbs_up: '👍', ok: '👌', clap: '👏', pray: '🙏', tada: '🎉', gift: '🎁', snow: '❄️', tree: '🌲', bell: '🔔', candy: '🍬', sock: '🧦', deer: '🦌', berry: '🍓' }; // 填充下拉菜单 以别名和字符组合显示 function populateEmojiSelect(){ if (!emojiSelect) { return; } // 清空除第一个提示项之外的选项 while (emojiSelect.options.length > 1){ emojiSelect.remove(1); } for (var key in emojiAliasMap){ var ch = emojiAliasMap[key]; var opt = document.createElement('option'); opt.value = ch; opt.textContent = ch + ' ' + key; emojiSelect.appendChild(opt); } } // 绑定下拉选择事件 选择后添加对应 emoji 并重置选中 if (emojiSelect){ populateEmojiSelect(); emojiSelect.addEventListener('change', function(){ var val = emojiSelect.value; if (String(val).trim() !== ''){ addEmojiByChar(val); emojiSelect.value = ''; } }); } // 显示建议列表 根据查询文本匹配别名 function showEmojiSuggestions(query){ if (!emojiSuggestBox) { return; } var q = String(query || '').toLowerCase().trim(); emojiSuggestBox.innerHTML = ''; if (q === '') { return; } var max = 12; var count = 0; for (var key in emojiAliasMap){ if (key.indexOf(q) !== -1){ var btn = document.createElement('button'); btn.type = 'button'; btn.className = 'button'; btn.textContent = emojiAliasMap[key] + ' ' + key; (function(ch){ btn.addEventListener('click', function(){ addEmojiByChar(ch); }); })(emojiAliasMap[key]); emojiSuggestBox.appendChild(btn); count++; if (count >= max){ break; } } } } // 将 emoji 字符添加到列表 并创建隐藏输入 function addEmojiByChar(ch){ if (!shapeListContainer) { return; } var key = String(ch); if (key.trim() === '') { return; } var exist = shapeListContainer.querySelector('.yoone-snow-emoji-item[data-emoji-char="' + key + '"]'); if (exist) { return; } var wrapper = document.createElement('div'); wrapper.className = 'yoone-snow-emoji-item'; wrapper.setAttribute('data-emoji-char', key); wrapper.style.border = '1px solid #ddd'; wrapper.style.padding = '8px'; wrapper.style.display = 'flex'; wrapper.style.flexDirection = 'column'; wrapper.style.alignItems = 'center'; var preview = document.createElement('div'); preview.textContent = key; preview.style.fontSize = '28px'; preview.style.lineHeight = '32px'; preview.style.backgroundColor = '#e6e6e6'; preview.style.border = '1px solid #ddd'; preview.style.borderRadius = '4px'; preview.style.width = '32px'; preview.style.height = '32px'; preview.style.display = 'flex'; preview.style.alignItems = 'center'; preview.style.justifyContent = 'center'; var weightInput = document.createElement('input'); weightInput.type = 'number'; weightInput.min = '0'; weightInput.name = 'yoone_snow_emoji_weights[' + key + ']'; weightInput.value = '1'; weightInput.style.width = '120px'; weightInput.style.marginTop = '6px'; var input = document.createElement('input'); input.type = 'hidden'; input.name = 'yoone_snow_emoji_items[]'; input.value = key; var removeBtn = document.createElement('button'); removeBtn.type = 'button'; removeBtn.className = 'button yoone-snow-remove-emoji'; removeBtn.textContent = t('cancel', 'Cancel'); removeBtn.style.marginTop = '6px'; wrapper.appendChild(preview); wrapper.appendChild(weightInput); wrapper.appendChild(input); wrapper.appendChild(removeBtn); if (unifiedAddCard && unifiedAddCard.parentNode === shapeListContainer){ shapeListContainer.insertBefore(wrapper, unifiedAddCard); } else { shapeListContainer.appendChild(wrapper); } } // 绑定 emoji 添加按钮 点击后优先按别名匹配 否则直接添加字符 // 监听输入变化 显示建议列表 支持即时搜索 function segmentGraphemes(text){ // 将输入参数转为字符串 防止出现非字符串类型 var segments = []; // 初始化结果数组 用于存放分割后的字符簇 var s = String(text || ''); // 如果当前环境支持 Intl.Segmenter 优先使用字符簇级别的分段 if (typeof Intl !== 'undefined' && Intl.Segmenter){ try { // 创建针对简体中文环境的分段器 按 grapheme 粒度分段 var sg = new Intl.Segmenter('zh-Hans', { granularity: 'grapheme' }); // 执行分段操作 并提取每个分段的文本内容 var it = sg.segment(s); it.forEach(function(rec){ segments.push(rec.segment); }); // 分段成功后返回结果数组 return segments; } catch(err){} } // 如果不支持 Intl.Segmenter 或发生异常 使用正则作为后备方案 try { // 正则匹配常见的 emoji 字符簇 包含 ZWJ 组合和区域指示符 var re = /(?:\p{Extended_Pictographic}\uFE0F?(?:\u200D\p{Extended_Pictographic}\uFE0F?)*)|(?:\p{Regional_Indicator}{2})|(?:[#*0-9]\uFE0F?\u20E3)/gu; var m = s.match(re); // 如果匹配到至少一个字符簇 则直接返回匹配结果 if (m && m.length > 0){ return m; } } catch(err){} // 若未匹配到任何字符簇 且原始字符串非空 则返回包含原字符串的数组 否则返回空数组 return s ? [s] : []; } function isEmojiCluster(cluster){ var str = String(cluster || ''); if (str.trim() === ''){ return false; } try { if (/\p{Extended_Pictographic}/u.test(str)){ return true; } } catch(err){} try { if (/[\u{1F1E6}-\u{1F1FF}]{2}/u.test(str)){ return true; } } catch(err){} if (/(?:[#*0-9]\uFE0F?\u20E3)/u.test(str)){ return true; } if (/\u200D/.test(str)){ return true; } if (/\uFE0F/.test(str)){ return true; } return false; } if (emojiInput){ emojiInput.addEventListener('input', function(){ showEmojiSuggestions(emojiInput.value); }); emojiInput.addEventListener('keydown', function(e){ if (e && e.key === 'Enter'){ e.preventDefault(); var q = String(emojiInput.value || '').trim(); if (q !== ''){ var lower = q.toLowerCase(); if (emojiAliasMap[lower]){ addEmojiByChar(emojiAliasMap[lower]); } else { var clusters = segmentGraphemes(q); for (var i = 0; i < clusters.length; i++){ if (isEmojiCluster(clusters[i])){ addEmojiByChar(clusters[i]); } } } emojiInput.value = ''; emojiSuggestBox && (emojiSuggestBox.innerHTML = ''); } } }); emojiInput.addEventListener('paste', function(e){ var txt = ''; if (e && e.clipboardData){ txt = String(e.clipboardData.getData('text') || ''); } if (txt.trim() === ''){ return; } setTimeout(function(){ var q = String(emojiInput.value || txt).trim(); var clusters = segmentGraphemes(q); for (var i = 0; i < clusters.length; i++){ if (isEmojiCluster(clusters[i])){ addEmojiByChar(clusters[i]); } } emojiInput.value = ''; emojiSuggestBox && (emojiSuggestBox.innerHTML = ''); }, 0); }); } if (shapeListContainer){ shapeListContainer.addEventListener('click', function(event){ var target = event.target; if (target && target.classList.contains('yoone-snow-cancel-shape')){ var item = target.closest('.yoone-snow-shape-item'); if (item){ var key = item.getAttribute('data-shape-key'); item.remove(); } } }); } if (shapeAddSelect){ // 监听默认形状下拉变化 用于更新左侧图像预览并添加卡片 shapeAddSelect.addEventListener('change', function(){ var val = shapeAddSelect.value; if (String(val).trim() !== ''){ // 更新左侧预览 显示当前选择形状的图像或渲染预览 if (shapeLabelPreviewHost){ while (shapeLabelPreviewHost.firstChild){ shapeLabelPreviewHost.removeChild(shapeLabelPreviewHost.firstChild); } var previewEl = createShapePreviewElement(val); if (previewEl){ try { previewEl.style.backgroundColor = 'transparent'; } catch(e){} try { previewEl.style.border = 'none'; } catch(e){} try { previewEl.style.borderRadius = '0'; } catch(e){} shapeLabelPreviewHost.style.display = 'flex'; shapeLabelPreviewHost.appendChild(previewEl); } } // 添加形状卡片到列表 addShapeBox(val); // 重置下拉并清空预览 保持与未选中状态一致 shapeAddSelect.value = ''; if (shapeLabelPreviewHost){ while (shapeLabelPreviewHost.firstChild){ shapeLabelPreviewHost.removeChild(shapeLabelPreviewHost.firstChild); } shapeLabelPreviewHost.style.display = 'none'; } } }); // 僅使用原生下拉 不再彈出自定義覆蓋列表 } // 切换类型面板 显示对应控件 其他隐藏 function updateTypePane(){ var t = typeSelect ? String(typeSelect.value || '') : ''; if (!paneDefault || !paneEmoji || !paneMedia || !paneText) { return; } paneDefault.style.display = (t === 'default') ? 'flex' : 'none'; paneEmoji.style.display = (t === 'emoji') ? 'flex' : 'none'; paneMedia.style.display = (t === 'media') ? 'flex' : 'none'; paneText.style.display = (t === 'text') ? 'flex' : 'none'; if (shapeLabelPreviewHost){ // 切換類型時預覽容器默認隱藏 僅在選中形狀時顯示 shapeLabelPreviewHost.style.display = 'none'; while (shapeLabelPreviewHost.firstChild){ shapeLabelPreviewHost.removeChild(shapeLabelPreviewHost.firstChild); } } } if (typeSelect){ typeSelect.value = 'default'; typeSelect.addEventListener('change', updateTypePane); updateTypePane(); } function addTextBox(textLabel){ if (!shapeListContainer) { return; } var key = String(textLabel).trim(); if (key === '') { return; } var exist = shapeListContainer.querySelector('.yoone-snow-text-item[data-text-label="' + key + '"]'); if (exist) { return; } var wrapper = document.createElement('div'); wrapper.className = 'yoone-snow-text-item'; wrapper.setAttribute('data-text-label', key); wrapper.style.border = '1px solid #ddd'; wrapper.style.padding = '8px'; wrapper.style.display = 'flex'; wrapper.style.flexDirection = 'column'; wrapper.style.alignItems = 'center'; wrapper.style.minWidth = '96px'; var preview = document.createElement('div'); preview.textContent = key; preview.style.fontSize = '14px'; preview.style.lineHeight = '18px'; preview.style.width = '120px'; preview.style.minHeight = '32px'; preview.style.display = 'flex'; preview.style.alignItems = 'center'; preview.style.justifyContent = 'center'; preview.style.backgroundColor = '#e6e6e6'; preview.style.border = '1px solid #ddd'; preview.style.borderRadius = '4px'; preview.style.wordBreak = 'break-word'; preview.style.textAlign = 'center'; var weightInput = document.createElement('input'); weightInput.type = 'number'; weightInput.min = '0'; weightInput.name = 'yoone_snow_text_weights[' + key + ']'; weightInput.value = '1'; weightInput.style.width = '120px'; weightInput.style.marginTop = '6px'; var input = document.createElement('input'); input.type = 'hidden'; input.name = 'yoone_snow_text_items[]'; input.value = key; var removeBtn = document.createElement('button'); removeBtn.type = 'button'; removeBtn.className = 'button yoone-snow-remove-text'; removeBtn.textContent = t('cancel', 'Cancel'); removeBtn.style.marginTop = '6px'; wrapper.appendChild(preview); wrapper.appendChild(weightInput); wrapper.appendChild(input); wrapper.appendChild(removeBtn); if (unifiedAddCard && unifiedAddCard.parentNode === shapeListContainer){ shapeListContainer.insertBefore(wrapper, unifiedAddCard); } else { shapeListContainer.appendChild(wrapper); } } if (textInput){ textInput.addEventListener('keydown', function(e){ if (e && e.key === 'Enter'){ e.preventDefault(); var val = String(textInput.value || '').trim(); if (val !== ''){ addTextBox(val); textInput.value = ''; } } }); } if (shapeListContainer){ shapeListContainer.addEventListener('click', function(event){ var target = event.target; if (target && target.classList.contains('yoone-snow-remove-text')){ var item = target.closest('.yoone-snow-text-item'); if (item){ item.remove(); } } }); } } // 条件判断 如果文档尚未加载则等待 DOMContentLoaded 事件 if (document.readyState === 'loading'){ document.addEventListener('DOMContentLoaded', initAdminMedia); } else { initAdminMedia(); } })(); // 初始化內嵌下拉的預覽與點擊交互 (function(){ if (!shapeNativeOverlay) { return; } var nodes = shapeNativeOverlay.querySelectorAll('.yoone-snow-shape-native-item'); nodes.forEach(function(btn){ var key = btn.getAttribute('data-shape-key'); var host = btn.querySelector('.yoone-snow-shape-native-preview'); if (host && host.childNodes && host.childNodes.length === 0){ var previewEl = createShapePreviewElement(key); if (previewEl){ try { previewEl.style.backgroundColor = 'transparent'; } catch(e){} try { previewEl.style.border = 'none'; } catch(e){} try { previewEl.style.borderRadius = '0'; } catch(e){} host.appendChild(previewEl); } } btn.addEventListener('click', function(){ // 先更新左側預覽 再添加卡片 並關閉內嵌下拉 if (shapeLabelPreviewHost){ while (shapeLabelPreviewHost.firstChild){ shapeLabelPreviewHost.removeChild(shapeLabelPreviewHost.firstChild); } var previewEl2 = createShapePreviewElement(key); if (previewEl2){ try { previewEl2.style.backgroundColor = 'transparent'; } catch(e){} try { previewEl2.style.border = 'none'; } catch(e){} try { previewEl2.style.borderRadius = '0'; } catch(e){} shapeLabelPreviewHost.style.display = 'flex'; shapeLabelPreviewHost.appendChild(previewEl2); } } addShapeBox(key); if (shapeNativeOverlay){ shapeNativeOverlay.style.display = 'none'; } // 重置原生下拉為未選中 清空左側預覽 保持簡潔 if (shapeAddSelect){ shapeAddSelect.value = ''; } if (shapeLabelPreviewHost){ while (shapeLabelPreviewHost.firstChild){ shapeLabelPreviewHost.removeChild(shapeLabelPreviewHost.firstChild); } shapeLabelPreviewHost.style.display = 'none'; } }); }); // 外部點擊時關閉內嵌下拉 document.addEventListener('click', function(e){ var t = e.target; var inside = (t === shapeNativeOverlay || shapeNativeOverlay.contains(t) || (shapeAddSelect && (t === shapeAddSelect || shapeAddSelect.contains(t)))); if (!inside){ shapeNativeOverlay.style.display = 'none'; } }); })(); function t(key, fallback){ var dict = (typeof window !== 'undefined' && window.YooneSnowAdmin && window.YooneSnowAdmin.i18n) ? window.YooneSnowAdmin.i18n : {}; var val = dict[key]; return String(val || fallback || ''); }