michael@0: michael@0: // An inefficient, but effective bubble sort michael@0: function sort(collection, key) michael@0: { michael@0: var i, j; michael@0: var count = collection.length; michael@0: var parent, child; michael@0: michael@0: for (i = count-1; i >= 0; i--) { michael@0: for (j = 1; j <= i; j++) { michael@0: if (collection[j-1][key] > collection[j][key]) { michael@0: // Move the item both in the local array and michael@0: // in the tree michael@0: child = collection[j]; michael@0: parent = child.parentNode; michael@0: michael@0: collection[j] = collection[j-1]; michael@0: collection[j-1] = child; michael@0: michael@0: parent.removeChild(child); michael@0: parent.insertBefore(child, collection[j]); michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: // Set user properties on the nodes in the collection michael@0: // based on information found in its children. For example, michael@0: // make a property "Author" based on the content of the michael@0: // "Author" element found in the childNode list of the node. michael@0: // This makes later sorting more efficient michael@0: function collectInfo(nodes, propNames) michael@0: { michael@0: var i, j, k; michael@0: var ncount = nodes.length; michael@0: var pcount = propNames.length; michael@0: michael@0: for (i = 0; i < ncount; i++) { michael@0: var node = nodes[i]; michael@0: var childNodes = node.childNodes; michael@0: var ccount = childNodes.length; michael@0: michael@0: for (j = 0; j < ccount; j++) { michael@0: var child = childNodes[j]; michael@0: michael@0: if (child.nodeType == Node.ELEMENT_NODE) { michael@0: var tagName = child.tagName; michael@0: michael@0: for (k = 0; k < pcount; k++) { michael@0: var prop = propNames[k]; michael@0: if (prop == tagName) { michael@0: node[prop] = child.firstChild.data; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: var enabled = true; michael@0: function toggleStyleSheet() michael@0: { michael@0: if (enabled) { michael@0: document.styleSheets[2].disabled = true; michael@0: } michael@0: else { michael@0: document.styleSheets[2].disabled = false; michael@0: } michael@0: michael@0: enabled = !enabled; michael@0: } michael@0: michael@0: // XXX This is a workaround for a bug where michael@0: // changing the disabled state of a stylesheet can't michael@0: // be done in an event handler. For now, we do it michael@0: // in a zero-delay timeout. michael@0: function initiateToggle() michael@0: { michael@0: setTimeout(toggleStyleSheet, 0); michael@0: } michael@0: michael@0: var sortableProps = new Array("Author", "Title", "ISBN"); michael@0: var books = new Array(); michael@0: michael@0: // We uppercase the tagName as a workaround for a bug michael@0: // that loses the original case of the tag. michael@0: var bookset = document.getElementsByTagName("Book"); michael@0: michael@0: // We need to create a "non-live" array to operate on. Since michael@0: // we'll be moving things around in this array, we can't use michael@0: // the read-only, live one returned by getElementsByTagName. michael@0: for (var i=0; i < bookset.length; i++) { michael@0: books[i] = bookset[i]; michael@0: } michael@0: michael@0: collectInfo(books, sortableProps); michael@0: