<style>
#notes {
width: 300px;
height: 200px;
background: rgba(255, 255, 255, 0.8);
border: 1px solid #ccc;
padding: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
overflow: auto;
font-family: Arial, sans-serif;
font-size: 16px;
line-height: 1.5;
color: #333;
position: fixed;
resize: both;
cursor: grab;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
<textarea id="notes"></textarea>
<!Notepad Positional Resize Data!>
<script>
// Global db connection
let dbConnection = null;
let contentSizeInBytes = 0;
// Initialize the broadcast channel
const broadcast = new BroadcastChannel('note_updates');
// Get the notes element
const notes = document.getElementById('notes');
// Debounce function to throttle the number of operations
function debounce(func, timeout = 300) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => { func.apply(this, args); }, timeout);
};
}
// Function to open a connection to the IndexedDB
function initDB(callback) {
if (dbConnection) {
callback(dbConnection);
return;
}
const request = indexedDB.open('notesDB', 2);
request.onupgradeneeded = function(event) {
const db = event.target.result;
if (!db.objectStoreNames.contains('notes')) {
db.createObjectStore('notes', { keyPath: 'id' });
}
};
request.onsuccess = function(event) {
dbConnection = event.target.result;
callback(dbConnection);
};
request.onerror = function(event) {
console.error('Database error:', event.target.error);
};
}
// Function to save a note to the IndexedDB
function saveNote(content, position, size) {
initDB(function(db) {
const transaction = db.transaction('notes', 'readwrite');
const objectStore = transaction.objectStore('notes');
objectStore.put({ id: 'singleNote', content, position, size });
});
}
// Function to load a note from the IndexedDB
function loadNote() {
initDB(function(db) {
const transaction = db.transaction('notes', 'readonly');
const objectStore = transaction.objectStore('notes');
const request = objectStore.get('singleNote');
request.onsuccess = function(event) {
const data = event.target.result;
if (data) {
notes.value = data.content;
notes.style.top = data.position.top;
notes.style.left = data.position.left;
notes.style.width = data.size.width;
notes.style.height = data.size.height;
}
};
});
}
// Function to update the content size in bytes
function updateContentSize(newContent) {
contentSizeInBytes = new Blob([newContent]).size;
checkMemoryUsage();
}
// Function to check the memory usage of the notepad
function checkMemoryUsage() {
const sizeInMegabytes = contentSizeInBytes / (1024 * 1024);
console.log(`Estimated notepad size: ${sizeInMegabytes.toFixed(2)} MB`);
if (sizeInMegabytes >= 10) {
console.log('Notepad size exceeds 10 MB. Initiating clear.');
clearNotepad();
} else {
console.log('Notepad size within limit. No action taken.');
}
}
// Function to clear the notepad content
function clearNotepad() {
notes.value = '';
contentSizeInBytes = 0; // Reset the content size
const position = { top: '50%', left: '50%' };
const size = { width: '300px', height: '200px' };
saveNote('', position, size);
broadcast.postMessage({ content: '', position, size });
console.log('Notepad content cleared and reset to default size and position.');
}
// Event listener for input, debounced
notes.addEventListener('input', debounce(function() {
const position = { top: notes.style.top, left: notes.style.left };
const size = { width: notes.style.width, height: notes.style.height };
updateContentSize(notes.value);
saveNote(notes.value, position, size);
}));
// Function to remove all event listeners if needed
function removeAllListeners() {
notes.removeEventListener('input', debounce);
}
const debouncedSaveNote = debounce((content, position, size) => {
saveNote(content, position, size);
});
function RETURN() {
const centerX = (window.innerWidth - notes.offsetWidth) / 2;
const centerY = (window.innerHeight - notes.offsetHeight) / 2;
notes.style.left = `${centerX}px`;
notes.style.top = `${centerY}px`;
const position = { top: `${centerY}px`, left: `${centerX}px` };
const size = { width: notes.style.width, height: notes.style.height };
saveNote(notes.value, position, size);
console.log('Notepad reset to center position.');
}
window.RETURN = RETURN;
// Prevent the context menu on right-click
notes.addEventListener('contextmenu', function(event) {
event.preventDefault();
});
window.addEventListener('resize', function() {
const size = { width: notes.style.width, height: notes.style.height };
saveNote(notes.value, { top: notes.style.top, left: notes.style.left }, size);
});
// Update the notepad size and position upon mouseup
notes.addEventListener('mouseup', function() {
const position = { top: notes.style.top, left: notes.style.left };
const size = { width: notes.style.width, height: notes.style.height };
saveNote(notes.value, position, size);
});
// Right-click drag functionality
notes.addEventListener('mousedown', function(event) {
if (event.button === 2) {
event.preventDefault();
let startPos = { x: event.clientX, y: event.clientY };
const onMove = function(moveEvent) {
let newPos = {
x: notes.offsetLeft + (moveEvent.clientX - startPos.x),
y: notes.offsetTop + (moveEvent.clientY - startPos.y)
};
notes.style.left = `${newPos.x}px`;
notes.style.top = `${newPos.y}px`;
startPos = { x: moveEvent.clientX, y: moveEvent.clientY };
};
const onUp = function(upEvent) {
document.removeEventListener('mousemove', onMove);
document.removeEventListener('mouseup', onUp);
saveNote(notes.value, { top: notes.style.top, left: notes.style.left }, { width: notes.style.width, height: notes.style.height });
};
document.addEventListener('mousemove', onMove);
document.addEventListener('mouseup', onUp);
}
});
// Ensure listeners are removed before the page unloads
window.addEventListener('beforeunload', removeAllListeners);
// Load the note when the window is fully loaded
window.addEventListener('load', loadNote);
</script>
When exceeding the 10mb limit a few times it will just not clear 50 – 100 mib of data and I can’t figure out why.
It should remove all the data in the notepad and the memory shoulddd be its own usage.
I dont know what else to add but stackoverflow is forcing me to put more details even though I dont have any more to share.
The leak
The expected