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>
// Outdent discussions for accessibility
//
// To use this script, add "importScript('User:Proteins/outdent.js');" to your monobook.js subpage 
// under your user page, as you can see at User:Proteins/monobook.js
 
function outdent() {
	var alert_string = "";
	var diagnostic_string = "";
 
	var indent_level = 0;
	var indent_level_string = "";
	var prev_indent_level_string = "";

	var prepended_string = "";

	var DL_elements;
	var temp_DL_element;
	var num_DL_elements = 0;
	var DL_element_index = 0;
	var num_deleted_DL_elements = 0;

	var DT_elements;
	var num_DT_elements = 0;

	var DD_elements;
	var temp_DD_element;
	var num_DD_elements = 0;
	var DD_element_index = 0;
	var DD_element_offset = 0;
	var num_deleted_DD_elements = 0;

	var num_outdented_DD_elements = 0;
	var outdented_DD_element_index = 0;
 
	var top_node;
	var parent_node;
	var top_DD_node;
	var grandparent_node;
 
	var top_DL_node;
	var prev_top_DL_node;

	var temp_DD_text;
	var untagged_text;
	var unspaced_text;
	var byte_count = 0;
	var num_sub_DL_elements = 0;

	var child_nodes;
	var temp_child_node;
	var num_child_nodes = 0;
	var child_node_index = 0;
	var child_node_offset = 0;

	var list_items;
	var temp_list_item;

	var placeholder_node;
	var new_element_node;
	var prev_element_node;

	var indent_text_missing = true;
	var indent_level_list = new Array();
	var top_DL_node_list = new Array();
	var outdented_DD_element_list = new Array();

	var uncreate_discursive_list = true;

	// Colors to help sighted people after the outdenting
	var num_colors = 0;
	var DD_background_colors = ["plum", "yellow", "greenyellow", "lightskyblue", "orange", "lightgrey", "lawngreen", "cyan", "gold", "darkorange"];
 
 
// Initialization
	num_colors = DD_background_colors.length;
 
	top_node = document.getElementById('bodyContent');
	DD_elements = top_node.getElementsByTagName("DD");
	num_DD_elements = DD_elements.length;


// First-pass loop colors the links and adds the level to the beginning
	top_DL_node = null;
	prev_top_DL_node = null;

	prepended_string = "";
	indent_level_string = "";
	prev_indent_level_string = "";

	diagnostic_string = "";
	num_outdented_DD_elements = 0;
	for (DD_element_index=0; DD_element_index<num_DD_elements; DD_element_index++) { 
		temp_DD_element = DD_elements[DD_element_index];
 
		num_sub_DL_elements = temp_DD_element.getElementsByTagName("DL").length;
 
		// Skip empty DD elements
		num_child_nodes = temp_DD_element.childNodes.length;
		if (!num_child_nodes) { continue; } // ignore empty DD elements
 
		temp_DD_text = temp_DD_element.innerHTML;
		unspaced_text = temp_DD_text.replace(/\s/ig, ""); // remove whitespaces
		untagged_text = unspaced_text.replace(/<dl>.*<\/dl>/ig, ""); // remove inner DL's
		untagged_text = untagged_text.replace(/(<([^>]+)>)/ig,""); // remove other HTML tags
 
		byte_count = untagged_text.length; // count characters
		if (byte_count < 1) { continue; }
 
 
		// Find the topmost DL element for this DD node
		indent_level = 0;
		top_DL_node = null;
		top_DD_node = temp_DD_element;
		parent_node = temp_DD_element.parentNode;
 
		while ((parent_node) && (parent_node != top_node)) {
			if (parent_node.nodeType != 1) {
				parent_node = parent_node.parentNode;
				continue; 
			} // examine only Element nodes
 
			if (parent_node.nodeName == "DL") { 
				// Check whether the parent DL element has any DT elements
				num_DT_elements = parent_node.getElementsByTagName("DT").length;
				if (num_DT_elements > 0) { break; } // if so, stop outdenting...
 
				// ...else make this the new indent level
				indent_level++;
				top_DL_node = parent_node;
			} // closes check for a parental DL element
 
			if (parent_node.nodeName == "DD") { top_DD_node = parent_node; }
 
			parent_node = parent_node.parentNode;
		} // closes loop climbing up the document tree
 
		if (top_DL_node != prev_top_DL_node) { 
			prev_indent_level_string = "";
		}
		prev_top_DL_node = top_DL_node;

		if (indent_level > 0) {
			// Build up arrays of the DD elements that need to be outdented
			indent_level_list[num_outdented_DD_elements] = indent_level;
			top_DL_node_list[num_outdented_DD_elements] = top_DL_node;
			outdented_DD_element_list[num_outdented_DD_elements] = temp_DD_element;
			num_outdented_DD_elements++;

			temp_DD_element.style.cssText = "background-color:" + DD_background_colors[indent_level%num_colors];
 
// Prepare indent-level text
			indent_level_string = "(Indent " + indent_level + ") ";

			if (indent_level_string == prev_indent_level_string) {
				prepended_string = indent_level_string; 
//				prepended_string = empty_prepended_string;
			} else {
				prepended_string = indent_level_string;
			}
			prev_indent_level_string = indent_level_string;
 
// Add indent-level text
			child_node_index = 0;
			indent_text_missing = true;
			num_child_nodes = temp_DD_element.childNodes.length;
			while ((indent_text_missing) && (child_node_index < num_child_nodes)) {
				temp_child_node = temp_DD_element.childNodes[child_node_index];

				if (!temp_child_node) { // if the element has no children
					temp_DD_element.appendChild(document.createTextNode(prepended_string));
					indent_text_missing = false;
					break;
				} else {
					if (temp_child_node.nodeType == 1) { // if node is an element
						if ((temp_child_node.nodeName == "UL") || (temp_child_node.nodeName == "OL")) {
							list_items = temp_child_node.getElementsByTagName("LI");
							if (list_items.length > 0) { 
								temp_list_item = list_items[0];
								if (temp_list_item.firstChild) { 
									temp_list_item.insertBefore(document.createTextNode(prepended_string), temp_list_item.firstChild);
									indent_text_missing = false;
									break;
								} else { 
									temp_list_item.appendChild(document.createTextNode(prepended_string));
									indent_text_missing = false;
									break;
								} // closes check that the first item has text
							} // closes check for non-empty list
						} // closes check for ordered and unordered list
						temp_DD_element.insertBefore(document.createTextNode(prepended_string), temp_child_node);
						indent_text_missing = false;
						break; 
					} else if ((temp_child_node.nodeType == 3) && (temp_child_node.data.replace(/\s/, "").length > 0)) { // if non-empty text-node
						if (!temp_child_node.data.match(/^\(Indent\s\d+\)/)) { 
							// add text if script hasn't been run already
							temp_DD_element.insertBefore(document.createTextNode(prepended_string), temp_child_node);
						}
						indent_text_missing = false;
						break; 
					} else { // if empty text-node or another type of node
						child_node_index++;
					}
				} // closes check that temp_child_node exists 
			} // closes while() loop looking where to insert the text 

			temp_DD_element.normalize();

//			diagnostic_string += "DD element " + DD_element_index + " is indented to level " + indent_level + " child_node_index " + child_node_index + ".\n";
//			window.alert(diagnostic_string);

		} // check for outdenting
	} // closes loop over the DD elements of the document
//	diagnostic_string = "First-pass loop: flagged " + num_outdented_DD_elements + " DD elements for outdenting\n";
//	window.alert(diagnostic_string);


//=====================2nd-pass loop to rearrange document structure=====================

// Forward 2nd-pass loop to change document structure
	diagnostic_string = "Beginning second-pass loop...\n\n";

	for (outdented_DD_element_index=0; outdented_DD_element_index<num_outdented_DD_elements; outdented_DD_element_index++) {
		indent_level = indent_level_list[outdented_DD_element_index];
		top_DL_node = top_DL_node_list[outdented_DD_element_index];
		if (!top_DL_node) { 
			alert_string = "Top_DL_node error in outdented_DD_element " + outdented_DD_element_index + "\n";
			window.alert(alert_string);
			continue;
		}
		temp_DD_element = outdented_DD_element_list[outdented_DD_element_index];		
		if (!temp_DD_element) { 
			alert_string = "Temp_DD_element error in outdented_DD_element " + outdented_DD_element_index + "\n";
			window.alert(alert_string);
			continue;
		}

// Check for a valid parent node
 		parent_node = temp_DD_element.parentNode;
		if (!parent_node) { 
			alert_string = "No-parent error in outdented_DD_element " + outdented_DD_element_index + "\n";
			window.alert(alert_string);
			continue; 
		} // should never happen

// If it has no children, don't bother outdenting this node
		child_nodes = temp_DD_element.childNodes;
		if (!child_nodes) { 
			alert_string = "No childNodes array in outdented_DD_element " + outdented_DD_element_index + "\n";
			window.alert(alert_string);
			continue; 
		}
		num_child_nodes = child_nodes.length;
		if (num_child_nodes == 0) { 
			alert_string = "No-children error in outdented_DD_element " + outdented_DD_element_index + "\n";
			window.alert(alert_string);
			continue; 
		}

		diagnostic_string += "DD element " + outdented_DD_element_index + " level " + indent_level + " num_children " + num_child_nodes + "...";
//		window.alert(diagnostic_string);


		placeholder_node = top_DL_node;

		if (!placeholder_node) { 
			alert_string = "No-placeholder error in outdented_DD_element " + outdented_DD_element_index + "\n";
			window.alert(alert_string);
			continue; 
		} // should never happen

		grandparent_node = placeholder_node.parentNode;
		if (!grandparent_node) { 
			alert_string = "No-grandparent error in outdented_DD_element " + outdented_DD_element_index + "\n";
			window.alert(alert_string);
			continue; 
		} // should never happen


		new_element_node = document.createElement("DIV");
		new_element_node.className = "indented-" + indent_level;
		new_element_node.style.cssText = temp_DD_element.style.cssText;

		child_node_offset = 0;
		for (child_node_index=0; child_node_index<num_child_nodes; child_node_index++) {
			temp_child_node = child_nodes[child_node_offset];
			if ((temp_child_node.nodeName == "DL") || (temp_child_node.nodeName == "DT") || (temp_child_node.nodeName == "DD")) {
				child_node_offset++; 
				continue;
			}
			new_element_node.appendChild(temp_child_node);
		}// closes loop over child elements of this DD element
		grandparent_node.insertBefore(new_element_node, placeholder_node);
//		parent_node.removeChild(temp_DD_element);

		diagnostic_string += "done\n";
//		window.alert(diagnostic_string);

//		diagnostic_string += "DD_element " + DD_element_index + " " + indent_level + " " + num_child_nodes + "\n";
	}
//	diagnostic_string = "Labeled, colored and outdented " + num_outdented_DD_elements + " paragraphs of " + num_DD_elements + " possible.";
//	window.alert(diagnostic_string);


//=====================Third-pass loop to uncreate empty discursive lists=====================
	top_node = document.getElementById('bodyContent');
	if (!top_node) { return; } // shouldn't happen, but...

	DD_elements = top_node.getElementsByTagName("DD");
	if (DD_elements) { 
		num_DD_elements = DD_elements.length;

		diagnostic_string = "The article has " + num_DD_elements + " DD elements.\n\n";
//		window.alert(diagnostic_string);

		// Delete the empty DD elements
		num_deleted_DD_elements = 0;
		for (DD_element_index=num_DD_elements; DD_element_index>0; DD_element_index--) { 
			temp_DD_element = DD_elements[DD_element_index-1];
			if (temp_DD_element == null) { continue; } // shouldn't happen, but...

			child_nodes = temp_DD_element.childNodes;
			if (!child_nodes) {
				parent_node = temp_DD_element.parentNode;
				if (parent_node) { 
					parent_node.removeChild(temp_DD_element);  
					num_deleted_DD_elements++; 
					continue;
				}
			}

			uncreate_discursive_discussion = true;
			num_child_nodes = child_nodes.length;
			for (child_node_index=num_child_nodes; child_node_index>0; child_node_index--) {
				temp_child_node = child_nodes[child_node_index-1];
				if (temp_child_node == null) { continue; } // shouldn't happen, but...

				untagged_text = temp_child_node.innerHTML;
				if (!untagged_text) { continue; }
				untagged_text = untagged_text.replace(/(<([^>]+)>)/ig,""); // remove HTML tags
				unspaced_text = untagged_text.replace(/&nbsp;/ig, " ");  // convert non-breaking spaces to spaces
				unspaced_text = unspaced_text.replace(/&#160;/g, " ");  // convert non-breaking spaces to spaces
				unspaced_text = unspaced_text.replace(/\s/g, ""); // remove all whitespace

				num_characters = unspaced_text.length;
				if (num_characters > 0) {
					diagnostic_string += "Saved discursive discussion " + DD_element_index + "; text = " + unspaced_text + "\n";
					uncreate_discursive_discussion = false;
					break;
				}
			} // closes loop over child nodes of DD elements
			if (uncreate_discursive_discussion == true) { 
				parent_node = temp_DD_element.parentNode;
				if (parent_node) { 
					parent_node.removeChild(temp_DD_element); 
					num_deleted_DD_elements++;
				}
			}
		} // closes loop over DD elements
		if (num_deleted_DD_elements != num_DD_elements) { 
//			window.alert(diagnostic_string);
		} else {
			diagnostic_string += "All of them were removed.";
//			window.alert(diagnostic_string);
		}
	} // closes check whether there are any DD elements


	// Delete the empty DL elements
	top_node = document.getElementById('bodyContent');
	if (!top_node) { return; } // shouldn't happen, but...

	DL_elements = top_node.getElementsByTagName("DL");
	if (DL_elements) { 
		num_DL_elements = DL_elements.length;

		diagnostic_string = "The article has " + num_DL_elements + " discursive lists.\n\n";

		num_deleted_DL_elements = 0; 
		for (DL_element_index=num_DL_elements; DL_element_index>0; DL_element_index--) { 
			temp_DL_element = DL_elements[DL_element_index-1];
			if (temp_DL_element == null) { continue; } // shouldn't happen, but...

			temp_DL_element.normalize(); // condense text nodes

			DT_elements = temp_DL_element.getElementsByTagName("DT");
			if ((DT_elements) && (DT_elements.length > 0)) { 
				diagnostic_string += "Skipped discursive list " + DL_element_index + " with " + num_DT_elements + " DT elements\n";  
				continue; 
			}

			child_nodes = temp_DL_element.childNodes;
			if (!child_nodes) {
				parent_node = temp_DL_element.parentNode;
				if (parent_node) { 
					parent_node.removeChild(temp_DL_element);  
					num_deleted_DL_elements++; 
					continue;
				}
			}

			uncreate_discursive_list = true;
			num_child_nodes = child_nodes.length;
			for (child_node_index=0; child_node_index<num_child_nodes; child_node_index++) {
				temp_child_node = child_nodes[child_node_index];
				if (temp_child_node == null) { continue; } // shouldn't happen, but...

				untagged_text = temp_child_node.innerHTML;
				if (!untagged_text) { continue; }
				untagged_text = untagged_text.replace(/(<([^>]+)>)/ig,""); // remove HTML tags
				unspaced_text = untagged_text.replace(/&nbsp;/ig, " ");  // convert non-breaking spaces to spaces
				unspaced_text = unspaced_text.replace(/&#160;/g, " ");  // convert non-breaking spaces to spaces
				unspaced_text = unspaced_text.replace(/\s/g, ""); // remove all whitespace

				num_characters = unspaced_text.length;
				if (num_characters > 0) {
					diagnostic_string += "Saved discursive list " + DL_element_index + "; text = " + unspaced_text + "\n";
					uncreate_discursive_list = false;
					break;
				}
			} // closes loop over the child nodes of this DL element

			if (uncreate_discursive_list == true) { 
				parent_node = temp_DL_element.parentNode;
				if (parent_node) { 
					parent_node.removeChild(temp_DL_element);
					num_deleted_DL_elements++; 
				}
			}
		} // closes loop over document discursive lists
		if (num_deleted_DL_elements != num_DL_elements) { 
//			window.alert(diagnostic_string);
		} else {
			diagnostic_string += "All of them were removed.";
//			window.alert(diagnostic_string);
		}
	} // closes check for DL elements


//Acknowledgment
	alert_string = "Labeled, colored and outdented " + num_outdented_DD_elements + " paragraphs of " + num_DD_elements + " possible.";
	window.alert(alert_string);
 
} // closes outdent() function
 
$(function () {
            mw.util.addPortletLink('p-cactions', 'javascript:outdent()', 'outdent', 'ca-outdent', 'Outdent discussions', 'o', '');
});
 
//</pre>