# Plugin for highlighting sections of text

Designed to highlight a part of the text with a certain template.
The plugin settings are very simple, you define a regular expression, finding which, the plugin will replace it with the function result.

## Options

### schema

- Type: `IDictionary<(jodit: IJodit, matches: RegExpMatchArray) => HTMLElement>`
- Default: `{}`

A dictionary where keys are regular expressions and values are functions that return HTML elements to wrap matched text.

```js
const editor = Jodit.make('#editor', {
    highlightSignature: {
        schema: {
            '[^\\s]+@[a-z.-]+': (jodit) => jodit.createInside.element('strong')
        }
    }
});
```

### processDelay

- Type: `number`
- Default: `0`

The delay in milliseconds between processing chunks of text. This can be useful to prevent UI freezing when processing large documents.

```js
const editor = Jodit.make('#editor', {
    highlightSignature: {
        processDelay: 10, // 10ms delay between processing chunks
        schema: {
            // your schema here
        }
    }
});
```

### processInChunkCount

- Type: `number`
- Default: `300`

The number of text nodes to process in a single chunk. This helps to optimize performance by breaking the processing into smaller chunks.

```js
const editor = Jodit.make('#editor', {
    highlightSignature: {
        processInChunkCount: 500, // Process 500 nodes at once
        schema: {
            // your schema here
        }
    }
});
```

### excludeTags

- Type: `HTMLTagNames[]`
- Default: `['pre']`

An array of HTML tag names that should be excluded from processing. By default, the plugin doesn't process text inside `<pre>` tags.

```js
const editor = Jodit.make('#editor', {
    highlightSignature: {
        excludeTags: ['pre', 'code', 'script'], // Don't process text in these tags
        schema: {
            // your schema here
        }
    }
});
```

But this temporary element will not get into the final HTML.

## Example 1

For example, we need to highlight email addresses everywhere:

```js
const editor = Jodit.make('#editor', {
    highlightSignature: {
        schema: {
            '[^\\s]+@[a-z.-]+': (jodit) => jodit.createInside.element('strong')
        }
    }
});

editor.value = '<p>Hi Valery chupurnov@gmail.om</p>';
console.log(editor.value); // '<p>Hi Valery chupurnov@gmail.om</p>'
console.log(editor.getNativeEditorValue()); // '<p>Hi Valery <strong data-jodit="temp">chupurnov@gmail.om</strong></p>'
```

The final value does not change. And in the original `textarea` the value not wrapped in the `strong` tag will be saved.

## Example 2

Now let's highlight something else. Let us have macros `${formSubmittedDate}`, `${formSessionURL}` which
need to be highlighted with different background color.

```js
const editor = Jodit.make('#editor', {
    highlightSignature: {
        schema: {
            '\\$\\{([^}]+)\\}': (jodit, matched) => {
                let color = 'yellow'; // all another macros will be `yellow`

                switch (matched[1]) {
                    case 'formSubmittedDate':
                        color = 'red';
                        break;

                    case 'formSessionURL':
                        color = '#0f0';
                        break;
                }

                const span = jodit.createInside.element('span', {
                    style: {
                        backgroundColor: color
                    }
                });

                return span;
            }
        }
    }
});

editor.value =
    '<p>The text ${formSubmittedDate} and ${formSessionURL} has some styling/decoration around it.</p>';
console.log(editor.value); // '<p>The text ${formSubmittedDate} and ${formSessionURL} has some styling/decoration around it.</p>'
console.log(editor.element.value); // '<p>The text ${formSubmittedDate} and ${formSessionURL} has some styling/decoration around it.</p>'
console.log(editor.getNativeEditorValue()); // '<p>The text <span data-jodit="temp" style="background-color:red">${formSubmittedDate}</span> and <span data-jodit="temp" style="background-color:#0f0">${formSessionURL}</span> has some styling/decoration around it.</p>'
console.log(editor.editor.innerHTML === editor.getNativeEditorValue()); // true
```

## Example 3: Performance Optimization

For large documents with many text nodes, you can optimize performance by adjusting the processing delay and chunk size:

```js
const editor = Jodit.make('#editor', {
    highlightSignature: {
        processDelay: 5, // 5ms delay between chunks
        processInChunkCount: 200, // Process 200 nodes at a time
        schema: {
            '\\b\\d{3}-\\d{3}-\\d{4}\\b': (jodit) => {
                // Highlight phone numbers
                const span = jodit.createInside.element('span', {
                    style: {
                        backgroundColor: '#e6f7ff',
                        borderBottom: '1px dashed #1890ff'
                    }
                });
                return span;
            }
        }
    }
});
```

## Example 4: Excluding Specific Tags

You can exclude specific tags from processing:

```js
const editor = Jodit.make('#editor', {
    highlightSignature: {
        excludeTags: ['pre', 'code', 'script', 'style'],
        schema: {
            '\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\b': (jodit) => {
                // Highlight email addresses
                const span = jodit.createInside.element('span', {
                    style: {
                        color: 'blue',
                        textDecoration: 'underline'
                    }
                });
                return span;
            }
        }
    }
});
```

## How It Works

1. The plugin scans the editor's content for text nodes
2. For each text node, it checks if the content matches any of the regular expressions defined in the schema
3. If a match is found, the plugin wraps the matched text with a temporary HTML element created by the corresponding function
4. These temporary elements are only visible in the editor and are removed when getting the final HTML value
5. The plugin also handles cursor position preservation when replacing text with highlighted elements

This approach allows you to visually highlight specific patterns in the editor without affecting the final HTML output.

## API Reference

### Configuration Interface

The highlight-signature plugin extends the Jodit configuration with the following interface:

```typescript
interface Config {
    highlightSignature: {
        processDelay: number;
        processInChunkCount: number;
        excludeTags: HTMLTagNames[];
        schema: IDictionary<
            (jodit: IJodit, matches: RegExpMatchArray) => HTMLElement
        >;
    };
}
```

### Schema Function Signature

The schema functions have the following signature:

```typescript
type SchemaFunction = (jodit: IJodit, matches: RegExpMatchArray) => HTMLElement;
```

**Parameters:**
- `jodit: IJodit` - The Jodit editor instance
- `matches: RegExpMatchArray` - The regular expression match results

**Returns:**
- `HTMLElement` - The HTML element that will wrap the matched text

### Default Configuration

```typescript
const defaultConfig = {
    processDelay: 0,
    processInChunkCount: 300,
    schema: {},
    excludeTags: ['pre']
};
```

### Type Definitions

#### IDictionary

```typescript
interface IDictionary<T> {
    [key: string]: T;
}
```

#### HTMLTagNames

```typescript
type HTMLTagNames = keyof HTMLElementTagNameMap;
```

### Methods

The plugin works automatically based on configuration, but it processes text using the following logic:

1. **Text Processing**: Scans text nodes in chunks defined by `processInChunkCount`
2. **Pattern Matching**: Applies regular expressions from the `schema` object keys
3. **Element Creation**: Calls the corresponding schema function to create wrapper elements
4. **Performance Optimization**: Uses `processDelay` to prevent UI blocking during large document processing

### Schema Pattern Examples

#### Email Highlighting

```typescript
schema: {
    '[^\\s]+@[a-z.-]+': (jodit: IJodit, matches: RegExpMatchArray) => {
        const strong = jodit.createInside.element('strong');
        strong.style.color = 'blue';
        return strong;
    }
}
```

#### Macro Highlighting with Conditional Styling

```typescript
schema: {
    '\\$\\{([^}]+)\\}': (jodit: IJodit, matches: RegExpMatchArray) => {
        const span = jodit.createInside.element('span');

        switch (matches[1]) {
            case 'formSubmittedDate':
                span.style.backgroundColor = 'red';
                break;
            case 'formSessionURL':
                span.style.backgroundColor = '#0f0';
                break;
            default:
                span.style.backgroundColor = 'yellow';
        }

        return span;
    }
}
```
