AO3: just my languages

Reduce language options to your preferences

2025-02-10 일자. 최신 버전을 확인하세요.

질문, 리뷰하거나, 이 스크립트를 신고하세요.
// ==UserScript==
// @name         AO3: just my languages
// @namespace    https://greasyfork.org/en/users/757649-certifieddiplodocus
// @version      1.1.1
// @description  Reduce language options to your preferences
// @author       CertifiedDiplodocus
// @require      http://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js
// @match        http*://archiveofourown.org/*
// @exclude      /^https?:\/\/archiveofourown\.org\/(?!((bookmarks|works).(search|work_search|bookmark_search))|((users|tags)\/.*\/(works|bookmarks)))/
// @icon         data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>𒈾</text></svg>
// @grant        GM_addStyle
// @license      GPL-3.0-or-later
// ==/UserScript==

/* eslint-env jquery */ //           allows jQuery

/* PURPOSE: Simplify language search options on AO3. Choose any combination of the following:
    1 - Show only your chosen languages in the dropdown list
    2 - Bold some languages in the dropdown (can be chosen independently from option 1)
    3 - Autofill:
            - Monolingual: automatically set the dropdown to your preferred language
            - Multilingual: add a query to each search to show fic in multiple languages at once (e.g. English AND Spanish AND Thai)
    4 - Manual multilingual search: click the 𒈾 button to add/remove multilingual filters. Also works with autofill.
----------------------------------------------------------------------------------------------------------------------
*/

