UNPKG

atom-nuclide

Version:

A unified developer experience for web and mobile development, built as a suite of features on top of Atom to provide hackability and the support of an active community.

194 lines (172 loc) 7.65 kB
Object.defineProperty(exports, '__esModule', { value: true }); /* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. */ var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); 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; }; })(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var _atom2; function _atom() { return _atom2 = require('atom'); } var _reactForAtom2; function _reactForAtom() { return _reactForAtom2 = require('react-for-atom'); } /** * The DiffViewEditor manages the lifecycle of the two editors used in the diff view, * and controls its rendering of highlights and offsets. */ var DiffViewEditor = (function () { function DiffViewEditor(editorElement) { _classCallCheck(this, DiffViewEditor); this._editorElement = editorElement; this._editor = editorElement.getModel(); this._highlightMarkers = []; this._offsetMarkers = []; this._uiElementsMarkers = []; } _createClass(DiffViewEditor, [{ key: 'setUIElements', value: function setUIElements(elements) { var _this = this; for (var marker of this._uiElementsMarkers) { marker.destroy(); } this._uiElementsMarkers = elements.map(function (element) { var node = element.node; var bufferRow = element.bufferRow; // TODO(most): OMG, this mutates React props for the created component!! Object.assign(node.props.helpers, { scrollToRow: _this._scrollToRow.bind(_this) }); var container = document.createElement('div'); (_reactForAtom2 || _reactForAtom()).ReactDOM.render(node, container); // an overlay marker at a buffer range with row x renders under row x + 1 // so, use range at bufferRow - 1 to actually display at bufferRow var range = [[bufferRow - 1, 0], [bufferRow - 1, 0]]; var marker = _this._editor.markBufferRange(range, { invalidate: 'never' }); _this._editor.decorateMarker(marker, { type: 'block', item: container, position: 'after' }); return marker; }); } }, { key: 'scrollToScreenLine', value: function scrollToScreenLine(screenLine) { this._editor.scrollToScreenPosition( // Markers are ordered in ascending order by line number. [screenLine, 0], { center: true }); } }, { key: 'setFileContents', value: function setFileContents(filePath, contents) { var buffer = this._editor.getBuffer(); if (buffer.getText() !== contents) { // Applies only to the compared read only text buffer. // Hence, it's safe and performant to use `setText` because the cursor position is hidden. buffer.setText(contents); } var grammar = atom.grammars.selectGrammar(filePath, contents); this._editor.setGrammar(grammar); } }, { key: 'getModel', value: function getModel() { return this._editor; } }, { key: 'getText', value: function getText() { return this._editor.getText(); } /** * @param addedLines An array of buffer line numbers that should be highlighted as added. * @param removedLines An array of buffer line numbers that should be highlighted as removed. */ }, { key: 'setHighlightedLines', value: function setHighlightedLines() { var _this2 = this; var addedLines = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; var removedLines = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1]; for (var marker of this._highlightMarkers) { marker.destroy(); } this._highlightMarkers = addedLines.map(function (lineNumber) { return _this2._createLineMarker(lineNumber, 'insert'); }).concat(removedLines.map(function (lineNumber) { return _this2._createLineMarker(lineNumber, 'delete'); })); } /** * @param lineNumber A buffer line number to be highlighted. * @param type The type of highlight to be applied to the line. * Could be a value of: ['insert', 'delete']. */ }, { key: '_createLineMarker', value: function _createLineMarker(lineNumber, type) { var range = new (_atom2 || _atom()).Range([lineNumber, 0], [lineNumber + 1, 0]); var marker = this._editor.markBufferRange(range, { invalidate: 'never' }); this._editor.decorateMarker(marker, { type: 'highlight', 'class': 'diff-view-' + type }); return marker; } }, { key: 'setOffsets', value: function setOffsets(lineOffsets) { this._offsetMarkers.forEach(function (marker) { return marker.destroy(); }); this._offsetMarkers = []; var lineHeight = this._editor.getLineHeightInPixels(); for (var _ref3 of lineOffsets) { var _ref2 = _slicedToArray(_ref3, 2); var lineNumber = _ref2[0]; var offsetLines = _ref2[1]; var blockItem = document.createElement('div'); blockItem.style.minHeight = offsetLines * lineHeight + 'px'; blockItem.className = 'nuclide-diff-view-block-offset'; var marker = this._editor.markBufferPosition([lineNumber, 0], { invalidate: 'never' }); // The position should be `after` if the offset is at the end of the file. var position = lineNumber >= this._editor.getLineCount() - 1 ? 'after' : 'before'; this._editor.decorateMarker(marker, { type: 'block', item: blockItem, position: position }); this._offsetMarkers.push(marker); } } }, { key: 'destroy', value: function destroy() { this._highlightMarkers.forEach(function (marker) { return marker.destroy(); }); this._highlightMarkers = []; this._offsetMarkers.forEach(function (marker) { return marker.destroy(); }); this._offsetMarkers = []; this._uiElementsMarkers.forEach(function (marker) { return marker.destroy(); }); this._uiElementsMarkers = []; this._editor.destroy(); } }, { key: '_scrollToRow', value: function _scrollToRow(row) { this._editor.scrollToBufferPosition([row, 0], { center: true }); } }]); return DiffViewEditor; })(); exports.default = DiffViewEditor; module.exports = exports.default;