Unify all formatting buttons to use consistent three-layer architecture

- Remove .insertr-default-style special styling (blue background, border, dot indicator)
- Make ALL buttons use .insertr-style-preview with unified appearance
- Maintain authentic style previews in isolated .insertr-style-sample layer
- Bold buttons show bold text, .brand buttons show green uppercase text, etc.
- Eliminate visual inconsistency between semantic and detected style buttons
- Simplify CSS by removing ~50 lines of duplicate button styling
- Provide consistent professional toolbar appearance across all formatting options
This commit is contained in:
2025-09-21 22:31:42 +02:00
parent 479a537f21
commit b25663f76b
5 changed files with 8 additions and 299 deletions

View File

@@ -256,8 +256,8 @@ The `.insertr-add` class transforms a container into a dynamic collection where
- Styling: All classes and structure preserved
### User Interface
- **Add Button**: Floating "+" button.
- **Remove Controls**: Delete option for each item (with confirmation)
- **Add Button**: Floating "+" button. Should be in the top right of the .insertr-add container.
- **Remove Controls**: Delete option for each item (with confirmation). Should be in the top tight corner of the item.
- **Reorder Capability**: Drag-and-drop or up/down controls
- **Duplication**: New items inherit the exact structure and styling

View File

@@ -1,187 +0,0 @@
# Insertr Structural Refactoring - Work in Progress
## Current Status: Major Simplification Opportunity Identified
We've identified that the current Insertr codebase has remnants from multiple refactoring phases and can be significantly simplified by fully embracing the HTML-first philosophy outlined in CLASSES.md.
## Key Insights Discovered
### 1. **Obsolete Content Type System**
- **Problem**: Currently has 3 content types (`'text'`, `'html'`, `'structured'`) with complex routing logic
- **HTML-First Reality**: Only need HTML preservation with automatic style detection
- **Opportunity**: Remove `data-content-type` attributes entirely and detect behavior from HTML element tags
### 2. **Multiple Editor Systems (Legacy)**
- **Current**: Complex strategy detection choosing between simple vs rich editors
- **HTML-First**: Always use StyleAwareEditor with HTML preservation and remove legacy code
- **Benefit**: Massive code reduction, consistent behavior everywhere
### 3. **Element-Based Behavior Detection**
- **Instead of**: `data-content-type="link"` attributes
- **Use**: Element tag analysis (`<a>` = link behavior, `<p>` = text behavior)
- **Source**: Behavior rules already defined in CLASSES.md
### 4. **UX Optimization Opportunity**
- **Direct Multi-Property Editing**: `<a class="insertr">` should open URL+text editor immediately
- **Rich Text Editing**: `<p class="insertr">` with nested elements should use StyleAwareEditor
- **Context-Appropriate UX**: Right editor for the right element type
## Planned Refactoring (Major Changes)
Keep in mind that we need no legacy code preserved or backwards compatibility. Database changes can be done to the schema, not with ALTER statements. We have no data to preserve and no users of any current insertr versions.
### Phase 1: Frontend Simplification
- [ ] **Remove content type routing** from StyleAwareEditor
- [ ] **Eliminate 'text' and 'structured' handlers** - keep only HTML preservation
- [ ] **Remove simple/textarea editor** that strips HTML formatting
- [ ] **Implement element-based behavior detection** using tag names
- [ ] **Create direct multi-property editors** for `<a>`, `<button>`, `<img>`
### Phase 2: Backend Simplification
- [ ] **Remove `data-content-type` generation** from enhancer
- [ ] **Simplify API** to be purely HTML-based
- [ ] **Keep only `data-content-id`** for content tracking
- [ ] **Update database schema** remove type field
### Phase 3: Container Expansion Intelligence
- [ ] **Improve viable children detection** with element-type-aware rules
- [ ] **Smart stopping rules** for multi-property elements (`<a>`, `<button>`, `<img>`)
- [ ] **Semantic container expansion** respecting HTML element purposes
- [ ] **Framework/technical container filtering** (React, Gatsby artifacts)
## Technical Architecture Changes
### Before (Complex Multi-System):
```javascript
// Multiple content types with routing
switch (content.type) {
case 'text': // Strips HTML - obsolete
case 'html': // HTML preservation
case 'structured': // Legacy template system
}
// Multiple editor strategies
switch (analysis.strategy) {
case 'simple': // Textarea - strips HTML
case 'rich': // Rich editor with styles
}
```
### After (Unified HTML-First):
```javascript
// Single path for ALL .insertr elements
class StyleAwareEditor {
async initialize() {
// 1. Always extract HTML with preservation
this.originalContent = this.htmlEngine.extractForEditing(this.element);
// 2. Always detect styles from nested elements
this.detectedStyles = this.styleEngine.detectStyles(this.element);
// 3. Element-based UX routing
if (this.isMultiPropertyElement()) {
this.createDirectEditor(); // URL+text for links
} else {
this.createRichEditor(); // Rich text with styles
}
}
}
```
## Container Expansion Rules (New Logic)
Container expansions are syntactic sugar for applying the insertr class to viable children. Our autodetection might need to be revised. Some anchor tags for instance can be a formatting style inside of content, or it could be a standalone navigation link. So for instance a p>a element might be formatting, while div>a could be a link. This might resolve itself when we respect boundaries, but would need further investigation.
### Stopping Rules:
- **Stop**: Element has `.insertr` (respect boundaries)
- **Stop**: Multi-property element found (`<a>`, `<button>`, `<img>` get direct editing)
- **Stop**: Framework containers (React, Gatsby artifacts)
- **Continue**: Semantic containers with viable children
## Benefits of This Refactoring
### 🚀 **Massive Code Reduction**
- Remove 3 content type handlers → 1 HTML handler
- Remove 2 editor types → 1 unified system
- Remove strategy detection → linear flow
- Remove attribute generation → tag-based detection
### 🎯 **Consistent Behavior**
- `<h1>Our <em>Services</em></h1>` always preserves formatting
- Style detection always runs
- No more edge cases between strategies
### ⚡ **Better Performance**
- No strategy detection overhead
- No conditional branching complexity
- Simpler initialization paths
### 🛠️ **Easier Maintenance**
- Single code path to test and debug
- Unified behavior aligns with CLASSES.md
- HTML-first philosophy consistently applied
## Current Working Files
### Fixed in This Session:
-**Style preview system** - Now uses CSS isolation for perfect previews
-**Simple demo cleanup** - Removed unsupported examples 6 & 8
-**Default demo preparation** - Stripped data attributes for clean enhancement
### Next Session Priorities:
1. **Remove content type routing** from StyleAwareEditor
2. **Implement element-based behavior detection**
3. **Create direct multi-property editors** for better UX
4. **Enhance container expansion logic** with smart stopping rules
## Status
**Phase 1, 2 & 3 COMPLETED** - Complete HTML-first architecture with container transformation!
### ✅ **Completed Across Multiple Sessions**:
#### **Phase 1 & 2: HTML-First Architecture**
- **Removed content type routing** from StyleAwareEditor - now uses unified HTML-first approach
- **Eliminated simple/textarea editor** that stripped HTML formatting
- **Implemented element-based behavior detection** using tag names (no more `data-content-type` attributes)
- **Created direct multi-property editors** for `<a>`, `<button>`, `<img>` elements
- **Removed `data-content-type` generation** from backend enhancer
- **Updated database schema** - completely removed type field from content and content_versions tables
- **Regenerated all sqlc code** with new schema
- **Simplified API layer** to be purely HTML-based
#### **Phase 3: Container Transformation**
- **Implemented backend container transformation** following CLASSES.md syntactic sugar specification
- **Added addClass/removeClass methods** to ContentEngine for proper class manipulation
- **Removed frontend container expansion logic** - frontend now only finds enhanced elements
- **Fixed StyleAwareEditor runtime error** (hasMultiPropertyElements method)
- **Verified container transformation** works correctly: `<section class="insertr">` → children get `.insertr`
### 🎯 **Results Achieved**:
- **Massive code reduction**: 3 content handlers → 1 unified system
- **Consistent behavior**: All content now uses HTML preservation with style detection
- **Element-based UX**: `<a>` tags get direct URL+text editor, `<p>` tags get rich text with formatting
- **Container transformation**: Syntactic sugar working per CLASSES.md specification
- **Simplified frontend**: No runtime container expansion - backend handles transformation
- **Zero breaking changes**: User-facing functionality maintained while simplifying backend
### 🚀 **System Now Works As**:
```javascript
// Single path for ALL .insertr elements
class StyleAwareEditor {
async initialize() {
// 1. Always extract HTML with preservation
this.originalContent = this.htmlEngine.extractForEditing(this.element);
// 2. Always detect styles from nested elements
this.detectedStyles = this.styleEngine.detectStyles(this.element);
// 3. Element-based UX routing
if (this.isMultiPropertyElement()) {
this.createDirectEditor(); // URL+text for links
} else {
this.createRichEditor(); // Rich text with styles
}
}
}
```
**Confidence Level**: High - All changes successfully implemented and tested. Server starts correctly, builds complete successfully.

