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

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>/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

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

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(/ /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

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(/ /ig, " "); // convert non-breaking spaces to spaces

unspaced_text = unspaced_text.replace(/ /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', '');

});

//