您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
This library provides the core functionality to add a stats badge onto your profile page and cache pages on geocaching.com.
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/389508/728988/GC%20Banner%20Stats%20Library.js
// ==UserScript== // @name GC Banner Stats Library // @namespace http://www.cryotest.com/ // @description This library provides the core functionality to add a stats badge onto your profile page and cache pages on geocaching.com. // @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html // @copyright 2019, Cryo99 // @include /^https?://www\.geocaching\.com/(account|my|default|geocache|profile|seek/cache_details|p)/ // @exclude /^https?://www\.geocaching\.com/(login|about|articles|myfriends|account/*)/ // @version 0.0.8 // @supportURL https://github.com/Cryo99/GCStatsBannerLib // @require https://openuserjs.org/src/libs/sizzle/GM_config.js // @grant GM_xmlhttpRequest // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // ==/UserScript== /*jshint esversion: 6 */ var gcStatsBanner = function(seriesName, seriesURL, seriesLevels = ['None'], seriesLevelDefault = 'None', elPrefix = '', callerVersion = '?'){ // Private members var _seriesLevels = seriesLevels, _seriesLevelDefault = seriesLevelDefault, _seriesName = seriesName, _elPrefix = elPrefix, _seriesURL = seriesURL, _callerVersion = callerVersion, /////////////////////////////////////////////// // Internal vars. _cacheName = document.getElementById("ctl00_ContentBody_CacheName"), // Images can be wider when level names are long. overflow: hidden; on <series>-container prevents images from overlaying the div border. _css = 'div.' + _elPrefix + '-container { border: 1px solid #b0b0b0; margin-top: 1.5em; padding: 0; text-align: center; overflow: hidden;} ' + '.WidgetBody div.' + _elPrefix + '-container { border: none; } ' + '#ctl00_ContentBody_ProfilePanel1_pnlProfile div.' + _elPrefix + '-container { border: none; text-align: inherit;} ' + 'a.' + _elPrefix + '-badge { background-color: white;} ' + '#ctl00_ContentBody_ProfilePanel1_pnlProfile div.' + _elPrefix + '-container {float: left}', _profileNameOld = document.getElementById("ctl00_ContentBody_ProfilePanel1_lblMemberName"), _profileName = document.getElementById("ctl00_ProfileHead_ProfileHeader_lblMemberName"), _userFieldOld = document.getElementsByClassName("li-user-info"), _userField = document.getElementsByClassName("user-name"); // Private methods function _getHiderName(){ var i, links = document.getElementsByTagName("a"), pos; if(links){ for(i = 0; i < links.length; i++){ pos = links[i].href.indexOf("/seek/nearest.aspx?u="); if(pos !== -1){ return decodeURIComponent(links[i].href.substr(pos + 21).replace(/\+/g, '%20')); } } } } function _parseNames(names){ // Filter out null or undefined entries, convert commas to semicolons, then convert to a comma-separated string. return encodeURIComponent(names .filter(function (n){ return n !== undefined; }) .map(function (n){ return (n + "").replace(/,/g, ";"); }) .join()); } function _getHtml(uname, brand){ return "<a class='" + _elPrefix + "-badge' href='https://" + _seriesURL + "' title='" + _seriesName + " stats.'><img src='https://" + _seriesURL + "/awards/find-badge.php?name=" + uname + "&brand=" + brand + "' /></a>"; } function _displayStats(stats, page, brand){ _getHtml(uname, brand) /////////////////////////// MOVE THIS DOWN? var widget = document.createElement("div"), html = "", i, target; for(i = 0; i < stats.length; i++){ var name = (stats[i].name + "") .replace(/;/g, ",") .replace(/'/g, "'") .replace(/"/g, """); if(i === 0 || stats[i].name !== stats[0].name){ html += _getHtml(name, brand); } } switch(page){ case "my": target = document.getElementById("ctl00_ContentBody_lnkProfile"); break; case "account": target = document.getElementsByClassName('sidebar-right')[0]; break; case "cache": target = document.getElementsByClassName('sidebar')[0]; break; case "profile": if(_profileName){ target = document.getElementById("ctl00_ContentBody_ProfilePanel1_lblProfile"); if (target) { target = target.parentNode; } }else if(_profileNameOld){ target = document.getElementById("HiddenProfileContent"); } break; } if(!target){ console.warn(_seriesName + " Stats: Aborted - couldn't find where to insert widget. You might not be logged in."); return; } if(html){ widget.className = _elPrefix + "-container"; widget.innerHTML = html; switch(page){ case "my": case "profile": target.parentNode.insertBefore(widget, target.nextSibling); break; default: target.insertBefore(widget, target.firstChild.nextSibling.nextSibling); break; } }else{ console.warn(_seriesName + " Stats: didn't generate an award badge."); } } function _createConfigDlg(){ // Register the menu item. GM_registerMenuCommand("Options", function(){ GM_config.open(); }, 'S'); var elName = elPrefix + '_branding'; GM_config.init({ 'id': elPrefix + '_config', // The id used for this instance of GM_config 'title': seriesName + ' Stats', // Panel Title 'fields': { // Fields object elName: { // This is the id of the field 'label': 'Branding', // Appears next to field 'type': 'select', // Makes this setting a dropdown 'options': _seriesLevels, // Possible choices 'default': 'Levels' // Default value if user doesn't change it } }, // Dialogue internal styles. 'css': '#' + _elPrefix + '_config {position: static !important; width: 75% !important; margin: 1.5em auto !important; border: 10 !important;} #afp_config_' + _elPrefix + '_branding_var {padding-top: 30px;}', 'events': { 'open': function(document, window, frame){ // iframe styles. frame.style.width = '300px'; frame.style.height = '250px'; frame.style.left = parent.document.body.clientWidth / 2 - 150 + 'px'; frame.style.borderWidth = '5px'; frame.style.borderStyle = 'ridge'; frame.style.borderColor = '#999999'; }, 'save': function(){ GM_setValue(elPrefix + '_branding', GM_config.get(elPrefix + '_branding')); location.reload(); // reload the page when configuration was changed } } }); } function _init(){ var currentPage, elCSS = document.createElement("style"), userName = "", userNames = [], stats = []; // Don't run on frames or iframes if(window.top !== window.self){ return false; } if(/\/my\//.test(location.pathname)){ // On a My Profile page currentPage = "my"; }else if(/\/account\//.test(location.pathname)){ // On a Profile page currentPage = "account"; }else{ if(_cacheName){ // On a Geocache page... var matcher = new RegExp(_seriesName, "i"); if(!matcher.test(_cacheName.innerHTML)){ // ...but not the right cache series. return; } currentPage = "cache"; }else{ currentPage = "profile"; } } // We're going to display so we can announce ourselves and prepare the configuration dialogue. console.info(_seriesName + " Stats V" + _callerVersion); console.info("GC Banner Stats library V" + GM_info.script.version); //CONFIG _createConfigDlg(); var brand = GM_getValue(elPrefix + '_branding', 'Levels'); console.info(seriesName + " Stats branding: " + brand); brand = brand.toLowerCase() // Get hider details. var hider; switch(currentPage){ case "profile": if(_profileName){ userNames = [_profileName.textContent.trim()]; }else if(_profileNameOld){ userNames = [_profileNameOld.textContent.trim()]; } break; default: if(_userField.length > 0){ userNames.push(_userField[0].innerHTML.trim()); } hider = _getHiderName(); if(typeof hider !== 'undefined'){ userNames.push(hider); } break; } for(var i = 0; i < userNames.length; i++){ stats[i] = {name: userNames[i]}; } userName = _parseNames(userNames); if(!userName){ console.error(seriesName + " Stats: Aborted - couldn't work out user name"); return; } // Inject widget styling elCSS.type = 'text/css'; if(elCSS.styleSheet){ elCSS.styleSheet.cssText = _css; }else{ elCSS.appendChild(document.createTextNode(_css)); } document.head.appendChild(elCSS); _displayStats(stats, currentPage, brand); } function _dump(){ console.log('>>>>', _seriesName); console.log('>>>>', _seriesURL); console.log('>>>>', _elPrefix); console.log('>>>>', _css); } //////////////////// PUBLIC //////////////////// return { // Public members dump: _dump, init: _init }; };