- Welcome to the Kancolle Wiki!
- If you have any questions regarding site content, account registration, etc., please visit the KanColle Wiki Discord
Difference between revisions of "MediaWiki:Common.js"
Jump to navigation
Jump to search
Benlisquare (talk | contribs) (add descriptions to code; translate zh -> en) |
|||
(57 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
− | /* | + | function filterTable(){ |
− | + | $("table.filterable").each(function(){ | |
− | + | var i=0; | |
− | + | var cols; | |
− | + | $(this).find("tr:first-child th, tr:first-child td").each(function(){ | |
+ | if (!$(this).hasClass("unfilterable")){ | ||
+ | cols=[]; | ||
+ | $(this).closest("table").find("tr td:nth-child("+(i+1)+")").each(function(){ | ||
+ | cols.push($(this).text()); | ||
+ | }); | ||
+ | cols = arrayUnique(cols); | ||
+ | l=0; | ||
+ | for (j=0; j<cols.length; j++){ | ||
+ | t=charLength(cols[j]); | ||
+ | if (l<t) l=t; | ||
+ | } | ||
+ | $(this).css("position","relative"); | ||
+ | $(this).html('<a href="javascript:void(0)" class="showFilterMenu">'+$(this).html()+'▼</a>'); | ||
+ | $(this).append($('<div class="filterMenu hidden" style="position: absolute; top: '+$(this).height()+35+'px; left: 0; width: '+(50+l*7)+'px; text-align: left; padding: 5px; border: 1px #333333 solid; -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; background: inherit; z-index: 1"></div>')); | ||
+ | for (j=0; j<cols.length; j++){ | ||
+ | $(this).find(".filterMenu").append('<div><input type="checkbox" value="'+cols[j]+'" col="'+(i+1)+'" class="filterOption" checked>'+cols[j]+'</div>'); | ||
+ | } | ||
+ | } | ||
+ | i++; | ||
+ | }); | ||
+ | $(this).find("tr:nth-child(n+1)").attr("condition", 0); | ||
+ | }); | ||
+ | $(".showFilterMenu").click(function(){ | ||
+ | if ($(this).parent().find(".filterMenu:visible").length){ | ||
+ | $(".filterMenu").slideUp(150); | ||
+ | }else{ | ||
+ | $(".filterMenu").slideUp(150); | ||
+ | $(this).parent().find(".filterMenu").slideDown(150); | ||
+ | } | ||
+ | }); | ||
+ | $(document).mouseup(function(e){ | ||
+ | var container = $(".filterMenu"); | ||
+ | if (!container.is(e.target) && container.has(e.target).length === 0){ | ||
+ | container.slideUp(150); | ||
+ | } | ||
+ | }); | ||
+ | $(".filterOption").click(function(){ | ||
+ | col=$(this).attr("col"); | ||
+ | val=$(this).val(); | ||
+ | if ($(this).is(":checked")) chg=1; else chg=-1; | ||
+ | $(this).closest("table").find("tr:nth-child(n+1)").each(function(){ | ||
+ | if ($(this).find("td:nth-child("+col+")").text()==val){ | ||
+ | var cond=$(this).attr("condition"); | ||
+ | cond=Number(cond)+chg; | ||
+ | $(this).attr("condition", cond); | ||
+ | if (cond===0) $(this).show(); | ||
+ | else $(this).hide(); | ||
+ | } | ||
+ | }); | ||
+ | }); | ||
+ | } | ||
− | function | + | function arrayUnique(a) { |
− | + | return a.reduce(function(p, c) { | |
− | + | if (p.indexOf(c) < 0) p.push(c); | |
− | + | return p; | |
− | + | }, []); | |
− | }); | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | function charLength(s){ | ||
+ | return s.length+(encodeURI(s).split(/%..|./).length-1-s.length)/2; | ||
+ | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
/** | /** | ||
* Shows and hides content and picture (if available) of navigation bars | * Shows and hides content and picture (if available) of navigation bars | ||
Line 162: | Line 83: | ||
/* if shown now */ | /* if shown now */ | ||
if ( NavToggle.firstChild.data === NavigationBarHide ) { | if ( NavToggle.firstChild.data === NavigationBarHide ) { | ||
− | for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) { | + | for ( NavChild = NavFrame.firstChild; NavChild !== null; NavChild = NavChild.nextSibling ) { |
if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) { | if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) { | ||
NavChild.style.display = 'none'; | NavChild.style.display = 'none'; | ||
Line 171: | Line 92: | ||
/* if hidden now */ | /* if hidden now */ | ||
} else if ( NavToggle.firstChild.data === NavigationBarShow ) { | } else if ( NavToggle.firstChild.data === NavigationBarShow ) { | ||
− | for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) { | + | for ( NavChild = NavFrame.firstChild; NavChild !== null; NavChild = NavChild.nextSibling ) { |
if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) { | if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) { | ||
NavChild.style.display = 'block'; | NavChild.style.display = 'block'; | ||
Line 206: | Line 127: | ||
* "collapsed" to the NavFrame itself, just like with collapsible tables. | * "collapsed" to the NavFrame itself, just like with collapsible tables. | ||
*/ | */ | ||
− | for ( NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling ) { | + | for ( NavChild = NavFrame.firstChild; NavChild !== null && !isCollapsed; NavChild = NavChild.nextSibling ) { |
if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) { | if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) { | ||
if ( NavChild.style.display === 'none' ) { | if ( NavChild.style.display === 'none' ) { | ||
Line 214: | Line 135: | ||
} | } | ||
if ( isCollapsed ) { | if ( isCollapsed ) { | ||
− | for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) { | + | for ( NavChild = NavFrame.firstChild; NavChild !== null; NavChild = NavChild.nextSibling ) { |
if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) { | if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) { | ||
NavChild.style.display = 'none'; | NavChild.style.display = 'none'; | ||
Line 236: | Line 157: | ||
mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton ); | mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton ); | ||
+ | |||
+ | // Fix Table Header | ||
+ | var TableHeadFix = function () { | ||
+ | var obj, $table, $newtable, $win; | ||
+ | obj = this; | ||
+ | |||
+ | this.clonehead = function () { | ||
+ | $newtable = $table.clone(); | ||
+ | $newtable.find('tr:gt(0)').remove(); | ||
+ | |||
+ | $newtable.css('top', '0'); | ||
+ | $newtable.css('position', 'fixed'); | ||
+ | // Fixed by kk @ 2015-04-03 | ||
+ | $newtable.css('margin-top', '0'); | ||
+ | $newtable.hide(); | ||
+ | }; | ||
+ | |||
+ | |||
+ | this.check = function () { | ||
+ | if($table.size() === 0){ | ||
+ | return; | ||
+ | } | ||
+ | var scrollTop = $win.scrollTop(); | ||
+ | var start_offset = $table.offset(); | ||
+ | if (scrollTop > start_offset.top && scrollTop <= (start_offset.top + $table.height())) { | ||
+ | $newtable.show(); | ||
+ | } else { | ||
+ | $newtable.hide(); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | this.event = function () { | ||
+ | $win.bind('scroll', obj.check); | ||
+ | }; | ||
+ | |||
+ | this.init = function (obj) { | ||
+ | $win = $(window); | ||
+ | $table = $(obj); | ||
+ | this.clonehead(); | ||
+ | $table.after($newtable); | ||
+ | |||
+ | this.event(); | ||
+ | this.check(); | ||
+ | }; | ||
+ | }; | ||
+ | |||
+ | $(function() { | ||
+ | |||
+ | // Extension:SoundManager2Button | ||
+ | // TODO: initialize properly so this isn't needed | ||
+ | if (window.soundManager && window.soundManager.beginDelayedInit && !window.soundManager.enabled) { | ||
+ | console.debug('KLUDGE: calling window.soundManager.beginDelayedInit()'); | ||
+ | window.soundManager.beginDelayedInit(); | ||
+ | } | ||
+ | |||
+ | // Table things | ||
+ | |||
+ | $(".showExtra").click(function() { | ||
+ | $(this).closest("table").find(".extraRow").fadeIn("slow");$(this).closest("tr").remove(); | ||
+ | }); | ||
+ | |||
+ | filterTable(); | ||
+ | |||
+ | $('.fixtable').each(function(){ | ||
+ | var tableHeadFix = new TableHeadFix(); | ||
+ | tableHeadFix.init(this); | ||
+ | }); | ||
+ | |||
+ | // Template:Map/ImageNode | ||
+ | |||
+ | function supportTemplateMapImageNode() { | ||
+ | $('.map-image > span > a').off('click'); | ||
+ | $('.map-image > span > a').click(function (e) { | ||
+ | e.preventDefault(); | ||
+ | var $element = $($(this).attr('href')); | ||
+ | var $container = $element.parent(); | ||
+ | $container.scrollTop($container.scrollTop() - $container.offset().top + $element.offset().top); | ||
+ | }); | ||
+ | } | ||
+ | supportTemplateMapImageNode(); | ||
+ | mw.hook('wikipage.content').add(supportTemplateMapImageNode); | ||
+ | |||
+ | // From gbf.wiki | ||
+ | // Add a dynamic fixed header to tables with: | ||
+ | // 1) table with "header-fixed" class | ||
+ | // 2) a table row with "header-row" class | ||
+ | // TODO: tablesorter, tabbertab, resize | ||
+ | // mw.loader.using('jquery.tablesorter', function() { | ||
+ | var tables = []; | ||
+ | |||
+ | function initializeStickyHeader() { | ||
+ | var $tables = $('.header-fixed'); | ||
+ | |||
+ | if ($tables.length == 0) return; | ||
+ | |||
+ | $tables.each(function(n) { | ||
+ | if ($(this).hasClass('header-fixed-done')) return; | ||
+ | if ($(this).hasClass('mw-collapsed')) { | ||
+ | console.debug('header-fixed: collapsed: ' + n) | ||
+ | $(this).find('.mw-collapsible-text').click(function() { | ||
+ | console.debug('header-fixed: click: ' + n) | ||
+ | setTimeout(function() { initializeStickyHeader(); }, 1000); | ||
+ | }) | ||
+ | return; | ||
+ | } | ||
+ | /* | ||
+ | var tabberTabParent = $(this).parent(".tabbertab")[0]; | ||
+ | var originalStyleDisplay; | ||
+ | if (tabberTabParent) { | ||
+ | originalStyleDisplay = tabberTabParent.style.display; | ||
+ | tabberTabParent.style.visibility = "hidden"; | ||
+ | tabberTabParent.style.display = "block"; | ||
+ | } | ||
+ | */ | ||
+ | var $headerRow = $(this).find('.header-row'); | ||
+ | var $newHeaderContent = $('<tbody>'); | ||
+ | $newHeaderContent.append($headerRow.clone()); | ||
+ | |||
+ | var $columnsOld = $headerRow.find('td:not([colspan]),th:not([colspan])'); | ||
+ | var $newHeaderColgroup = $('<colgroup>'); | ||
+ | for (var i = 0; i < $columnsOld.length; i++) { | ||
+ | $newHeaderColgroup.append($('<col>').css('width', $columnsOld[i].getBoundingClientRect().width)); | ||
+ | } | ||
+ | |||
+ | $(this).before( | ||
+ | $('<table>') | ||
+ | .addClass('header-fixed-helper') | ||
+ | .addClass('wikitable') | ||
+ | .css('position', 'sticky') | ||
+ | .css('top', '0') | ||
+ | .css('z-index', '9') | ||
+ | .css('display', 'none') | ||
+ | .css('background-color', '#fff') | ||
+ | .css('margin-top', '0') | ||
+ | .css('margin-bottom', '0') | ||
+ | .css('table-layout', 'fixed') | ||
+ | .append($newHeaderColgroup) | ||
+ | .append($newHeaderContent) | ||
+ | ); | ||
+ | tables.push({ table: this, helper: this.previousSibling }); | ||
+ | $(this.previousSibling).css('width', $(this).width() + 1); | ||
+ | /* | ||
+ | if (tabberTabParent) { | ||
+ | tabberTabParent.style.visibility = ""; | ||
+ | tabberTabParent.style.display = originalStyleDisplay; | ||
+ | } | ||
+ | */ | ||
+ | $(this).addClass('header-fixed-done'); | ||
+ | console.debug('header-fixed: fixed: ' + n) | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | $(window).on('scroll', function() { | ||
+ | var scrollOffset = $(this).scrollTop(); | ||
+ | for (var i = 0; i < tables.length; i++) { | ||
+ | var tableOffset = $(tables[i].table).offset().top; | ||
+ | var tableHeight = $(tables[i].table).height(); | ||
+ | var helperHeight = $(tables[i].helper).height(); | ||
+ | if ((scrollOffset > tableOffset) && (scrollOffset < (tableOffset + tableHeight - helperHeight))) { | ||
+ | if ($(tables[i].helper).is(':hidden')) { | ||
+ | $(tables[i].helper).show(); | ||
+ | } | ||
+ | } else { | ||
+ | $(tables[i].helper).hide(); | ||
+ | } | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | /* | ||
+ | var ts = $.fn.tablesorter; | ||
+ | $.fn.tablesorter = function() { | ||
+ | ts.apply(this, arguments); | ||
+ | initializeStickyHeader(); | ||
+ | } | ||
+ | */ | ||
+ | setTimeout(function() { initializeStickyHeader(); }, 1000); | ||
+ | //}) | ||
+ | |||
+ | // Basic video support using <img> and <video> elements | ||
+ | |||
+ | $('.video').each(function () { | ||
+ | var src = $(this).data('src') || ''; | ||
+ | var parts = src.split('.'); | ||
+ | var ext = parts[parts.length - 1] || ''; | ||
+ | if (ext === 'webp') { | ||
+ | var a = $('<a>').addClass('image').attr('href', '/File:' + src); | ||
+ | var img = $('<img>'); | ||
+ | for (var attr in $(this).data()) { | ||
+ | img.attr(attr, (attr === 'src' ? 'https://en.kancollewiki.net/Special:Filepath/' : '') + $(this).data(attr)); | ||
+ | } | ||
+ | a.append(img); | ||
+ | $(this).append(a); | ||
+ | } else { | ||
+ | var video = $('<video>').attr('controls', ''); | ||
+ | var source = $('<source>').attr('type', 'video/' + ext); | ||
+ | for (var attr in $(this).data()) { | ||
+ | var el = attr === 'src' || attr === 'type' ? source : video; | ||
+ | el.attr(attr, (attr === 'src' ? 'https://en.kancollewiki.net/Special:Filepath/' : '') + $(this).data(attr)); | ||
+ | } | ||
+ | video.append(source); | ||
+ | $(this).append(video); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | }); | ||
+ | |||
+ | (function(mw, $) { | ||
+ | |||
+ | "use strict"; | ||
+ | |||
+ | $(document).ready(function() { | ||
+ | |||
+ | console.log('DetailToggle v1.0.0'); | ||
+ | |||
+ | // custom hidable content and togglers supported by local storage | ||
+ | |||
+ | if (typeof(Storage) === "undefined") { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | var ToggleStorage = function(property, property_default) { | ||
+ | if (!localStorage[property]) { | ||
+ | localStorage[property] = property_default; | ||
+ | } | ||
+ | return { | ||
+ | toggle: function() { | ||
+ | localStorage[property] = localStorage[property] === "show" ? "hide" : "show"; | ||
+ | }, | ||
+ | on: function() { | ||
+ | return localStorage[property] === "show"; | ||
+ | } | ||
+ | }; | ||
+ | } | ||
+ | |||
+ | function update(toggle_element, toggle) { | ||
+ | var property = toggle_element.data("target") || "default", | ||
+ | property_anti = toggle_element.data("anti-target"), | ||
+ | property_default = toggle_element.data("default") || "show", | ||
+ | property_classes = toggle_element.data("classes") && toggle_element.data("classes").split(' ').map(function (e) { return "toggle-class-" + e.trim() }).join(' '), | ||
+ | target = "toggle-target-" + property, | ||
+ | target_class = "." + target, | ||
+ | anti_target_class, | ||
+ | toggleStorage = ToggleStorage(target, property_default); | ||
+ | if (property_anti) { | ||
+ | anti_target_class = ".toggle-anti-target-" + property; | ||
+ | } | ||
+ | if (toggle) { | ||
+ | toggleStorage.toggle(); | ||
+ | } | ||
+ | var toggle_show_selector = '.toggle[data-target="' + property + '"] .toggle-show', | ||
+ | toggle_hide_selector = '.toggle[data-target="' + property + '"] .toggle-hide'; | ||
+ | if (toggleStorage.on()) { | ||
+ | $(toggle_show_selector).show(); | ||
+ | $(toggle_hide_selector).hide(); | ||
+ | if (property_classes) { | ||
+ | $(target_class).addClass(property_classes); | ||
+ | } else { | ||
+ | $(target_class).show(); | ||
+ | } | ||
+ | if (anti_target_class) { | ||
+ | $(anti_target_class).hide(); | ||
+ | } | ||
+ | } else { | ||
+ | $(toggle_show_selector).hide(); | ||
+ | $(toggle_hide_selector).show(); | ||
+ | if (property_classes) { | ||
+ | $(target_class).removeClass(property_classes); | ||
+ | } else { | ||
+ | $(target_class).hide(); | ||
+ | } | ||
+ | if (anti_target_class) { | ||
+ | $(anti_target_class).show(); | ||
+ | } | ||
+ | } | ||
+ | $(window).trigger("WideTablesScan"); | ||
+ | } | ||
+ | |||
+ | //Local storage for multi toggles. | ||
+ | var MultiToggleStorage = function(property, property_default) { | ||
+ | if (!localStorage[property]) { | ||
+ | localStorage[property] = property_default; | ||
+ | } | ||
+ | return { | ||
+ | set: function(value) { | ||
+ | localStorage[property] = value; | ||
+ | }, | ||
+ | get: function(value) { | ||
+ | return localStorage[property]; | ||
+ | }, | ||
+ | on: function(value) { | ||
+ | return localStorage[property] === value; | ||
+ | } | ||
+ | }; | ||
+ | } | ||
+ | |||
+ | //Update a multi toggle. If selected is passed it is set as the state of the multi toggle. Pass "none" to selected to deselect when the multi toggle is a filter. | ||
+ | function multi_update(multi_toggle_element, selected) { | ||
+ | var property = multi_toggle_element.data("target") || "default", | ||
+ | property_states = multi_toggle_element.data("states"), | ||
+ | property_default = multi_toggle_element.data("default"), | ||
+ | property_filter = multi_toggle_element.data("filter") || false, //Whether or not the multi toggle is a filter | ||
+ | property_base_colspan = multi_toggle_element.data("base-colspan"), | ||
+ | target = "multi-toggle-target-" + property; | ||
+ | //make sure the states are an array. | ||
+ | if (!property_states || !Array.isArray(property_states) || property_states.length < 1) { | ||
+ | multi_toggle_element.hide(); | ||
+ | return; | ||
+ | } else if (property_filter && property_states[0] !== "none") { | ||
+ | property_states.splice(0, 0, "none") | ||
+ | } | ||
+ | //need to set default here rather than in the declaration above to ensure the states are valid. | ||
+ | if (!property_default) { | ||
+ | property_default = property_states[0]; | ||
+ | } | ||
+ | var multiToggleStorage = MultiToggleStorage(target, property_default); | ||
+ | //set the new state of the multi toggle. | ||
+ | if (selected && property_states.indexOf(selected) >= 0) { | ||
+ | //If the selected filter was re-selected, that is a remove filter action. | ||
+ | if ((property_filter && multiToggleStorage.on(selected))) { | ||
+ | selected = "none"; | ||
+ | } | ||
+ | multiToggleStorage.set(selected); | ||
+ | } else { | ||
+ | //No selection, so we are initializing the multi toggle. | ||
+ | selected = multiToggleStorage.get() | ||
+ | } | ||
+ | //Update non-selected states | ||
+ | var hide_selectors = []; | ||
+ | var show_selectors = []; | ||
+ | property_states.forEach(function(state) { | ||
+ | var toggle_active_selector = '.multi-toggle[data-target="' + property + '"] .multi-toggle-button[data-state="' + state + '"] .multi-toggle-active', | ||
+ | toggle_inactive_selector = '.multi-toggle[data-target="' + property + '"] .multi-toggle-button[data-state="' + state + '"] .multi-toggle-inactive'; | ||
+ | if (selected !== state) { | ||
+ | $(toggle_active_selector).hide(); | ||
+ | $(toggle_inactive_selector).show(); | ||
+ | if (selected === "none") { | ||
+ | show_selectors.push("." + target + "-" + state); | ||
+ | } else { | ||
+ | hide_selectors.push("." + target + "-" + state); | ||
+ | } | ||
+ | } else { | ||
+ | $(toggle_active_selector).show(); | ||
+ | $(toggle_inactive_selector).hide(); | ||
+ | show_selectors.push("." + target + "-" + state); | ||
+ | } | ||
+ | }) | ||
+ | $(hide_selectors.join(',')).hide(); | ||
+ | //Update selected state last | ||
+ | $(show_selectors.join(',')).show(); | ||
+ | //Update colspan for custom rows. | ||
+ | if (property_filter) { | ||
+ | if (selected === "none") { | ||
+ | $(".custom-row." + target).attr("colSpan", property_base_colspan); | ||
+ | } else { | ||
+ | $(".custom-row." + target).attr("colSpan", property_base_colspan - property_states.length + 2); | ||
+ | } | ||
+ | } | ||
+ | //cleanup | ||
+ | $(window).trigger("WideTablesScan"); | ||
+ | } | ||
+ | |||
+ | function updateContent() { | ||
+ | |||
+ | $(".toggle").each(function() { | ||
+ | var toggle_element = $(this); | ||
+ | toggle_element.show(); | ||
+ | update(toggle_element); | ||
+ | if (toggle_element.hasClass('toggle-passive')) { | ||
+ | return; | ||
+ | } | ||
+ | toggle_element.off("click"); | ||
+ | toggle_element.click(function() { | ||
+ | update(toggle_element, true); | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | //Activate multi toggles. | ||
+ | var targets = {}; | ||
+ | $(".multi-toggle").each(function() { | ||
+ | var multi_toggle_element = $(this), | ||
+ | multi_toggle_buttons = multi_toggle_element.children(".multi-toggle-button"), | ||
+ | target = multi_toggle_element.data("target") || "default"; | ||
+ | multi_toggle_element.show(); | ||
+ | if (!targets.hasOwnProperty(target)) | ||
+ | targets[target] = multi_toggle_element; | ||
+ | //Remove click event handlers from all multi toggle buttons | ||
+ | multi_toggle_buttons.off("click"); | ||
+ | //Add click event handler for all multi toggle buttons to trigger multi_update with select action. | ||
+ | multi_toggle_buttons.click(function() { | ||
+ | multi_update(multi_toggle_element, $(this).data("state")); | ||
+ | }); | ||
+ | }); | ||
+ | //call multi-update once for each target to allow multiple controls | ||
+ | //without horrible lag | ||
+ | Object.keys(targets).forEach(function (key) {multi_update(targets[key])}); | ||
+ | |||
+ | // .mw-collapsible togglers | ||
+ | |||
+ | $(".mw-collapsible-expand-all").each(function() { | ||
+ | var toggle_element = $(this); | ||
+ | toggle_element.off("click"); | ||
+ | toggle_element.click(function() { | ||
+ | $(".mw-collapsible-toggle.mw-collapsible-toggle-collapsed").click(); | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | $(".mw-collapsible-collapse-all").each(function() { | ||
+ | var toggle_element = $(this); | ||
+ | toggle_element.off("click"); | ||
+ | toggle_element.click(function() { | ||
+ | $(".mw-collapsible-toggle:not(.mw-collapsible-toggle-collapsed)").click(); | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | $(".mw-collapsible-toggle-all").each(function() { | ||
+ | var toggle_element = $(this); | ||
+ | toggle_element.off("click"); | ||
+ | toggle_element.click(function() { | ||
+ | $(".mw-collapsible-toggle").click(); | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | } | ||
+ | |||
+ | updateContent(); | ||
+ | mw.hook("wikipage.content").add(updateContent); | ||
+ | |||
+ | }); | ||
+ | |||
+ | }(mediaWiki, jQuery)); |
Revision as of 17:12, 15 May 2024
function filterTable(){
$("table.filterable").each(function(){
var i=0;
var cols;
$(this).find("tr:first-child th, tr:first-child td").each(function(){
if (!$(this).hasClass("unfilterable")){
cols=[];
$(this).closest("table").find("tr td:nth-child("+(i+1)+")").each(function(){
cols.push($(this).text());
});
cols = arrayUnique(cols);
l=0;
for (j=0; j<cols.length; j++){
t=charLength(cols[j]);
if (l<t) l=t;
}
$(this).css("position","relative");
$(this).html('<a href="javascript:void(0)" class="showFilterMenu">'+$(this).html()+'▼</a>');
$(this).append($('<div class="filterMenu hidden" style="position: absolute; top: '+$(this).height()+35+'px; left: 0; width: '+(50+l*7)+'px; text-align: left; padding: 5px; border: 1px #333333 solid; -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; background: inherit; z-index: 1"></div>'));
for (j=0; j<cols.length; j++){
$(this).find(".filterMenu").append('<div><input type="checkbox" value="'+cols[j]+'" col="'+(i+1)+'" class="filterOption" checked>'+cols[j]+'</div>');
}
}
i++;
});
$(this).find("tr:nth-child(n+1)").attr("condition", 0);
});
$(".showFilterMenu").click(function(){
if ($(this).parent().find(".filterMenu:visible").length){
$(".filterMenu").slideUp(150);
}else{
$(".filterMenu").slideUp(150);
$(this).parent().find(".filterMenu").slideDown(150);
}
});
$(document).mouseup(function(e){
var container = $(".filterMenu");
if (!container.is(e.target) && container.has(e.target).length === 0){
container.slideUp(150);
}
});
$(".filterOption").click(function(){
col=$(this).attr("col");
val=$(this).val();
if ($(this).is(":checked")) chg=1; else chg=-1;
$(this).closest("table").find("tr:nth-child(n+1)").each(function(){
if ($(this).find("td:nth-child("+col+")").text()==val){
var cond=$(this).attr("condition");
cond=Number(cond)+chg;
$(this).attr("condition", cond);
if (cond===0) $(this).show();
else $(this).hide();
}
});
});
}
function arrayUnique(a) {
return a.reduce(function(p, c) {
if (p.indexOf(c) < 0) p.push(c);
return p;
}, []);
}
function charLength(s){
return s.length+(encodeURI(s).split(/%..|./).length-1-s.length)/2;
}
/**
* Shows and hides content and picture (if available) of navigation bars
* Parameters:
* indexNavigationBar: the index of navigation bar to be toggled
**/
window.toggleNavigationBar = function ( indexNavigationBar, event ) {
var NavToggle = document.getElementById( 'NavToggle' + indexNavigationBar );
var NavFrame = document.getElementById( 'NavFrame' + indexNavigationBar );
var NavChild;
if ( !NavFrame || !NavToggle ) {
return false;
}
/* if shown now */
if ( NavToggle.firstChild.data === NavigationBarHide ) {
for ( NavChild = NavFrame.firstChild; NavChild !== null; NavChild = NavChild.nextSibling ) {
if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) {
NavChild.style.display = 'none';
}
}
NavToggle.firstChild.data = NavigationBarShow;
/* if hidden now */
} else if ( NavToggle.firstChild.data === NavigationBarShow ) {
for ( NavChild = NavFrame.firstChild; NavChild !== null; NavChild = NavChild.nextSibling ) {
if ( $( NavChild ).hasClass( 'NavContent' ) || $( NavChild ).hasClass( 'NavPic' ) ) {
NavChild.style.display = 'block';
}
}
NavToggle.firstChild.data = NavigationBarHide;
}
event.preventDefault();
};
/* adds show/hide-button to navigation bars */
function createNavigationBarToggleButton( $content ) {
var NavChild;
/* iterate over all < div >-elements */
var $divs = $content.find( 'div' );
$divs.each( function ( i, NavFrame ) {
/* if found a navigation bar */
if ( $( NavFrame ).hasClass( 'NavFrame' ) ) {
indexNavigationBar++;
var NavToggle = document.createElement( 'a' );
NavToggle.className = 'NavToggle';
NavToggle.setAttribute( 'id', 'NavToggle' + indexNavigationBar );
NavToggle.setAttribute( 'href', '#' );
$( NavToggle ).on( 'click', $.proxy( window.toggleNavigationBar, window, indexNavigationBar ) );
var isCollapsed = $( NavFrame ).hasClass( 'collapsed' );
/**
* Check if any children are already hidden. This loop is here for backwards compatibility:
* the old way of making NavFrames start out collapsed was to manually add style="display:none"
* to all the NavPic/NavContent elements. Since this was bad for accessibility (no way to make
* the content visible without JavaScript support), the new recommended way is to add the class
* "collapsed" to the NavFrame itself, just like with collapsible tables.
*/
for ( NavChild = NavFrame.firstChild; NavChild !== null && !isCollapsed; NavChild = NavChild.nextSibling ) {
if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) {
if ( NavChild.style.display === 'none' ) {
isCollapsed = true;
}
}
}
if ( isCollapsed ) {
for ( NavChild = NavFrame.firstChild; NavChild !== null; NavChild = NavChild.nextSibling ) {
if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) {
NavChild.style.display = 'none';
}
}
}
var NavToggleText = document.createTextNode( isCollapsed ? NavigationBarShow : NavigationBarHide );
NavToggle.appendChild( NavToggleText );
/* Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked) */
for( var j = 0; j < NavFrame.childNodes.length; j++ ) {
if ( $( NavFrame.childNodes[j] ).hasClass( 'NavHead' ) ) {
NavToggle.style.color = NavFrame.childNodes[j].style.color;
NavFrame.childNodes[j].appendChild( NavToggle );
}
}
NavFrame.setAttribute( 'id', 'NavFrame' + indexNavigationBar );
}
} );
}
mw.hook( 'wikipage.content' ).add( createNavigationBarToggleButton );
// Fix Table Header
var TableHeadFix = function () {
var obj, $table, $newtable, $win;
obj = this;
this.clonehead = function () {
$newtable = $table.clone();
$newtable.find('tr:gt(0)').remove();
$newtable.css('top', '0');
$newtable.css('position', 'fixed');
// Fixed by kk @ 2015-04-03
$newtable.css('margin-top', '0');
$newtable.hide();
};
this.check = function () {
if($table.size() === 0){
return;
}
var scrollTop = $win.scrollTop();
var start_offset = $table.offset();
if (scrollTop > start_offset.top && scrollTop <= (start_offset.top + $table.height())) {
$newtable.show();
} else {
$newtable.hide();
}
};
this.event = function () {
$win.bind('scroll', obj.check);
};
this.init = function (obj) {
$win = $(window);
$table = $(obj);
this.clonehead();
$table.after($newtable);
this.event();
this.check();
};
};
$(function() {
// Extension:SoundManager2Button
// TODO: initialize properly so this isn't needed
if (window.soundManager && window.soundManager.beginDelayedInit && !window.soundManager.enabled) {
console.debug('KLUDGE: calling window.soundManager.beginDelayedInit()');
window.soundManager.beginDelayedInit();
}
// Table things
$(".showExtra").click(function() {
$(this).closest("table").find(".extraRow").fadeIn("slow");$(this).closest("tr").remove();
});
filterTable();
$('.fixtable').each(function(){
var tableHeadFix = new TableHeadFix();
tableHeadFix.init(this);
});
// Template:Map/ImageNode
function supportTemplateMapImageNode() {
$('.map-image > span > a').off('click');
$('.map-image > span > a').click(function (e) {
e.preventDefault();
var $element = $($(this).attr('href'));
var $container = $element.parent();
$container.scrollTop($container.scrollTop() - $container.offset().top + $element.offset().top);
});
}
supportTemplateMapImageNode();
mw.hook('wikipage.content').add(supportTemplateMapImageNode);
// From gbf.wiki
// Add a dynamic fixed header to tables with:
// 1) table with "header-fixed" class
// 2) a table row with "header-row" class
// TODO: tablesorter, tabbertab, resize
// mw.loader.using('jquery.tablesorter', function() {
var tables = [];
function initializeStickyHeader() {
var $tables = $('.header-fixed');
if ($tables.length == 0) return;
$tables.each(function(n) {
if ($(this).hasClass('header-fixed-done')) return;
if ($(this).hasClass('mw-collapsed')) {
console.debug('header-fixed: collapsed: ' + n)
$(this).find('.mw-collapsible-text').click(function() {
console.debug('header-fixed: click: ' + n)
setTimeout(function() { initializeStickyHeader(); }, 1000);
})
return;
}
/*
var tabberTabParent = $(this).parent(".tabbertab")[0];
var originalStyleDisplay;
if (tabberTabParent) {
originalStyleDisplay = tabberTabParent.style.display;
tabberTabParent.style.visibility = "hidden";
tabberTabParent.style.display = "block";
}
*/
var $headerRow = $(this).find('.header-row');
var $newHeaderContent = $('<tbody>');
$newHeaderContent.append($headerRow.clone());
var $columnsOld = $headerRow.find('td:not([colspan]),th:not([colspan])');
var $newHeaderColgroup = $('<colgroup>');
for (var i = 0; i < $columnsOld.length; i++) {
$newHeaderColgroup.append($('<col>').css('width', $columnsOld[i].getBoundingClientRect().width));
}
$(this).before(
$('<table>')
.addClass('header-fixed-helper')
.addClass('wikitable')
.css('position', 'sticky')
.css('top', '0')
.css('z-index', '9')
.css('display', 'none')
.css('background-color', '#fff')
.css('margin-top', '0')
.css('margin-bottom', '0')
.css('table-layout', 'fixed')
.append($newHeaderColgroup)
.append($newHeaderContent)
);
tables.push({ table: this, helper: this.previousSibling });
$(this.previousSibling).css('width', $(this).width() + 1);
/*
if (tabberTabParent) {
tabberTabParent.style.visibility = "";
tabberTabParent.style.display = originalStyleDisplay;
}
*/
$(this).addClass('header-fixed-done');
console.debug('header-fixed: fixed: ' + n)
});
}
$(window).on('scroll', function() {
var scrollOffset = $(this).scrollTop();
for (var i = 0; i < tables.length; i++) {
var tableOffset = $(tables[i].table).offset().top;
var tableHeight = $(tables[i].table).height();
var helperHeight = $(tables[i].helper).height();
if ((scrollOffset > tableOffset) && (scrollOffset < (tableOffset + tableHeight - helperHeight))) {
if ($(tables[i].helper).is(':hidden')) {
$(tables[i].helper).show();
}
} else {
$(tables[i].helper).hide();
}
}
});
/*
var ts = $.fn.tablesorter;
$.fn.tablesorter = function() {
ts.apply(this, arguments);
initializeStickyHeader();
}
*/
setTimeout(function() { initializeStickyHeader(); }, 1000);
//})
// Basic video support using <img> and <video> elements
$('.video').each(function () {
var src = $(this).data('src') || '';
var parts = src.split('.');
var ext = parts[parts.length - 1] || '';
if (ext === 'webp') {
var a = $('<a>').addClass('image').attr('href', '/File:' + src);
var img = $('<img>');
for (var attr in $(this).data()) {
img.attr(attr, (attr === 'src' ? 'https://en.kancollewiki.net/Special:Filepath/' : '') + $(this).data(attr));
}
a.append(img);
$(this).append(a);
} else {
var video = $('<video>').attr('controls', '');
var source = $('<source>').attr('type', 'video/' + ext);
for (var attr in $(this).data()) {
var el = attr === 'src' || attr === 'type' ? source : video;
el.attr(attr, (attr === 'src' ? 'https://en.kancollewiki.net/Special:Filepath/' : '') + $(this).data(attr));
}
video.append(source);
$(this).append(video);
}
});
});
(function(mw, $) {
"use strict";
$(document).ready(function() {
console.log('DetailToggle v1.0.0');
// custom hidable content and togglers supported by local storage
if (typeof(Storage) === "undefined") {
return;
}
var ToggleStorage = function(property, property_default) {
if (!localStorage[property]) {
localStorage[property] = property_default;
}
return {
toggle: function() {
localStorage[property] = localStorage[property] === "show" ? "hide" : "show";
},
on: function() {
return localStorage[property] === "show";
}
};
}
function update(toggle_element, toggle) {
var property = toggle_element.data("target") || "default",
property_anti = toggle_element.data("anti-target"),
property_default = toggle_element.data("default") || "show",
property_classes = toggle_element.data("classes") && toggle_element.data("classes").split(' ').map(function (e) { return "toggle-class-" + e.trim() }).join(' '),
target = "toggle-target-" + property,
target_class = "." + target,
anti_target_class,
toggleStorage = ToggleStorage(target, property_default);
if (property_anti) {
anti_target_class = ".toggle-anti-target-" + property;
}
if (toggle) {
toggleStorage.toggle();
}
var toggle_show_selector = '.toggle[data-target="' + property + '"] .toggle-show',
toggle_hide_selector = '.toggle[data-target="' + property + '"] .toggle-hide';
if (toggleStorage.on()) {
$(toggle_show_selector).show();
$(toggle_hide_selector).hide();
if (property_classes) {
$(target_class).addClass(property_classes);
} else {
$(target_class).show();
}
if (anti_target_class) {
$(anti_target_class).hide();
}
} else {
$(toggle_show_selector).hide();
$(toggle_hide_selector).show();
if (property_classes) {
$(target_class).removeClass(property_classes);
} else {
$(target_class).hide();
}
if (anti_target_class) {
$(anti_target_class).show();
}
}
$(window).trigger("WideTablesScan");
}
//Local storage for multi toggles.
var MultiToggleStorage = function(property, property_default) {
if (!localStorage[property]) {
localStorage[property] = property_default;
}
return {
set: function(value) {
localStorage[property] = value;
},
get: function(value) {
return localStorage[property];
},
on: function(value) {
return localStorage[property] === value;
}
};
}
//Update a multi toggle. If selected is passed it is set as the state of the multi toggle. Pass "none" to selected to deselect when the multi toggle is a filter.
function multi_update(multi_toggle_element, selected) {
var property = multi_toggle_element.data("target") || "default",
property_states = multi_toggle_element.data("states"),
property_default = multi_toggle_element.data("default"),
property_filter = multi_toggle_element.data("filter") || false, //Whether or not the multi toggle is a filter
property_base_colspan = multi_toggle_element.data("base-colspan"),
target = "multi-toggle-target-" + property;
//make sure the states are an array.
if (!property_states || !Array.isArray(property_states) || property_states.length < 1) {
multi_toggle_element.hide();
return;
} else if (property_filter && property_states[0] !== "none") {
property_states.splice(0, 0, "none")
}
//need to set default here rather than in the declaration above to ensure the states are valid.
if (!property_default) {
property_default = property_states[0];
}
var multiToggleStorage = MultiToggleStorage(target, property_default);
//set the new state of the multi toggle.
if (selected && property_states.indexOf(selected) >= 0) {
//If the selected filter was re-selected, that is a remove filter action.
if ((property_filter && multiToggleStorage.on(selected))) {
selected = "none";
}
multiToggleStorage.set(selected);
} else {
//No selection, so we are initializing the multi toggle.
selected = multiToggleStorage.get()
}
//Update non-selected states
var hide_selectors = [];
var show_selectors = [];
property_states.forEach(function(state) {
var toggle_active_selector = '.multi-toggle[data-target="' + property + '"] .multi-toggle-button[data-state="' + state + '"] .multi-toggle-active',
toggle_inactive_selector = '.multi-toggle[data-target="' + property + '"] .multi-toggle-button[data-state="' + state + '"] .multi-toggle-inactive';
if (selected !== state) {
$(toggle_active_selector).hide();
$(toggle_inactive_selector).show();
if (selected === "none") {
show_selectors.push("." + target + "-" + state);
} else {
hide_selectors.push("." + target + "-" + state);
}
} else {
$(toggle_active_selector).show();
$(toggle_inactive_selector).hide();
show_selectors.push("." + target + "-" + state);
}
})
$(hide_selectors.join(',')).hide();
//Update selected state last
$(show_selectors.join(',')).show();
//Update colspan for custom rows.
if (property_filter) {
if (selected === "none") {
$(".custom-row." + target).attr("colSpan", property_base_colspan);
} else {
$(".custom-row." + target).attr("colSpan", property_base_colspan - property_states.length + 2);
}
}
//cleanup
$(window).trigger("WideTablesScan");
}
function updateContent() {
$(".toggle").each(function() {
var toggle_element = $(this);
toggle_element.show();
update(toggle_element);
if (toggle_element.hasClass('toggle-passive')) {
return;
}
toggle_element.off("click");
toggle_element.click(function() {
update(toggle_element, true);
});
});
//Activate multi toggles.
var targets = {};
$(".multi-toggle").each(function() {
var multi_toggle_element = $(this),
multi_toggle_buttons = multi_toggle_element.children(".multi-toggle-button"),
target = multi_toggle_element.data("target") || "default";
multi_toggle_element.show();
if (!targets.hasOwnProperty(target))
targets[target] = multi_toggle_element;
//Remove click event handlers from all multi toggle buttons
multi_toggle_buttons.off("click");
//Add click event handler for all multi toggle buttons to trigger multi_update with select action.
multi_toggle_buttons.click(function() {
multi_update(multi_toggle_element, $(this).data("state"));
});
});
//call multi-update once for each target to allow multiple controls
//without horrible lag
Object.keys(targets).forEach(function (key) {multi_update(targets[key])});
// .mw-collapsible togglers
$(".mw-collapsible-expand-all").each(function() {
var toggle_element = $(this);
toggle_element.off("click");
toggle_element.click(function() {
$(".mw-collapsible-toggle.mw-collapsible-toggle-collapsed").click();
});
});
$(".mw-collapsible-collapse-all").each(function() {
var toggle_element = $(this);
toggle_element.off("click");
toggle_element.click(function() {
$(".mw-collapsible-toggle:not(.mw-collapsible-toggle-collapsed)").click();
});
});
$(".mw-collapsible-toggle-all").each(function() {
var toggle_element = $(this);
toggle_element.off("click");
toggle_element.click(function() {
$(".mw-collapsible-toggle").click();
});
});
}
updateContent();
mw.hook("wikipage.content").add(updateContent);
});
}(mediaWiki, jQuery));