Greasy Fork

Greasy Fork is available in English.

AO3: Reorder Ship Tags

Reorders relationship tags on blurbs so platonic ships (&) appear after romantic ships (/)

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name          AO3: Reorder Ship Tags
// @version       1.0.4
// @description   Reorders relationship tags on blurbs so platonic ships (&) appear after romantic ships (/)
// @author        BlackBatCat
// @match         *://archiveofourown.org/tags/*
// @match         *://archiveofourown.org/works
// @match         *://archiveofourown.org/works?*
// @match         *://archiveofourown.org/works/*
// @match         *://archiveofourown.org/users/*
// @match         *://archiveofourown.org/collections/*
// @match         *://archiveofourown.org/bookmarks*
// @match         *://archiveofourown.org/series/*
// @license       MIT
// @grant         none
// @namespace http://greasyfork.icu/users/1498004
// ==/UserScript==

(function () {
  "use strict";

  console.log("[AO3: Reorder Ship Tags] loaded.");

  function reorderItems(items, container, insertBefore = null) {
    if (items.length <= 1) return;

    const romantic = [];
    const minorOrBackground = [];
    const platonic = [];
    let needsReorder = false;

    for (let i = 0; i < items.length; i++) {
      const text = items[i].textContent;

      if (/\brelationship\b/i.test(text)) {
        if (platonic.length > 0) needsReorder = true;
        minorOrBackground.push(items[i]);
      } else if (text.includes("/")) {
        if (platonic.length > 0 || minorOrBackground.length > 0) needsReorder = true;
        romantic.push(items[i]);
      } else if (text.includes("&")) {
        platonic.push(items[i]);
      }
    }

    if (!needsReorder) return;

    romantic.forEach((li) => li.remove());
    minorOrBackground.forEach((li) => li.remove());
    platonic.forEach((li) => li.remove());

    const fragment = document.createDocumentFragment();
    romantic.forEach((li) => fragment.appendChild(li));
    minorOrBackground.forEach((li) => fragment.appendChild(li));
    platonic.forEach((li) => fragment.appendChild(li));

    if (insertBefore) {
      container.insertBefore(fragment, insertBefore);
    } else {
      container.appendChild(fragment);
    }
  }

  function reorderRelationshipTags(blurbElement) {
    const tagsContainer = blurbElement.querySelector("ul.tags");
    if (!tagsContainer) return;

    const items = tagsContainer.querySelectorAll("li.relationships");
    const referenceNode = items[0]?.nextSibling;
    reorderItems(items, tagsContainer, referenceNode);
  }

  function reorderWorkPageTags(workElement) {
    const tagsContainer = workElement.querySelector("dd.relationship.tags ul.commas");
    if (!tagsContainer) return;

    const items = tagsContainer.querySelectorAll("li");
    reorderItems(items, tagsContainer);
  }

  function reorderAllBlurbs() {
    const blurbs = document.querySelectorAll("li.blurb");
    for (let i = 0; i < blurbs.length; i++) {
      reorderRelationshipTags(blurbs[i]);
    }

    const workPages = document.querySelectorAll("dl.work.meta.group");
    for (let i = 0; i < workPages.length; i++) {
      reorderWorkPageTags(workPages[i]);
    }
  }

  // Initialize on page load
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", reorderAllBlurbs);
  } else {
    reorderAllBlurbs();
  }
})();