NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name AtmoBurn Services - labels
// @namespace sk.seko
// @license MIT
// @description Rename fleet or colony; visible only localy (in your browser) - it's a client side "rename"
// @updateURL https://openuserjs.org/meta/rsenderak/abs-labels.meta.js
// @downloadURL https://openuserjs.org/install/rsenderak/abs-labels.user.js
// @match https://*.atmoburn.com/*
// @exclude https://*.atmoburn.com/extras/view_universe.php*
// @version 2.3
// @grant none
// ==/UserScript==
// v1.0 - script published at openuserjs.org
// v1.1 - all fleet and colony names are replaced (by labels, if defined) on any page
// v1.2 - fixed bug where original name was not displayed as tooltip, sometimes
// v1.2.1 - esversion set to 11
// v2.0 - new storage format (migrated automatically); small fixes
// v2.1 - excluded universe map (at least for now)
// v2.1.1 - small fix for modal windows
// v2.2 - migrated data (from 1.x) are fixed when detail screen is opened for the first time
// v2.2.1 - fleet name matching fix
// v2.2.2 - fleet ID matching fix
// v2.3 - tooltips now shows original fleet/colony name
/* jshint esversion: 11 */
/* jshint node: true */
"use strict";
const WF_BASE_URL=`https://${window.location.host}`;
// local DB (browser database) keys
const KEY_FLEET_LABELS = "abs.fleetLabels";
const KEY_COLONY_LABELS = "abs.colonyLabels";
// global variables (fleets)
var fleetId = parseFleetIDFromURL(); // fleet ID from URL; or null if not on the right page
var fleetHeadline = fleetId ? byId("pageHeadLine") : null; // fleet name element from fleet detail page; or null
// global variables (colonies)
var colonyId = parseColonyIDFromURL(); // colony ID from URL; or null if not on the right page
var colonyHeadline = colonyId ? byId("midcolumn").querySelector(".pagetitle") : null; // colony name element from colony detail page; or null
// Get element by ID.
function byId(ele) {
return document.getElementById(ele);
}
function getFleetLabels() {
const v = localStorage.getItem(KEY_FLEET_LABELS);
return v ? JSON.parse(v) : {};
}
function getColonyLabels() {
const v = localStorage.getItem(KEY_COLONY_LABELS);
return v ? JSON.parse(v) : {};
}
// set new "label" for record ID "rid", with original name "current"; remove label if label=null
function storeLabel(key, labelMap, rid, label, current) {
if (label) { // set label
const rec = labelMap[rid];
if (rec) { // label existed, just replace it
rec.l = label;
} else { // no label, store label and original name as well
labelMap[rid] = {"l": label, "n": current};
}
} else { // remove label
delete labelMap[rid];
}
localStorage.setItem(key, JSON.stringify(labelMap));
return labelMap[rid];
}
function parseFleetIDFromURL() {
let m = document.URL.match(/(?:[\?\&]fleet=|\/fleet\/)(\d+)/);
if (m && m[1]) {
return parseInt(m[1]);
}
return null;
}
function parseColonyIDFromURL() {
let m = document.URL.match(/[\?\&]colony=(\d+)/);
if (m && m[1]) {
return parseInt(m[1]);
}
return null;
}
// set or reset label
function displayLabel(node, label, oldLabel) {
if (label) { // set new label
node.innerHTML = label;
}
if (oldLabel) {
node.title = oldLabel;
}
}
// TEMPORARY: check/fix original name if migrated
function checkMigration(labelMap, key, node, record) {
if (record && record.l == record.n) {
try {
if (node.innerHTML && node.innerHTML != record.n) {
console.log(`ABS-label: Fixing migrated from "${record.n}" to "${node.innerHTML}"`);
record.n = node.innerHTML;
localStorage.setItem(key, JSON.stringify(labelMap));
}
} catch (error) {
console.error(error);
}
}
}
function displayFleetLabel(fid, label, oldLabel) {
function getTargetFleetId(href) {
if (!href) {
return null;
}
let m = null;
if (href.match(/tfleet=/)) {
m = href.match(/\/fleet\.php.*\Wtfleet=(\d+)/);
} else {
m = href.match(/\/fleet\.php.*\Wfleet=(\d+)/);
}
return m ? parseInt(m[1]) : null;
}
if (label) {
document.querySelectorAll(`a[href*="fleet=${fid}"]`).forEach((node) => {
try {
// replace only if URL really matches
if (fid == getTargetFleetId(node.href)) {
// and if content matches oldLabel (FIXME: for migrated values, there is a hack: label == oldLabel
if (!oldLabel || label == oldLabel || node.textContent == oldLabel || node.textContent.endsWith(oldLabel)) {
displayLabel(node, label, oldLabel);
}
}
} catch (error) {
console.error(error);
}
});
}
}
function displayColonyLabel(cid, label, oldLabel) {
if (label) {
document.querySelectorAll(`a[href*="colony=${cid}"]`).forEach((node) => {
try {
const m = node.href.match(/\/view_colony\.php.*\Wcolony=(\d+)/);
// replace only if URL really matches
if (m && cid == parseInt(m[1])) {
// and if content matches oldLabel (FIXME: for migrated values, there is a hack: label == oldLabel
if (!oldLabel || label == oldLabel || node.textContent == oldLabel) {
displayLabel(node, label, oldLabel);
}
}
} catch (error) {
console.error(error);
}
});
}
}
function displayFleetLabels() {
const labelMap = getFleetLabels();
Object.entries(labelMap).forEach(([rid, record]) => {
displayFleetLabel(rid, record.l, record.n);
});
if (fleetId && fleetHeadline) {
const record = labelMap[fleetId];
checkMigration(labelMap, KEY_FLEET_LABELS, fleetHeadline, record);
displayLabel(fleetHeadline, record?.l, record?.n);
}
}
function displayColonyLabels() {
const labelMap = getColonyLabels();
Object.entries(labelMap).forEach(([rid, record]) => {
displayColonyLabel(rid, record.l, record.n);
});
if (colonyId && colonyHeadline) {
const record = labelMap[colonyId];
checkMigration(labelMap, KEY_COLONY_LABELS, colonyHeadline, record);
displayLabel(colonyHeadline, record?.l, record?.n);
}
}
function editFleetLabel() {
const headlineText = fleetHeadline.textContent?.trim();
let val = prompt("New name, or empty string for original name", headlineText);
if (val === null) {
return; // dialog cancelled; quitting
}
const labelMap = getFleetLabels();
let record = labelMap[fleetId];
// reset to original name
if (record) {
displayFleetLabel(fleetId, record.n, record.l);
displayLabel(fleetHeadline, record.n, record.l);
}
// store new label
record = storeLabel(KEY_FLEET_LABELS, labelMap, fleetId, val, headlineText);
// display new label
if (record) {
displayFleetLabel(fleetId, record.l, record.n);
displayLabel(fleetHeadline, record.l, record.n);
}
}
function editColonyLabel() {
const headlineText = colonyHeadline.textContent?.trim();
let val = prompt("New name, or empty string for original name", headlineText);
if (val === null) {
return; // dialog cancelled; quitting
}
const labelMap = getColonyLabels();
let record = labelMap[colonyId];
// reset to original name
if (record) {
displayColonyLabel(colonyId, record.n, record.l);
displayLabel(colonyHeadline, record.n, record.l);
}
// store new label
record = storeLabel(KEY_COLONY_LABELS, labelMap, colonyId, val, headlineText);
// display new label
if (record) {
displayColonyLabel(colonyId, record.l, record.n);
displayLabel(colonyHeadline, record.l, record.n);
}
}
function addLabelEditIcon(headline, callback) {
const tooltip = "Change the name; enter empty string to reset it back to original";
const editIcon = document.createElement('span');
editIcon.innerHTML = ` <span id="labelEdit" style="font-size: 50%" class="fa-light fa-pen" title="${tooltip}"></span>`;
headline.after(editIcon);
byId("labelEdit").addEventListener('click', callback);
}
function addFleetLabelEditIcon() {
addLabelEditIcon(fleetHeadline, editFleetLabel);
}
function addColonyLabelEditIcon() {
// fix headline html so we can add an edit icon
const colonyName = colonyHeadline.textContent.trim();
colonyHeadline.innerHTML = `<span id="pageHeadLine">${colonyName}</span>`;
colonyHeadline = byId("pageHeadLine");
// add an edit icon
addLabelEditIcon(colonyHeadline, editColonyLabel);
}
// TEMPORARY: migrate if needed (from version 1.2.X)
function migrateFrom12() {
function migrateKey(fromKey, toKey) {
function convertMap(m) {
Object.keys(m).forEach((key) => {
// convert "label" to object with old and new name, and timestamp
// note: old and new names will be equal to label for migrated data; it's a temporary anyway
m[key] = {'l':m[key], 'n':m[key]};
});
}
const labels = localStorage.getItem(fromKey);
if (labels) {
const m = labels ? JSON.parse(labels) : {};
convertMap(m);
localStorage.setItem(toKey, JSON.stringify(m));
localStorage.removeItem(fromKey);
}
}
migrateKey("abs.flabs", KEY_FLEET_LABELS);
migrateKey("abs.clabs", KEY_COLONY_LABELS);
}
// migrate from older storage format if needed
migrateFrom12();
// show edit icon on fleet detail page title
if (fleetId && fleetHeadline) {
addFleetLabelEditIcon();
}
// show edit icon on colony detail page title
if (colonyId && colonyHeadline) {
addColonyLabelEditIcon();
}
// replace labels for fleets and/or colonies on the page
displayFleetLabels();
displayColonyLabels();