View File

@@ -457,57 +457,7 @@ body:not(.insertr-edit-mode) .insertr-editing-hover::after {
transform: none;
}
/* Active state for default style buttons */
.insertr-style-btn.insertr-default-style.insertr-style-active {
background: var(--insertr-info);
border-color: var(--insertr-info);
color: white;
box-shadow: 0 2px 4px rgba(23, 162, 184, 0.3);
}
.insertr-style-btn.insertr-default-style.insertr-style-active .insertr-style-sample {
color: white;
}
/* Default formatting style buttons */
.insertr-style-btn.insertr-default-style {
border-color: var(--insertr-info);
background: rgba(23, 162, 184, 0.1);
position: relative;
}
.insertr-style-btn.insertr-default-style:hover {
border-color: var(--insertr-info);
background: rgba(23, 162, 184, 0.2);
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(23, 162, 184, 0.3);
}
.insertr-style-btn.insertr-default-style:active {
transform: translateY(0);
box-shadow: 0 1px 2px rgba(23, 162, 184, 0.2);
}
/* Default preview content styling */
.insertr-default-preview {
font-size: var(--insertr-font-size-sm);
font-weight: 500;
padding: var(--insertr-spacing-xs) var(--insertr-spacing-sm);
display: inline-block;
}
/* Small indicator for default styles */
.insertr-style-btn.insertr-default-style::after {
content: '';
position: absolute;
top: 2px;
right: 2px;
width: 6px;
height: 6px;
background: var(--insertr-info);
border-radius: 50%;
opacity: 0.7;
}
/* Editor components */
.insertr-simple-editor,

