User:What7what8/CommentHistoryTool b.js
外观
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
//TODO:
//若留言經刪後重建,無法搜尋到重建以前的歷史 (https://zh.wikipedia.org/w/index.php?title=Wikipedia:%E4%BA%92%E5%8A%A9%E5%AE%A2%E6%A0%88/%E6%96%B9%E9%92%88&diff=next&oldid=80890074)
//適配對話頁討論存檔,找回原討論
$(function () {
mw.loader.using( 'ext.gadget.HanAssist' ).then( ( require ) => {
const { conv } = require( 'ext.gadget.HanAssist' );
mw.loader.load('https://zh.wikipedia.org/w/load.php?lang='+mw.config.get("wgPageViewLanguage")+'&modules=ext.visualEditor.diffPage.init.styles%7Cmediawiki.diff.styles&only=styles'/*&skin=vector*/,'text/css');
$(".ext-discussiontools-init-replylink-buttons").after(`
<span style="display: none;" class="tool-init-comment-historybutton oo-ui-widget oo-ui-widget-enabled oo-ui-buttonElement oo-ui-buttonElement-frameless oo-ui-iconElement oo-ui-labelElement oo-ui-flaggedElement-progressive oo-ui-buttonWidget" id="ooui-php-42" data-ooui="">
<div class="tool-init-comment-historybutton-tooltip" data-hasrun="false" haspreview="false" oldest_old_id = -1></div>
<a class="oo-ui-buttonElement-button" role="button" tabindex="0" rel="nofollow">
<span class="oo-ui-iconElement-icon oo-ui-icon-clock oo-ui-image-progressive style="background-size: 1.2em;top: -0.1em;"></span>
<span class="oo-ui-labelElement-label">`+conv({hans:'历史',hant:'歷史'})+`</span>
<span class="oo-ui-indicatorElement-indicator oo-ui-indicatorElement-noIndicator oo-ui-image-progressive"></span>
</a>
</span>`);
$(document).ajaxStop(function() {
$(".tool-init-comment-historybutton").css("display","")
});
$(".tool-init-comment-historybutton-tooltip").css({
"display":"none",
"width": "auto",
"background-color": "black",
"color": "#fff",
"border-radius": "6px",
"padding": "5px 0",
"position": "absolute",
"z-index": "1",
"flex-wrap": "wrap",
"justify-content": "center",
"align-items": "center",
"align-content": "center"
});
String.format = function(format) {
var args = Array.prototype.slice.call(arguments, 1);
return format.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
function equal(a,b){
return JSON.stringify(a) === JSON.stringify(b);
}
function updateWorkingProgress(input_tooltip){
if (jQuery.active === 1){
input_tooltip[0].childNodes[0].nodeValue = conv({hans:'搜寻完了', hant:'搜尋完了'});
} else input_tooltip[0].childNodes[0].nodeValue = mw.format(conv({hans:'正在努力搜寻中(查询:$1)', hant:'正在努力搜尋中(查詢:$1)'}), jQuery.active)
}
function findComment(input_xml,input_comment_id) {
//return new RegExp(input_comment_id+'"></span>([\\s\\S]*?)'+input_comment_id).exec(input_html.replaceAll(' class="userlink"','').trim());
//$..[?(@ && @.id=='c-Benevolen-20240301000700-Wongan4614-20240229185600')]
return input_xml.find('[id="'+input_comment_id+'"]').attr("html");
}
function hashCode(s) {
return s.split("").reduce(function(a, b) {
a = ((a << 5) - a) + b.charCodeAt(0);
return a & a;
}, 0);
}
$.fn.addPreview = function() {
console.log("preview gogo"+$(this).find("a").attr("href"))
let url = $(this).find("a").attr("href")
let item = $(this)
item.attr("haspreview","true")
$.get(url, function(html){
console.log("preview going"+item.find("a").attr("href"))
let diff = $('<div/>').html(html).find('.diff');
diff.find(".diff-title").remove();
//diff.css("display","inline-block");
diff.find("td").css("font-size","10px");
diff = diff[0].outerHTML;
item.append('<div class="diff-comment-preview" style="display: none;">'+diff+'</div>');
//console.log(item[0].innerHTML)
item.find(".diff-comment-preview").css({
"overflow":"auto",
"display": "none",
"min-width": "auto",
"width":"14cm",
"height": "auto",
"backgroundColor": '#000',
"position": 'absolute',
"transform": 'translate(-50%, -50%)',
"borderRadius": '5%',
"boxShadow": '0 0 20px rgba(16, 0, 54, 0.2)',
"transition": '0.1s ease-out',
"float": "left",
"z-index": 2
//"flex-wrap": "wrap",
//"justify-content": "center",
//"align-items": "center",
//"align-content": "center"
})
const move = (e) => {
let offset = item.offset();
let show_diff = item[0].querySelector('.diff-comment-preview')
const rect = show_diff.getBoundingClientRect();
if ((e.clientX - 25) < rect.width) {
show_diff.style.left = (e.pageX - offset.left + rect.width/2 + 25) + "px";
} else {
show_diff.style.left = (e.pageX - offset.left - rect.width/2 - 25) + "px";
}
if (e.clientY + rect.height * 0.15 < rect.height/2) {
show_diff.style.top = (e.pageY - offset.top + rect.height/2) + "px";
} else {
show_diff.style.top = (e.pageY - offset.top) + "px";
}
};
//For mouse
item.find(".date-item").on("mousemove", (e) => {
move(e);
});
item.find(".date-item").hover(
function() {
item.find(".diff-comment-preview").css("display", "");
},
function() {
item.find(".diff-comment-preview").css("display", "none");
}
);
updateWorkingProgress(item.parents('div'));
});
}
$.fn.removeDuplicate = function(input_comment) {
let temp_comment = hashCode(input_comment);
$(this).find('*').each(function(){
//console.log("ready remove")
if (typeof $(this).attr("data-old_comment") === 'undefined') {
return;
}
//console.log(temp_comment+"vs"+$(this).attr("data-old_comment"));
//console.log($(this).attr("data-old_comment") === temp_comment)
if ($(this).attr("data-old_comment") === temp_comment){
temp_comment = $(this).attr("data-old_comment");
$(this).css("display","none")
//console.log("removed")
} else {
console.log($(this).attr("data-old_comment") +" vs "+ temp_comment)
temp_comment = $(this).attr("data-old_comment");
if ($(this).attr("haspreview") !== 'true') $(this).addPreview();
}
})
}
$.fn.addToolTipItem = function(input_item,input_diff) {
//console.log(input_item.old_comment)
//try{
let display_item = new DOMParser().parseFromString('<div data-old_id="'+input_item.old_id+'" data-old_comment="'+hashCode(input_item.old_comment)+'"><div class="date-item">'+input_item.timestamp.toISOString()+
' </div><a href="'+input_item.url+'">url</a></div>', 'text/html').body.firstChild;
console.log(display_item);
let children = Array.prototype.slice.call($(this)[0].children);
// Find the one we should insert in front of
let before = children.find(function(element) {
return parseInt(element.getAttribute("data-old_id"),10) < input_item.old_id;
});
$(this)[0].insertBefore(display_item, before);
$(this).removeDuplicate(input_item.comment);
}
//oldest_old_id is oldest page id has target comment
function isOldPageHasntOldComment(oldest_old_id,input_old_id){
return oldest_old_id !== "-1" && parseInt(oldest_old_id,10) > parseInt(input_old_id,10);
}
window.wikipage_history_req = {};
function compareOldComment(input_edit,input_comment,input_comment_id,input_tooltip){
let old_id = input_edit.id;
let timestamp = new Date(input_edit.timestamp);
if (isOldPageHasntOldComment(input_tooltip.attr("oldest_old_id"),old_id)){
console.log("returned!!! out")
return;
}
let req = new mw.Api().get({
"action": "discussiontoolspageinfo",
"format": "xml",
"formatversion": 2,
"uselang": mw.config.get("wgPageViewLanguage"),
"page": mw.config.get("wgPageName"),
"prop": "threaditemshtml",
"excludesignatures": true,
"oldid": old_id
}).done(function(old_page){
updateWorkingProgress(input_tooltip)
if (isOldPageHasntOldComment(input_tooltip.attr("oldest_old_id"),old_id)){
console.log("returned!!! in")
return;
}
let old_page_xml = $($.parseXML(old_page))
let old_comment = findComment(old_page_xml,input_comment_id);
if (old_page_xml.find("error").length){
//console.log("deteted"+old_id)
return;
}
if (old_comment === null){
let start_item = {
"isDiff":false,
"timestamp": timestamp,
"old_id": old_id,
"comment":input_comment,
"old_comment":'',
"url":"https://" + mw.config.get("wgServerName") + "/w/index.php?title=" + encodeURIComponent(mw.config.get("wgPageName")) + "&diff=next&oldid=" + old_id //+ "#" + input_comment_id
};
input_tooltip.addToolTipItem(start_item);
input_tooltip.attr("oldest_old_id",old_id);
console.log(start_item);
for (const [ongoing_req_old_id, ongoing_req] of Object.entries(window.wikipage_history_req[input_comment_id])) {
if (isOldPageHasntOldComment(old_id,ongoing_req_old_id)) {
ongoing_req.abort();
console.log(ongoing_req_old_id+" is aborted!!!")
delete window.wikipage_history_req[input_comment_id][ongoing_req_old_id]
}
}
return;
}
//notice: comment will not change to old_comment
//that mean it can only detect is comment same as now
if (input_comment !== old_comment) {
let item = {
"isDiff": true,
"url" : "https://" + mw.config.get("wgServerName") + "/w/index.php?title=" + encodeURIComponent(mw.config.get("wgPageName")) + "&diff=next&oldid=" + old_id, //+ "#" + input_comment_id
"timestamp": timestamp,
"old_id": old_id,
"comment":input_comment,
"old_comment": old_comment
};
console.log(item);
input_tooltip.addToolTipItem(item);
}
});
if (!window.wikipage_history_req.hasOwnProperty(input_comment_id)){
window.wikipage_history_req[input_comment_id] = {}
}
window.wikipage_history_req[input_comment_id][old_id] = {};
window.wikipage_history_req[input_comment_id][old_id] = req;
}
function search(input_maxSearch, input_comment, input_comment_id, input_tooltip){
updateWorkingProgress(input_tooltip)
if (input_maxSearch >= window.maxSearch){
return;
}
if (window.wikipage_history_list.length >= (input_maxSearch+1)*20){
console.log("using preload");
for (j=input_maxSearch*20;j<(input_maxSearch+1)*20;j++){
if (isOldPageHasntOldComment(input_tooltip.attr("oldest_old_id"),window.wikipage_history_list[j].id)){
return;
}
compareOldComment(window.wikipage_history_list[j],input_comment,input_comment_id,input_tooltip);
}
search(input_maxSearch + 1, input_comment, input_comment_id, input_tooltip);
} else {
$.get(window.wikipage_history_url, function(data){
window.wikipage_history_list = window.wikipage_history_list.concat(data.revisions);
data.revisions.forEach(edit => {
console.log(window.wikipage_history_url);
compareOldComment(edit,input_comment,input_comment_id,input_tooltip);
});
if(data.hasOwnProperty('older')){
console.log(window.wikipage_history_url);
window.wikipage_history_url = data.older;
if (isOldPageHasntOldComment(input_tooltip.attr("oldest_old_id"),data.older.split("older_than=").slice(-1))){
return;
}
search(input_maxSearch + 1, input_comment, input_comment_id, input_tooltip);
} else {
return;
}
});
}
}
$(".tool-init-comment-historybutton").click(function(){
let tooltip = $(this).find(".tool-init-comment-historybutton-tooltip");
if (tooltip.css("display") === "none") {
tooltip.css("display","flex");
}
else {
tooltip.css("display","none");
}
if (tooltip.attr("data-hasrun") === "false"){
try{
tooltip.attr("data-hasrun","true");
let comment_id = $(this).prev(".ext-discussiontools-init-replylink-buttons").attr("data-mw-thread-id");
tooltip.append("正在努力搜尋中")
window.maxSearch = 100;
if (typeof window.wikipage_history_list === 'undefined'){
window.wikipage_history_list = [];
}
if (typeof window.wikipage_history_url === 'undefined'){
window.wikipage_history_url = 'https://' + mw.config.get("wgServerName") + '/w/rest.php/v1/page/' + encodeURIComponent(mw.config.get("wgPageName")) +'/history';
}
new mw.Api().get({
"action": "discussiontoolspageinfo",
"format": "xml",
"formatversion": 2,
"uselang": mw.config.get("wgPageViewLanguage"),
"page": mw.config.get("wgPageName"),
"prop": "threaditemshtml",
"excludesignatures": true
}).done( (xml) => {
let comment = findComment($($.parseXML(xml)),comment_id);
search(0, comment, comment_id, tooltip)
});
} catch (e){
console.log(e);
}
}
});
});
});