[ Disclaimer, Create new user --- Wiki markup help, Install P99 ]
MediaWiki:LocMaps.js
From Project 1999 Wiki
Note: After saving, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Clear the cache in Tools → Preferences
/* Any JavaScript here will be loaded for all users on every page load. */ importScript('MediaWiki:Polyfills.js'); importScript('MediaWiki:Zones.js'); /* p1999wiki.js * written by http://wiki.project1999.com/User:Ravhin * last update: 7 January, 2018 by Loramin */ $(function() { var hideDelay = 0; var trigDelay = 250; var hideTimer = null; var ajax = null; var currentPosition = { left: '0px', top: '0px' }; // One instance that's reused to show info for the current person var container = $('<div id="itemHoverContainer">' + '<div id="HoverContent"></div>' + '</div>'); $('body').append(container); /* --- hoverbox for item/mob, currently only used in magelo --- */ // Determine which "a" elements should trigger the item stats mouseover var $mouseoverTargets = $('span.ih a'); var isItemCategory = document.title.startsWith('Category:') && document.title.includes('Equipment - Project 1999 Wiki') && !document.title.includes('Worshiper Equipment'); if (isItemCategory) { // Include the category's item list along with ".ih" links $mouseoverTargets = $mouseoverTargets.add('.mw-content-ltr a'); } $mouseoverTargets = $mouseoverTargets.filter(function(i, a) { // Don't add hover to links like "next 200" return !$(a).attr('href').startsWith('/Special:') && !$(a).attr('href').includes('title=Category:') }); $mouseoverTargets.on('mouseover', function() { var $this = $(this); var itemname = $this.attr('title'); if (itemname == '' || itemname == 'undefined') return; if (hideTimer) clearTimeout(hideTimer); if ($this.parents('div.mw-content-ltr').length) { var pos = $this.offset(); var width = $this.width(); container.css({ left: pos.left + 5 + 'px', top: pos.top + 5 + 'px' }); } $(this).trigger('mousemove'); $('#itemHoverContent').html(' '); //$('#itemHoverContent').html('<div class="itemtopbg"><div class="itemtitle">Loading...</div></div>' // + '<div class="itembg" style="min-height:50px;"><div class="itemdata">' // + '<div class="itemicon" style="float:right;"><img alt="" src="/images/Ajax_loader.gif" border="0"></div>' // + '<p></p></div></div><div class="itembotbg"></div>'); if (ajax) { ajax.abort(); ajax = null; } ajax = $.ajax({ url: window.location.protocol + '//wiki.project1999.com/index.php/Special:AjaxHoverHelper/' + itemname, cacheResponse: true, success: function(html) { var $html = $(html); $('#itemHoverContent').html($html[2]).prepend($html[0]).prepend($html[1]); } }); container.css('display', 'block'); //container.fadeIn('fast'); }); //on mouseover $('span.ih a').on('mouseout', function() { if (hideTimer) clearTimeout(hideTimer); hideTimer = setTimeout(function() { container.css('display', 'none'); //container.fadeOut('fast'); }, hideDelay); }); $('span.ih a').mousemove(function(e){ var mousex = e.pageX + 20; //Get X coodrinates var mousey = e.pageY + 20; //Get Y coordinates var tipWidth = container.width(); //Find width of tooltip var tipHeight = container.height(); //Find height of tooltip //Distance of element from the right edge of viewport var tipVisX = $(window).width() - (mousex + tipWidth); //Distance of element from the bottom of viewport var tipVisY = $(window).height() - (mousey + tipHeight); if ( tipVisX < 20 ) { //If tooltip exceeds the X coordinate of viewport if( tipWidth > e.pageX - 20 ){ mousex = 0; } else { mousex = e.pageX - tipWidth - 20; } } if ( tipVisY < 20 ) { //If tooltip exceeds the Y coordinate of viewport mousey = e.pageY - tipHeight - 20; } container.css({ top: mousey, left: mousex }); }); // Allow mouse over of details without hiding details $('#itemHoverContainer').mouseover(function() { if (hideTimer) clearTimeout(hideTimer); }); // Hide after mouseout $('#itemHoverContainer').mouseout(function() { if (hideTimer) clearTimeout(hideTimer); hideTimer = setTimeout(function() { container.css('display', 'none'); //container.fadeOut('fast'); }, hideDelay); }); // magelo non-ajax item hover, but move box with mouse $('.magelohb').mousemove(function(e){ var childContainer = $(this).children('span.hb'); var tipWidth = childContainer.width(); //Find width of tooltip var tipHeight = childContainer.height(); //Find height of tooltip var mousex = e.pageX + 20; //Get X coodrinates var mousey = e.pageY + 20; //Get Y coordinates //Distance of element from the right edge of viewport var tipVisX = $(window).width() - (mousex + tipWidth - 20); //Distance of element from the bottom of viewport var tipVisY = $(window).height() - (mousey + tipHeight - 20); if ( tipVisX < 20 ) { //If tooltip exceeds the X coordinate of viewport if( tipWidth > e.pageX - 20){ mousex = 0; } else { mousex = e.pageX - tipWidth - 20; } } if ( tipVisY < 20 ) { //If tooltip exceeds the Y coordinate of viewport mousey = e.pageY - tipHeight - 20; } childContainer.css({ top: mousey, left: mousex, 'z-index':'999' }); }); // change to position:fixed on all hover divs if we have JS active // otherwise leave as position:absolute so the stationary hovers are near their items $('.magelohb span.hb').each(function(i) { $(this).css({'position':'fixed'}); }); // Chrome no longer displays alt text when an image is hovered over. However the wiki only has // alt attributes for images, not titles. This fixes that by converting alt => title $('img[alt]').each(function (i, img) { $(img).attr('title', $(img).attr('alt')); }); // Fashion for item pages var extractFashionHtml = function(html) { return $(html).find('.fashion_show, .primary_secondary_show').map(function(i, el) { var $el = $(el); var data = $el.data(); data.race = $el.find('.fashion_race').html(); if ($el.is('.fashion_show')) { data.armor = $el.find('.fashion_armor').html(); } return data; }).toArray(); }; var getFashionShows = function(fashionCategory) { var url = 'http://wiki.project1999.com/Category:Fashion: ' + fashionCategory; return $.get(url).then(extractFashionHtml); }; var getItemPageShows = function() { var fashionCategories = $('#catlinks li a') .map(function(i, a) { return $(a).text(); }) .filter(function(i, text) { return text.startsWith('Fashion:'); }) .map(function(i, text) { return text.substr('Fashion: '.length); }); var fashion = fashionCategories[0]; if (!fashion) return $.when(); var tint = fashionCategories[1]; return getFashionShows(fashion).then(function(shows) { var sameTint = []; var otherTint = []; shows.forEach(function(show) { // Primary/secondary slots have no tint if (show.primaryFashion || show.secondaryFashion) sameTint.push(show); else (show.tint === tint ? sameTint : otherTint).push(show); }); return { matches: sameTint, otherTint: otherTint, fashion: fashion, tint: tint }; }); } var addFashionSection = function() { getItemPageShows().then(function(pageShows) { if(!pageShows || !pageShows.matches) return; // Build fashion section var lis = pageShows.matches.map(function(show) { return '<li class="fashion-link" data-file="' + show.file +'">' + '<a href="#">' + show.gender + ' ' + show.race + '</a></li>'; }); var $ul = $('<ul>').append(lis); var $div = $('<div><h2>Fashion/Appearance</h2></div>').append($ul); // Not sure why we have two IDs: two different item templates? $('#Drop_looted_from, #Drops_From').parent().before($div); }); }; addFashionSection(); //***************************************** // Add class-based filtering to item tables //*****************************************w // Determine whether or not a provided row should be shown for the provided // class abbreviation (eg. "BRD") var isRowShown = function($tr, classAbbrev) { // Extract classes (and races) var classText = $tr.find('td').eq(3).text().split('Class:')[1]; if (!classText) return true; // Ignore (don't filter) rows without class text // remove "Race: " part (if any) and upper-case text classText = classText.split('Race:')[0] || classText; classText = classText.toUpperCase(); // determine matching text var isMatch = classText.includes(classAbbrev); var isAllMatch = classText.includes('ALL'); var isExcept = classText.includes('ALL EXCEPT'); // determine matches if (isMatch && !isExcept) return true; // (eg. BRD in "BRD") if (!isMatch && isExcept) return true; // (eg. BRD in "ALL EXCEPT WIZ") if (!isExcept && isAllMatch) return true; // (eg. BRD in "ALL") return false; }; var scrollToTable = function($table) { window.setTimeout(function() { $('html, body').animate({ scrollTop: ($table.offset().top) }, 200); }, 100); }; // Filter the provided table to only display rows for the provided class // abbreviation var filterTable = function($table, classAbbrev) { $table.find('tr').each(function (i, tr) { var $tr = $(tr); var rowIsShown = isRowShown($tr, classAbbrev); $tr.toggle(rowIsShown); }); scrollToTable($table); addFilterLink($table, false); $('.itemsUnfilterLink').click(function() { unfilterTable($table); }); alert('Filtered to only show rows containing ' + classAbbrev + ' gear.'); }; // Restore a table to its previous, un-filtered state var unfilterTable = function($table) { $table.find('tr').show(); addFilterLink($table, true); scrollToTable($table); }; // When a user clicks on a table class filter link, handle it by asking them // which class (and then filtering the table for that class) var handleItemFilterLinkClick = function(e) { var promptMessage = 'Please enter the three-letter abbreviation for the ' + 'class you want to filter by (eg. "brd" for "Bard").'; var $table = $(e.target).closest('table'); var classAbbrev = prompt(promptMessage).toUpperCase(); if (!classAbbrev || classAbbrev.length !== 3 || classAbbrev === 'ALL') { alert('A 3-digit abbreviation wasn\'t entered (or "All" was entered); ' + 'filtering disabled'); unfilterTable($table); return false; } filterTable($table, classAbbrev); }; // Adds either a filter or unfilter link (as determined by showFilter) to the // provided table var addFilterLink = function($table, showFilter) { var $statsHeaderCells = $table.find('th:contains("Stats")'); var filterType = showFilter ? 'Filter' : 'Unfilter'; $statsHeaderCells.html('Stats <span style="float:right">' + '<a style="text-decoration: underline" class="items' + filterType + 'Link" href="#">' + filterType + (showFilter ? ' by Class' : '') + '</a></span>'); var $link = $statsHeaderCells.find('.items' + filterType + 'Link'); if (showFilter) $link.click(handleItemFilterLinkClick); else $link.click(function() { unfilterTable($table); }) }; // Add class filtering links to all item tables var addItemFilteringLinks = function() { var $tables = $('table th:contains("Item Name")').closest('table'); $tables.each(function(i, table) { var $table = $(table); // Make sure it has both "Item Name" and "Stats" columns if (!$table.has('th:contains("Stats")')) return; addFilterLink($table, true); }); }; addItemFilteringLinks(); //***************************************** // End class-based filtering to item tables //***************************************** // Add No-Drop-Based filtering to the class equipment pages if (window.location.pathname.includes('Special:ClassSlotEquip')) { // Add checkboxes UI to the page $('table') .before('<label><input id="showNoDrop" type="checkbox" checked/> Show No Drop</label> ' + '<label><input id="showDroppable" type="checkbox" checked/> Show Droppable</label>'); // Handle when either box is checked $('#showNoDrop, #showDroppable').change(function() { var showNoDrop = $('#showNoDrop').is(':checked'); var showDroppable = $('#showDroppable').is(':checked'); // NOTE: Some tables are weird and don't keep their TRs in THEAD // .... but those rows do have an old bgcolor="#cccccc" attribute // that we can use to identify (and not hide) them $('tbody tr[bgcolor!=#cccccc]').each(function(i, el) { var text = $(el).find('td:eq(0) .itemdata').text(); var isNoDrop = text.includes('NO DROP'); $(el).toggle((showNoDrop && isNoDrop) || (showDroppable && !isNoDrop)); }); }); } // Generic Table Filtering (for Template:TableFilterCheckbox) $('.table-filter-checkbox-container').each(function(i, el) { var $container = $(el); var matchSelector = $container.data('match'); var text = $container.text(); $container.html('<label><input class="table-filter-checkbox" type="checkbox" ' + 'value="' + matchSelector + '" checked />' + text + '</label>'); }); var shouldRowBeShown = function(tr) { var $tr = $(tr); // Check all the checkboxes to see if any given row should appear // TODO: Instead of checking *every* checkbox, check ones in the same .filter-group return $('.table-filter-checkbox') .toArray() .reduce(function(isShown, checkbox) { var matchSelector = $(checkbox).val(); var matches = $tr.is(matchSelector) || !!$tr.has(matchSelector).length; var isChecked = $(checkbox).attr('checked'); return isShown && !!(isChecked || (!isChecked && !matches)); }, true); } $('body').on('change', '.table-filter-checkbox', function(e) { $('table').show(); $('table:not(.toc) tbody tr:not([bgcolor="#cccccc"])').each(function(i, tr) { $(tr).toggle(shouldRowBeShown(tr)); }); // If all of a table's non-header rows are hidden, hide it $('table').filter(function(i, table) { return !$(table).has('tr:visible:not([bgcolor="#cccccc"])').length; }).hide(); }); importScript('MediaWiki:CheckboxLists.js'); importScript('MediaWiki:LocMaps.js'); var fullTitle = $('title').text(); var title = fullTitle.substr(0, fullTitle.length - ' - Project 1999 Wiki'.length); switch(title) { // Give the Per-Level Hunting Guide Page its own JS case 'Per-Level Hunting Guide': importScript('MediaWiki:HuntingGuide.js'); break; // The item category search also needs special JS case 'Item Category Search': importScript('MediaWiki:ItemCategorySearch.js'); break; // So does the Solo Artist Challenge case 'Solo Artist Challenge': importScript('MediaWiki:SoloArtistChallenge.js'); break; case 'Treasure Hunting Guide': importScript('MediaWiki:TreasureHuntingGuide.js'); break; case 'Buff Lines': importScript('MediaWiki:BuffLines.js'); break; case 'FashionQuest Finder': importScript('MediaWiki:FashionQuest.js'); break; case 'Mobs By Level': // Basic DOM manipulation (since the wiki won't let us add <input> tags in the wiki text $('#placeholder') .replaceWith( '<form id="form">' + 'Class: <input id="class" style="width: 8em" value="Warrior" /> ' + 'Level: <input id="level" style="width: 4em" /> ' + '<input type="submit"/>' + '</form>' ); $('#form').submit(function() { var clazz = $('#class').val(); var level = $('#level').val(); window.location = 'https://wiki.project1999.com/index.php?title=Special:Search&limit=500&offset=0&redirs=0&profile=default&search=%22Level%5C%3A%5C+' + level + '%22+-%22Shopkeeper%22+-%22Merchant%22+%22Class%5C%3A%5C+'+ clazz + '%22+-"startMageloProfile"'; return false; }); break; } // Warn users who accidentally try to edit a templated section if ((window.location + '').includes('title=Template:Namedmobpage&action=edit')) { alert('Warning: You are attempting you edit the template for all named mobs. You probably didn\'t mean to do that: you probably clicked on an edit link somewhere in the page and wound up here. To avoid this simply go back and use the edit *tab* at the top of the page instead.'); } // Warn uses who try to edit a mostly-transcluded section (and offer to take them to the transcluded page) var text = $('#wpTextbox1').val(); var match = text && text.match(/\{\{\#lsth\:(.*?)\|\[\[(.*?)\]\]\}\}/); if (match) { var pageName = match[1]; var section = match[2]; var isEdit = (window.location + '').includes('action=edit'); var isUnderTenLines = $('#wpTextbox1').val().split('\n').length < 10; var url = '/' + pageName + '#' + section; var message = 'This page uses "transclusion" to show part of another page, specifically the code:\n\n {{#lsth:' + pageName + '|[[' + section + ']]}}\n\nIf you want to edit the transcluded section, click "Ok": you will be taken to that page.' + ' If you want to stay on this page, click "Cancel".'; if (isEdit && isUnderTenLines && confirm(message)) location = url; } // Add links to search the forum for items to their auction tracker const forumSearchUrl = 'https://www.project1999.com/forums/search.php?do=process&forumchoice[]=27&query=%22' + $('#firstHeading').text() + '%22'; $('.auctrackerbox span span:contains("Project 1999 Auction Tracker")') .append( '<a ' + 'style="font-size: 0.5em; float: right" '+ 'target="_new" ' + 'href="' + forumSearchUrl + '"' + '>Search Forum</a>'); });