// ==UserScript==
// @name komica發文自訂名稱跟類別(Komica name and category custom settings)
// @namespace http://tampermonkey.net/
// @version 2.1
// @description 為快速回覆表單添加自訂名稱和類別功能,保持拖拽功能,支持點擊No.插入引用到快速回覆內文並更新標題,通過AJAX刷新最新回覆,保留無貼圖、連貼機能、SAGE等功能,修復連貼機能點擊跳頁問題,優化503錯誤處理,處理Cloudflare預加載警告和$.isMobile錯誤,排除線程列表頁(如mode=module&load=mod_threadlist)
// @author Grok
// @match *://*.komica1.org/*
// @exclude *://*.komica1.org/*/src/*
// @exclude *://*.komica1.org/*/thumb/*
// @exclude *://*.komica1.org/*/pixmicat.php?mode=module*
// @grant none
// @require https://code.jquery.com/jquery-3.6.0.min.js
// @require https://code.jquery.com/ui/1.12.1/jquery-ui.min.js
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 檢查當前網址,排除線程列表頁
if (/mode=module/.test(window.location.search) && /load=mod_threadlist/.test(window.location.search)) {
console.log('檢測到線程列表頁(mode=module&load=mod_threadlist),腳本已退出');
return;
}
// 修補$.isMobile以避免script.js錯誤
$.isMobile = function() {
return /Mobi|Android/i.test(navigator.userAgent);
};
// 等待DOM加載完成
$(document).ready(function() {
// 修復Cloudflare預加載警告
$('link[href*="challenges.cloudflare.com"]').attr('as', 'fetch');
// 檢查quickreply表單並啟用拖拽
var $quickReply = $('#quickreply');
if ($quickReply.length) {
$quickReply.draggable({
handle: '.quickreply-head',
containment: 'window'
});
}
// 修復快速回覆表單的連貼機能勾選框
var $quickReplyUpSeries = $('#quickreply-form input[name="up_series"]');
if ($quickReplyUpSeries.length) {
$quickReplyUpSeries.attr('id', 'quickreply-up_series');
var $upSeriesLabel = $quickReplyUpSeries.next('label[for="up_series"]');
if ($upSeriesLabel.length) {
$upSeriesLabel.attr('for', 'quickreply-up_series');
} else {
$quickReplyUpSeries.after('<label for="quickreply-up_series">[連貼機能]</label>');
}
$quickReplyUpSeries.add($upSeriesLabel).on('click', function(e) {
e.preventDefault();
console.log('點擊連貼機能:', e.target);
$quickReplyUpSeries.prop('checked', !$quickReplyUpSeries.prop('checked'));
$('#postform input[name="up_series"]').prop('checked', false);
});
}
// 修復其他勾選框(noimg, ObHGyhdTR)
var $quickReplyNoImg = $('#quickreply-form input[name="noimg"]');
if ($quickReplyNoImg.length) {
$quickReplyNoImg.attr('id', 'quickreply-noimg');
var $noImgLabel = $quickReplyNoImg.next('label[for="noimg"]');
if ($noImgLabel.length) {
$noImgLabel.attr('for', 'quickreply-noimg');
} else {
$quickReplyNoImg.after('<label for="quickreply-noimg">[無貼圖]</label>');
}
$quickReplyNoImg.add($noImgLabel).on('click', function(e) {
e.preventDefault();
console.log('點擊無貼圖:', e.target);
$quickReplyNoImg.prop('checked', !$quickReplyNoImg.prop('checked'));
$('#postform input[name="noimg"]').prop('checked', false);
});
}
var $quickReplySage = $('#quickreply-form input[name="ObHGyhdTR"]');
if ($quickReplySage.length) {
$quickReplySage.attr('id', 'quickreply-sage');
var $sageLabel = $quickReplySage.next('label[for="ObHGyhdTR"]');
if ($sageLabel.length) {
$sageLabel.attr('for', 'quickreply-sage');
} else {
$quickReplySage.after('<label for="quickreply-sage">[SAGE]</label>');
}
$quickReplySage.add($sageLabel).on('click', function(e) {
e.preventDefault();
console.log('點擊SAGE:', e.target);
$quickReplySage.prop('checked', !$quickReplySage.prop('checked'));
$('#postform input[name="ObHGyhdTR"]').prop('checked', false);
});
}
// 處理名稱輸入框
var $nameInputFname = $('#fname');
var $nameInputPlaceholder = $("input[placeholder='名稱']:not(.hide)");
var $nameInputs = $().add($nameInputFname).add($nameInputPlaceholder);
if ($nameInputs.length) {
$nameInputs.each(function() {
var $input = $(this);
var $setNameBtn = $('<button type="button" style="font-family: Arial; margin-left: 5px;">設置名稱</button>');
$input.after($setNameBtn);
$setNameBtn.on('click', function() {
var customName = prompt('請輸入自訂名稱:', $input.val() || '');
if (customName !== null && customName.trim() !== '') {
if ($input.attr('id') === 'fname') {
customName = customName.substring(0, 100);
}
$input.val(customName);
localStorage.setItem('input-name-' + ($input.attr('id') || 'placeholder'), customName);
}
});
var savedName = localStorage.getItem('input-name-' + ($input.attr('id') || 'placeholder'));
if (savedName) {
$input.val(savedName);
}
});
}
// 處理類別輸入框
var $categoryInputs = $("input[name='category']");
if ($categoryInputs.length) {
$categoryInputs.each(function() {
var $input = $(this);
var $setCategoryBtn = $('<button type="button" style="font-family: Arial; margin-left: 5px;">設置類別</button>');
$input.after($setCategoryBtn);
$setCategoryBtn.on('click', function() {
var customCategory = prompt('請輸入類別標籤(以逗號分隔):', $input.val() || '');
if (customCategory !== null && customCategory.trim() !== '') {
var tags = customCategory.split(',').map(tag => tag.trim()).filter(tag => tag !== '');
if (tags.length > 0) {
var categoryValue = tags.join(', ');
$input.val(categoryValue);
localStorage.setItem('input-category-' + ($input.attr('name') || 'category'), categoryValue);
} else {
alert('請輸入至少一個有效的標籤!');
}
}
});
var savedCategory = localStorage.getItem('input-category-' + ($input.attr('name') || 'category'));
if (savedCategory) {
$input.val(savedCategory);
}
});
}
// 處理點擊No.插入引用並更新標題
$('.qlink').on('click', function(e) {
e.preventDefault();
var postNo = $(this).attr('data-no');
var quoteText = `>>No.${postNo}\n`;
var $quickReplyTextarea = $('#quickreply textarea[name="pOBvrtyJK"]');
if ($quickReplyTextarea.length) {
$quickReply.css('display', 'block');
var currentText = $quickReplyTextarea.val();
$quickReplyTextarea.val(quoteText + currentText);
$quickReplyTextarea.focus();
var $quickReplyTitle = $('.quickreply-title');
if ($quickReplyTitle.length) {
$quickReplyTitle.text(`Quick Reply >>No.${postNo}`);
}
} else {
console.warn('未找到快速回覆表單的textarea');
}
});
// 處理快速回覆表單關閉按鈕
$('.quickreply-close').on('click', function() {
$quickReply.css('display', 'none');
});
// 處理快速回覆表單提交(帶重試機制)
function submitReply(formData, $form, attempt = 1, maxAttempts = 3) {
console.log(`提交表單(嘗試 ${attempt}/${maxAttempts}):`, Array.from(formData.entries()));
$.ajax({
url: $form.attr('action') || 'pixmicat.php',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(response, status, xhr) {
console.log('提交成功,回應狀態:', xhr.status, '回應內容:', response);
// 重置表單
$form.find('textarea[name="pOBvrtyJK"]').val('');
$form.find('input[name="upfile"]').val('');
$form.find('input[name="noimg"]').prop('checked', false);
$form.find('input[name="up_series"]').prop('checked', false);
$form.find('input[name="ObHGyhdTR"]').prop('checked', false);
$form.find('input[name="category"]').val(localStorage.getItem('input-category-category') || '');
$form.find('input[name="bvUFbdrIC"]').val(localStorage.getItem('input-name-placeholder') || '');
// 刷新線程
refreshThread();
},
error: function(xhr, status, error) {
console.error(`提交失敗(嘗試 ${attempt}/${maxAttempts}):`, status, error, '回應狀態:', xhr.status, '回應內容:', xhr.responseText);
// 處理503錯誤或潛在成功
if (xhr.status === 503 && attempt < maxAttempts) {
console.log(`檢測到503錯誤,重試 ${attempt + 1}/${maxAttempts}...`);
setTimeout(() => submitReply(formData, $form, attempt + 1, maxAttempts), 2000);
} else if (xhr.status === 200 || xhr.status === 302 || xhr.responseText.includes('成功')) {
console.log('檢測到可能的成功提交,嘗試刷新線程');
refreshThread();
} else {
alert('回覆提交失敗(狀態碼: ' + xhr.status + '),請檢查網絡或稍後重試。手動刷新頁面可能顯示您的回覆。');
// 仍嘗試刷新以檢查是否成功
refreshThread();
}
}
});
}
// 表單提交事件
$('#quickreply-form').on('submit', function(e) {
e.preventDefault();
var $form = $(this);
var formData = new FormData(this);
// 確保Cloudflare Turnstile token包含
var $turnstileResponse = $('.cf-turnstile input[name="cf-turnstile-response"]');
if ($turnstileResponse.length) {
if (!$turnstileResponse.val()) {
console.warn('Turnstile token 為空,可能導致提交失敗');
}
formData.append('cf-turnstile-response', $turnstileResponse.val());
} else {
console.warn('未找到Cloudflare Turnstile token,可能導致提交失敗');
}
// 開始提交
submitReply(formData, $form);
});
// 刷新線程函數(帶重試機制並規避$.isMobile錯誤)
function refreshThread(attempt = 1, maxAttempts = 3) {
var threadNo = $('#quickreply-form input[name="resto"]').val();
if (!threadNo) {
console.warn('無法獲取線程ID');
alert('無法刷新線程,請手動重新整理頁面。');
return;
}
var $thread = $(`div.thread[data-no="${threadNo}"]`);
var existingReplyIds = $thread.find('.post.reply').map(function() {
return $(this).attr('data-no');
}).get();
console.log('正在刷新線程:', threadNo, '現有回覆ID:', existingReplyIds);
$.ajax({
url: `pixmicat.php?res=${threadNo}`,
type: 'GET',
cache: false,
success: function(data) {
console.log('線程數據獲取成功,解析新回覆...');
var $newContent = $('<div>').html(data);
var $newReplies = $newContent.find(`div.thread[data-no="${threadNo}"] .post.reply`);
if ($newReplies.length === 0) {
console.warn('未找到新回覆,可能是伺服器延遲');
if (attempt < maxAttempts) {
console.log(`重試 ${attempt + 1}/${maxAttempts}...`);
setTimeout(() => refreshThread(attempt + 1, maxAttempts), 2000);
return;
} else {
alert('未檢測到新回覆,請手動刷新頁面確認。');
return;
}
}
var newRepliesAdded = false;
$newReplies.each(function() {
var replyId = $(this).attr('data-no');
if (!existingReplyIds.includes(replyId)) {
try {
$thread.find('hr').before($(this));
newRepliesAdded = true;
console.log('添加新回覆:', replyId);
} catch (e) {
console.error('添加回覆時發生錯誤(可能是Komica原生腳本問題):', e);
}
}
});
if (newRepliesAdded) {
console.log('線程已刷新,新回覆已添加');
// 直接展開回覆,規避$.isMobile錯誤
$thread.find('.post.reply').each(function() {
var $post = $(this);
try {
$post.find('.post-content').show();
} catch (e) {
console.warn('展開回覆失敗:', e);
}
});
} else {
console.warn('未找到新回覆,可能是伺服器延遲或無新內容');
if (attempt < maxAttempts) {
console.log(`重試 ${attempt + 1}/${maxAttempts}...`);
setTimeout(() => refreshThread(attempt + 1, maxAttempts), 2000);
} else {
alert('未檢測到新回覆,請手動刷新頁面確認。');
}
}
},
error: function(xhr, status, error) {
console.error('線程刷新失敗:', status, error, '回應狀態:', xhr.status, '回應內容:', xhr.responseText);
if (attempt < maxAttempts) {
console.log(`重試 ${attempt + 1}/${maxAttempts}...`);
setTimeout(() => refreshThread(attempt + 1, maxAttempts), 2000);
} else {
alert('無法刷新線程,請手動重新整理頁面。');
}
}
});
}
});
})();