├── .browserslistrc
├── .eslintignore
├── .eslintrc.json
├── .github
└── workflows
│ └── codeql-analysis.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── doc
├── browser support.txt
├── build on windows.txt
├── codingStyle.txt
├── create a CSS module.txt
├── eslint.txt
├── greasyfork_description.txt
├── importantInterfaces.txt
├── listJSON.txt
├── to a future maintainer.txt
└── using Automail without persistent storage.txt
├── icons
├── automail-128.png
├── automail-16.png
├── automail-2.png
├── automail-3.png
├── automail-32.png
├── automail-48.png
├── automail-8.png
├── automail-96.png
└── automail.svg
├── package.json
└── src
├── HOWTO.css
├── HOWTO.js
├── README.txt
├── alias.js
├── automail.m4
├── boneless.m4
├── cache.js
├── conditionalStyles.js
├── controller.js
├── css
├── CSSfavs.js
├── SFWmode.css
├── compactBrowse.css
├── displayBox.css
├── expandFeedFilters.css
├── footerLinks.css
├── global.css
├── greenManga.css
├── noAWC.css
├── notifications.css
├── rightToLeft.css
├── smallScreens.css
├── termsFeed.css
└── verticalNav.css
├── data
├── AnimePlanet_anthologies.json
├── AnimePlanet_mappings_anime.json
├── AnimePlanet_mappings_manga.json
├── badDomains.json
├── commonUnfinishedManga.json
├── data contribution.txt
├── inlineSVG.json
├── languages
│ ├── English.json
│ ├── English_CA.json
│ ├── English_US.json
│ ├── English_short.json
│ ├── French.json
│ ├── German.json
│ ├── Italian.json
│ ├── JSON field details.txt
│ ├── Japanese.json
│ ├── Norwegian.json
│ ├── Portuguese.json
│ ├── README.txt
│ ├── SouthernSami.json
│ ├── Spanish.json
│ ├── Swedish.json
│ ├── Turkish.json
│ ├── diff_tool.html
│ ├── raw_keys.json
│ └── special_keys.txt
├── legacyModuleDescriptions.json
├── review_scripts
│ └── review.html
├── sequel_scripts
│ ├── .eslintrc.json
│ ├── api.mjs
│ ├── fuzzyDateCompare.mjs
│ ├── getAnimeSequels.mjs
│ └── legacy
│ │ ├── anime.html
│ │ └── manga.html
├── sequel_special_cases.txt
├── sequels.json
├── sequels_manga.json
├── shortRomaji.json
├── studios.json
└── titlecaseRomaji.json
├── graphql.js
├── localisation.js
├── makefile
├── manifest.json
├── modules
├── ALbuttonReload.js
├── accessTokenWarning.js
├── addActivityLinks.js
├── addActivityTimeline.js
├── addBrowseFilters.js
├── addComparisionPage.js
├── addCompletedScores.js
├── addCustomCSS.js
├── addDblclickZoom.js
├── addEntryScore.js
├── addFeedFilters.js
├── addFeedFilters_user.js
├── addFollowCount.js
├── addForumMedia.js
├── addForumMediaNoAWC.js
├── addForumMediaTitle.js
├── addImageFallback.js
├── addMALscore.js
├── addMediaReviewConfidence.js
├── addMoreStats.js
├── addMyThreadsLink.js
├── addProgressBar.js
├── addRelationStatusDot.js
├── addReviewConfidence.js
├── addSocialThemeSwitch.js
├── addStudioBrowseSwitch.js
├── addSubTitleInfo.js
├── additionalTranslation.js
├── altBanner.js
├── anisongs.js
├── autoLogin.js
├── betterListPreview.js
├── betterReviewRatings.js
├── browseSubmenu.js
├── cencorMediaPage.js
├── character.js
├── characterBrowse.js
├── clickableActivityHistory.js
├── directEditorAccess.js
├── documentTitleManager.js
├── dubMarker.js
├── durationTooltip.js
├── embedHentai.js
├── enumerateSubmissionStaff.js
├── expandDescriptions.js
├── expandFeedFilters.js
├── expandRight.js
├── expandedListNotes.js
├── extraDefaultSorts.js
├── extraFavs.js
├── feedListLikes.js
├── filterStaffTabs.js
├── forumLikes.js
├── forumRecent.js
├── forumVisualLikes.js
├── hideGlobalFeed.js
├── hideScores.js
├── hollowHearts.js
├── imageFreeEditor.js
├── infoTable.js
├── interestingRecs.js
├── keepAlive.js
├── mangaBrowse.js
├── mangaGuess.js
├── markdownHelp.js
├── meanScoreBack.js
├── mediaList.js
├── mediaTranslation.js
├── middleClickLinkFixer.js
├── mobileAdjustments.js
├── mobileTags.js
├── moreImports.js
├── navbarDroptext.js
├── newChapters.js
├── noAutoplay.js
├── noScrollPosts.js
├── noSequel.js
├── nonJapaneseVoiceDefaults.js
├── nonJumpScroll.js
├── notificationCake.js
├── notifications.js
├── oldDarkTheme.js
├── possibleBlocked.js
├── profileBackground.js
├── randomButtons.js
├── rangeSetter.js
├── recommendationsFade.js
├── reinaDark.js
├── relations.js
├── replaceStaffRoles.js
├── rightSideNavbar.js
├── scoreOverviewFixer.js
├── selectMyThreads.js
├── selfInsert.js
├── settingsPage.js
├── showMarkdown.js
├── singleActivityReplyLikes.js
├── slimNav.js
├── socialTab.js
├── socialTabFeed.js
├── staff.js
├── staffBrowse.js
├── studio.js
├── submenu.js
├── termsFeed.js
├── tweets.js
├── twoColumnFeed.js
├── unicodifier.js
├── videoMimeTypeFixer.js
├── viewAdvancedScores.js
├── webmResize.js
├── yearStepper.js
└── youtubeFullscreen.js
├── polyfills.js
├── purify.js
├── queries
├── BroomCat.js
├── autorecs.js
├── blockedNumber.js
├── compatibility.js
├── datingMess.js
├── datingMessDanger.js
├── findBlocked.js
├── findMessage.js
├── findStatus.js
├── firstActivity.js
├── mediaStatistics.js
├── messageSpy.js
├── mostLikedStatus.js
├── notecleaner.js
├── popularFavourites.js
├── queries.js
├── rank.js
├── relatedAnime.js
├── relatedManga.js
├── reviews.js
├── seasonalStats.js
└── submissionStats.js
├── settings.js
├── utilities.js
└── utilities
├── colourPicker.js
├── displayBox.js
├── levDist.js
├── localforage.js
├── lz-string.js
├── modification.txt
├── parseListJSON.js
├── saveAs.js
└── showdown.js
/.browserslistrc:
--------------------------------------------------------------------------------
1 | # Browsers that support ES9 (2018)
2 | Edge >= 79
3 | Firefox >= 78
4 | Chrome >= 64
5 | Safari >= 12
6 | Opera >= 51
7 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # Third-party code
2 | /src/utilities/levDist.js
3 | /src/utilities/localforage.js
4 | /src/utilities/lz-string.js
5 | /src/utilities/showdown.js
6 | /src/purify.js
7 |
8 | # Code fragments
9 | /src/queries/
10 |
11 | # Build artifacts
12 | /src/build/
13 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "env": {
4 | "browser": true,
5 | "es2018": true,
6 | "greasemonkey": true
7 | },
8 | "extends": ["eslint:recommended", "plugin:compat/recommended"],
9 | "rules": {
10 | "no-unused-vars": "off",
11 | "no-undef": "off",
12 | "no-extra-semi": "warn",
13 | "no-useless-escape": "warn",
14 | "array-callback-return": "warn",
15 | "no-await-in-loop": "warn",
16 | "no-constructor-return": "warn",
17 | "no-promise-executor-return": "warn",
18 | "no-self-compare": "warn",
19 | "no-template-curly-in-string": "warn",
20 | "no-unmodified-loop-condition": "warn",
21 | "no-unreachable-loop": "warn",
22 | "no-use-before-define": "warn",
23 | "no-caller": "warn",
24 | "no-eval": "warn",
25 | "no-implied-eval": "warn",
26 | "no-extend-native": "warn",
27 | "no-extra-bind": "warn",
28 | "no-floating-decimal": "warn"
29 | },
30 | "globals": {
31 | "DOMPurify": "readonly",
32 | "localforage": "readonly",
33 | "showdown": "readonly"
34 | },
35 | "settings": {
36 | "polyfills": [
37 | "String.prototype.includes",
38 | "BroadcastChannel",
39 | "Array.prototype.flat"
40 | ]
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ master ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ master ]
20 | schedule:
21 | - cron: '44 0 * * 1'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
37 | # Learn more:
38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
39 |
40 | steps:
41 | - name: Checkout repository
42 | uses: actions/checkout@v4
43 |
44 | # Initializes the CodeQL tools for scanning.
45 | - name: Initialize CodeQL
46 | uses: github/codeql-action/init@v3
47 | with:
48 | languages: ${{ matrix.language }}
49 | # If you wish to specify custom queries, you can do so here or in a config file.
50 | # By default, queries listed here will override any specified in a config file.
51 | # Prefix the list here with "+" to use these queries and those in the config file.
52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
53 |
54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
55 | # If this step fails, then you should remove it and run the build manually (see below)
56 | - name: Autobuild
57 | uses: github/codeql-action/autobuild@v3
58 |
59 | # ℹ️ Command-line programs to run using the OS shell.
60 | # 📚 https://git.io/JvXDl
61 |
62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
63 | # and modify them (or add more) to build your code if your project
64 | # uses a compiled language
65 |
66 | #- run: |
67 | # make bootstrap
68 | # make release
69 |
70 | - name: Perform CodeQL Analysis
71 | uses: github/codeql-action/analyze@v3
72 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | src/build/
2 | automail.zip
3 | node_modules
4 | package-lock.json
5 | yarn.lock
6 | pnpm-lock.yaml
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Automail
2 | Extra parts for anilist.co
3 |
4 | When installed, a list of options in https://anilist.co/settings/apps can be used to configure the behaviour of the website
5 |
6 | Automail primarily deals with:
7 | - Notifications
8 | - Statistics
9 | - Styling
10 | - Navigation
11 | - UI translation (Japanese, Spanish, Portuguese, German, Turkish, Norwegian, Southern Sami, Italian, French)
12 |
13 | ## Available releases
14 |
15 | As a userscript: https://greasyfork.org/en/scripts/370473-automail ([How to use userscripts](https://greasyfork.org/en/help/installing-user-scripts))
16 | As a Firefox addon: https://github.com/hohMiyazawa/Automail/releases
17 |
18 | ## Build from source
19 |
20 | "src/" contains a makefile, run "make" there.
21 | Requires make, m4 and basic shell utilities
22 |
23 | Will build the userscript and a Firefox addon in src/build/
24 |
25 | If you have an archived version of this repo, updated code can be found at
26 | https://github.com/hohMiyazawa/Automail
27 |
28 | ## Copyright
29 |
30 | Copyright (C) 2019-2023 hoh and the Automail contributors
31 |
32 | This program is free software: you can redistribute it and/or modify
33 | it under the terms of the GNU General Public License as published by
34 | the Free Software Foundation, either version 3 of the License, or
35 | (at your option) any later version.
36 |
37 | This program is distributed in the hope that it will be useful,
38 | but WITHOUT ANY WARRANTY; without even the implied warranty of
39 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 | GNU General Public License for more details.
41 |
42 | You should have received a copy of the GNU General Public License
43 | along with this program. If not, see .
44 |
--------------------------------------------------------------------------------
/doc/browser support.txt:
--------------------------------------------------------------------------------
1 | SHOULD WORK: Browsers Automail should theoretically work for:
2 | - Firefox 52+
3 | - Chrome 55+
4 | - Chromium
5 | - Edge 14+
6 | - Opera 32+
7 | - Safari 10.1+
8 |
9 | DOESN'T WORK: Browsers Automail should theoretically NOT work for:
10 | - All versions of Internet Explorer [no support planned]
11 | - Dillo [no support planned]
12 |
13 | ---
14 |
15 | Versions confirmed to work with Automail:
16 | - Firefox 76.0.1, 96.0, 105.0, 108.0.2
17 | - Chromium 81.0.4044.138
18 |
19 | Browsers confirmed to NOT work with Automail:
20 | - Dillo [no support planned]
21 |
22 | Platforms with dedicated testers:
23 | - Firefox on Linux: hoh
24 |
25 |
26 |
27 | Both positive and negative confirmations can be posted as issues on github:
28 | "Automail does not work in "
29 | in body, include details about what doesn't work
30 | "Automail works in "
31 | (optionally) in body, include the steps used to install Automail
32 |
--------------------------------------------------------------------------------
/doc/build on windows.txt:
--------------------------------------------------------------------------------
1 | See https://github.com/hohMiyazawa/Automail/issues/5
2 | for one possible way found by Reinachan
3 |
--------------------------------------------------------------------------------
/doc/codingStyle.txt:
--------------------------------------------------------------------------------
1 | 0. Just do your thing. I can deal with code submissions pretty quickly.
2 |
3 | ---
4 |
5 | There's also an eslint config.
6 |
7 | ---
8 |
9 | As with any project, follow its established coding style.
10 |
11 | Your contributions may still be accepted if you don't but there will be less of a cleanup job for me.
12 |
13 | 1. Indent with tabs, not spaces
14 |
15 | 2. Opening curly { are on the same line as control flow statements
16 |
17 | 3. There's no space between control flow statements and the opening curly {
18 |
19 | 4. If statements should always have curly brackets {}, even when trivial. Also always ()
20 |
21 | 5. Omit semicolons when possible
22 |
23 | 6. Conditionals can be split over multiple lines for clarity
24 |
25 | --- example if statement, showing 1-6:
26 |
27 | if(
28 | someTest()
29 | && (
30 | useScripts.someModule
31 | || useScripts.someOtherModule
32 | )
33 | ){
34 | counter++
35 | }
36 |
37 | ---
38 |
39 | 7. Use double quotes, not single quotes. (single quotes may be used for single characters, like in c)
40 |
41 | 8. Make HTML elements with the "create" function. (see /src/utilities.js)
42 |
43 | 9. All usage of "innerHTML" should be avoided if possible (innerText, textContent), and if that's unavoidable, you MUST use DOMPurify.sanitize
44 |
45 | 10. If you need some caching, use localForage
46 |
47 | 11. Format your module using the "exportModule" syntax if possible (see src/HOWTO.js)
48 |
49 | 12. Don't import any external libraries. (see if you usecase can be covered by purify.js, localforage.js, anything in utilities.js, or src/utitilites/). Write it yourself if you really need it.
50 |
51 | 13. Avoid calling anilist code.
52 | (permitted, for opening the list editor: document.getElementById("app").__vue__.$store.dispatch("medialistEditor/open",mediaID) )
53 | (permitted, for loading other parts of the site from memory: document.getElementById("app").__vue__._router.push() BUT MAKE SURE IT FALLS BACK TO A REGULAR LINK!)
54 |
55 | 14. All communication with the Anilist API must be done via the interfaces defined in src/graphql.js
56 |
57 | 15. Joke comments are permitted.
58 |
59 | 16. m4 and make are the only permitted pre-processing tools (Python3 scripts, using the standard library only, can be permitted)
60 |
--------------------------------------------------------------------------------
/doc/create a CSS module.txt:
--------------------------------------------------------------------------------
1 | --- new way:
2 |
3 | Follow the template in src/HOWTO.css, insert your css in the css field, and save in /src/modules/yourModule.js
4 |
5 | --- old way:
6 |
7 | 1. Add a boolean in useScripts, in settings.js
8 |
9 | 2. Link your boolean in useScriptsDefinitions, in controller.js
10 |
11 | 3. Inline you insertion in conditionalStyles.js
12 |
13 | 4. (optional) split it into its own file in the css directory, linking it by m4 from conditionalStyles.js
14 |
--------------------------------------------------------------------------------
/doc/eslint.txt:
--------------------------------------------------------------------------------
1 | Eslint is a tool to detect style and code mistakes.
2 | This is optional, and neither required for building nor contributing to Automail. (It can however save you some time)
3 |
4 | How to use:
5 |
6 | Install Node.js (https://nodejs.org/en/) LTS for your platform
7 | Open terminal and enter the Automail directory
8 | Run "npm install"
9 | Run "npm run lint" to lint all JS project files
10 | Or "npm run lint-build" to lint just the compiled userscript
11 |
12 | Installing globally (alternative):
13 | Follow the same steps as above, except replace step 3 with:
14 |
15 | Run "npm install -g eslint@8 eslint-plugin-compat@4"
16 |
17 | Optional:
18 |
19 | Install an integration (https://eslint.org/docs/user-guide/integrations#editors) for your code editor.
20 | will apply linting as you edit open files instead of needing to run the terminal command
21 |
22 |
23 | Added in https://github.com/hohMiyazawa/Automail/pull/138
24 |
--------------------------------------------------------------------------------
/doc/greasyfork_description.txt:
--------------------------------------------------------------------------------
1 | Repository at https://github.com/hohMiyazawa/Automail
2 |
3 | A collection of enhancements for Anilist.
4 | Main:
5 | - New notification system
6 | - More stats (including full lists instead of just 30 items)
7 | - Add scores to completion activities in the feed
8 | - Custom tags
9 | - Find old media activities
10 | Minor:
11 | - Social tab average score, notes and progress
12 | - Various pieces of optional page styling
13 | - Title aliases
14 | - Themes (including high contrast dark)
15 | - Following/follower counts
16 | - Custom profile backgrounds and CSS
17 | - MAL score, recs and serialisation info
18 | - Feed filtering and blocking
19 | - Anime-Planet list importer
20 | - A list exporter
21 | - Accessibility options
22 | - Staff page sorting and filtering
23 | - Translation (Français, Português, Italiano, Español, 日本語, Norsk, Türkçe, Deutsch)
24 |
25 | These can be turned on and off individually in settings > apps
26 |
--------------------------------------------------------------------------------
/doc/importantInterfaces.txt:
--------------------------------------------------------------------------------
1 | The "create" function
2 | Used to create new DOM elements
3 | documented in /src/utilities.js
4 |
5 | ---
6 |
7 | graphql.js contains some important functions for interacting with the Anilist API
8 |
9 | ---
10 |
11 | The automailAPI
12 |
13 | Behind a setting (turned off by default), users can enable API to controll Automail.
14 |
15 | This is in the form of an object that belongs to the document object.
16 |
17 | document.automailAPI
18 |
19 | This exposes some functions of Automail to any other script. The goal being to either simplify writing of third-party script, or make it easier for such scripts to adapt to the changes Automail does.
20 |
21 | This is not a security vulnerability, as these permissions are available in any case to scripts a user decides to run. It just makes it easier for those scripts.
22 |
23 | Current interfaces:
24 |
25 | automailAPI.automailAPI
26 | -- an object containing various info about the version of Automail running. Can be found in src/scriptInfo.js
27 | automailAPI.api
28 | -- the new Automail internal Graphql API
29 | automailAPI.generalAPIcall
30 | automailAPI.authAPIcall
31 | automailAPI.queryPacker
32 | -- implements an interface to the Anilist Graphql API.
33 | -- their implementation can be found in src/graphql.js
34 | automailAPI.settings
35 | -- an object containing the user's script settings
36 | automailAPI.logOut
37 | -- a function to make Automail forget its access token
38 | -- the access token is still valid, and must be retracted from the apps permission page if you want to disable it entirely
39 |
40 | ---
41 |
42 | All raw HTML (avoid if possible) must be sanitised.
43 | Do:
44 | DOMPurify.sanitize(yourHTML)
45 |
--------------------------------------------------------------------------------
/doc/listJSON.txt:
--------------------------------------------------------------------------------
1 | A somewhat unimportant system that's implemented in the script, which allows for making adjustments to the stats generated.
2 |
3 | It works by including a JSON object to the list notes of an entry, surounded by $-signs
4 |
5 | Implements the following keys:
6 |
7 | "adjust": takes a number, representing the number of episodes to add/remove for the show's duration.
8 | "more": takes an array of episode numbers, or a string specifying extra episodes watched.
9 | "skip": same as more, except it represents filler
10 | String syntax:
11 | comma separated, each enty bein either:
12 | a number, representing an episode
13 | number dash number, representing a range (like 4-8)
14 | both episode numbers and ranges can have an "x" multiplier after them
15 |
16 | valid eamples:
17 | [1,3,"1-4"]
18 | "1,2,3"
19 | "1-3"
20 | "4,7x5,1-3x4"
21 |
22 |
23 | Implemented in the function "parseListJSON"
24 |
25 |
26 | Other list note stuff:
27 |
28 | #tag <- this is a custom tag, which shows up in your "more stats" section, and in an index on your list
29 |
30 | ##STRICT <- a special tag, used to turn off various functions fixing "sloppy" tag formatting and casing errors
31 |
--------------------------------------------------------------------------------
/doc/to a future maintainer.txt:
--------------------------------------------------------------------------------
1 | videoMimeTypeFixer:
2 | check if Anilist still serves all video as "video/webm".
3 | if not, this module can be removed.
4 | purify.js:
5 | check for new versions of this every six months or so, to keep up with the xss meta
6 |
7 | "remind hoh to update the commonUnfinishedManga list"
8 | /src/data/commonUnfinishedManga.json contains a mini-database of unfinished manga.
9 | edit the timestamp in /src/utilities.js to make it stop nagging
10 |
11 | How do I publish the firefox addon?
12 | You have to register a firefox account, and publish it separately.
13 | The existing firefox addon is currently not kept up to date
14 |
15 | sequels.json, sequels_manga.json
16 | These are also databases, and must manually be kept up to date.
17 | /src/data/sequel_scripts has some code, were you run the calli() function with page numbers (wait some time, or get throttled) until the entire database is scanned.
18 | Then merge this somehow. Be aware of special cases in sequels_special_cases.txt
19 |
20 | If hoh can't be reached, ask synthtech about the architecture of the script
21 |
--------------------------------------------------------------------------------
/doc/using Automail without persistent storage.txt:
--------------------------------------------------------------------------------
1 | Automail has configurable settings.
2 | If those settings are to be kept, they have to be stored somewhere.
3 |
4 | Since Automail DOES NOT make use of a central server, they have to be saved locally on your computer.
5 | Browsers provide several APIs for this, generally known as cookies.
6 |
7 |
8 |
9 | Automail still mostly works without persistant storage, but in case you want to re-enable it anyway, it should be sufficient to only enable it for the anilist.co domain.
10 |
11 |
12 |
13 |
14 | Case 1. All storage disabled
15 |
16 | Automail will always have the default settings, and you will not be able to sign in to it, making certain modules unavailable
17 |
18 |
19 | Case 2. Storage is not kept between sessions.
20 |
21 | You can change the settings and sign in, but your settings will be gone and you will be signed out if you close and re-open your browser
22 |
23 |
24 |
25 | Patching default settings:
26 |
27 |
28 | src/settings.js contains an object called "useScripts" with the default settings.
29 | (some modules are not listed there. But you can still add their keys there, and it will work. For instance, if you look at the file "/src/modules/hollowHearts.js", you can take the id "hollowHearts", and place it in the usescript settings as "hollowHearts: true")
30 |
31 | Edit this to your taste, and build the script. (you can also save your access token here, which should be in the URL when you click the sign in button on the settings page)
32 |
33 | (if you are editing a compiled build, the relevant code can be located by searching for "let useScripts =")
34 |
--------------------------------------------------------------------------------
/icons/automail-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hohMiyazawa/Automail/79a88dde51ceb40ac56a9d547afc98efa7952c38/icons/automail-128.png
--------------------------------------------------------------------------------
/icons/automail-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hohMiyazawa/Automail/79a88dde51ceb40ac56a9d547afc98efa7952c38/icons/automail-16.png
--------------------------------------------------------------------------------
/icons/automail-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hohMiyazawa/Automail/79a88dde51ceb40ac56a9d547afc98efa7952c38/icons/automail-2.png
--------------------------------------------------------------------------------
/icons/automail-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hohMiyazawa/Automail/79a88dde51ceb40ac56a9d547afc98efa7952c38/icons/automail-3.png
--------------------------------------------------------------------------------
/icons/automail-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hohMiyazawa/Automail/79a88dde51ceb40ac56a9d547afc98efa7952c38/icons/automail-32.png
--------------------------------------------------------------------------------
/icons/automail-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hohMiyazawa/Automail/79a88dde51ceb40ac56a9d547afc98efa7952c38/icons/automail-48.png
--------------------------------------------------------------------------------
/icons/automail-8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hohMiyazawa/Automail/79a88dde51ceb40ac56a9d547afc98efa7952c38/icons/automail-8.png
--------------------------------------------------------------------------------
/icons/automail-96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hohMiyazawa/Automail/79a88dde51ceb40ac56a9d547afc98efa7952c38/icons/automail-96.png
--------------------------------------------------------------------------------
/icons/automail.svg:
--------------------------------------------------------------------------------
1 |
2 |
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "automail",
3 | "version": "10.4.6",
4 | "description": "An enhancement collection for anilist.co",
5 | "author": "hoh",
6 | "license": "GPL-3.0-or-later",
7 | "private": true,
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/hohMiyazawa/Automail.git"
11 | },
12 | "bugs": {
13 | "url": "https://github.com/hohMiyazawa/Automail/issues"
14 | },
15 | "homepage": "https://github.com/hohMiyazawa/Automail",
16 | "scripts": {
17 | "build": "make -C src",
18 | "build-wsl": "wsl make -C src",
19 | "dev": "http-server src/build -s -c5 -o automail.user.js",
20 | "lint": "eslint \"**/*.js\"",
21 | "lint-build": "eslint --rule \"no-unused-vars: warn\" --rule \"no-undef: warn\" --no-ignore src/build/automail.user.js",
22 | "update-anime-sequels": "node src/data/sequel_scripts/getAnimeSequels.mjs"
23 | },
24 | "devDependencies": {
25 | "eslint": "^8.33.0",
26 | "eslint-plugin-compat": "^4.1.1",
27 | "http-server": "^14.1.1"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/HOWTO.css:
--------------------------------------------------------------------------------
1 | //create your own CSS module
2 | //make a javascript file, called yourModule.js, in the directory "modules" (even when it is a CSS-only module)
3 | //worked example: /src/modules/noScrollPosts.js
4 | //include the following code:
5 |
6 | exportModule({
7 | id: "howto",//an unique identified for your module
8 | description: "what your module does",
9 | extendedDescription: `
10 | A more detailed description of what your module does. (optional)
11 |
12 | This appears when people click the "more info" icon (🛈) on the settings page.
13 | `,
14 | isDefault: false,
15 | importance: 0,//a number, which determines the order of the settings page. Higher numbers are more important. Leave it as 0 if unsure.
16 | categories: [],//what categories your module belongs in
17 | //Notifications, Feeds, Forum, Lists, Profiles, Stats, Media, Navigation, Browse, Script, Login, Newly Added
18 | visible: false,//if the module should be visible in the settings (REMEMBER TO CHANGE THIS TO TRUE!)
19 | css: ""//your CSS here, use `` instead for multi line
20 |
21 | //your module can also have extra code and utility functions
22 |
--------------------------------------------------------------------------------
/src/HOWTO.js:
--------------------------------------------------------------------------------
1 | //create your own module
2 | //make a javascript file, called yourModule.js, in the directory "modules"
3 | //include the following code:
4 |
5 | exportModule({
6 | id: "howto",//an unique identified for your module
7 | description: "what your module does",
8 | extendedDescription: `
9 | A more detailed description of what your module does. (optional)
10 |
11 | This appears when people click the "more info" icon (🛈) on the settings page.
12 | `,
13 | isDefault: false,
14 | importance: 0,//a number, which determines the order of the settings page. Higher numbers are more important. Leave it as 0 if unsure.
15 | categories: [],//what categories your module belongs in
16 | //Notifications, Feeds, Forum, Lists, Profiles, Stats, Media, Navigation, Browse, Script, Login, Newly Added
17 | visible: false,//if the module should be visible in the settings (REMEMBER TO CHANGE THIS TO TRUE!)
18 | urlMatch: function(url,oldUrl){//a function that returns true when on the parts of the site you want it to run. url is the current url, oldUrl is the previous page
19 | //example: return url === "https://anilist.co/reviews"
20 | return false;
21 | },
22 | code: function(){
23 | //your code goes here
24 | },
25 | css: ""//css rules you need
26 | })
27 |
28 | //your module can also have extra code and utility functions
29 |
--------------------------------------------------------------------------------
/src/README.txt:
--------------------------------------------------------------------------------
1 | Run "make" to build Automail
2 | A userscript and a firefox addon will be built in the build directory
3 |
4 | Read "HOWTO.js" for instructions about how to write your own module
5 |
--------------------------------------------------------------------------------
/src/alias.js:
--------------------------------------------------------------------------------
1 | //begin "alias.js"
2 | const moreStyle = create("style");
3 | moreStyle.id = "conditional-" + script_type.toLowerCase() + "-styles";
4 | moreStyle.type = "text/css";
5 |
6 | let createAlias = function(alias){
7 | if(alias[0] === "css/"){
8 | moreStyle.textContent += alias[1]
9 | }
10 | else{
11 | const dataSelect = `[href^="${alias[0]}"]`;
12 | const targetName = alias[1].substring(0,Math.min(100,alias[1].length));
13 | moreStyle.textContent += `
14 | .title > a${dataSelect}
15 | ,a.title${dataSelect}
16 | ,.overlay > a.title${dataSelect}
17 | ,.media-preview-card a.title${dataSelect}
18 | ,.quick-search-results .el-select-dropdown__item a${dataSelect}> span
19 | ,.media-embed${dataSelect} .title
20 | ,.status > a.title${dataSelect}
21 | ,.role-card a.content${dataSelect} > .name{
22 | visibility: hidden;
23 | line-height: 0px;
24 | }
25 | .results.media a.title${dataSelect}
26 | ,.home .status > a.title${dataSelect}{
27 | font-size: 2%;
28 | }
29 |
30 | a.title${dataSelect}::before
31 | ,.quick-search-results .el-select-dropdown__item a${dataSelect} > span::before
32 | ,.role-card a.content${dataSelect} > .name::before
33 | ,.home .status > a.title${dataSelect}::before
34 | ,.media-embed${dataSelect} .title::before
35 | ,.overlay > a.title${dataSelect}::before
36 | ,.media-preview-card a.title${dataSelect}::before
37 | ,.title > a${dataSelect}::before{
38 | content:"${targetName}";
39 | visibility: visible;
40 | }`;
41 | }
42 | }
43 |
44 | const shortRomaji = (useScripts.titlecaseRomaji ? m4_include(data/titlecaseRomaji.json) : []).concat(
45 | (useScripts.shortRomaji ? m4_include(data/shortRomaji.json) : [])
46 | );
47 | //end "alias.js"
48 |
--------------------------------------------------------------------------------
/src/css/CSSfavs.js:
--------------------------------------------------------------------------------
1 | if(useScripts.CSSfavs){
2 | /*adds a logo to most favourite studio entries. Add more if needed */
3 | const favStudios = m4_include(data/studios.json)
4 | let favStudioString = "";
5 | if(useScripts.CSSfavs){
6 | favStudioString += `
7 | .overview .favourites > .favourites-wrap > div,
8 | .overview .favourites > .favourites-wrap > a{
9 | /*make the spaces in the grid even*/
10 | margin-bottom: 0px!important;
11 | margin-right: 0px!important;
12 | column-gap: 10px!important;
13 | }
14 | .user .overview{
15 | grid-template-columns: 470px auto!important;
16 | }
17 | .overview .favourites > .favourites-wrap{
18 | display: grid!important;
19 | padding: 0px!important;
20 | display: grid;
21 | grid-gap: 10px;
22 | column-gap: 10px!important;
23 | grid-template-columns: repeat(auto-fill,85px);
24 | grid-template-rows: repeat(auto-fill,115px);
25 | background: rgb(0,0,0,0) !important;
26 | width: 470px;
27 | }
28 | .genre-overview .genre{
29 | display: inline!important;
30 | }
31 | .genre-overview .genre .name{
32 | font-size: small;
33 | }
34 | .overview .favourite.studio{
35 | cursor: pointer;
36 | min-height: 115px;
37 | font-size: 15px;
38 | display: grid;
39 | grid-gap: 10px;
40 | padding: 2px!important;
41 | padding-top: 8px!important;
42 | background-color: rgba(var(--color-foreground))!important;
43 | text-align: center;
44 | align-content: center;
45 | }
46 | .site-theme-dark .overview .favourite.studio{
47 | background-color: rgb(49,56,68)!important;
48 | }
49 | .preview .favourite.media,
50 | .preview .favourite.staff,
51 | .preview .favourite.character{
52 | background-color: rgb(var(--color-foreground));
53 | }
54 | .overview .favourite.studio::after{
55 | display: inline-block;
56 | background-repeat: no-repeat;
57 | content:"";
58 | margin-left:5px;
59 | background-size: 76px 19px;
60 | width: 76px;
61 | height: 19px;
62 | }`;
63 | favStudios.forEach(studio => {
64 | if(studio[2] !== ""){
65 | favStudioString += `.favourite.studio[href="/studio/${studio[0]}/${studio[1]}"]::after{background-image: url("${studio[2]}");`;
66 | if(studio.length === 5){
67 | favStudioString += `background-size: ${studio[3]}px ${studio[4]}px;width: ${studio[3]}px;height: ${studio[4]}px;`;
68 | }
69 | favStudioString += "}";
70 | }
71 | });
72 | }
73 | moreStyle.textContent += favStudioString;
74 | }
75 |
--------------------------------------------------------------------------------
/src/css/compactBrowse.css:
--------------------------------------------------------------------------------
1 | .results > .studio{
2 | counter-reset: ranking;
3 | }
4 | .studio .media-card.isMain{
5 | border-bottom: rgb(var(--color-blue));
6 | border-bottom-width: 1px;
7 | border-bottom-style: solid;
8 | }
9 | .search .results.cover .media-card,
10 | .search .results .staff-card,
11 | .search-landing .results:not(.table) .media-card{
12 | width: 150px;
13 | }
14 | .search .results.cover,
15 | .search-landing .results:not(.table){
16 | grid-template-columns: repeat(auto-fill,150px);
17 | grid-gap: 25px 20px;
18 | }
19 | .search .results.table{
20 | grid-gap: 12px;
21 | }
22 | .search .results.table .cover{
23 | height: 81px;
24 | width: 54px;
25 | }
26 | .search .results.table .media-card{
27 | padding: 0px;
28 | }
29 | .search .results.cover .media-card .cover,
30 | .search-landing .results:not(.table) .media-card .cover,
31 | .search .results .staff-card .cover{
32 | height: 225px;
33 | }
34 | .search:not(.other-type) .landing-section:not(.top) .link{
35 | max-width: 1000px;
36 | }
37 |
--------------------------------------------------------------------------------
/src/css/displayBox.css:
--------------------------------------------------------------------------------
1 | .hohDisplayBox{
2 | position: fixed;
3 | top: 80px;
4 | left: 200px;
5 | z-index: 9999;
6 | padding: 20px;
7 | background-color: rgb(var(--color-foreground));
8 | border: solid 1px;
9 | border-radius: 4px;
10 | box-shadow: black 2px 2px 20px;
11 | overflow: hidden;
12 | filter: brightness(110%);
13 | }
14 | .hohDisplayBox .scrollableContent{
15 | overflow: auto;
16 | height: 100%;
17 | scrollbar-width: thin;
18 | margin-top: 5px;
19 | padding: 30px;
20 | padding-top: 35px;
21 | padding-left: 15px;
22 | }
23 | .hohDisplayBoxClose{
24 | position: absolute;
25 | right: 15px;
26 | top: 15px;
27 | cursor: pointer;
28 | background-color: red;
29 | border: solid;
30 | border-width: 1px;
31 | border-radius: 2px;
32 | color: white;
33 | border-color: rgb(var(--color-text));
34 | filter: drop-shadow(0 0 0.2rem crimson);
35 | z-index: 20;
36 | }
37 | }
38 | .hohDisplayBoxClose:hover{
39 | filter: drop-shadow(0 0 0.75rem crimson);
40 | }
41 | .hohNewChapter .hohDisplayBoxClose{
42 | display: none;
43 | top: 7px;
44 | }
45 | .hohNewChapter:hover .hohDisplayBoxClose{
46 | display: inline;
47 | }
48 | .hohDisplayBoxTitle{
49 | position: absolute;
50 | top: 5px;
51 | left: 5px;
52 | font-weight: bold;
53 | font-size: 1.2em;
54 | }
55 |
--------------------------------------------------------------------------------
/src/css/expandFeedFilters.css:
--------------------------------------------------------------------------------
1 | .home .activity-feed-wrap .section-header .el-dropdown-menu,
2 | .user .activity-feed-wrap .section-header .el-dropdown-menu{
3 | background: none;
4 | position: static;
5 | display: inline !important;
6 | margin-right: 15px;
7 | box-shadow: none !important;
8 | }
9 | .home .activity-feed-wrap .section-header .el-dropdown-menu__item,
10 | .user .activity-feed-wrap .section-header .el-dropdown-menu__item{
11 | font-weight: normal;
12 | color: rgb(var(--color-text-lighter));
13 | margin-left: -2px !important;
14 | display: inline;
15 | font-size: 1.2rem;
16 | padding: 4px 15px 5px 15px;
17 | border-radius: 3px;
18 | transition: .2s;
19 | background: none;
20 | }
21 | .home .activity-feed-wrap .section-header .el-dropdown-menu__item.active,
22 | .user .activity-feed-wrap .section-header .el-dropdown-menu__item.active{
23 | background: none!important;
24 | color: rgb(var(--color-blue));
25 | }
26 | .home .activity-feed-wrap .section-header .el-dropdown-menu__item:hover,
27 | .user .activity-feed-wrap .section-header .el-dropdown-menu__item:hover{
28 | background: none!important;
29 | color: rgb(var(--color-blue));
30 | }
31 | .home .feed-select .feed-filter,
32 | .user .section-header > .el-dropdown > .el-dropdown-selfdefine{
33 | display: none;
34 | }
35 |
--------------------------------------------------------------------------------
/src/css/greenManga.css:
--------------------------------------------------------------------------------
1 | .review-card:hover .banner[data-src*="/media/manga/"] + .content > .header{
2 | color: rgb(var(--color-green));
3 | }
4 | .review-card:hover .banner[data-src*="/media/anime/"] + .content > .header{
5 | color: rgb(var(--color-blue));
6 | }
7 | .user .review-card:hover .banner[data-src*="/media/anime/"] + .content > .header{
8 | color: rgb(61,180,242);
9 | }
10 | .activity-markdown a[href^="https://anilist.co/manga/"],
11 | .activity-markdown a[href^="https://anilist.co/search/manga"],
12 | .activity-markdown a[href^="/manga/"],
13 | .reply-markdown a[href^="https://anilist.co/manga/"],
14 | .reply-markdown a[href^="https://anilist.co/search/manga"],
15 | .reply-markdown a[href^="/manga/"]{
16 | color: rgba(var(--color-green));
17 | }
18 | .hohDataChange a[href^="/manga/"]{
19 | color: rgba(var(--color-green));
20 | }
21 | .activity-manga_list > div > div > div > div > .title,
22 | .hohPinned .list .title[href^="/manga/"]{
23 | color: rgba(var(--color-green))!important;
24 | }
25 | .media .relations .cover[href^="/manga/"] + div div{
26 | color: rgba(var(--color-green));
27 | }
28 | .media .relations .cover[href^="/anime/"] + div div{
29 | color: rgba(var(--color-blue));
30 | }
31 | .media .relations .cover[href^="/manga/"]{
32 | border-bottom-style: solid;
33 | border-bottom-color: rgba(var(--color-green));
34 | border-bottom-width: 2px;
35 | }
36 | .character-wrap .role-card:hover .title[href^="/anime/"]{
37 | color: rgb(var(--color-blue)) !important;
38 | }
39 | .character-wrap .role-card .title[href^="/manga/"],
40 | .character-wrap .role-card:hover .title[href^="/manga/"],
41 | .media-roles .media .content:hover[href^="/manga/"] .name{
42 | color: rgb(var(--color-green)) !important;
43 | }
44 | .media .relations.small .cover[href^="/manga/"]::after{
45 | position:absolute;
46 | left:1px;
47 | bottom:3px;
48 | content:"";
49 | border-style: solid;
50 | border-color: rgba(var(--color-green));
51 | border-width: 2px;
52 | }
53 | .media .relations .cover[href^="/anime/"]{
54 | border-bottom-style: solid;
55 | border-bottom-color: rgba(var(--color-blue));
56 | border-bottom-width: 2px;
57 | }
58 | .media .relations .cover div.image-text{
59 | margin-bottom: 2px!important;
60 | border-radius: 0px!important;
61 | padding-bottom: 8px!important;
62 | padding-top: 8px!important;
63 | font-weight: 500!important;
64 | }
65 | .media-embed[data-media-type="manga"] .title{
66 | color: rgba(var(--color-green));
67 | }
68 | .media-manga .actions .list{
69 | background: rgba(var(--color-green));
70 | }
71 | .media-manga .sidebar .review.button{
72 | background: rgba(var(--color-green));
73 | }
74 | .media-manga .container .content .nav .link{
75 | color: rgba(var(--color-green));
76 | }
77 | .hover-manga:hover{
78 | color: rgba(var(--color-green))!important;
79 | }
80 | .home .recent-reviews + div .cover[href^="/manga/"] + .content .info-header{
81 | color: rgba(var(--color-green));
82 | }
83 | .recommendations-wrap .recommendation-pair-card a[href^="/manga/"]:hover .title{
84 | color: rgba(var(--color-green));
85 | }
86 |
--------------------------------------------------------------------------------
/src/css/noAWC.css:
--------------------------------------------------------------------------------
1 | .hohNoAWC .thread-card.small{
2 | margin-bottom: 15px;
3 | background: rgb(var(--color-foreground));
4 | border-radius: 3px;
5 | padding: 18px;
6 | position: relative;
7 | }
8 | .hohNoAWC .title{
9 | font-size: 1.4rem;
10 | display: block;
11 | margin-bottom: 12px;
12 | margin-right: 110px;
13 | }
14 | .hohNoAWC .footer{
15 | align-items: center;
16 | display: flex;
17 | flex-direction: row;
18 | }
19 | .hohNoAWC .avatar{
20 | background-position: 50%;
21 | background-repeat: no-repeat;
22 | background-size: cover;
23 | border-radius: 3px;
24 | display: inline-block;
25 | height: 25px;
26 | vertical-align: text-top;
27 | width: 25px;
28 | }
29 | .hohNoAWC .name{
30 | display: inline-block;
31 | font-size: 1.3rem;
32 | padding-left: 10px;
33 | }
34 | .hohNoAWC .name span{
35 | color: rgb(var(--color-blue));
36 | }
37 | .hohNoAWC .categories{
38 | margin-left: auto;
39 | white-space: nowrap;
40 | max-width: 310px;
41 | }
42 | .hohNoAWC .category{
43 | border-radius: 100px;
44 | color: #fff;
45 | display: inline-block;
46 | font-size: 1.1rem;
47 | margin-left: 10px;
48 | padding: 4px 8px;
49 | }
50 | .hohNoAWC .category.default{
51 | text-transform: lowercase;
52 | }
53 | .hohNoAWC .category:hover{
54 | color: rgba(26,27,28,.6);
55 | }
56 | .hohNoAWC .info{
57 | color: rgb(var(--color-text-lighter));
58 | font-size: 1.2rem;
59 | position: absolute;
60 | right: 12px;
61 | top: 12px;
62 | }
63 | .hohNoAWC .info span{
64 | padding-left: 10px;
65 | }
66 |
--------------------------------------------------------------------------------
/src/css/rightToLeft.css:
--------------------------------------------------------------------------------
1 | .favourites-wrap.anime,
2 | .favourites-wrap.manga,
3 | .favourites-wrap.staff,
4 | .favourites-wrap.characters,
5 | .favourites-wrap.studios{
6 | direction: rtl;
7 | }
8 | .genre-overview .genres{
9 | direction: rtl;
10 | }
11 | .genre-overview .percentage-bar{
12 | direction: rtl;
13 | }
14 | .milestones{
15 | direction: rtl;
16 | }
17 | .milestones + .progress{
18 | transform: scale(-1);
19 | }
20 | .list-preview{
21 | direction: rtl;
22 | }
23 | #hohListPreview .list-preview{
24 | width: 100%;
25 | }
26 | .media-preview-card .hohFallback,
27 | .media-preview-card .content{
28 | direction: ltr;
29 | }
30 | .media-preview-card .content meter{
31 | direction: rtl;
32 | }
33 | .banner-content{
34 | direction: rtl;
35 | }
36 | .banner-content .actions{
37 | margin-right: auto;
38 | margin-left: inherit!important;
39 | }
40 | #hohListPreview .info-left .content {
41 | border-radius: 3px 0 0 3px;
42 | left: auto !important;
43 | right: 100%;
44 | text-align: right;
45 | }
46 | #app .home{
47 | grid-template-columns: 470px auto !important;
48 | }
49 | .home > .activity-feed-wrap + div{
50 | grid-row: 1;
51 | }
52 | .recent-reviews .review-wrap{
53 | direction: rtl;
54 | }
55 | .recent-reviews .review-card{
56 | direction: ltr;
57 | }
58 | .recent-reviews + div .media-preview{
59 | direction: rtl;
60 | }
61 | #app > .progress{
62 | transform: scale(-1);
63 | }
64 | .hohColourPicker{
65 | margin-right: 20px;
66 | }
67 | .home .activity-feed-wrap .section-header{
68 | direction: rtl;
69 | }
70 | .home .activity-feed-wrap .section-header .feed-select{
71 | margin-right: auto;
72 | margin-left: inherit;
73 | }
74 | .home .activity-feed-wrap .section-header .feed-select .el-dropdown{
75 | direction: ltr;
76 | margin-left: 20px;
77 | }
78 | .hohSubMenuLink{
79 | text-align: right;
80 | }
81 | .quick-search .input{
82 | direction: rtl;
83 | }
84 | .quick-search .results{
85 | direction: rtl;
86 | }
87 | .quick-search .results .result{
88 | direction: ltr;
89 | }
90 | .quick-search .results .result-col h3.title{
91 | right: 0px;
92 | }
93 | .home .section-header{
94 | text-align: right;
95 | }
96 | .home .list-previews .section-header{
97 | direction: rtl;
98 | }
99 | .user .nav-wrap{
100 | direction: rtl;
101 | }
102 | .user .medialist{
103 | direction: rtl;
104 | }
105 | .medialist .filters .filter-group:first-child > span .count{
106 | left: 0px;
107 | right: inherit;
108 | }
109 | .medialist.table .entry .title a{
110 | margin-left: auto;
111 | margin-right: 10px;
112 | direction: ltr;
113 | }
114 | .medialist .lists > .actions{
115 | left: 0px;
116 | right: inherit;
117 | }
118 | .list-editor-wrap .header .content{
119 | direction: rtl;
120 | }
121 |
--------------------------------------------------------------------------------
/src/data/AnimePlanet_anthologies.json:
--------------------------------------------------------------------------------
1 | {
2 | "The Dragon Dentist": 20947,
3 | "Hill Climb Girl": 20947,
4 | "20min Walk From Nishi-Ogikubo Station": 20947,
5 | "Collection of Key Animation Films": 20947,
6 | "(Making of) Evangelion: Another Impact": 20947,
7 | "Sex and Violence with Mach Speed": 20947,
8 | "Memoirs of Amorous Gentlemen": 20947,
9 | "Denkou Choujin Gridman: boys invent great hero": 20947,
10 | "Evangelion: Another Impact": 20947,
11 | "Bureau of Proto Society": 20947,
12 | "Cassette Girl": 20947,
13 | "Bubu & Bubulina": 20947,
14 | "I can Friday by day!": 20947,
15 | "Three Fallen Witnesses": 20947,
16 | "Robot on the Road": 20947,
17 | "Comedy Skit 1989": 20947,
18 | "Power Plant No.33": 20947,
19 | "Me! Me! Me! Chronic": 20947,
20 | "Endless Night": 20947,
21 | "Neon Genesis IMPACTS": 20947,
22 | "Obake-chan": 20947,
23 | "Hammerhead": 20947,
24 | "Girl": 20947,
25 | "Yamadeloid": 20947,
26 | "Me! Me! Me!": 20947,
27 | "Ibuseki Yoruni": 20947,
28 | "Rapid Rouge": 20947,
29 | "Tomorrow from there": 20947,
30 | "The Diary of Ochibi": 20947,
31 | "until You come to me.": 20947,
32 | "Tsukikage no Tokio": 20947,
33 | "Carnage": 20947,
34 | "Iconic Field": 20947,
35 | "The Ultraman (2015)": 20947,
36 | "Kanoun": 20947,
37 | "Ragnarok": 20947,
38 | "Death Note Rewrite 1: Visions of a God": 2994,
39 | "Death Note Rewrite 2: L's Successors": 2994
40 | }
41 |
--------------------------------------------------------------------------------
/src/data/AnimePlanet_mappings_anime.json:
--------------------------------------------------------------------------------
1 | {
2 | "Rebuild of Evangelion: Final": 3786,
3 | "KonoSuba – God’s blessing on this wonderful world!! Movie: Legend of Crimson": 102976,
4 | "Puella Magi Madoka Magica: Magica Quartet x Nisioisin": 20891,
5 | "Kanye West: Good Morning": 8626,
6 | "Patlabor 2: The Movie": 1096,
7 | "She and Her Cat": 1004,
8 | "Star Blazers: Space Battleship Yamato 2199": 12029,
9 | "Digimon Season 3: Tamers": 874,
10 | "The Anthem of the Heart": 20968,
11 | "Digimon Movie 1: Digimon Adventure": 2961,
12 | "Love, Chunibyo & Other Delusions!: Sparkling... Slapstick Noel": 16934,
13 | "The Labyrinth of Grisaia Special": 21312,
14 | "Candy Boy EX01": 5116,
15 | "Candy Boy EX02": 6479,
16 | "Attack on Titan 3rd Season": 99147,
17 | "Attack on Titan 2nd Season": 20958,
18 | "Nichijou - My Ordinary Life: Episode 0": 8857,
19 | "March Comes in like a Lion 2nd Season": 98478,
20 | "KonoSuba – God’s blessing on this wonderful world!! 2 OVA": 97996,
21 | "KonoSuba – God’s blessing on this wonderful world!! OVA": 21574,
22 | "Laid-Back Camp Specials": 101206,
23 | "Spice and Wolf II OVA": 6007,
24 | "Mob Psycho 100 Specials": 102449
25 | }
26 |
--------------------------------------------------------------------------------
/src/data/AnimePlanet_mappings_manga.json:
--------------------------------------------------------------------------------
1 | {
2 | "GATE: Where the JSDF Fought": 71733,
3 | "Emanon: Memories of Emamon": 47465
4 | }
5 |
--------------------------------------------------------------------------------
/src/data/badDomains.json:
--------------------------------------------------------------------------------
1 | [556415734,1724824539,-779421562,-1111399772,-93654449,1120312799,-781704176,-1550515495,3396395,567115318,-307082983,1954992241,-307211474,-307390044,1222804306,-795095039,-1014860289,403785740,547002932,128627683]
2 |
--------------------------------------------------------------------------------
/src/data/commonUnfinishedManga.json:
--------------------------------------------------------------------------------
1 | {
2 | "30002":{
3 | "chapters":376,
4 | "volumes":40,
5 | "comment":"berserk"
6 | },
7 | "30013":{
8 | "chapters":1118,
9 | "volumes":101,
10 | "comment":"one piece"
11 | },
12 | "85486":{
13 | "chapters":375,
14 | "volumes":32,
15 | "comment":"mha"
16 | },
17 | "74347":{
18 | "chapters":152,
19 | "volumes":24,
20 | "comment":"opm"
21 | },
22 | "30026":{
23 | "chapters":390,
24 | "volumes":36,
25 | "comment":"HxH"
26 | },
27 | "30656":{
28 | "chapters":327,
29 | "volumes":37,
30 | "comment":"vagabond"
31 | },
32 | "30105":{
33 | "chapters":106,
34 | "volumes":14,
35 | "comment":"yotsuba&"
36 | },
37 | "105398":{
38 | "chapters":173,
39 | "volumes":4,
40 | "comment":"solo leveling"
41 | },
42 | "101517":{
43 | "chapters":167,
44 | "volumes":17,
45 | "comment":"juju"
46 | },
47 | "97852":{
48 | "chapters":383,
49 | "volumes":23,
50 | "comment":"komi"
51 | },
52 | "102988":{
53 | "chapters":233,
54 | "volumes":24,
55 | "comment":"revengers"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/data/data contribution.txt:
--------------------------------------------------------------------------------
1 | --- badDomains.json
2 |
3 | This file contains an array of hashes for illegal manga/anime aggregators, for link filtering (it's currently only used by a few modules)
4 |
5 | Use the simple java-hash on the domain name, without the top level domain (so "wikipedia.org" would be just "wikipedia", which would be 1558992055 (and not a domain we want to block!))
6 |
7 |
8 | function hashCode(string){
9 | var hash = 0, i, chr;
10 | if(string.length === 0){
11 | return hash
12 | }
13 | for(i = 0; i < string.length; i++) {
14 | chr = string.charCodeAt(i);
15 | hash = ((hash << 5) - hash) + chr;
16 | hash |= 0;
17 | }
18 | return hash
19 | }
20 |
21 |
22 | It's not supposed to be cryptocraphically secure, the purpouse is just to not dump a huge catalogue of such sites to anyone taking a glance.
23 |
24 | If you submit a new domain, your pull request must mention in plaintext the domain it blocks.
25 |
26 | --- inlineSVG.json
27 |
28 | Use this if your module needs a new icon, as Automail must be delivered in a single file
29 |
30 |
31 | --- studios.json
32 |
33 | Format:
34 |
35 | [
36 | studio ID,
37 | studio name (as stringified in the URL),
38 | direct link to logo,
39 | [optional width],
40 | [optional height]
41 | ]
42 |
43 | Example:
44 |
45 | [
46 | 309,
47 | "GoHands",
48 | "https://i.stack.imgur.com/pScIZ.jpg",
49 | ]
50 |
51 | --- shortRomaji.json
52 |
53 | Alternate romaji titles for stuff that's too long.
54 |
55 | --- legacyModuleDescriptions.json
56 |
57 | Do not use, see HOWTO.js instead.
58 |
59 | --- languages/translation
60 |
61 | See https://github.com/hohMiyazawa/Automail/issues/69
62 |
--------------------------------------------------------------------------------
/src/data/languages/English_CA.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "language": "English (CA)",
4 | "language_english": "English (CA)",
5 | "variation_of": "English",
6 | "locale": "en-CA",
7 | "fallback": ["English"],
8 | "maintainer": "Zarin",
9 | "maintainer_link": "https://github.com/kazzarin",
10 | "discussion_link": "",
11 | "notes": "There's in general no need to translate all the keys, since the default fallback is English."
12 | },
13 | "keys": {
14 | "$MAL_serialization": "Serialization",
15 | "$compare_normalizeRatings": "Normalize ratings:",
16 | "$setting_MALserial": "Add MAL serialization info to manga",
17 | "$forumCategory_14": "List Customization"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/data/languages/English_US.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "language": "English (US)",
4 | "language_english": "English (US)",
5 | "variation_of": "English",
6 | "locale": "en-US",
7 | "fallback": ["English"],
8 | "maintainer": "hoh",
9 | "maintainer_link": "https://anilist.co/user/hoh/",
10 | "discussion_link": "",
11 | "notes": "There's in general no need to translate all the keys, since the default fallback is English."
12 | },
13 | "keys": {
14 | "$setting_CSSsmileyScore": "Give smiley ratings distinct colors",
15 | "$profileBackground_help2": "Tip: Use a color with transparancy, to work better with both light and dark themes. Example:",
16 | "$compare_colourCell": "Color entire cell:",
17 | "$adjustColours_title": "Adjust Colors",
18 | "$settings_notificationDotColour": "Notification Dot Colors",
19 | "$statusBorder_description": "Color code the right border of activities by media status",
20 | "$submenu_favourites": "Favorites",
21 | "$characterBrowseTooltip": "Favorites",
22 | "$MAL_serialization": "Serialization",
23 | "$compare_normalizeRatings": "Normalize ratings:",
24 | "$setting_MALserial": "Add MAL serialization info to manga",
25 | "$forumCategory_14": "List Customization",
26 | "$CSSoldDarkTheme_description":"Use the old dark theme colors",
27 | "$dataSet_favorites": "Favorites"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/data/languages/JSON field details.txt:
--------------------------------------------------------------------------------
1 | The main JSON object has two field: "info", containing the metadata, and "keys", containing the translations.
2 |
3 | In "info":
4 | "language": The name of your language, in your language. Add parenthesis if you need to distinguish it as a variant of another language.
5 | "language_english": The name of your language, in English. Copy the value of "language" if your language doesn't have a name in English.
6 | (Optional) "variation_of": If you are adding a dialect of an existing translation, this should be the name of that translation.
7 | "fallback": A list, containing in descending order what languages the script should try to search for missing translations until it finds one. The last one should be "English".
8 | "maintainer": The name you wish to be addressed as. Does not have to be your real name. Your Anilist name or Github name are good candidates, but it doesn't have to be one of those.
9 | "maintainer_link": Were people can contact you. An anilist user page or a Github page are good candidates. But you can also use a nick on some chat platform if that's your preference. Can be left blank. Add "I do not wish to be contacted" + the same in your language if you really do not wish people to contact you.
10 | "discussion_link": Where people can discuss this translation. Use "https://github.com/hohMiyazawa/Automail/issues/69" if you don't have a dedicated place for discussion.
11 | (Optional) "notes": Anything. You can also create your own text file in the /src/data/languages directory if you have more detailed notes
12 | (Optional) "translators": A list of translators, if multiple people have contributed. But there can only be one maintainer.
13 | (Optional) "locale": a BCP 47 code identifying the language. Mostly the same as the ISO 639 two and three letter language codes.
14 |
15 | You are allowed to add additional fields in "info".
16 |
17 | In "keys":
18 | language keys, all starting with "$". You do not have to translate all the keys as the script will fall back to English or the dedicated fallback languages.
19 |
20 |
21 | Example:
22 |
23 | {
24 | "info": {
25 | "language": "Norsk",
26 | "language_english": "Norwegian",
27 | "locale": "nn-NO",
28 | "fallback": ["Svenska","English"],
29 | "maintainer": "hoh",
30 | "maintainer_link": "https://anilist.co/user/hoh/",
31 | "discussion_link": "https://github.com/hohMiyazawa/Automail/issues/69",
32 | "notes": "",
33 | "translators": ["hoh"]
34 | },
35 | "keys": {
36 | "$logo_home": "Heim"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/data/languages/README.txt:
--------------------------------------------------------------------------------
1 | Q: How do I add a translation?
2 |
3 | A: You create a file named "yourlanguage.json" in this directory. Copy one of the existing translations to get the right structure. (or see "JSON field details.txt")
4 | To get it added to Automail I prefer pull requests (https://github.com/hohMiyazawa/Automail/), but just sending me a translation file is fine.
5 |
6 |
7 | Q: How do I activate my translation in the Automail code?
8 |
9 | A: I will happily do this for you, but if you want to do this yourself, you must add an entry near the top of the file in "/src/localisation.js", and a settings option near the bottom of "/src/data/legacyModuleDescriptions.json".
10 |
11 |
12 | Q: What tools do I need?
13 |
14 | A: Just a simple text editor, that is, something without formatting. (think notepad)
15 |
16 |
17 | Q: Do I have to translate all the keys?
18 |
19 | A: No. Any key you leave out will have the default English text, or text from one of the fallback languages.
20 |
21 |
22 | Q: How can I find out what keys I'm missing?
23 |
24 | A: There's a tool called "diff_tool.html" in this directory, which you can open in your browser to compare translation files.
25 |
26 |
27 | Q: How do fallback languages work?
28 |
29 | A: If your translation file is missing a key, the script will go through the languages listed in the "fallback" field in order.
30 | If one of those translations has the key, it will use that. If none of those have it, it will use the default English text.
31 | Fallbacks are useful if an existing translation is close to your language.
32 |
33 |
34 | Q: Do I have to be a native speaker?
35 |
36 | A: You do not.
37 |
38 |
39 | Q: What can I do if I only know English?
40 |
41 | A: You can proofread the English language file ("/src/data/English.json), as I'm not a native speaker and likely made many mistakes.
42 |
43 |
44 | Q: is not a real language! It's a dialect/version of !
45 |
46 | A: That's not a problem. It's up to the individual translators if making the translation is worth their time.
47 |
48 |
49 | Q: Should I translate keys that are exactly the same in my language (Like "Format" in English is "Format" in my language)
50 |
51 | A: Yes.
52 |
53 |
54 | Q: In what order are languages ordered?
55 |
56 | A: The order is determined by the list at the bottom of /src/data/legacyModuleDescriptions.json
57 | The order should be the following
58 | 1. English, the default Anilist language
59 | 2. Translations to other languages
60 | - As a main rule, languages are ordered by the *completeness* of the translation, most complete first
61 | - A possible measure of "completeness" is the number of keys translated.
62 | - If multiple languages are complete, the complete translations should be ordered as Japanese first, then alphabetically by English name.
63 | 3. English variations
64 | 4. $raw_keys translator mode file
65 |
--------------------------------------------------------------------------------
/src/data/languages/SouthernSami.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "language": "Åarjelsaemie",
4 | "language_english": "Southern Sami",
5 | "locale": "sma",
6 | "fallback": ["Norsk","Svenska","English"],
7 | "maintainer": "hoh",
8 | "maintainer_link": "https://anilist.co/user/hoh/",
9 | "discussion_link": "",
10 | "notes": ""
11 | },
12 | "keys": {
13 | "$button_search": "Ohtsh",
14 | "$settings_experimental_suffix": "[PRYÖVENASSE]",
15 | "$settings_partialLocalisationLanguage_description": "Automailen gïele",
16 | "$stats_moreStats_title": "Vielie Deahpadimmieh",
17 | "$stats_siteStats_title": "Sijjien Deahpadimmieh",
18 | "$stats_longestTime": "{1} {0}% lea",
19 | "$stats_mostCommonScore": "Sïejhmemes: ",
20 | "$stats_name": "Nomme",
21 | "$settings_title": "Automailen bïjre",
22 | "$settings_version": "Versjovne: ",
23 | "$settings_homepage": "Gaskeviermesne: ",
24 | "$settings_category_Feeds": "Galkijh",
25 | "$settings_category_Newly Added": "Orre",
26 | "$notification_likeActivity_1person_1activity": " dov aatem lyjhki.",
27 | "$notification_likeActivity_1person_Mactivity": " dov aath lyjhki.",
28 | "$notification_likeActivity_2person_1activity": " dov aatem lyjhkigan.",
29 | "$notification_likeActivity_2person_Mactivity": " dov aath lyjhkigan.",
30 | "$notification_likeActivity_Mperson_1activity": " dov aatem lyjhkin.",
31 | "$notification_likeActivity_Mperson_Mactivity": " dov aath lyjhkin.",
32 | "$notification_message": " prieviem seedti.",
33 | "$menu_home": "gåetie",
34 | "$menu_profile": "manne",
35 | "$menu_animelist": "animelæstoe",
36 | "$menu_mangalist": "mangalæstoe",
37 | "$menu_browse": "ohtsh",
38 | "$menu_forum": "digkie",
39 | "$filters_year": "Jaepie",
40 | "$markdown_help_images_header": "Guvvieh",
41 | "$markdown_help_infixOr": "jallh",
42 | "$preview_animeSection_title": "Dov Anime",
43 | "$preview_mangaSection_title": "Dov Manga",
44 | "$preview_airingSection_title": "Saadtegh",
45 | "$profile_title": "{0}en sæjroe",
46 | "$recs_forYou": "Dutnjien",
47 | "$colour_transparent": "Tjaetsie",
48 | "$colour_blue": "Plaave",
49 | "$colour_white": "Veelkes",
50 | "$colour_black": "Tjeehpes",
51 | "$colour_red": "Rööpses",
52 | "$colour_peach": "Peersika",
53 | "$colour_orange": "Rööps-viskes",
54 | "$colour_yellow": "Viskes",
55 | "$colour_green": "Kruana",
56 | "$mediaFormat_ONE_SHOT" : "Oktegh"
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/data/languages/Swedish.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "language": "Svenska",
4 | "language_english": "Swedish",
5 | "locale": "sv-SE",
6 | "fallback": ["Norsk","English"],
7 | "maintainer": "no maintainer",
8 | "maintainer_link": "",
9 | "discussion_link": "",
10 | "notes": "This translation is not maintained. Want to contribute?"
11 | },
12 | "keys": {
13 | "$time_1second": "1 sekund sedan",
14 | "$time_Msecond": "{0} sekund sedan",
15 | "$time_1minute": "1 minut sedan",
16 | "$time_Mminute": "{0} minut sedan",
17 | "$time_1hour": "1 timme sedan",
18 | "$time_Mhour": "{0} timmar sedan",
19 | "$time_1day": "1 dag sedan",
20 | "$time_Mday": "{0} dagar sedan",
21 | "$time_1week": "1 vecka sida",
22 | "$time_Mweek": "{0} veckor sedan",
23 | "$time_1month": "1 månad sedan",
24 | "$time_Mmonth": "{0} månadar sedan",
25 | "$time_1year": "1 år sedan",
26 | "$time_Myear": "{0} år sedan",
27 | "$settings_homepage": "Hemesida: ",
28 | "$settings_repository": "Källkod: ",
29 | "$button_search": "Sök",
30 | "$mediaStatus_dropped": "droppad",
31 | "$language_English": "engelska",
32 | "$language_German": "tyska",
33 | "$language_Italian": "italienska",
34 | "$language_Spanish": "spanska",
35 | "$language_French": "franska",
36 | "$language_Korean": "koreanska",
37 | "$language_Portuguese": "portugisiska",
38 | "$language_Hebrew": "hebreiska",
39 | "$language_Hungarian": "ungerska",
40 | "$language_Chinese": "kinesiska",
41 | "$language_Japanese": "japanska",
42 | "$language_Arabic": "arabiska",
43 | "$language_Filipino": "filipino",
44 | "$language_Catalan": "katalanska",
45 | "$language_Polish": "polska",
46 | "$language_Norwegian": "norska",
47 | "$mediaFormat_NOVEL": "Lättroman"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/data/languages/diff_tool.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Translation diff tool
8 |
Load two translation files to find untranslated keys
9 |
10 |
11 |
12 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/src/data/languages/raw_keys.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "language": "$raw_keys",
4 | "language_english": "$raw_translator_keys",
5 | "locale": "",
6 | "fallback": [],
7 | "maintainer": "(translator mode)",
8 | "maintainer_link": "",
9 | "discussion_link": "https://github.com/hohMiyazawa/Automail/issues/69",
10 | "notes": "This is a special language file, used to see raw keys in the UI. DO NOT USE THIS FILE AS A TEMPLATE FOR YOUR OWN TRANSLATION FILE (use English.json, or Norwegian.json, or read the documentation)",
11 | "translators": ["(translator mode)"]
12 | },
13 | "keys": {}
14 | }
15 |
--------------------------------------------------------------------------------
/src/data/languages/special_keys.txt:
--------------------------------------------------------------------------------
1 | The English language file does not contain keys of the form "$role_something".
2 | These are used on staff pages to translate roles, but since those are already in English, there's no need to translate them into English.
3 | But if you want those roles translated into your language, you need to add keys like "$role_Story & Art" and "$role_Director".
4 | There's a ton of those roles, so just adding the most common ones is good enough
5 |
--------------------------------------------------------------------------------
/src/data/sequel_scripts/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "node": true
4 | },
5 | "parserOptions": {
6 | "ecmaVersion": "latest",
7 | "sourceType": "module"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/data/sequel_scripts/api.mjs:
--------------------------------------------------------------------------------
1 | let apiResetLimit;
2 |
3 | /**
4 | * Constructs and sends a request to the AniList GraphQL API
5 | * @param {string} query - A GraphQL query string.
6 | * @param {object} [variables] - GraphQL variables.
7 | * @returns {Promise