› Core

This is the core API for doing text area–based text selection manipulation.

Start

Create a text area element, then include text-editor.min.js next to it:

<!DOCTYPE html>
<html dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Test</title>
  </head>
  <body>
    <p><textarea></textarea></p>
    <script src="text-editor.min.js"></script>
    <script>
    var editor = new TE(document.querySelector('textarea'));
    </script>
    <p>
      <button onclick="return editor.wrap('<b>', '</b>'), false;">Bold</button>
      <button onclick="return editor.wrap('<i>', '</i>'), false;">Italic</button>
      <button onclick="return editor.wrap('<u>', '</u>'), false;">Underline</button>
    </p>
  </body>
</html>

Configure

Instance

new TE(node);
var editor = new TE(document.querySelector('textarea'));

Configuration

Configuration is not available.

Extend

All text editor instances are stored in TE.__instance__ as a collection with keys generated by the text area ID, text area name or text area sequence:

console.log(TE.__instance__);

The TE.each() method allows you to loop through the captured instances easily:

TE.each(function($, key, any) {
    // `$` refers to the text editor instance
    // `key` refers to the instance key in `TE.__instance__`
    // `any` refers to `TE.__instance__`
});

Methods

Get the Editor Area

Getting the editor area DOM:

var target = editor.target;

Set Value

Set value to the editor area:

editor.set('foo bar baz');

Get Value

Get value from the editor area:

console.log(editor.get());
console.log(editor.get('default value if empty'));

Save State

Save state to the editor storage:

editor.save('my_state_id', 1);

Restore State

Restore the saved state from the editor storage:

alert(editor.restore('my_state_id', '#')); // should return `1` or `#` if not available

Focus the Editor Area

Just focus to the editor area:

editor.focus();

Focus to the start of the editor area:

editor.focus(0);

Focus to the end of the editor area:

editor.focus(1);

Blur the Editor Area

editor.blur();

Get Selection

A method to capture the current text selection. Set the first parameter to true to capture the caret offset from text area in pixels:

console.log(editor.$(true));
// for “test before i am selected test after”
// with “i am selected” as the selected value
{
  start: 12, // selection start
  end: 25, // selection end
  value: 'i am selected', // selected text
  before: 'test before ', // text before selection
  after: ' test after', // text after selection
  caret: [ // caret offset from text area in pixel(s)
    { // selection start
      x: 99,
      y: 3
    },
    { // selection end
      x: 203,
      y: 3
    }
  ],
  length: 13 // length of selected text
}

Set Selection

Set selection range without select event:

editor.select(7, 10);

Move caret position:

editor.select(7);

Restore selection after editor’s blur event:

editor.select();

Select all:

editor.select(true);

Replace At Selection

Replace selected text with something:

editor.replace(/foo/g, 'bar');

Replace Before Caret/Selection

Replace something before caret/selection with something:

editor.replaceBefore(/foo/g, 'bar');

Replace After Caret/Selection

Replace something after caret/selection with something:

editor.replaceAfter(/foo/g, 'bar');

Match Selection

Return true if selection matched with pattern:

if (editor.match(/foo/)) { … }

Custom return value:

var match = editor.match(/^\d+$/, function(m) {
    return +(m[0] || 0);
});

if (match === 1) { … }

Insert At Caret/Selection

Insert something at caret/selection. The current selection will be replaced by the inserted text:

editor.insert(':)');

Insert Before Caret/Selection

Insert something before caret/selection. Set the second parameter to true to delete current selection before the text being inserted:

editor.insertBefore(':)', true);

Insert After Caret/Selection

Insert something after caret/selection. Set the second parameter to true to delete current selection before the text being inserted:

editor.insertAfter(':)', true);

Wrap Selection

Wrap selection with <b> and </b>:

editor.wrap('<b>', '</b>');

Include <b> and </b> to selection:

editor.wrap('<b>', '</b>', true);

Unwrap Selection

Unwrap selection from <b> and </b>:

editor.unwrap('<b>', '</b>');

Trim <b> and </b> in selection:

editor.unwrap('<b>', '</b>', true);

Unwrap selection from any HTML tags:

