UNPKG

@atlaskit/editor-core

Version:

A package contains Atlassian editor core functionality

296 lines • 12 kB
import { Plugin, PluginKey, } from '../../prosemirror'; import * as commands from '../../commands'; import keymapHandler from './keymap'; import inputRulePlugin from './input-rule'; import { transformToCodeAction } from './transform-to-code'; var TextFormattingState = (function () { function TextFormattingState(state) { this.changeHandlers = []; // public state this.emActive = false; this.emDisabled = false; this.emHidden = false; this.codeActive = false; this.codeDisabled = false; this.codeHidden = false; this.underlineActive = false; this.underlineDisabled = false; this.underlineHidden = false; this.strikeActive = false; this.strikeDisabled = false; this.strikeHidden = false; this.strongActive = false; this.strongDisabled = false; this.strongHidden = false; this.superscriptActive = false; this.superscriptDisabled = false; this.superscriptHidden = false; this.subscriptActive = false; this.subscriptDisabled = false; this.subscriptHidden = false; this.state = state; this.emHidden = !state.schema.marks.em; this.strongHidden = !state.schema.marks.strong; this.underlineHidden = !state.schema.marks.underline; this.codeHidden = !state.schema.marks.code; this.superscriptHidden = !state.schema.marks.subsup; this.subscriptHidden = !state.schema.marks.subsup; this.strikeHidden = !state.schema.marks.strike; this.update(state); } TextFormattingState.prototype.toggleEm = function (view) { var em = this.state.schema.marks.em; if (em) { return this.toggleMark(view, em); } return false; }; TextFormattingState.prototype.toggleCode = function (view) { var code = this.state.schema.marks.code; var _a = this.state.selection, from = _a.from, to = _a.to; if (code) { if (!this.codeActive) { view.dispatch(transformToCodeAction(view.state, from, to)); return true; } return commands.toggleMark(code)(view.state, view.dispatch); } return false; }; TextFormattingState.prototype.toggleStrike = function (view) { var strike = this.state.schema.marks.strike; if (strike) { return this.toggleMark(view, strike); } return false; }; TextFormattingState.prototype.toggleStrong = function (view) { var strong = this.state.schema.marks.strong; if (strong) { return this.toggleMark(view, strong); } return false; }; TextFormattingState.prototype.toggleSuperscript = function (view) { var subsup = this.state.schema.marks.subsup; if (subsup) { if (this.subscriptActive) { // If subscript is enabled, turn it off first. return this.toggleMark(view, subsup); } return this.toggleMark(view, subsup, { type: 'sup' }); } return false; }; TextFormattingState.prototype.toggleSubscript = function (view) { var subsup = this.state.schema.marks.subsup; if (subsup) { if (this.superscriptActive) { // If superscript is enabled, turn it off first. return this.toggleMark(view, subsup); } return this.toggleMark(view, subsup, { type: 'sub' }); } return false; }; TextFormattingState.prototype.toggleUnderline = function (view) { var underline = this.state.schema.marks.underline; if (underline) { return this.toggleMark(view, underline); } return false; }; TextFormattingState.prototype.subscribe = function (cb) { this.changeHandlers.push(cb); cb(this); }; TextFormattingState.prototype.unsubscribe = function (cb) { this.changeHandlers = this.changeHandlers.filter(function (ch) { return ch !== cb; }); }; TextFormattingState.prototype.update = function (newEditorState) { this.state = newEditorState; var state = this.state; var _a = state.schema.marks, em = _a.em, code = _a.code, strike = _a.strike, strong = _a.strong, subsup = _a.subsup, underline = _a.underline; var dirty = false; if (code) { var newCodeActive = this.markActive(code.create()); if (newCodeActive !== this.codeActive) { this.codeActive = newCodeActive; dirty = true; } var newCodeDisabled = !commands.toggleMark(code)(this.state); if (newCodeDisabled !== this.codeDisabled) { this.codeDisabled = newCodeDisabled; dirty = true; } } if (em) { var newEmActive = this.anyMarkActive(em); if (newEmActive !== this.emActive) { this.emActive = newEmActive; dirty = true; } var newEmDisabled = !commands.toggleMark(em)(this.state); if (this.codeActive || newEmDisabled !== this.emDisabled) { this.emDisabled = this.codeActive ? true : newEmDisabled; dirty = true; } } if (strike) { var newStrikeActive = this.anyMarkActive(strike); if (newStrikeActive !== this.strikeActive) { this.strikeActive = newStrikeActive; dirty = true; } var newStrikeDisabled = !commands.toggleMark(strike)(this.state); if (this.codeActive || newStrikeDisabled !== this.strikeDisabled) { this.strikeDisabled = this.codeActive ? true : newStrikeDisabled; dirty = true; } } if (strong) { var newStrongActive = this.anyMarkActive(strong); if (newStrongActive !== this.strongActive) { this.strongActive = newStrongActive; dirty = true; } var newStrongDisabled = !commands.toggleMark(strong)(this.state); if (this.codeActive || newStrongDisabled !== this.strongDisabled) { this.strongDisabled = this.codeActive ? true : newStrongDisabled; dirty = true; } } if (subsup) { var subMark = subsup.create({ type: 'sub' }); var supMark = subsup.create({ type: 'sup' }); var newSubscriptActive = this.markActive(subMark); if (newSubscriptActive !== this.subscriptActive) { this.subscriptActive = newSubscriptActive; dirty = true; } var newSubscriptDisabled = !commands.toggleMark(subsup, { type: 'sub' })(this.state); if (this.codeActive || newSubscriptDisabled !== this.subscriptDisabled) { this.subscriptDisabled = this.codeActive ? true : newSubscriptDisabled; dirty = true; } var newSuperscriptActive = this.markActive(supMark); if (newSuperscriptActive !== this.superscriptActive) { this.superscriptActive = newSuperscriptActive; dirty = true; } var newSuperscriptDisabled = !commands.toggleMark(subsup, { type: 'sup' })(this.state); if (this.codeActive || newSuperscriptDisabled !== this.superscriptDisabled) { this.superscriptDisabled = this.codeActive ? true : newSuperscriptDisabled; dirty = true; } } if (underline) { var newUnderlineActive = this.anyMarkActive(underline); if (newUnderlineActive !== this.underlineActive) { this.underlineActive = newUnderlineActive; dirty = true; } var newUnderlineDisabled = !commands.toggleMark(underline)(this.state); if (this.codeActive || newUnderlineDisabled !== this.underlineDisabled) { this.underlineDisabled = this.codeActive ? true : newUnderlineDisabled; dirty = true; } } if (dirty) { this.triggerOnChange(); } }; /** * Determine if a mark (with specific attribute values) exists anywhere in the selection. */ TextFormattingState.prototype.markActive = function (mark) { var state = this.state; var _a = state.selection, from = _a.from, to = _a.to, empty = _a.empty; var foundMark = false; if (this.marksToRemove) { this.marksToRemove.forEach(function (markToRemove) { if (markToRemove.type.name === mark.type.name) { foundMark = true; } }); } var currentMarkBefore = state.doc.rangeHasMark(from - 1, to, mark.type); var currentMarkAfter = state.doc.rangeHasMark(from, to, mark.type); if (foundMark && (!currentMarkBefore || (!mark.type.spec.inclusive && !currentMarkAfter))) { return false; } // When the selection is empty, only the active marks apply. if (empty) { return !!mark.isInSet(state.tr.storedMarks || state.selection.$from.marks()); } // For a non-collapsed selection, the marks on the nodes matter. var found = false; state.doc.nodesBetween(from, to, function (node) { found = found || mark.isInSet(node.marks); }); return found; }; TextFormattingState.prototype.triggerOnChange = function () { var _this = this; this.changeHandlers.forEach(function (cb) { return cb(_this); }); }; /** * Determine if a mark of a specific type exists anywhere in the selection. */ TextFormattingState.prototype.anyMarkActive = function (markType) { var state = this.state; var _a = state.selection, from = _a.from, to = _a.to, empty = _a.empty; var found = false; if (this.marksToRemove) { this.marksToRemove.forEach(function (mark) { if (mark.type.name === markType.name) { found = true; } }); } if (found && !state.doc.rangeHasMark(from - 1, to, markType)) { return false; } if (empty) { return !!markType.isInSet(state.tr.storedMarks || state.selection.$from.marks()); } return state.doc.rangeHasMark(from, to, markType); }; TextFormattingState.prototype.toggleMark = function (view, markType, attrs) { // Disable text-formatting inside code if (this.codeActive ? this.codeDisabled : true) { return commands.toggleMark(markType, attrs)(view.state, view.dispatch); } return false; }; return TextFormattingState; }()); export { TextFormattingState }; export var stateKey = new PluginKey('textFormatting'); export var plugin = new Plugin({ state: { init: function (config, state) { return new TextFormattingState(state); }, apply: function (tr, pluginState, oldState, newState) { pluginState.update(newState); return pluginState; } }, key: stateKey, view: function (view) { var pluginState = stateKey.getState(view.state); pluginState.keymapHandler = keymapHandler(view, pluginState); return {}; }, props: { handleKeyDown: function (view, event) { return stateKey.getState(view.state).keymapHandler(view, event); } } }); var plugins = function (schema) { return [plugin, inputRulePlugin(schema)].filter(function (plugin) { return !!plugin; }); }; export default plugins; //# sourceMappingURL=index.js.map