Buttons oben rechts + farbige SVG-Icons + Pick-a-Brick mit allen Alternativnummern + Snap-Suche + BrickOwl
// ==UserScript==
// @name BrickLink Kombi-Suchscript
// @namespace https://bricklink.com/
// @version 1.0.6
// @description Buttons oben rechts + farbige SVG-Icons + Pick-a-Brick mit allen Alternativnummern + Snap-Suche + BrickOwl
// @match https://www.bricklink.com/v2/catalog/catalogitem.page*
// @match http://www.bricklink.com/v2/catalog/catalogitem.page*
// @match https://www.bluebrixx.com/*
// @run-at document-end
// @grant none
// @license MIT
// @author Glattnoppe
// ==/UserScript==
(function() {
'use strict';
const host = location.hostname;
// ------------------------------------------------------------
// SVG ICONS (farbig, hoher Kontrast)
// ------------------------------------------------------------
const ICON_WOBRICK =
"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI0ZGRkZGRiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB4PSI0IiB5PSI4IiB3aWR0aD0iMTYiIGhlaWdodD0iOCIgcng9IjIiIGZpbGw9IiM3NzdDODAiIHN0cm9rZT0iIzQ0NCIgc3Ryb2tlLXdpZHRoPSIyIi8+PHJlY3QgeD0iNiIgeT0iNiIgd2lkdGg9IjQiIGhlaWdodD0iMyIgZmlsbD0iI0NDQ0NDQyIgc3Ryb2tlPSIjNDQ0IiBzdHJva2Utd2lkdGg9IjIiLz48cmVjdCB4PSIxNCIgeT0iNiIgd2lkdGg9IjQiIGhlaWdodD0iMyIgZmlsbD0iI0NDQ0NDQyIgc3Ryb2tlPSIjNDQ0IiBzdHJva2Utd2lkdGg9IjIiLz48L3N2Zz4=";
const ICON_PAB =
"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSI4IiBmaWxsPSIjRkZEMzAwIiBzdHJva2U9IiNBODcwMDAiIHN0cm9rZS13aWR0aD0iMiIvPjwvc3ZnPg==";
const ICON_BLUEBRIXX =
"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSI4IiBmaWxsPSIjMDA3OEVCIiBzdHJva2U9IiMwMDU2QzgiIHN0cm9rZS13aWR0aD0iMiIvPjwvc3ZnPg==";
const ICON_ALI =
"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA0aDIuNWwyIDloMTRsMi41LTdIM3YtMnoiIGZpbGw9IiNFMzAwMDAiIHN0cm9rZT0iI0IwMDAwMCIgc3Ryb2tlLXdpZHRoPSIyIi8+PGNpcmNsZSBjeD0iOSIgY3k9IjE4IiByPSIxIiBmaWxsPSIjRkZGIi8+PGNpcmNsZSBjeD0iMTUiIGN5PSIxOCIgcj0iMSIgZmlsbD0iI0ZGRiIvPjwvc3ZnPg==";
const ICON_REBRICKABLE =
"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxMCIgY3k9IjEwIiByPSI2IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0iI2ZmZiIvPjxsaW5lIHgxPSIxNCIgeTE9IjE0IiB4Mj0iMjAiIHkyPSIyMCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjIiLz48L3N2Zz4=";
const ICON_SNAP =
"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSI4IiBmaWxsPSIjNzc3IiBzdHJva2U9IiM0NDQiIHN0cm9rZS13aWR0aD0iMiIvPjwvc3ZnPg==";
const ICON_BRICKOWL =
"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSI4IiBmaWxsPSIjRjY2N0ZGIiBzdHJva2U9IiM0NDQiIHN0cm9rZS13aWR0aD0iMiIvPjxjaXJjbGUgY3g9IjkiIGN5PSIxMSIgcj0iMSIgZmlsbD0iIzAwMCIvPjxjaXJjbGUgY3g9IjE1IiBjeT0iMTEiIHI9IjEiIGZpbGw9IiMwMDAiLz48cGF0aCBkPSJNOC41IDE1YzEuNSAxLjUgNS41IDEuNSA3IDBsLTEtMS41Yy0xIDEuNS0zIDEuNS00IDBsLTEgMS41eiIgZmlsbD0iIzQ0NCIvPjwvc3ZnPg==";
function iconImg(src) {
return `<img src="${src}" style="width:14px;height:14px;vertical-align:middle;margin-right:4px;">`;
}
// ------------------------------------------------------------
// TEIL A: BRICKLINK
// ------------------------------------------------------------
if (host.includes("bricklink.com")) {
const params = new URLSearchParams(window.location.search);
const partNumber = params.get("P");
if (!partNumber) return;
// ------------------------------------------------------------
// ALTERNATIVNUMMERN AUSLESEN
// ------------------------------------------------------------
let altNumbers = [];
const altElem = [...document.querySelectorAll("td, div, span, p")]
.find(el => el.textContent.includes("Alternate Item No:"));
if (altElem) {
let text = altElem.textContent;
const idx = text.indexOf("Alternate Item No:");
if (idx !== -1) text = text.substring(idx + "Alternate Item No:".length).trim();
text = text.split("View Price Guide")[0];
text = text.split("Color")[0];
text = text.split("\n")[0];
const ids = text.match(/[0-9A-Za-z-]+/g);
if (ids) altNumbers = [...new Set(ids.map(n => n.toLowerCase()))];
}
const allIDs = [partNumber, ...altNumbers].join("+");
// ------------------------------------------------------------
// URL-Generatoren
// ------------------------------------------------------------
const wobrickUrl = `https://wobrick.com/?s=${partNumber}&post_type=product`;
const pickabrickUrl = `https://www.lego.com/de-de/pick-and-build/pick-a-brick?query=${allIDs}`;
const snapUrl = `https://snap.co/de/einzelteile?q=${partNumber}`;
const bluebrixxUrl = `https://www.bluebrixx.com/de/#/dummy?startSearch=${partNumber}`;
const aliexpressUrl = `https://de.aliexpress.com/w/wholesale-${partNumber}-moc.html`;
const rebrickableUrl = `https://rebrickable.com/parts/?get_drill_downs=&tag=&q=${partNumber}&part_cat=`;
const brickowlUrl = `https://www.brickowl.com/search/catalog?query=${partNumber}&cat=1&variant_type=0`;
// ------------------------------------------------------------
// BUTTONS
// ------------------------------------------------------------
const topRightCell = document.querySelector("table[width='100%'] td[align='right']");
if (!topRightCell) return;
function makeButton(icon, text, url, tooltip) {
const btn = document.createElement("a");
btn.href = url;
btn.target = "_blank";
btn.innerHTML = `${iconImg(icon)}${text}`;
btn.className = "blButton blButtonInput blButtonBlue bold";
btn.style.marginLeft = "6px";
btn.style.padding = "5px 8px";
btn.style.textDecoration = "none";
btn.style.color = "#eee";
btn.style.fontSize = "12px";
btn.style.whiteSpace = "nowrap";
if (tooltip) btn.title = tooltip;
return btn;
}
topRightCell.appendChild(makeButton(ICON_PAB, "PaB", pickabrickUrl, "LEGO® Pick a Brick"));
topRightCell.appendChild(makeButton(ICON_BRICKOWL, "BrOwl", brickowlUrl, "BrickOwl"));
topRightCell.appendChild(makeButton(ICON_REBRICKABLE, "Rebr", rebrickableUrl, "Rebrickable"));
topRightCell.appendChild(makeButton(ICON_SNAP, "Snap", snapUrl, "Snap.co"));
topRightCell.appendChild(makeButton(ICON_BLUEBRIXX, "Blue", bluebrixxUrl, "BlueBrixx - Hinweis: Auf der sich öffnenden BlueBrixx-Seite einmal ins Suchfeld klicken."));
topRightCell.appendChild(makeButton(ICON_WOBRICK, "Wobr", wobrickUrl, "Wobrick"));
topRightCell.appendChild(makeButton(ICON_ALI, "Ali", aliexpressUrl, "AliExpress"));
// ------------------------------------------------------------
// BB-BRICKBAR PREISBERECHNUNG (funktioniert jetzt sicher)
// ------------------------------------------------------------
const weightElem = document.querySelector("#item-weight-info");
if (weightElem) {
const weightText = weightElem.textContent.trim(); // z.B. "0.68g"
const weightMatch = weightText.match(/([\d.,]+)\s*g/i);
if (weightMatch) {
const grams = parseFloat(weightMatch[1].replace(",", "."));
if (!isNaN(grams) && grams > 0) {
const price495 = grams * (4.95 / 100);
const price395 = grams * (3.95 / 100);
const formatted495 = price495.toFixed(4).replace(".", ",") + " €";
const formatted395 = price395.toFixed(4).replace(".", ",") + " €";
// Das <font>-Element finden, das "Pack. Dim.:" enthält
const fontElem = [...document.querySelectorAll("font")]
.find(f => f.innerText.includes("Pack. Dim.:"));
if (fontElem) {
// Neue Zeile wie BrickLink selbst erzeugen
const newLine = document.createElement("div");
newLine.style.marginTop = "2px";
newLine.innerHTML = `<strong>BB-Brickbar:</strong> ${formatted495} (${formatted395})`;
// Direkt unter Pack. Dim. einfügen
fontElem.appendChild(newLine);
}
}
}
}
return;
}
// ------------------------------------------------------------
// TEIL B: BLUEBRIXX
// ------------------------------------------------------------
if (host.includes("bluebrixx.com")) {
const hash = location.hash;
if (!hash.includes("startSearch=")) return;
const params = new URLSearchParams(hash.split("?")[1]);
const part = params.get("startSearch");
if (!part) return;
const idInterval = setInterval(() => {
const currentHash = location.hash;
const match = currentHash.match(/^#([a-f0-9]{4})\//i);
if (match) {
clearInterval(idInterval);
const id = match[1];
const newHash = `#${id}/brand-categories/m=and&q=${part}`;
location.hash = newHash;
const searchInterval = setInterval(() => {
const input = document.querySelector("input[type='search'], input[placeholder*='Suche'], input[placeholder*='Search']");
if (input) {
clearInterval(searchInterval);
input.focus();
input.dispatchEvent(new Event("focus", { bubbles: true }));
input.value = part;
input.dispatchEvent(new Event("input", { bubbles: true }));
input.dispatchEvent(new KeyboardEvent("keyup", { key: "Enter", bubbles: true }));
setTimeout(() => {
const suggestion = [...document.querySelectorAll("button, div")]
.find(el => el.textContent.trim() === part);
if (suggestion) suggestion.click();
}, 500);
}
}, 200);
}
}, 100);
return;
}
})();