/* v7 only. Also runs on cached HTML where Vue is absent. */ (function (window, document) { 'use strict'; if (window.WitBlogRankingV7) return; var requests = new Map(); var states = new WeakMap(); var selector = '[data-wit-blog-ranking]'; function httpUrl(value, base) { if (typeof value !== 'string' || /[\x00-\x20\x7f\\]/.test(value)) return null; try { var url = new URL(value, base); return /^(https?:)$/.test(url.protocol) && !url.username && !url.password ? url : null; } catch (_) { return null; } } function config(root) { var d = root.dataset; var days = d.rankingDays === undefined ? 30 : Number(d.rankingDays); if (![7, 14, 30].includes(days)) return null; var base = httpUrl(d.rankingBase || '/_ranking_', window.location.href); if (!/^[a-zA-Z0-9_]+$/.test(d.rankingCid || '') || !/^[a-zA-Z0-9_]+$/.test(d.rankingGid || '') || !base || base.search || base.hash) return null; return { cid: d.rankingCid, gid: d.rankingGid, days: days, url: base.href.replace(/\/$/, '') + '/' + encodeURIComponent(d.rankingCid) + '/' + encodeURIComponent(d.rankingGid) + '/' + days + 'd.json', title: d.rankingTitle || '人気記事ランキング', limit: Math.min(10, Math.max(1, parseInt(d.rankingLimit, 10) || 5)), images: d.rankingImages !== 'false', preview: d.rankingPreview === 'true' || d.rankingComparison === 'true' }; } function load(url) { if (!requests.has(url)) { var controller = new AbortController(); var timer = window.setTimeout(function () { controller.abort(); }, 8000); var promise = window.fetch(url, { credentials: 'omit', cache: 'no-cache', signal: controller.signal }) .then(function (response) { if (!response.ok) throw new Error('ranking fetch failed'); return response.json(); }).then(function (payload) { if (!payload || payload.version !== 1 || !Array.isArray(payload.items)) throw new Error('invalid ranking'); return payload; }).finally(function () { window.clearTimeout(timer); }); requests.set(url, promise); promise.catch(function () { requests.delete(url); }); } return requests.get(url); } function notice(root, text, preview) { var element = root.querySelector('[data-ranking-notice]'); if (element) { element.textContent = text; element.hidden = !preview; } root.hidden = !preview; } function render(root, settings, payload) { if (payload.cid !== settings.cid || payload.gid !== settings.gid || (payload.periodDays || 30) !== settings.days) throw new Error('ranking target mismatch'); var list = root.querySelector('[data-ranking-list]'); var title = root.querySelector('[data-ranking-heading]'); if (!list || !title) return 0; title.textContent = settings.title; var period = root.querySelector('[data-ranking-period]'); if (period && payload.period) period.textContent = payload.period.start + ' 〜 ' + payload.period.end; list.replaceChildren(); var items = payload.items.slice(0, settings.limit); items.forEach(function (item) { var url = item && httpUrl(item.url); if (!url || typeof item.title !== 'string' || !Number.isInteger(item.rank) || item.rank < 1 || item.rank > 10) return; var li = document.createElement('li'); var link = document.createElement('a'); link.href = url.href; link.className = 'p-blog-ranking__link'; var rank = document.createElement('span'); rank.className = 'p-blog-ranking__rank'; rank.textContent = String(item.rank); rank.setAttribute('aria-label', String(item.rank) + '位'); link.appendChild(rank); var imageUrl = settings.images && httpUrl(item.imageUrl); if (imageUrl) { var img = document.createElement('img'); img.src = imageUrl.href; img.alt = ''; img.width = 96; img.height = 64; img.loading = 'lazy'; img.className = 'p-blog-ranking__image'; img.addEventListener('error', function () { img.remove(); }, { once: true }); link.appendChild(img); } var label = document.createElement('strong'); label.className = 'p-blog-ranking__title'; label.textContent = item.title; link.appendChild(label); li.appendChild(link); list.appendChild(li); }); var message = root.querySelector('[data-ranking-notice]'); if (message) message.hidden = true; root.hidden = list.children.length === 0; if (root.hidden) notice(root, 'この期間に閲覧された記事はありません。', settings.preview); return list.children.length; } function mount(root) { var settings = config(root); var signature = JSON.stringify(settings) + '|' + root.dataset.rankingPreview; var old = states.get(root); var list = root.querySelector('[data-ranking-list]'); if (!list) return; if (old && old.signature === signature && (old.loading || !old.count || list.children.length === old.count)) return; var state = { signature: signature, count: 0, loading: true }; states.set(root, state); list.replaceChildren(); if (!settings) { state.loading = false; notice(root, '対象ブログまたは配信URLを設定してください。', root.dataset.rankingPreview === 'true'); return; } var title = root.querySelector('[data-ranking-heading]'); if (title) title.textContent = settings.title; notice(root, 'ランキングを読み込んでいます。', settings.preview); load(settings.url).then(function (payload) { if (states.get(root) !== state) return; state.count = render(root, settings, payload); }).catch(function () { if (states.get(root) !== state) return; notice(root, 'ランキングを読み込めませんでした。', settings.preview); }).finally(function () { state.loading = false; }); } function scan() { document.querySelectorAll(selector).forEach(mount); } window.WitBlogRankingV7 = { scan: scan }; if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', scan, { once: true }); else scan(); new MutationObserver(scan).observe(document.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: ['data-ranking-days', 'data-ranking-comparison', 'data-ranking-cid', 'data-ranking-gid', 'data-ranking-base', 'data-ranking-title', 'data-ranking-limit', 'data-ranking-images', 'data-ranking-preview'] }); })(window, document); /* Refresh sidebar FAQs from the same public CMS export used by the FAQ pages. */ (function (window, document) { 'use strict'; if (window.WitBlogFaqV7) return; var requests = new Map(); var states = new WeakMap(); function load(source) { if (!requests.has(source)) { var controller = new AbortController(); var timer = window.setTimeout(function () { controller.abort(); }, 10000); var request = window.fetch(source, {credentials: 'omit', cache: 'no-store', signal: controller.signal}) .then(function (response) { if (!response.ok) throw new Error('FAQ request failed'); return response.json(); }).then(function (data) { if (!data || data.schemaVersion !== 1 || !Array.isArray(data.items)) throw new Error('Invalid FAQ data'); return data.items; }).finally(function () { window.clearTimeout(timer); }); requests.set(source, request); request.catch(function () { requests.delete(source); }); } return requests.get(source); } function select(items, subsidy) { var seen = new Set(); return items.filter(function (item) { if (!item || typeof item.id !== 'string' || !item.id || typeof item.question !== 'string' || !item.question.trim() || !Array.isArray(item.subsidies) || !item.subsidies.includes(subsidy) || seen.has(item.id)) return false; seen.add(item.id); return true; }).sort(function (a, b) { // Dedicated questions precede cross-subsidy questions; preserve CMS order within each group. return a.subsidies.length - b.subsidies.length; }).slice(0, 5); } function scan() { document.querySelectorAll('[data-wit-faq-subsidy]').forEach(function (root) { var subsidy = root.dataset.witFaqSubsidy; var source = root.dataset.faqSource; if (!['combined', 'saving'].includes(subsidy) || !source) return; var key = source + '|' + subsidy; if (states.get(root) === key) return; states.set(root, key); var list = root.querySelector('[data-faq-list]'); if (!list) return; list.replaceChildren(); load(source).then(function (items) { if (states.get(root) !== key) return; select(items, subsidy).forEach(function (item) { var li = document.createElement('li'); var link = document.createElement('a'); link.href = '/faq/answer.html?id=' + encodeURIComponent(item.id); link.textContent = item.question; li.appendChild(link); list.appendChild(li); }); root.dataset.faqState = list.children.length ? 'ready' : 'empty'; }).catch(function () { if (states.get(root) === key) root.dataset.faqState = 'error'; // Keep the filtered FAQ index available when the public feed is unavailable. }); }); } window.WitBlogFaqV7 = {scan: scan}; if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', scan); else scan(); })(window, document); /* Live projection of the existing CMS common text variables. */ (function (window, document) { 'use strict'; if (window.WitSubsidyCommon) return; function node(tag, text, className) { var e = document.createElement(tag); e.textContent = text; if (className) e.className = className; return e; } function render(e, value) { var mode=e.dataset.subsidyFormat, prefix=e.dataset.subsidyPrefix; var m=value.match(/^(\d{4}年)\s*(\d{1,2})(月)(?:(\d{1,2})(日))?(.*)$/); e.replaceChildren(); if (mode==='hero' && /^p-(?:mono-hero|growth-hero|labor-hero|column-mv)$/.test(prefix)) { if (m) { e.appendChild(node('p',m[1],prefix+'__fact-year')); var p=node('p','',prefix+'__fact-value'); p.appendChild(document.createTextNode(m[2]));p.appendChild(node('small',m[3])); if(m[4])p.appendChild(document.createTextNode(m[4])); p.appendChild(node('small',(m[5]||'')+m[6]));e.appendChild(p); } else { var fallback=node('p',value,prefix+'__support-date');e.appendChild(fallback); } } else if (mode==='support' && m) { e.appendChild(document.createTextNode(m[1]+' ')); e.appendChild(node('strong',m[2]+m[3]+(m[4]||'')+(m[5]||''))); e.appendChild(document.createTextNode(m[6])); } else e.textContent=value; } async function refresh() { var elements=Array.from(document.querySelectorAll('[data-subsidy-common]')); if(!elements.length)return; // Format the server-rendered common values even if the refresh is unavailable. elements.forEach(function(e){render(e,e.textContent.trim());}); var controller=new AbortController();var timeout=window.setTimeout(function(){controller.abort();},10000); try { var response=await window.fetch('https://svltd2.files.cmssv.awsv.jp/_api_/subsidy-schedule.json',{cache:'no-store',credentials:'omit',signal:controller.signal}); if(!response.ok)throw new Error('Unavailable schedule'); var data=await response.json();if(data.schemaVersion!==1||!data.values)throw new Error('Invalid schedule'); elements.forEach(function(e){var value=data.values[e.dataset.subsidyCommon];if(typeof value==='string')render(e,value);}); document.documentElement.dataset.subsidyCommonState='ready'; } catch (_) {document.documentElement.dataset.subsidyCommonState='unavailable';} finally {window.clearTimeout(timeout);} } window.WitSubsidyCommon={refresh:refresh}; if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',refresh);else refresh(); })(window,document);