跳转到内容

User:What7what8/CommentHistoryTool b.js

维基百科,自由的百科全书

注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ 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()+
					'&nbsp;&nbsp;</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);
			}
		}
	});
	});
});