Refactored overlay.js to be Object Oriented

This commit is contained in:
SwingTheVine 2025-07-26 21:09:39 -04:00
parent 87657ae1c2
commit 08eae5c094
7 changed files with 134 additions and 9 deletions

File diff suppressed because one or more lines are too long

View file

@ -35,7 +35,7 @@
<a href="https://github.com/SwingTheVine/Wplace-BlueMarble/blob/main/LICENSE.txt" target="_blank"><img alt="Software License: MPL-2.0" src="https://img.shields.io/badge/Software_License-MPL--2.0-brightgreen?style=flat"></a>
<a href="https://discord.gg/tpeBPy46hf" target="_blank"><img alt="Contact Me" src="https://img.shields.io/badge/Contact_Me-gray?style=flat&logo=Discord&logoColor=white&logoSize=auto&labelColor=cornflowerblue"></a>
<a href="" target="_blank"><img alt="WakaTime" src="https://img.shields.io/badge/Coding_Time-10hrs_0mins-blue?style=flat&logo=wakatime&logoColor=black&logoSize=auto&labelColor=white"></a>
<a href="" target="_blank"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-109-black?style=flat"></a>
<a href="" target="_blank"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-114-black?style=flat"></a>
<a href="" target="_blank"><img alt="Total Lines of Code" src="https://tokei.rs/b1/github/SwingTheVine/Wplace-BlueMarble?category=code"></a>
<a href="" target="_blank"><img alt="Total Comments" src="https://tokei.rs/b1/github/SwingTheVine/Wplace-BlueMarble?category=comments"></a>
<a href="" target="_blank"><img alt="Build" src="https://github.com/SwingTheVine/Wplace-BlueMarble/actions/workflows/build.yml/badge.svg"></a>

4
package-lock.json generated
View file

@ -7,7 +7,7 @@
"devDependencies": {
"esbuild": "^0.25.0"
},
"version": "0.43.1"
"version": "0.43.6"
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.8",
@ -467,5 +467,5 @@
}
}
},
"version": "0.43.1"
"version": "0.43.6"
}

View file