(function() {
    'use strict';
    let index = 0

    /* ================================= USER SETTINGS (save to text file in case of script updates) =================================

    LANGUAGE CODES are listed at the end of this script. (AO3 appears to use a mix of 2 and 3-character codes.)
    Leave blank for the AO3 default appearance.*/

    let myLanguages = ['en', 'es', 'fr', 'ptBR', 'ptPT', 'sux'] //    <- dropdown will show only these
    let boldedLanguages = ['en', 'es', 'fr']

    /* OPTIONAL: autofill new searches to your chosen language(s). Filters can still be changed by hand.
    This carries a small risk of hiding mistagged fics, so is disabled by default (searchMode = 0).
        0 - AO3 default (blank dropdown)
        1 - MONOLINGUAL autofill (fills the dropdown with your preferred language)
        2 - MULTILINGUAL autofill (adds a search query to show fic in all your preferred languages at once)
               * note: may be slower / have more impact on the servers. If noticeable, try reducing the number of languages. */
    let searchMode = 0
    let defaultLanguage = 'es'
    let multiLanguages = ['ptBR', 'ptPT', 'sux']

    // ===============================================================================================================================

    // Set filter for searching multiple languages. (If user didn't fill in multiLanguages, use myLanguages instead.)
    let languageFilters = 'language_id:' + (multiLanguages || myLanguages).join(' OR language_id:');

    // select the elements depending on the page
    let dropdown, searchbox
    if (window.location.href.includes('/bookmarks')) {
        dropdown = $('#bookmark_search_language_id')
        searchbox = $('#bookmark_search_bookmarkable_query')
    } else {
        dropdown = $('#work_search_language_id')
        searchbox = $('#work_search_query')
    }

    // show only my languages (and the default 'blank' value) in the dropdown
    if (myLanguages.some(Boolean)) {
        dropdown.children().hide()
        dropdown.children('[value=""]').show()
        for (index = 0; index < myLanguages.length; ++index) {
            dropdown.children(`[value="${myLanguages[index]}"]`).show();
        }
    }

    // bold languages in the dropdown
    for (index = 0; index < boldedLanguages.length; ++index) {
        dropdown.children(`[value="${boldedLanguages[index]}"]`).css('font-weight','bold');
    }

    /* Autofill (if the dropdown/searchbox are blank)
        1 - MONOLINGUAL AUTOFILL: set dropdown to the default language.
        2 - MULTILINGUAL AUTOFILL: insert search string into "Search within results / Any field": "language_id:egy OR language_id:sux"   */

    switch (searchMode) {
        case 1: if (!dropdown.val()) {
            dropdown.children(`[value="${defaultLanguage}"]`).attr('selected','selected')
        }
            break;
        case 2: if ($.trim(searchbox.val()).length == 0) {
            searchbox.val(languageFilters)
        }
    }

    // Add (𒈾) button for multilingual searches next to "Languages" label. When a multilingual filter has been applied, (𒈾) is green.
    let dropdownLabel = dropdown.parent().prev()
    let babelButton = $(`<a class="question" title="Search multiple languages:&#10;${multiLanguages.join(', ')}">
    <span class="symbol question babel-button">&#74302;</span></a>`)
    dropdownLabel.append(babelButton)

    // Conditional CSS: alignment + colour
    // align the 𒈾 normally except on search pages, where it should use the default page style to match the neighbouring "?"
    babelButton.children().first().toggleClass('babel-normal-align', !window.location.href.includes('/search'))
    showIfBabelOn()
    searchbox.on('change', showIfBabelOn)

    // On click of (𒈾), add OR remove language filters from the "all fields" searchbox (after the current query)
    babelButton.click(function(){
        let searchboxContent = $.trim(searchbox.val())
        if (searchboxContent.length == 0) {
            searchbox.val(languageFilters)
        } else if (!searchboxContent.includes(languageFilters)) {
            searchbox.val(searchboxContent + ' ' + languageFilters) // toggle on
        } else {
            searchbox.val(searchboxContent.replace(languageFilters,'').trim()) // toggle off
        }
        searchbox.trigger('change')
    })

    // Colour 𒈾 green as long as the search box contains the filter (check with different site skins)
    function showIfBabelOn() {
        babelButton.children().first().toggleClass('babel-button-filter-on', searchbox.val().includes(languageFilters))
        babelButton.attr('title',`Searching multiple languages:\n${multiLanguages.join(', ')}`) // use \n not &#10; in javascript
    }

    //--- Style newly-added button in CSS.
    // SPECIFICITY hierarchy: inline > #id > .class > attribute (e.g '[type="text"]') > element (e.g 'p'). Remember: p.class > .class

    GM_addStyle ( `
    .babel-button {
        cursor:copy;
    }
    span.babel-normal-align {
        vertical-align:inherit;
    }
    span.babel-button-filter-on {
        color: mintcream;
        background-color: darkgreen;
        border-color: darkgreen;
    }
    `)

    /*--------- LANGUAGE CODES ON AO3 ------------------------------------------------------------------------------------------------

so:  af Soomaali
afr: Afrikaans
ain: Aynu itak | アイヌ イタㇰ
ar:  العربية
amh: አማርኛ
egy: 𓂋𓏺𓈖 𓆎𓅓𓏏𓊖
arc: ܐܪܡܝܐ | ארמיא
hy:  հայերեն
ase: American Sign Language
ast: asturianu
id:  Bahasa Indonesia
ms:  Bahasa Malaysia
bg:  Български
bn:  বাংলা
jv:  Basa Jawa
ba:  Башҡорт теле
be:  беларуская
bos: Bosanski
br:  Brezhoneg
ca:  Català
ceb: Cebuano
cs:  Čeština
chn: Chinuk Wawa
crh: къырымтатар тили | qırımtatar tili
cy:  Cymraeg
da:  Dansk
de:  Deutsch
et:  eesti keel
el:  Ελληνικά
sux: 𒅴𒂠
en:  English
ang: Eald Englisċ
es:  Español
eo:  Esperanto
eu:  Euskara
fa:  فارسی
fil: Filipino
fr:  Français
frr: Friisk
fur: Furlan
ga:  Gaeilge
gd:  Gàidhlig
gl:  Galego
got: 𐌲𐌿𐍄𐌹𐍃𐌺𐌰
gyn: Creolese
hak: 中文-客家话
ko:  한국어
hau: Hausa | هَرْشَن هَوْسَ
hi:  हिन्दी
hr:  Hrvatski
haw: ʻŌlelo Hawaiʻi
ia:  Interlingua
zu:  isiZulu
is:  Íslenska
it:  Italiano
he:  עברית
kal: Kalaallisut
kan: ಕನ್ನಡ
kat: ქართული
cor: Kernewek
khm: ភាសាខ្មែរ
qkz: Khuzdul
sw:  Kiswahili
ht:  kreyòl ayisyen
ku:  Kurdî | کوردی
kir: Кыргызча
fcs: Langue des signes québécoise
lv:  Latviešu valoda
lb:  Lëtzebuergesch
lt:  Lietuvių kalba
la:  Lingua latina
hu:  Magyar
mk:  македонски
ml:  മലയാളം
mt:  Malti
mnc: ᠮᠠᠨᠵᡠ ᡤᡳᠰᡠᠨ
qmd: Mando&#39;a
mr:  मराठी
mik: Mikisúkî
mon: ᠮᠣᠩᠭᠣᠯ ᠪᠢᠴᠢᠭ᠌ | Монгол Кирилл үсэг
my:  မြန်မာဘာသာ
myv: Эрзянь кель
nah: Nāhuatl
nan: 中文-闽南话 臺語
ppl: Nawat
nl:  Nederlands
ja:  日本語
no:  Norsk
azj: Азәрбајҹан дили | آذربایجان دیلی
ce:  Нохчийн мотт
ood: ‘O’odham Ñiok
ota: لسان عثمانى
ps:  پښتو
nds: Plattdüütsch
pl:  Polski
ptBR:  Português brasileiro
ptPT:  Português europeu
pa:  ਪੰਜਾਬੀ
kaz: qazaqşa | қазақша
qlq: Uncategorized Constructed Languages
qya: Quenya
ro:  Română
ru:  Русский
sco: Scots
sq:  Shqip
sjn: Sindarin
si:  සිංහල
sk:  Slovenčina
slv: Slovenščina
gem: Sprēkō Þiudiskō
sr:  Српски
fi:  suomi
sv:  Svenska
ta:  தமிழ்
tat: татар теле
mri: te reo Māori
tel: తెలుగు
th:  ไทย
tqx: Thermian
bod: བོད་སྐད་
vi:  Tiếng Việt
cop: ϯⲙⲉⲧⲣⲉⲙⲛ̀ⲭⲏⲙⲓ
tlh: tlhIngan-Hol
tok: toki pona
trf: Trinidadian Creole
tsd: τσακώνικα
chr: ᏣᎳᎩ ᎦᏬᏂᎯᏍᏗ
tr:  Türkçe
uk:  Українська
urd: اُردُو
uig: ئۇيغۇر تىلى
vol: Volapük
wuu: 中文-吴语
yi:  יידיש
yua: maayaʼ tʼàan
yue: 中文-广东话 粵語
zh:  中文-普通话 國語


 Userscript should activate only for these URLs: */
    // tags/*/works
    // tags/*/bookmarks
    // users/*/works
    // users/*/bookmarks
    // bookmarks/search*
    // works/search*

})(jQuery);