//<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(/ /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<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(/ /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', '');
});
//</pre>