SquibView Events Reference

Complete reference for all events emitted by SquibView and how to handle them.

Event System Overview

SquibView uses an event-driven architecture for communication between components and plugins. Events are accessed through the editor.events object.

// Subscribe to an event
editor.events.on('content:change', (content, contentType) => {
  console.log('Content changed:', content);
});

// Unsubscribe from an event
editor.events.off('content:change', handler);

// Note: Event names use colons (:) not hyphens (-)

Core Events

content:change

Fired when the editor content changes.

Event Parameters:

Example:

editor.events.on('content:change', (content, contentType) => {
  console.log('New content:', content);
  console.log('Type:', contentType);
  saveToServer(content);
});

view:change

Fired when the view mode changes.

Event Parameters:

Example:

editor.events.on('view:change', (view) => {
  console.log(`View changed to ${view}`);
  updateUIButtons(view);
});

text:selected

Fired when text is selected in either the source or rendered view.

Event Data:

{
  text: string,     // Selected textsource: string,   // Selection source ('input' or 'output')range: {          // Selection range (for input only)start: number,
    end: number
  }
}

Example:

editor.events.on('text:selected', (data) => {
  console.log('Selected text:', data.text);
  console.log('From:', data.source);

  // Enable formatting buttonsif (data.text) {
    enableFormatButtons();
  }
});

render

Fired after content is rendered.

Event Data:

{
  content: string,      // Source contentrendered: string,     // Rendered HTMLcontentType: string,  // Content typeduration: number      // Render time in milliseconds
}

Example:

editor.on('render', (data) => {
  console.log(`Rendered in ${data.duration}ms`);
  processRenderedContent(data.rendered);
});

Selection Events

selection-change

Fired when text selection changes.

Event Data:

{
  text: string,         // Selected texthtml: string,         // Selected HTML (if from output)markdown: string,     // Converted markdownstart: number,        // Start positionend: number,          // End positionsource: string,       // 'input' or 'output'hasSelection: boolean // Whether text is selected
}

Example:

editor.on('selection-change', (data) => {
  if (data.hasSelection) {
    console.log('Selected:', data.text);
    showContextMenu(data);
  } else {
    hideContextMenu();
  }
});

copy

Fired when content is copied to clipboard.

Event Data:

{
  content: string,     // Copied contentformat: string,      // Format ('plain', 'html', 'markdown', 'formatted')source: string,      // Source of copy ('input' or 'output')success: boolean     // Whether copy succeeded
}

Example:

editor.on('copy', (data) => {
  if (data.success) {
    showNotification(`Copied as ${data.format}`);
  }
});

Revision Events

revision-added

Fired when a new revision is saved.

Event Data:

{
  revision: number,    // Revision numbercontent: string,     // Content snapshotcontentType: string, // Content typetimestamp: number    // Unix timestamp
}

Example:

editor.on('revision-added', (data) => {
  console.log(`Revision ${data.revision} saved`);
  updateRevisionIndicator(data.revision);
});

undo

Fired when undo is performed.

Event Data:

{
  revision: number,    // Current revision after undocontent: string,     // Restored contentcontentType: string  // Restored content type
}

Example:

editor.on('undo', (data) => {
  console.log('Undone to revision:', data.revision);
  updateUndoRedoButtons();
});

redo

Fired when redo is performed.

Event Data:

{
  revision: number,    // Current revision after redocontent: string,     // Restored contentcontentType: string  // Restored content type
}

Example:

editor.on('redo', (data) => {
  console.log('Redone to revision:', data.revision);
  updateUndoRedoButtons();
});

Lifecycle Events

ready

Fired when the editor is fully initialized and ready.

Event Data:

{
  version: string,     // SquibView versioncontentType: string, // Initial content typeview: string        // Initial view mode
}

Example:

editor.on('ready', (data) => {
  console.log('Editor ready:', data);
  loadInitialContent();
});

destroy

Fired when the editor is being destroyed.

Event Data: None

Example:

editor.events.on('destroy', () => {
  console.log('Editor destroyed');
  cleanupResources();
});

Plugin Events

plugin-register

Fired when a plugin (renderer) is registered.

Event Data:

{
  type: string,       // Content typename: string,       // Plugin namehasButtons: boolean // Whether plugin adds buttons
}

Example:

editor.on('plugin-register', (data) => {
  console.log(`Plugin registered: ${data.name} for ${data.type}`);
});

plugin-render

Fired when a plugin renders content.

Event Data:

{
  type: string,        // Content typeinput: string,       // Source contentoutput: string,      // Rendered outputpluginName: string   // Plugin that rendered
}

Example:

editor.on('plugin-render', (data) => {
  console.log(`${data.pluginName} rendered ${data.type} content`);
});

Custom Events

You can emit and listen to custom events for plugin communication:

// Emit a custom event
editor.emit('my-plugin:action', {
  action: 'process',
  data: { /* ... */ }
});

// Listen to custom events
editor.on('my-plugin:action', (data) => {
  if (data.action === 'process') {
    processPluginData(data.data);
  }
});

Event Patterns

Global Event Handlers

// Log all eventsconst events = [
  'content-change', 'view-change', 'type-change',
  'render', 'selection-change', 'copy',
  'revision-added', 'undo', 'redo'
];

events.forEach(event => {
  editor.on(event, (data) => {
    console.log(`Event: ${event}`, data);
  });
});

Debounced Event Handling

let saveTimer;

editor.on('content-change', (data) => {
  clearTimeout(saveTimer);
  saveTimer = setTimeout(() => {
    saveContent(data.content);
  }, 1000); // Save after 1 second of inactivity
});

Event Chaining

editor.on('content-change', (data) => {
  // Trigger custom analysis
  editor.emit('analyze:content', {
    content: data.content,
    type: data.contentType
  });
});

editor.on('analyze:content', (data) => {
  // Perform analysisconst stats = analyzeContent(data);
  editor.emit('analyze:complete', stats);
});

Removing Event Listeners

// Named function handlerconsthandler = (data) => {
  console.log(data);
};

// Add listener
editor.on('content-change', handler);

// Remove specific listener
editor.off('content-change', handler);

// Remove all listeners for an event
editor.off('content-change');

Best Practices

  1. Always remove listeners when components are destroyed
  2. Debounce frequent events like content-change for performance
  3. Use namespaced custom events to avoid conflicts (e.g., ‘myplugin:action’)
  4. Check event data before using it in handlers
  5. Handle errors in event handlers to prevent breaking the editor

See Also