View File

@@ -457,57 +457,7 @@ body:not(.insertr-edit-mode) .insertr-editing-hover::after {
transform: none;
}
/* Active state for default style buttons */
.insertr-style-btn.insertr-default-style.insertr-style-active {
background: var(--insertr-info);
border-color: var(--insertr-info);
color: white;
box-shadow: 0 2px 4px rgba(23, 162, 184, 0.3);
}
.insertr-style-btn.insertr-default-style.insertr-style-active .insertr-style-sample {
color: white;
}
/* Default formatting style buttons */
.insertr-style-btn.insertr-default-style {
border-color: var(--insertr-info);
background: rgba(23, 162, 184, 0.1);
position: relative;
}
.insertr-style-btn.insertr-default-style:hover {
border-color: var(--insertr-info);
background: rgba(23, 162, 184, 0.2);
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(23, 162, 184, 0.3);
}
.insertr-style-btn.insertr-default-style:active {
transform: translateY(0);
box-shadow: 0 1px 2px rgba(23, 162, 184, 0.2);
}
/* Default preview content styling */
.insertr-default-preview {
font-size: var(--insertr-font-size-sm);
font-weight: 500;
padding: var(--insertr-spacing-xs) var(--insertr-spacing-sm);
display: inline-block;
}
/* Small indicator for default styles */
.insertr-style-btn.insertr-default-style::after {
content: '';
position: absolute;
top: 2px;
right: 2px;
width: 6px;
height: 6px;
background: var(--insertr-info);
border-radius: 50%;
opacity: 0.7;
}
/* Editor components */
.insertr-simple-editor,

View File

@@ -639,12 +639,12 @@ export class StyleAwareEditor {
applyStyleButtonStyling(button, styleSample, styleInfo) {
if (!styleInfo) return;
// Apply styling based on whether this is a detected style or default
// ALL buttons use the same unified three-layer architecture
button.classList.add('insertr-style-preview');
// Apply appropriate preview styling to the isolated sample
if (styleInfo.isDefault) {
// Default style - apply semantic styling
button.classList.add('insertr-default-style');
// Add semantic styling for default elements
// Default semantic formatting - apply styling to sample
if (styleInfo.tagName === 'strong') {
styleSample.style.fontWeight = 'bold';
} else if (styleInfo.tagName === 'em') {
@@ -657,10 +657,7 @@ export class StyleAwareEditor {
// Add helpful description to title
button.title = `${styleInfo.name}: ${styleInfo.description || 'Default formatting option'}`;
} else if (styleInfo.element && styleInfo.classes && styleInfo.classes.length > 0) {
// Detected style - apply original classes to style sample
button.classList.add('insertr-style-preview');
// Add the detected classes to the style sample (isolated preview)
// Detected style - apply original classes to style sample (isolated preview)
styleInfo.classes.forEach(className => {
styleSample.classList.add(className);
});
@@ -668,7 +665,6 @@ export class StyleAwareEditor {
button.title = `Apply ${styleInfo.classes.join(' ')} styling`;
} else {
// No meaningful styles detected - use fallback
button.classList.add('insertr-style-preview');
styleSample.classList.add('insertr-fallback-style');
}
}