`;
sbm_pageNumberEl.textContent = "Cover";
} else {
// Show Page Content
const pageIndex = sbm_currentPreviewPage - 1;
sbm_pageContentEl.innerHTML = sbm_escapeHTML(sbm_data.pages[pageIndex]);
sbm_pageNumberEl.textContent = `Page ${sbm_currentPreviewPage} of ${totalPages}`;
}
// Update nav buttons
sbm_prevPageBtn.disabled = (sbm_currentPreviewPage === 0);
sbm_nextPageBtn.disabled = (sbm_currentPreviewPage === totalPages);
}
window.sbm_nextPage = function() {
if (sbm_currentPreviewPage < sbm_data.pages.length) {
sbm_currentPreviewPage++;
sbm_renderPreview();
}
}
window.sbm_prevPage = function() {
if (sbm_currentPreviewPage > 0) {
sbm_currentPreviewPage--;
sbm_renderPreview();
}
}
// --- CONFIGURATION FUNCTIONS ---
/**
* Loads data into the config tab fields
*/
function sbm_loadConfigData() {
sbm_bookTitleInput.value = sbm_data.title;
sbm_renderManageList();
}
/**
* Updates the main data store when the title is changed
*/
function sbm_updateTitle() {
sbm_data.title = sbm_bookTitleInput.value;
sbm_renderPreview(); // Update preview if cover is showing
}
/**
* Renders the list of editable pages
*/
function sbm_renderManageList() {
if (!sbm_managePagesEl) return;
sbm_managePagesEl.innerHTML = '';
if (sbm_data.pages.length === 0) {
sbm_managePagesEl.innerHTML = '
';
return;
}
sbm_data.pages.forEach((content, index) => {
const item = document.createElement('div');
item.className = 'sbm-list-item';
item.innerHTML = `
Page ${index + 1}: ${sbm_escapeHTML(content)}
`;
sbm_managePagesEl.appendChild(item);
});
}
/**
* Handles the save button submit (add new or update existing)
*/
window.sbm_handlePageSave = function(event) {
event.preventDefault();
const content = sbm_pageContentInput.value.trim();
const editIndex = sbm_pageEditIndex.value;
if (!content) {
alert('Page content cannot be empty.');
return;
}
if (editIndex === '') {
// Add new page
sbm_data.pages.push(content);
} else {
// Update existing page
sbm_data.pages[parseInt(editIndex)] = content;
}
sbm_clearPageForm();
sbm_renderManageList();
sbm_renderPreview(); // Update dashboard in case total pages changed
}
/**
* Loads a page's content into the form for editing
*/
window.sbm_editPage = function(index) {
sbm_pageContentInput.value = sbm_data.pages[index];
sbm_pageEditIndex.value = index;
sbm_savePageBtn.textContent = 'Save Changes';
sbm_savePageBtn.classList.remove('sbm-btn-success');
sbm_savePageBtn.classList.add('sbm-btn-primary');
sbm_pageContentInput.focus();
}
/**
* Deletes a page
*/
window.sbm_deletePage = function(index) {
if (confirm(`Are you sure you want to delete Page ${index + 1}?`)) {
sbm_data.pages.splice(index, 1);
sbm_clearPageForm(); // In case it was being edited
sbm_renderManageList();
sbm_currentPreviewPage = 0; // Reset preview to cover
sbm_renderPreview();
}
}
/**
* Clears the page form and resets its state
*/
window.sbm_clearPageForm = function() {
sbm_pageContentInput.value = '';
sbm_pageEditIndex.value = '';
sbm_savePageBtn.textContent = 'Add New Page';
sbm_savePageBtn.classList.add('sbm-btn-success');
sbm_savePageBtn.classList.remove('sbm-btn-primary');
}
// --- TAB & NAVIGATION FUNCTIONS ---
window.sbm_switchTab = function(tabIndex) {
sbm_currentTabIndex = tabIndex;
sbm_tabContents.forEach((content, index) => {
content.classList.toggle('sbm-active', index === tabIndex);
});
sbm_tabs.forEach((tab, index) => {
tab.classList.toggle('sbm-active', index === tabIndex);
});
sbm_updateNavButtons();
}
window.sbm_navigateTabs = function(direction) {
if (direction === 'next' && sbm_currentTabIndex < sbm_numTabs - 1) {
sbm_switchTab(sbm_currentTabIndex + 1);
} else if (direction === 'prev' && sbm_currentTabIndex > 0) {
sbm_switchTab(sbm_currentTabIndex - 1);
}
}
function sbm_updateNavButtons() {
sbm_prevBtn.style.visibility = (sbm_currentTabIndex === 0) ? 'hidden' : 'visible';
sbm_nextBtn.style.visibility = (sbm_currentTabIndex === sbm_numTabs - 1) ? 'hidden' : 'visible';
}
// --- PDF GENERATION ---
window.sbm_generatePdf = function() {
if (typeof jspdf === 'undefined' || typeof jspdf.jsPDF === 'undefined') {
alert('Error: PDF generation library (jsPDF) not loaded.');
return;
}
try {
const { jsPDF } = jspdf;
const doc = new jsPDF();
const margin = 20;
const docWidth = doc.internal.pageSize.getWidth();
const docHeight = doc.internal.pageSize.getHeight();
const textWidth = docWidth - (margin * 2);
// --- Page 1: Cover ---
doc.setFont('helvetica', 'bold');
doc.setFontSize(28);
doc.setTextColor(varGet('--sbm-primary-color', '#0073e6'));
const titleLines = doc.splitTextToSize(sbm_data.title, textWidth);
doc.text(titleLines, docWidth / 2, docHeight / 2 - 10, { align: 'center' });
doc.setFont('helvetica', 'normal');
doc.setFontSize(16);
doc.setTextColor(varGet('--sbm-text-color', '#333'));
doc.text("A Simple Book", docWidth / 2, docHeight / 2 + (titleLines.length * 10), { align: 'center' });
// --- Content Pages ---
sbm_data.pages.forEach((content, index) => {
doc.addPage();
let cursorY = margin;
// Page Number
const pageNum = index + 1;
doc.setFont('helvetica', 'bold');
doc.setFontSize(14);
doc.setTextColor(varGet('--sbm-primary-color', '#0073e6'));
doc.text(`Page ${pageNum}`, docWidth / 2, cursorY, { align: 'center' });
cursorY += 15;
// Page Content
doc.setFont('helvetica', 'normal');
doc.setFontSize(12);
doc.setTextColor(varGet('--sbm-text-color', '#333'));
const contentLines = doc.splitTextToSize(content, textWidth);
// Check for page overflow (simple check)
const textHeight = contentLines.length * (doc.getLineHeight() / doc.internal.scaleFactor);
if (cursorY + textHeight > docHeight - margin) {
// This simple implementation doesn't handle content splitting across pages.
// For this tool, we assume one page's text fits on one PDF page.
console.warn(`Page ${pageNum} content may be truncated in PDF.`);
}
doc.text(contentLines, margin, cursorY, { lineHeightFactor: 1.5 });
});
// --- Save PDF ---
const safeTitle = sbm_data.title.replace(/[^a-z0-9]/gi, '_').toLowerCase();
doc.save(`${safeTitle || 'simple_book'}.pdf`);
} catch (e) {
console.error("PDF Generation Error: ", e);
alert("An error occurred while generating the PDF.");
}
}
// --- UTILITY FUNCTIONS ---
function varGet(varName, fallback = '#000') {
try {
return getComputedStyle(document.documentElement).getPropertyValue(varName).trim() || fallback;
} catch (e) {
return fallback;
}
}
function sbm_escapeHTML(str) {
if (!str) return '';
// Basic escape to prevent HTML injection in preview
// Replaces < and >
return str.replace(//g, ">");
}
// --- INITIALIZATION ---
function sbm_initTool() {
// Setup tabs
sbm_switchTab(0);
// Load config data
sbm_loadConfigData();
// Render initial preview
sbm_renderPreview();
// Attach listeners
sbm_bookTitleInput.addEventListener('input', sbm_updateTitle);
}
sbm_initTool(); // Run the tool
}); // End of DOMContentLoaded
No pages added yet.
