- 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
175 lines
6.0 KiB
JavaScript
175 lines
6.0 KiB
JavaScript
/**
|
|
* Insertr Configuration System
|
|
* Extensible field type detection and form configuration
|
|
*/
|
|
|
|
class InsertrConfig {
|
|
constructor(customConfig = {}) {
|
|
// Default field type mappings
|
|
this.defaultFieldTypes = {
|
|
'H1': { type: 'text', label: 'Headline', maxLength: 60, placeholder: 'Enter headline...' },
|
|
'H2': { type: 'text', label: 'Subheading', maxLength: 80, placeholder: 'Enter subheading...' },
|
|
'H3': { type: 'text', label: 'Section Title', maxLength: 100, placeholder: 'Enter title...' },
|
|
'H4': { type: 'text', label: 'Title', maxLength: 100, placeholder: 'Enter title...' },
|
|
'H5': { type: 'text', label: 'Title', maxLength: 100, placeholder: 'Enter title...' },
|
|
'H6': { type: 'text', label: 'Title', maxLength: 100, placeholder: 'Enter title...' },
|
|
'P': { type: 'textarea', label: 'Paragraph', rows: 3, placeholder: 'Enter paragraph text...' },
|
|
'A': { type: 'link', label: 'Link', placeholder: 'Enter link text...' },
|
|
'SPAN': { type: 'text', label: 'Text', placeholder: 'Enter text...' },
|
|
'CITE': { type: 'text', label: 'Citation', placeholder: 'Enter citation...' },
|
|
'BUTTON': { type: 'text', label: 'Button Text', placeholder: 'Enter button text...' }
|
|
};
|
|
|
|
// CSS class-based enhancements
|
|
this.classEnhancements = {
|
|
'lead': {
|
|
label: 'Lead Paragraph',
|
|
rows: 4,
|
|
placeholder: 'Enter lead paragraph...'
|
|
},
|
|
'btn-primary': {
|
|
type: 'link',
|
|
label: 'Primary Button',
|
|
includeUrl: true,
|
|
placeholder: 'Enter button text...'
|
|
},
|
|
'btn-secondary': {
|
|
type: 'link',
|
|
label: 'Secondary Button',
|
|
includeUrl: true,
|
|
placeholder: 'Enter button text...'
|
|
},
|
|
'section-subtitle': {
|
|
label: 'Section Subtitle',
|
|
placeholder: 'Enter subtitle...'
|
|
}
|
|
};
|
|
|
|
// Content ID-based enhancements
|
|
this.contentIdRules = [
|
|
{
|
|
pattern: /cta/i,
|
|
config: { label: 'Call to Action' }
|
|
},
|
|
{
|
|
pattern: /quote/i,
|
|
config: {
|
|
type: 'textarea',
|
|
rows: 3,
|
|
label: 'Quote',
|
|
placeholder: 'Enter quote...'
|
|
}
|
|
}
|
|
];
|
|
|
|
// Validation limits
|
|
this.limits = {
|
|
maxContentLength: 10000,
|
|
maxHtmlTags: 20,
|
|
...customConfig.limits
|
|
};
|
|
|
|
// Markdown configuration
|
|
this.markdown = {
|
|
enabled: true,
|
|
label: 'Content (Markdown)',
|
|
rows: 8,
|
|
placeholder: 'Enter content in Markdown format...\n\nUse **bold**, *italic*, [links](url), and double line breaks for new paragraphs.',
|
|
...customConfig.markdown
|
|
};
|
|
|
|
// Merge custom configurations
|
|
this.fieldTypes = { ...this.defaultFieldTypes, ...customConfig.fieldTypes };
|
|
this.classEnhancements = { ...this.classEnhancements, ...customConfig.classEnhancements };
|
|
|
|
if (customConfig.contentIdRules) {
|
|
this.contentIdRules = [...this.contentIdRules, ...customConfig.contentIdRules];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate field configuration for an element
|
|
* @param {HTMLElement} element - The element to configure
|
|
* @returns {Object} Field configuration
|
|
*/
|
|
generateFieldConfig(element) {
|
|
// Check for explicit markdown type first
|
|
const fieldType = element.getAttribute('data-field-type');
|
|
if (fieldType === 'markdown') {
|
|
return { type: 'markdown', ...this.markdown };
|
|
}
|
|
|
|
// Start with tag-based configuration
|
|
const tagName = element.tagName;
|
|
let config = { ...this.fieldTypes[tagName] } || {
|
|
type: 'text',
|
|
label: 'Content',
|
|
placeholder: 'Enter content...'
|
|
};
|
|
|
|
// Apply class-based enhancements
|
|
for (const [className, enhancement] of Object.entries(this.classEnhancements)) {
|
|
if (element.classList.contains(className)) {
|
|
config = { ...config, ...enhancement };
|
|
}
|
|
}
|
|
|
|
// Apply content ID-based rules
|
|
const contentId = element.getAttribute('data-content-id');
|
|
if (contentId) {
|
|
for (const rule of this.contentIdRules) {
|
|
if (rule.pattern.test(contentId)) {
|
|
config = { ...config, ...rule.config };
|
|
}
|
|
}
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
/**
|
|
* Add or override field type mapping
|
|
* @param {string} tagName - HTML tag name
|
|
* @param {Object} config - Field configuration
|
|
*/
|
|
addFieldType(tagName, config) {
|
|
this.fieldTypes[tagName.toUpperCase()] = config;
|
|
}
|
|
|
|
/**
|
|
* Add class-based enhancement
|
|
* @param {string} className - CSS class name
|
|
* @param {Object} enhancement - Configuration enhancement
|
|
*/
|
|
addClassEnhancement(className, enhancement) {
|
|
this.classEnhancements[className] = enhancement;
|
|
}
|
|
|
|
/**
|
|
* Add content ID rule
|
|
* @param {RegExp|string} pattern - Pattern to match content IDs
|
|
* @param {Object} config - Configuration to apply
|
|
*/
|
|
addContentIdRule(pattern, config) {
|
|
const regexPattern = pattern instanceof RegExp ? pattern : new RegExp(pattern, 'i');
|
|
this.contentIdRules.push({ pattern: regexPattern, config });
|
|
}
|
|
|
|
/**
|
|
* Get validation limits
|
|
* @returns {Object} Validation limits
|
|
*/
|
|
getValidationLimits() {
|
|
return { ...this.limits };
|
|
}
|
|
}
|
|
|
|
// Export for module usage
|
|
if (typeof module !== 'undefined' && module.exports) {
|
|
module.exports = InsertrConfig;
|
|
}
|
|
|
|
// Global export for browser usage
|
|
if (typeof window !== 'undefined') {
|
|
window.InsertrConfig = InsertrConfig;
|
|
} |