editor.unwrap(/<[^\/<>]+?>/, /<\/[^<>]+?>/)

Trim <*> and </*> in selection:

editor.unwrap(/<[^\/<>]+?>/, /<\/[^<>]+?>/, true)

Indent At Caret/Selection

Indent selected text with a tab:

editor.indent();

Indent selected text with a :::

editor.indent('::');

Outdent At Caret/Selection

Outdent selected text from a tab:

editor.outdent();

Outdent selected text from a :::

editor.outdent('::');

Outdent selected text from any white–spaces:

editor.outdent(/[\t ]*/);

Trim White–Spaces

Trim white–spaces before and after selection range, and at the beginning and end of selection range:

editor.trim();

Replace the trimmed white–spaces before and after selection range with *:

editor.trim('*', '*');

Replace the trimmed white–spaces at the beginning and end of selection range with *:

editor.trim("", "", '*', '*');

Left trim only:

editor.trim("", false, "", false);

Right trim only:

editor.trim(false, "", false, "");

Toggle States

The first parameter should return an array index to access a function in the second parameter by its array index:

document.querySelector('button').addEventListener("click", function() {
    var state = (editor.$().value.match(/^do state (\d+)$/) || [0]); // default is `0`
    editor.toggle(state[0], [
        function($) {
            alert('did state 0');
        },
        function($) {
            alert('did state 1');
        },
        function($) {
            alert('did state 2');
        },
        …
    ]);
}, false);

Update History

Update history data:

editor.record();

Replace the second history data with custom value:

// 0: content
// 1: selection start
// 2: selection end
// 3: scroll / text height
editor.record(['foo bar baz', 2, 4, 1], 1); // 0–based index

Remove History

Remove the last history data:

editor.loss();

Remove the second history data:

editor.loss(1); // 0–based index

Reset the history data:

editor.loss(true);

Read History

Read all history data:

console.log(editor.records());

Read the second history data:

console.log(editor.records(1)); // 0–based index

Read the second history data if any, otherwise, return #:

console.log(editor.records(1, '#'));

Disable History Feature

Temporarily disable the history feature:

editor[0](); // disable

editor.foo().bar().baz();

editor[1](); // re–enable

Inline mode:

editor[0]().foo().bar().baz()[1]();

Undo

Undo from the previous state:

editor.undo();

Redo

Redo from the previous undo:

editor.redo();

Scroll

Get the current scroll step (text area scroll height divided by text height) and text height:

console.log(editor.scroll()); // `[4, 16]`

Scroll one step down from the current scroll step:

editor.scroll(1);

Scroll one step up from the current scroll step:

editor.scroll(-1);

Scroll 3 rows from top:

editor.scroll(0, 3);

Scroll to the end of the text area:

editor.scroll(true);

Keyboard Key Events

Normalized KeyboardEvent.key value in their lower–cased mode. It does support key aliases and regular expression matching too:

editor.target.addEventListener("keydown", function(e) {

    console.log(e.key); // [^1]

    console.log(e.TE.key()); // [^2]
    console.log(e.TE.control()); // [^3]
    console.log(e.TE.shift()); // [^4]
    console.log(e.TE.option()); // [^5]
    console.log(e.TE.meta()); // [^6]

    console.log(e.TE.control('b')); // [^7]

    // check for current key character (try pressing the “control” key)
    if (e.TE.key('ctrl')) { … } // [^8]
    if (e.TE.key() === 'ctrl') { … } // [^9]
    if (e.TE.key() === 'control') { … } // [^10]
    if (e.TE.key(/^[abc]$/)) { … } // [^11]
    if (e.TE.key(['ctrl', 'alt', 'shift'])) { … } // [^12]

}, false);

// [^1]: return the native `KeyboardEvent.key` value if supported
// [^2]: return the current key character (lower–cased)
// [^3]: return `true` if “control” key is pressed
// [^4]: return `true` if “shift” key is pressed
// [^5]: return `true` if “option” key is pressed
// [^6]: return `true` if “meta” key is pressed
// [^7]: return `true` if “control” and `b` keys are pressed
// [^8]: `ctrl` is an alias for `control`, this will return `true`
// [^9]: comparing `ctrl` outside the function, this will return `false`
// [^10]: is equal to the original key value, this will return `true`
// [^11]: return `true` if key character is either `a`, `b` or `c`
// [^12]: return `true` if key character is either `control`, `alt` or `shift`

