document.addEventListener('DOMContentLoaded', function () { var titleInput = document.getElementById('ansico_wp_basic_meta_title'); var descInput = document.getElementById('ansico_wp_basic_meta_description'); var snippet = document.querySelector('.ansico-wp-basic-snippet'); if (titleInput && descInput && snippet) { var titleTarget = snippet.querySelector('.ansico-wp-basic-snippet-title'); var descTextTarget = snippet.querySelector('.ansico-wp-basic-snippet-description-text'); var urlTarget = snippet.querySelector('.ansico-wp-basic-snippet-url'); var truncationNote = document.querySelector('.ansico-wp-basic-truncation-note'); var titleCounter = document.querySelector('[data-counter-for="title"]'); var descCounter = document.querySelector('[data-counter-for="description"]'); var titleMaxPixels = 580; var descMaxPixels = 920; var titleIdealMin = 30; var titleIdealMax = 60; var descIdealMin = 70; var descIdealMax = 155; var titleCanvas = document.createElement('canvas'); var descCanvas = document.createElement('canvas'); var titleContext = titleCanvas.getContext('2d'); var descContext = descCanvas.getContext('2d'); titleContext.font = '400 22px Arial'; descContext.font = '400 14px Arial'; function measure(context, text) { return Math.round(context.measureText(text || '').width); } function truncateByPixels(text, maxPixels, context) { text = (text || '').trim(); var fullWidth = measure(context, text); if (!text || fullWidth <= maxPixels) { return { visible: text, isTruncated: false, hiddenChars: 0, hiddenText: '', width: fullWidth }; } var ellipsis = '…'; var low = 0; var high = text.length; var best = ''; while (low <= high) { var mid = Math.floor((low + high) / 2); var candidate = text.slice(0, mid).replace(/[\s.,;:-]+$/u, ''); var candidateWithEllipsis = candidate + ellipsis; if (measure(context, candidateWithEllipsis) <= maxPixels) { best = candidate; low = mid + 1; } else { high = mid - 1; } } if (!best) { best = text.slice(0, 1); } var hiddenText = text.slice(best.length).trim(); return { visible: best + ellipsis, isTruncated: true, hiddenChars: hiddenText.length, hiddenText: hiddenText, width: fullWidth }; } function setCounter(el, current, minIdeal, maxIdeal, pxWidth, pxLimit, overflowText) { if (!el) { return; } el.classList.remove('is-good', 'is-warning', 'is-danger'); var statusClass = 'is-good'; var notes = []; if (current === 0) { statusClass = 'is-warning'; notes.push('empty'); } else if (current < minIdeal) { statusClass = 'is-warning'; notes.push('a bit short'); } if (current > maxIdeal || pxWidth > pxLimit) { statusClass = (current > maxIdeal + 15 || pxWidth > pxLimit + 120) ? 'is-danger' : 'is-warning'; notes.push(overflowText); } el.classList.add(statusClass); el.textContent = current + ' chars · ' + pxWidth + ' px'; if (notes.length) { el.textContent += ' — ' + notes.join(' · '); } } function updateSnippet() { var rawTitle = titleInput.value.trim() || snippet.dataset.fallbackTitle || ''; var siteName = (snippet.dataset.siteName || '').trim(); var title = rawTitle; if (siteName && rawTitle.toLowerCase().indexOf(siteName.toLowerCase()) === -1) { title += ' - ' + siteName; } var desc = descInput.value.trim() || 'This is how your page may appear in Google search results when a meta description is available.'; var permalink; try { permalink = new URL(snippet.dataset.permalink); } catch (e) { permalink = null; } var host = permalink ? permalink.hostname.replace(/^www\./, '') : ''; var path = permalink ? permalink.pathname.replace(/^\//, '').replace(/\/$/, '') : ''; var prettyUrl = host; if (path) { prettyUrl += ' › ' + path.replace(/\//g, ' › '); } var titleResult = truncateByPixels(title, titleMaxPixels, titleContext); var descResult = truncateByPixels(desc, descMaxPixels, descContext); var rawTitleWidth = measure(titleContext, title); var rawDescWidth = measure(descContext, desc); titleTarget.textContent = titleResult.visible; descTextTarget.textContent = descResult.visible; urlTarget.textContent = prettyUrl; setCounter(titleCounter, rawTitle.length, titleIdealMin, titleIdealMax, rawTitleWidth, titleMaxPixels, 'will truncate in preview'); setCounter(descCounter, desc.length, descIdealMin, descIdealMax, rawDescWidth, descMaxPixels, 'will truncate in preview'); if (truncationNote) { if (descResult.isTruncated) { truncationNote.textContent = 'Preview is truncating the meta description. About ' + descResult.hiddenChars + ' characters are no longer visible.'; truncationNote.classList.add('is-warning'); } else { truncationNote.textContent = 'Preview currently fits within the available description space.'; truncationNote.classList.remove('is-warning'); } } } titleInput.addEventListener('input', updateSnippet); descInput.addEventListener('input', updateSnippet); updateSnippet(); } document.querySelectorAll('.ansico-wp-basic-copy-button').forEach(function (button) { button.addEventListener('click', function () { var text = button.getAttribute('data-copy-text') || ''; if (!text) { return; } var resetButtonState = function () { button.classList.remove('is-copied'); button.setAttribute('title', button.getAttribute('data-original-title') || ''); button.setAttribute('aria-label', button.getAttribute('data-original-label') || ''); }; if (!button.hasAttribute('data-original-title')) { button.setAttribute('data-original-title', button.getAttribute('title') || ''); } if (!button.hasAttribute('data-original-label')) { button.setAttribute('data-original-label', button.getAttribute('aria-label') || ''); } var markCopied = function () { button.classList.add('is-copied'); button.setAttribute('title', 'Copied'); button.setAttribute('aria-label', 'Copied'); window.setTimeout(resetButtonState, 1500); }; if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(markCopied).catch(function () { var tempInput = document.createElement('input'); tempInput.value = text; document.body.appendChild(tempInput); tempInput.select(); document.execCommand('copy'); document.body.removeChild(tempInput); markCopied(); }); return; } var tempInput = document.createElement('input'); tempInput.value = text; document.body.appendChild(tempInput); tempInput.select(); document.execCommand('copy'); document.body.removeChild(tempInput); markCopied(); }); }); });