Clean up demo site: remove manual IDs and frontend-only approach
- Remove all manual data-content-id attributes from HTML files - Archive old insertr JS/CSS assets to demo-site/archive/ - Remove hardcoded script includes and CSS links - Remove old authentication controls and mock API - Enable pure zero-config approach with class='insertr' only - Parser now generates all 40 content IDs automatically
This commit is contained in:
268
demo-site/archive/insertr-old/content-manager.js
Normal file
268
demo-site/archive/insertr-old/content-manager.js
Normal file
@@ -0,0 +1,268 @@
|
||||
/**
|
||||
* Insertr Content Manager Module
|
||||
* Handles content operations, storage, and API interactions
|
||||
*/
|
||||
|
||||
class InsertrContentManager {
|
||||
constructor(options = {}) {
|
||||
this.options = {
|
||||
apiEndpoint: options.apiEndpoint || '/api/content',
|
||||
storageKey: options.storageKey || 'insertr_content',
|
||||
...options
|
||||
};
|
||||
|
||||
this.contentCache = new Map();
|
||||
this.loadContentFromStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load content from localStorage
|
||||
*/
|
||||
loadContentFromStorage() {
|
||||
try {
|
||||
const stored = localStorage.getItem(this.options.storageKey);
|
||||
if (stored) {
|
||||
const data = JSON.parse(stored);
|
||||
this.contentCache = new Map(Object.entries(data));
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to load content from storage:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save content to localStorage
|
||||
*/
|
||||
saveContentToStorage() {
|
||||
try {
|
||||
const data = Object.fromEntries(this.contentCache);
|
||||
localStorage.setItem(this.options.storageKey, JSON.stringify(data));
|
||||
} catch (error) {
|
||||
console.warn('Failed to save content to storage:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content for a specific element
|
||||
* @param {string} contentId - Content identifier
|
||||
* @returns {string|Object} Content data
|
||||
*/
|
||||
getContent(contentId) {
|
||||
return this.contentCache.get(contentId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set content for an element
|
||||
* @param {string} contentId - Content identifier
|
||||
* @param {string|Object} content - Content data
|
||||
*/
|
||||
setContent(contentId, content) {
|
||||
this.contentCache.set(contentId, content);
|
||||
this.saveContentToStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply content to DOM element
|
||||
* @param {HTMLElement} element - Element to update
|
||||
* @param {string|Object} content - Content to apply
|
||||
*/
|
||||
applyContentToElement(element, content) {
|
||||
const config = element._insertrConfig;
|
||||
|
||||
if (config.type === 'markdown') {
|
||||
// Handle markdown collection - content is a string
|
||||
this.applyMarkdownContent(element, content);
|
||||
} else if (config.type === 'link' && config.includeUrl && content.url !== undefined) {
|
||||
// Update link text and URL
|
||||
element.textContent = this.sanitizeForDisplay(content.text, 'text') || element.textContent;
|
||||
if (content.url) {
|
||||
element.href = this.sanitizeForDisplay(content.url, 'url');
|
||||
}
|
||||
} else if (content.text !== undefined) {
|
||||
// Update text content
|
||||
element.textContent = this.sanitizeForDisplay(content.text, 'text');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply markdown content to element
|
||||
* @param {HTMLElement} element - Element to update
|
||||
* @param {string} markdownText - Markdown content
|
||||
*/
|
||||
applyMarkdownContent(element, markdownText) {
|
||||
// This method will be implemented by the main Insertr class
|
||||
// which has access to the markdown processor
|
||||
if (window.insertr && window.insertr.renderMarkdown) {
|
||||
window.insertr.renderMarkdown(element, markdownText);
|
||||
} else {
|
||||
console.warn('Markdown processor not available');
|
||||
element.textContent = markdownText;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract content from DOM element
|
||||
* @param {HTMLElement} element - Element to extract from
|
||||
* @returns {string|Object} Extracted content
|
||||
*/
|
||||
extractContentFromElement(element) {
|
||||
const config = element._insertrConfig;
|
||||
|
||||
if (config.type === 'markdown') {
|
||||
// For markdown collections, return cached content or extract text
|
||||
const contentId = element.getAttribute('data-content-id');
|
||||
const cached = this.contentCache.get(contentId);
|
||||
|
||||
if (cached) {
|
||||
// Handle both old format (object) and new format (string)
|
||||
if (typeof cached === 'string') {
|
||||
return cached;
|
||||
} else if (cached.text && typeof cached.text === 'string') {
|
||||
return cached.text;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: extract basic text content
|
||||
const clone = element.cloneNode(true);
|
||||
const editBtn = clone.querySelector('.insertr-edit-btn');
|
||||
if (editBtn) editBtn.remove();
|
||||
|
||||
// Convert basic HTML structure to markdown
|
||||
return this.basicHtmlToMarkdown(clone.innerHTML);
|
||||
}
|
||||
|
||||
// Clone element to avoid modifying original
|
||||
const clone = element.cloneNode(true);
|
||||
|
||||
// Remove edit button from clone
|
||||
const editBtn = clone.querySelector('.insertr-edit-btn');
|
||||
if (editBtn) editBtn.remove();
|
||||
|
||||
// Extract content based on element type
|
||||
if (config.type === 'link' && config.includeUrl) {
|
||||
return {
|
||||
text: clone.textContent.trim(),
|
||||
url: element.href || ''
|
||||
};
|
||||
}
|
||||
|
||||
return clone.textContent.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert basic HTML to markdown (for initial content extraction)
|
||||
* @param {string} html - HTML content
|
||||
* @returns {string} Markdown content
|
||||
*/
|
||||
basicHtmlToMarkdown(html) {
|
||||
let markdown = html;
|
||||
|
||||
// Basic paragraph conversion
|
||||
markdown = markdown.replace(/<p[^>]*>(.*?)<\/p>/gis, (match, content) => {
|
||||
return content.trim() + '\n\n';
|
||||
});
|
||||
markdown = markdown.replace(/<br\s*\/?>/gi, '\n');
|
||||
|
||||
// Remove HTML tags
|
||||
markdown = markdown.replace(/<[^>]*>/g, '');
|
||||
|
||||
// Clean up entities
|
||||
markdown = markdown.replace(/ /g, ' ');
|
||||
markdown = markdown.replace(/&/g, '&');
|
||||
markdown = markdown.replace(/</g, '<');
|
||||
markdown = markdown.replace(/>/g, '>');
|
||||
|
||||
// Clean whitespace
|
||||
markdown = markdown
|
||||
.split('\n')
|
||||
.map(line => line.trim())
|
||||
.join('\n')
|
||||
.replace(/\n\n\n+/g, '\n\n')
|
||||
.trim();
|
||||
|
||||
return markdown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save content to server (mock implementation)
|
||||
* @param {string} contentId - Content identifier
|
||||
* @param {string|Object} content - Content to save
|
||||
* @returns {Promise} Save operation promise
|
||||
*/
|
||||
async saveToServer(contentId, content) {
|
||||
// Mock API call - replace with real implementation
|
||||
try {
|
||||
console.log(`💾 Saving content for ${contentId}:`, content);
|
||||
|
||||
// Simulate network delay
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
|
||||
// Store locally for now
|
||||
this.setContent(contentId, content);
|
||||
|
||||
return { success: true, contentId, content };
|
||||
} catch (error) {
|
||||
console.error('Failed to save content:', error);
|
||||
throw new Error('Save operation failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic sanitization for display
|
||||
* @param {string} content - Content to sanitize
|
||||
* @param {string} type - Content type
|
||||
* @returns {string} Sanitized content
|
||||
*/
|
||||
sanitizeForDisplay(content, type) {
|
||||
if (!content) return '';
|
||||
|
||||
switch (type) {
|
||||
case 'text':
|
||||
return this.escapeHtml(content);
|
||||
case 'url':
|
||||
if (content.startsWith('javascript:') || content.startsWith('data:')) {
|
||||
return '';
|
||||
}
|
||||
return content;
|
||||
default:
|
||||
return this.escapeHtml(content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape HTML characters
|
||||
* @param {string} text - Text to escape
|
||||
* @returns {string} Escaped text
|
||||
*/
|
||||
escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all cached content
|
||||
*/
|
||||
clearCache() {
|
||||
this.contentCache.clear();
|
||||
localStorage.removeItem(this.options.storageKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all cached content
|
||||
* @returns {Object} All cached content
|
||||
*/
|
||||
getAllContent() {
|
||||
return Object.fromEntries(this.contentCache);
|
||||
}
|
||||
}
|
||||
|
||||
// Export for module usage
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = InsertrContentManager;
|
||||
}
|
||||
|
||||
// Global export for browser usage
|
||||
if (typeof window !== 'undefined') {
|
||||
window.InsertrContentManager = InsertrContentManager;
|
||||
}
|
||||
Reference in New Issue
Block a user