User:Mike Dillon/Scripts/defaultsort.js
From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Firefox/Mozilla/Safari: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Internet Explorer: press Ctrl-F5, Opera/Konqueror: press F5.
// Requires: [[User:Mike Dillon/Scripts/toolbox.js]], [[User:Mike Dillon/Scripts/easydom.js]] /* <pre><nowiki> */ function scrollToFit(target) { // Determine the bounds of the target element var top = target.offsetTop; var e = target.offsetParent; while (e != null) { top += e.offsetTop; e = e.offsetParent; } var height = target.offsetHeight; var bottom = top + height; // Determine the visible bounds of the viewable area var viewTop = document.documentElement.scrollTop; var viewHeight = window.innerHeight; var viewBottom = viewTop + viewHeight; // Determine where to scroll to var scrollTop = viewTop; if (top < viewTop || height > viewHeight) { scrollTop = top; } else if (bottom > viewBottom) { scrollTop = viewTop + (bottom - viewBottom); } // Scroll the window window.scroll(0, scrollTop); } function editDefaultSort(textbox, existingDefaults, categories, defaultSortForm) { var text = textbox.value; // Remove any existing defaults for (var i in existingDefaults) { text = text.substring(0, existingDefaults[i][0]) + text.substring(existingDefaults[i][0] + existingDefaults[i][1]); // Shift any categories that come after the removed default back // by the length of the removed default for (var j in categories) { if (categories[j][0] < existingDefaults[i][0]) continue; categories[j][0] -= existingDefaults[i][1]; } } // Remove sort keys from selected categories var removed = 0; for (var i in categories) { categories[i][0] -= removed; if (!defaultSortForm.elements["category_" + i].checked) continue; var newCategoryText = "[[Category:" + categories[i][2] + "]]\n"; text = text.substring(0, categories[i][0]) + newCategoryText + text.substring(categories[i][0] + categories[i][1]); removed += categories[i][1] - newCategoryText.length; } // Insert new default before first category, if any if (defaultSortForm.elements["defaultsort"].value) { var newDefaultSort = "{{DEFAULTSORT:" + defaultSortForm.elements["defaultsort"].value + "}}\n"; if (categories.length) { text = text.substring(0, categories[0][0]) + newDefaultSort + text.substring(categories[0][0]); } else { // Else place at the end text += "\n" + newDefaultSort; } } textbox.value = text; return defaultSortForm.elements["defaultsort"].value; } function doDefaultSort() { var formDiv = document.getElementById("defaultSortForm"); if (formDiv != null) { formDiv.parentNode.removeChild(formDiv); } var editform = document.getElementById("editform"); var textbox = document.getElementById("wpTextbox1"); if (editform == null || textbox == null) return; var match; var text = textbox.value; // Find any existing {{DEFAULTSORT:}} var existingDefaultRegex = new RegExp( "\\{\\{DEFAULTSORT:(\\{\\{(?:FULL)?PAGENAME\\}\\}|[^}]+)\\}\\}[ \\t]*(?:\\n\\r?|\\r)?", "gi"); var existingDefaults = []; while (match = existingDefaultRegex.exec(text)) { // Start, length, default sort key existingDefaults.push([ existingDefaultRegex.lastIndex - match[0].length, match[0].length, match[1] ]); } // Find all categories var categoryRegex = new RegExp( "\\[\\[Category:([^|\\]]+)(?:\\|([^\\]]+))?\\]\\][ \\t]*(?:\\n\\r?|\\r)?", "gi"); var categories = []; while (match = categoryRegex.exec(text)) { // Start, length, category, sort key categories.push([ categoryRegex.lastIndex - match[0].length, match[0].length, match[1], match[2] ]); } // Construct the default sort form with (easydom) { var defaultSortForm = form(); // Create default sort input box var initialDefaultSort = ''; var defaultSortInput = input({ name: "defaultsort", size: "40" }); for (var i in existingDefaults) { initialDefaultSort = existingDefaults[i][2]; } // Create warning for multiple default sorts var defaultSortWarning = span({ style: "font-size: smaller; color: red" }); if (existingDefaults.length > 1) { defaultSortWarning.appendChild(span(" ", strong("Note"), ": Multiple default sorts found")); } // Use most frequent sort key if no initialDefaultSort if (!initialDefaultSort) { var sortKeyFreq = {}; for (var i in categories) { var cat = categories[i]; var currentSort = cat[3]; if (currentSort) { if (!sortKeyFreq[currentSort]) { sortKeyFreq[currentSort] = 0; } sortKeyFreq[currentSort]++; } } var maxSortKeyCount = 0; for (var i in sortKeyFreq) { if (sortKeyFreq[i] > maxSortKeyCount) { initialDefaultSort = i; maxSortKeyCount = sortKeyFreq[i]; } } } // Create category list var categoryList = ul(); for (var i in categories) { var cat = categories[i]; var isDefault = false; var currentSort = cat[3]; if (!currentSort) { currentSort = em("default"); isDefault = true; } var boxId = "category_" + i; var checkbox = input({ type: "checkbox", name: boxId, id: boxId }); if (isDefault) { checkbox.checked = true; checkbox.disabled = true; } else { var changeDefaultSort = (function (value) { return function () { defaultSortInput.value = value; return false; }; })(currentSort); if (currentSort == initialDefaultSort) { checkbox.checked = true; } currentSort = a({ href: "#", onclick: changeDefaultSort }, currentSort); } categoryList.appendChild(li(checkbox, " ", label({ "for": boxId }, cat[2]), " (", span({ style: "color: gray" }, currentSort), ")" )); } // Add category list to form defaultSortForm.appendChild(categoryList); // Set initial default sort defaultSortInput.value = initialDefaultSort; // Add default sort input box to form defaultSortForm.appendChild(div({ style: "padding: 0.1em" }, strong("Default sort"), ": ", defaultSortInput, defaultSortWarning )); // Create cancel button var defaultSortCancel = input({ type: "button", value: "Cancel" }); defaultSortCancel.onclick = function () { formDiv.parentNode.removeChild(formDiv); textbox.disabled = false; window.focus(); return false; }; // Add submit and cancel buttons to form defaultSortForm.appendChild(div({ style: "padding: 0.1em" }, input({ type: "submit", style: "font-weight: bold", value: "Edit default sort" }), " ", defaultSortCancel )); // Create the form <div> var formDiv = div({ id: "defaultSortForm", style: "border: solid thin #aaa; padding: 0.1em;" }, defaultSortForm); // Attach the submit handler defaultSortForm.onsubmit = function () { var changed = editDefaultSort(textbox, existingDefaults, categories, this); formDiv.parentNode.removeChild(formDiv); textbox.disabled = false; var summary = document.getElementById("wpSummary"); if (summary.value) { summary.value += "; "; } if (changed) { summary.value += "Changed [[Help:Category#Default_sort_key|default sort key]]" + " to \"" + changed + "\""; } else { summary.value += "Removed [[Help:Category#Default_sort_key|default sort key]]"; } document.getElementById("wpMinoredit").checked = true; document.getElementById("wpDiff").click(); return false; }; // Stick the form in the page editform.insertBefore(formDiv, document.getElementById("wpSummaryLabel")); // Scroll to the form div scrollToFit(formDiv); // Disable the main text box textbox.disabled = true; // Focus on the input field defaultSortInput.focus(); } } addOnloadHook(function () { if (document.getElementById("wpTextbox1") != null) { addToolboxLink("javascript:doDefaultSort()", "Edit default sort", "t-defaultsort", "Edit default sort"); } }); /* </nowiki></pre> */