Skip to content

alegauss/universal-editor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

universal-editor

Universal Editor - Modern TypeScript implementation with clean, modular, and maintainable code.

🎯 Overview

A modern TypeScript implementation of the Universal Editor that allows content authors to edit content directly in context. This version is written in TypeScript and generates a minified JavaScript bundle with all dependencies included.

✨ Features

  • TypeScript: Full TypeScript implementation with type safety
  • Multiple Editor Support: Works with both TinyMCE and ProseMirror
  • Cross-frame Communication: Uses Penpal for secure parent-child frame communication
  • Type-safe Validation: Utilizes Zod for runtime type checking
  • State Management: Built with Zustand for lightweight, reactive state
  • Event-driven Architecture: Comprehensive event system for content operations
  • Minified Build: Production-ready minified bundle with all dependencies included
  • Clean Code: Fully documented TypeScript source

📦 Installation

npm install

🔨 Building

Build the TypeScript source into a minified JavaScript bundle:

npm run build

This will:

  1. Compile TypeScript to JavaScript
  2. Bundle all dependencies
  3. Minify the output
  4. Generate source maps
  5. Output to dist/universal-editor.min.js (~224KB minified with all dependencies)

🔧 Dependencies

Runtime Dependencies

All public libraries are now properly managed via npm:

  • penpal (^6.2.2): Cross-frame communication
  • zod (^3.22.4): TypeScript-first schema validation
  • prosemirror-* : Rich text editor framework
  • zustand (^4.4.7): State management

Dev Dependencies

  • typescript (^5.3.3): TypeScript compiler
  • esbuild (^0.19.9): Fast JavaScript bundler and minifier
  • tsx (^4.7.0): TypeScript execution engine

🚀 Usage

For Production (Built Bundle)

Use the minified bundle that includes all dependencies:

<script src="dist/universal-editor.min.js"></script>

For Development (Local)

 <script type="module" src="src/universal-editor.ts"></script>
 <script type="module" src="src/editor/editor-bridge.ts"></script>

See src/pages/example.html for a complete working example.

🎮 Testing the Editor

Starting the Development Server

First, start the development server:

npm run dev

This will start a Vite server at http://localhost:3000.

Viewing Example Pages

You can view the example pages directly to see the content:

  • Example 1 (Universal Editor): http://localhost:3000/pages/example.html
  • Example 2 (Technology and AI): http://localhost:3000/pages/example2.html
  • Example 3 (Travel and Nature): http://localhost:3000/pages/example3.html

These pages show different content themes with various layouts and styles.

Editing Content

To edit the content, you need to use the editor host:

http://localhost:3000/pages/editor-host.html

