您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds keyword highlight, category search, display options to Second Life Marketplace.
- // ==UserScript==
- // @name marketplace.secondlife.com tools
- // @description Adds keyword highlight, category search, display options to Second Life Marketplace.
- // @namespace http://sites.google.com/site/cerisesorbet/
- // @include http://marketplace.secondlife.com/*
- // @include https://marketplace.secondlife.com/*
- // @include https://betasearch-marketplace.secondlife.com/*
- // @version 20151111
- // @copyright (c) 2012-2015 Cerise Sorbet
- // @license MIT License
- // @grant none
- // ==/UserScript==
- function GetCookie(key) {
- var encKey = encodeURIComponent(key);
- var raw = document.cookie.split(/\s*;\s*/);
- for (var i = 0; i < raw.length; i++) {
- var pair = raw[i].split('=', 2);
- if (pair[0] == encKey && pair.length > 1)
- return decodeURIComponent(pair[1]);
- }
- return null;
- }
- function SetCookie(key, value) {
- document.cookie = encodeURIComponent(key) + '=' + encodeURIComponent(value)
- + ';path=/;expires=' + new Date(Date.now() + 31556926000).toUTCString();
- }
- // attributes is an {attr: value, ...} object
- function BuildTag(tagName, attributes) {
- var rv = document.createElement(tagName);
- for (var i in attributes)
- rv.setAttribute(i, attributes[i]);
- return rv;
- }
- // adapted from http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
- function GetParams(search) {
- var params = {};
- var segment = search.replace(/^\?/,'').split('&');
- var s;
- for (var i = 0; i < segment.length; i++) {
- if (!segment[i]) continue;
- s = segment[i].split('=');
- var sVal = s[1].split('+');
- for (var j = 0; j < sVal.length; j++)
- sVal[j] = decodeURIComponent(sVal[j]);
- params[decodeURIComponent(s[0])] = sVal.join(' ');
- }
- return params;
- }
- // fetch the keywords from the meta tags and display them inline
- function ShowKeywords() {
- var metaTags = document.getElementsByTagName('head')[0].getElementsByTagName('meta');
- var keywords = '<span style="color: #333333"><small>[no keywords]</small></span>';
- if (metaTags) {
- for (var i = metaTags.length - 1; i >= 0; i--) {
- if (metaTags[i].name == "keywords") {
- if (metaTags[i].content.length)
- keywords = '<span style="color: #cc6633" <b>Keywords:</b> ' + metaTags[i].content + '</span>';
- break;
- }
- }
- }
- var tabs = document.getElementById('product-tabs');
- if (tabs) {
- var kwDiv = document.createElement('div');
- kwDiv.className = 'span-6';
- kwDiv.innerHTML = keywords;
- tabs.parentNode.insertBefore(kwDiv, tabs);
- }
- }
- function SetupShowFeatured() {
- var featuredItems = document.getElementById('featured-items'); // main page
- if (!featuredItems)
- featuredItems = document.getElementById('featured-items-category'); // category page
- if (featuredItems) {
- var featHeading = featuredItems.getElementsByTagName('h2')[0];
- if (featHeading) {
- var showHideLink = document.createElement('span');
- showHideLink.innerHTML = '<button id="showFeatured"></button> ';
- featHeading.insertBefore(showHideLink, featHeading.firstChild);
- ShowFeatured(GetCookie('hideFeatured'), featuredItems);
- document.getElementById('showFeatured').addEventListener('click', function() { ShowFeatured('toggle', featuredItems); }, false);
- }
- }
- }
- function ShowFeatured(hideFeatured, featuredItems) {
- if (hideFeatured == 'toggle')
- hideFeatured = !(GetCookie('hideFeatured') == 'true');
- else
- hideFeatured = (hideFeatured == 'true');
- SetCookie('hideFeatured', hideFeatured ? 'true' : 'false');
- // find the featured items and show or hide them as requested
- var scrollable = document.getElementById('featured-items-scrollable');
- if (scrollable)
- scrollable.style.display = hideFeatured ? 'none' : '';
- var carousels = featuredItems.getElementsByTagName('div');
- for (var i = carousels.length - 1; i >= 0; i--) {
- if (carousels[i].className == 'carousel-controls') {
- var caroKids = carousels[i].childNodes;
- for (var j = 0; j < caroKids.length; j++) {
- if (caroKids[j].style)
- caroKids[j].style.display = hideFeatured ? 'none' : '';
- }
- }
- }
- // set the button text to match the show/hide state
- var showHideA = document.getElementById('showFeatured');
- if (showHideA) {
- showHideA.innerHTML = hideFeatured ? '+' : '-';
- showHideA.blur();
- }
- }
- function ForceResultsParams() {
- var wantRefresh = false;
- // if these values are strange there can be reload loops, so fix them.
- // It would be better to check these against live values in the sort header but those are not on all pages.
- var sortOrder = GetCookie('sortBy');
- if (!~['relevance_desc', 'created_at_desc', 'created_at_asc', 'price_asc', 'price_desc', 'name_asc', 'name_desc',
- 'prim_count_asc', 'prim_count_desc', 'average_rating_desc', 'sales_rank_asc'].indexOf(sortOrder))
- sortOrder = 'relevance_desc';
- SetCookie('sortBy', sortOrder); // refresh
- // If the link came from outside, display parameters could be the defaults.
- if (/^\/?products\/search$/.test(window.location.pathname) || /^\/?stores\/\d+$/.test(window.location.pathname)) {
- // XXX skipping this for now, some browsers do not like it.
- // var parsed = GetParams(window.location.search);
- // if (!parsed['search[sort]'])
- // parsed['search[sort]'] = 'relevance_desc';
- // if (parsed['search[sort]'] != sortOrder) {
- // parsed['search[sort]'] = sortOrder;
- // wantRefresh = true;
- // }
- if (wantRefresh) {
- var newSearch = '?';
- for (var key in parsed)
- newSearch += '&' + encodeURIComponent(key) + '=' + encodeURIComponent(parsed[key]);
- window.location.search = newSearch; // reload the page
- }
- }
- // fix up the search form
- var searchForm = document.getElementById('search');
- if (searchForm) {
- var forms = searchForm.getElementsByTagName('form');
- var newLink = document.createElement('a');
- for (var i = 0; i < forms.length; i++) {
- newLink.href = forms[i].action;
- if (/^\/?products\/search$/.test(newLink.pathname))
- forms[i].appendChild(BuildTag('input', {type: 'hidden', name: 'search[sort]', value: sortOrder}));
- break;
- }
- }
- matureCookie = (GetCookie('overrideMature') == 'true');
- // change all search and store links to saved items per page
- var tags, i;
- tags = document.getElementsByTagName('a');
- for (i = 0; i < tags.length; i++) {
- if (window.location.hostname != tags[i].hostname) continue;
- if (/^\/?products\/search$/.test(tags[i].pathname) || /^\/?stores\/\d+$/.test(tags[i].pathname)) {
- var parsed = GetParams(tags[i].search);
- parsed['search[sort]'] = sortOrder;
- tags[i].search = '?';
- for (var key in parsed)
- tags[i].search += '&' + encodeURIComponent(key) + '=' + encodeURIComponent(parsed[key]);
- }
- }
- // SLM bugfix: for the category sidebar links, make sure they go to page 1.
- var searchCat = document.getElementById('search-category');
- if (searchCat) {
- tags = searchCat.getElementsByTagName('a');
- for (i = 0; i < tags.length; i++) {
- if (window.location.hostname != tags[i].hostname) continue;
- if (/^\/?products\/search$/.test(tags[i].pathname)) {
- var parsed = GetParams(tags[i].search);
- parsed['search[page]'] = '1';
- tags[i].search = '?';
- for (var key in parsed)
- tags[i].search += '&' + encodeURIComponent(key) + '=' + encodeURIComponent(parsed[key]);
- }
- }
- }
- }
- function SaveResultsParam() {
- var selectVal;
- if (/(^|\s)sort-by(\s|$)/.test(this.className)) {
- selectVal = document.getElementById('search_sort_id');
- if (selectVal)
- SetCookie('sortBy', selectVal.options[selectVal.selectedIndex].value);
- }
- else
- return;
- }
- function SetupSearchEventListeners() {
- var i;
- var container = document.getElementById('search-results-container');
- if (!container)
- return;
- var tags = container.getElementsByTagName('span');
- if (tags) {
- for (i = 0; i < tags.length; i++) {
- if (tags[i].className && /(^|\s)sort-by(\s|$)/.test(tags[i].className)) {
- tags[i].addEventListener('change', SaveResultsParam, false);
- break;
- }
- }
- }
- }
- // Add "search in this category"
- function AddCurrentCategory() {
- var thisCatText = "This category"; // no I18N, but better than hovercfrafts full of eels.
- var currentCat = '1'; // all categories
- var parsed;
- var catDrop = document.getElementById('top_search_category_id');
- if (!catDrop)
- return;
- parsed = GetParams(window.location.search);
- if (parsed['search[category_id]']) {
- currentCat = parsed['search[category_id]'];
- // try to find the cat
- var catTags = document.getElementsByClassName('current-category');
- if (catTags.length) {
- if (catTags[0].nodeName == 'SPAN')
- thisCatText = catTags[0].innerHTML;
- }
- }
- else {
- var breadcrumb = document.getElementById('breadcrumb');
- if (breadcrumb) {
- var tags = breadcrumb.getElementsByTagName('a');
- if (tags.length) {
- parsed = GetParams(tags[tags.length - 1].search);
- if (parsed['search[category_id]']) {
- currentCat = parsed['search[category_id]'];
- thisCatText = tags[tags.length - 1].innerHTML;
- }
- }
- }
- }
- if (currentCat != '1') { // no need to add if category is All
- // Add it to the search form if it is not there, else activate it
- var newOption = document.createElement('option');
- newOption.value = parsed['search[category_id]'];
- newOption.innerHTML = thisCatText;
- catDrop.insertBefore(newOption, catDrop.firstChild);
- catDrop.selectedIndex = 0;
- }
- // try to get a current store too
- var storeID = null;
- var mat;
- mat = window.location.pathname.match(/^\/?stores\/\d+$/); // from our custom search
- if (mat) {
- storeID = mat[0].split('/').pop();
- }
- else if (parsed['search[store_id]']) { // standard store page
- storeID = parsed['search[store_id]'];
- }
- else { // try on product pages
- var merchBox = document.getElementById('merchant-box');
- if (merchBox) {
- var merchLinks = merchBox.getElementsByTagName('a');
- if (merchLinks.length) {
- mat = merchLinks[0].pathname.match(/^\/?stores\/\d+$/);
- if (mat)
- storeID = mat[0].split('/').pop();
- }
- }
- }
- }
- SetupSearchEventListeners();
- ForceResultsParams();
- AddCurrentCategory();
- ShowKeywords();
- SetupShowFeatured();