- Firefox-Version
- 157.0.1
- Betriebssystem
- Win 11
Hallo,
gibt es eventl ein Script das es ermöglich bei jedes Lesezeichen ein Notizfeld hinzufügen ?
Hallo,
gibt es eventl ein Script das es ermöglich bei jedes Lesezeichen ein Notizfeld hinzufügen ?
Und wo soll das gespeichert werden?
Mozilla hat so ein Feld aus Performancegründen abgeschafft.
Ansonsten:
ein Script
Laut KI ChatGPT
Teste bitte:
// ==UserScript==
// Author: KI ChatGPT
// Name: Zusatzfeld.uc.js
// Funktion: Zusatzfeld für eigenen Text unter dem Stern bei gespeichertem Lesezeichen
// compatibility: Firefox Version 157
(function() {
if (window.gCustomBookmarkField) return;
window.gCustomBookmarkField = {
STORAGE_FILE: "bookmark-custom-notes.json",
saveQueue: Promise.resolve(),
init() {
window.addEventListener("popupshowing", (e) => {
if (e.target.id === "editBookmarkPanel") {
this.tryInject(0);
}
}, true);
window.addEventListener("popuphiding", (e) => {
if (e.target.id === "editBookmarkPanel") {
this.saveData();
}
}, true);
},
getItemGuid() {
if (!window.gEditItemOverlay) return null;
// Aktuelle Firefox-Schnittstelle
const guid = gEditItemOverlay.concreteGuid;
if (guid) return guid;
// Rückfall für ältere Firefox-Versionen
return gEditItemOverlay._guid ||
gEditItemOverlay.nodeForProperties?.bookmarkGuid ||
null;
},
getStoragePath() {
return PathUtils.join(
PathUtils.profileDir,
this.STORAGE_FILE
);
},
async readAll() {
try {
const path = this.getStoragePath();
if (!(await IOUtils.exists(path))) {
return {};
}
const content = await IOUtils.readUTF8(path);
const data = JSON.parse(content);
return data && typeof data === "object" &&
!Array.isArray(data) ? data : {};
} catch (e) {
console.error(
"Custom Bookmark Notes: Lesefehler",
e
);
return {};
}
},
async writeAll(data) {
const path = this.getStoragePath();
await IOUtils.writeUTF8(
path,
JSON.stringify(data, null, 2)
);
},
tryInject(attempts) {
if (attempts > 20) return;
const anchorRow =
document.getElementById("editBMPanel_keywordRow") ||
document.getElementById("keywordRow") ||
document.getElementById("editBMPanel_tagsSelectorRow");
if (!anchorRow) {
setTimeout(() => this.tryInject(attempts + 1), 40);
return;
}
this.injectUI(anchorRow);
this.loadData();
},
injectUI(anchorRow) {
if (document.getElementById("editBMPanel_customNotesRow")) {
return;
}
const row = document.createElementNS(
"http://www.w3.org/1999/xhtml",
"div"
);
row.id = "editBMPanel_customNotesRow";
row.style.cssText =
"margin:12px 0 !important;" +
"display:block !important;" +
"width:100% !important;" +
"clear:both !important;";
const label = document.createElementNS(
"http://www.w3.org/1999/xhtml",
"label"
);
label.textContent = "Eigene Notizen / Beschreibung:";
label.htmlFor = "editBMPanel_customNotesField";
label.style.cssText =
"display:block !important;" +
"font-weight:600 !important;" +
"margin-bottom:6px !important;" +
"color:var(--panel-description-color, inherit) !important;";
const input = document.createElementNS(
"http://www.w3.org/1999/xhtml",
"textarea"
);
input.id = "editBMPanel_customNotesField";
input.rows = 3;
input.style.cssText =
"width:100% !important;" +
"box-sizing:border-box !important;" +
"padding:6px !important;" +
"border:1px solid var(--panel-separator-color, #ccc) !important;" +
"border-radius:4px !important;" +
"background:var(--arrowpanel-background, #fff) !important;" +
"color:var(--arrowpanel-color, #000) !important;" +
"resize:vertical !important;" +
"font:inherit !important;";
// Änderungen während der Eingabe dauerhaft speichern.
input.addEventListener("input", () => {
this.saveData();
});
row.appendChild(label);
row.appendChild(input);
anchorRow.parentNode.insertBefore(row, anchorRow);
},
async loadData() {
const field = document.getElementById(
"editBMPanel_customNotesField"
);
if (!field) return;
field.value = "";
const guid = this.getItemGuid();
if (!guid) return;
try {
const data = await this.readAll();
// Nicht den Inhalt eines inzwischen anderen
// geöffneten Lesezeichens überschreiben.
if (this.getItemGuid() && this.getItemGuid() !== guid) return;
field.value = typeof data[guid] === "string"
? data[guid]
: "";
} catch (e) {
console.error(
"Custom Bookmark Notes: Laden fehlgeschlagen",
e
);
}
},
saveData() {
const field = document.getElementById(
"editBMPanel_customNotesField"
);
const guid = this.getItemGuid();
if (!field || !guid) return this.saveQueue;
// Wert sofort sichern, damit spätere Eingaben
// nicht versehentlich frühere Werte überschreiben.
const value = field.value;
const path = this.getStoragePath();
this.saveQueue = this.saveQueue
.catch(() => {})
.then(async () => {
const data = await this.readAll();
if (value.trim()) {
data[guid] = value;
} else {
delete data[guid];
}
await this.writeAll(data);
})
.catch((e) => {
console.error(
"Custom Bookmark Notes: Speichern fehlgeschlagen",
e,
path
);
});
return this.saveQueue;
}
};
window.gCustomBookmarkField.init();
})();
Alles anzeigen
2002Andreas Mit diesem Skript kann man aber nur über den Stern in der Adresszeile Lesezeichen bearbeiten!
Wenn Du direkt über die Lesezeichen gehst, Rechtsklick Menü "Lesezeichen bearbeiten ...",
und so schaut das Popup von Son Goku aus, ist da kein Notizfeld!
Ich arbeite da gerade drann, ob's was wird, weiß ich noch nicht!
Rechtsklick Menü "Lesezeichen bearbeiten ..."
Damit wird beides abgedeckt.
// ==UserScript==
// Author: KI ChatGPT
// Name: Zusatzfeld.uc.js
// Funktion: Eigene Notizen für gespeicherte Lesezeichen
// compatibility: Firefox 157
(function() {
if (window.gCustomBookmarkField) return;
const script = window.gCustomBookmarkField = {
STORAGE_FILE: "bookmark-custom-notes.json",
saveQueue: Promise.resolve(),
hookedDocs: new WeakSet(),
init() {
// Stern-Popup im Hauptfenster
window.addEventListener("popupshowing", e => {
if (e.target.id === "editBookmarkPanel") {
this.tryInject(document, 0);
}
}, true);
// Separaten Lesezeichen-Dialog überwachen
this.watchMainWindow();
},
watchMainWindow() {
const check = () => {
const frame = document.querySelector(
"#window-modal-dialog browser.dialogFrame"
);
if (!frame) return;
try {
const doc = frame.contentDocument;
if (
doc &&
doc.getElementById("bookmarkpropertiesdialog")
) {
// Äußeren Firefox-Dialog vergrößern
const outerDialog = document.getElementById(
"window-modal-dialog"
);
const container = outerDialog?.querySelector(
".dialogOverlay-window-modal-dialog-subdialog"
);
if (container) {
// Gewünschte Höhe: 700 Pixel
container.style.setProperty(
"--subdialog-inner-height",
"700px"
);
const box = container.querySelector(".dialogBox");
if (box) {
box.style.setProperty(
"min-height",
"700px",
"important"
);
}
const frame = container.querySelector(
"browser.dialogFrame"
);
if (frame) {
frame.style.setProperty(
"height",
"700px",
"important"
);
}
}
this.tryInject(doc, 0);
}
} catch (e) {
// Der Dialog kann während des Ladens
// vorübergehend noch nicht erreichbar sein.
}
};
window.addEventListener("DOMWindowCreated", check, true);
window.addEventListener("load", check, true);
// Auch nach dem Öffnen des Dialogs erneut prüfen
window.addEventListener("click", () => {
setTimeout(check, 100);
setTimeout(check, 400);
}, true);
// Periodische Prüfung ist hier nicht nötig:
// Der Dialog wird zusätzlich beim Öffnen geprüft.
this.checkDialog = check;
},
getItemGuid(doc) {
try {
const win = doc.defaultView;
const overlay = win.gEditItemOverlay;
if (overlay?.concreteGuid) {
return overlay.concreteGuid;
}
if (overlay?._guid) {
return overlay._guid;
}
if (overlay?.nodeForProperties?.bookmarkGuid) {
return overlay.nodeForProperties.bookmarkGuid;
}
const args = win.arguments?.[0];
if (args?.bookmarkGuid) return args.bookmarkGuid;
if (args?.node?.bookmarkGuid) return args.node.bookmarkGuid;
} catch (e) {}
return null;
},
getStoragePath() {
return PathUtils.join(
PathUtils.profileDir,
this.STORAGE_FILE
);
},
async readAll() {
try {
const path = this.getStoragePath();
if (!(await IOUtils.exists(path))) return {};
const data = JSON.parse(
await IOUtils.readUTF8(path)
);
return data &&
typeof data === "object" &&
!Array.isArray(data)
? data
: {};
} catch (e) {
console.error(
"Custom Bookmark Notes: Lesefehler", e
);
return {};
}
},
async writeAll(data) {
await IOUtils.writeUTF8(
this.getStoragePath(),
JSON.stringify(data, null, 2)
);
},
tryInject(doc, attempts) {
if (attempts > 30) return;
const anchor =
doc.getElementById("editBMPanel_tagsSelectorRow") ||
doc.getElementById("editBMPanel_keywordRow") ||
doc.getElementById("keywordRow") ||
doc.getElementById("editBMPanel_folderRow") ||
doc.getElementById("editBMPanel_locationRow");
if (!anchor) {
doc.defaultView.setTimeout(
() => this.tryInject(doc, attempts + 1),
100
);
return;
}
this.injectUI(doc, anchor);
},
injectUI(doc, anchor) {
let row = doc.getElementById(
"editBMPanel_customNotesRow"
);
if (!row) {
row = doc.createElementNS(
"http://www.w3.org/1999/xhtml",
"div"
);
row.id = "editBMPanel_customNotesRow";
row.style.cssText =
"display:block!important;" +
"width:100%!important;" +
"box-sizing:border-box!important;" +
"margin:12px 0!important;";
const label = doc.createElementNS(
"http://www.w3.org/1999/xhtml",
"label"
);
label.textContent =
"Eigene Notizen / Beschreibung:";
label.htmlFor = "editBMPanel_customNotesField";
label.style.cssText =
"display:block!important;" +
"font-weight:600!important;" +
"margin-bottom:6px!important;";
const field = doc.createElementNS(
"http://www.w3.org/1999/xhtml",
"textarea"
);
field.id = "editBMPanel_customNotesField";
field.rows = 3;
field.style.cssText =
"display:block!important;" +
"width:100%!important;" +
"box-sizing:border-box!important;" +
"padding:6px!important;" +
"border:1px solid var(--in-content-box-border-color,#aaa)!important;" +
"border-radius:4px!important;" +
"resize:vertical!important;" +
"font:inherit!important;";
field.addEventListener("input", () => {
this.saveData(doc);
});
row.appendChild(label);
row.appendChild(field);
anchor.parentNode.insertBefore(row, anchor);
}
if (!this.hookedDocs.has(doc)) {
this.hookedDocs.add(doc);
doc.defaultView.addEventListener("unload", () => {
this.saveData(doc);
}, { once: true });
doc.addEventListener("dialogaccept", () => {
this.saveData(doc);
});
}
this.loadData(doc);
// Mehr Platz für das Notizfeld im separaten Dialog
if (doc.getElementById("bookmarkpropertiesdialog")) {
const win = doc.defaultView;
win.setTimeout(() => {
const dialog = win.document.getElementById(
"bookmarkpropertiesdialog"
);
if (dialog) {
dialog.style.minHeight = "600px";
}
const root = win.document.documentElement;
if (root) {
root.style.minHeight = "600px";
}
}, 100);
}
},
async loadData(doc) {
const field = doc.getElementById(
"editBMPanel_customNotesField"
);
if (!field) return;
const guid = this.getItemGuid(doc);
field.value = "";
if (!guid) return;
try {
const data = await this.readAll();
if (this.getItemGuid(doc) !== guid) return;
field.value =
typeof data[guid] === "string"
? data[guid]
: "";
} catch (e) {
console.error(
"Custom Bookmark Notes: Laden fehlgeschlagen", e
);
}
},
saveData(doc) {
const field = doc.getElementById(
"editBMPanel_customNotesField"
);
const guid = this.getItemGuid(doc);
if (!field || !guid) return this.saveQueue;
const value = field.value;
const path = this.getStoragePath();
this.saveQueue = this.saveQueue
.catch(() => {})
.then(async () => {
const data = await this.readAll();
if (value.trim()) {
data[guid] = value;
} else {
delete data[guid];
}
await this.writeAll(data);
})
.catch(e => {
console.error(
"Custom Bookmark Notes: Speichern fehlgeschlagen",
e, path
);
});
return this.saveQueue;
}
};
script.init();
})();
Alles anzeigen
Super![]()
In zweien Füchsen getestet, klappt! ![]()
klappt!
Danke für den Test![]()
![]()
Danke auch von mir.
klappt alles
klappt alles
sehr schön