@ -1,6 +1,6 @@
{
"name": "wplace-bluemarble",
"version": "0.43.1",
"version": "0.43.6",
"type": "module",
"scripts": {
"build": "node build/build.js",

View file

@ -1,7 +1,7 @@
// ==UserScript==
// @name Blue Marble
// @namespace https://github.com/SwingTheVine/
// @version 0.43.1
// @version 0.43.6
// @description A userscript to automate and/or enhance the user experience on Wplace.live. Make sure to comply with the site's Terms of Service, and rules! This script is not affiliated with Wplace.live in any way, use at your own risk. This script is not affiliated with TamperMonkey. The author of this userscript is not responsible for any damages, issues, loss of data, or punishment that may occur as a result of using this script. This script is provided "as is" under the MPL-2.0 license. The "Blue Marble" icon is licensed under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication. The image is owned by NASA.
// @author SwingTheVine
// @license MPL-2.0

View file

@ -80,7 +80,13 @@ const apiHandler = new ApiHandler(coordsHandler); // Constructs a new ApiHandler
overlay.setApiHandler(apiHandler); // Sets the API handler
overlay.create(); // Deploys the overlay to the page
// Deploys the overlay to the page
overlay.addDiv({'id': 'bm-overlay', 'style': 'top: 10px; right: 75px;'})
.addDiv({'id': 'bm-contain-header'})
.addDiv({'id': 'bm-bar-drag'}).buildElement()
.addImg({'alt': 'Blue Marble Icon', 'src': 'https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/src/assets/Favicon.png'}).buildElement()
.buildOverlay(document.body);
apiHandler.spontaneousResponseListener(overlay); // Reads spontaneous fetch responces
console.log(`${name} (${version}) userscript has loaded!`);

View file

@ -13,8 +13,14 @@ export class Overlay {
constructor(name, version) {
this.name = name; // Name of userscript
this.version = version; // Version of userscript
this.apiHandler = null; // The API handler instance. Later populated when setApiHandler is called
this.outputStatusId = 'bm-output-status'; // ID for status element
this.overlay = null; // The overlay root DOM HTMLElement
this.currentParent = null; // The current parent HTMLElement in the overlay
this.parentStack = []; // Tracks the parent elements BEFORE the currentParent so we can nest elements
}
/** Populates the apiHandler variable with the apiHandler class.
@ -23,6 +29,119 @@ export class Overlay {
*/
setApiHandler(apiHandler) {this.apiHandler = apiHandler;}
/** Creates an element.
* For internal use of the {@link Overlay} class
* @param {string} tag - The tag name as a string.
* @param {Object.<string, any>} [properties={}] - The DOM properties of the element.
* @returns {HTMLElement} HTML Element
* @since 0.43.2
*/
createElement(tag, properties = {}, additionalProperties={}) {
const element = document.createElement(tag); // Creates the element
// If this is the first element made...
if (!this.overlay) {
this.overlay = element; // Declare it the highest overlay element
this.currentParent = element;
} else {
this.currentParent.appendChild(element); // ...else delcare it the child of the last element
this.parentStack.push(this.currentParent);
this.currentParent = element;
}
// For every passed in property (shared by all like-elements), apply the it to the element
for (const [property, value] of Object.entries(properties)) {
element[property] = value;
}
// For every passed in additional property, apply the it to the element
for (const [property, value] of Object.entries(additionalProperties)) {
element[property] = value;
}
return element;
}
/** Finishes building an element.
* Call this after you are finished adding children.
* If the element will have no children, call it anyways.
* @returns {Overlay} Overlay class instance (this)
* @since 0.43.2
* @example
* overlay
* .addDiv()
* .addHeader1().buildElement() // Breaks out of the <h1>
* .addParagraph().buildElement() // Breaks out of the <p>
* .buildElement() // Breaks out of the <div>
* .addHr() // Since there are no more elements, calling buildElement() is optional
* .buildOverlay();
*/
buildElement() {
if (this.parentStack.length > 0) {
this.currentParent = this.parentStack.pop();
}
return this;
}
/** Finishes building the overlay and displays it.
* Call this when you are done chaining methods.
* @param {HTMLElement} parent - The parent HTMLElement this overlay should be appended to as a child.
* @since 0.43.2
* @example
* overlay
* .addDiv()
* .addParagraph().buildElement()
* .buildElement()
* .buildOverlay(document.body); // Adds DOM structure to document body
* // <div><p></p></div>
*/
buildOverlay(parent) {
parent.appendChild(this.overlay);
}
/** Adds a `<div>` to the overlay.
* This `<div>` element will have properties shared between all `<div>` elements in the overlay.
* You can override the shared properties by using a callback.
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `<div>` that are NOT shared between all overlay `<div>` elements. These should be camelCase.
* @param {function(HTMLElement):void} [callback=()=>{}] - Additional modification to the div.
* @returns {Overlay} Overlay class instance (this)
* @since 0.43.2
* @example
* // Assume all <div> elements have a shared class (e.g. {'className': 'bar'})
* overlay.addDiv({'id': 'foo'}).buildOverlay();
* // <div id="foo" class="bar"></div>
*/
addDiv(additionalProperties = {}, callback = () => {}) {
const properties = {}; // Shared <div> DOM properties
const div = this.createElement('div', properties, additionalProperties); // Creates the div element
callback(div); // Runs (optionally) passed in script
return this;
}
/** Adds a `<img>` to the overlay.
* This `<img>` element will have properties shared between all `<img>` elements in the overlay.
* You can override the shared properties by using a callback.
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `<img>` that are NOT shared between all overlay `<img>` elements. These should be camelCase.
* @param {function(HTMLElement):void} [callback=()=>{}] - Additional modification to the img.
* @returns {Overlay} Overlay class instance (this)
* @since 0.43.2
* @example
* // Assume all <img> elements have a shared class (e.g. {'className': 'bar'})
* overlay.addimg({'id': 'foo'}).buildOverlay();
* // <img id="foo" class="bar">
*/
addImg(additionalProperties = {}, callback = () => {}) {
const properties = {}; // Shared <div> DOM properties
const img = this.createElement('img', properties, additionalProperties); // Creates the div element
callback(img); // Runs (optionally) passed in script
return this;
}
/** Creates and deploys the overlay element
* @since 0.0.2
*/