User:Proteins/outdent.js

// // 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.*<\/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(/ /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]+)>)/ig,""); // remove HTML tags unspaced_text = untagged_text.replace(/ /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', ''); }); //