(function() {
document.addEventListener('DOMContentLoaded', function() {
var mediaBtn = document.getElementById('pfeai-media-button');
if (mediaBtn) {
mediaBtn.addEventListener('click', function(e) {
e.preventDefault();
if (window.PFEditorialAI) {
PFEditorialAI.togglePanel();
}
});
}
});
if (typeof tinymce === 'undefined') {
return;
}
tinymce.create('tinymce.plugins.PFEditorialAI', {
init: function(editor, url) {
editor.on('init', function() {
PFEditorialAI.createPanel(editor);
PFEditorialAI.bindTooltipEvents();
PFEditorialAI.preloadSavedData();
});
},
getInfo: function() {
return { longname: 'PF Editorial AI', author: 'PatsFans + AI', version: '5.2.7' };
}
});
tinymce.PluginManager.add('pfeai_plugin', tinymce.plugins.PFEditorialAI);
window.PFEditorialAI = {
panelCreated: false,
panelEl: null,
loadingEl: null,
analysisEl: null,
titlesEl: null,
ideasEl: null,
transcriptEl: null,
socialEl: null,
savedEl: null,
factsEl: null,
linksEl: null,
isMinimized: false,
// Cache window tracking
cacheWindowStart: null,
cacheWindowTimer: null,
cacheWindowDuration: 4 * 60 * 1000, // 4 minutes (conservative estimate)
tasksInWindow: 0,
/**
* SECURITY: Escape HTML to prevent XSS
* This function must be used for ALL user/API data inserted into the DOM
*/
escapeHtml: function(str) {
if (str === null || str === undefined) return '';
return String(str)
.replace(/&/g, '&')
.replace(//g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
},
/**
* SECURITY: Sanitize for textarea/input values
*/
escapeAttr: function(str) {
if (str === null || str === undefined) return '';
return String(str)
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(//g, '>');
},
/**
* Cache Window Indicator - shows when implicit caching is active
*/
startCacheWindow: function(fromCache) {
var self = this;
// If result was from app cache, don't start/extend the API cache window
if (fromCache) return;
this.tasksInWindow++;
// Start or extend the cache window
this.cacheWindowStart = Date.now();
// Clear existing timer
if (this.cacheWindowTimer) {
clearInterval(this.cacheWindowTimer);
}
// Update indicator immediately
this.updateCacheIndicator();
// Update every second
this.cacheWindowTimer = setInterval(function() {
self.updateCacheIndicator();
}, 1000);
},
updateCacheIndicator: function() {
var indicator = document.getElementById('pfeai-cache-indicator');
if (!indicator) return;
if (!this.cacheWindowStart) {
indicator.style.display = 'none';
return;
}
var elapsed = Date.now() - this.cacheWindowStart;
var remaining = this.cacheWindowDuration - elapsed;
if (remaining <= 0) {
// Cache window expired
indicator.style.display = 'none';
this.cacheWindowStart = null;
this.tasksInWindow = 0;
if (this.cacheWindowTimer) {
clearInterval(this.cacheWindowTimer);
this.cacheWindowTimer = null;
}
return;
}
// Show indicator
indicator.style.display = 'block';
var minutes = Math.floor(remaining / 60000);
var seconds = Math.floor((remaining % 60000) / 1000);
var timeStr = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
var savingsText = this.tasksInWindow > 1
? ' · ' + (this.tasksInWindow - 1) + ' task' + (this.tasksInWindow > 2 ? 's' : '') + ' cached'
: '';
indicator.innerHTML = '⚡ Cache active: ' + timeStr + ' remaining' + savingsText + '
Run more tasks now to save tokens';
},
getProvider: function() {
var select = document.getElementById('pfeai-provider-select');
return select ? select.value : 'gemini';
},
getSafeContent: function(editor) {
try {
if (editor && !editor.isHidden()) return editor.getContent({ format: 'raw' });
var textArea = document.getElementById('content');
return textArea ? textArea.value : '';
} catch (e) { return ''; }
},
getSafeText: function(editor) {
try {
if (editor && !editor.isHidden()) return editor.getContent({ format: 'text' });
var textArea = document.getElementById('content');
return textArea ? textArea.value : '';
} catch (e) { return ''; }
},
createPanel: function(editor) {
if (this.panelCreated) return;
// FIX: Inject Layout Push Styles directly to ensure they work
var style = document.createElement('style');
style.innerHTML = 'body.pfeai-panel-open #wpbody-content { margin-right: 360px !important; transition: margin-right 0.3s ease; } body.pfeai-panel-open .pfeai-panel { right: 0; box-shadow: -2px 0 5px rgba(0,0,0,0.1); }';
document.head.appendChild(style);
var panel = document.createElement('div');
panel.id = 'pfeai-panel';
var html = '';
html += '
Error: ' + self.escapeHtml(json.message) + '
'; } }).catch(function(e) { self.setLoading(false); console.error(e); }); }, renderSocialPack: function(data) { var self = this; this.socialEl.innerHTML = 'Error: ' + self.escapeHtml(json.message) + '
'; } }).catch(function(e) { self.setLoading(false); console.error(e); }); }, runTitles: function(editor, forceRefresh) { var self = this; var contentHtml = this.getSafeContent(editor); var title = (document.getElementById('title') || {}).value || ''; this.showResults('titles'); this.setLoading(true); fetch(PFEAI.rest_url + 'seo-titles?_t=' + Date.now(), { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': PFEAI.nonce }, body: JSON.stringify({ content: contentHtml, title: title, post_id: PFEAI.post_id, provider: this.getProvider(), force_refresh: forceRefresh || false }) }) .then(function(r){return r.json()}).then(function(json){ self.setLoading(false); if(json.titles) { self.renderTitles(json); var timestamp = json.generated_at || Date.now()/1000; self.setCachedState('btn-titles', 'View Titles', 'titles', timestamp, json.from_cache); self.startCacheWindow(json.from_cache); } else if (json.code) { self.titlesEl.innerHTML = 'Error: ' + self.escapeHtml(json.message) + '
'; } }); }, runTranscriptScan: function(editor, forceRefresh) { var self = this; var contentText = this.getSafeText(editor); if (contentText.length < 50) { alert('Please paste transcript.'); return; } this.showResults('transcript'); this.setLoading(true); fetch(PFEAI.rest_url + 'transcript-scan?_t=' + Date.now(), { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': PFEAI.nonce }, body: JSON.stringify({ content: contentText, post_id: PFEAI.post_id, provider: this.getProvider(), force_refresh: forceRefresh || false }) }) .then(function(r){return r.json()}) .then(function(json){ self.setLoading(false); var suggestions = null; if (json.suggestions && Array.isArray(json.suggestions)) { suggestions = json.suggestions; } else if (json.title && json.context) { suggestions = [json]; } if (suggestions && suggestions.length > 0) { self.renderTranscriptSuggestions(suggestions, contentText); var timestamp = json.generated_at || Date.now()/1000; self.setCachedState('btn-transcript', 'View Transcript Results', 'transcript', timestamp, json.from_cache); self.startCacheWindow(json.from_cache); } else if (json.code) { self.transcriptEl.innerHTML = 'Error: ' + self.escapeHtml(json.message) + '
'; } else { self.transcriptEl.innerHTML = 'Unexpected response format. Please click "Rescan" to refresh.
'; } }) .catch(function(err) { self.setLoading(false); self.transcriptEl.innerHTML = 'Request failed: ' + self.escapeHtml(err.message) + '
'; }); }, runTranscriptOutline: function(title, content, clickedCard) { var self = this; var resDiv = document.getElementById('pfeai-transcript-result'); resDiv.innerHTML = 'Generating outline...
This may take up to 30 seconds for longer transcripts.
'; if (!title) { resDiv.innerHTML = 'Error: No headline selected. Please click a headline above.
'; return; } if (!content || content.length < 50) { resDiv.innerHTML = 'Error: Transcript content is too short or missing.
'; return; } var controller = new AbortController(); var timeoutId = setTimeout(function() { controller.abort(); }, 180000); fetch(PFEAI.rest_url + 'transcript-outline?_t=' + Date.now(), { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': PFEAI.nonce }, body: JSON.stringify({ selected_title: title, content: content, provider: this.getProvider() }), signal: controller.signal }) .then(function(r) { clearTimeout(timeoutId); if (!r.ok) { throw new Error('Server returned status ' + r.status); } return r.json(); }) .then(function(json) { if (json.code) { resDiv.innerHTML = 'Error: ' + self.escapeHtml(json.message) + '
Try selecting a different headline or click Rescan.
'; return; } if (json.blurb) { self.renderTranscriptOutlineResult(json, title); } else { resDiv.innerHTML = 'AI response was incomplete. Please try again.
Response received but missing required content.
'; } }) .catch(function(err) { clearTimeout(timeoutId); var errorMsg = 'Error generating outline.'; if (err.name === 'AbortError') { errorMsg = 'Request timed out. The transcript may be too long.'; } else if (err.message) { errorMsg = err.message; } resDiv.innerHTML = '' + self.escapeHtml(errorMsg) + '
Try again or select a different headline.
'; }); }, runArticleIdeas: function(editor, forceRefresh) { var self = this; var title = (document.getElementById('title') || {}).value || ''; var contentText = this.getSafeText(editor).trim(); if (!forceRefresh && (title.length > 0 || contentText.length > 5)) { alert('To generate fresh Topic Inspiration, please clear the Title and Content editor first.'); return; } this.showResults('ideas'); this.setLoading(true); var fetchIdeas = function() { fetch(PFEAI.rest_url + 'article-ideas?_t=' + Date.now(), { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': PFEAI.nonce }, body: JSON.stringify({ title: '', post_id: PFEAI.post_id, provider: self.getProvider(), force_refresh: forceRefresh || false }) }) .then(function(r){return r.json()}).then(function(json){ self.setLoading(false); if(json.ideas) { self.renderIdeasInteractive(json); self.setCachedState('btn-ideas', 'View Topics', 'ideas', Date.now()/1000); } else if (json.code) { self.ideasEl.innerHTML = 'Error: ' + self.escapeHtml(json.message) + '
'; } }).catch(function(e) { self.setLoading(false); console.error(e); }); }; if (forceRefresh) { fetch(PFEAI.rest_url + 'clear-ideas-cache?_t=' + Date.now(), { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': PFEAI.nonce }, body: JSON.stringify({ post_id: PFEAI.post_id }) }) .then(function() { fetchIdeas(); }) .catch(function() { fetchIdeas(); }); } else { fetchIdeas(); } }, runIdeaOutline: function(title, context) { var self = this; var resDiv = document.getElementById('pfeai-idea-result'); if(!resDiv) return; resDiv.innerHTML = 'Drafting outline...
This may take up to 30 seconds.
'; var controller = new AbortController(); var timeoutId = setTimeout(function() { controller.abort(); }, 180000); fetch(PFEAI.rest_url + 'idea-outline?_t=' + Date.now(), { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': PFEAI.nonce }, body: JSON.stringify({ idea_title: title, context: context, provider: this.getProvider() }), signal: controller.signal }) .then(function(r) { clearTimeout(timeoutId); if (!r.ok) { throw new Error('Server returned status ' + r.status); } return r.json(); }) .then(function(json) { if (json.code) { resDiv.innerHTML = 'Error: ' + self.escapeHtml(json.message) + '
'; return; } if(json.blurb) { self.renderIdeaOutlineResult(json, title); } else { resDiv.innerHTML = 'AI response was incomplete. Please try again.
'; } }) .catch(function(err) { clearTimeout(timeoutId); var errorMsg = 'Error generating outline.'; if (err.name === 'AbortError') { errorMsg = 'Request timed out. Please try again.'; } else if (err.message) { errorMsg = err.message; } resDiv.innerHTML = '' + self.escapeHtml(errorMsg) + '
'; }); }, runTagline: function(editor) { var self = this; var c = this.getSafeContent(editor); var t = (document.getElementById('title') || {}).value || ''; if (!t) { alert('Enter title first'); return; } var btn = this.panelEl.querySelector('.pfeai-tagline-btn'); var originalText = btn ? btn.textContent : ''; if (btn) { btn.disabled = true; btn.innerHTML = ' Thinking...'; } fetch(PFEAI.rest_url + 'generate-tagline?_t=' + Date.now(), { method: 'POST', headers: {'Content-Type':'application/json','X-WP-Nonce':PFEAI.nonce}, body:JSON.stringify({content:c, title:t, provider: this.getProvider()}) }) .then(function(r){ return r.json(); }) .then(function(j){ if (btn) { btn.disabled = false; btn.textContent = originalText; } if(j.tagline) { document.getElementById('pftwt_tagline').value = j.tagline; self.startCacheWindow(false); } else if (j.code) { alert('Error: ' + j.message); } else { alert('No tagline was generated. Please try again.'); } }) .catch(function(e) { if (btn) { btn.disabled = false; btn.textContent = originalText; } alert('Error: ' + e.message); }); }, runTagSuggestions: function(editor) { var self = this; var c = this.getSafeContent(editor); var t = (document.getElementById('title') || {}).value || ''; if (!c || c.length < 50) { alert('Please add more content before generating tags.'); return; } var btn = this.panelEl.querySelector('.pfeai-tags-btn'); var originalText = btn ? btn.textContent : ''; if (btn) { btn.disabled = true; btn.innerHTML = ' Thinking...'; } fetch(PFEAI.rest_url + 'suggest-tags?_t=' + Date.now(), { method: 'POST', headers: {'Content-Type':'application/json','X-WP-Nonce':PFEAI.nonce}, body:JSON.stringify({content:c, title:t, provider: this.getProvider()}) }) .then(function(r){ return r.json(); }) .then(function(j){ if (btn) { btn.disabled = false; btn.textContent = originalText; } if (j.code) { alert('Error generating tags: ' + (j.message || j.code)); return; } if(j.tags && j.tags.length > 0 && jQuery) { var $ = jQuery; var tagsAdded = 0; var tagBox = $('#post_tag'); if (window.tagBox && typeof window.tagBox.flushTags === 'function') { var $input = $('#new-tag-post_tag'); j.tags.forEach(function(tag) { $input.val(tag); window.tagBox.flushTags(tagBox, false, 1); tagsAdded++; }); } else { var $input = $('#new-tag-post_tag'); var $addBtn = $('#post_tag .tagadd'); j.tags.forEach(function(tag, index) { setTimeout(function() { $input.val(tag); $addBtn.trigger('click'); var e = $.Event('keypress'); e.which = 13; $input.trigger(e); tagsAdded++; if (index === j.tags.length - 1) { setTimeout(function() { if (window.tagBox && typeof window.tagBox.get === 'function') { window.tagBox.get('post_tag'); } }, 100); } }, index * 50); }); } self.startCacheWindow(false); if (btn) { btn.textContent = 'Added ' + j.tags.length + ' tags!'; setTimeout(function() { btn.textContent = originalText; }, 2000); } } else { alert('No tags were generated. Please try again.'); } }) .catch(function(e) { if (btn) { btn.disabled = false; btn.textContent = originalText; } alert('Error: ' + e.message); }); }, runMetaDescFromMenu: function(editor) { var self = this; var title = (document.getElementById('title') || {}).value || ''; var content = this.getSafeContent(editor); if (!title && !content) { alert('Please add a title or content first.'); return; } var btn = this.panelEl.querySelector('.pfeai-meta-btn'); var originalText = btn ? btn.textContent : ''; if (btn) { btn.disabled = true; btn.innerHTML = ' Thinking...'; } fetch(PFEAI.rest_url + 'generate-meta-desc?_t=' + Date.now(), { method: 'POST', headers: {'Content-Type':'application/json','X-WP-Nonce':PFEAI.nonce}, body: JSON.stringify({content: content, title: title, provider: this.getProvider()}) }) .then(function(r){return r.json()}) .then(function(j){ if (btn) { btn.disabled = false; btn.textContent = originalText; } if(j.meta_description) { self.showResults('seo'); var textarea = document.getElementById('pfeai-meta-description'); if (textarea) { textarea.value = j.meta_description; self.updateSerpPreview(); } self.startCacheWindow(false); if (btn) { btn.textContent = 'Generated!'; setTimeout(function() { btn.textContent = originalText; }, 2000); } } else if (j.code) { alert('Error: ' + j.message); } else { alert('No meta description was generated. Please try again.'); } }) .catch(function(e) { if (btn) { btn.disabled = false; btn.textContent = originalText; } alert('Error: ' + e.message); }); }, runMetaDescription: function() { var self = this; var title = (document.getElementById('title') || {}).value || ''; var content = this.getSafeContent(tinymce.activeEditor); if (!title && !content) { alert('Please add a title or content first.'); return; } var btn = document.getElementById('pfeai-generate-meta-btn'); if (btn) { btn.textContent = 'Generating...'; btn.disabled = true; } fetch(PFEAI.rest_url + 'generate-meta-desc?_t=' + Date.now(), { method: 'POST', headers: {'Content-Type':'application/json','X-WP-Nonce':PFEAI.nonce}, body: JSON.stringify({content: content, title: title, provider: this.getProvider()}) }) .then(function(r){return r.json()}) .then(function(j){ if (btn) { btn.innerHTML = '✨ Generate New Meta Description'; btn.disabled = false; } if(j.meta_description) { var textarea = document.getElementById('pfeai-meta-description'); if (textarea) { textarea.value = j.meta_description; self.updateSerpPreview(); } self.startCacheWindow(false); } else if (j.code) { alert('Error: ' + j.message); } }) .catch(function(e) { if (btn) { btn.innerHTML = '✨ Generate New Meta Description'; btn.disabled = false; } }); }, runFAQ: function(editor) { var self = this; var c = this.getSafeContent(editor); var t = (document.getElementById('title') || {}).value || ''; if (!c || c.length < 100) { alert('Please write or paste the article content first so the AI can generate accurate FAQs.'); return; } this.showResults('faq'); this.setLoading(true); fetch(PFEAI.rest_url + 'generate-faq?_t=' + Date.now(), { method: 'POST', headers: {'Content-Type':'application/json','X-WP-Nonce':PFEAI.nonce}, body: JSON.stringify({content: c, title: t, provider: this.getProvider()}) }) .then(function(r){ return r.json(); }) .then(function(j){ self.setLoading(false); if(j.faq && j.faq.length > 0) { self.renderFAQ(j.faq, editor); self.startCacheWindow(false); } else if (j.code) { self.faqEl.innerHTML = 'Error: ' + self.escapeHtml(j.message) + '
'; } else { self.faqEl.innerHTML = 'Failed to generate FAQ. Please try again.
'; } }) .catch(function(e) { self.setLoading(false); self.faqEl.innerHTML = 'Error: ' + self.escapeHtml(e.message) + '
'; }); }, renderFAQ: function(faqData, editor) { var self = this; if (!this.faqEl) return; this.faqEl.innerHTML = ''; var header = document.createElement('h4'); header.style.margin = '0 0 10px 0'; header.textContent = 'Review & Edit FAQ'; this.faqEl.appendChild(header); var instruction = document.createElement('p'); instruction.style.fontSize = '11px'; instruction.style.color = '#666'; instruction.textContent = 'Review your FAQs below. Clicking the button will send them down to the "Article FAQ & Schema" box at the bottom of your post screen. Remember to click the WordPress Update/Publish button to save them!'; this.faqEl.appendChild(instruction); var faqContainer = document.createElement('div'); faqContainer.id = 'pfeai-faq-inputs-container'; faqData.forEach(function(item, index) { var box = document.createElement('div'); box.style.background = '#fff'; box.style.padding = '10px'; box.style.marginBottom = '10px'; box.style.border = '1px solid #ddd'; box.style.borderRadius = '4px'; var qLabel = document.createElement('strong'); qLabel.style.fontSize = '11px'; qLabel.textContent = 'Question ' + (index + 1); box.appendChild(qLabel); var qInput = document.createElement('input'); qInput.type = 'text'; qInput.className = 'pfeai-faq-q'; qInput.style.width = '100%'; qInput.style.marginBottom = '8px'; qInput.value = item.question || ''; box.appendChild(qInput); var aLabel = document.createElement('strong'); aLabel.style.fontSize = '11px'; aLabel.textContent = 'Answer ' + (index + 1); box.appendChild(aLabel); var aInput = document.createElement('textarea'); aInput.className = 'pfeai-faq-a'; aInput.style.width = '100%'; aInput.style.height = '50px'; aInput.style.fontSize = '12px'; aInput.value = item.answer || ''; box.appendChild(aInput); faqContainer.appendChild(box); }); this.faqEl.appendChild(faqContainer); var insertBtn = document.createElement('button'); insertBtn.type = 'button'; insertBtn.className = 'button button-primary'; insertBtn.style.width = '100%'; insertBtn.innerHTML = '↓ Send to FAQ Meta Box'; insertBtn.onclick = function() { var qInputs = faqContainer.querySelectorAll('.pfeai-faq-q'); var aInputs = faqContainer.querySelectorAll('.pfeai-faq-a'); var transferCount = 0; for (var i = 0; i < qInputs.length; i++) { var qText = qInputs[i].value.trim(); var aText = aInputs[i].value.trim(); var metaQ = document.getElementById('pfeai_meta_q_' + i); var metaA = document.getElementById('pfeai_meta_a_' + i); if (metaQ && metaA) { metaQ.value = qText; metaA.value = aText; if (qText && aText) transferCount++; } } if (transferCount === 0) { alert('Could not locate the FAQ Meta Box on the screen. Please ensure "Article FAQ & Schema" is checked in your Screen Options at the top right.'); return; } insertBtn.innerHTML = '✓ Sent to Meta Box!'; setTimeout(function() { insertBtn.innerHTML = '↓ Send to FAQ Meta Box'; }, 2000); }; this.faqEl.appendChild(insertBtn); }, updateSerpPreview: function(selectedTitle) { var titleEl = document.getElementById('pfeai-serp-title'); var descEl = document.getElementById('pfeai-serp-desc'); var charCount = document.getElementById('pfeai-meta-char-count'); var titleCharNote = document.getElementById('pfeai-title-char-note'); var metaTextarea = document.getElementById('pfeai-meta-description'); if (selectedTitle && titleEl) { titleEl.textContent = selectedTitle; if (selectedTitle.length > 60) { titleEl.textContent = selectedTitle.substring(0, 57) + '...'; } } if (titleCharNote && titleEl) { var currentTitle = selectedTitle || titleEl.textContent; if (currentTitle === '(Select a title above)') currentTitle = ''; var titleLen = currentTitle.length; var titleColor = titleLen <= 60 ? '#2e7d32' : '#c62828'; titleCharNote.innerHTML = 'Title: ' + titleLen + '/60 chars ' + (titleLen <= 60 ? '✓' : '(may be truncated)'); } if (metaTextarea && descEl) { var desc = metaTextarea.value; if (desc) { descEl.textContent = desc.length > 155 ? desc.substring(0, 152) + '...' : desc; } else { descEl.textContent = '(Enter a meta description above)'; } } if (metaTextarea && charCount) { var len = metaTextarea.value.length; var color = '#666'; var status = ''; if (len === 0) { color = '#666'; } else if (len < 120) { color = '#e65100'; status = ' (too short)'; } else if (len >= 120 && len <= 155) { color = '#2e7d32'; status = ' ✓ optimal'; } else if (len > 155 && len <= 160) { color = '#e65100'; status = ' (slightly long)'; } else { color = '#c62828'; status = ' (will be truncated)'; } charCount.innerHTML = '' + len + ' / 155 characters' + status + ''; } }, saveToClipboard: function(title, html, redirectToNew) { fetch(PFEAI.rest_url + 'save-clipboard?_t=' + Date.now(), { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': PFEAI.nonce }, body: JSON.stringify({ title: title, content: html }) }) .then(function(){ if (redirectToNew) { window.open('/patriots/blog/wp-admin/post-new.php', '_blank'); } else { alert('Saved! You can now access this draft in the "Saved" tab on any new post.'); location.reload(); } }); }, clearClipboard: function() { fetch(PFEAI.rest_url + 'clear-clipboard?_t=' + Date.now(), { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': PFEAI.nonce } }) .then(function(r) { return r.json(); }) .then(function(json) { if (json.success) { alert('Saved draft cleared.'); location.reload(); } }) .catch(function(e) { console.error(e); }); }, clearIdeasCache: function() { fetch(PFEAI.rest_url + 'clear-ideas-cache?_t=' + Date.now(), { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': PFEAI.nonce }, body: JSON.stringify({ post_id: PFEAI.post_id }) }) .then(function(r) { return r.json(); }) .then(function(json) { if (json.success) { alert('Topics cache cleared.'); location.reload(); } }) .catch(function(e) { console.error(e); }); }, togglePanel: function(forceState) { if (!this.panelEl) return; var open = this.panelEl.classList.contains('pfeai-open'); var shouldOpen = (typeof forceState === 'boolean') ? forceState : !open; if (shouldOpen) { this.panelEl.classList.add('pfeai-open'); document.body.classList.add('pfeai-panel-open'); this.updateTranscriptVisibility(); if (this.isMinimized) document.body.classList.add('pfeai-panel-minimized'); else document.body.classList.remove('pfeai-panel-minimized'); } else { this.panelEl.classList.remove('pfeai-open'); document.body.classList.remove('pfeai-panel-open'); } }, showMenu: function() { this.panelEl.classList.remove('pfeai-show-results'); }, showResults: function(activeTab) { this.panelEl.classList.add('pfeai-show-results'); if (activeTab) this.switchTab(activeTab); }, updateTranscriptVisibility: function() { var isTranscript = false; var labels = document.querySelectorAll('.categorychecklist label'); for (var i = 0; i < labels.length; i++) { if (labels[i].innerText.indexOf('Patriots Transcripts') !== -1) { var input = labels[i].querySelector('input[type="checkbox"]'); if (input && input.checked) isTranscript = true; } } var btn = document.getElementById('btn-transcript'); var tab = document.getElementById('tab-transcript'); if (isTranscript) { if (btn) btn.style.display = 'block'; if (tab) tab.style.display = 'inline-block'; } else { if (btn) btn.style.display = 'none'; if (tab) tab.style.display = 'none'; } }, preloadSavedData: function() { if (!PFEAI.saved_data) return; if (PFEAI.saved_data.transcript && PFEAI.saved_data.transcript.suggestions) { this.renderTranscriptSuggestions(PFEAI.saved_data.transcript.suggestions, ''); this.setCachedState('btn-transcript', 'View Transcript Results', 'transcript', PFEAI.saved_data.transcript.generated_at); } if (PFEAI.saved_data.analysis && PFEAI.saved_data.analysis.highlights) { this.renderAnalysis(PFEAI.saved_data.analysis); this.setCachedState('btn-scan', 'View Analysis Results', 'highlights', PFEAI.saved_data.analysis.generated_at); } if (PFEAI.saved_data.titles && PFEAI.saved_data.titles.titles) { this.renderTitles(PFEAI.saved_data.titles); this.setCachedState('btn-titles', 'View Titles', 'titles', PFEAI.saved_data.titles.generated_at); } if (PFEAI.saved_data.ideas && PFEAI.saved_data.ideas.ideas) { this.renderIdeasInteractive(PFEAI.saved_data.ideas); this.setCachedState('btn-ideas', 'View Topics', 'ideas', PFEAI.saved_data.ideas.generated_at); } if (PFEAI.saved_data.social && PFEAI.saved_data.social.tweets) { this.renderSocialPack(PFEAI.saved_data.social); this.setCachedState('btn-social', 'View Social Posts', 'social', PFEAI.saved_data.social.generated_at); } if (PFEAI.saved_data.clipboard && this.savedEl) { this.renderSavedDraft(PFEAI.saved_data.clipboard); } if (PFEAI.saved_data.fact_check && PFEAI.saved_data.fact_check.factChecks) { this.renderFacts(PFEAI.saved_data.fact_check.factChecks); this.setCachedState('btn-fact-check', 'View Fact Check', 'facts', PFEAI.saved_data.fact_check.generated_at); } if (PFEAI.saved_data.links && PFEAI.saved_data.links.links) { this.renderInternalLinks(PFEAI.saved_data.links, null); this.setCachedState('btn-internal-links', '\uD83D\uDD17 View Links', 'links', PFEAI.saved_data.links.generated_at); } // Always render the SEO tab this.renderSeoTab(); // Render the Search Insights data this.renderGSCPanel(); }, setCachedState: function(btnId, newText, tabName, timestamp) { var btn = document.getElementById(btnId); if (btn) { if (btnId === 'btn-transcript' || btnId === 'btn-ideas' || btnId === 'btn-social') { btn.innerHTML = '' + this.escapeHtml(newText) + 'This team is so damn frustrating.\u00a0 The Opening drive by the Titans set me off right away.\u00a0 The Patriots had them at 3rd<\/sup> and 12 and Dietrich Wise blows up the field and lost his containment lane, allowing Mason Rudolph to scramble for a key 1st<\/sup> down.<\/p>\n This play infuriated me.\u00a0 Wise has made the same mistake over and over again losing containment.\u00a0 Selfish looking for the sack to pad his stats.\u00a0 They made Rudolph look like an All-Pro going 20\/33 for 240 yards 2 TDs and a bad INT.<\/p>\n <\/p>\n This team is so damn frustrating.\u00a0 The Opening drive by the Titans set me off right away.\u00a0 The Patriots had them at 3rd and 12 and Dietrich Wise blows up the field and lost his containment lane, allowing Mason Rudolph to scramble for a key 1st down.\u00a0<\/p>\n","protected":false},"author":23,"featured_media":56294,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[11],"tags":[],"class_list":["post-56301","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-patriots-commentary"],"yoast_head":"\n\n