Skip to content

Instantly share code, notes, and snippets.

@BrickGrass
Last active Sep 7, 2021
Embed
What would you like to do?

AO3 Bookmark wordcount autofill

This is a simple little tampermonkey/greasemonkey extension that autofills a wordcount tag whenever you open a bookmark form on ao3. It doesn't work on the dedicated bookmark edit page (eg: https://archiveofourown.org/bookmarks/<bookmark_id>/edit) since the wordcount cannot be found in the html there.

Install by clicking this https://gist.github.com/BrickGrass/6ddece6536cb1b0558cf6f4d8eeb2ad9/raw/3b6aa413c11f651291ef973f2b824de22ee4563b/wordcount_autofill.pub.user.js

// ==UserScript==
// @name AO3 Bookmark wordcount autofill
// @namespace https://brickgrass.uk
// @version 0.1
// @description Automatically add wordcount tags to the ao3 bookmark form whenever it is opened.
// @author BrickGrass
// @include https://archiveofourown.org/*
// @require http://code.jquery.com/jquery-3.6.0.min.js
// @require https://greasyfork.org/scripts/6250-waitforkeyelements/code/waitForKeyElements.js?version=23756
// @grant none
// ==/UserScript==
// following two are similar, check first *then* second if failed first
const work_bookmarks_url = /https:\/\/archiveofourown\.org\/works\/\d+\/bookmarks/;
const work_url = /https:\/\/archiveofourown\.org\/works\/\d+/;
const series_url = /https:\/\/archiveofourown\.org\/series\/\d+/;
const bookmark_form_url = /https:\/\/archiveofourown\.org\/bookmarks\/\d+\/edit/;
const num_separators = /[\.,]/;
const wordcount_tags = {
"0-99": "Wordcount: 0-100",
"100-999": "Wordcount: 100-1.000",
"1000-4999": "Wordcount: 1.000-5.000",
"5000-9999": "Wordcount: 5.000-10.000",
"10000-29999": "Wordcount: 10.000-30.000",
"30000-49999": "Wordcount: 30.000-50.000",
"50000-99999": "Wordcount: 50.000-100.000",
"100000-149999": "Wordcount: 100.000-150.000",
"150000-9999999999999": "Wordcount: Over 150.000"
}
function autopopulate_wordcount() {
if (this === window) {
return; // Don't know why, but the id selector also returns window?
}
let dds = $(this).find("fieldset > fieldset > dl > dd");
let tag_dd = dds[1];
let tag_list = $(tag_dd).children("ul");
let tag_input = $(this).find("[id=bookmark_tag_string_autocomplete]");
tag_input = tag_input[0]; // get actual DOM node
// what page is this? can we find the wordcount?
let href = window.location.href;
let wordcount = null;
if (!href.match(work_bookmarks_url) && href.match(work_url)) {
// Work page, need to look in slightly different place for wordcount
wordcount = $("#main div.wrapper dd.stats dd.words");
} else if (href.match(series_url)) {
// Series page, need to look in slightly different place for wordcount
wordcount = $("#main div.wrapper dd.stats dd").first();
} else if (href.match(bookmark_form_url)) {
// Dedicated bookmark edit page, wordcount not accessable
return;
} else {
// All other pages have the bookmark form nested within a bookmark article
let bookmark_article = $(this).closest("li.bookmark[role=article]");
wordcount = $(bookmark_article).find("dl.stats > dd.words");
// Series listings have wordcount laid out differently
if (wordcount.length === 0) {
wordcount = $(bookmark_article).find("dl.stats > dd").first();
}
}
wordcount = wordcount.text();
wordcount = wordcount.replace(num_separators, "");
wordcount = parseInt(wordcount);
let tag = "";
for (const [range, tag_str] of Object.entries(wordcount_tags)) {
let [ low, high ] = range.split("-");
[ low, high ] = [ parseInt(low), parseInt(high) ];
if (low <= wordcount && wordcount <= high) {
tag = tag_str;
break;
}
}
// adding tag spoofing from: https://github.com/LazyCats-dev/ao3-podfic-posting-helper/blob/main/src/inject.js
const event = new InputEvent('input', {bubbles: true, data: tag});
tag_input.value = tag;
// Replicates the value changing.
tag_input.dispatchEvent(event);
// Replicates the user hitting comma.
tag_input.dispatchEvent(new KeyboardEvent('keydown', {'key': ','}));
}
function set_context(j_node) {
autopopulate_wordcount.call(j_node);
}
// $("[id='idofelement']") due to multiple elements with same id being possible on ao3 bookmark page
waitForKeyElements("[id='bookmark-form']", set_context, false /*false = continue searching after first*/);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment