Răsfoiți Sursa

ref: use css loader

Sv443 1 an în urmă
părinte
comite
53e39f3375

+ 4 - 2
.gitignore

@@ -1,5 +1,7 @@
 node_modules/
-out/
 test.js
 test.ts
-*.map
+
+dist/*.map
+dist/out/
+dist/*.css

+ 0 - 6
global.d.ts

@@ -10,9 +10,3 @@ declare module "*.md" {
   const htmlContent: string;
   export default htmlContent;
 }
-
-declare module "*.css" {
-  /** Content of the CSS file as a string */
-  const cssContent: string;
-  export default cssContent;
-}

Fișier diff suprimat deoarece este prea mare
+ 672 - 119
package-lock.json


+ 7 - 5
package.json

@@ -38,12 +38,14 @@
     "@types/node": "^20.2.4",
     "@typescript-eslint/eslint-plugin": "^5.59.8",
     "@typescript-eslint/parser": "^5.59.7",
+    "css-loader": "^6.8.1",
+    "css-minimizer-webpack-plugin": "^5.0.0",
     "eslint": "^7.32.0",
     "express": "^4.18.2",
     "html-loader": "^4.2.0",
     "markdown-loader": "^8.0.0",
+    "mini-css-extract-plugin": "^2.7.6",
     "nodemon": "^2.0.22",
-    "raw-loader": "^4.0.2",
     "ts-loader": "^9.4.3",
     "ts-node": "^10.9.1",
     "tslib": "^2.5.2",
@@ -57,13 +59,13 @@
   ],
   "nodemonConfig": {
     "watch": [
-      "src/*",
-      "tools/*"
+      "src/**",
+      "tools/**"
     ],
-    "ext": "ts,js,json",
+    "ext": "ts,js,json,html,css",
     "ignore": [
       "dist/*",
       "dev/*"
     ]
   }
-}
+}

+ 4 - 1
src/BetterYTM.user.ts

@@ -1,6 +1,6 @@
 import { getFeatures } from "./config";
 import { dbg, info } from "./constants";
-import { getDomain, initSiteEvents } from "./utils";
+import { addGlobalStyle, getDomain, initSiteEvents } from "./utils";
 import {
   // layout
   initQueueButtons, addWatermark,
@@ -22,6 +22,9 @@ async function init() {
     console.log(`${info.name} v${info.version} (${info.lastCommit}) - ${info.namespace}`);
     console.log(`Powered by lots of ambition and my song metadata API: ${geniUrlBase}`);
 
+    // post-build these double quotes are replaced by backticks
+    addGlobalStyle("{{GLOBAL_STYLE}}", "global");
+
     document.addEventListener("DOMContentLoaded", onDomLoad);
   }
   catch(err) {

+ 40 - 0
src/features/layout.css

@@ -0,0 +1,40 @@
+/* #MARKER watermark */
+
+#betterytm-watermark {
+    font-size: 10px;
+    display: inline-block;
+    position: absolute;
+    left: 45px;
+    top: 46px;
+    z-index: 10;
+    color: white;
+    text-decoration: none;
+    cursor: pointer;
+}
+
+@media(max-width: 615px) {
+    #betterytm-watermark {
+        display: none;
+    }
+}
+
+#betterytm-watermark:hover {
+    text-decoration: underline;
+}
+
+/* #MARKER queue buttons */
+/* TODO: */
+
+.side-panel.modular ytmusic-player-queue-item .song-info.ytmusic-player-queue-item {
+    position: relative;
+}
+
+.side-panel.modular ytmusic-player-queue-item .song-info .bytm-queue-btn-container {
+    display: none;
+    position: absolute;
+    right: 0;
+}
+
+.side-panel.modular ytmusic-player-queue-item:hover .song-info .bytm-queue-btn-container {
+    display: inline-block;
+}

+ 3 - 46
src/features/layout.ts

@@ -3,6 +3,7 @@ import { getFeatures } from "../config";
 import { addGlobalStyle, insertAfter, siteEvents } from "../utils";
 import type { FeatureConfig } from "../types";
 import { openMenu } from "./menu/menu_old";
+import "./layout.css";
 
 let features: FeatureConfig;
 
@@ -12,9 +13,7 @@ export async function preInitLayout() {
 
 //#MARKER watermark
 
-/**
- * Adds a watermark beneath the logo
- */
+/** Adds a watermark beneath the logo */
 export function addWatermark() {
   const watermark = document.createElement("span");
   watermark.id = "betterytm-watermark";
@@ -24,37 +23,9 @@ export function addWatermark() {
 
   watermark.addEventListener("click", () => openMenu());
 
-
-  const style = `\
-#betterytm-watermark {
-  font-size: 10px;
-  display: inline-block;
-  position: absolute;
-  left: 45px;
-  top: 46px;
-  z-index: 10;
-  color: white;
-  text-decoration: none;
-  cursor: pointer;
-}
-
-@media(max-width: 615px) {
-  #betterytm-watermark {
-    display: none;
-  }
-}
-
-#betterytm-watermark:hover {
-  text-decoration: underline;
-}`;
-
-  addGlobalStyle(style, "watermark");
-
-
   const logoElem = document.querySelector("#left-content") as HTMLElement;
   insertAfter(logoElem, watermark);
 
-
   dbg && console.log("BetterYTM: Added watermark element:", watermark);
 }
 
@@ -91,7 +62,7 @@ export function setVolSliderSize() {
   width: ${size}px !important;
 }`;
 
-  addGlobalStyle(style, "vol_slider_size");
+  addGlobalStyle(style, "vol-slider");
 }
 
 /** Sets the `step` attribute of the volume slider */
@@ -111,20 +82,6 @@ export function initQueueButtons() {
     }
   });
 
-  const queueBtnsStyle = `\
-.side-panel.modular ytmusic-player-queue-item .song-info.ytmusic-player-queue-item {
-  position: relative;
-}
-.side-panel.modular ytmusic-player-queue-item .song-info .bytm-queue-btn-container {
-  display: none;
-  position: absolute;
-  right: 0;
-}
-.side-panel.modular ytmusic-player-queue-item:hover .song-info .bytm-queue-btn-container {
-  display: inline-block;
-}`;
-  addGlobalStyle(queueBtnsStyle, "queue-btns");
-
   const queueItems = document.querySelectorAll("#contents.ytmusic-player-queue > ytmusic-player-queue-item");
   if(queueItems.length === 0)
     return;

+ 24 - 0
src/features/lyrics.css

@@ -0,0 +1,24 @@
+#betterytm-lyrics-button {
+    align-items: center;
+    justify-content: center;
+    position: relative;
+    vertical-align: middle;
+
+    margin-left: 8px;
+    width: 40px;
+    height: 40px;
+    border-radius: 100%;
+    background-color: transparent;
+}
+
+#betterytm-lyrics-button:hover {
+    background-color: #383838;
+}
+
+#betterytm-lyrics-img {
+    display: inline-block;
+    z-index: 10;
+    width: 24px;
+    height: 24px;
+    padding: 5px;
+}

+ 2 - 29
src/features/lyrics.ts

@@ -1,5 +1,6 @@
 import { dbg, triesInterval, triesLimit } from "../constants";
-import { addGlobalStyle, insertAfter } from "../utils";
+import { insertAfter } from "../utils";
+import "./lyrics.css";
 
 /** Base URL of geniURL */
 export const geniUrlBase = "https://api.sv443.net/geniurl";
@@ -37,34 +38,6 @@ export async function addMediaCtrlGeniusBtn(): Promise<unknown> {
   linkElem.style.visibility = gUrl ? "initial" : "hidden";
   linkElem.style.display = gUrl ? "inline-flex" : "none";
 
-  const style = `\
-    #betterytm-lyrics-button {
-      align-items: center;
-      justify-content: center;
-      position: relative;
-      vertical-align: middle;
-
-      margin-left: 8px;
-      width: 40px;
-      height: 40px;
-      border-radius: 100%;
-      background-color: transparent;
-    }
-
-    #betterytm-lyrics-button:hover {
-      background-color: #383838;
-    }
-
-    #betterytm-lyrics-img {
-      display: inline-block;
-      z-index: 10;
-      width: 24px;
-      height: 24px;
-      padding: 5px;
-    }`;
-
-  addGlobalStyle(style, "lyrics");
-
 
   const imgElem = document.createElement("img");
   imgElem.id = "betterytm-lyrics-img";

+ 17 - 0
src/features/menu/menu.css

@@ -1,3 +1,20 @@
+/* #bytm-menu-backdrop {
+    display: none;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+}
+
+#bytm-menu-backdrop[data-menu-open="true"] {
+    display: flex;
+} */
+
+#bytm-menu-header-container {
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+}
+
 #bytm-menu-header-option {
     display: "flex";
     justify-content: center;

+ 4 - 7
src/features/menu/menu.html

@@ -1,5 +1,5 @@
 <dialog id="bytm-menu-dialog">
-    <div id="bytm-menu-header">
+    <div id="bytm-menu-header-container">
         <div class="bytm-menu-header-option" id="bytm-menu-tab-options-header" data-active="true">
             <h3>Options</h3>
         </div>
@@ -11,11 +11,8 @@
         </div>
     </div>
     <div id="bytm-menu-body">
-        <div class="bytm-menu-tab-content" id="bytm-menu-tab-options-content" data-active="true">
-        </div>
-        <!-- <div class="bytm-menu-tab-content" id="bytm-menu-tab-info-content" data-active="false">
-        </div> -->
-        <div class="bytm-menu-tab-content" id="bytm-menu-tab-changelog-content" data-active="false">
-        </div>
+        <div class="bytm-menu-tab-content" id="bytm-menu-tab-options-content" data-active="true"></div>
+        <!-- <div class="bytm-menu-tab-content" id="bytm-menu-tab-info-content" data-active="false"></div> -->
+        <div class="bytm-menu-tab-content" id="bytm-menu-tab-changelog-content" data-active="false"></div>
     </div>
 </dialog>

+ 30 - 55
src/features/menu/menu.ts

@@ -1,7 +1,11 @@
-import { addGlobalStyle } from "../../utils";
-import changelog from "../../../changelog.md";
+// import { addGlobalStyle } from "../../utils";
+import { triesInterval, triesLimit } from "../../constants";
+
+import changelogContent from "../../../changelog.md";
 import menuContent from "./menu.html";
-import menuStyle from "./menu.css";
+import "./menu.css";
+
+//#MARKER menu
 
 /**
  * These are the base selector values for the menu tabs  
@@ -15,17 +19,19 @@ const tabsSelectors = {
 };
 
 export function initMenu() {
-  initChangelog();
-
-  addGlobalStyle(menuStyle, "menu2"); // TODO
+  // addGlobalStyle(menuStyle, "menu2"); // TODO
 
   document.addEventListener("DOMContentLoaded", () => {
-    // create menu backdrop element
-    const backdrop = document.createElement("div");
-    backdrop.id = "bytm-menu-backdrop";
-    backdrop.style.display = "none";
+    // create menu container
+    const menuContainer = document.createElement("div");
+    menuContainer.id = "bytm-menu-container";
     // add menu html
-    backdrop.innerHTML = menuContent;
+    menuContainer.innerHTML = menuContent;
+
+    document.body.appendChild(menuContainer);
+
+    initOptionsContent();
+    initChangelogContent();
   });
 }
 
@@ -53,52 +59,21 @@ export function closeMenu() {
   (document.querySelector("#bytm-menu-dialog") as HTMLDialogElement).close();
 }
 
-//#MARKER changelog
+//#MARKER menu tab contents
 
-async function initChangelog() {
-  //   const clStyle = `\
-  // #betterytm-changelog-bg {
-  //   display: block;
-  //   position: fixed;
-  //   width: 100vw;
-  //   height: 100vh;
-  //   top: 0;
-  //   left: 0;
-  //   z-index: 15;
-  //   background-color: rgba(0, 0, 0, 0.6);
-  // }
+let optionsTries = 0;
 
-  // #betterytm-changelog {
-  //   display: inline-block;
-  //   position: fixed;
-  //   width: 50vw;
-  //   height: auto;
-  //   min-height: 500px;
-  //   left: 25vw;
-  //   top: 25vh;
-  //   z-index: 16;
-  //   overflow: auto;
-  //   padding: 8px;
-  //   color: #fff;
-  //   background-color: #212121;
-  // }
-
-  // #betterytm-changelog-close {
-  //   cursor: pointer;
-  // }`;
-
-
-  // console.log("#DEBUG _CHANGELOG:", changelog);
-  // const cl = document.createElement("div");
-  // cl.style.position = "fixed";
-  // cl.style.top = "0";
-  // cl.style.left = "0";
-  // cl.style.minWidth = "500px";
-  // cl.style.minHeight = "500px";
-  // cl.style.overflowY = "scroll";
-  // cl.innerHTML = changelog;
-  // document.addEventListener("DOMContentLoaded", () => document.body.appendChild(cl));
+function initOptionsContent(): unknown {
+  const tab = document.querySelector("#bytm-menu-tab-options-content");
+  if(!tab)
+    return optionsTries++ < triesLimit ? setTimeout(initOptionsContent, triesInterval) : undefined;
+}
 
+let changelogTries = 0;
 
-  void ["TODO", changelog];
+function initChangelogContent(): unknown {
+  const tab = document.querySelector("#bytm-menu-tab-changelog-content");
+  if(!tab)
+    return changelogTries++ < triesLimit ? setTimeout(initChangelogContent, triesInterval) : undefined;
+  tab.innerHTML = changelogContent;
 }

+ 14 - 7
src/tools/post-build.ts

@@ -6,7 +6,7 @@ import pkg from "../../package.json" assert { type: "json" };
 
 const repo = "Sv443/BetterYTM";
 const userscriptDistFile = "BetterYTM.user.js";
