在PSN管理网页上搜索和隐藏游戏
// ==UserScript==
// @name Hide Your Games on PSN
// @name:zh-CN 隐藏PSN游戏
// @namespace http://tampermonkey.net/
// @version 0.2
// @description Search and hide games on PSN management site
// @description:zh-CN 在PSN管理网页上搜索和隐藏游戏
// @author Nathaniel Wu
// @include *id.sonyentertainmentnetwork.com/*
// @license Apache-2.0
// @grant GM_addStyle
// @supportURL https://github.com/Nathaniel-Wu/userscript-hide-psn-games/issues
// ==/UserScript==
(function () {
'use strict';
const text_tags = {
text_search: 0,
regex_search: 1,
cancel: 2,
game_found: 3,
total_games_found: 4,
game_classifier: 5,
new_games_ready_to_be_hidden: 6,
save_reminder: 7
}
const localization = {
"zh-Hans": ['文本搜索', '正则表达式搜索', '取消', '游戏已找到:', '共找到:', '款', '可供隐藏的新游戏:', '点击保存按钮隐藏'],
"zh-Hant": ['文本搜索', '正則表達式搜索', '取消', '遊戲已找到:', '共找到:', '款', '可供隱藏的新遊戲:', '點擊保存按鈕隱藏'],
"en-US": ['Text Search', 'RegEx Search', 'Cancel', 'Game Found: ', 'Total Game(s) Found: ', '', 'New Games(s) Ready To Be Hidden: ', 'Click the Save button to hide the game(s)']
};
function localized_text(text_tag) {
let site_lang = document.documentElement.lang;
let lang = localization.hasOwnProperty(site_lang) ? site_lang : "en-US";
return localization[lang][text_tag];
}
function repeat_until_successful(function_ptr, interval) {
if (!function_ptr())
setTimeout(() => {
repeat_until_successful(function_ptr, interval);
}, interval);
}
function search_and_hide_game(pattern) {
let regex_search = typeof (pattern) === 'object';
let lower_case_pattern = null;
if (!regex_search)
lower_case_pattern = pattern.toLowerCase();
let game_titles = [];
let new_games_ready_to_be_hidden = 0;
repeat_until_successful(() => {
let found = false;
let load_more_button_container_candidates = Array.prototype.slice.call(document.querySelectorAll('div.columns-center.fitting-width, ul#ps4-games-list'));
let UL_index = load_more_button_container_candidates.findIndex((e) => e.tagName === 'UL');
let game_elements = load_more_button_container_candidates[UL_index].querySelectorAll('.pdr-list-column.main-text.ps4-game-name-text.text-selectionitem');
game_elements.forEach((e) => {
if (e === game_elements[game_elements.length - 1] && !found)
e.scrollIntoView();
if (regex_search) {
if (!Boolean(e.innerHTML.match(pattern)))
return;
} else {
if (!Boolean(e.innerHTML.toLowerCase().match(lower_case_pattern)))
return;
}
found = true;
let parent = e;
while (parent.classList.length != 2 || (!parent.classList.contains('pdr-list-item')) || ((!parent.classList.contains('gamelist-check-on')) && (!parent.classList.contains('gamelist-check-off'))))
parent = parent.parentElement;
let not_checked_before;
if (not_checked_before = parent.classList.contains('gamelist-check-off')) {
parent.querySelector('.pdr-list-item.inner-list-item.list-thumbnail.check-box-item.game-list').click();
new_games_ready_to_be_hidden++;
}
let game_title = e.innerText;
if (game_titles.indexOf(game_title) < 0) {
game_titles.push(game_title);
console.log(`${localized_text(text_tags.game_found)}${game_title}${not_checked_before ? '✅' : ''}`);
e.scrollIntoView();
}
});
if (UL_index != load_more_button_container_candidates.length - 1) {
load_more_button_container_candidates[UL_index + 1].querySelector('button.secondary-button.row-button.text-button').click();
return false;
} else {
let alert_message = `${localized_text(text_tags.total_games_found)}${game_titles.length}${localized_text(text_tags.game_classifier)}
${localized_text(text_tags.new_games_ready_to_be_hidden)}${new_games_ready_to_be_hidden}${localized_text(text_tags.game_classifier)}
${localized_text(text_tags.save_reminder)}`
console.log(alert_message);
alert(alert_message);
return true;
}
}, 3500 + Math.random() * 1000);
}
window.addEventListener('popstate', () => {
if (Boolean(window.location.href.match(/privacy_settings\/group\/games\/hidden_games/))) {
const search_menu = document.createElement('div');
search_menu.id = 'search_menu';
search_menu.innerHTML = `
<div class="columns-center">
<form>
<input type="text" id="search_pattern" value="">
<div data-components="pdr-button" class="column-flex button ember-view">
<button id="text_search_button" tabindex="0" class="primary-button row-button text-button">
<span dir="ltr" class="caption">${localized_text(text_tags.text_search)}</span>
</button>
</div>
<div data-components="pdr-button" class="column-flex button ember-view">
<button id="regex_search_button" tabindex="0" class="primary-button row-button text-button">
<span dir="ltr" class="caption">${localized_text(text_tags.regex_search)}</span>
</button>
</div>
<div data-components="pdr-button" class="column-flex button ember-view">
<button id="cancel_button" tabindex="0" class="secondary-button row-button text-button">
<span dir="ltr" class="caption">${localized_text(text_tags.cancel)}</span>
</button>
</div>
</form>
</div>
`;
document.querySelector('body').appendChild(search_menu);
document.querySelector('#text_search_button').onclick = () => {
let pattern = document.querySelector('#search_pattern').value;
setTimeout(() => search_and_hide_game(pattern), 200);
search_menu.remove();
};
document.querySelector('#regex_search_button').onclick = () => {
let pattern = new RegExp(document.querySelector('#search_pattern').value);
setTimeout(() => search_and_hide_game(pattern), 200);
search_menu.remove();
};
document.querySelector('#cancel_button').onclick = () => {
search_menu.remove();
};
GM_addStyle(`
#search_menu {
position: absolute;
display: block;
padding: 10px;
background: #f0f0f0;
z-index: 999;
left: 50%;
top: 50%;
margin-left: -97px;
margin-top: -80px;
}
`);
}
});
})();