UNPKG

slate-edit-code

Version:

A Slate plugin to handle code blocks editing.

1,770 lines (1,303 loc) 1.62 MB
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ 'use strict'; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* eslint-disable import/no-extraneous-dependencies */ /* global document */ var _react = require('react'); var React = _interopRequireWildcard(_react); var _reactDom = require('react-dom'); var _reactDom2 = _interopRequireDefault(_reactDom); var _slateReact = require('slate-react'); var _lib = require('../lib/'); var _lib2 = _interopRequireDefault(_lib); var _value = require('./value'); var _value2 = _interopRequireDefault(_value); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var plugin = (0, _lib2.default)(); var plugins = [plugin]; function renderNode(props) { var node = props.node, children = props.children, attributes = props.attributes; switch (node.type) { case 'code_block': return React.createElement( 'div', _extends({ className: 'code' }, attributes), children ); case 'code_line': return React.createElement( 'pre', attributes, children ); case 'paragraph': return React.createElement( 'p', attributes, children ); case 'heading': return React.createElement( 'h1', attributes, children ); default: return null; } } var Example = function (_React$Component) { _inherits(Example, _React$Component); function Example() { var _ref; var _temp, _this, _ret; _classCallCheck(this, Example); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Example.__proto__ || Object.getPrototypeOf(Example)).call.apply(_ref, [this].concat(args))), _this), _this.state = { value: _value2.default }, _this.onChange = function (_ref2) { var value = _ref2.value; _this.setState({ value: value }); }, _this.onToggleCode = function () { var value = _this.state.value; _this.onChange(plugin.changes.toggleCodeBlock(value.change(), 'paragraph').focus()); }, _temp), _possibleConstructorReturn(_this, _ret); } _createClass(Example, [{ key: 'render', value: function render() { var value = this.state.value; return React.createElement( 'div', null, React.createElement( 'button', { onClick: this.onToggleCode }, plugin.utils.isInCodeBlock(value) ? 'Paragraph' : 'Code Block' ), React.createElement(_slateReact.Editor, { placeholder: 'Enter some text...', plugins: plugins, value: value, onChange: this.onChange, renderNode: renderNode }) ); } }]); return Example; }(React.Component); // $FlowFixMe _reactDom2.default.render(React.createElement(Example, null), document.getElementById('example')); },{"../lib/":21,"./value":2,"react":403,"react-dom":250,"slate-react":411}],2:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _slateHyperscript = require('slate-hyperscript'); var h = (0, _slateHyperscript.createHyperscript)({ blocks: { heading: 'heading', paragraph: 'paragraph', code_block: 'code_block', code_line: 'code_line' } }); /** @jsx h */ // eslint-disable-next-line var value = h( 'value', null, h( 'document', null, h( 'heading', null, 'Slate + Code Editing' ), h( 'paragraph', null, 'This page is a basic example of Slate + slate-edit-code plugin. Press Tab to indent code. Shift+Tab to unindent. Press Enter to carry indentation onto the newline. Press Mod (Cmd on Mac, Ctrl on Windows) + Enter to exit the code block.' ), h( 'code_block', null, h( 'code_line', null, '// Some JavaScript' ), h( 'code_line', null, 'function hello() {' ), h( 'code_line', null, " console.log('Hello World')" ), h( 'code_line', null, '}' ) ), h( 'paragraph', null, 'End paragraph' ) ) ); exports.default = value; },{"slate-hyperscript":408}],3:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); /** * Dedent all lines in selection */ function dedentLines(opts, change, // Indent to remove indent) { var value = change.value; var document = value.document, selection = value.selection; var lines = document.getBlocksAtRange(selection).filter(function (node) { return node.type === opts.lineType; }); return lines.reduce(function (c, line) { // Remove a level of indent from the start of line var text = line.nodes.first(); var lengthToRemove = text.characters.takeWhile(function (char, index) { return indent.charAt(index) === char.text; }).count(); return c.removeTextByKey(text.key, 0, lengthToRemove); }, change); } exports.default = dedentLines; },{"slate":428}],4:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); /** * Indent all lines in selection */ function indentLines(opts, change, // Indent to add indent) { var value = change.value; var document = value.document, selection = value.selection; var lines = document.getBlocksAtRange(selection).filter(function (node) { return node.type === opts.lineType; }); return lines.reduce(function (c, line) { // Insert an indent at start of line var text = line.nodes.first(); return c.insertTextByKey(text.key, 0, indent); }, change); } exports.default = indentLines; },{"slate":428}],5:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.wrapCodeBlockByKey = exports.wrapCodeBlock = exports.unwrapCodeBlockByKey = exports.unwrapCodeBlock = exports.toggleCodeBlock = exports.indentLines = exports.dedentLines = undefined; var _dedentLines = require('./dedentLines'); var _dedentLines2 = _interopRequireDefault(_dedentLines); var _indentLines = require('./indentLines'); var _indentLines2 = _interopRequireDefault(_indentLines); var _toggleCodeBlock = require('./toggleCodeBlock'); var _toggleCodeBlock2 = _interopRequireDefault(_toggleCodeBlock); var _unwrapCodeBlock = require('./unwrapCodeBlock'); var _unwrapCodeBlock2 = _interopRequireDefault(_unwrapCodeBlock); var _unwrapCodeBlockByKey = require('./unwrapCodeBlockByKey'); var _unwrapCodeBlockByKey2 = _interopRequireDefault(_unwrapCodeBlockByKey); var _wrapCodeBlock = require('./wrapCodeBlock'); var _wrapCodeBlock2 = _interopRequireDefault(_wrapCodeBlock); var _wrapCodeBlockByKey = require('./wrapCodeBlockByKey'); var _wrapCodeBlockByKey2 = _interopRequireDefault(_wrapCodeBlockByKey); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.dedentLines = _dedentLines2.default; exports.indentLines = _indentLines2.default; exports.toggleCodeBlock = _toggleCodeBlock2.default; exports.unwrapCodeBlock = _unwrapCodeBlock2.default; exports.unwrapCodeBlockByKey = _unwrapCodeBlockByKey2.default; exports.wrapCodeBlock = _wrapCodeBlock2.default; exports.wrapCodeBlockByKey = _wrapCodeBlockByKey2.default; },{"./dedentLines":3,"./indentLines":4,"./toggleCodeBlock":6,"./unwrapCodeBlock":7,"./unwrapCodeBlockByKey":8,"./wrapCodeBlock":9,"./wrapCodeBlockByKey":10}],6:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); var _utils = require('../utils'); var _wrapCodeBlock = require('./wrapCodeBlock'); var _wrapCodeBlock2 = _interopRequireDefault(_wrapCodeBlock); var _unwrapCodeBlock = require('./unwrapCodeBlock'); var _unwrapCodeBlock2 = _interopRequireDefault(_unwrapCodeBlock); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Toggle code block / paragraph. */ function toggleCodeBlock(opts, change, // When toggling a code block off, type to convert to type) { if ((0, _utils.isInCodeBlock)(opts, change.value)) { return (0, _unwrapCodeBlock2.default)(opts, change, type); } return (0, _wrapCodeBlock2.default)(opts, change); } exports.default = toggleCodeBlock; },{"../utils":27,"./unwrapCodeBlock":7,"./wrapCodeBlock":9,"slate":428}],7:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); var _utils = require('../utils'); var _unwrapCodeBlockByKey = require('./unwrapCodeBlockByKey'); var _unwrapCodeBlockByKey2 = _interopRequireDefault(_unwrapCodeBlockByKey); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Convert a code block to a normal block. */ function unwrapCodeBlock(opts, change, type) { var value = change.value; var codeBlock = (0, _utils.getCurrentCode)(opts, value); if (!codeBlock) { return change; } // Convert to paragraph (0, _unwrapCodeBlockByKey2.default)(opts, change, codeBlock.key, type); return change; } exports.default = unwrapCodeBlock; },{"../utils":27,"./unwrapCodeBlockByKey":8,"slate":428}],8:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); /** * Unwrap a code block into a normal block. */ function unwrapCodeBlockByKey(opts, change, key, type) { var value = change.value; var document = value.document; // Get the code block var codeBlock = document.getDescendant(key); if (!codeBlock || codeBlock.type != opts.containerType) { throw new Error('Block passed to unwrapCodeBlockByKey should be a code block container'); } // change lines into paragraph codeBlock.nodes.forEach(function (line) { return change.setNodeByKey(line.key, { type: type }, { normalize: false }).unwrapNodeByKey(line.key, { normalize: false }); }); return change; } exports.default = unwrapCodeBlockByKey; },{"slate":428}],9:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); var _wrapCodeBlockByKey = require('./wrapCodeBlockByKey'); var _wrapCodeBlockByKey2 = _interopRequireDefault(_wrapCodeBlockByKey); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Wrap current block into a code block. */ function wrapCodeBlock(opts, change) { var value = change.value; var startBlock = value.startBlock, selection = value.selection; // Convert to code block (0, _wrapCodeBlockByKey2.default)(opts, change, startBlock.key); // Move selection back in the block change.collapseToStartOf(change.value.document.getDescendant(startBlock.key)).moveOffsetsTo(selection.startOffset); return change; } exports.default = wrapCodeBlock; },{"./wrapCodeBlockByKey":10,"slate":428}],10:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); var _utils = require('../utils'); /** * Wrap a block into a code block. */ function wrapCodeBlockByKey(opts, change, key) { var value = change.value; var document = value.document; var startBlock = document.getDescendant(key); var text = startBlock.text; // Remove all child startBlock.nodes.forEach(function (node) { change.removeNodeByKey(node.key, { normalize: false }); }); // Insert new text var toInsert = (0, _utils.deserializeCode)(opts, text); toInsert.nodes.forEach(function (node, i) { change.insertNodeByKey(startBlock.key, i, node, { normalize: false }); }); // Set node type change.setNodeByKey(startBlock.key, { type: opts.containerType }); return change; } exports.default = wrapCodeBlockByKey; },{"../utils":27,"slate":428}],11:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _options = require('./options'); var _options2 = _interopRequireDefault(_options); var _utils = require('./utils'); var _changes = require('./changes'); var _validation = require('./validation'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * The core of the plugin, which does not relies on `slate-react`, and includes * everything but behavior and rendering logic. */ function core(optsParam) { var opts = new _options2.default(optsParam); return { schema: (0, _validation.schema)(opts), changes: { unwrapCodeBlockByKey: _changes.unwrapCodeBlockByKey.bind(null, opts), wrapCodeBlockByKey: _changes.wrapCodeBlockByKey.bind(null, opts), wrapCodeBlock: _changes.wrapCodeBlock.bind(null, opts), unwrapCodeBlock: _changes.unwrapCodeBlock.bind(null, opts), toggleCodeBlock: _changes.toggleCodeBlock.bind(null, opts) }, utils: { isInCodeBlock: _utils.isInCodeBlock.bind(null, opts), deserializeCode: _utils.deserializeCode.bind(null, opts) } }; } exports.default = core; },{"./changes":5,"./options":22,"./utils":27,"./validation":29}],12:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.onKeyDown = exports.onPaste = exports.onSelectAll = exports.onBackspace = exports.onModEnter = exports.onEnter = exports.onShiftTab = exports.onTab = undefined; var _onTab = require('./onTab'); var _onTab2 = _interopRequireDefault(_onTab); var _onShiftTab = require('./onShiftTab'); var _onShiftTab2 = _interopRequireDefault(_onShiftTab); var _onEnter = require('./onEnter'); var _onEnter2 = _interopRequireDefault(_onEnter); var _onModEnter = require('./onModEnter'); var _onModEnter2 = _interopRequireDefault(_onModEnter); var _onBackspace = require('./onBackspace'); var _onBackspace2 = _interopRequireDefault(_onBackspace); var _onSelectAll = require('./onSelectAll'); var _onSelectAll2 = _interopRequireDefault(_onSelectAll); var _onPaste = require('./onPaste'); var _onPaste2 = _interopRequireDefault(_onPaste); var _onKeyDown = require('./onKeyDown'); var _onKeyDown2 = _interopRequireDefault(_onKeyDown); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.onTab = _onTab2.default; exports.onShiftTab = _onShiftTab2.default; exports.onEnter = _onEnter2.default; exports.onModEnter = _onModEnter2.default; exports.onBackspace = _onBackspace2.default; exports.onSelectAll = _onSelectAll2.default; exports.onPaste = _onPaste2.default; exports.onKeyDown = _onKeyDown2.default; },{"./onBackspace":13,"./onEnter":14,"./onKeyDown":15,"./onModEnter":16,"./onPaste":17,"./onSelectAll":18,"./onShiftTab":19,"./onTab":20}],13:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); var _endsWith = require('ends-with'); var _endsWith2 = _interopRequireDefault(_endsWith); var _utils = require('../utils'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * User pressed Delete in an editor: * Remove last idnentation before cursor */ function onBackspace(opts, event, change, editor) { var value = change.value; if (value.isExpanded) { return undefined; } var startOffset = value.startOffset, startText = value.startText; var currentLine = value.startBlock; // Detect and remove indentation at cursor var indent = (0, _utils.getCurrentIndent)(opts, value); var beforeSelection = currentLine.text.slice(0, startOffset); // If the line before selection ending with the indentation? if ((0, _endsWith2.default)(beforeSelection, indent)) { // Remove indent event.preventDefault(); return change.deleteBackward(indent.length).focus(); } else if (opts.exitBlockType) { // Otherwise check if we are in an empty code container... var currentCode = (0, _utils.getCurrentCode)(opts, value); var isStartOfCode = startOffset === 0 && currentCode.getFirstText() === startText; // PERF: avoid checking for whole currentCode.text var isEmpty = currentCode.nodes.size === 1 && currentLine.text.length === 0; if (isStartOfCode && isEmpty) { event.preventDefault(); // Convert it to default exit type return change.setBlocks(opts.exitBlockType, { normalize: false }).unwrapNodeByKey(currentLine.key); } } return undefined; } exports.default = onBackspace; },{"../utils":27,"ends-with":34,"slate":428}],14:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); var _utils = require('../utils'); /** * User pressed Enter in an editor: * Insert a new code line and start it with the indentation from previous line */ function onEnter(opts, event, change, editor) { var value = change.value; if (!value.isCollapsed) { return undefined; } event.preventDefault(); var startBlock = value.startBlock; var currentLineText = startBlock.text; var indent = (0, _utils.getIndent)(currentLineText, ''); return change.splitBlock().insertText(indent).focus(); } exports.default = onEnter; },{"../utils":27,"slate":428}],15:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _isHotkey = require('is-hotkey'); require('slate'); var _utils = require('../utils'); var _onTab = require('./onTab'); var _onTab2 = _interopRequireDefault(_onTab); var _onShiftTab = require('./onShiftTab'); var _onShiftTab2 = _interopRequireDefault(_onShiftTab); var _onEnter = require('./onEnter'); var _onEnter2 = _interopRequireDefault(_onEnter); var _onModEnter = require('./onModEnter'); var _onModEnter2 = _interopRequireDefault(_onModEnter); var _onBackspace = require('./onBackspace'); var _onBackspace2 = _interopRequireDefault(_onBackspace); var _onSelectAll = require('./onSelectAll'); var _onSelectAll2 = _interopRequireDefault(_onSelectAll); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var isModA = (0, _isHotkey.isKeyHotkey)('mod+a'); var isShiftTab = (0, _isHotkey.isKeyHotkey)('shift+tab'); var isTab = (0, _isHotkey.isKeyHotkey)('tab'); var isModEnter = (0, _isHotkey.isKeyHotkey)('mod+enter'); var isEnter = (0, _isHotkey.isKeyHotkey)('enter'); var isBackspace = (0, _isHotkey.isKeyHotkey)('backspace'); /** * User is pressing a key in the editor */ function onKeyDown(opts, event, change, editor) { var value = change.value; var currentCode = (0, _utils.getCurrentCode)(opts, value); // Inside code ? if (!currentCode) { return undefined; } // Add opts in the argument list var args = [opts, event, change, editor]; // Select all the code in the block (Mod+a) if (opts.selectAll && isModA(event)) { return _onSelectAll2.default.apply(undefined, args); } else if (isShiftTab(event)) { // User is pressing Shift+Tab return _onShiftTab2.default.apply(undefined, args); } else if (isTab(event)) { // User is pressing Tab return _onTab2.default.apply(undefined, args); } else if (opts.exitBlockType && isModEnter(event)) { // User is pressing Mod+Enter return _onModEnter2.default.apply(undefined, args); } else if (isEnter(event)) { // User is pressing Enter return _onEnter2.default.apply(undefined, args); } else if (isBackspace(event)) { // User is pressing Backspace return _onBackspace2.default.apply(undefined, args); } return undefined; } exports.default = onKeyDown; },{"../utils":27,"./onBackspace":13,"./onEnter":14,"./onModEnter":16,"./onSelectAll":18,"./onShiftTab":19,"./onTab":20,"is-hotkey":65,"slate":428}],16:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); /** * User pressed Mod+Enter in an editor * Exit the current code block */ function onModEnter(opts, event, change, editor) { var value = change.value; if (!value.isCollapsed) { return undefined; } event.preventDefault(); // Exit the code block return opts.resolvedOnExit(change); } exports.default = onModEnter; },{"slate":428}],17:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _slate = require('slate'); var _slateReact = require('slate-react'); var _utils = require('../utils'); /** * User is pasting content, insert it as text */ function onPaste(opts, event, change, editor) { var value = change.value; var data = (0, _slateReact.getEventTransfer)(event); var currentCode = (0, _utils.getCurrentCode)(opts, value); // Only handle paste when selection is completely a code block var endBlock = value.endBlock; if (!currentCode || !currentCode.hasDescendant(endBlock.key)) { return undefined; } // Convert to text if needed var text = void 0; if (data.type === 'fragment') { text = data.fragment.getTexts().map(function (t) { return t.text; }).join('\n'); } else { text = data.text; } // Convert the text to code lines var lines = (0, _utils.deserializeCode)(opts, text).nodes; var fragment = _slate.Document.create({ nodes: lines }); return change.insertFragment(fragment); } exports.default = onPaste; },{"../utils":27,"slate":428,"slate-react":411}],18:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); var _utils = require('../utils'); /** * User is Cmd+A to select all text */ function onSelectAll(opts, event, change, editor) { var value = change.value; event.preventDefault(); var currentCode = (0, _utils.getCurrentCode)(opts, value); return change.collapseToStartOf(currentCode.getFirstText()).extendToEndOf(currentCode.getLastText()); } exports.default = onSelectAll; },{"../utils":27,"slate":428}],19:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); var _utils = require('../utils'); var _changes = require('../changes'); /** * User pressed Shift+Tab in an editor: * Reduce indentation in the selected lines. */ function onShiftTab(opts, event, change, editor) { var value = change.value; event.preventDefault(); event.stopPropagation(); var indent = (0, _utils.getCurrentIndent)(opts, value); // We dedent all selected lines return (0, _changes.dedentLines)(opts, change, indent); } exports.default = onShiftTab; },{"../changes":5,"../utils":27,"slate":428}],20:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); var _utils = require('../utils'); var _changes = require('../changes'); /** * User pressed Tab in an editor: * Insert a tab after detecting it from code block content. */ function onTab(opts, event, change, editor) { var value = change.value; event.preventDefault(); event.stopPropagation(); var isCollapsed = value.isCollapsed; var indent = (0, _utils.getCurrentIndent)(opts, value); // Selection is collapsed, we just insert an indent at cursor if (isCollapsed) { return change.insertText(indent).focus(); } // We indent all selected lines return (0, _changes.indentLines)(opts, change, indent); } exports.default = onTab; },{"../changes":5,"../utils":27,"slate":428}],21:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _options = require('./options'); var _options2 = _interopRequireDefault(_options); var _handlers = require('./handlers'); var _core = require('./core'); var _core2 = _interopRequireDefault(_core); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A Slate plugin to handle keyboard events in code blocks. */ function EditCode() { var optsParam = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var opts = new _options2.default(optsParam); var corePlugin = (0, _core2.default)(opts); return _extends({}, corePlugin, { onKeyDown: _handlers.onKeyDown.bind(null, opts), onPaste: _handlers.onPaste.bind(null, opts) }); } exports.default = EditCode; },{"./core":11,"./handlers":12,"./options":22}],22:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _slate = require('slate'); var _immutable = require('immutable'); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var DEFAULTS = { containerType: 'code_block', lineType: 'code_line', exitBlockType: 'paragraph', selectAll: true, allowMarks: false, getIndent: null, onExit: null }; /** * The plugin options container */ var Options = function (_Record) { _inherits(Options, _Record); function Options() { _classCallCheck(this, Options); return _possibleConstructorReturn(this, (Options.__proto__ || Object.getPrototypeOf(Options)).apply(this, arguments)); } _createClass(Options, [{ key: 'resolvedOnExit', value: function resolvedOnExit(change) { if (this.onExit) { // Custom onExit option return this.onExit(change); } // Default behavior: insert an exit block var range = change.value.selection; var exitBlock = _slate.Block.create({ type: this.exitBlockType, nodes: [_slate.Text.create()] }); change.deleteAtRange(range, { normalize: false }); change.insertBlockAtRange(change.value.selection, exitBlock, { normalize: false }); // Exit the code block change.unwrapNodeByKey(exitBlock.key); return change.collapseToStartOf(exitBlock); } }]); return Options; }((0, _immutable.Record)(DEFAULTS)); exports.default = Options; },{"immutable":62,"slate":428}],23:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _slate = require('slate'); var _immutable = require('immutable'); var _detectNewline = require('detect-newline'); var _detectNewline2 = _interopRequireDefault(_detectNewline); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var DEFAULT_NEWLINE = '\n'; /** * Deserialize a text into a code block */ function deserializeCode(opts, text) { var sep = (0, _detectNewline2.default)(text) || DEFAULT_NEWLINE; var lines = (0, _immutable.List)(text.split(sep)).map(function (line) { return _slate.Block.create({ type: opts.lineType, nodes: [_slate.Text.create(line)] }); }); var code = _slate.Block.create({ type: opts.containerType, nodes: lines }); return code; } exports.default = deserializeCode; },{"detect-newline":32,"immutable":62,"slate":428}],24:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); /** * Return the current code block, from current selection or from a node key. */ function getCurrentCode(opts, value, key) { var document = value.document; var currentBlock = void 0; if (key) { currentBlock = value.document.getDescendant(key); } else { if (!value.selection.startKey) return null; currentBlock = value.startBlock; } // The structure is always code_block -> code_line -> text // So the parent of the currentBlock should be the code_block var parent = document.getParent(currentBlock.key); if (parent && parent.type === opts.containerType) { return parent; } return null; } exports.default = getCurrentCode; },{"slate":428}],25:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); var _getIndent = require('./getIndent'); var _getIndent2 = _interopRequireDefault(_getIndent); var _getCurrentCode = require('./getCurrentCode'); var _getCurrentCode2 = _interopRequireDefault(_getCurrentCode); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Detect indentation in the current code block */ function getCurrentIndent(opts, value) { if (opts.getIndent) { return opts.getIndent(value); } var currentCode = (0, _getCurrentCode2.default)(opts, value); if (!currentCode) { return ''; } var text = currentCode.getTexts().map(function (t) { return t.text; }).join('\n'); return (0, _getIndent2.default)(text); } exports.default = getCurrentIndent; },{"./getCurrentCode":24,"./getIndent":26,"slate":428}],26:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _detectIndent = require('detect-indent'); var _detectIndent2 = _interopRequireDefault(_detectIndent); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var DEFAULT_INDENTATION = ' '; /** * Detect indentation in a text */ function getIndent(text) { var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_INDENTATION; return (0, _detectIndent2.default)(text).indent || defaultValue; } exports.default = getIndent; },{"detect-indent":31}],27:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.isInCodeBlock = exports.getIndent = exports.getCurrentIndent = exports.getCurrentCode = exports.deserializeCode = undefined; var _deserializeCode = require('./deserializeCode'); var _deserializeCode2 = _interopRequireDefault(_deserializeCode); var _getCurrentCode = require('./getCurrentCode'); var _getCurrentCode2 = _interopRequireDefault(_getCurrentCode); var _getCurrentIndent = require('./getCurrentIndent'); var _getCurrentIndent2 = _interopRequireDefault(_getCurrentIndent); var _getIndent = require('./getIndent'); var _getIndent2 = _interopRequireDefault(_getIndent); var _isInCodeBlock = require('./isInCodeBlock'); var _isInCodeBlock2 = _interopRequireDefault(_isInCodeBlock); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.deserializeCode = _deserializeCode2.default; exports.getCurrentCode = _getCurrentCode2.default; exports.getCurrentIndent = _getCurrentIndent2.default; exports.getIndent = _getIndent2.default; exports.isInCodeBlock = _isInCodeBlock2.default; },{"./deserializeCode":23,"./getCurrentCode":24,"./getCurrentIndent":25,"./getIndent":26,"./isInCodeBlock":28}],28:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); require('slate'); /** * Test if current selection is in a code block. */ function isInCodeBlock(opts, value) { var document = value.document, startKey = value.startKey; var codeBlock = document.getClosest(startKey, function (block) { return block.type === opts.containerType; }); return Boolean(codeBlock); } exports.default = isInCodeBlock; },{"slate":428}],29:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.schema = undefined; var _schema = require('./schema'); var _schema2 = _interopRequireDefault(_schema); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.schema = _schema2.default; },{"./schema":30}],30:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _slate = require('slate'); var _slateSchemaViolations = require('slate-schema-violations'); var _immutable = require('immutable'); var _utils = require('../utils'); function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /** * Create a schema definition with rules to normalize code blocks */ function schema(opts) { var _blocks; var baseSchema = { blocks: (_blocks = {}, _defineProperty(_blocks, opts.containerType, { nodes: [{ types: [opts.lineType] }], normalize: function normalize(change, violation, context) { switch (violation) { case _slateSchemaViolations.CHILD_TYPE_INVALID: return onlyLine(opts, change, context); default: return undefined; } } }), _defineProperty(_blocks, opts.lineType, { nodes: [{ objects: ['text'], min: 1 }], parent: { types: [opts.containerType] }, normalize: function normalize(change, violation, context) { switch (violation) { case _slateSchemaViolations.PARENT_TYPE_INVALID: return noOrphanLine(opts, change, context); default: return undefined; } } }), _blocks) }; if (!opts.allowMarks) { baseSchema.blocks[opts.lineType].marks = []; } return baseSchema; } /** * A rule that ensure code blocks only contain lines of code, and no marks */ function onlyLine(opts, change, context) { return change.withoutNormalization(function (c) { var codeLines = (0, _immutable.List)(); context.node.nodes.forEach(function (node) { if (node.object === opts.lineType) { return; } if (node.object === 'text') { if (node.text.length === 0) { return; } codeLines = codeLines.concat((0, _utils.deserializeCode)(opts, node.text).nodes); } c.removeNodeByKey(node.key); }); codeLines.forEach(function (codeLine, index) { c.insertNodeByKey(context.node.key, index, codeLine); }); return c; }); } /** * Return a list of group of code lines. Used to wrap them together in * independent code blocks. */ function getSuccessiveCodeLines(opts, nodes) { var isLine = function isLine(n) { return n.type === opts.lineType; }; var nonLines = nodes.takeUntil(isLine); var afterNonLines = nodes.skip(nonLines.size); if (afterNonLines.isEmpty()) { return (0, _immutable.List)(); } var firstGroup = afterNonLines.takeWhile(isLine); var restOfNodes = afterNonLines.skip(firstGroup.size); return (0, _immutable.List)([firstGroup]).concat(getSuccessiveCodeLines(opts, restOfNodes)); } /** * A rule that ensure code lines are always children * of a code block. */ function noOrphanLine(opts, change, context) { var parent = context.parent; var linesGroup = getSuccessiveCodeLines(opts, parent.nodes); linesGroup.forEach(function (group) { var container = _slate.Block.create({ type: opts.containerType, nodes: [] }); var firstLineIndex = parent.nodes.indexOf(group.first()); change.insertNodeByKey(parent.key, firstLineIndex, container, { normalize: false }); group.forEach(function (line, index) { return change.moveNodeByKey(line.key, container.key, index, { normalize: false }); }); }); } exports.default = schema; },{"../utils":27,"immutable":62,"slate":428,"slate-schema-violations":427}],31:[function(require,module,exports){ /* eslint-disable guard-for-in */ 'use strict'; var repeating = require('repeating'); // detect either spaces or tabs but not both to properly handle tabs // for indentation and spaces for alignment var INDENT_RE = /^(?:( )+|\t+)/; function getMostUsed(indents) { var result = 0; var maxUsed = 0; var maxWeight = 0; for (var n in indents) { var indent = indents[n]; var u = indent[0]; var w = indent[1]; if (u > maxUsed || u === maxUsed && w > maxWeight) { maxUsed = u; maxWeight = w; result = Number(n); } } return result; } module.exports = function (str) { if (typeof str !== 'string') { throw new TypeError('Expected a string'); } // used to see if tabs or spaces are the most used var tabs = 0; var spaces = 0; // remember the size of previous line's indentation var prev = 0; // remember how many indents/unindents as occurred for a given size // and how much lines follow a given indentation // // indents = { // 3: [1, 0], // 4: [1, 5], // 5: [1, 0], // 12: [1, 0], // } var indents = {}; // pointer to the array of last used indent var current; // whether the last action was an indent (opposed to an unindent) var isIndent; str.split(/\n/g).forEach(function (line) { if (!line) { // ignore empty lines return; } var indent; var matches = line.match(INDENT_RE); if (!matches) { indent = 0; } else { indent = matches[0].length; if (matches[1]) { spaces++; } else { tabs++; } } var diff = indent - prev; prev = indent; if (diff) { // an indent or unindent has been detected isIndent = diff > 0; current = indents[isIndent ? diff : -diff]; if (current) { current[0]++; } else { current = indents[diff] = [1, 0]; } } else if (current) { // if the last action was an indent, increment the weight current[1] += Number(isIndent); } }); var amount = getMostUsed(indents); var type; var actual; if (!amount) { type = null; actual = ''; } else if (spaces >= tabs) { type = 'space'; actual = repeating(' ', amount); } else { type = 'tab'; actual = repeating('\t', amount); } return { amount: amount, type: type, indent: actual }; }; },{"repeating":404}],32:[function(require,module,exports){ 'use strict'; module.exports = function (str) { if (typeof str !== 'string') { throw new TypeError('Expected a string'); } var newlines = (str.match(/(?:\r?\n)/g) || []); if (newlines.length === 0) { return null; } var crlf = newlines.filter(function (el) { return el === '\r\n'; }).length; var lf = newlines.length - crlf; return crlf > lf ? '\r\n' : '\n'; }; module.exports.graceful = function (str) { return module.exports(str) || '\n'; }; },{}],33:[function(require,module,exports){ 'use strict'; var GROUP_LEFT_TO_RIGHT, GROUP_RIGHT_TO_LEFT, EXPRESSION_LEFT_TO_RIGHT, EXPRESSION_RIGHT_TO_LEFT; /* * Character ranges of left-to-right characters. */ GROUP_LEFT_TO_RIGHT = 'A-Za-z\u00C0-\u00D6\u00D8-\u00F6' + '\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF\u200E\u2C00-\uFB1C' + '\uFE00-\uFE6F\uFEFD-\uFFFF'; /* * Character ranges of right-to-left characters. */ GROUP_RIGHT_TO_LEFT = '\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC'; /* * Expression to match a left-to-right string. * * Matches the start of a string, followed by zero or * more non-right-to-left characters, followed by a * left-to-right character. */ EXPRESSION_LEFT_TO_RIGHT = new RegExp( '^[^' + GROUP_RIGHT_TO_LEFT + ']*[' + GROUP_LEFT_TO_RIGHT + ']' ); /* * Expression to match a right-to-left string. * * Matches the start of a string, followed by zero or * more non-left-to-right characters, followed by a * right-to-left character. */ EXPRESSION_RIGHT_TO_LEFT = new RegExp( '^[^' + GROUP_LEFT_TO_RIGHT + ']*[' + GROUP_RIGHT_TO_LEFT + ']' ); /** * Detect the direction of text. * * @param {string} value - value to stringify and check. * @return {string} - One of `"rtl"`, `"ltr"`, or * `"neutral"`. */ function direction(value) { value = value.toString(); if (EXPRESSION_RIGHT_TO_LEFT.test(value)) { return 'rtl'; } if (EXPRESSION_LEFT_TO_RIGHT.test(value)) { return 'ltr'; } return 'neutral'; } /* * Expose `direction`. */ module.exports = direction; },{}],34:[function(require,module,exports){ /*! * ends-with <https://github.com/jonschlinkert/ends-with> * * Copyright (c) 2014 Jon Schlinkert, contributors. * Licensed under the MIT license. */ 'use strict'; module.exports = function (a, b) { if (Array.isArray(a)) { return a[a.length - 1] === b; } a = String(a); b = String(b); var i = b.length; var len = a.length - i; while (i--) { if (b.charAt(i) !== a.charAt(len + i)) { return false; } } return true; }; },{}],35:[function(require,module,exports){ (function (global){ /*! https://mths.be/esrever v0.2.0 by @mathias */ ;(function(root) { // Detect free variables `exports` var freeExports = typeof exports == 'object' && exports; // Detect free variable `module` var freeModule = typeof module == 'object' && module && module.exports == freeExports && module; // Detect free variable `global`, from Node.js or Browserified code, // and use it as `root` var freeGlobal = typeof global == 'object' && global; if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { root = freeGlobal; } /*--------------------------------------------------------------------------*/ var regexSymbolWithCombiningMarks = /([\0-\u02FF\u0370-\u1AAF\u1B00-\u1DBF\u1E00-\u20CF\u2100-\uD7FF\uE000-\uFE1F\uFE30-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])([\u0300-\u036F\u1AB0-\u1AFF\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]+)/g; var regexSurrogatePair = /([\uD800-\uDBFF])([\uDC00-\uDFFF])/g; var reverse = function(string) { // Step 1: deal with combining marks and astral symbols (surrogate pairs) string = string // Swap symbols with their combining marks so the combining marks go first .replace(regexSymbolWithCombiningMarks, function($0, $1, $2) { // Reverse the combining marks so they will end up in the same order // later on (after another round of reversing) return reverse($2) + $1; }) // Swap high and low surrogates so the low surrogates go first .replace(regexSurrogatePair, '$2$1'); // Step 2: reverse the code units in the string var result = ''; var index = string.length; while (index--) { result += string.charAt(index); } return result; }; /*--------------------------------------------------------------------------*/ var esrever = { 'version': '0.2.0', 'reverse': reverse }; // Some AMD build optimizers, like r.js, check for specific condition patterns // like the following: if ( typeof define == 'function' && typeof define.amd == 'object' && define.amd ) { define(function() { return esrever; }); } else if (freeExports && !freeExports.nodeType) { if (freeModule) { // in Node.js, io.js, or RingoJS v0.8.0+ freeModule.exports = esrever; } else { // in Narwhal or RingoJS v0.7.0- for (var key in esrever) { esrever.hasOwnProperty(key) && (freeExports[key] = esrever[key]); } } } else { // in Rhino or a web browser root.esrever = esrever; } }(this)); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],36:[function(require,module,exports){ (function (process){ 'use strict'; /** * Copyright (c) 2013-present, Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @typechecks */ var emptyFunction = require