From 7639c7c36a19e97f17d6b2fc5922ca4592cae87f Mon Sep 17 00:00:00 2001 From: Idrees Hassan Date: Fri, 14 Nov 2025 00:06:49 -0500 Subject: [PATCH] Add sticky note support to obsidian --- dist/birb.js | 63 ++++++++++++++++++++++++++------- dist/extension.zip | Bin 149338 -> 149728 bytes dist/extension/birb.js | 63 ++++++++++++++++++++++++++------- dist/extension/manifest.json | 2 +- dist/obsidian/main.js | 65 +++++++++++++++++++++++++++-------- dist/obsidian/manifest.json | 2 +- dist/userscript/birb.user.js | 65 +++++++++++++++++++++++++++-------- src/application.js | 4 +-- src/context.js | 44 ++++++++++++++++++++---- src/shared.js | 10 ++++-- src/stickyNotes.js | 2 +- src/stylesheet.css | 1 + 12 files changed, 253 insertions(+), 68 deletions(-) diff --git a/dist/birb.js b/dist/birb.js index db44b3a..ae6f91e 100644 --- a/dist/birb.js +++ b/dist/birb.js @@ -70,8 +70,9 @@ * @param {HTMLElement|null} element The element to detect drag events on * @param {boolean} [parent] Whether to move the parent element when the child is dragged * @param {(top: number, left: number) => void} [callback] Callback for when element is moved + * @param {HTMLElement} [pageElement] The page element to constrain movement within */ - function makeDraggable(element, parent = true, callback = () => { }) { + function makeDraggable(element, parent = true, callback = () => { }, pageElement) { if (!element) { return; } @@ -117,9 +118,12 @@ }); document.addEventListener("mousemove", (e) => { + const page = pageElement || document.documentElement; + const maxX = page.scrollWidth - elementToMove.clientWidth; + const maxY = page.scrollHeight - elementToMove.clientHeight; if (isMouseDown) { - elementToMove.style.left = `${Math.max(0, e.clientX - offsetX)}px`; - elementToMove.style.top = `${Math.max(0, e.clientY - offsetY)}px`; + elementToMove.style.left = `${Math.max(0, Math.min(maxX, e.clientX - offsetX))}px`; + elementToMove.style.top = `${Math.max(0, Math.min(maxY, e.clientY - offsetY))}px`; } }); @@ -840,6 +844,7 @@ } const SAVE_KEY = "birbSaveData"; + const ROOT_PATH = ""; /** * @typedef {import('./application.js').BirbSaveData} BirbSaveData @@ -1070,7 +1075,6 @@ } class ObsidianContext extends Context { - /** * @override * @returns {boolean} @@ -1085,8 +1089,12 @@ * @returns {Promise} */ async getSaveData() { - // @ts-expect-error - return await OBSIDIAN_PLUGIN.loadData() ?? {}; + return new Promise((resolve) => { + // @ts-expect-error + OBSIDIAN_PLUGIN.loadData().then((data) => { + resolve(data ?? {}); + }); + }); } /** @@ -1095,7 +1103,7 @@ */ async putSaveData(saveData) { // @ts-expect-error - return await OBSIDIAN_PLUGIN.saveData(saveData); + await OBSIDIAN_PLUGIN.saveData(saveData); } /** @override */ @@ -1116,8 +1124,36 @@ } /** @override */ - areStickyNotesEnabled() { - return false; + getPath() { + // @ts-expect-error + const file = app.workspace.getActiveFile(); + if (file && this.getActiveEditorElement()) { + return file.path; + } else { + return ROOT_PATH; + } + } + + /** @override */ + getActivePage() { + if (this.getPath() === ROOT_PATH) { + // Root page, use document element + return document.documentElement + } + return this.getActiveEditorElement() ?? document.documentElement; + } + + /** @override */ + isPathApplicable(path) { + return path === this.getPath(); + } + + /** @returns {HTMLElement|null} */ + getActiveEditorElement() { + // @ts-expect-error + const activeLeaf = app.workspace.activeLeaf; + const leafElement = activeLeaf?.view?.containerEl; + return leafElement?.querySelector(".cm-scroller") ?? null; } } @@ -1217,7 +1253,7 @@ stickyNote.top = top; stickyNote.left = left; onSave(); - }); + }, page); if (closeButton) { makeClosable(() => { @@ -1574,6 +1610,7 @@ flex-grow: 1; user-select: none; color: var(--birb-background-color); + white-space: nowrap; } .birb-window-close { @@ -1815,7 +1852,7 @@ const AFK_TIME = isDebug() ? 0 : 1000 * 5; const PET_BOOST_DURATION = 1000 * 60 * 5; const PET_MENU_COOLDOWN = 1000; - const URL_CHECK_INTERVAL = 500; + const URL_CHECK_INTERVAL = 250; const HOP_DELAY = 500; // Random event chances per tick @@ -1957,7 +1994,7 @@ insertModal(`${birdBirb()} Mode`, message); }), new Separator(), - new MenuItem("2025.11.13.80", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.80"); }, false), + new MenuItem("2025.11.14.16", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.14.16"); }, false), ]; const styleElement = document.createElement("style"); @@ -2156,7 +2193,7 @@ setInterval(() => { const currentPath = getContext().getPath().split("?")[0]; if (currentPath !== lastPath) { - log("Path changed, updating sticky notes"); + log("Path changed, updating sticky notes: " + currentPath); lastPath = currentPath; drawStickyNotes(stickyNotes, save, deleteStickyNote); } diff --git a/dist/extension.zip b/dist/extension.zip index 84c58c8ca619bad06ea33ce0c35d88ca25ddf83a..94c87e96a0c354e409d64a66aaf8edbcf78a2fa3 100644 GIT binary patch delta 27444 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 delta 27127 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 void} [callback] Callback for when element is moved + * @param {HTMLElement} [pageElement] The page element to constrain movement within */ - function makeDraggable(element, parent = true, callback = () => { }) { + function makeDraggable(element, parent = true, callback = () => { }, pageElement) { if (!element) { return; } @@ -117,9 +118,12 @@ }); document.addEventListener("mousemove", (e) => { + const page = pageElement || document.documentElement; + const maxX = page.scrollWidth - elementToMove.clientWidth; + const maxY = page.scrollHeight - elementToMove.clientHeight; if (isMouseDown) { - elementToMove.style.left = `${Math.max(0, e.clientX - offsetX)}px`; - elementToMove.style.top = `${Math.max(0, e.clientY - offsetY)}px`; + elementToMove.style.left = `${Math.max(0, Math.min(maxX, e.clientX - offsetX))}px`; + elementToMove.style.top = `${Math.max(0, Math.min(maxY, e.clientY - offsetY))}px`; } }); @@ -840,6 +844,7 @@ } const SAVE_KEY = "birbSaveData"; + const ROOT_PATH = ""; /** * @typedef {import('./application.js').BirbSaveData} BirbSaveData @@ -1070,7 +1075,6 @@ } class ObsidianContext extends Context { - /** * @override * @returns {boolean} @@ -1085,8 +1089,12 @@ * @returns {Promise} */ async getSaveData() { - // @ts-expect-error - return await OBSIDIAN_PLUGIN.loadData() ?? {}; + return new Promise((resolve) => { + // @ts-expect-error + OBSIDIAN_PLUGIN.loadData().then((data) => { + resolve(data ?? {}); + }); + }); } /** @@ -1095,7 +1103,7 @@ */ async putSaveData(saveData) { // @ts-expect-error - return await OBSIDIAN_PLUGIN.saveData(saveData); + await OBSIDIAN_PLUGIN.saveData(saveData); } /** @override */ @@ -1116,8 +1124,36 @@ } /** @override */ - areStickyNotesEnabled() { - return false; + getPath() { + // @ts-expect-error + const file = app.workspace.getActiveFile(); + if (file && this.getActiveEditorElement()) { + return file.path; + } else { + return ROOT_PATH; + } + } + + /** @override */ + getActivePage() { + if (this.getPath() === ROOT_PATH) { + // Root page, use document element + return document.documentElement + } + return this.getActiveEditorElement() ?? document.documentElement; + } + + /** @override */ + isPathApplicable(path) { + return path === this.getPath(); + } + + /** @returns {HTMLElement|null} */ + getActiveEditorElement() { + // @ts-expect-error + const activeLeaf = app.workspace.activeLeaf; + const leafElement = activeLeaf?.view?.containerEl; + return leafElement?.querySelector(".cm-scroller") ?? null; } } @@ -1217,7 +1253,7 @@ stickyNote.top = top; stickyNote.left = left; onSave(); - }); + }, page); if (closeButton) { makeClosable(() => { @@ -1574,6 +1610,7 @@ flex-grow: 1; user-select: none; color: var(--birb-background-color); + white-space: nowrap; } .birb-window-close { @@ -1815,7 +1852,7 @@ const AFK_TIME = isDebug() ? 0 : 1000 * 5; const PET_BOOST_DURATION = 1000 * 60 * 5; const PET_MENU_COOLDOWN = 1000; - const URL_CHECK_INTERVAL = 500; + const URL_CHECK_INTERVAL = 250; const HOP_DELAY = 500; // Random event chances per tick @@ -1957,7 +1994,7 @@ insertModal(`${birdBirb()} Mode`, message); }), new Separator(), - new MenuItem("2025.11.13.80", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.80"); }, false), + new MenuItem("2025.11.14.16", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.14.16"); }, false), ]; const styleElement = document.createElement("style"); @@ -2156,7 +2193,7 @@ setInterval(() => { const currentPath = getContext().getPath().split("?")[0]; if (currentPath !== lastPath) { - log("Path changed, updating sticky notes"); + log("Path changed, updating sticky notes: " + currentPath); lastPath = currentPath; drawStickyNotes(stickyNotes, save, deleteStickyNote); } diff --git a/dist/extension/manifest.json b/dist/extension/manifest.json index bf67d73..43c5156 100644 --- a/dist/extension/manifest.json +++ b/dist/extension/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 3, "name": "Pocket Bird", "description": "It's a pet bird in your browser, what more could you want?", - "version": "2025.11.13.80", + "version": "2025.11.14.16", "homepage_url": "https://idreesinc.com", "icons": { "48": "images/icons/transparent/48x48x1.png", diff --git a/dist/obsidian/main.js b/dist/obsidian/main.js index e192150..145d3ce 100644 --- a/dist/obsidian/main.js +++ b/dist/obsidian/main.js @@ -2,7 +2,7 @@ const { Plugin, Notice } = require('obsidian'); module.exports = class PocketBird extends Plugin { onload() { - console.log("Loading Pocket Bird version 2025.11.13.80..."); + console.log("Loading Pocket Bird version 2025.11.14.16..."); const OBSIDIAN_PLUGIN = this; (function () { 'use strict'; @@ -76,8 +76,9 @@ module.exports = class PocketBird extends Plugin { * @param {HTMLElement|null} element The element to detect drag events on * @param {boolean} [parent] Whether to move the parent element when the child is dragged * @param {(top: number, left: number) => void} [callback] Callback for when element is moved + * @param {HTMLElement} [pageElement] The page element to constrain movement within */ - function makeDraggable(element, parent = true, callback = () => { }) { + function makeDraggable(element, parent = true, callback = () => { }, pageElement) { if (!element) { return; } @@ -123,9 +124,12 @@ module.exports = class PocketBird extends Plugin { }); document.addEventListener("mousemove", (e) => { + const page = pageElement || document.documentElement; + const maxX = page.scrollWidth - elementToMove.clientWidth; + const maxY = page.scrollHeight - elementToMove.clientHeight; if (isMouseDown) { - elementToMove.style.left = `${Math.max(0, e.clientX - offsetX)}px`; - elementToMove.style.top = `${Math.max(0, e.clientY - offsetY)}px`; + elementToMove.style.left = `${Math.max(0, Math.min(maxX, e.clientX - offsetX))}px`; + elementToMove.style.top = `${Math.max(0, Math.min(maxY, e.clientY - offsetY))}px`; } }); @@ -846,6 +850,7 @@ module.exports = class PocketBird extends Plugin { } const SAVE_KEY = "birbSaveData"; + const ROOT_PATH = ""; /** * @typedef {import('./application.js').BirbSaveData} BirbSaveData @@ -1076,7 +1081,6 @@ module.exports = class PocketBird extends Plugin { } class ObsidianContext extends Context { - /** * @override * @returns {boolean} @@ -1091,8 +1095,12 @@ module.exports = class PocketBird extends Plugin { * @returns {Promise} */ async getSaveData() { - // @ts-expect-error - return await OBSIDIAN_PLUGIN.loadData() ?? {}; + return new Promise((resolve) => { + // @ts-expect-error + OBSIDIAN_PLUGIN.loadData().then((data) => { + resolve(data ?? {}); + }); + }); } /** @@ -1101,7 +1109,7 @@ module.exports = class PocketBird extends Plugin { */ async putSaveData(saveData) { // @ts-expect-error - return await OBSIDIAN_PLUGIN.saveData(saveData); + await OBSIDIAN_PLUGIN.saveData(saveData); } /** @override */ @@ -1122,8 +1130,36 @@ module.exports = class PocketBird extends Plugin { } /** @override */ - areStickyNotesEnabled() { - return false; + getPath() { + // @ts-expect-error + const file = app.workspace.getActiveFile(); + if (file && this.getActiveEditorElement()) { + return file.path; + } else { + return ROOT_PATH; + } + } + + /** @override */ + getActivePage() { + if (this.getPath() === ROOT_PATH) { + // Root page, use document element + return document.documentElement + } + return this.getActiveEditorElement() ?? document.documentElement; + } + + /** @override */ + isPathApplicable(path) { + return path === this.getPath(); + } + + /** @returns {HTMLElement|null} */ + getActiveEditorElement() { + // @ts-expect-error + const activeLeaf = app.workspace.activeLeaf; + const leafElement = activeLeaf?.view?.containerEl; + return leafElement?.querySelector(".cm-scroller") ?? null; } } @@ -1223,7 +1259,7 @@ module.exports = class PocketBird extends Plugin { stickyNote.top = top; stickyNote.left = left; onSave(); - }); + }, page); if (closeButton) { makeClosable(() => { @@ -1580,6 +1616,7 @@ module.exports = class PocketBird extends Plugin { flex-grow: 1; user-select: none; color: var(--birb-background-color); + white-space: nowrap; } .birb-window-close { @@ -1821,7 +1858,7 @@ module.exports = class PocketBird extends Plugin { const AFK_TIME = isDebug() ? 0 : 1000 * 5; const PET_BOOST_DURATION = 1000 * 60 * 5; const PET_MENU_COOLDOWN = 1000; - const URL_CHECK_INTERVAL = 500; + const URL_CHECK_INTERVAL = 250; const HOP_DELAY = 500; // Random event chances per tick @@ -1963,7 +2000,7 @@ module.exports = class PocketBird extends Plugin { insertModal(`${birdBirb()} Mode`, message); }), new Separator(), - new MenuItem("2025.11.13.80", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.80"); }, false), + new MenuItem("2025.11.14.16", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.14.16"); }, false), ]; const styleElement = document.createElement("style"); @@ -2162,7 +2199,7 @@ module.exports = class PocketBird extends Plugin { setInterval(() => { const currentPath = getContext().getPath().split("?")[0]; if (currentPath !== lastPath) { - log("Path changed, updating sticky notes"); + log("Path changed, updating sticky notes: " + currentPath); lastPath = currentPath; drawStickyNotes(stickyNotes, save, deleteStickyNote); } diff --git a/dist/obsidian/manifest.json b/dist/obsidian/manifest.json index 1b8b3da..8066f1f 100644 --- a/dist/obsidian/manifest.json +++ b/dist/obsidian/manifest.json @@ -1,7 +1,7 @@ { "id": "pocket-bird", "name": "Pocket Bird", - "version": "2025.11.13.80", + "version": "2025.11.14.16", "minAppVersion": "0.15.0", "description": "It's a pet bird in your Obsidian, what more could you want?", "author": "Idrees Hassan", diff --git a/dist/userscript/birb.user.js b/dist/userscript/birb.user.js index 0d465ed..4741ba3 100644 --- a/dist/userscript/birb.user.js +++ b/dist/userscript/birb.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Pocket Bird // @namespace https://idreesinc.com -// @version 2025.11.13.80 +// @version 2025.11.14.16 // @description It's a bird that hops around your web browser, the future is here // @author Idrees // @downloadURL https://github.com/IdreesInc/Pocket-Bird/raw/refs/heads/main/dist/userscript/birb.user.js @@ -84,8 +84,9 @@ * @param {HTMLElement|null} element The element to detect drag events on * @param {boolean} [parent] Whether to move the parent element when the child is dragged * @param {(top: number, left: number) => void} [callback] Callback for when element is moved + * @param {HTMLElement} [pageElement] The page element to constrain movement within */ - function makeDraggable(element, parent = true, callback = () => { }) { + function makeDraggable(element, parent = true, callback = () => { }, pageElement) { if (!element) { return; } @@ -131,9 +132,12 @@ }); document.addEventListener("mousemove", (e) => { + const page = pageElement || document.documentElement; + const maxX = page.scrollWidth - elementToMove.clientWidth; + const maxY = page.scrollHeight - elementToMove.clientHeight; if (isMouseDown) { - elementToMove.style.left = `${Math.max(0, e.clientX - offsetX)}px`; - elementToMove.style.top = `${Math.max(0, e.clientY - offsetY)}px`; + elementToMove.style.left = `${Math.max(0, Math.min(maxX, e.clientX - offsetX))}px`; + elementToMove.style.top = `${Math.max(0, Math.min(maxY, e.clientY - offsetY))}px`; } }); @@ -854,6 +858,7 @@ } const SAVE_KEY = "birbSaveData"; + const ROOT_PATH = ""; /** * @typedef {import('./application.js').BirbSaveData} BirbSaveData @@ -1084,7 +1089,6 @@ } class ObsidianContext extends Context { - /** * @override * @returns {boolean} @@ -1099,8 +1103,12 @@ * @returns {Promise} */ async getSaveData() { - // @ts-expect-error - return await OBSIDIAN_PLUGIN.loadData() ?? {}; + return new Promise((resolve) => { + // @ts-expect-error + OBSIDIAN_PLUGIN.loadData().then((data) => { + resolve(data ?? {}); + }); + }); } /** @@ -1109,7 +1117,7 @@ */ async putSaveData(saveData) { // @ts-expect-error - return await OBSIDIAN_PLUGIN.saveData(saveData); + await OBSIDIAN_PLUGIN.saveData(saveData); } /** @override */ @@ -1130,8 +1138,36 @@ } /** @override */ - areStickyNotesEnabled() { - return false; + getPath() { + // @ts-expect-error + const file = app.workspace.getActiveFile(); + if (file && this.getActiveEditorElement()) { + return file.path; + } else { + return ROOT_PATH; + } + } + + /** @override */ + getActivePage() { + if (this.getPath() === ROOT_PATH) { + // Root page, use document element + return document.documentElement + } + return this.getActiveEditorElement() ?? document.documentElement; + } + + /** @override */ + isPathApplicable(path) { + return path === this.getPath(); + } + + /** @returns {HTMLElement|null} */ + getActiveEditorElement() { + // @ts-expect-error + const activeLeaf = app.workspace.activeLeaf; + const leafElement = activeLeaf?.view?.containerEl; + return leafElement?.querySelector(".cm-scroller") ?? null; } } @@ -1231,7 +1267,7 @@ stickyNote.top = top; stickyNote.left = left; onSave(); - }); + }, page); if (closeButton) { makeClosable(() => { @@ -1588,6 +1624,7 @@ flex-grow: 1; user-select: none; color: var(--birb-background-color); + white-space: nowrap; } .birb-window-close { @@ -1829,7 +1866,7 @@ const AFK_TIME = isDebug() ? 0 : 1000 * 5; const PET_BOOST_DURATION = 1000 * 60 * 5; const PET_MENU_COOLDOWN = 1000; - const URL_CHECK_INTERVAL = 500; + const URL_CHECK_INTERVAL = 250; const HOP_DELAY = 500; // Random event chances per tick @@ -1971,7 +2008,7 @@ insertModal(`${birdBirb()} Mode`, message); }), new Separator(), - new MenuItem("2025.11.13.80", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.13.80"); }, false), + new MenuItem("2025.11.14.16", () => { alert("Thank you for using Pocket Bird! You are on version: 2025.11.14.16"); }, false), ]; const styleElement = document.createElement("style"); @@ -2170,7 +2207,7 @@ setInterval(() => { const currentPath = getContext().getPath().split("?")[0]; if (currentPath !== lastPath) { - log("Path changed, updating sticky notes"); + log("Path changed, updating sticky notes: " + currentPath); lastPath = currentPath; drawStickyNotes(stickyNotes, save, deleteStickyNote); } diff --git a/src/application.js b/src/application.js index acb1a7b..8ba58fe 100644 --- a/src/application.js +++ b/src/application.js @@ -90,7 +90,7 @@ const UPDATE_INTERVAL = 1000 / 60; // 60 FPS const AFK_TIME = isDebug() ? 0 : 1000 * 5; const PET_BOOST_DURATION = 1000 * 60 * 5; const PET_MENU_COOLDOWN = 1000; -const URL_CHECK_INTERVAL = 500; +const URL_CHECK_INTERVAL = 250; const HOP_DELAY = 500; // Random event chances per tick @@ -431,7 +431,7 @@ Promise.all([ setInterval(() => { const currentPath = getContext().getPath().split("?")[0]; if (currentPath !== lastPath) { - log("Path changed, updating sticky notes"); + log("Path changed, updating sticky notes: " + currentPath); lastPath = currentPath; drawStickyNotes(stickyNotes, save, deleteStickyNote); } diff --git a/src/context.js b/src/context.js index 9f1f50b..1600065 100644 --- a/src/context.js +++ b/src/context.js @@ -1,6 +1,7 @@ import { debug, log, error } from "./shared.js"; const SAVE_KEY = "birbSaveData"; +const ROOT_PATH = ""; /** * @typedef {import('./application.js').BirbSaveData} BirbSaveData @@ -231,7 +232,6 @@ class BrowserExtensionContext extends Context { } export class ObsidianContext extends Context { - /** * @override * @returns {boolean} @@ -246,8 +246,12 @@ export class ObsidianContext extends Context { * @returns {Promise} */ async getSaveData() { - // @ts-expect-error - return await OBSIDIAN_PLUGIN.loadData() ?? {}; + return new Promise((resolve) => { + // @ts-expect-error + OBSIDIAN_PLUGIN.loadData().then((data) => { + resolve(data ?? {}); + }); + }); } /** @@ -256,7 +260,7 @@ export class ObsidianContext extends Context { */ async putSaveData(saveData) { // @ts-expect-error - return await OBSIDIAN_PLUGIN.saveData(saveData); + await OBSIDIAN_PLUGIN.saveData(saveData); } /** @override */ @@ -277,8 +281,36 @@ export class ObsidianContext extends Context { } /** @override */ - areStickyNotesEnabled() { - return false; + getPath() { + // @ts-expect-error + const file = app.workspace.getActiveFile(); + if (file && this.getActiveEditorElement()) { + return file.path; + } else { + return ROOT_PATH; + } + } + + /** @override */ + getActivePage() { + if (this.getPath() === ROOT_PATH) { + // Root page, use document element + return document.documentElement + } + return this.getActiveEditorElement() ?? document.documentElement; + } + + /** @override */ + isPathApplicable(path) { + return path === this.getPath(); + } + + /** @returns {HTMLElement|null} */ + getActiveEditorElement() { + // @ts-expect-error + const activeLeaf = app.workspace.activeLeaf; + const leafElement = activeLeaf?.view?.containerEl; + return leafElement?.querySelector(".cm-scroller") ?? null; } } diff --git a/src/shared.js b/src/shared.js index 80c9889..c2100ce 100644 --- a/src/shared.js +++ b/src/shared.js @@ -67,8 +67,9 @@ export function onClick(element, action) { * @param {HTMLElement|null} element The element to detect drag events on * @param {boolean} [parent] Whether to move the parent element when the child is dragged * @param {(top: number, left: number) => void} [callback] Callback for when element is moved + * @param {HTMLElement} [pageElement] The page element to constrain movement within */ -export function makeDraggable(element, parent = true, callback = () => { }) { +export function makeDraggable(element, parent = true, callback = () => { }, pageElement) { if (!element) { return; } @@ -114,9 +115,12 @@ export function makeDraggable(element, parent = true, callback = () => { }) { }); document.addEventListener("mousemove", (e) => { + const page = pageElement || document.documentElement; + const maxX = page.scrollWidth - elementToMove.clientWidth; + const maxY = page.scrollHeight - elementToMove.clientHeight; if (isMouseDown) { - elementToMove.style.left = `${Math.max(0, e.clientX - offsetX)}px`; - elementToMove.style.top = `${Math.max(0, e.clientY - offsetY)}px`; + elementToMove.style.left = `${Math.max(0, Math.min(maxX, e.clientX - offsetX))}px`; + elementToMove.style.top = `${Math.max(0, Math.min(maxY, e.clientY - offsetY))}px`; } }); diff --git a/src/stickyNotes.js b/src/stickyNotes.js index f070e69..130f52d 100644 --- a/src/stickyNotes.js +++ b/src/stickyNotes.js @@ -69,7 +69,7 @@ export function renderStickyNote(stickyNote, page, onSave, onDelete) { stickyNote.top = top; stickyNote.left = left; onSave(); - }); + }, page); if (closeButton) { makeClosable(() => { diff --git a/src/stylesheet.css b/src/stylesheet.css index 0d4811a..1653def 100644 --- a/src/stylesheet.css +++ b/src/stylesheet.css @@ -119,6 +119,7 @@ flex-grow: 1; user-select: none; color: var(--birb-background-color); + white-space: nowrap; } .birb-window-close {