diff --git a/build.js b/build.js index f04ad33..060294a 100644 --- a/build.js +++ b/build.js @@ -80,6 +80,9 @@ await bundle.close(); let birbJs = readFileSync('dist/birb.bundled.js', 'utf8'); +// Replace version placeholder +birbJs = birbJs.replaceAll('__VERSION__', version); + // Compile and insert sprite sheets for (const spriteSheet of spriteSheets) { const dataUri = readFileSync(spriteSheet.path, 'base64'); diff --git a/dist/birb.js b/dist/birb.js index be18492..034edc6 100644 --- a/dist/birb.js +++ b/dist/birb.js @@ -844,29 +844,38 @@ * @returns {HTMLElement} */ function renderStickyNote(stickyNote, onSave, onDelete) { - let html = ` -
-
Sticky Note
-
x
-
-
- -
`; const noteElement = makeElement("birb-window"); noteElement.classList.add("birb-sticky-note"); - noteElement.innerHTML = html; + + // Create header + const header = makeElement("birb-window-header"); + const titleDiv = makeElement("birb-window-title", "Sticky Note"); + const closeButton = makeElement("birb-window-close", "x"); + header.appendChild(titleDiv); + header.appendChild(closeButton); + + // Create content + const content = makeElement("birb-window-content"); + const textarea = document.createElement("textarea"); + textarea.className = "birb-sticky-note-input"; + textarea.style.width = "150px"; + textarea.placeholder = "Write your notes here and they'll stick to the page!"; + textarea.value = stickyNote.content; + content.appendChild(textarea); + + noteElement.appendChild(header); + noteElement.appendChild(content); noteElement.style.top = `${stickyNote.top}px`; noteElement.style.left = `${stickyNote.left}px`; document.body.appendChild(noteElement); - makeDraggable(noteElement.querySelector(".birb-window-header"), true, (top, left) => { + makeDraggable(header, true, (top, left) => { stickyNote.top = top; stickyNote.left = left; onSave(); }); - const closeButton = noteElement.querySelector(".birb-window-close"); if (closeButton) { makeClosable(() => { if (confirm("Are you sure you want to delete this sticky note?")) { @@ -876,7 +885,6 @@ }, closeButton); } - const textarea = noteElement.querySelector(".birb-sticky-note-input"); if (textarea && textarea instanceof HTMLTextAreaElement) { let saveTimeout; // Save after debounce @@ -1001,7 +1009,8 @@ } let menu = makeElement("birb-window", undefined, MENU_ID); let header = makeElement("birb-window-header"); - header.innerHTML = `
${title}
`; + const titleDiv = makeElement("birb-window-title", title); + header.appendChild(titleDiv); let content = makeElement("birb-window-content"); const removeCallback = () => removeMenu(); for (const item of menuItems) { @@ -1057,7 +1066,9 @@ error("Birb: Content not found"); return; } - content.innerHTML = ""; + while (content.firstChild) { + content.removeChild(content.firstChild); + } const removeCallback = () => removeMenu(); for (const item of menuItems) { if (!item.isDebug || isDebug()) { @@ -1586,7 +1597,9 @@ userSettings.birbMode = !userSettings.birbMode; save(); insertModal(`${birdBirb()} Mode`, `Your ${birdBirb().toLowerCase()} shall now be referred to as "${birdBirb()}"${userSettings.birbMode ? "\n\nWelcome back to 2012" : ""}`); - }) + }), + new Separator(), + new MenuItem("2025.10.26.500", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.10.26.500"); }, false), ]; const styleElement = document.createElement("style"); @@ -1738,11 +1751,6 @@ } function init() { - if (window !== window.top) { - // Skip installation if within an iframe - log("In iframe, skipping Birb script initialization"); - return; - } log("Sprite sheets loaded successfully, initializing bird..."); // Preload font @@ -1761,13 +1769,18 @@ font-style: normal; } `; - const fontStyle = document.createElement("style"); - fontStyle.innerHTML = fontFace; - document.head.appendChild(fontStyle); + + try { + const fontStyle = document.createElement("style"); + fontStyle.textContent = fontFace; + document.head.appendChild(fontStyle); + } catch (e) { + error("Failed to load font: " + e); + } load(); - styleElement.innerHTML = STYLESHEET; + styleElement.textContent = STYLESHEET; document.head.appendChild(styleElement); birb = new Birb(BIRB_CSS_SCALE, CANVAS_PIXEL_SIZE, SPRITE_SHEET, SPRITE_WIDTH, SPRITE_HEIGHT); @@ -1871,7 +1884,7 @@ function draw() { requestAnimationFrame(draw); - if (!birb.isVisible()) { + if (!birb || !birb.isVisible()) { return; } diff --git a/dist/birb.user.js b/dist/birb.user.js index d7563ea..756cb4f 100644 --- a/dist/birb.user.js +++ b/dist/birb.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Pocket Bird // @namespace https://idreesinc.com -// @version 2025.10.26.455 +// @version 2025.10.26.500 // @description birb // @author Idrees // @downloadURL https://github.com/IdreesInc/Pocket-Bird/raw/refs/heads/main/dist/birb.user.js @@ -858,29 +858,38 @@ * @returns {HTMLElement} */ function renderStickyNote(stickyNote, onSave, onDelete) { - let html = ` -
-
Sticky Note
-
x
-
-
- -
`; const noteElement = makeElement("birb-window"); noteElement.classList.add("birb-sticky-note"); - noteElement.innerHTML = html; + + // Create header + const header = makeElement("birb-window-header"); + const titleDiv = makeElement("birb-window-title", "Sticky Note"); + const closeButton = makeElement("birb-window-close", "x"); + header.appendChild(titleDiv); + header.appendChild(closeButton); + + // Create content + const content = makeElement("birb-window-content"); + const textarea = document.createElement("textarea"); + textarea.className = "birb-sticky-note-input"; + textarea.style.width = "150px"; + textarea.placeholder = "Write your notes here and they'll stick to the page!"; + textarea.value = stickyNote.content; + content.appendChild(textarea); + + noteElement.appendChild(header); + noteElement.appendChild(content); noteElement.style.top = `${stickyNote.top}px`; noteElement.style.left = `${stickyNote.left}px`; document.body.appendChild(noteElement); - makeDraggable(noteElement.querySelector(".birb-window-header"), true, (top, left) => { + makeDraggable(header, true, (top, left) => { stickyNote.top = top; stickyNote.left = left; onSave(); }); - const closeButton = noteElement.querySelector(".birb-window-close"); if (closeButton) { makeClosable(() => { if (confirm("Are you sure you want to delete this sticky note?")) { @@ -890,7 +899,6 @@ }, closeButton); } - const textarea = noteElement.querySelector(".birb-sticky-note-input"); if (textarea && textarea instanceof HTMLTextAreaElement) { let saveTimeout; // Save after debounce @@ -1015,7 +1023,8 @@ } let menu = makeElement("birb-window", undefined, MENU_ID); let header = makeElement("birb-window-header"); - header.innerHTML = `
${title}
`; + const titleDiv = makeElement("birb-window-title", title); + header.appendChild(titleDiv); let content = makeElement("birb-window-content"); const removeCallback = () => removeMenu(); for (const item of menuItems) { @@ -1071,7 +1080,9 @@ error("Birb: Content not found"); return; } - content.innerHTML = ""; + while (content.firstChild) { + content.removeChild(content.firstChild); + } const removeCallback = () => removeMenu(); for (const item of menuItems) { if (!item.isDebug || isDebug()) { @@ -1600,7 +1611,9 @@ userSettings.birbMode = !userSettings.birbMode; save(); insertModal(`${birdBirb()} Mode`, `Your ${birdBirb().toLowerCase()} shall now be referred to as "${birdBirb()}"${userSettings.birbMode ? "\n\nWelcome back to 2012" : ""}`); - }) + }), + new Separator(), + new MenuItem("2025.10.26.500", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.10.26.500"); }, false), ]; const styleElement = document.createElement("style"); @@ -1752,11 +1765,6 @@ } function init() { - if (window !== window.top) { - // Skip installation if within an iframe - log("In iframe, skipping Birb script initialization"); - return; - } log("Sprite sheets loaded successfully, initializing bird..."); // Preload font @@ -1775,13 +1783,18 @@ font-style: normal; } `; - const fontStyle = document.createElement("style"); - fontStyle.innerHTML = fontFace; - document.head.appendChild(fontStyle); + + try { + const fontStyle = document.createElement("style"); + fontStyle.textContent = fontFace; + document.head.appendChild(fontStyle); + } catch (e) { + error("Failed to load font: " + e); + } load(); - styleElement.innerHTML = STYLESHEET; + styleElement.textContent = STYLESHEET; document.head.appendChild(styleElement); birb = new Birb(BIRB_CSS_SCALE, CANVAS_PIXEL_SIZE, SPRITE_SHEET, SPRITE_WIDTH, SPRITE_HEIGHT); @@ -1885,7 +1898,7 @@ function draw() { requestAnimationFrame(draw); - if (!birb.isVisible()) { + if (!birb || !birb.isVisible()) { return; } diff --git a/manifest.json b/manifest.json index 1ccf6a1..ccecd4d 100644 --- a/manifest.json +++ b/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 3, "name": "Pocket Bird", "description": "It's a bird, in your browser. What more could you want?", - "version": "2025.10.26.455", + "version": "2025.10.26.500", "homepage_url": "https://idreesinc.com", "content_scripts": [ { diff --git a/src/application.js b/src/application.js index e12a268..8977df9 100644 --- a/src/application.js +++ b/src/application.js @@ -216,7 +216,9 @@ Promise.all([ userSettings.birbMode = !userSettings.birbMode; save(); insertModal(`${birdBirb()} Mode`, `Your ${birdBirb().toLowerCase()} shall now be referred to as "${birdBirb()}"${userSettings.birbMode ? "\n\nWelcome back to 2012" : ""}`); - }) + }), + new Separator(), + new MenuItem("__VERSION__", () => { alert("Thank you for using Pocket Bird! You are on version: __VERSION__") }, false), ]; const styleElement = document.createElement("style"); @@ -368,11 +370,6 @@ Promise.all([ } function init() { - if (window !== window.top) { - // Skip installation if within an iframe - log("In iframe, skipping Birb script initialization"); - return; - } log("Sprite sheets loaded successfully, initializing bird..."); // Preload font @@ -391,13 +388,18 @@ Promise.all([ font-style: normal; } `; - const fontStyle = document.createElement("style"); - fontStyle.innerHTML = fontFace; - document.head.appendChild(fontStyle); + + try { + const fontStyle = document.createElement("style"); + fontStyle.textContent = fontFace; + document.head.appendChild(fontStyle); + } catch (e) { + error("Failed to load font: " + e); + } load(); - styleElement.innerHTML = STYLESHEET; + styleElement.textContent = STYLESHEET; document.head.appendChild(styleElement); birb = new Birb(BIRB_CSS_SCALE, CANVAS_PIXEL_SIZE, SPRITE_SHEET, SPRITE_WIDTH, SPRITE_HEIGHT); @@ -501,7 +503,7 @@ Promise.all([ function draw() { requestAnimationFrame(draw); - if (!birb.isVisible()) { + if (!birb || !birb.isVisible()) { return; } diff --git a/src/menu.js b/src/menu.js index 8e14717..f4e7c68 100644 --- a/src/menu.js +++ b/src/menu.js @@ -72,7 +72,8 @@ export function insertMenu(menuItems, title, updateLocationCallback) { } let menu = makeElement("birb-window", undefined, MENU_ID); let header = makeElement("birb-window-header"); - header.innerHTML = `
${title}
`; + const titleDiv = makeElement("birb-window-title", title); + header.appendChild(titleDiv); let content = makeElement("birb-window-content"); const removeCallback = () => removeMenu(); for (const item of menuItems) { @@ -128,7 +129,9 @@ export function switchMenuItems(menuItems, updateLocationCallback) { error("Birb: Content not found"); return; } - content.innerHTML = ""; + while (content.firstChild) { + content.removeChild(content.firstChild); + } const removeCallback = () => removeMenu(); for (const item of menuItems) { if (!item.isDebug || isDebug()) { diff --git a/src/stickyNotes.js b/src/stickyNotes.js index ef04e1f..2044365 100644 --- a/src/stickyNotes.js +++ b/src/stickyNotes.js @@ -77,29 +77,38 @@ export function isStickyNoteApplicable(stickyNote) { * @returns {HTMLElement} */ export function renderStickyNote(stickyNote, onSave, onDelete) { - let html = ` -
-
Sticky Note
-
x
-
-
- -
` const noteElement = makeElement("birb-window"); noteElement.classList.add("birb-sticky-note"); - noteElement.innerHTML = html; + + // Create header + const header = makeElement("birb-window-header"); + const titleDiv = makeElement("birb-window-title", "Sticky Note"); + const closeButton = makeElement("birb-window-close", "x"); + header.appendChild(titleDiv); + header.appendChild(closeButton); + + // Create content + const content = makeElement("birb-window-content"); + const textarea = document.createElement("textarea"); + textarea.className = "birb-sticky-note-input"; + textarea.style.width = "150px"; + textarea.placeholder = "Write your notes here and they'll stick to the page!"; + textarea.value = stickyNote.content; + content.appendChild(textarea); + + noteElement.appendChild(header); + noteElement.appendChild(content); noteElement.style.top = `${stickyNote.top}px`; noteElement.style.left = `${stickyNote.left}px`; document.body.appendChild(noteElement); - makeDraggable(noteElement.querySelector(".birb-window-header"), true, (top, left) => { + makeDraggable(header, true, (top, left) => { stickyNote.top = top; stickyNote.left = left; onSave(); }); - const closeButton = noteElement.querySelector(".birb-window-close"); if (closeButton) { makeClosable(() => { if (confirm("Are you sure you want to delete this sticky note?")) { @@ -109,7 +118,6 @@ export function renderStickyNote(stickyNote, onSave, onDelete) { }, closeButton); } - const textarea = noteElement.querySelector(".birb-sticky-note-input"); if (textarea && textarea instanceof HTMLTextAreaElement) { let saveTimeout; // Save after debounce