Utilities

Helper functions. Most of them can be accessed staticly:

Escape

Escape regular expression characters:

var escaped = TE._.x('foo/bar % **baz**'); // return `foo\/bar % \*\*baz\*\*`

Extend

Extend two objects:

var o = {
    foo: 0,
    bar: 1,
    baz: {
        qux: 2
    }
};

o = TE._.extend(o, {
    bar: '#',
    baz: {
        qux: '#'
        wow: '#'
    }
}); // return `{foo:0,bar:'#',baz:{qux:'#',wow:'#'}}`

Iterator

Iterate over array or object:

TE._.each([0, 1, 2, 3, 4], function(value, key, source) {
    console.log(arguments);
});
TE._.each({"foo":0,"bar":1,"baz":2}, function(value, key, source) {
    console.log(arguments);
});

Trim White–Spaces

Remove white–spaces at the beginning and end of a string:

TE._.trim('  foo bar baz\r\n');

Remove white–spaces at the beginning of a string:

TE._.trim('  foo bar baz\r\n', 0);

Remove white–spaces at the end of a string:

TE._.trim('  foo bar baz\r\n', 1);

Get/Set CSS Value

Get all CSS properties from #foo:

var css = TE._.css(document.querySelector('#foo'));

Get color value from #foo:

var css = TE._.css(document.querySelector('#foo'), 'color'); // return `rgb(0, 0, 0)`

Get background-color, color and border-top-width value from #foo:

var css = TE._.css(document.querySelector('#foo'), [
    'background-color',
    'color',
    'border-top-width'
]); // return `['rgb(255, 255, 255)', 'rgb(0, 0, 0)', 1]`

Set background-color, color and border style to #foo:

TE._.css(document.querySelector('#foo'), {
    'background-color': '#fff',
    'color': '#000',
    'border': '1px solid #000'
}); // return `document.querySelector('#foo')`

All CSS value that can be parsed by JavaScript parseFloat will be returned as number:

TE._.css(document.querySelector('#foo'), 'border-top-width'); // return `1`

To disable that behaviour, prepend a \0 to the CSS property:

TE._.css(document.querySelector('#foo'), '\0border-top-width'); // return `1px`

Edge

Prevent input exceeds the min and max value:

TE._.edge(input, min, max);

Pattern

Currently, this is just an alias for new RegExp():

TE._.pattern('<\\/?[^<>\\s]+.*?>', 'g'); // match HTML tags

Parse Integer

Get integer/float number from a string input. Currently, this is just an alias for parseFloat(input):

TE._.i('1px'); // is equal to `parseFloat('1px')`

Timer

Set

Currently, this is just an alias for setTimeout():

var foo = function() { … };
TE._.timer.set(foo); // is equal to `setTimeout(foo, 0)`
TE._.timer.set(foo, 1000); // is equal to `setTimeout(foo, 1000)`

Reset

Currently, this is just an alias for clearTimeout():

TE._.timer.reset(foo); // is equal to `clearTimeout(foo)`

Logic

Data type checks.

Array

Check if input is array:

TE.is.a(input);

Boolean

Check if input is true or false:

TE.is.b(input);

Element

Check if input is a HTML element:

TE.is.e(input);

Function

Check if input is function:

TE.is.f(input);

Number

Check if input is number:

TE.is.i(input);

Null

Check if input is null:

TE.is.n(input);

Object

Check if input is array or object:

TE.is.o(input);

Regular Expression

Check if input is a regular expression pattern:

TE.is.r(input); // return `input.source` or `false`

String

Check if input is a string:

TE.is.s(input);

Undefined

Check if input is undefined:

TE.is.x(input);

Editor Type

Check for user defined editor type that is stored in editor.type. Default is "":

console.log(editor.is('Markdown'));
console.log(editor.is(/^(?:HTML|Markdown)$/));

Tests