The editor host provides:

  • 🎨 Toolbar with edit/preview mode buttons
  • 📝 Rich Text Editor modal for editing text content
  • 🖼️ Image Editor modal for changing images
  • 🔄 URL Switcher to load different pages (default: http://localhost:3000/pages/example.html)
  • 💾 Save Button to persist changes

How to use:

  1. Open editor-host.html in your browser
  2. Change the URL in the header if you want to edit a different page (example2.html, example3.html, etc.)
  3. Click "🔄 Load" to load the page
  4. Click "✏️ Edit" to enter edit mode
  5. Click on any highlighted element to edit it
  6. Make your changes in the modal editor
  7. Click "💾 Save" to save (when implemented)

Example URLs to try:

  • http://localhost:3000/pages/example.html - Original Universal Editor intro
  • http://localhost:3000/pages/example2.html - Technology and AI theme
  • http://localhost:3000/pages/example3.html - Travel and Nature theme
  • Or any other URL you want to make editable!

📝 Content Editing

The editor supports various content types:

  • ✏️ Text: Plain text content
  • 📄 Rich Text: HTML formatted content
  • 🖼️ Media: Images and other media
  • 🔗 References: Links to other content
  • 📦 Containers: Groups of components
  • 🧩 Components: Reusable content blocks

Marking Content as Editable

Use data attributes to define editable regions:

<!-- Text Content -->
<h1 
  data-aue-resource="urn:aem:/content/page/title" 
  data-aue-type="text"
  data-aue-prop="title">
  My Title
</h1>

<!-- Rich Text Content -->
<div 
  data-aue-resource="urn:aem:/content/page/body"
  data-aue-type="richtext"
  data-aue-prop="content">
  <p>Rich text content here...</p>
</div>

<!-- Image Content -->
<img 
  data-aue-resource="urn:aem:/content/page/hero"
  data-aue-type="media"
  data-aue-prop="image"
  src="/path/to/image.jpg" 
  alt="Hero" />

<!-- Container -->
<div 
  data-aue-resource="urn:aem:/content/page/container"
  data-aue-type="container">
  <!-- Components go here -->
</div>

🎪 Events

The editor dispatches various custom events you can listen to:

// Editor initialized and ready
document.addEventListener('aue:initialized', () => {
  console.log('Editor ready!');
});

// Entering/exiting edit mode
document.addEventListener('aue:ui-edit', () => {
  console.log('Edit mode activated');
});

document.addEventListener('aue:ui-preview', () => {
  console.log('Preview mode activated');
});

// Content operations
document.addEventListener('aue:content-update', (event) => {
  console.log('Content updated:', event.detail);
});

document.addEventListener('aue:content-add', (event) => {
  console.log('Content added:', event.detail);
});

document.addEventListener('aue:content-remove', (event) => {
  console.log('Content removed:', event.detail);
});

Available Events

Event Description
aue:initialized Editor is ready
aue:content-add Content was added
aue:content-remove Content was removed
aue:content-move Content was moved
aue:content-patch Content was patched
aue:content-update Content was updated
aue:content-copy Content was copied
aue:ui-edit Entered edit mode
aue:ui-preview Entered preview mode
aue:ui-select Element was selected

🛠️ Development

Testing

npm test

This validates the TypeScript source structure and verifies:

  • All required imports and functions are present
  • TypeScript types are properly defined
  • Built bundle exists and is correctly generated

Building

npm run build

Compiles TypeScript and bundles into a minified JavaScript file with all dependencies.

Cleaning

npm run clean

Removes the dist/ directory with all built files.

Validation

npm run validate

Runs both tests and build to ensure everything works correctly.

📁 Project Structure

universal-editor/
├── src/                          # TypeScript source files
│   ├── universal-editor.ts       # Main editor implementation
│   ├── build.ts                  # Build script
│   ├── test.ts                   # Test script
│   ├── editor/                   # Editor components
│   │   ├── editor-bridge.ts      # Bridge between iframe and host
│   │   └── prosemirror-toolbar.ts # ProseMirror toolbar implementation
│   └── pages/                    # Example HTML pages
│       ├── editor-host.html      # Editor host with toolbar (EDITING)
│       ├── example.html          # Example page 1 - Universal Editor intro
│       ├── example2.html         # Example page 2 - Technology and AI
│       └── example3.html         # Example page 3 - Travel and Nature
├── dist/                         # Built files (generated)
│   ├── universal-editor.min.js   # Minified bundle with all dependencies
│   ├── universal-editor.min.js.map # Source map
│   ├── universal-editor.js       # Compiled TypeScript (not minified)
│   ├── universal-editor.d.ts     # TypeScript declarations
│   └── ...                       # Other compiled files
├── tsconfig.json                 # TypeScript configuration
├── vite.config.ts                # Vite configuration
├── package.json                  # Project configuration
└── README.md                     # This file

Code Structure

The TypeScript code is organized as follows:

src/universal-editor.ts       # Main entry point
├── Types & Interfaces        # TypeScript type definitions
├── Constants                 # EditorMode, ContentType, Events, etc.
├── State Management          # Zustand store for editor state
├── ProseMirror Setup         # Rich text editor configuration
├── Event Handlers            # DOM event listeners and handlers
├── Parent Communication      # Penpal methods for cross-frame calls
└── Initialization            # App startup logic

Performance Metrics

File Size Comparison:

  • Original minified bundle: ~596 KB
  • TypeScript source: ~17 KB
  • New minified bundle (with all deps): ~224 KB (62% reduction)
  • With tree-shaking and gzip, production size is even smaller

📄 Files

TypeScript Source

  • src/universal-editor.ts - Main editor implementation (TypeScript)
  • src/build.ts - Build script (TypeScript)
  • src/test.ts - Test script (TypeScript)
  • tsconfig.json - TypeScript configuration

Built Output

  • dist/universal-editor.min.js - Minified bundle with all dependencies
  • dist/universal-editor.min.js.map - Source map
  • dist/universal-editor.js - Compiled JavaScript (not minified)
  • dist/universal-editor.d.ts - TypeScript declarations

🤝 Contributing

When contributing, please:

  1. Keep code clean and well-documented
  2. Use TypeScript for new code
  3. Follow existing code style
  4. Test your changes thoroughly
  5. Run npm run validate before submitting

🔗 Links

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors