Đăng truyện nhanh TTV với nhiều tính năng mới và tự động tách chương
目前為
// ==UserScript==
// @name TTV
// @namespace http://tampermonkey.net/
// @version 2.9
// @description Đăng truyện nhanh TTV với nhiều tính năng mới và tự động tách chương
// @author HA
// @match https://tangthuvien.net/dang-chuong/story/*
// @match https://tangthuvien.net/danh-sach-chuong/story/*
// @grant none
// @required https://code.jquery.com/jquery-3.2.1.min.js
// @icon https://tangthuvien.net/images/icon-favico.png
// @copyright 2021-2023, by HA
// @license AGPL-3.0-only
// @collaborator HA
// ==/UserScript==
var headerSign = "";
var footerSign = "";
var dăngnhanhTTV = {
YEAR_ALIVE: 2021,
MAX_CHAPTER_POST: 10,
CHAP_NUMBER: 1,
CHAP_STT: 1,
CHAP_SERIAL: 1,
CHAP_NUMBER_ORIGINAL: 1,
CHAP_STT_ORIGINAL: 1,
CHAP_SERIAL_ORIGINAL: 1,
addNewChapter: function () {
var me = this;
if ((me.CHAP_NUMBER + 1) <= me.MAX_CHAPTER_POST) {
me.updateChapNumber(true);
var chap_vol = parseInt(jQuery('.chap_vol').val());
var chap_vol_name = jQuery('.chap_vol_name').val();
var html =
'<div data-gen="MK_GEN" id="COUNT_CHAP_' + me.CHAP_NUMBER + '_MK">' +
'<div class="col-xs-12 form-group"></div>' +
'<div class="form-group">' +
'<label class="col-sm-2" for="chap_stt">STT</label>' +
'<div class="col-sm-8">' +
'<input class="form-control" required name="chap_stt[' + me.CHAP_NUMBER + ']" value="' + me.CHAP_STT +
'" placeholder="Số thứ tự của chương" type="text"/>' +
'</div>' +
'</div>' +
'<div class="form-group">' +
'<label class="col-sm-2" for="chap_number">Chương thứ..</label>' +
'<div class="col-sm-8">' +
'<input value="' + me.CHAP_SERIAL + '" required class="form-control" name="chap_number[' + me.CHAP_NUMBER +
']" placeholder="Chương thứ.. (1,2,3..)" type="text"/>' +
'</div>' +
'</div>' +
'<div class="form-group">' +
'<label class="col-sm-2" for="chap_name">Quyển số</label>' +
'<div class="col-sm-8">' +
'<input class="form-control" name="vol[' + me.CHAP_NUMBER +
']" placeholder="Quyển số" type="number" value="' + chap_vol + '" required/>' +
'</div>' +
'</div>' +
'<div class="form-group">' +
'<label class="col-sm-2" for="chap_name">Tên quyển</label>' +
'<div class="col-sm-8">' +
'<input class="form-control chap_vol_name" name="vol_name[' + me.CHAP_NUMBER +
']" placeholder="Tên quyển" type="text" value="' + chap_vol_name + '" />' +
'</div>' +
'</div>' +
'<div class="form-group">' +
'<label class="col-sm-2" for="chap_name">Tên chương</label>' +
'<div class="col-sm-8">' +
'<input required class="form-control" name="chap_name[' + me.CHAP_NUMBER +
']" placeholder="Tên chương" type="text"/>' +
'</div>' +
'</div>' +
'<div class="form-group">' +
'<label class="col-sm-2" for="introduce">Nội dung</label>' +
'<div class="col-sm-8">' +
'<textarea maxlength="75000" style="color:#000;font-weight: 400;" required class="form-control" ' +
'name="introduce[' + me.CHAP_NUMBER + ']" rows="20" placeholder="Nội dung" type="text"></textarea>' +
'</div>' +
'</div>' +
'<div class="form-group">' +
'<label class="col-sm-2" for="adv">Quảng cáo</label>' +
'<div class="col-sm-8">' +
'<textarea maxlength="1000" class="form-control" name="adv[' + me.CHAP_NUMBER +
']" placeholder="Quảng cáo" type="text"></textarea>' +
'</div>' +
'</div>' +
'</div>';
jQuery('#add-chap').before(html);
}
else {
var chapterLeft = me.MAX_CHAPTER_POST - me.CHAP_NUMBER;
chapterLeft = chapterLeft < 0 ? 0 : chapterLeft;
alert('Bạn nên đăng tối đa ' + me.MAX_CHAPTER_POST + ' chương một lần, số chương đã tạo ' +
me.CHAP_NUMBER + ' chương, bạn có thể đăng thêm ' + chapterLeft + ' chương nữa.');
}
},
createListAddChapter: function (isSilent) {
var me = this;
var chapterAdd = 0;
chapterAdd = parseInt(jQuery("#qpNumberOfChapter").val());
if ((me.CHAP_NUMBER + chapterAdd) <= me.MAX_CHAPTER_POST) {
for (var i = 0; i < chapterAdd; i++) {
me.addNewChapter();
}
if (!isSilent) {
alert('Đã tạo thêm ' + chapterAdd + ' chương, hãy copy và dán nội dung cần đăng.');
}
}
else {
alert('Bạn nên đăng tối đa ' + me.MAX_CHAPTER_POST + ' chương một lần, số chương đã tạo ' + me.CHAP_NUMBER + ' chương, bạn có thể đăng thêm ' + (me.MAX_CHAPTER_POST - me.CHAP_NUMBER) + ' chương nữa.');
}
},
removeLastedPost: function () {
var me = this;
jQuery("#COUNT_CHAP_" + me.CHAP_NUMBER + "_MK").remove();
me.updateChapNumber();
},
updateChapNumber: function (isAdd) {
var me = this;
try {
if (isAdd) {
var chap_stt = parseInt(jQuery('.chap_stt1').val());
var chap_serial = parseInt(jQuery('.chap_serial').val());
if (parseInt(jQuery('#chap_stt').val()) > chap_stt) {
chap_stt = parseInt(jQuery('#chap_stt').val());
}
if (parseInt(jQuery('#chap_serial').val()) > chap_serial) {
chap_serial = parseInt(jQuery('#chap_serial').val());
}
me.CHAP_STT = chap_stt;
me.CHAP_SERIAL = chap_serial;
me.CHAP_NUMBER++;
me.CHAP_STT++;
me.CHAP_SERIAL++;
}
else {
if (me.CHAP_NUMBER > me.CHAP_NUMBER_ORIGINAL) {
me.CHAP_NUMBER--;
}
if (me.CHAP_STT > me.CHAP_STT_ORIGINAL) {
me.CHAP_STT--;
}
if (me.CHAP_SERIAL > me.CHAP_SERIAL_ORIGINAL) {
me.CHAP_SERIAL--;
}
}
jQuery('#chap_number').val(me.CHAP_NUMBER);
jQuery('#chap_stt').val(me.CHAP_STT);
jQuery('#chap_serial').val(me.CHAP_SERIAL);
jQuery('#countNumberPost').text(me.CHAP_NUMBER);
}
catch (e) {
console.log("Lỗi: " + e);
}
},
createEl: function (n) {
return document.createElement(n);
},
addStyle: function (style) {
var me = this;
var s = me.createEl("style"),
h = document.getElementById('HA');
s.type = "text/css";
s.appendChild(document.createTextNode(style));
h.appendChild(s);
},
addCss: function () {
var me = this;
var s =
'#HA { ' +
'background-color: rgb(255, 255, 255) !important;' +
'padding: 3px 15px;' +
'color: black !important;' +
'border-radius: 5px 0px 0px 5px;' +
'margin-bottom: 15px;' +
'position: fixed;' +
'right: 10px;' +
'top: 10px;' +
'max-width: 400px;' +
'z-index: 9999;' +
'box-shadow: -2px 0 5px rgba(0,0,0,0.1);' +
'}' +
'#HA > .form-group > div {' +
'font-size: 13px;' +
'color: black !important;' +
'}' +
'#HA > p {' +
'font-size: 13px;' +
'color: black !important;' +
'text-align: right;' +
'}' +
'#HA .HA-option {' +
'padding: 5px;' +
'border: 1px dashed #4CAF50;' +
'border-radius: 5px;' +
'margin-bottom: 32px;' +
'}' +
'#HA .HA-option-label {' +
'width: 100%;' +
'background-color: black;' +
'padding: 10px;' +
'border-radius: 5px 5px 0px 0px;' +
'margin: 0;' +
'}' +
'#qpn {' +
'max-height: 300px;' +
'overflow-y: auto;' +
'margin-top: 10px;' +
'font-size: 12px;' +
'}' +
'#qpn div {' +
'font-size: 12px;' +
'margin: 2px 0;' +
'}' +
'.hidden-element, .hidden-config-section {' +
'display: none !important;' +
'height: 0 !important;' +
'overflow: hidden !important;' +
'visibility: hidden !important;' +
'padding: 0 !important;' +
'margin: 0 !important;' +
'position: absolute !important;' +
'left: -9999px !important;' +
'}';
me.addStyle(s);
setTimeout(function () {
const elementsToHide = [
document.querySelector('.hidden-config-section'),
document.getElementById('qpSplitValue'),
document.getElementById('qpSplitValueReplace'),
document.getElementById('qpNumberOfChapter')
];
elementsToHide.forEach(function (el) {
if (el) {
el.style.display = 'none';
el.style.visibility = 'hidden';
el.style.height = '0px';
el.style.overflow = 'hidden';
el.style.position = 'absolute';
el.style.left = '-9999px';
el.setAttribute('aria-hidden', 'true');
}
});
}, 100);
},
createInjectHTML: function () {
var me = this;
var h =
'<div id="HA">' +
'<div class="form-group"></div>' +
'<center>' +
'<h3>CÔNG CỤ ĐĂNG NHANH</h3>' +
'</center>' +
'<center>' +
'<h4><span id="short-chapter-warning" style="display:none; color:red;"></span></h4>' +
'</center>' +
'<div class="form-group">' +
'<textarea placeholder="Nội dung truyện (Dán vào đây để tự động tách chương)" id="qpContent" class="form-control" rows="5"></textarea>' +
'<div class="form-group" id="qpAdv" class="form-control" rows="2"></div>' +
'<div class="form-group" style="text-align: center; margin-top: 10px;">' +
'<button type="button" id="qpButtonSubmit" class="btn btn-default" style="margin: 0 5px;" onclick="javascript:;">Đăng chương</button>' +
'<button type="button" id="qpButtonRemoveEmpty" class="btn btn-danger" style="margin: 0 5px; display: none;">Xóa chương trống</button>' +
'</div>' +
'<div class="form-group">' +
'<span id="qpn" style="margin:0px 15px;font-weight:bold"></span>' +
'</div>' +
'</div>' +
'<div class="hidden-config-section" style="display:none;height:0;overflow:hidden;visibility:hidden;">' +
'<h4></h4>' +
'<div class="form-group">' +
'<input type="text" id="qpSplitValue" class="form-control" value="/[c|C]hương\\s?\\d+\\s?:?\\s?/">' +
'</div>' +
'<div class="form-group" id="qpSplitValueReplace"></div>' +
'<div class="form-group">' +
'<input type="number" placeholder="Thêm" value="9" id="qpNumberOfChapter" class="form-control">' +
'</div>' +
'</div>' +
'</div>';
jQuery(".list-in-user").before(h);
},
performAction: function () {
try {
var me = this;
var a = jQuery("#qpContent").val(),
s = jQuery("#qpSplitValue").val(),
st = jQuery('#qpSplitValueReplace').val().trim(),
titles = jQuery("[name^=chap_name]"),
contents = jQuery("[name^=introduce]"),
advs = jQuery("[name^=adv]"),
error = false,
advContent = jQuery("#qpAdv").val();
me.fillEmptyForms(titles, contents, advs, advContent, st);
if (s.startsWith('/') && s.endsWith('/') && s.length > 0) {
s = new RegExp(s.substring(1, s.length - 1));
}
a = a.split(s).filter(function (entry) {
return entry.trim() !== "";
});
if (!loop && a.length < titles.length) {
error = true;
}
if (loop && (a.length / 2) < titles.length) {
error = true;
}
var splitTitle = st.toLowerCase();
if (!loop) {
jQuery.each(titles, (function (k, v) {
if (k < a.length) {
var at = a[k].trim(),
content = at.split('\n'),
originalTitle = content.shift().trim(),
title = originalTitle.toLowerCase();
originalTitle = me.ucFirst(originalTitle);
if (title.startsWith(splitTitle)) {
titles[k].value = originalTitle;
contents[k].value = headerSign + "\r\n" + content.join('\n') + "\r\n" + footerSign;
advs[k].value = advContent;
}
else {
titles[k].value = st + " " + originalTitle;
contents[k].value = headerSign + "\r\n" + content.join('\n') + "\r\n" + footerSign;
advs[k].value = advContent;
}
}
else {
jQuery("#qpContent").val("Đã thực hiện được " + k + " /" + (titles.length) + " nhập ban đầu, có thể nhấn Xóa chương trống, sau đó nhấn Đăng chương");
return false;
}
}));
}
else {
var j = 0,
ha = a.length / 2;
jQuery.each(titles, (function (k, v) {
if (k < ha) {
var at = a[++j].trim(),
content = at.split('\n'),
originalTitle = content.shift().trim(),
title = '';
title = originalTitle.toLowerCase();
if (title === '') {
while (title === '' && content.length > 0) {
originalTitle = content.shift().trim();
title = originalTitle.toLowerCase();
}
}
originalTitle = me.ucFirst(originalTitle);
if (title.startsWith(splitTitle)) {
titles[k].value = originalTitle;
contents[k].value = headerSign + "\r\n" + content.join('\n') + "\r\n" + footerSign;
advs[k].value = advContent;
}
else {
titles[k].value = st + " " + originalTitle;
contents[k].value = headerSign + "\r\n" + content.join('\n') + "\r\n" + footerSign;
advs[k].value = advContent;
}
}
else {
jQuery("#qpContent").val("Đã thực hiện được " + k + " /" + (titles.length) + " nhập ban đầu, có thể nhấn Vẫn Đăng để tiếp tục");
return false;
}
j++;
}));
}
if (!error) {
jQuery("#qpButtonSubmit").removeClass("btn-disable").addClass("btn-success");
jQuery("#qpContent").val("Đã thực hiện xong, OK");
}
}
catch (e) {
console.log("Lỗi: " + e);
}
},
removeEmptyList: function () {
try {
var me = this;
var titles = jQuery("[name^=chap_name]"),
contents = jQuery("[name^=introduce]"),
count = 0;
jQuery("#qpn").html('');
if (titles && titles.length) {
for (var i = 0; i < titles.length; i++) {
var t = titles[i];
var c = contents[i];
if (t) {
if (!t.value || (c && !c.value.trim().replace(headerSign, '').replace(footerSign, '').trim())) {
if (t.parentElement.parentElement.parentElement.tagName != 'FORM') {
t.parentElement.parentElement.parentElement.remove();
}
me.updateChapNumber();
count++;
}
}
}
}
alert('Đã loại bỏ ' + count + ' chương trống. Đã có thể nhấn Đăng chương');
}
catch (e) {
console.log("Lỗi: " + e);
}
},
registerEvents: function () {
var me = this;
jQuery("#qpContent").on("paste", function (e) {
jQuery(this).val("");
var processingMsg = jQuery("<div>", {
id: "processing-notification",
text: "Đang xử lý tách chương...",
css: {
position: "fixed",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
backgroundColor: "rgba(0, 0, 0, 0.7)",
color: "white",
padding: "15px 20px",
borderRadius: "5px",
zIndex: "10000",
fontSize: "16px"
}
});
jQuery("body").append(processingMsg);
setTimeout(function () {
dăngnhanhTTV.splitChapters();
jQuery("#processing-notification").fadeOut(300, function () {
jQuery(this).remove();
});
var completeMsg = jQuery("<div>", {
id: "complete-notification",
text: "Đã tách chương tự động!",
css: {
position: "fixed",
top: "20px",
right: "20px",
backgroundColor: "#4CAF50",
color: "white",
padding: "10px 15px",
borderRadius: "5px",
zIndex: "10000",
fontSize: "14px"
}
});
jQuery("body").append(completeMsg);
completeMsg.fadeIn(300).delay(2000).fadeOut(500, function () {
jQuery(this).remove();
});
}, 500);
});
jQuery("#qpButtonRemoveLast").on('click', function (e) {
e.preventDefault();
dăngnhanhTTV.removeLastedPost();
});
jQuery("#qpButtonGenChapter").on('click', function (e) {
e.preventDefault();
dăngnhanhTTV.createListAddChapter();
});
jQuery("#qpButtonResetChapter").on('click', function (e) {
e.preventDefault();
if (confirm('Bạn có chắc chắn xóa toàn bộ danh sách đã tạo, chú ý sẽ xóa toàn bộ nội dung đã dán trước đó')) {
var count = jQuery('[data-gen="MK_GEN"]').length;
jQuery('[data-gen="MK_GEN"]').remove();
for (var i = 0; i < count; i++) {
me.updateChapNumber();
}
}
});
jQuery("#qpSaveConfig").on("click", function (e) {
e.preventDefault();
me.saveCookies();
});
jQuery('#qpButtonRemoveEmpty').on('click', function (e) {
e.preventDefault();
me.removeEmptyList();
var titles = jQuery("[name^=chap_name]");
var contents = jQuery("[name^=introduce]");
var advs = jQuery("[name^=adv]");
var advContent = jQuery("#qpAdv").val();
var st = jQuery('#qpSplitValueReplace').val().trim();
me.fillEmptyForms(titles, contents, advs, advContent, st);
});
jQuery('#qpButtonTitleReplace').on('click', function (e) {
e.preventDefault();
me.replaceTitle();
});
jQuery("#qpButtonSubmit").on('click', function (e) {
e.preventDefault();
var titles = jQuery("[name^=chap_name]");
var contents = jQuery("[name^=introduce]");
var advs = jQuery("[name^=adv]");
var advContent = jQuery("#qpAdv").val();
var st = jQuery('#qpSplitValueReplace').val().trim();
me.fillEmptyForms(titles, contents, advs, advContent, st);
jQuery('form button[type=submit]')[0].click();
});
me.readCookies();
},
saveCookies: function () {
try {
var value = {
splitValue: jQuery("#qpSplitValue").val(),
optionLoop: jQuery("#qpOptionLoop")[0].checked,
numberChapter: jQuery('#qpNumberOfChapter').val(),
splitValueReplace: jQuery('#qpSplitValueReplace').val()
};
var cookieValue = JSON.stringify(value);
var d = new Date();
d.setTime(d.getTime() + (30 * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toUTCString();
document.cookie = "HAconfig=" + encodeURIComponent(cookieValue) + ";" + expires + ";path=/;domain=tangthuvien.net";
alert("Đã lưu lại thiết lập thành công");
} catch (e) {
console.log("Lỗi khi lưu thiết lập: " + e);
alert("Có lỗi xảy ra khi lưu thiết lập");
}
},
readCookies: function () {
try {
var cookieValue = null;
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.indexOf('HAconfig=') === 0) {
cookieValue = decodeURIComponent(cookie.substring('HAconfig='.length));
break;
}
}
if (cookieValue) {
try {
var settings = JSON.parse(cookieValue);
if (settings.splitValue) jQuery("#qpSplitValue").val(settings.splitValue);
if (settings.optionLoop !== undefined) jQuery("#qpOptionLoop")[0].checked = settings.optionLoop;
if (settings.numberChapter) jQuery("#qpNumberOfChapter").val(settings.numberChapter);
if (settings.splitValueReplace) jQuery("#qpSplitValueReplace").val(settings.splitValueReplace);
} catch (e) {
console.log("Lỗi khi parse cookie: " + e);
}
}
} catch (e) {
console.log("Lỗi khi đọc cookie: " + e);
}
},
setCopyRight: function () {
try {
var me = this;
var str = "© " + me.YEAR_ALIVE;
var d = new Date(),
y = d.getFullYear();
if (y > me.YEAR_ALIVE) {
str += " - " + y;
}
jQuery('#mkcopyright').text(str);
}
catch (e) {
console.log("Lỗi: " + e);
}
},
replaceTitle: function () {
var me = this,
titles = jQuery("[name^=chap_name]"),
replaceVal = jQuery("#qpTextTitleReplace").val(),
findVal = jQuery("#qpTextTitleFind").val();
if (findVal.startsWith('/') && findVal.endsWith('/') && findVal.length > 2) {
var re = findVal.substring(1, findVal.length - 1);
findVal = new RegExp(re);
}
if (titles && titles.length > 0) {
for (var i = 0; i < titles.length; i++) {
var t = titles[i];
if (t && t.value) {
t.value = t.value.replace(findVal, replaceVal);
}
}
alert('Đã thay thế xong.');
}
},
ucFirst: function (str) {
if (str && typeof str === 'string' && str.length > 0) {
let fst = str[0].toUpperCase();
str = str.length === 1 ? fst : fst + str.substring(1);
}
return str;
},
init: function () {
try {
var me = this;
var chap_number = parseInt(jQuery('#chap_number').val());
var chap_stt = parseInt(jQuery('.chap_stt1').val());
var chap_serial = parseInt(jQuery('.chap_serial').val());
if (parseInt(jQuery('#chap_stt').val()) > chap_stt) {
chap_stt = parseInt(jQuery('#chap_stt').val());
}
if (parseInt(jQuery('#chap_serial').val()) > chap_serial) {
chap_serial = parseInt(jQuery('#chap_serial').val());
}
me.CHAP_NUMBER = me.CHAP_NUMBER_ORIGINAL = chap_number;
me.CHAP_STT = me.CHAP_STT_ORIGINAL = chap_stt;
me.CHAP_SERIAL = me.CHAP_STT_ORIGINAL = chap_serial;
me.createInjectHTML();
me.addCss();
me.registerEvents();
me.setCopyRight();
me.createListAddChapter(true);
jQuery('#qpNumberOfChapter').attr('max', me.MAX_CHAPTER_POST);
jQuery("#qpContent").focus();
var style = document.createElement('style');
style.innerHTML = `
@keyframes blink-red {
0% { box-shadow: 0 0 5px rgba(255, 0, 0, 0.5); }
50% { box-shadow: 0 0 15px rgba(255, 0, 0, 0.8); }
100% { box-shadow: 0 0 5px rgba(255, 0, 0, 0.5); }
}
textarea[style*='border: 3px solid red'] {
animation: blink-red 2s infinite;
border: 2px solid #ea4335 !important;
border-radius: 8px !important;
background-color: rgba(255, 235, 238, 0.2) !important;
}
#short-chapter-warning {
animation: blink-red 2s infinite;
display: inline-block;
padding: 8px 12px;
border-radius: 6px;
}
.form-control {
border: 1px solid #e0e0e0;
border-radius: 6px;
padding: 10px;
font-size: 14px;
transition: all 0.3s ease;
}
.form-control:focus {
border-color: #4285f4;
box-shadow: 0 0 5px rgba(66, 133, 244, 0.3);
outline: none;
}
.btn {
padding: 8px 16px;
border-radius: 6px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
border: none;
font-size: 14px;
margin: 5px;
}
.btn-success {
background-color: #4285f4;
color: white;
}
.btn-success:hover {
background-color: #3367d6;
}
.btn-danger {
background-color: #ea4335;
color: white;
}
.btn-danger:hover {
background-color: #d33426;
}
.btn-default {
background-color: #f1f3f4;
color: #333333;
}
.btn-default:hover {
background-color: #e8eaed;
}
/* Styles for summary sections */
.summary-section {
padding: 10px;
margin-bottom: 8px;
border-radius: 6px;
background-color: #ffffff;
border-left: 4px solid #4285f4;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.summary-section.warning {
border-left-color: #fbbc05;
background-color: #fffde7;
}
.summary-section.error {
border-left-color: #ea4335;
background-color: #fef2f2;
}
.summary-label {
font-weight: 600;
color: #202124;
display: inline-block;
min-width: 140px;
}
.summary-value {
color: #3c4043;
font-weight: 500;
}
.summary-details {
margin: 5px 0 5px 15px;
padding: 5px 0 5px 10px;
border-left: 2px solid #e0e0e0;
}
.detail-item {
padding: 5px 0;
color: #5f6368;
font-size: 13px;
}
`;
document.head.appendChild(style);
}
catch (e) {
console.log("Lỗi: " + e);
}
},
copyToClipboard: function (text) {
var textarea = document.createElement('textarea');
textarea.value = text;
textarea.setAttribute('readonly', '');
textarea.style.position = 'absolute';
textarea.style.left = '-9999px';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
},
fillEmptyForms: function (titles, contents, advs, advContent, st) {
var me = this;
try {
var maxIterations = 3;
var iteration = 0;
var hasEmptyForms = true;
while (hasEmptyForms && iteration < maxIterations) {
hasEmptyForms = false;
for (var i = 0; i < titles.length; i++) {
var currentTitle = titles[i];
var currentContent = contents[i];
if (currentTitle && (!currentTitle.value || (currentContent && !currentContent.value.trim().replace(headerSign, '').replace(footerSign, '').trim()))) {
hasEmptyForms = true;
var foundNextValid = false;
for (var j = i + 1; j < titles.length; j++) {
var nextTitle = titles[j];
var nextContent = contents[j];
if (nextTitle && nextTitle.value && nextContent && nextContent.value.trim().replace(headerSign, '').replace(footerSign, '').trim()) {
currentTitle.value = nextTitle.value;
currentContent.value = nextContent.value;
if (advs && advs[i]) {
advs[i].value = advs[j] ? advs[j].value : advContent;
}
nextTitle.value = "";
nextContent.value = "";
if (advs && advs[j]) {
advs[j].value = "";
}
foundNextValid = true;
break;
}
}
}
}
iteration++;
}
var emptyFormCount = 0;
for (var i = 0; i < titles.length; i++) {
var currentTitle = titles[i];
var currentContent = contents[i];
if (currentTitle && (!currentTitle.value || (currentContent && !currentContent.value.trim().replace(headerSign, '').replace(footerSign, '').trim()))) {
emptyFormCount++;
}
}
if (emptyFormCount > 0) {
jQuery("#qpn").html(jQuery("#qpn").html() + "<br><b style='color:red'>Cảnh báo: Vẫn còn " + emptyFormCount + " chương trống.</b>");
jQuery('#qpButtonRemoveEmpty').show();
} else {
jQuery('#qpButtonRemoveEmpty').hide();
}
} catch (e) {
console.log("Lỗi khi đẩy chương lên form trống: " + e);
}
},
splitChapters: function () {
var me = this;
try {
window.shortChapterNotified = false;
var warningEl = document.getElementById('short-chapter-warning');
if (warningEl) {
warningEl.style.display = 'none';
}
var content = jQuery("#qpContent").val(),
st = jQuery('#qpSplitValueReplace').val().trim(),
advContent = jQuery("#qpAdv").val();
var lines = content.split('\n');
var chapters = [];
var currentChapter = [];
var regex = /^\s+[Cc]hương\s*\d+:/;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line.match(regex)) {
if (currentChapter.length > 0) {
chapters.push(currentChapter.join('\n'));
currentChapter = [];
}
currentChapter.push(line);
} else {
currentChapter.push(line);
}
}
if (currentChapter.length > 0) {
chapters.push(currentChapter.join('\n'));
}
chapters = chapters.filter(function (chapter) {
var lines = chapter.split('\n');
return lines.some(function (line, index) {
return index > 0 && line.trim().length > 0;
});
});
var i = 0;
while (i < chapters.length) {
if (chapters[i].length > 19000) {
var largeChapter = chapters[i];
var lines = largeChapter.split('\n');
var chapterTitle = lines.shift();
var contentToSplit = lines.join('\n');
var contentLength = contentToSplit.length;
var numSubChapters = Math.ceil(contentLength / 15000);
var chunkSize = Math.floor(contentLength / numSubChapters);
var subChapters = [];
var startPos = 0;
for (var j = 0; j < numSubChapters; j++) {
var endPos = (j === numSubChapters - 1) ? contentLength : startPos + chunkSize;
if (j < numSubChapters - 1) {
var lookAhead = Math.min(200, contentLength - endPos);
var segment = contentToSplit.substring(endPos, endPos + lookAhead);
var sentenceEnd = segment.search(/[.!?][^.!?]*$/);
if (sentenceEnd !== -1) {
endPos += sentenceEnd + 1;
}
}
var subContent = contentToSplit.substring(startPos, endPos);
var subTitle = chapterTitle.trim() + " (Phần " + (j + 1) + "/" + numSubChapters + ")";
subChapters.push(subTitle + "\n" + subContent);
startPos = endPos;
}
chapters.splice(i, 1, ...subChapters);
i += numSubChapters;
} else {
i++;
}
}
var titles = jQuery("[name^=chap_name]");
var contents = jQuery("[name^=introduce]");
var advs = jQuery("[name^=adv]");
var validChapters = 0;
var processedChapters = 0;
for (var i = 0; i < Math.min(chapters.length, titles.length); i++) {
var chapterLines = chapters[i].split('\n');
var title = chapterLines.shift().trim();
var content = chapterLines.join('\n');
if (content) {
validChapters++;
if (title.includes(':')) {
title = title.split(':').slice(1).join(':').trim();
}
title = me.ucFirst(title);
if (title.toLowerCase().startsWith(st.toLowerCase())) {
titles[i].value = title;
} else {
titles[i].value = st + " " + title;
}
contents[i].value = headerSign + "\r\n" + content + "\r\n" + footerSign;
advs[i].value = advContent;
var contentWithoutEmpty = content.split('\n')
.filter(line => line.trim().length > 0)
.join('\n');
var charCount = contentWithoutEmpty.length;
if (charCount < 3000) {
contents[i].style.border = '3px solid red';
contents[i].style.borderRadius = '5px';
contents[i].style.backgroundColor = 'rgba(255, 0, 0, 0.1)';
if (!window.shortChapterNotified) {
window.shortChapterNotified = true;
var numbershortChapters = document.querySelectorAll("textarea[style*='border: 3px solid red']").length;
var warningEl = document.getElementById('short-chapter-warning');
if (warningEl) {
warningEl.textContent = '⚠️ Có chương dưới 3000 ký tự. ⚠️';
warningEl.style.display = 'block';
}
setTimeout(function () {
alert('Cảnh báo: Phát hiện chương có chương dưới 3000 ký tự.');
}, 500);
}
}
processedChapters++;
}
}
var totalProcessedChapters = chapters.length;
var splitChaptersCount = 0;
// Khai báo các biến thiếu
var largeChapterCount = 0;
var totalParts = 0;
var splitChapterGroups = [];
var duplicateTitles = [];
var shortChapters = [];
// Đếm số chương dài đã được chia
for (var i = 0; i < chapters.length; i++) {
var firstLine = chapters[i].split('\n')[0];
if (firstLine && firstLine.includes(" (Phần ")) {
splitChaptersCount++;
// Phân tích thông tin phần
var parts = firstLine.match(/\(Phần (\d+)\/(\d+)\)/);
if (parts && parts[2]) {
var totalPartsInChapter = parseInt(parts[2]);
if (parts[1] === "1") { // Chỉ đếm khi là phần đầu tiên
largeChapterCount++;
totalParts += totalPartsInChapter;
// Lưu thông tin nhóm chương đã chia
var chapterName = firstLine.replace(/\s*\(Phần \d+\/\d+\)/, "");
splitChapterGroups.push({
name: chapterName,
totalParts: totalPartsInChapter
});
}
}
}
}
// Kiểm tra chương ngắn
for (var i = 0; i < Math.min(chapters.length, titles.length); i++) {
var chapterLines = chapters[i].split('\n');
var title = chapterLines.shift().trim();
var content = chapterLines.join('\n');
if (content) {
var contentWithoutEmpty = content.split('\n')
.filter(line => line.trim().length > 0)
.join('\n');
var charCount = contentWithoutEmpty.length;
if (charCount < 3000) {
shortChapters.push(title);
}
}
}
// Kiểm tra chương trùng lặp
var titleMap = {};
for (var i = 0; i < Math.min(chapters.length, titles.length); i++) {
if (titles[i] && titles[i].value) {
var titleText = titles[i].value.toLowerCase();
if (titleMap[titleText]) {
duplicateTitles.push(titles[i].value);
} else {
titleMap[titleText] = true;
}
}
}
var originalChapterCount = totalProcessedChapters - splitChaptersCount + Math.ceil(splitChaptersCount / 2);
var largeChapters = [];
for (var i = 0; i < chapters.length; i++) {
if (chapters[i].length > 19000) {
largeChapters.push(i);
}
}
var newChaptersFromSplit = splitChaptersCount;
// Cải thiện hiển thị thông báo
var mainSummary = "";
mainSummary += "Đã xử lý " + totalProcessedChapters + " chương\n";
mainSummary += "Đã lấy " + Math.min(chapters.length, titles.length) + " chương";
if (chapters.length > titles.length) {
mainSummary += "\nĐã lưu " + (chapters.length - titles.length) + " chương vào Clipboard";
}
// Tạo thông báo chi tiết với định dạng tốt hơn
var detailedSummary = "";
detailedSummary += "<div class='summary-section'><span class='summary-label'>Tổng số chương:</span> <span class='summary-value'>" + totalProcessedChapters + "</span></div>";
detailedSummary += "<div class='summary-section'><span class='summary-label'>Đã xử lý:</span> <span class='summary-value'>" + Math.min(chapters.length, titles.length) + " chương</span></div>";
if (chapters.length > titles.length) {
detailedSummary += "<div class='summary-section'><span class='summary-label'>Đã lưu vào Clipboard:</span> <span class='summary-value'>" + (chapters.length - titles.length) + " chương</span></div>";
}
// Hiển thị thông tin về chương dài
if (largeChapterCount > 0) {
detailedSummary += "<div class='summary-section warning'><span class='summary-label'>Chương dài:</span> <span class='summary-value'>" + largeChapterCount + " chương được chia thành " + totalParts + " phần</span></div>";
if (splitChapterGroups.length > 0) {
detailedSummary += "<div class='summary-details'>";
for (var i = 0; i < splitChapterGroups.length; i++) {
var chapterMatch = splitChapterGroups[i].name.match(/[Cc]hương\s*(\d+):/);
var chapterNum = chapterMatch ? chapterMatch[0] : "Chương";
detailedSummary += "<div class='detail-item'>" + chapterNum + " chia thành " +
splitChapterGroups[i].totalParts + " chương</div>";
}
detailedSummary += "</div>";
}
}
// Hiển thị thông tin về chương trùng lặp
if (duplicateTitles.length > 0) {
detailedSummary += "<div class='summary-section error'><span class='summary-label'>Chương trùng lặp:</span> <span class='summary-value'>" + duplicateTitles.length + " chương</span></div>";
detailedSummary += "<div class='summary-details'>";
for (var i = 0; i < duplicateTitles.length; i++) {
detailedSummary += "<div class='detail-item'>" + duplicateTitles[i] + "</div>";
}
detailedSummary += "</div>";
}
// Hiển thị thông tin về chương ngắn
if (shortChapters.length > 0) {
detailedSummary += "<div class='summary-section error'><span class='summary-label'>Chương ngắn:</span> <span class='summary-value'>" + shortChapters.length + " chương</span></div>";
detailedSummary += "<div class='summary-details'>";
for (var i = 0; i < shortChapters.length; i++) {
detailedSummary += "<div class='detail-item'>" + shortChapters[i] + "</div>";
}
detailedSummary += "</div>";
}
if (chapters.length > titles.length) {
var remainingContent = chapters.slice(titles.length).join("\n\n");
me.copyToClipboard(remainingContent);
}
jQuery("#qpContent").val(mainSummary);
jQuery("#qpn").html(detailedSummary);
jQuery("#qpButtonSubmit").removeClass("btn-disable").addClass("btn-success");
var emptyChaptersExist = false;
for (var i = 0; i < titles.length; i++) {
var currentTitle = titles[i];
var currentContent = contents[i];
if (currentTitle && (!currentTitle.value || (currentContent && !currentContent.value.trim().replace(headerSign, '').replace(footerSign, '').trim()))) {
emptyChaptersExist = true;
break;
}
}
if (emptyChaptersExist) {
jQuery('#qpButtonRemoveEmpty').show();
} else {
jQuery('#qpButtonRemoveEmpty').hide();
}
} catch (e) {
console.log("Lỗi khi tách chương: " + e);
jQuery("#qpn").html("<div class='summary-section error'><span class='summary-label'>Lỗi:</span> <span class='summary-value'>" + e + "</span></div>").addClass("text-danger");
}
}
};
if (window.location.href.includes('tangthuvien.net/message/successchapter')) {
setTimeout(function () {
var previousUrl = document.referrer;
var storyId = '';
if (previousUrl.includes('/dang-chuong/story/')) {
var matches = previousUrl.match(/\/dang-chuong\/story\/(\d+)/);
if (matches && matches[1]) {
storyId = matches[1];
window.location.href = 'https://tangthuvien.net/dang-chuong/story/' + storyId;
}
}
}, 3000);
}
else if (window.location.href.includes('/story/') && window.location.href.includes('/danh-sach-chuong')) {
setTimeout(function () {
var matches = window.location.href.match(/\/story\/(\d+)/);
if (matches && matches[1]) {
var storyId = matches[1];
window.location.href = 'https://tangthuvien.net/dang-chuong/story/' + storyId;
}
}, 3000);
} else {
dăngnhanhTTV.init();
}