User:Proteins/quickdiffs.js

This is an old revision of this page, as edited by Proteins (talk | contribs) at 20:40, 3 November 2008 (fix the code for printing the results after the summary). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
//<pre>
//Summarizes the differences between two page versions in pop-up windows
// Perhaps calculate fractional change in document 

function quickDiffs() {
	var alert_string = "";
	var num_alert_strings = 0;
	var alert_string_index = 0;
	var alert_string_list = new Array();

	var body_content;

	var article_tables;
	var temp_article_table;
	var num_article_tables = 0;
	var article_table_index = 0;

	var diff_table;
	var num_diff_tables = 0;

	var diff_table_body;
	var diff_table_bodies;
	var num_diff_table_bodies = 0;

	var temp_table_row;
	var diff_table_rows;
	var table_row_index= 0;
	var num_diff_table_rows = 0;

	var table_row_data;
	var temp_table_datum;
	var table_datum_index = 0;
	var num_table_row_data = 0;
	var temp_table_datum_text = "";
	var temp_table_datum_text_node;

	var diff_old_version_info; //className = "diff-otitle"
	var diff_new_version_info; //className = "diff-ntitle"

	var mw_diff_otitle1 = "";
	var mw_diff_otitle2 = "";
	var mw_diff_otitle3 = "";
	var mw_diff_otitle4 = "";

	var mw_diff_ntitle1 = "";
	var mw_diff_ntitle2 = "";
	var mw_diff_ntitle3 = "";
	var mw_diff_ntitle4 = "";

	var num_diff_context_lines = 0;
	var revisions = "";
	var num_revisions = 0;

	var num_line_numbers = 0;
	var current_old_line_number = 0;
	var current_new_line_number = 0;
	var old_line_numbers = new Array();
	var new_line_numbers = new Array();

	var line_number_flag = 0;
	var num_diff_addedlines = 0;
	var num_diff_deletedlines = 0;
	var num_diff_context_lines = 0;
	var num_diff_undefined_lines = 0;

	var num_additions = 0;
	var num_deletions = 0;
	var num_replacements = 0;
	var span_index = 0;
	var num_potential_spans = 0;

	var temp_added_span;
	var added_span_nodes;
	var num_added_spans = 0;
	var added_span_text = "";
	var temp_added_line = "";
	var prev_added_line = "";
	var temp_added_span_text = "";

	var temp_deleted_span;
	var deleted_span_nodes;
	var num_deleted_spans = 0;
	var deleted_span_text = "";
	var temp_deleted_line = "";
	var prev_deleted_line = "";
	var temp_deleted_span_text = "";

	var num_changed_lines = 0;
	var diff_added_lines = new Array();
	var diff_deleted_lines = new Array();
	var num_changes_in_line = new Array();

	var diff_changes = new Array();
	var diff_change_line_numbers = new Array();


// Check that there is exactly one table on this page with the className "diff"
	body_content = document.getElementById('bodyContent');
	if (!body_content) { 
		alert_string = "ERROR: This article has no bodyContent element.";
		window.alert(alert_string);
		return;
	}

	article_tables = body_content.getElementsByTagName("TABLE");
	if (!article_tables) { 
		alert_string = "ERROR: This article has no TABLE elements.";
		window.alert(alert_string);
		return;
	}
	num_article_tables = article_tables.length;
	if (!num_article_tables) { 
		alert_string = "ERROR: This article has no TABLE elements.";
		window.alert(alert_string);
		return;
	}

	num_diff_tables = 0;
	for (article_table_index=0; article_table_index<num_article_tables; article_table_index++) { 
		temp_article_table = article_tables[article_table_index];
		if (!temp_article_table) { continue; }

		if (temp_article_table.className == "diff") { 
			num_diff_tables++;
			diff_table = temp_article_table;
		}
	} // closes loop searching for the diff table
	if (num_diff_tables == 0) { 
		alert_string = "ERROR: This article has no TABLE elements belonging to the \"diff\" class.";
		window.alert(alert_string);
		return;
	} else if (num_diff_tables != 1) { 
		alert_string = "ERROR: This article has " + num_diff_tables + " TABLE elements belonging to the \"diff\" class.";
		alert_string += "An article should have at most one \"diff\" table.\n";
		window.alert(alert_string);
		return;
	}

// Check that there is exactly one table body
	diff_table_bodies = diff_table.getElementsByTagName("TBODY");
	if (!diff_table_bodies) { 
		alert_string = "ERROR: This article has no TBODY element within its \"diff\" table.";
		window.alert(alert_string);
		return;
	}
	num_diff_table_bodies = diff_table_bodies.length;
	if (!num_diff_table_bodies) { 
		alert_string = "ERROR: This article has no TBODY element within its \"diff\" table.";
		window.alert(alert_string);
		return;
	} else if (num_diff_table_bodies != 1) { 
		alert_string = "ERROR: This article has " + num_diff_table_bodies + " TBODY elements within its \"diff\" table.";
		alert_string += "A \"diff\" table should have at most one TBODY element.\n";
		window.alert(alert_string);
		return;
	}
	diff_table_body = diff_table_bodies[0];
	if (!diff_table_body) { 
		alert_string = "ERROR: This article has a null TBODY element within its \"diff\" table.";
		window.alert(alert_string);
		return;
	}


// Loop over the table rows in the table body 
	diff_table_rows = diff_table_body.getElementsByTagName("TR");
	if (!diff_table_rows) { 
		alert_string = "ERROR: This article has no TR elements within its \"diff\" table body.";
		window.alert(alert_string);
		return;
	}
	num_diff_table_rows = diff_table_rows.length;
	if (!num_diff_table_rows) { 
		alert_string = "ERROR: This article has no TR elements within its \"diff\" table body.";
		window.alert(alert_string);
		return;
	} else if (num_diff_table_rows < 3) { 
		alert_string = "ERROR: This article has " + num_diff_table_rows + " rows (TR elements) within its \"diff\" table body.";
		alert_string += "A \"diff\" table body should have at least three rows.\n";
		window.alert(alert_string);
		return;
	}

// Loop over the rows in the difference table

	num_alert_strings = 0;
	alert_string_list[0] = "NONE";

	num_revisions = 1;
	revisions = "The newer version is separated from the older version by one revision.";

	for (table_row_index=0; table_row_index<num_diff_table_rows; table_row_index++) {
		temp_table_row = diff_table_rows[table_row_index];
		if (!temp_table_row) { continue; }

		table_row_data = temp_table_row.getElementsByTagName("TD");
		if (!table_row_data) { continue; }
		num_table_row_data = table_row_data.length;
		if (!num_table_row_data) { continue; }

		temp_added_line = "";
		temp_deleted_line = "";

		line_number_flag = 0;
		num_diff_addlines = 0;
		num_diff_deletedlines = 0;
		num_diff_context_lines = 0;
		num_diff_undefined_lines = 0;

		for (table_datum_index=0; table_datum_index<num_table_row_data; table_datum_index++) { 
			temp_table_datum = table_row_data[table_datum_index];
			if (!temp_table_datum) { continue; }

			if (temp_table_datum.className == "diff-lineno") {
				temp_table_datum_text_node = temp_table_datum.firstChild;
				if (!temp_table_datum_text_node) { continue; }
				if (temp_table_datum_text_node.nodeType != 3) { continue; }
				temp_table_datum_text = temp_table_datum_text_node.data;
				temp_table_datum_text = temp_table_datum_text.replace(/[^0-9]*/ig, "");
				if (line_number_flag == 0) {
					current_old_line_number = temp_table_datum_text - 2;
					line_number_flag = 1;
				} else if (line_number_flag == 1) {
					current_new_line_number = temp_table_datum_text - 2; 
					line_number_flag = 2;
				} else if (line_number_flag == 2) { 
					// ignore this table_datum as anomalous
					// there should be only two line numbers in any table row
				} else {
					alert_string = "ERROR: Line_number_flag = " + line_number_flag + " in datum " + table_datum_index + " of diff table row " + table_row_index + ".\n";
					window.alert(alert_string);
					return;
				}
			} else if (temp_table_datum.className == "diff-multi") {
				temp_table_datum_text_node = temp_table_datum.firstChild;
				if (!temp_table_datum_text_node) { continue; }
				if (temp_table_datum_text_node.nodeType == 3) {
					temp_table_datum_text = temp_table_datum_text_node.data;
					temp_table_datum_text = temp_table_datum_text.replace(/[^0-9]*/ig, "");
					if (temp_table_datum_text) {
						num_revisions = temp_table_datum_text;
						num_revisions++;
						revisions = "The newer version is separated from the older version by " + num_revisions + " revisions.";
					}
				}
			} else if (temp_table_datum.className == "diff-context") {  
				num_diff_context_lines++;

			} else if (temp_table_datum.className == "diff-addedline") {  
				num_diff_addedlines = 1;
				num_added_spans = 0;
				added_span_text = "";
				temp_added_line = temp_table_datum.innerHTML;
				if (temp_added_line) {
					// replace HTML tags
 					temp_added_line = temp_added_line.replace(/&gt;/ig, ">");
 					temp_added_line = temp_added_line.replace(/&lt;/ig, "<");
					temp_added_line = temp_added_line.replace(/(<([^>]+)>)/ig,"");

					// replace renamed wiki links
					temp_added_line = temp_added_line.replace(/\[\[([^\|\]]+?)\|([^\|]+?)\]\]/ig,"$2");
					// replace renamed HTTP links, such as external links and diffs
					temp_added_line = temp_added_line.replace(/\[http:([^\s]+)\s(.*?)\]/, "$2");

					temp_added_line = temp_added_line.replace(/&amp;/ig, "&");
					temp_added_line = temp_added_line.replace(/&nbsp;/ig, " ");
					temp_added_line = temp_added_line.replace(/&#160;/ig, " ");
					temp_added_line = temp_added_line.replace(/\s+/ig, " ");
				} else { temp_added_line = ""; }
				if (temp_added_line == prev_deleted_line) { num_diff_addedlines = 0; continue; }
				if (temp_added_line.replace(/\s/ig, "").length < 1) { num_diff_addedlines = 0; continue; }
				added_span_nodes = temp_table_datum.getElementsByTagName("SPAN");
				if (!added_span_nodes) { num_added_spans = 0; continue; }
				num_potential_spans = added_span_nodes.length;
				for (span_index=0; span_index<num_potential_spans; span_index++) { 
					temp_added_span = added_span_nodes[span_index];
					if (!temp_added_span) { continue; }
					
					temp_added_span_text = temp_added_span.innerHTML;
					if (!temp_added_span_text) { continue; }
					temp_added_span_text = temp_added_span_text.replace(/(<([^>]+)>)/ig,"");
					if (!temp_added_span_text) { continue; }

					num_added_spans++;
					added_span_text += "\t Addition " + num_added_spans + ": " + temp_added_span_text + "\n";	
				} // closes loop over the added spans
				added_span_text = "The " + num_added_spans + " additions were:\n" + added_span_text;
			} else if (temp_table_datum.className == "diff-deletedline") {  
				num_diff_deletedlines = 1;
				num_deleted_spans = 0;
				deleted_span_text = "";
				temp_deleted_line = temp_table_datum.innerHTML;
				if (temp_deleted_line) {
					// replace HTML tags
 					temp_deleted_line = temp_deleted_line.replace(/&gt;/ig, ">");
 					temp_deleted_line = temp_deleted_line.replace(/&lt;/ig, "<");
					temp_deleted_line = temp_deleted_line.replace(/(<([^>]+)>)/ig,"");

					// replace renamed wiki links
					temp_deleted_line = temp_deleted_line.replace(/\[\[([^\|\]]+?)\|([^\|]+?)\]\]/ig,"$2");
					// replace renamed HTTP links, such as external links and diffs
					temp_deleted_line = temp_deleted_line.replace(/\[http:([^\s]+)\s(.*?)\]/, "$2");

					temp_deleted_line = temp_deleted_line.replace(/&amp;/ig, "&");
					temp_deleted_line = temp_deleted_line.replace(/&nbsp;/ig, " ");
					temp_deleted_line = temp_deleted_line.replace(/&#160;/ig, " ");
					temp_deleted_line = temp_deleted_line.replace(/\s+/ig, " "); 
				} else { temp_deleted_line = ""; }
				if (temp_deleted_line == prev_added_line) { num_diff_addedlines = 0; continue; }
				if (temp_deleted_line.replace(/\s/ig, "").length < 1) { num_diff_deletedlines = 0; continue; }
				deleted_span_nodes = temp_table_datum.getElementsByTagName("SPAN");
				if (!deleted_span_nodes) { num_deleted_spans = 0; continue; }
				num_potential_spans = deleted_span_nodes.length;
				for (span_index=0; span_index<num_potential_spans; span_index++) { 
					temp_deleted_span = deleted_span_nodes[span_index];
					if (!temp_deleted_span) { continue; }
					
					temp_deleted_span_text = temp_deleted_span.innerHTML;
					if (!temp_deleted_span_text) { continue; }
					temp_deleted_span_text = temp_deleted_span_text.replace(/(<([^>]+)>)/ig,"");
					if (!temp_deleted_span_text) { continue; }

					num_deleted_spans++;
					deleted_span_text += "\t Deletion " + num_deleted_spans + ": " + temp_deleted_span_text + "\n";	
				} // closes loop over the deleted spans
				deleted_span_text = "The " + num_deleted_spans + " deletions were:\n" + deleted_span_text;
			} else if (temp_table_datum.className == "diff-marker") {  
				// do nothing
			} else { 
				num_diff_undefined_lines++;
			} // closes classification of the table datum
		} // closes loop over the data within a table row

		if ((num_diff_addedlines > 0) && (num_diff_deletedlines > 0)) {
			current_new_line_number++;
			current_old_line_number++; 
			num_replacements++;
			alert_string = "Text replacement " + num_replacements + " in line number " + current_new_line_number + " of the newer version (line number " + current_old_line_number + " of the older version)\n\n";
			alert_string += "There were " + num_added_spans + " additions and " + num_deleted_spans + " deletions to arrive at the current version of this line:\n\n";
			alert_string += temp_added_line + "\n\n";

			if ((num_added_spans>15) && (alert_string)) {
				num_alert_strings++;
				alert_string_list[num_alert_strings-1] = alert_string;
//				window.alert(alert_string); 
				alert_string = "";
			}
			if (num_added_spans>0) {
				alert_string += added_span_text;
			}
			if ((num_deleted_spans>15) && (alert_string)) {
				num_alert_strings++;
				alert_string_list[num_alert_strings-1] = alert_string;
//				window.alert(alert_string); 
				alert_string = "";
			}
			if (num_deleted_spans>0) {
				alert_string += deleted_span_text;
			}
			if (alert_string) { 
				num_alert_strings++;
				alert_string_list[num_alert_strings-1] = alert_string;
//				window.alert(alert_string); 
			}
		} else if ((num_diff_addedlines > 0) && (temp_added_line)) { 
			num_additions++;
			current_new_line_number++;
			alert_string = "Text addition " + num_additions + " in line number " + current_new_line_number + " of the newer version (line number " + current_old_line_number + " of the older version)\n\n";
			alert_string += "The following line was added to the article:\n\n";
			alert_string += temp_added_line;
			num_alert_strings++;
			alert_string_list[num_alert_strings-1] = alert_string;
//			window.alert(alert_string);
		} else if ((num_diff_deletedlines > 0) && (temp_deleted_line)) { 
			num_deletions++;
			current_old_line_number++;
			alert_string = "Text deletion " + num_deletions + " in line number " + current_new_line_number + " of the newer version (line number " + current_old_line_number + " of the older version)\n\n";
			alert_string += "The following line was deleted from the article:\n\n";
			alert_string += temp_deleted_line;
			num_alert_strings++;
			alert_string_list[num_alert_strings-1] = alert_string;
//			window.alert(alert_string);
		} else if (num_diff_context_lines == 2) {
			current_new_line_number++;
			current_old_line_number++;
		} // closes classification change as addition, deletion or replacement

		prev_added_line = temp_added_line;
		prev_deleted_line = temp_deleted_line;
	} // closes loop over the table rows

// Report the results
	alert_string = "";
	if (revisions) { 
		alert_string += revisions + "\n\n";
	}
	alert_string += "The newer version differs by " + num_additions + " additions, " + num_deletions + " deletions, and " + num_replacements + " replacements.\n\n";
	alert_string += "These changes will be described on the following " + num_alert_strings + " alert windows.\n";
	window.alert(alert_string);

	for (alert_string_index=0; alert_string_index<num_alert_strings; alert_string_index++) {
		alert_string = alert_atring_list[alert_string_index];
		window.alert(alert_string);
	}
} // closes function quickDiffs()
 
addOnloadHook(function () {
addPortletLink('p-cactions', 'javascript:quickDiffs()', 'qd', 'ca-diff', 'Summarizes the differences between two page versions', 'b', '');
});
 
//</pre>