-const userscriptDistPath = `dist/${userscriptDistFile}`;
+const distFolderPath = "./dist/";
 const scriptUrl = `https://raw.githubusercontent.com/${repo}/main/dist/${userscriptDistFile}`;
 /** Which URLs should the userscript be active on - see https://wiki.greasespot.net/Metadata_Block#%40match */
 const matchUrls = [
@@ -45,7 +45,9 @@ ${matchDirectives}\
  █▄▄▀ ▀▄▄ ▀▄▄ ▀▄▄ ▀▄▄ █   █   █  █   █
 
          Made with ❤️ by Sv443
- I welcome every contribution on GitHub! */
+ I welcome every contribution on GitHub!
+   https://github.com/Sv443/BetterYTM
+*/
 
 /* Disclaimer: I am not affiliated with YouTube, Google, Alphabet, Genius or anyone else */
 /* C&D this 🖕 */
@@ -53,17 +55,22 @@ ${matchDirectives}\
 
 (async () => {
   try {
+    const rootPath = join(dirname(fileURLToPath(import.meta.url)), "../../");
     const lastCommitSha = await getLastCommitSha();
-    const path = join(dirname(fileURLToPath(import.meta.url)), `../../${userscriptDistPath}`);
+
+    const scriptPath = join(rootPath, distFolderPath, userscriptDistFile);
+    const globalStylePath = join(rootPath, distFolderPath, "main.css");
+    const globalStyle = String(await readFile(globalStylePath)).replace(/\n\s*\/\*.+\*\//gm, "");
 
     // read userscript and inject build number
-    const userscript = String(await readFile(path))
-      .replace(/{{BUILD_NUMBER}}/gm, lastCommitSha);
+    const userscript = String(await readFile(scriptPath))
+      .replace(/\/?\*?{{BUILD_NUMBER}}\*?\/?/gm, lastCommitSha)
+      .replace(/"\/?\*?{{GLOBAL_STYLE}}\*?\/?"/gm, `\`${globalStyle}\``);
 
-    await writeFile(path, `${header}\n${userscript}${userscript.endsWith("\n") ? "" : "\n"}`);
+    await writeFile(scriptPath, `${header}\n${userscript}${userscript.endsWith("\n") ? "" : "\n"}`);
 
     console.info(`Successfully added the userscript header. Last commit SHA is ${lastCommitSha}`);
-    console.info(`Final size is \x1b[32m${((await stat(path)).size / 1024).toFixed(2)} KiB\x1b[0m\n`);
+    console.info(`Final size is \x1b[32m${((await stat(scriptPath)).size / 1024).toFixed(2)} KiB\x1b[0m\n`);
   }
   catch(err) {
     console.error("Error while adding userscript header:");

+ 1 - 1
src/utils.ts

@@ -113,7 +113,7 @@ export function insertAfter(beforeNode: HTMLElement, afterNode: HTMLElement) {
 /**
  * Adds global CSS style through a `<style>` element in the document's `<head>`
  * @param style CSS string
- * @param ref Reference name that is included in the `<style>`'s ID - defaults to a random number if left undefined
+ * @param ref Reference name that is included in the `<style>`'s ID - prefixed with `betterytm-style-` - defaults to a random number if left undefined
  */
 export function addGlobalStyle(style: string, ref?: string) {
   if(typeof ref !== "string" || ref.length === 0)

+ 17 - 3
webpack.config.js

@@ -2,6 +2,9 @@ import { dirname, join } from "path";
 import { exec } from "child_process";
 import { fileURLToPath } from "url";
 
+import MiniCssExtractPlugin from "mini-css-extract-plugin";
+import CssMinimizerPlugin from "css-minimizer-webpack-plugin";
+
 export default {
   entry: "./src/BetterYTM.user.ts",
   mode: "production",
@@ -31,12 +34,23 @@ export default {
         ],
       },
       {
-        test: /\.css$/i,
-        use: "raw-loader",
+        test: /.css$/,
+        use: [MiniCssExtractPlugin.loader, "css-loader" /*, "sass-loader"*/],
       },
+      // {
+      //   test: /\.css$/i,
+      //   use: "raw-loader",
+      // },
+    ],
+  },
+  optimization: {
+    minimizer: [
+      `...`,
+      new CssMinimizerPlugin(),
     ],
   },
   plugins: [
+    new MiniCssExtractPlugin(),
     {
       apply: (compiler) => {
         compiler.hooks.afterEmit.tap("AfterEmitPlugin", () => {
@@ -49,7 +63,7 @@ export default {
     },
   ],
   resolve: {
-    extensions: [".ts", ".js"],
+    extensions: [".ts", ".js", ".css"],
   },
   output: {
     filename: "BetterYTM.user.js",

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff