您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Optimize GayRomeo (and PlanetRomeo) pages
// ==UserScript== // @name GayRomeo Optimizer // @namespace http://marvinate.wordpress.com // @description Optimize GayRomeo (and PlanetRomeo) pages // @include http*://*.gayromeo.com/* // @include http*://*.planetromeo.com/* // @include http*://83.98.143.20/* // @grant GM_xmlhttpRequest // @version 1.4 // ==/UserScript== // Version 1.1 [2011-11-14] // [*] Changed internal system to use real objects instead of procedural stuff // // Version 1.1a [2011-11-23] // [*] Optimized JavaScript code - yes, back to procedural stuff... just shut up ;-) // // Version 1.2 [2012-01-14] // [+] Integrated callback to GR-Tools // // Version 1.2.1 [2012-02-01] // [*] Added GayRomeo IP address as default include // [*] Special handling for club pages (thanks to gymnazein) // // Version 1.2.1a [2012-02-02] // [*] Correct useof window.location instead of document.location // // Version 1.2.2 [2012-10-31] // [*] Small DOM adjustments (thanks to gymnazein) // // Version 1.3 [2012-11-24] // [*] Detect last page (thanks to djamana) // [*] Optimized generated DOM (thanks to djamana) // [*] Refactored internal logics // // Version 1.3a [2012-12-17] // [*] Small source code enhancements // // Version 1.4 [2013-02-10] // [*] Compatibility to latest GR-Tools // ----------------------------------------------------------------------------- // --- Search list enhancements ---------------------------------------------- // ----------------------------------------------------------------------------- if(window.location.href.indexOf("/search/index.php") > -1 || window.location.href.indexOf("/search/?") > -1) { // We're in a list page, which means that we can create the list optimizer // that is being used to alter the current pages content function GrListOptimizer() { var currentPageRegexArray = /.*?resultPage=(\d+)/.exec(window.location.href); this.currentPageIndex = currentPageRegexArray == null ? 1 : parseInt(currentPageRegexArray[1]); var lastPageLink = MV_getElementByPath("//table[@class='searchLayout']//tr[last()]/td[last()]/a[last()]"); this.lastPageIndex = lastPageLink == null ? -1 : parseInt(lastPageLink.innerHTML); var nextPageUrl = MV_getElementByPath("//body/table[2]/tbody/tr/td/a[last()]"); this.nextPageLink = nextPageUrl.getAttribute("href"); this.navigationTableElement = MV_getElementByPath("//body/table[2]"); } // Append the given element to the currently displayed content on the screen. // The content is always added before the pagination table GrListOptimizer.prototype.appendContent = function(pElement) { this.navigationTableElement.parentNode.insertBefore(pElement, this.navigationTableElement); } // Append the link to the next page (if there is a next page, otherwise, we'll // do nothing) GrListOptimizer.prototype.appendNextPageLink = function(pNextPageIndex) { var targetPageIndex = pNextPageIndex ? pNextPageIndex : this.currentPageIndex + 1; if(this.lastPageIndex > 1 && targetPageIndex <= this.lastPageIndex) { var thisOptimizer = this; var nextPageLink = MV_createElement("a", { style: "display: block; text-align: left; border: 1px solid #ffffff; padding: 5px 5px 5px 5px;", name: "gayromeooptimizer_" + targetPageIndex, href: "#gayromeooptimizer_" + targetPageIndex }, "Load next page (page " + targetPageIndex + ")..."); nextPageLink.addEventListener("click", function() { thisOptimizer.appendResultPage(nextPageLink, targetPageIndex); }, true); nextPageLink.addEventListener("mouseover", function() { thisOptimizer.appendResultPage(nextPageLink, targetPageIndex); }, true); this.appendContent(nextPageLink); } } // Load the content for the page with the specified index and append it to // the current page GrListOptimizer.prototype.appendResultPage = function(pSourceLinkElement, pPageIndex) { var loadingMessageDiv = MV_createElement("div", { style: "border: 1px solid #ffffff; padding: 5px 5px 5px 5px;" }, "Loading next page (page " + pPageIndex + ")..."); pSourceLinkElement.parentElement.insertBefore(loadingMessageDiv, pSourceLinkElement); pSourceLinkElement.parentElement.removeChild(pSourceLinkElement); var thisOptimizer = this; var thisPageParameterStart = window.location.href.indexOf("?"); var thisPageBaseUrl = thisPageParameterStart < 0 ? window.location.href : window.location.href.substring(0, thisPageParameterStart); var nextPageOriginalUrl = thisPageBaseUrl + this.nextPageLink; var nextPageMatchedArray = /(.*?)resultPage=\d+(.*)/.exec(nextPageOriginalUrl); var nextPageUrl = nextPageMatchedArray == null ? nextPageOriginalUrl : (nextPageMatchedArray[1] + "&resultPage=" + pPageIndex + nextPageMatchedArray[2]); MV_sendRequest({ url: nextPageUrl, xpath: "//body/table[1]", onComplete: function(pElement, pRequest, pResponse) { thisOptimizer.appendResultFromResponse(loadingMessageDiv, pElement, pRequest, pResponse); }, onError: function(pRequest, pResponse, pException) { thisOptimizer.appendResultFromError(loadingMessageDiv, pRequest, pResponse, pException); }, pageIndex: pPageIndex }); } GrListOptimizer.prototype.appendResultFromResponse = function(pLoadingElement, pElement, pRequest, pResponse) { // Replace the "loading" message with the title of the current page var nextPageTableHeader = MV_createElement("div", { style: "padding: 5px 5px 5px 5px; border: 1px solid #ffffff" }, "Result list (page " + pRequest.pageIndex + ")"); pLoadingElement.parentElement.insertBefore(nextPageTableHeader, pLoadingElement); pLoadingElement.parentElement.removeChild(pLoadingElement); // Append the content we've received for the next page this.appendContent(pElement); this.appendNextPageLink(pRequest.pageIndex + 1); // retrigger GRT-Tools if installed // (http://userscripts.org/scripts/show/33184) var grtEvent = document.createEvent('Event'); grtEvent.initEvent('GRT_RETRIGGER', false, false); document.dispatchEvent(grtEvent); } GrListOptimizer.prototype.appendResultFromError = function(pLoadingElement, pRequest, pResponse, pException) { var errorElement = MV_createElement("div", { style: "border: 1px solid red; padding: 5px 5px 5px; font-weight: bold;" }, "Cannot load page " + pRequest.pageIndex); if(pException != null) { errorElement.appendChild(document.createTextNode(" [" + pException + "]")) } var thisOptimizer = this; var retryLink = MV_createElement("a", null, "Retry loading page"); retryLink.addEventListener("click", function() { thisOptimizer.appendResultPage(errorElement, pRequest.pageIndex); }, true); errorElement.appendChild(document.createTextNode(" (")); errorElement.appendChild(retryLink); errorElement.appendChild(document.createTextNode(")")); pLoadingElement.parentElement.insertBefore(errorElement, pLoadingElement); pLoadingElement.parentElement.removeChild(pLoadingElement); } // Initialize the Optimizer var listOptimizer = new GrListOptimizer(); listOptimizer.appendNextPageLink(); } // ----------------------------------------------------------------------------- // --- Close a picture in a popup Window by clicking on it. ------------------- // ----------------------------------------------------------------------------- if(window.location.pathname.indexOf("/auswertung/pix/popup") > -1) { var imageElementsResult = document.evaluate("//img", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); for(var i = 0; i < imageElementsResult.snapshotLength; i++) { imageElementsResult.snapshotItem(i).addEventListener("click", function() { window.close(); }, false); } } // ----------------------------------------------------------------------------- // --- Includes -------------------------------------------------------------- // ----------------------------------------------------------------------------- // Include start [xmlhttpUtil.js] /** * Sends the request to the remote system and evaluates the response which * must be valid HTML and contain a specified element identifiable by an XPath * expression * * Expected properties in the request are: * url * the URL to which the request will be made * xpath * the XPath expression that must evaluate to an element that will be * extracted from the response received by the remote system * onComplete * a function that will be called when the result has been received and the * content should be displayed * onError * a function that will be called if the request cannot be sent or the * response received is invalid */ function MV_sendRequest(pRequest) { var processResponse = function(pResponse) { var responseHtmlStart = pResponse.responseText.indexOf("<html"); var responseHtmlEnd = pResponse.responseText.indexOf("</html>"); if(responseHtmlStart < 0 || responseHtmlEnd < 0) { pRequest.onError(pRequest, pResponse, "Invalid HTML document received"); } else { var responseHtmlElement = document.createElement("html"); responseHtmlElement.innerHTML = pResponse.responseText.substring(responseHtmlStart, responseHtmlEnd + "</html>".length); var responseXpathResult = document.evaluate(pRequest.xpath, responseHtmlElement, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); if(responseXpathResult.snapshotLength <= 0) { pRequest.onError(pRequest, pResponse, "Invalid HTML document received"); } else { pRequest.onComplete(responseXpathResult.snapshotItem(0), pRequest, pResponse); } } }; try { GM_xmlhttpRequest({ method: "GET", url: pRequest.url, onload: processResponse, onerror: function(pResponse) { pRequest.onError(pRequest, pResponse, null); } }); } catch(e) { pRequest.onError(pRequest, null, e); } } // Include end [xmlhttpUtil.js] // Include start [domUtil.js] function MV_removeElementsByPath(pPath) { var pathResult = document.evaluate(pPath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); if(pathResult.snapshotLength > 0) { for(var i=0; i < pathResult.snapshotLength; i++) { var pathNode = pathResult.snapshotItem(i); pathNode.parentNode.removeChild(pathNode); } } } function MV_getElementByPath(pPath, pRoot) { var pathResult = document.evaluate(pPath, pRoot == null ? document : pRoot, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); return pathResult.snapshotLength <= 0 ? null : pathResult.snapshotItem(0); } function MV_createButton(pAttributes, pClickListener) { pAttributes.type = "button"; var resultElement = MV_createElement("input", pAttributes); if(pClickListener != null) { resultElement.addEventListener("click", pClickListener, true); } return resultElement; } function MV_createElement(pElementName, pAttributes, pInnerHtml) { var resultElement = document.createElement(pElementName); for(attributeName in pAttributes) { resultElement.setAttribute(attributeName, pAttributes[attributeName]); } if(pInnerHtml != null) { resultElement.innerHTML = pInnerHtml; } return resultElement; } // Include end [domUtil.js]