Previous tabbable element.
Features
- Press ⎈b.
- Press ⎈e.
- Press ⎈h.
- Press ⎈i.
- Press ⎈k.
- Press ⎈o.
- Press ⎈q.
Usage
Browser
<script src="./key/index.min.js"></script>
<script src="./text-editor/index.min.js"></script>
<script src="./text-editor.history/index.min.js"></script>
<script src="./text-editor.source/index.min.js"></script>
<script src="./text-editor.source-x-m-l/index.min.js"></script>
<script src="./text-editor.source-h-t-m-l/index.min.js"></script>
<script src="./text-editor.source-markdown/index.min.js"></script>
<script>
Object.assign(TE.prototype, TE.History.that, TE.Source.that);
const editor = new TE(document.querySelector('textarea'));
const map = new K(editor);
Object.assign(map.commands, TE.SourceHTML.commands, TE.SourceMarkdown.commands);
map.keys['Control-b'] = 'bold';
map.keys['Control-e'] = 'code';
map.keys['Control-h'] = 'blocks';
map.keys['Control-i'] = 'italic';
map.keys['Control-l'] = 'link';
map.keys['Control-o'] = 'image';
map.keys['Control-q'] = 'quote';
map.keys['Control-Shift-Q'] = 'quote'; // Use `Control-Shift-Q` if `Control-q` closes the window
const {
canKeyDown: canKeyDownSource,
canKeyDownEnter: canKeyDownEnterSource,
canKeyDownHistory: canKeyDownHistorySource,
canKeyDownMove: canKeyDownMoveSource,
canKeyDownTab: canKeyDownTabSource,
canKeyUp: canKeyUpSource
} = TE.Source;
const {
canKeyDown: canKeyDownSourceXML
} = TE.SourceXML;
const {
canKeyDown: canKeyDownSourceHTML
} = TE.SourceHTML;
const {
canKeyDown: canKeyDownSourceMarkdown
} = TE.SourceMarkdown;
function fromStates(...lot) { … }
editor.state = fromStates({}, editor.state, TE.Source.state, TE.SourceXML.state, TE.SourceHTML.state, TE.SourceMarkdown.state, {
commands: map.commands,
keys: map.keys
});
editor.self.addEventListener('blur', () => map.pull());
editor.self.addEventListener('input', () => map.pull());
let debounce;
editor.self.addEventListener('keydown', e => {
map.push(e.key);
let command = map.command();
// Check for custom command…
if (command) {
let value = map.fire(command);
if (false === value) {
e.preventDefault();
} else if (null === value) {
console.error('Unknown command:', command);
}
// Else, run the defaults!
} else {
if (
canKeyDownSourceMarkdown(map, editor) &&
canKeyDownSourceHTML(map, editor) &&
canKeyDownSourceXML(map, editor) &&
canKeyDownSource(map, editor) &&
canKeyDownEnterSource(map, editor) &&
canKeyDownHistorySource(map, editor) &&
canKeyDownMoveSource(map, editor) &&
canKeyDownTabSource(map, editor)
) {
// Normal key strokes. Add more key strokes extension here!
} else {
e.preventDefault();
}
}
debounce && clearTimeout(debounce);
debounce = setTimeout(() => map.pull(), 1000);
});
editor.self.addEventListener('keyup', e => {
canKeyUpSource(map, editor) || e.preventDefault();
map.pull(e.key);
});
editor.self.addEventListener('mousedown', e => {
canMouseDownSourceXML(map, editor) || e.preventDefault();
});
editor.record(); // Record the first history data!
</script>
CommonJS
const {fromStates} = require('@taufik-nurrohman/from');
const {debounce} = require('@taufik-nurrohman/tick');
const K = require('@taufik-nurrohman/key').default;
const TE = require('@taufik-nurrohman/text-editor').default;
const {that: thatHistory} = require('@taufik-nurrohman/text-editor.history');
const {
canKeyDown: canKeyDownSource,
canKeyDownEnter: canKeyDownEnterSource,
canKeyDownHistory: canKeyDownHistorySource,
canKeyDownMove: canKeyDownMoveSource,
canKeyDownTab: canKeyDownTabSource,
canKeyUp: canKeyUpSource,
state: stateSource,
that: thatSource
} = require('@taufik-nurrohman/text-editor.source');
const {
canKeyDown: canKeyDownSourceXML,
canMouseDown: canMouseDownSourceXML,
state: stateSourceXML,
that: thatSourceXML
} = require('@taufik-nurrohman/text-editor.source-x-m-l');
const {
canKeyDown: canKeyDownSourceHTML,
commands: commandsSourceHTML,
state: stateSourceHTML
} = require('@taufik-nurrohman/text-editor.source-h-t-m-l');
const {
canKeyDown: canKeyDownSourceMarkdown,
commands: commandsSourceMarkdown,
state: stateSourceMarkdown
} = require('@taufik-nurrohman/text-editor.source-markdown');
Object.assign(TE.prototype, thatHistory, thatSource);
const editor = new TE(document.querySelector('textarea'));
const map = new K(editor);
const bounce = debounce(() => map.pull(), 1000);
Object.assign(map.commands, commandsSourceHTML);
map.keys['Control-b'] = 'bold';
map.keys['Control-e'] = 'code';
map.keys['Control-h'] = 'blocks';
map.keys['Control-i'] = 'italic';
map.keys['Control-l'] = 'link';
map.keys['Control-o'] = 'image';
map.keys['Control-q'] = 'quote';
map.keys['Control-Shift-Q'] = 'quote'; // Use `Control-Shift-Q` if `Control-q` closes the window
editor.state = fromStates({}, editor.state, stateSource, stateSourceXML, stateSourceHTML, stateSourceMarkdown, {
commands: map.commands,
keys: map.keys
});
editor.self.addEventListener('blur', () => map.pull());
editor.self.addEventListener('input', () => map.pull());
editor.self.addEventListener('keydown', e => {
map.push(e.key);
let command = map.command();
// Check for custom command…
if (command) {
let value = map.fire(command);
if (false === value) {
e.preventDefault();
} else if (null === value) {
console.error('Unknown command:', command);
}
// Else, run the defaults!
} else {
if (
canKeyDownSourceMarkdown(map, editor) &&
canKeyDownSourceHTML(map, editor) &&
canKeyDownSourceXML(map, editor) &&
canKeyDownSource(map, editor) &&
canKeyDownEnterSource(map, editor) &&
canKeyDownHistorySource(map, editor) &&
canKeyDownMoveSource(map, editor) &&
canKeyDownTabSource(map, editor)
) {
// Normal key strokes. Add more key strokes extension here!
} else {
e.preventDefault();
}
}
bounce();
});
editor.self.addEventListener('keyup', e => {
canKeyUpSource(map, editor) || e.preventDefault();
map.pull(e.key);
});
editor.self.addEventListener('mousedown', e => {
canMouseDownSourceXML(map, editor) || e.preventDefault();
});
editor.record(); // Record the first history data!
ECMAScript
import {fromStates} from '@taufik-nurrohman/from';
import {debounce} from '@taufik-nurrohman/tick';
import K from '@taufik-nurrohman/key';
import TE from '@taufik-nurrohman/text-editor';
import {that as thatHistory} from '@taufik-nurrohman/text-editor.history';
import {
canKeyDown as canKeyDownSource,
canKeyDownEnter as canKeyDownEnterSource,
canKeyDownHistory as canKeyDownHistorySource,
canKeyDownMove as canKeyDownMoveSource,
canKeyDownTab as canKeyDownTabSource,
canKeyUp as canKeyUpSource,
state as stateSource,
that as thatSource
} from '@taufik-nurrohman/text-editor.source';
import {
canKeyDown as canKeyDownSourceXML,
canMouseDown as canMouseDownSourceXML,
state as stateSourceXML,
that as thatSourceXML
} from '@taufik-nurrohman/text-editor.source-x-m-l';
import {
canKeyDown as canKeyDownSourceHTML,
commands as commandsSourceHTML,
state as stateSourceHTML
} from '@taufik-nurrohman/text-editor.source-h-t-m-l';
import {
canKeyDown as canKeyDownSourceMarkdown,
commands as commandsSourceMarkdown,
state as stateSourceMarkdown
} from '@taufik-nurrohman/text-editor.source-markdown';
Object.assign(TE.prototype, thatHistory, thatSource);
const editor = new TE(document.querySelector('textarea'));
const map = new K(editor);
const bounce = debounce(() => map.pull(), 1000);
Object.assign(map.commands, commandsSourceHTML, commandsSourceMarkdown);
map.keys['Control-b'] = 'bold';
map.keys['Control-e'] = 'code';
map.keys['Control-h'] = 'blocks';
map.keys['Control-i'] = 'italic';
map.keys['Control-l'] = 'link';
map.keys['Control-o'] = 'image';
map.keys['Control-q'] = 'quote';
map.keys['Control-Shift-Q'] = 'quote'; // Use `Control-Shift-Q` if `Control-q` closes the window
editor.state = fromStates({}, editor.state, stateSource, stateSourceXML, stateSourceHTML, stateSourceMarkdown, {
commands: map.commands,
keys: map.keys
});
editor.self.addEventListener('blur', () => map.pull());
editor.self.addEventListener('input', () => map.pull());
editor.self.addEventListener('keydown', e => {
map.push(e.key);
let command = map.command();
// Check for custom command…
if (command) {
let value = map.fire(command);
if (false === value) {
e.preventDefault();
} else if (null === value) {
console.error('Unknown command:', command);
}
// Else, run the defaults!
} else {
if (
canKeyDownSourceMarkdown(map, editor) &&
canKeyDownSourceHTML(map, editor) &&
canKeyDownSourceXML(map, editor) &&
canKeyDownSource(map, editor) &&
canKeyDownEnterSource(map, editor) &&
canKeyDownHistorySource(map, editor) &&
canKeyDownMoveSource(map, editor) &&
canKeyDownTabSource(map, editor)
) {
// Normal key strokes. Add more key strokes extension here!
} else {
e.preventDefault();
}
}
bounce();
});
editor.self.addEventListener('keyup', e => {
canKeyUpSource(map, editor) || e.preventDefault();
map.pull(e.key);
});
editor.self.addEventListener('mousedown', e => {
canMouseDownSourceXML(map, editor) || e.preventDefault();
});
editor.record(); // Record the first history data!
Properties
TE.SourceMarkdown.commands
Return the default commands to be merged with editor.state.source.commands
.
TE.SourceMarkdown.state
Return the default state to be merged with editor.state
.
Strokes
Strokes can either return false
or true
. If it returns false
, it means that this extension has manipulated the existing value. If it returns true
, it means that current stroke works normally.