1// Form Validation (Length checks only) 2function validateCommentForm(name, content) { 3 // Name validation 4 if (!name || name.length < 3) { 5 showToast(_LANG.at_least_3, false); 6 return false; 7 } 8 9 if (name.length > 20) { 10 showToast('Name cannot exceed 20 characters', false); 11 return false; 12 } 13 14 // Content validation 15 if (!content || content.length < 10) { 16 showToast(_LANG.at_least_10, false); 17 return false; 18 } 19 20 if (content.length > 500) { 21 showToast('Comment cannot exceed 500 characters', false); 22 return false; 23 } 24 25 return true; 26} 27 28// Form Submission Handler 29var wwwdomain = window.wwwdomain || ''; 30var iflogin = typeof window.iflogin !== 'undefined' ? window.iflogin : 0; 31 32function setupLoginDialog(){ 33 if (typeof showConfirm !== 'function') return null; 34 return { show: function(){ showConfirm(_LANG.continue_by_sign||'continue by sign'); } }; 35} 36 37document.getElementById('commentForm')?.addEventListener('submit', async function(e) { 38 e.preventDefault(); 39 40 const form = e.target; 41 const submitBtn = form.querySelector('button[type="submit"]'); 42 const nameInput = form.querySelector('#comment_name'); 43 const commentInput = form.querySelector('#comment_message'); 44 45 // Validate form 46 if (!validateCommentForm(nameInput.value, commentInput.value)) { 47 return; 48 } 49 50 // Disable button during submission 51 submitBtn.disabled = true; 52 submitBtn.textContent = _LANG.submitting; 53 54 try { 55 const formData = new FormData(form); 56 const urlParams = new URLSearchParams(); 57 58 // å° FormData 转æ¢ä¸º URLSearchParams 59 for (const [key, value] of formData.entries()) { 60 urlParams.append(key, value); 61 } 62 63 console.log('Sending comment data (comments.js):', Object.fromEntries(urlParams.entries())); 64 65 const response = await fetch('/api/submitComment', { 66 method: 'POST', 67 headers: { 68 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 69 'X-Requested-With': 'XMLHttpRequest' 70 }, 71 body: urlParams.toString() 72 }); 73 74 if (!response.ok) throw new Error(_LANG.try_again_later); 75 76 const result = await response.json(); 77 78 if (result.success) { 79 showToast(_LANG.submitted, true); 80 if (typeof window.clearCommentsListCache === 'function') { 81 window.clearCommentsListCache(); 82 } 83 addCommentToUI(nameInput.value, commentInput.value); 84 commentInput.value = ''; 85 } else { 86 throw new Error(result.message || _LANG.try_again_later); 87 } 88 } catch (error) { 89 //showToast(error.message || _LANG.try_again_later, false); 90 showToast(error.message === '-1' ? _LANG.voted_today :error.message ? error.message :_LANG.try_again_later,false); 91 console.error('Error:', error); 92 } finally { 93 submitBtn.disabled = false; 94 submitBtn.textContent = _LANG.leaveacomment; 95 } 96}); 97 98// 表åéªè¯å½æ°ï¼ç¤ºä¾ï¼ 99function validateCommentForm(name, content) { 100 if (!name || name.length < 3) { 101 showToast(_LANG.at_least_3, false); 102 return false; 103 } 104 105 if (!content || content.length < 10) { 106 showToast(_LANG.at_least_10, false); 107 return false; 108 } 109 110 return true; 111} 112 113// æ·»å è¯è®ºå°UIç彿° 114function addCommentToUI(name, content) { 115 const commentsContainer = document.querySelector('.comments__list') || 116 document.querySelector('.comments'); 117 if (!commentsContainer) return; 118 119 const newComment = document.createElement('div'); 120 newComment.className = 'comments__item'; 121 newComment.innerHTML = ` 122 <div class="comments__avatar">${name.charAt(0).toUpperCase()}</div> 123 <div class="comments__content"> 124 <div class="comments__header"> 125 <span class="comments__author">${name}<span class="comments__under-review">${_LANG.under_review}</span></span>
126 <span class="comments__date">${_LANG.just_now}</span> 127 </div> 128 <p class="comments__text">${content}</p> 129 </div> 130 `; 131 132 commentsContainer.prepend(newComment); 133} 134 135// Rate limiting (10 seconds between submissions) 136let lastSubmitTime = 0; 137document.getElementById('commentForm')?.addEventListener('submit', function(e) { 138 const now = Date.now(); 139 if (now - lastSubmitTime < 10000) { 140 e.preventDefault(); 141 showToast(_LANG.try_again_later, false); 142 return false; 143 } 144 lastSubmitTime = now; 145}); 146 147// Character counters setup 148function setupCharCounters() { 149 // Comment character counter 150 const commentInput = document.getElementById('comment_message'); 151 if (commentInput) { 152 const counter = document.createElement('div'); 153 counter.id = 'comment-char-count'; 154 counter.style.fontSize = '12px'; 155 counter.style.color = '#666'; 156 counter.style.marginTop = '5px'; 157 commentInput.parentNode.appendChild(counter); 158 159 commentInput.addEventListener('input', function(e) { 160 const charCount = e.target.value.length; 161 counter.textContent = `${charCount}/500 characters`; 162 counter.style.color = charCount > 500 ? 'red' : '#666'; 163 }); 164 } 165 166 // Name character counter 167 const nameInput = document.getElementById('comment_name'); 168 if (nameInput) { 169 const counter = document.createElement('div'); 170 counter.id = 'name-char-count'; 171 counter.style.fontSize = '12px'; 172 counter.style.color = '#666'; 173 counter.style.marginTop = '5px'; 174 nameInput.parentNode.appendChild(counter); 175 176 nameInput.addEventListener('input', function(e) { 177 const charCount = e.target.value.length; 178 counter.textContent = `${charCount}/20 characters`; 179 counter.style.color = charCount > 20 ? 'red' : '#666'; 180 }); 181 } 182} 183 184// Initialize character counters 185document.addEventListener('DOMContentLoaded', setupCharCounters);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.