or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

commands.mdconfiguration.mddata-management.mdeditor-lifecycle.mdindex.mdplugins.mduser-interface.md
tile.json

data-management.mddocs/

Data Management

Comprehensive data input/output operations for getting and setting editor content with support for various data formats and processing options.

Capabilities

Set Editor Data

Sets the editor's content data, replacing all existing content.

/**
 * Sets editor content data
 * @param data - HTML string or object with root names as keys and HTML as values
 */
setData(data: string | Record<string, string>): void;

Usage Examples:

// Set simple HTML content
editor.setData('<p>Hello <strong>world</strong>!</p>');

// Set complex content with multiple elements
editor.setData(`
  <h2>Welcome to CKEditor 5</h2>
  <p>This is a <em>rich text editor</em> with many features:</p>
  <ul>
    <li>Text formatting</li>
    <li>Lists and tables</li>
    <li>Images and media</li>
  </ul>
  <blockquote>
    <p>CKEditor 5 provides excellent writing experience.</p>
  </blockquote>
`);

// Set content with images
editor.setData(`
  <p>Check out this image:</p>
  <figure class="image">
    <img src="https://example.com/image.jpg" alt="Example image">
    <figcaption>This is an image caption</figcaption>
  </figure>
`);

// Set content with tables
editor.setData(`
  <figure class="table">
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Age</th>
          <th>City</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Alice</td>
          <td>25</td>
          <td>New York</td>
        </tr>
        <tr>
          <td>Bob</td>
          <td>30</td>
          <td>London</td>
        </tr>
      </tbody>
    </table>
  </figure>
`);

// Multi-root editor (if configured)
editor.setData({
  header: '<h1>Main Title</h1>',
  content: '<p>Main content goes here.</p>',
  footer: '<p>Footer content</p>'
});

Get Editor Data

Retrieves the current editor content as HTML string.

/**
 * Gets editor content as HTML string
 * @param options - Optional configuration for data retrieval
 * @returns HTML string representation of editor content
 */
getData(options?: DataGetOptions): string;

interface DataGetOptions {
  rootName?: string;
  trim?: 'empty' | 'none';
}

Usage Examples:

// Get all editor content
const content = editor.getData();
console.log(content); // '<p>Hello <strong>world</strong>!</p>'

// Get content with trimming options
const trimmedContent = editor.getData({ trim: 'empty' });

// Multi-root editor - get specific root
const headerContent = editor.getData({ rootName: 'header' });

// Process retrieved data
const data = editor.getData();
if (data.includes('<img')) {
  console.log('Content contains images');
}

// Save to server
const content = editor.getData();
fetch('/api/save-content', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ content })
});

Data Controller Access

Direct access to the data controller for advanced data operations.

/**
 * Data controller instance providing low-level data operations
 */
readonly data: DataController;

interface DataController {
  setData(data: string | Record<string, string>): void;
  getData(options?: DataGetOptions): string;
  
  /**
   * Converts model to view (for display)
   */
  stringify(modelElementOrFragment: any): string;
  
  /**
   * Converts view to model (for editing)
   */
  parse(data: string, context?: any): any;
  
  /**
   * Processes data through the conversion system
   */
  processor: DataProcessor;
}

Usage Examples:

// Access data controller directly
const dataController = editor.data;

// Use processor for custom conversions
const htmlProcessor = dataController.processor;

// Parse HTML to model
const modelFragment = dataController.parse('<p>Custom content</p>');

// Convert model to HTML
const htmlString = dataController.stringify(modelFragment);

Data Processing Events

Monitor data changes and processing events.

/**
 * Data-related events
 */
interface DataEvents {
  'set': (evt: EventInfo) => void;
  'get': (evt: EventInfo) => void;
  'ready': (evt: EventInfo) => void;
}

Usage Examples:

// Listen for data changes
editor.data.on('set', () => {
  console.log('Data was set');
});

// Listen for data retrieval
editor.data.on('get', () => {
  console.log('Data was retrieved');
});

// Track all editor changes
editor.model.document.on('change:data', () => {
  console.log('Editor content changed');
  const currentData = editor.getData();
  localStorage.setItem('editorContent', currentData);
});

Content Validation

Validate and sanitize content before setting or after getting.

/**
 * Model document for validation and change tracking
 */
readonly model: {
  document: ModelDocument;
  schema: Schema;
};

interface Schema {
  checkChild(contextElement: any, def: any): boolean;
  checkAttribute(contextElement: any, attributeName: string): boolean;
  isRegistered(item: string | any): boolean;
}

Usage Examples:

// Validate content structure
const schema = editor.model.schema;

// Check if element is allowed
const isValidHeading = schema.checkChild(
  editor.model.document.getRoot(),
  'heading1'
);

// Validate before setting data
function setValidatedData(htmlContent: string) {
  try {
    editor.setData(htmlContent);
  } catch (error) {
    console.error('Invalid content:', error);
    // Fallback to safe content
    editor.setData('<p>Default content</p>');
  }
}

// Content sanitization example
function sanitizeAndSetData(userContent: string) {
  // Remove script tags and other dangerous elements
  const sanitized = userContent
    .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
    .replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, '');
  
  editor.setData(sanitized);
}

Auto-save Implementation

Implement automatic content saving with data management.

Usage Example:

class AutoSave {
  constructor(editor, saveInterval = 30000) {
    this.editor = editor;
    this.saveInterval = saveInterval;
    this.lastSavedData = '';
    this.saveTimer = null;
    
    this.startAutoSave();
  }
  
  startAutoSave() {
    // Save on content changes
    this.editor.model.document.on('change:data', () => {
      this.scheduleeSave();
    });
    
    // Save before page unload
    window.addEventListener('beforeunload', () => {
      this.saveNow();
    });
  }
  
  scheduleSave() {
    clearTimeout(this.saveTimer);
    this.saveTimer = setTimeout(() => {
      this.saveNow();
    }, this.saveInterval);
  }
  
  async saveNow() {
    const currentData = this.editor.getData();
    
    if (currentData !== this.lastSavedData) {
      try {
        await this.saveToServer(currentData);
        this.lastSavedData = currentData;
        console.log('Content auto-saved');
      } catch (error) {
        console.error('Auto-save failed:', error);
      }
    }
  }
  
  async saveToServer(content) {
    const response = await fetch('/api/auto-save', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ content, timestamp: Date.now() })
    });
    
    if (!response.ok) {
      throw new Error('Save failed');
    }
  }
}

// Usage
const autoSave = new AutoSave(editor, 10000); // Save every 10 seconds