git-svn-id: svn://euphorik.ch/pompage@45 02bbb61a-6d21-0410-aba0-cb053bdfd66a
[pompage.git] / doc / webdeveloper / information.js
diff --git a/doc/webdeveloper/information.js b/doc/webdeveloper/information.js
new file mode 100644 (file)
index 0000000..f653111
--- /dev/null
@@ -0,0 +1,2273 @@
+// Adds colors from the specified property of the element to the given list
+function webdeveloper_addColor(element, property, colorList)
+{
+    // If the element, property and color list are set
+    if(element && property && colorList)
+    {
+        var computedStyle = element.ownerDocument.defaultView.getComputedStyle(element, null);
+        var color         = computedStyle.getPropertyCSSValue(property);
+
+        // If the color is set and it is a color
+        if(color && color.primitiveType == CSSPrimitiveValue.CSS_RGBCOLOR)
+        {
+            color = color.getRGBColorValue();
+
+            colorList.push("#" + webdeveloper_formatColor(color.red.getFloatValue(CSSPrimitiveValue.CSS_NUMBER)) + webdeveloper_formatColor(color.green.getFloatValue(CSSPrimitiveValue.CSS_NUMBER)) + webdeveloper_formatColor(color.blue.getFloatValue(CSSPrimitiveValue.CSS_NUMBER)));
+        }
+    }
+}
+
+// Displays all abbreviations
+function webdeveloper_displayAbbreviations(element)
+{
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/display_abbreviations.css", "webdeveloper-display-abbreviations");
+    webdeveloper_toggleFeatureTooltipStyles(element, "webdeveloper-display-abbreviations-tooltips", "*:before");
+}
+
+// Displays all access keys
+function webdeveloper_displayAccessKeys(element)
+{
+    var accessKeyElement        = null;
+    var accessKeyElementList    = null;
+    var accessKeyElementsLength = null;
+    var display                 = element.getAttribute("checked");
+    var documentList            = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength          = documentList.length;
+    var pageDocument            = null;
+    var spanElement             = null;
+    var text                    = null;
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        pageDocument = documentList[i];
+
+        // Need to do this to stop the feature running twice
+        webdeveloper_removeAllElementsByXPath(pageDocument, "//span[@class='webdeveloper-display-access-keys']");
+
+        // If displaying
+        if(display)
+        {
+            accessKeyElementList    = webdeveloper_evaluateXPath(pageDocument, "//*[@accesskey]");
+            accessKeyElementsLength = accessKeyElementList.length;
+
+            // Loop through all the access key elements
+            for(var j = 0; j < accessKeyElementsLength; j++)
+            {
+                accessKeyElement = accessKeyElementList[j];
+                spanElement      = pageDocument.createElement("span");
+                text             = "Accesskey=" + accessKeyElement.getAttribute("accesskey");
+
+                spanElement.setAttribute("class", "webdeveloper-display-access-keys");
+                spanElement.setAttribute("title", text);
+                spanElement.appendChild(pageDocument.createTextNode(text));
+                accessKeyElement.parentNode.insertBefore(spanElement, accessKeyElement);
+            }
+        }
+    }
+
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/imports/tooltips.css", "webdeveloper-display-access-keys");
+    webdeveloper_toggleFeatureTooltipStyles(element, "webdeveloper-display-access-keys-tooltips", "span.webdeveloper-display-access-keys");
+}
+
+// Displays all anchors
+function webdeveloper_displayAnchors(element)
+{
+    var anchorElement        = null;
+    var anchorElementList    = null;
+    var anchorElementsLength = null;
+    var anchorText           = null;
+    var display              = element.getAttribute("checked");
+    var documentList         = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength       = documentList.length;
+    var linkElement          = null;
+    var pageDocument         = null;
+    var spanElement          = null;
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        pageDocument = documentList[i];
+
+        // Need to do this to stop the feature running twice
+        webdeveloper_removeAllElementsByXPath(pageDocument, "//span[@class='webdeveloper-display-anchors']");
+
+        // If displaying
+        if(display)
+        {
+            anchorElementList    = webdeveloper_evaluateXPath(pageDocument, "//*[@id] | //a[@name]");
+            anchorElementsLength = anchorElementList.length;
+
+            // Loop through all the anchor elements
+            for(var j = 0; j < anchorElementsLength; j++)
+            {
+                anchorElement = anchorElementList[j];
+                linkElement   = pageDocument.createElement("a");
+                spanElement   = pageDocument.createElement("span");
+
+                // If the anchor element has an id attribute
+                if(anchorElement.hasAttribute("id"))
+                {
+                    anchorText = "#" + anchorElement.getAttribute("id");
+                }
+                else if(anchorElement.hasAttribute("name"))
+                {
+                    anchorText = "#" + anchorElement.getAttribute("name");
+                }
+
+                linkElement.setAttribute("href", anchorText);
+                linkElement.setAttribute("title", anchorText);
+                linkElement.appendChild(pageDocument.createTextNode(anchorText));
+
+                spanElement.setAttribute("class", "webdeveloper-display-anchors");
+                spanElement.setAttribute("title", anchorText);
+                spanElement.appendChild(linkElement);
+
+
+                // Try to insert the anchor element
+                try
+                {
+                    anchorElement.parentNode.insertBefore(spanElement, anchorElement);
+                }
+                catch(exception)
+                {
+                    // Do nothing
+                }
+            }
+        }
+    }
+
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/display_anchors.css", "webdeveloper-display-anchors");
+    webdeveloper_toggleFeatureTooltipStyles(element, "webdeveloper-display-anchors-tooltips", "span.webdeveloper-display-anchors, span.webdeveloper-display-anchors a");
+}
+
+// Displays all block sizes
+function webdeveloper_displayBlockSize(element)
+{
+    var blockSizeElement        = null;
+    var blockSizeElementList    = null;
+    var blockSizeElementsLength = null;
+    var display                 = element.getAttribute("checked");
+    var documentList            = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength          = documentList.length;
+    var height                  = null;
+    var left                    = null;
+    var pageDocument            = null;
+    var spanElement             = null;
+    var text                    = null;
+    var top                     = null;
+    var width                   = null;
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        pageDocument = documentList[i];
+
+        // Need to do this to stop the feature running twice
+        webdeveloper_removeAllElementsByXPath(pageDocument, "//span[@class='webdeveloper-display-block-size']");
+
+        // If displaying
+        if(display)
+        {
+            blockSizeElementList    = webdeveloper_evaluateXPath(pageDocument, "//div | //form | //table");
+            blockSizeElementsLength = blockSizeElementList.length;
+
+            // Loop through the block size elements
+            for(var j = 0; j < blockSizeElementsLength; j++)
+            {
+                blockSizeElement = blockSizeElementList[j];
+                height           = blockSizeElement.offsetHeight;
+                left             = blockSizeElement.offsetLeft;
+                spanElement      = pageDocument.createElement("span");
+                top              = blockSizeElement.offsetTop;
+                width            = blockSizeElement.offsetWidth;
+                text             = webdeveloper_getElementDescription(blockSizeElement) + " " + width + "x" + height;
+
+                spanElement.style.left     = left + "px";
+                spanElement.style.position = "absolute";
+                spanElement.style.top      = top + "px";
+
+                spanElement.setAttribute("class", "webdeveloper-display-block-size");
+                spanElement.setAttribute("title", text);
+                spanElement.appendChild(pageDocument.createTextNode(text));
+
+                webdeveloper_insertAsFirstChild(blockSizeElement, spanElement);
+            }
+        }
+    }
+
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/display_block_size.css", "webdeveloper-display-block-size");
+    webdeveloper_toggleFeatureTooltipStyles(element, "webdeveloper-display-block-size-tooltips", "span.webdeveloper-display-block-size");
+}
+
+// Displays the order of the divs on the page
+function webdeveloper_displayDivOrder(element)
+{
+    var display            = element.getAttribute("checked");
+    var divElement         = null;
+    var divElementList     = null;
+    var divElementsLength  = null;
+    var documentList       = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength     = documentList.length;
+    var pageDocument       = null;
+    var spanElement        = null;
+    var text               = null;
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        pageDocument = documentList[i];
+
+        // Need to do this to stop the feature running twice
+        webdeveloper_removeAllElementsByXPath(pageDocument, "//span[@class='webdeveloper-display-div-order']");
+
+        // If displaying
+        if(display)
+        {
+            divElementList    = pageDocument.getElementsByTagName("div");
+            divElementsLength = divElementList.length;
+
+            // Loop through the div elements
+            for(var j = 0; j < divElementsLength; j++)
+            {
+                divElement  = divElementList[j];
+                spanElement = pageDocument.createElement("span");
+                text        = webdeveloper_getElementDescription(divElement) + " " + (j + 1);
+
+                spanElement.setAttribute("class", "webdeveloper-display-div-order");
+                spanElement.setAttribute("title", text);
+                spanElement.appendChild(pageDocument.createTextNode(text));
+
+                webdeveloper_insertAsFirstChild(divElement, spanElement);
+            }
+        }
+    }
+
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/display_div_order.css", "webdeveloper-display-div-order");
+    webdeveloper_toggleFeatureTooltipStyles(element, "webdeveloper-display-div-order-tooltips", "span.webdeveloper-display-div-order");
+}
+
+// Displays id and class details for the page
+function webdeveloper_displayIdClassDetails(element)
+{
+    var display               = element.getAttribute("checked");
+    var documentList          = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength        = documentList.length;
+    var idClassElement        = null;
+    var idClassElementList    = null;
+    var idClassElementsLength = null;
+    var idClassElementText    = null;
+    var pageDocument          = null;
+    var spanElement           = null;
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        pageDocument = documentList[i];
+
+        // Need to do this to stop the feature running twice
+        webdeveloper_removeAllElementsByXPath(pageDocument, "//span[@class='webdeveloper-display-id-class-details']");
+
+        // If displaying
+        if(display)
+        {
+            idClassElementList    = webdeveloper_evaluateXPath(pageDocument, "//*[@class] | //*[@id]");
+            idClassElementsLength = idClassElementList.length;
+
+            // Loop through all the id class elements
+            for(var j = 0; j < idClassElementsLength; j++)
+            {
+                idClassElement = idClassElementList[j];
+
+                // If the id class element is a Web Developer element
+                if((idClassElement.hasAttribute("class") && idClassElement.getAttribute("class").indexOf("webdeveloper-")) || (idClassElement.hasAttribute("id") && idClassElement.getAttribute("id").indexOf("webdeveloper-")))
+                {
+                    idClassElementText = "";
+                    spanElement        = pageDocument.createElement("span");
+
+                    // If the id class element has an id attribute
+                    if(idClassElement.hasAttribute("id"))
+                    {
+                        idClassElementText += " #" + idClassElement.getAttribute("id");
+                    }
+
+                    // If the id class element has a class attribute
+                    if(idClassElement.hasAttribute("class"))
+                    {
+                        idClassElementText += " ." + idClassElement.getAttribute("class");
+                    }
+
+                    spanElement.setAttribute("class", "webdeveloper-display-id-class-details");
+                    spanElement.setAttribute("title", idClassElementText);
+                    spanElement.appendChild(pageDocument.createTextNode(idClassElementText));
+
+                    // Try to insert the id class element
+                    try
+                    {
+                        idClassElement.parentNode.insertBefore(spanElement, idClassElement);
+                    }
+                    catch(exception)
+                    {
+                        // Do nothing
+                    }
+                }
+            }
+        }
+    }
+
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/imports/tooltips.css", "webdeveloper-display-id-class-details");
+    webdeveloper_toggleFeatureTooltipStyles(element, "webdeveloper-display-id-class-details-tooltips", "span.webdeveloper-display-id-class-details");
+}
+
+// Displays all link details
+function webdeveloper_displayLinkDetails(element)
+{
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/display_link_details.css", "webdeveloper-display-link-details");
+    webdeveloper_toggleFeatureTooltipStyles(element, "webdeveloper-display-link-details-tooltips", "*:before");
+}
+
+// Displays object information
+function webdeveloper_displayObjectInformation(element)
+{
+    var checked              = element.getAttribute("checked");
+    var divElement           = null;
+    var documentList         = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength       = documentList.length;
+    var objectAttributes     = null;
+    var objectElement        = null;
+    var objectElementList    = null;
+    var objectElementsLength = null;
+    var pageDocument         = null;
+    var paramAttributes      = null;
+    var paramElement         = null;
+    var paramElementList     = null;
+    var paramElementsLength  = null;
+    var pElement             = null;
+    var treeWalker           = null;
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        pageDocument = documentList[i];
+
+        // Need to do this to stop the feature running twice
+        webdeveloper_removeAllElementsByXPath(pageDocument, "//div[@class='webdeveloper-display-object-information']");
+
+        // If the element is checked
+        if(checked)
+        {
+            objectElementList    = pageDocument.getElementsByTagName("object");
+            objectElementsLength = objectElementList.length;
+
+            // Loop through all the object elements
+            for(var j = 0; j < objectElementsLength; j++)
+            {
+                divElement          = pageDocument.createElement("div");
+                objectAttributes    = "";
+                objectElement       = objectElementList[j];
+                paramElementList    = objectElement.getElementsByTagName("param");
+                paramElementsLength = paramElementList.length;
+                pElement            = pageDocument.createElement("p");
+
+                // If the object has an width attribute
+                if(objectElement.hasAttribute("width"))
+                {
+                    objectAttributes += ' width="' + objectElement.getAttribute("width") + '"';
+                }
+
+                // If the object has an height attribute
+                if(objectElement.hasAttribute("height"))
+                {
+                    objectAttributes += ' height="' + objectElement.getAttribute("height") + '"';
+                }
+
+                // If the object has an archive attribute
+                if(objectElement.hasAttribute("archive"))
+                {
+                    objectAttributes += ' archive="' + objectElement.getAttribute("archive") + '"';
+                }
+
+                // If the object has an classid attribute
+                if(objectElement.hasAttribute("classid"))
+                {
+                    objectAttributes += ' classid="' + objectElement.getAttribute("classid") + '"';
+                }
+
+                // If the object has an codebase attribute
+                if(objectElement.hasAttribute("codebase"))
+                {
+                    objectAttributes += ' codebase="' + objectElement.getAttribute("codebase") + '"';
+                }
+
+                // If the object has an codetype attribute
+                if(objectElement.hasAttribute("codetype"))
+                {
+                    objectAttributes += ' codetype="' + objectElement.getAttribute("codetype") + '"';
+                }
+
+                // If the object has an data attribute
+                if(objectElement.hasAttribute("data"))
+                {
+                    objectAttributes += ' data="' + objectElement.getAttribute("data") + '"';
+                }
+
+                // If the object has an standby attribute
+                if(objectElement.hasAttribute("standby"))
+                {
+                    objectAttributes += ' standby="' + objectElement.getAttribute("standby") + '"';
+                }
+
+                // If the object has an type attribute
+                if(objectElement.hasAttribute("type"))
+                {
+                    objectAttributes += ' type="' + objectElement.getAttribute("type") + '"';
+                }
+
+                pElement.appendChild(document.createTextNode("<object" + objectAttributes + ">"));
+                divElement.appendChild(pElement);
+
+                // Loop through all the param elements
+                for(var k = 0; k < paramElementsLength; k++)
+                {
+                    paramAttributes = "";
+                    paramElement    = paramElementList[k];
+                    pElement        = pageDocument.createElement("p");
+
+                    // If the param has a name attribute
+                    if(paramElement.hasAttribute("name"))
+                    {
+                        paramAttributes += ' name="' + paramElement.getAttribute("name") + '"';
+                    }
+
+                    // If the param has a value attribute
+                    if(paramElement.hasAttribute("value"))
+                    {
+                        paramAttributes += ' value="' + paramElement.getAttribute("value") + '"';
+                    }
+
+                    pElement.appendChild(document.createTextNode("<param" + paramAttributes + " />"));
+                    pElement.setAttribute("class", "param");
+                    divElement.appendChild(pElement);
+                }
+
+                pElement = pageDocument.createElement("p");
+                pElement.appendChild(document.createTextNode("</object>"));
+                divElement.appendChild(pElement);
+
+                divElement.setAttribute("class", "webdeveloper-display-object-information");
+                objectElement.parentNode.insertBefore(divElement, objectElement);
+            }
+        }
+    }
+
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/display_object_information.css", "webdeveloper-display-object-information");
+    webdeveloper_toggleFeatureTooltipStyles(element, "webdeveloper-display-object-information-tooltips", "div.webdeveloper-display-object-information");
+}
+
+// Displays the stack level of all elements on the page
+function webdeveloper_displayStackLevels(element)
+{
+    var display            = element.getAttribute("checked");
+    var documentList       = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength     = documentList.length;
+    var pageDocument       = null;
+    var pageElement        = null;
+    var spanElement        = null;
+    var text               = null;
+    var treeWalker         = null;
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        pageDocument = documentList[i];
+
+        // Need to do this to stop the feature running twice
+        webdeveloper_removeAllElementsByXPath(pageDocument, "//span[@class='webdeveloper-display-stack-levels']");
+
+        // If displaying
+        if(display)
+        {
+            treeWalker = pageDocument.createTreeWalker(pageDocument, NodeFilter.SHOW_ELEMENT, webdeveloper_stackLevelFilter, false);
+
+            // While the tree walker has more nodes
+            while((pageElement = treeWalker.nextNode()) != null)
+            {
+                spanElement = pageDocument.createElement("span");
+                text        = webdeveloper_getElementDescription(pageElement) + " Z-index=" + pageElement.ownerDocument.defaultView.getComputedStyle(pageElement, null).getPropertyCSSValue("z-index").cssText;
+
+                spanElement.setAttribute("class", "webdeveloper-display-stack-levels");
+                spanElement.setAttribute("title", text);
+                spanElement.appendChild(pageDocument.createTextNode(text));
+
+                webdeveloper_insertAsFirstChild(pageElement, spanElement);
+            }
+        }
+    }
+
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/imports/tooltips.css", "webdeveloper-display-stack-levels");
+    webdeveloper_toggleFeatureTooltipStyles(element, "webdeveloper-display-stack-levels-tooltips", "span.webdeveloper-display-stack-levels");
+}
+
+// Displays all tab indices
+function webdeveloper_displayTabIndex(element)
+{
+    var checked                = element.getAttribute("checked");
+    var documentList           = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength         = documentList.length;
+    var pageDocument           = null;
+    var spanElement            = null;
+    var tabIndexElement        = null;
+    var tabIndexElementList    = null;
+    var tabIndexElementsLength = null;
+    var text                   = null;
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        pageDocument = documentList[i];
+
+        // Need to do this to stop the feature running twice
+        webdeveloper_removeAllElementsByXPath(pageDocument, "//span[@class='webdeveloper-display-tab-index']");
+
+        // If the element is checked
+        if(checked)
+        {
+            tabIndexElementList    = webdeveloper_evaluateXPath(pageDocument, "//*[@tabindex]");
+            tabIndexElementsLength = tabIndexElementList.length;
+
+            // Loop through all the tab index elements
+            for(var j = 0; j < tabIndexElementsLength; j++)
+            {
+                spanElement     = pageDocument.createElement("span");
+                tabIndexElement = tabIndexElementList[j];
+                text            = "Tabindex=" + tabIndexElement.getAttribute("tabindex");
+
+                spanElement.setAttribute("class", "webdeveloper-display-tab-index");
+                spanElement.setAttribute("title", text);
+                spanElement.appendChild(document.createTextNode(text));
+                tabIndexElement.parentNode.insertBefore(spanElement, tabIndexElement);
+            }
+        }
+    }
+
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/imports/tooltips.css", "webdeveloper-display-tab-index");
+    webdeveloper_toggleFeatureTooltipStyles(element, "webdeveloper-display-tab-index-tooltips", "span.webdeveloper-display-tab-index");
+}
+
+// Displays the depth of all tables
+function webdeveloper_displayTableDepth(element)
+{
+    var checked             = element.getAttribute("checked");
+    var documentList        = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength      = documentList.length;
+    var pageDocument        = null;
+    var spanElement         = null;
+    var stringBundle        = document.getElementById("webdeveloper-string-bundle");
+    var tableElement        = null;
+    var tableElementList    = null;
+    var tableElementsLength = null;
+    var text                = null;
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        pageDocument = documentList[i];
+
+        // Need to do this to stop the feature running twice
+        webdeveloper_removeAllElementsByXPath(pageDocument, "//span[@class='webdeveloper-display-table-depth']");
+
+        // If the element is checked
+        if(checked)
+        {
+            tableElementList    = pageDocument.getElementsByTagName("table");
+            tableElementsLength = tableElementList.length;
+
+            // Loop through all the table elements
+            for(var j = 0; j < tableElementsLength; j++)
+            {
+                spanElement  = pageDocument.createElement("span");
+                tableElement = tableElementList[j];
+                text         = stringBundle.getString("webdeveloper_depth") + "=" + webdeveloper_getTableDepth(tableElement);
+
+                spanElement.setAttribute("class", "webdeveloper-display-table-depth");
+                spanElement.setAttribute("title", text);
+                spanElement.appendChild(document.createTextNode(text));
+                tableElement.parentNode.insertBefore(spanElement, tableElement);
+            }
+        }
+    }
+
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/imports/tooltips.css", "webdeveloper-display-table-depth");
+    webdeveloper_toggleFeatureTooltipStyles(element, "webdeveloper-display-table-depth-tooltips", "span.webdeveloper-display-table-depth");
+}
+
+// Displays table information
+function webdeveloper_displayTableInformation(element)
+{
+    var checked                 = element.getAttribute("checked");
+    var divElement              = null;
+    var documentList            = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength          = documentList.length;
+    var pageDocument            = null;
+    var tableCellElementList    = null;
+    var tableCellElementsLength = null;
+    var tableElement            = null;
+    var tableElementList        = null;
+    var tableElementsLength     = null;
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        pageDocument = documentList[i];
+
+        // Need to do this to stop the feature running twice
+        webdeveloper_removeAllElementsByXPath(pageDocument, "//div[@class='webdeveloper-display-table-information']");
+
+        // If the element is checked
+        if(checked)
+        {
+            tableElementList    = pageDocument.getElementsByTagName("table");
+            tableElementsLength = tableElementList.length;
+
+            // Loop through all the table elements
+            for(var j = 0; j < tableElementsLength; j++)
+            {
+                tableElement            = tableElementList[j];
+                tableCellElementList    = tableElement.getElementsByTagName("th");
+                tableCellElementsLength = tableCellElementList.length;
+
+                // If the table has a summary attribute
+                if(tableElement.hasAttribute("summary"))
+                {
+                    divElement = pageDocument.createElement("div");
+
+                    divElement.setAttribute("class", "webdeveloper-display-table-information");
+                    divElement.appendChild(pageDocument.createTextNode("Summary=" + tableElement.getAttribute("summary")));
+                    tableElement.parentNode.insertBefore(divElement, tableElement);
+                }
+
+                // Loop through the cell elements
+                for(var k = 0; k < tableCellElementsLength; k++)
+                {
+                    webdeveloper_outputTableCellInformation(tableCellElementList[k], pageDocument);
+                }
+
+                tableCellElementList    = tableElement.getElementsByTagName("td");
+                tableCellElementsLength = tableCellElementList.length;
+
+                // Loop through the cell elements
+                for(k = 0; k < tableCellElementsLength; k++)
+                {
+                    webdeveloper_outputTableCellInformation(tableCellElementList[k], pageDocument);
+                }
+            }
+        }
+    }
+
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/display_table_information.css", "webdeveloper-display-table-information");
+    webdeveloper_toggleFeatureTooltipStyles(element, "webdeveloper-display-table-information-tooltips", "div.webdeveloper-display-table-information");
+}
+
+// Displays all title attributes
+function webdeveloper_displayTitleAttributes(element)
+{
+    var checked                      = element.getAttribute("checked");
+    var documentList                 = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength               = documentList.length;
+    var pageDocument                 = null;
+    var spanElement                  = null;
+    var text                         = null;
+    var titleAttributeElement        = null;
+    var titleAttributeElementList    = null;
+    var titleAttributeElementsLength = null;
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        pageDocument = documentList[i];
+
+        // Need to do this to stop the feature running twice
+        webdeveloper_removeAllElementsByXPath(pageDocument, "//span[@class='webdeveloper-display-title-attributes']");
+
+        // If the element is checked
+        if(checked)
+        {
+            titleAttributeElementList    = webdeveloper_evaluateXPath(pageDocument, "//*[@title]");
+            titleAttributeElementsLength = titleAttributeElementList.length;
+
+            // Loop through all the title attribute elements
+            for(var j = 0; j < titleAttributeElementsLength; j++)
+            {
+                spanElement           = pageDocument.createElement("span");
+                titleAttributeElement = titleAttributeElementList[j];
+                text                  = "Title=" + titleAttributeElement.getAttribute("title");
+
+                spanElement.setAttribute("class", "webdeveloper-display-title-attributes");
+                spanElement.setAttribute("title", text);
+                spanElement.appendChild(pageDocument.createTextNode(text));
+                titleAttributeElement.parentNode.insertBefore(spanElement, titleAttributeElement);
+            }
+        }
+    }
+
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/imports/tooltips.css", "webdeveloper-display-title-attributes");
+    webdeveloper_toggleFeatureTooltipStyles(element, "webdeveloper-display-title-attributes-tooltips", "span.webdeveloper-display-title-attributes");
+}
+
+// Displays the topographic information for all elements
+function webdeveloper_displayTopographicInformation(element)
+{
+    webdeveloper_toggleStyleSheet(element, "chrome://webdeveloper/content/stylesheets/display_topographic_information.css", "webdeveloper-display-topographic-information");
+}
+
+// Formats a CSS color
+function webdeveloper_formatColor(color)
+{
+    var formattedColor = color.toString(16);
+
+    // If the formatted color is less than 2 characters long
+    if(formattedColor.length < 2)
+    {
+        return "0" + formattedColor;
+    }
+    else
+    {
+        return formattedColor;
+    }
+}
+
+// Returns the depth of the table
+function webdeveloper_getTableDepth(table)
+{
+    var depth = 1;
+
+    // If the table is set
+    if(table)
+    {
+        var ancestorList   = webdeveloper_getElementAncestors(table);
+        var ancestorLength = ancestorList.length;
+        var tagName        = null;
+
+        // Loop through the ancestors
+        for(var i = 0; i < ancestorLength; i++)
+        {
+            tagName = ancestorList[i].tagName;
+
+            // If the tag name is set and equals table
+            if(tagName && tagName.toLowerCase() == "table")
+            {
+                depth++;
+            }
+        }
+    }
+
+    return depth;
+}
+
+// Returns the text from a table heading
+function webdeveloper_getTableHeadingText(headingNode, headingText)
+{
+    // If the heading node is set
+    if(headingNode)
+    {
+        var childNode       = null;
+        var childNodeList   = headingNode.childNodes;
+        var childNodeLength = childNodeList.length;
+        var childNodeType   = null;
+
+        // Loop through the child nodes
+        for(var i = 0; i < childNodeLength; i++)
+        {
+            childNode     = childNodeList[i];
+            childNodeType = childNode.nodeType;
+
+            // If the child node type is an element and it does not have a webdeveloper-table-information class
+            if(childNodeType == Node.ELEMENT_NODE && (!childNode.hasAttribute("class") || childNode.getAttribute("class") != "webdeveloper-table-information"))
+            {
+                headingText = webdeveloper_getTableHeadingText(childNode, headingText);
+            }
+            else if(childNodeType == Node.TEXT_NODE)
+            {
+                headingText += childNode.nodeValue + " ";
+            }
+        }
+    }
+
+    return headingText.trim();
+}
+
+// Outputs the information for a table cell
+function webdeveloper_outputTableCellInformation(tableCellElement, pageDocument)
+{
+    // If the table cell element is set
+    if(tableCellElement)
+    {
+        var divElement   = null;
+        var pElement     = null;
+        var stringBundle = document.getElementById("webdeveloper-string-bundle");
+
+        // If the table cell has a headers attribute
+        if(tableCellElement.hasAttribute("headers"))
+        {
+            var definitionElement = pageDocument.createElement("dd");
+            var headerList        = tableCellElement.getAttribute("headers").split(" ");
+            var headersLength     = headerList.length;
+
+            // Loop through the headers
+            for(var i = 0; i < headersLength; i++)
+            {
+                pElement = pageDocument.createElement("p");
+                pElement.appendChild(pageDocument.createTextNode(webdeveloper_getTableHeadingText(pageDocument.getElementById(headerList[i]), "")));
+                definitionElement.appendChild(pElement);
+            }
+
+            // If the definition element has child nodes
+            if(definitionElement.childNodes.length > 0)
+            {
+                var listElement = pageDocument.createElement("dl");
+                var termElement = pageDocument.createElement("dt");
+
+                divElement = pageDocument.createElement("div");
+
+                termElement.appendChild(pageDocument.createTextNode(stringBundle.getString("webdeveloper_headers")));
+                listElement.appendChild(termElement);
+                listElement.appendChild(definitionElement);
+
+                divElement.setAttribute("class", "webdeveloper-table-information");
+                divElement.appendChild(listElement);
+                tableCellElement.appendChild(divElement);
+            }
+        }
+
+        divElement = pageDocument.createElement("div");
+
+        // If the table cell has a scope attribute
+        if(tableCellElement.hasAttribute("scope"))
+        {
+            var scope = tableCellElement.getAttribute("scope");
+
+            pElement = pageDocument.createElement("p");
+
+            // If the scope is col
+            if(scope == "col")
+            {
+                pElement.appendChild(pageDocument.createTextNode(stringBundle.getString("webdeveloper_tableInformationHeadingColumn")));
+            }
+            else if(scope == "colgroup")
+            {
+                pElement.appendChild(pageDocument.createTextNode(stringBundle.getString("webdeveloper_tableInformationHeadingColumnGroup")));
+            }
+            else if(scope == "row")
+            {
+                pElement.appendChild(pageDocument.createTextNode(stringBundle.getString("webdeveloper_tableInformationHeadingRow")));
+            }
+            else if(scope == "rowgroup")
+            {
+                pElement.appendChild(pageDocument.createTextNode(stringBundle.getString("webdeveloper_tableInformationHeadingRowGroup")));
+            }
+
+            divElement.appendChild(pElement);
+        }
+
+        // If the table cell has an abbr attribute
+        if(tableCellElement.hasAttribute("abbr"))
+        {
+            pElement = pageDocument.createElement("p");
+            pElement.appendChild(pageDocument.createTextNode(stringBundle.getString("webdeveloper_abbreviation") + "=" + tableCellElement.getAttribute("abbr")));
+            divElement.appendChild(pElement);
+        }
+
+        // If the table cell has an axis attribute
+        if(tableCellElement.hasAttribute("axis"))
+        {
+            pElement = pageDocument.createElement("p");
+            pElement.appendChild(pageDocument.createTextNode(stringBundle.getString("webdeveloper_axis") + "=" + tableCellElement.getAttribute("axis")));
+            divElement.appendChild(pElement);
+        }
+
+        // If the div element has child nodes
+        if(divElement.childNodes.length > 0)
+        {
+            divElement.setAttribute("class", "webdeveloper-table-information");
+            tableCellElement.appendChild(divElement);
+        }
+    }
+}
+
+// Sets the image file sizes for a list of images
+function webdeveloper_setImageFileSizes(imageList)
+{
+    var image           = null;
+    var imageListLength = imageList.length;
+    var newImageList    = new Array();
+
+    // Loop through the images
+    for(var i = 0; i < imageListLength; i++)
+    {
+        image          = imageList[i];
+        image.fileSize = webdeveloper_getFileSize(image.src);
+
+        newImageList.push(image);
+    }
+
+    return newImageList;
+}
+
+// Sets the script file sizes for a list of scripts
+function webdeveloper_setScriptFileSizes(scriptList)
+{
+    var script           = null;
+    var scriptListLength = scriptList.length;
+    var newScriptList    = new Array();
+
+    // Loop through the images
+    for(var i = 0; i < scriptListLength; i++)
+    {
+        script                      = scriptList[i];
+        script.fileSize             = webdeveloper_getFileSize(script.src);
+        script.uncompressedFileSize = webdeveloper_getUncompressedFileSize(script.src);
+
+        newScriptList.push(script);
+    }
+
+    return newScriptList;
+}
+
+// Sets the style sheet file sizes for a list of style sheets
+function webdeveloper_setStyleSheetFileSizes(styleSheetList)
+{
+    var styleSheet           = null;
+    var styleSheetListLength = styleSheetList.length;
+    var newStyleSheetList    = new Array();
+
+    // Loop through the style sheets
+    for(var i = 0; i < styleSheetListLength; i++)
+    {
+        styleSheet                      = styleSheetList[i];
+        styleSheet.fileSize             = webdeveloper_getFileSize(styleSheet.href);
+        styleSheet.uncompressedFileSize = webdeveloper_getUncompressedFileSize(styleSheet.href);
+
+        newStyleSheetList.push(styleSheet);
+    }
+
+    return newStyleSheetList;
+}
+
+// Sorts two anchors
+function webdeveloper_sortAnchors(anchorOne, anchorTwo)
+{
+    // If both anchors are set
+    if(anchorOne && anchorTwo)
+    {
+        var anchorOneLink = null;
+        var anchorTwoLink = null;
+
+        // If the first anchor has an id attribute
+        if(anchorOne.hasAttribute("id"))
+        {
+            anchorOneLink = anchorOne.getAttribute("id");
+        }
+        else if(anchorOne.hasAttribute("name"))
+        {
+            anchorOneLink = anchorOne.getAttribute("name");
+        }
+
+        // If the second anchor has an id attribute
+        if(anchorTwo.hasAttribute("id"))
+        {
+            anchorTwoLink = anchorTwo.getAttribute("id");
+        }
+        else if(anchorTwo.hasAttribute("name"))
+        {
+            anchorTwoLink = anchorTwo.getAttribute("name");
+        }
+
+        // If the anchor links are equal
+        if(anchorOneLink == anchorTwoLink)
+        {
+            return 0;
+        }
+        else if(anchorOneLink < anchorTwoLink)
+        {
+            return -1;
+        }
+    }
+
+    return 1;
+}
+
+// Sorts two documents
+function webdeveloper_sortDocuments(documentOne, documentTwo)
+{
+    // If both documents are set
+    if(documentOne && documentTwo)
+    {
+        var documentOneURL = documentOne.documentURI;
+        var documentTwoURL = documentTwo.documentURI;
+
+        // If the documents are equal
+        if(documentOneURL == documentTwoURL)
+        {
+            return 0;
+        }
+        else if(documentOneURL < documentTwoURL)
+        {
+            return -1;
+        }
+    }
+
+    return 1;
+}
+
+// Sorts two documents by file size
+function webdeveloper_sortDocumentsByFileSize(documentOne, documentTwo)
+{
+    // If both documents and their URLs are set
+    if(documentOne && documentTwo && documentOne.documentURI && documentTwo.documentURI)
+    {
+        var documentOneFileSize = webdeveloper_getFileSize(documentOne.documentURI);
+        var documentTwoFileSize = webdeveloper_getFileSize(documentTwo.documentURI);
+
+        // If the document file sizes are equal
+        if(documentOneFileSize == documentTwoFileSize)
+        {
+            return webdeveloper_sortDocuments(documentOne, documentTwo);
+        }
+        else if(documentOneFileSize > documentTwoFileSize)
+        {
+            return -1;
+        }
+    }
+
+    return 1;
+}
+
+// Sorts two images by file size
+function webdeveloper_sortImagesByFileSize(imageOne, imageTwo)
+{
+    // If both images and their file sizes are set
+    if(imageOne && imageTwo && imageOne.fileSize && imageTwo.fileSize)
+    {
+        var imageOneFileSize = imageOne.fileSize;
+        var imageTwoFileSize = imageTwo.fileSize;
+
+        // If the image file sizes are equal
+        if(imageOneFileSize == imageTwoFileSize)
+        {
+            return webdeveloper_sortImages(imageOne, imageTwo);
+        }
+        else if(imageOneFileSize > imageTwoFileSize)
+        {
+            return -1;
+        }
+    }
+
+    return 1;
+}
+
+// Sorts two links
+function webdeveloper_sortLinks(linkOne, linkTwo)
+{
+    // If both links are set
+    if(linkOne && linkTwo)
+    {
+        var linkOneHref = linkOne.href;
+        var linkTwoHref = linkTwo.href;
+
+        // If the links are equal
+        if(linkOneHref == linkTwoHref)
+        {
+            return 0;
+        }
+        else if(linkOneHref < linkTwoHref)
+        {
+            return -1;
+        }
+    }
+
+    return 1;
+}
+
+// Sorts two scripts
+function webdeveloper_sortScripts(scriptOne, scriptTwo)
+{
+    // If both scripts and src are set
+    if(scriptOne && scriptTwo && scriptOne.src && scriptTwo.src)
+    {
+        var scriptOneSrc = scriptOne.src;
+        var scriptTwoSrc = scriptTwo.src;
+
+        // If the scripts are equal
+        if(scriptOneSrc == scriptTwoSrc)
+        {
+            return 0;
+        }
+        else if(scriptOneSrc < scriptTwoSrc)
+        {
+            return -1;
+        }
+    }
+
+    return 1;
+}
+
+// Sorts two scripts by file size
+function webdeveloper_sortScriptsByFileSize(scriptOne, scriptTwo)
+{
+    // If both scripts and src are set
+    if(scriptOne && scriptTwo && scriptOne.src && scriptTwo.src)
+    {
+        var scriptOneFileSize = webdeveloper_getFileSize(scriptOne.src);
+        var scriptTwoFileSize = webdeveloper_getFileSize(scriptTwo.src);
+
+        // If the script file sizes are equal
+        if(scriptOneFileSize == scriptTwoFileSize)
+        {
+            return webdeveloper_sortScripts(scriptOne, scriptTwo);
+        }
+        else if(scriptOneFileSize > scriptTwoFileSize)
+        {
+            return -1;
+        }
+    }
+
+    return 1;
+}
+
+// Sorts two style sheets
+function webdeveloper_sortStyleSheets(styleSheetOne, styleSheetTwo)
+{
+    // If both style sheets and href are set
+    if(styleSheetOne && styleSheetTwo && styleSheetOne.href && styleSheetTwo.href)
+    {
+        var styleSheetOneSrc = styleSheetOne.href;
+        var styleSheetTwoSrc = styleSheetTwo.href;
+
+        // If the style sheets are equal
+        if(styleSheetOneSrc == styleSheetTwoSrc)
+        {
+            return 0;
+        }
+        else if(styleSheetOneSrc < styleSheetTwoSrc)
+        {
+            return -1;
+        }
+    }
+
+    return 1;
+}
+
+// Sorts two style sheets by file size
+function webdeveloper_sortStyleSheetsByFileSize(styleSheetOne, styleSheetTwo)
+{
+    // If both style sheets and href are set
+    if(styleSheetOne && styleSheetTwo && styleSheetOne.href && styleSheetTwo.href)
+    {
+        var styleSheetOneFileSize = webdeveloper_getFileSize(styleSheetOne.href);
+        var styleSheetTwoFileSize = webdeveloper_getFileSize(styleSheetTwo.href);
+
+        // If the style sheet file sizes are equal
+        if(styleSheetOneFileSize == styleSheetTwoFileSize)
+        {
+            return webdeveloper_sortStyleSheets(styleSheetOne, styleSheetTwo);
+        }
+        else if(styleSheetOneFileSize > styleSheetTwoFileSize)
+        {
+            return -1;
+        }
+    }
+
+    return 1;
+}
+
+// Filter for stack level tree walker
+function webdeveloper_stackLevelFilter(node)
+{
+    // If the node has a class attribute and it starts with webdeveloper
+    if(node && (!node.hasAttribute("class") || node.getAttribute("class").indexOf("webdeveloper-") != 0))
+    {
+        var zIndex = node.ownerDocument.defaultView.getComputedStyle(node, null).getPropertyCSSValue("z-index").cssText;
+
+        // If the node has a z-index and it is not set to auto
+        if(zIndex && zIndex != "auto")
+        {
+            return NodeFilter.FILTER_ACCEPT;
+        }
+    }
+
+    return NodeFilter.FILTER_SKIP;
+}
+
+// Tidies a list of anchors by removing duplicates and sorting
+function webdeveloper_tidyAnchors(anchorList)
+{
+    var anchor              = null;
+    var anchorLink          = null;
+    var anchorListLength    = anchorList.length;
+    var newAnchorList       = new Array();
+    var newAnchorListLength = null;
+    var nextAnchor          = null;
+    var nextAnchorLink      = null;
+    var tidiedAnchorList    = new Array();
+
+    // Loop through the anchors
+    for(var i = 0; i < anchorListLength; i++)
+    {
+        newAnchorList.push(anchorList[i]);
+    }
+
+    newAnchorList.sort(webdeveloper_sortAnchors);
+
+    newAnchorListLength = newAnchorList.length;
+
+    // Loop through the anchors
+    for(i = 0; i < newAnchorListLength; i++)
+    {
+        anchor = newAnchorList[i];
+
+        // If the anchor has an id attribute
+        if(anchor.hasAttribute("id"))
+        {
+            anchorLink = anchor.getAttribute("id");
+        }
+        else
+        {
+            anchorLink = anchor.getAttribute("name");
+        }
+
+        // If this is not the last anchor
+        if(i + 1 < newAnchorListLength)
+        {
+            nextAnchor = newAnchorList[i + 1];
+
+            // If the next anchor has an id attribute
+            if(nextAnchor.hasAttribute("id"))
+            {
+                nextAnchorLink = nextAnchor.getAttribute("id");
+            }
+            else
+            {
+                nextAnchorLink = nextAnchor.getAttribute("name");
+            }
+
+            // If the anchor link is the same as the next anchor link
+            if(anchorLink == nextAnchorLink)
+            {
+                continue;
+            }
+        }
+
+        tidiedAnchorList.push(anchor);
+    }
+
+    return tidiedAnchorList;
+}
+
+// Tidies a list of colors by removing duplicates and sorting
+function webdeveloper_tidyColors(colorList)
+{
+    var color              = null;
+    var colorListLength    = colorList.length;
+    var newColorList       = new Array();
+    var newColorListLength = null;
+    var tidiedColorList    = new Array();
+
+    // Loop through the colors
+    for(var i = 0; i < colorListLength; i++)
+    {
+        newColorList.push(colorList[i]);
+    }
+
+    newColorList.sort();
+
+    newColorListLength = newColorList.length;
+
+    // Loop through the colors
+    for(i = 0; i < newColorListLength; i++)
+    {
+        color = newColorList[i];
+
+        // If this is not the last color and the color is the same as the next color
+        if(i + 1 < newColorListLength && color == newColorList[i + 1])
+        {
+            continue;
+        }
+
+        tidiedColorList.push(color);
+    }
+
+    return tidiedColorList;
+}
+
+// Tidies a list of documents by removing duplicates and sorting
+function webdeveloper_tidyDocuments(documentList)
+{
+    var documentListLength    = documentList.length;
+    var documentURL           = null;
+    var newDocumentList       = new Array();
+    var newDocumentListLength = null;
+    var pageDocument          = null;
+    var tidiedDocumentList    = new Array();
+
+    // Loop through the documents
+    for(var i = 0; i < documentListLength; i++)
+    {
+        newDocumentList.push(documentList[i]);
+    }
+
+    newDocumentList.sort(webdeveloper_sortDocuments);
+
+    newDocumentListLength = newDocumentList.length;
+
+    // Loop through the documents
+    for(i = 0; i < newDocumentListLength; i++)
+    {
+        pageDocument = newDocumentList[i];
+
+        // If this is not the last document and the document is the same as the next document
+        if(i + 1 < newDocumentListLength && pageDocument.documentURI == newDocumentList[i + 1].documentURI)
+        {
+            continue;
+        }
+
+        tidiedDocumentList.push(pageDocument);
+    }
+
+    return tidiedDocumentList;
+}
+
+// Tidies a list of links by removing duplicates and sorting
+function webdeveloper_tidyLinks(linkList)
+{
+    var link              = null;
+    var linkListLength    = linkList.length;
+    var newLinkList       = new Array();
+    var newLinkListLength = null;
+    var tidiedLinkList    = new Array();
+
+    // Loop through the links
+    for(var i = 0; i < linkListLength; i++)
+    {
+        link = linkList[i];
+
+        // If this link is set
+        if(link.href)
+        {
+            newLinkList.push(link);
+        }
+    }
+
+    newLinkList.sort(webdeveloper_sortLinks);
+
+    newLinkListLength = newLinkList.length;
+
+    // Loop through the links
+    for(i = 0; i < newLinkListLength; i++)
+    {
+        link = newLinkList[i];
+
+        // If this is not the last link and the link is the same as the next link
+        if(i + 1 < newLinkListLength && link.href == newLinkList[i + 1].href)
+        {
+            continue;
+        }
+
+        tidiedLinkList.push(link);
+    }
+
+    return tidiedLinkList;
+}
+
+// Tidies a list of scripts by removing duplicates and sorting
+function webdeveloper_tidyScripts(scriptList)
+{
+    var script              = null;
+    var scriptListLength    = scriptList.length;
+    var newScriptList       = new Array();
+    var newScriptListLength = null;
+    var tidiedScriptList    = new Array();
+
+    // Loop through the scripts
+    for(var i = 0; i < scriptListLength; i++)
+    {
+        script = scriptList[i];
+
+        // If this script and the src is set
+        if(script && script.src)
+        {
+            newScriptList.push(script);
+        }
+    }
+
+    newScriptList.sort(webdeveloper_sortScripts);
+
+    newScriptListLength = newScriptList.length;
+
+    // Loop through the scripts
+    for(i = 0; i < newScriptListLength; i++)
+    {
+        script = newScriptList[i];
+
+        // If this is not the last script and the script is the same as the next script
+        if(i + 1 < newScriptListLength && script.src == newScriptList[i + 1].src)
+        {
+            continue;
+        }
+
+        tidiedScriptList.push(script);
+    }
+
+    return tidiedScriptList;
+}
+
+// Tidies a list of style sheets by removing duplicates and sorting
+function webdeveloper_tidyStyleSheets(styleSheetList)
+{
+    var styleSheet              = null;
+    var styleSheetListLength    = styleSheetList.length;
+    var newStyleSheetList       = new Array();
+    var newStyleSheetListLength = null;
+    var tidiedStyleSheetList    = new Array();
+
+    // Loop through the style sheets
+    for(var i = 0; i < styleSheetListLength; i++)
+    {
+        styleSheet = styleSheetList[i];
+
+        // If this style sheet and the href is set
+        if(styleSheet && styleSheet.href)
+        {
+            newStyleSheetList.push(styleSheet);
+        }
+    }
+
+    newStyleSheetList.sort(webdeveloper_sortStyleSheets);
+
+    newStyleSheetListLength = newStyleSheetList.length;
+
+    // Loop through the style sheets
+    for(i = 0; i < newStyleSheetListLength; i++)
+    {
+        styleSheet = newStyleSheetList[i];
+
+        // If this is not the last style sheet and the style sheet is the same as the next style sheet
+        if(i + 1 < newStyleSheetListLength && styleSheet.href == newStyleSheetList[i + 1].href)
+        {
+            continue;
+        }
+
+        tidiedStyleSheetList.push(styleSheet);
+    }
+
+    return tidiedStyleSheetList;
+}
+
+// Updates the information menu
+function webdeveloper_updateInformationMenu(suffix)
+{
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-abbreviations-" + suffix), "checked", "webdeveloper-display-abbreviations");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-access-keys-" + suffix), "checked", "webdeveloper-display-access-keys");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-anchors-" + suffix), "checked", "webdeveloper-display-anchors");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-block-size-" + suffix), "checked", "webdeveloper-display-block-size");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-div-order-" + suffix), "checked", "webdeveloper-display-div-order");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-element-information-" + suffix), "checked", "webdeveloper-display-element-information");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-id-class-details-" + suffix), "checked", "webdeveloper-display-id-class-details");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-link-details-" + suffix), "checked", "webdeveloper-display-link-details");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-object-information-" + suffix), "checked", "webdeveloper-display-object-information");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-stack-levels-" + suffix), "checked", "webdeveloper-display-stack-levels");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-tab-index-" + suffix), "checked", "webdeveloper-display-tab-index");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-table-depth-" + suffix), "checked", "webdeveloper-display-table-depth");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-table-information-" + suffix), "checked", "webdeveloper-display-table-information");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-title-attributes-" + suffix), "checked", "webdeveloper-display-title-attributes");
+    webdeveloper_configureElementByAppliedStyle(document.getElementById("webdeveloper-display-topographic-information-" + suffix), "checked", "webdeveloper-display-topographic-information");
+}
+
+// Displays all the anchors for the page
+function webdeveloper_viewAnchorInformation()
+{
+    var anchor            = null;
+    var anchorLength      = null;
+    var anchorLink        = null;
+    var anchorList        = null;
+    var divElement        = null;
+    var documentList      = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength    = documentList.length;
+    var documentURL       = null;
+    var linkElement       = null;
+    var linkHref          = null;
+    var linkLength        = null;
+    var listElement       = null;
+    var listItemElement   = null;
+    var oldTab            = getBrowser().selectedTab;
+    var oldURL            = getBrowser().currentURI.spec;
+    var generatedDocument = webdeveloper_generateDocument("");
+    var bodyElement       = webdeveloper_getDocumentBodyElement(generatedDocument);
+    var headElement       = webdeveloper_getDocumentHeadElement(generatedDocument);
+    var headerElement     = generatedDocument.createElement("h1");
+    var pageDocument      = null;
+    var pElement          = null;
+    var scriptElement     = generatedDocument.createElement("script");
+    var spanElement       = null;
+    var stringBundle      = document.getElementById("webdeveloper-string-bundle");
+    var title             = stringBundle.getFormattedString("webdeveloper_viewAnchorInformationTitle", [oldURL]);
+
+    generatedDocument.title = title;
+
+    webdeveloper_addGeneratedStyles(generatedDocument);
+
+    headerElement.appendChild(generatedDocument.createTextNode(title));
+    bodyElement.appendChild(headerElement);
+
+    webdeveloper_addGeneratedTools(generatedDocument);
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        divElement    = generatedDocument.createElement("div");
+        headerElement = generatedDocument.createElement("h2");
+        linkElement   = generatedDocument.createElement("a");
+        pageDocument  = documentList[i];
+        anchorList    = webdeveloper_evaluateXPath(pageDocument, "//*[@id] | //a[@name]");
+        documentURL   = pageDocument.documentURI;
+        spanElement   = generatedDocument.createElement("span");
+
+        // If the tidy information preference is set
+        if(webdeveloper_getBooleanPreference("webdeveloper.information.tidy", true))
+        {
+            anchorList = webdeveloper_tidyAnchors(anchorList);
+        }
+
+        spanElement.setAttribute("class", "expanded pivot");
+        headerElement.appendChild(spanElement);
+        linkElement.setAttribute("href", documentURL);
+        linkElement.appendChild(generatedDocument.createTextNode(documentURL));
+        headerElement.appendChild(linkElement);
+        bodyElement.appendChild(headerElement);
+
+        anchorLength = anchorList.length;
+
+        // If there are no anchors
+        if(anchorLength == 0)
+        {
+            pElement = generatedDocument.createElement("p");
+
+            pElement.appendChild(generatedDocument.createTextNode(stringBundle.getString("webdeveloper_noAnchors")));
+            divElement.appendChild(pElement);
+        }
+        else
+        {
+            listElement = generatedDocument.createElement("ol");
+
+            // Loop through the links
+            for(var j = 0; j < anchorLength; j++)
+            {
+                anchor = anchorList[j];
+
+                // If the anchor has an id attribute
+                if(anchor.hasAttribute("id"))
+                {
+                    anchorLink = "#" + anchor.getAttribute("id");
+                }
+                else
+                {
+                    anchorLink = "#" + anchor.getAttribute("name");
+                }
+
+                linkElement     = generatedDocument.createElement("a");
+                listItemElement = generatedDocument.createElement("li");
+
+                linkElement.setAttribute("href", documentURL + anchorLink);
+                linkElement.appendChild(generatedDocument.createTextNode(anchorLink));
+                listItemElement.appendChild(linkElement);
+                listElement.appendChild(listItemElement);
+            }
+
+            divElement.appendChild(listElement);
+        }
+
+        divElement.setAttribute("class", "output");
+        bodyElement.appendChild(divElement);
+    }
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/common/xpath.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    scriptElement = generatedDocument.createElement("script");
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/generated/output_pivot.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    // If the open tabs in background preference is set to true
+    if(webdeveloper_getBooleanPreference("webdeveloper.open.tabs.background", true))
+    {
+        getBrowser().selectedTab = oldTab;
+    }
+}
+
+// Displays all the colors on the page
+function webdeveloper_viewColorInformation()
+{
+    var color                 = null;
+    var colorList             = null;
+    var colorsLength          = null;
+    var definitionElement     = null;
+    var definitionListElement = null;
+    var divElement            = null;
+    var documentList          = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength        = documentList.length;
+    var documentURL           = null;
+    var element               = null;
+    var oldTab                = getBrowser().selectedTab;
+    var oldURL                = getBrowser().currentURI.spec;
+    var generatedDocument     = webdeveloper_generateDocument("");
+    var bodyElement           = webdeveloper_getDocumentBodyElement(generatedDocument);
+    var headElement           = webdeveloper_getDocumentHeadElement(generatedDocument);
+    var headerElement         = generatedDocument.createElement("h1");
+    var linkElement           = generatedDocument.createElement("link");
+    var pageDocument          = null;
+    var scriptElement         = generatedDocument.createElement("script");
+    var spanElement           = null;
+    var termElement           = null;
+    var title                 = document.getElementById("webdeveloper-string-bundle").getFormattedString("webdeveloper_viewColorInformationTitle", [oldURL]);
+    var treeWalker            = null;
+
+    generatedDocument.title = title;
+
+    webdeveloper_addGeneratedStyles(generatedDocument);
+
+    linkElement.setAttribute("href", "chrome://webdeveloper/content/stylesheets/generated/view_color_information.css");
+    linkElement.setAttribute("rel", "stylesheet");
+    linkElement.setAttribute("type", "text/css");
+    headElement.appendChild(linkElement);
+
+    headerElement.appendChild(generatedDocument.createTextNode(title));
+    bodyElement.appendChild(headerElement);
+
+    webdeveloper_addGeneratedTools(generatedDocument);
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        colorList     = new Array();
+        divElement    = generatedDocument.createElement("div");
+        headerElement = generatedDocument.createElement("h2");
+        linkElement   = generatedDocument.createElement("a");
+        pageDocument  = documentList[i];
+        documentURL   = pageDocument.documentURI;
+        spanElement   = generatedDocument.createElement("span");
+        treeWalker    = pageDocument.createTreeWalker(webdeveloper_getDocumentBodyElement(pageDocument), NodeFilter.SHOW_ELEMENT, null, false);
+
+        // Loop through the anchor elements
+        while((element = treeWalker.nextNode()) != null)
+        {
+            webdeveloper_addColor(element, "background-color", colorList);
+            webdeveloper_addColor(element, "border-bottom-color", colorList);
+            webdeveloper_addColor(element, "border-left-color", colorList);
+            webdeveloper_addColor(element, "border-right-color", colorList);
+            webdeveloper_addColor(element, "border-top-color", colorList);
+            webdeveloper_addColor(element, "color", colorList);
+        }
+
+        spanElement.setAttribute("class", "expanded pivot");
+        headerElement.appendChild(spanElement);
+        linkElement.setAttribute("href", documentURL);
+        linkElement.appendChild(generatedDocument.createTextNode(documentURL));
+        headerElement.appendChild(linkElement);
+        bodyElement.appendChild(headerElement);
+
+        colorList    = webdeveloper_tidyColors(colorList);
+        colorsLength = colorList.length;
+
+        // Loop through the colors
+        for(var j = 0; j < colorsLength; j++)
+        {
+            color                 = colorList[j];
+            definitionElement     = generatedDocument.createElement("dd");
+            definitionListElement = generatedDocument.createElement("dl");
+            termElement           = generatedDocument.createElement("dt");
+
+            termElement.appendChild(generatedDocument.createTextNode(color));
+            definitionListElement.appendChild(termElement);
+
+            definitionElement.setAttribute("style", "background-color: " + color);
+            definitionListElement.appendChild(definitionElement);
+            divElement.appendChild(definitionListElement);
+        }
+
+        divElement.setAttribute("class", "output");
+        bodyElement.appendChild(divElement);
+    }
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/common/xpath.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    scriptElement = generatedDocument.createElement("script");
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/generated/output_pivot.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    // If the open tabs in background preference is set to true
+    if(webdeveloper_getBooleanPreference("webdeveloper.open.tabs.background", true))
+    {
+        getBrowser().selectedTab = oldTab;
+    }
+}
+
+// Displays an outline of the page
+function webdeveloper_viewDocumentOutline()
+{
+    var divElement           = null;
+    var documentList         = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength       = documentList.length;
+    var documentURL          = null;
+    var headerElementList    = null;
+    var headerElementsLength = null;
+    var headerLevel          = null;
+    var headerTagName        = null;
+    var headerText           = null;
+    var oldTab               = getBrowser().selectedTab;
+    var oldURL               = getBrowser().currentURI.spec;
+    var generatedDocument    = webdeveloper_generateDocument("");
+    var bodyElement          = webdeveloper_getDocumentBodyElement(generatedDocument);
+    var headElement          = webdeveloper_getDocumentHeadElement(generatedDocument);
+    var headerElement        = generatedDocument.createElement("h1");
+    var linkElement          = generatedDocument.createElement("link");
+    var outlineElement       = null;
+    var pageDocument         = null;
+    var previousHeaderLevel  = null;
+    var scriptElement        = generatedDocument.createElement("script");
+    var spanElement          = null;
+    var stringBundle         = document.getElementById("webdeveloper-string-bundle");
+    var title                = stringBundle.getFormattedString("webdeveloper_viewDocumentOutlineTitle", [oldURL]);
+    var treeWalker           = null;
+
+    generatedDocument.title = title;
+
+    webdeveloper_addGeneratedStyles(generatedDocument);
+
+    linkElement.setAttribute("href", "chrome://webdeveloper/content/stylesheets/generated/view_document_outline.css");
+    linkElement.setAttribute("rel", "stylesheet");
+    linkElement.setAttribute("type", "text/css");
+    headElement.appendChild(linkElement);
+
+    headerElement.appendChild(generatedDocument.createTextNode(title));
+    bodyElement.appendChild(headerElement);
+
+    webdeveloper_addGeneratedTools(generatedDocument);
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        divElement           = generatedDocument.createElement("div");
+        headerElement        = generatedDocument.createElement("h2");
+        linkElement          = generatedDocument.createElement("a");
+        pageDocument         = documentList[i];
+        documentURL          = pageDocument.documentURI;
+        headerElementList    = webdeveloper_evaluateXPath(pageDocument, "//h1 | //h2 | //h3 | //h4 | //h5 | //h6");
+        headerElementsLength = headerElementList.length;
+        previousHeaderLevel  = 0;
+        spanElement          = generatedDocument.createElement("span");
+
+        spanElement.setAttribute("class", "expanded pivot");
+        headerElement.appendChild(spanElement);
+        linkElement.setAttribute("href", documentURL);
+        linkElement.appendChild(generatedDocument.createTextNode(documentURL));
+        headerElement.appendChild(linkElement);
+        bodyElement.appendChild(headerElement);
+
+        // Loop through the heading elements
+        for(var j = 0; j < headerElementsLength; j++)
+        {
+            headerElement = headerElementList[j];
+            headerTagName = headerElement.tagName.toLowerCase();
+            headerText    = webdeveloper_getElementText(headerElement).trim();
+            headerLevel   = parseInt(headerTagName.substring(1));
+
+            // Loop through any missing headers
+            for(var k = previousHeaderLevel + 1; k < headerLevel; k++)
+            {
+                outlineElement = generatedDocument.createElement("h" + k);
+
+                outlineElement.setAttribute("class", "webdeveloper-document-outline webdeveloper-document-outline-missing");
+                outlineElement.appendChild(generatedDocument.createTextNode(stringBundle.getString("webdeveloper_viewDocumentOutlineMissingHeading")));
+                divElement.appendChild(outlineElement);
+            }
+
+            // If there is no header text
+            if(!headerText)
+            {
+                headerText = stringBundle.getString("webdeveloper_viewDocumentOutlineEmptyHeading");
+            }
+
+            outlineElement = generatedDocument.createElement(headerTagName);
+
+            outlineElement.setAttribute("class", "webdeveloper-document-outline");
+            outlineElement.appendChild(generatedDocument.createTextNode(headerText));
+            divElement.appendChild(outlineElement);
+
+            previousHeaderLevel = headerLevel;
+        }
+
+        divElement.setAttribute("class", "output");
+        bodyElement.appendChild(divElement);
+    }
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/common/xpath.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    scriptElement = generatedDocument.createElement("script");
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/generated/output_pivot.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    // If the open tabs in background preference is set to true
+    if(webdeveloper_getBooleanPreference("webdeveloper.open.tabs.background", true))
+    {
+        getBrowser().selectedTab = oldTab;
+    }
+}
+
+// View JavaScript
+function webdeveloper_viewJavaScript()
+{
+    var divElement        = null;
+    var documentList      = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength    = documentList.length;
+    var documentURL       = null;
+    var linkElement       = null;
+    var oldTab            = getBrowser().selectedTab;
+    var oldURL            = getBrowser().currentURI.spec;
+    var generatedDocument = webdeveloper_generateDocument("");
+    var bodyElement       = webdeveloper_getDocumentBodyElement(generatedDocument);
+    var headElement       = webdeveloper_getDocumentHeadElement(generatedDocument);
+    var headerElement     = generatedDocument.createElement("h1");
+    var pageDocument      = null;
+    var preElement        = null;
+    var scriptElement     = null;
+    var scriptLength      = null;
+    var scriptList        = new Array();
+    var scriptSource      = null;
+    var spanElement       = null;
+    var stringBundle      = document.getElementById("webdeveloper-string-bundle");
+    var title             = stringBundle.getFormattedString("webdeveloper_viewJavaScriptTitle", [oldURL]);
+
+    generatedDocument.title = title;
+
+    webdeveloper_addGeneratedStyles(generatedDocument);
+
+    headerElement.appendChild(generatedDocument.createTextNode(title));
+    bodyElement.appendChild(headerElement);
+
+    webdeveloper_addGeneratedTools(generatedDocument);
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        headerElement = generatedDocument.createElement("h2");
+        linkElement   = generatedDocument.createElement("a");
+        pageDocument  = documentList[i];
+        documentURL   = pageDocument.documentURI;
+        scriptList    = pageDocument.getElementsByTagName("script");
+        scriptLength  = scriptList.length;
+
+        linkElement.setAttribute("href", pageDocument.documentURI);
+        linkElement.appendChild(generatedDocument.createTextNode(documentURL));
+        headerElement.appendChild(linkElement);
+        bodyElement.appendChild(headerElement);
+
+        // Loop through the scripts
+        for(var j = 0; j < scriptLength; j++)
+        {
+            divElement    = generatedDocument.createElement("div");
+            headerElement = generatedDocument.createElement("h3");
+            preElement    = generatedDocument.createElement("pre");
+            scriptElement = scriptList[j];
+            scriptSource  = scriptElement.src;
+            spanElement   = generatedDocument.createElement("span");
+
+            // If the script is external
+            if(scriptSource)
+            {
+                // If this is a not chrome script
+                if(scriptSource.indexOf("chrome://") != 0)
+                {
+                    linkElement = generatedDocument.createElement("a");
+
+                    spanElement.setAttribute("class", "expanded pivot");
+                    headerElement.appendChild(spanElement);
+                    linkElement.setAttribute("href", scriptSource);
+                    linkElement.appendChild(generatedDocument.createTextNode(scriptSource));
+                    headerElement.appendChild(linkElement);
+                    bodyElement.appendChild(headerElement);
+
+                    preElement.appendChild(generatedDocument.createTextNode(webdeveloper_retrieveSource(scriptSource).replace(new RegExp("\r", "gi"), "\n")));
+                    divElement.setAttribute("class", "output");
+                    divElement.appendChild(preElement);
+                    bodyElement.appendChild(divElement);
+                }
+            }
+            else
+            {
+                spanElement.setAttribute("class", "expanded pivot");
+                headerElement.appendChild(spanElement);
+                headerElement.appendChild(generatedDocument.createTextNode(stringBundle.getFormattedString("webdeveloper_inlineScript", [documentURL])));
+                bodyElement.appendChild(headerElement);
+
+                preElement.appendChild(generatedDocument.createTextNode(scriptElement.innerHTML));
+                divElement.setAttribute("class", "output");
+                divElement.appendChild(preElement);
+                bodyElement.appendChild(divElement);
+            }
+        }
+    }
+
+    scriptElement = generatedDocument.createElement("script");
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/common/xpath.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    scriptElement = generatedDocument.createElement("script");
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/generated/output_pivot.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    // If the open tabs in background preference is set to true
+    if(webdeveloper_getBooleanPreference("webdeveloper.open.tabs.background", true))
+    {
+        getBrowser().selectedTab = oldTab;
+    }
+}
+
+// Displays all the links for the page
+function webdeveloper_viewLinkInformation()
+{
+    var divElement        = null;
+    var documentList      = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength    = documentList.length;
+    var documentURL       = null;
+    var link              = null;
+    var linkElement       = null;
+    var linkHref          = null;
+    var linkLength        = null;
+    var links             = null;
+    var listElement       = null;
+    var listItemElement   = null;
+    var oldTab            = getBrowser().selectedTab;
+    var oldURL            = getBrowser().currentURI.spec;
+    var generatedDocument = webdeveloper_generateDocument("");
+    var bodyElement       = webdeveloper_getDocumentBodyElement(generatedDocument);
+    var headElement       = webdeveloper_getDocumentHeadElement(generatedDocument);
+    var headerElement     = generatedDocument.createElement("h1");
+    var pageDocument      = null;
+    var pElement          = null;
+    var scriptElement     = generatedDocument.createElement("script");
+    var spanElement       = null;
+    var stringBundle      = document.getElementById("webdeveloper-string-bundle");
+    var title             = stringBundle.getFormattedString("webdeveloper_viewLinkInformationTitle", [oldURL]);
+
+    generatedDocument.title = title;
+
+    webdeveloper_addGeneratedStyles(generatedDocument);
+
+    headerElement.appendChild(generatedDocument.createTextNode(title));
+    bodyElement.appendChild(headerElement);
+
+    webdeveloper_addGeneratedTools(generatedDocument);
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        divElement    = generatedDocument.createElement("div");
+        headerElement = generatedDocument.createElement("h2");
+        linkElement   = generatedDocument.createElement("a");
+        pageDocument  = documentList[i];
+        documentURL   = pageDocument.documentURI;
+        links         = pageDocument.links;
+        spanElement   = generatedDocument.createElement("span");
+
+        // If the tidy information preference is set
+        if(webdeveloper_getBooleanPreference("webdeveloper.information.tidy", true))
+        {
+            links = webdeveloper_tidyLinks(links);
+        }
+
+        spanElement.setAttribute("class", "expanded pivot");
+        headerElement.appendChild(spanElement);
+        linkElement.setAttribute("href", documentURL);
+        linkElement.appendChild(generatedDocument.createTextNode(documentURL));
+        headerElement.appendChild(linkElement);
+        bodyElement.appendChild(headerElement);
+
+        linkLength = links.length;
+
+        // If there are no links
+        if(linkLength == 0)
+        {
+            pElement = generatedDocument.createElement("p");
+
+            pElement.appendChild(generatedDocument.createTextNode(stringBundle.getString("webdeveloper_noLinks")));
+            divElement.appendChild(pElement);
+        }
+        else
+        {
+            listElement = generatedDocument.createElement("ol");
+
+            // Loop through the links
+            for(var j = 0; j < linkLength; j++)
+            {
+                link     = links[j];
+                linkHref = link.href;
+
+                // If the link is set
+                if(linkHref)
+                {
+                    linkElement     = generatedDocument.createElement("a");
+                    listItemElement = generatedDocument.createElement("li");
+
+                    linkElement.setAttribute("href", linkHref);
+                    linkElement.appendChild(generatedDocument.createTextNode(linkHref));
+                    listItemElement.appendChild(linkElement);
+                    listElement.appendChild(listItemElement);
+                }
+            }
+
+            divElement.appendChild(listElement);
+        }
+
+        divElement.setAttribute("class", "output");
+        bodyElement.appendChild(divElement);
+    }
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/common/xpath.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    scriptElement = generatedDocument.createElement("script");
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/generated/output_pivot.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    // If the open tabs in background preference is set to true
+    if(webdeveloper_getBooleanPreference("webdeveloper.open.tabs.background", true))
+    {
+        getBrowser().selectedTab = oldTab;
+    }
+}
+
+// Displays all the meta tags for the page
+function webdeveloper_viewMetaTagInformation()
+{
+    var cellDataElement   = null;
+    var cellHeaderElement = null;
+    var divElement        = null;
+    var documentList      = webdeveloper_getDocuments(webdeveloper_getContentWindow());
+    var documentLength    = documentList.length;
+    var documentURL       = null;
+    var linkElement       = null;
+    var metaTag           = null;
+    var metaTags          = null;
+    var metaTagsLength    = null;
+    var oldTab            = getBrowser().selectedTab;
+    var oldURL            = getBrowser().currentURI.spec;
+    var generatedDocument = webdeveloper_generateDocument("");
+    var bodyElement       = webdeveloper_getDocumentBodyElement(generatedDocument);
+    var headElement       = webdeveloper_getDocumentHeadElement(generatedDocument);
+    var headerElement     = generatedDocument.createElement("h1");
+    var pageDocument      = null;
+    var pElement          = null;
+    var scriptElement     = generatedDocument.createElement("script");
+    var spanElement       = null;
+    var stringBundle      = document.getElementById("webdeveloper-string-bundle");
+    var tableElement      = null;
+    var tableRowElement   = null;
+    var title             = stringBundle.getFormattedString("webdeveloper_viewMetaTagInformationTitle", [oldURL]);
+
+    generatedDocument.title = title;
+
+    webdeveloper_addGeneratedStyles(generatedDocument);
+
+    headerElement.appendChild(generatedDocument.createTextNode(title));
+    bodyElement.appendChild(headerElement);
+
+    webdeveloper_addGeneratedTools(generatedDocument);
+
+    // Loop through the documents
+    for(var i = 0; i < documentLength; i++)
+    {
+        divElement     = generatedDocument.createElement("div");
+        headerElement  = generatedDocument.createElement("h2");
+        linkElement    = generatedDocument.createElement("a");
+        pageDocument   = documentList[i];
+        documentURL    = pageDocument.documentURI;
+        metaTags       = pageDocument.getElementsByTagName("meta");
+        metaTagsLength = metaTags.length;
+        spanElement    = generatedDocument.createElement("span");
+
+        spanElement.setAttribute("class", "expanded pivot");
+        headerElement.appendChild(spanElement);
+        linkElement.setAttribute("href", documentURL);
+        linkElement.appendChild(generatedDocument.createTextNode(documentURL));
+        headerElement.appendChild(linkElement);
+        bodyElement.appendChild(headerElement);
+
+        // If there are no meta tags
+        if(metaTagsLength == 0)
+        {
+            pElement = generatedDocument.createElement("p");
+
+            pElement.appendChild(generatedDocument.createTextNode(stringBundle.getString("webdeveloper_noMetaTags")));
+            divElement.appendChild(pElement);
+        }
+        else
+        {
+            tableElement    = generatedDocument.createElement("table");
+            tableRowElement = generatedDocument.createElement("tr");
+
+            //  Name heading
+            cellHeaderElement = generatedDocument.createElement("th");
+
+            cellHeaderElement.appendChild(generatedDocument.createTextNode(stringBundle.getString("webdeveloper_name")));
+            tableRowElement.appendChild(cellHeaderElement);
+
+            //  Content heading
+            cellHeaderElement = generatedDocument.createElement("th");
+
+            cellHeaderElement.appendChild(generatedDocument.createTextNode(stringBundle.getString("webdeveloper_content")));
+            tableRowElement.appendChild(cellHeaderElement);
+            tableElement.appendChild(tableRowElement);
+
+            // Loop through the meta tags
+            for(var j = 0; j < metaTagsLength; j++)
+            {
+                metaTag         = metaTags[j];
+                tableRowElement = generatedDocument.createElement("tr");
+
+                // If this is an even row
+                if(j % 2 != 0)
+                {
+                    tableRowElement.setAttribute("class", "shaded");
+                }
+
+                cellDataElement = generatedDocument.createElement("td");
+
+                // If the meta tag has a name attribute
+                if(metaTag.hasAttribute("name"))
+                {
+                    cellDataElement.appendChild(generatedDocument.createTextNode(metaTag.getAttribute("name")));
+                }
+                else if(metaTag.hasAttribute("http-equiv"))
+                {
+                    cellDataElement.appendChild(generatedDocument.createTextNode(metaTag.getAttribute("http-equiv")));
+                }
+
+                tableRowElement.appendChild(cellDataElement);
+
+                //  Content
+                cellDataElement = generatedDocument.createElement("td");
+
+                cellDataElement.appendChild(generatedDocument.createTextNode(metaTag.getAttribute("content")));
+                tableRowElement.appendChild(cellDataElement);
+                tableElement.appendChild(tableRowElement);
+            }
+
+            tableElement.setAttribute("class", "sortable");
+            divElement.appendChild(tableElement);
+        }
+
+        divElement.setAttribute("class", "output");
+        bodyElement.appendChild(divElement);
+    }
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/common/dom.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    scriptElement = generatedDocument.createElement("script");
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/common/xpath.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    scriptElement = generatedDocument.createElement("script");
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/generated/output_pivot.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    scriptElement = generatedDocument.createElement("script");
+
+    scriptElement.setAttribute("defer", "defer");
+    scriptElement.setAttribute("src", "chrome://webdeveloper/content/generated/table_sort.js");
+    scriptElement.setAttribute("type", "text/javascript");
+    headElement.appendChild(scriptElement);
+
+    // If the open tabs in background preference is set to true
+    if(webdeveloper_getBooleanPreference("webdeveloper.open.tabs.background", true))
+    {
+        getBrowser().selectedTab = oldTab;
+    }
+}
+
+// View page information
+function webdeveloper_viewPageInformation(chromeLocation)
+{
+    window.openDialog(chromeLocation, "webdeveloper-page-information-dialog", "chrome,dialog=no,resizable");
+}
+
+// View the response headers
+function webdeveloper_viewResponseHeaders()
+{
+    var headerElement     = null;
+    var oldTab            = getBrowser().selectedTab;
+    var oldURL            = getBrowser().currentURI.spec;
+    var generatedDocument = webdeveloper_generateDocument("");
+    var bodyElement       = webdeveloper_getDocumentBodyElement(generatedDocument);
+    var preElement        = null;
+    var request           = new XMLHttpRequest();
+    var responseHeaders   = null;
+    var title             = document.getElementById("webdeveloper-string-bundle").getFormattedString("webdeveloper_viewResponseHeadersTitle", [oldURL]);
+
+    request.open("get", oldURL, false);
+    request.send(null);
+
+    responseHeaders         = request.getAllResponseHeaders();
+    generatedDocument.title = title;
+
+    webdeveloper_addGeneratedStyles(generatedDocument);
+
+    headerElement = generatedDocument.createElement("h1");
+    headerElement.appendChild(generatedDocument.createTextNode(title));
+    bodyElement.appendChild(headerElement);
+
+    preElement = generatedDocument.createElement("pre");
+    preElement.appendChild(generatedDocument.createTextNode(responseHeaders + "\n" + request.status + " " + request.statusText));
+    bodyElement.appendChild(preElement);
+
+    // If the open tabs in background preference is set to true
+    if(webdeveloper_getBooleanPreference("webdeveloper.open.tabs.background", true))
+    {
+        getBrowser().selectedTab = oldTab;
+    }
+}