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.

167 lines (132 loc) 7.96 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'); } }; })(); exports.default = createDiagnosticsPanel; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _paneUtils2; function _paneUtils() { return _paneUtils2 = require('./paneUtils'); } var _reactForAtom2; function _reactForAtom() { return _reactForAtom2 = require('react-for-atom'); } var _DiagnosticsPanel2; function _DiagnosticsPanel() { return _DiagnosticsPanel2 = _interopRequireDefault(require('./DiagnosticsPanel')); } var _commonsNodeEvent2; function _commonsNodeEvent() { return _commonsNodeEvent2 = require('../../commons-node/event'); } var _commonsNodeStream2; function _commonsNodeStream() { return _commonsNodeStream2 = require('../../commons-node/stream'); } var _nuclideUiLibBindObservableAsProps2; function _nuclideUiLibBindObservableAsProps() { return _nuclideUiLibBindObservableAsProps2 = require('../../nuclide-ui/lib/bindObservableAsProps'); } var _rxjsBundlesRxUmdMinJs2; function _rxjsBundlesRxUmdMinJs() { return _rxjsBundlesRxUmdMinJs2 = require('rxjs/bundles/Rx.umd.min.js'); } var DEFAULT_TABLE_WIDTH = 600; function createDiagnosticsPanel(diagnostics, initialHeight, initialfilterByActiveTextEditor, disableLinter, onFilterByActiveTextEditorChange) { var item = document.createElement('div'); // A FixedDataTable must specify its own width. We always want it to match that of the bottom // panel. Unfortunately, there is no way to register for resize events on a DOM element: it is // only possible to listen for resize events on a window. (MutationObserver does not help here.) // // As such, we employ a hack inspired by http://stackoverflow.com/a/20888342/396304. // We create an invisible iframe with 100% width, so it will match the width of the panel. We // subscribe to its resize events and use that as a proxy for the panel being resized and update // the width of the FixedDataTable accordingly. var iframe = window.document.createElement('iframe'); iframe.style.width = '100%'; iframe.style.height = '1px'; iframe.style.position = 'absolute'; iframe.style.visibility = 'hidden'; iframe.style.border = 'none'; // Both the iframe and the host element for the React component are children of the root element // that serves as the item for the panel. var rootElement = document.createElement('div'); rootElement.className = 'nuclide-diagnostics-ui'; rootElement.appendChild(iframe); rootElement.appendChild(item); var bottomPanel = atom.workspace.addBottomPanel({ item: rootElement }); var warnAboutLinterStream = new (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).BehaviorSubject(false); var setWarnAboutLinter = function setWarnAboutLinter(warn) { warnAboutLinterStream.next(warn); }; var panelVisibilityStream = (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.concat((_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.of(true), (0, (_commonsNodeEvent2 || _commonsNodeEvent()).observableFromSubscribeFunction)(bottomPanel.onDidChangeVisible.bind(bottomPanel))).distinctUntilChanged(); // When the panel becomes visible for the first time, render the component. var subscription = panelVisibilityStream.filter(Boolean).take(1).subscribe(function () { var propsStream = getPropsStream(diagnostics, warnAboutLinterStream, initialHeight, initialfilterByActiveTextEditor, disableLinter, iframe.contentWindow, onFilterByActiveTextEditorChange, function () { bottomPanel.hide(); }).publishReplay(1).refCount(); var Component = (0, (_nuclideUiLibBindObservableAsProps2 || _nuclideUiLibBindObservableAsProps()).bindObservableAsProps)( // A stream that contains the props, but is "muted" when the panel's not visible. (0, (_commonsNodeStream2 || _commonsNodeStream()).toggle)(propsStream, panelVisibilityStream), (_DiagnosticsPanel2 || _DiagnosticsPanel()).default); // $FlowFixMe: `bindObservableAsProps` needs to be typed better. (_reactForAtom2 || _reactForAtom()).ReactDOM.render((_reactForAtom2 || _reactForAtom()).React.createElement(Component, null), item); }); // Currently, destroy() does not appear to be idempotent: // https://github.com/atom/atom/commit/734a79b7ec9f449669e1871871fd0289397f9b60#commitcomment-12631908 bottomPanel.onDidDestroy(function () { subscription.unsubscribe(); (_reactForAtom2 || _reactForAtom()).ReactDOM.unmountComponentAtNode(item); }); return { atomPanel: bottomPanel, setWarnAboutLinter: setWarnAboutLinter }; } function getPropsStream(diagnosticsStream, warnAboutLinterStream, initialHeight, initialfilterByActiveTextEditor, disableLinter, win, onFilterByActiveTextEditorChange, onDismiss) { var activeTextEditorPaths = (0, (_commonsNodeEvent2 || _commonsNodeEvent()).observableFromSubscribeFunction)(atom.workspace.observeActivePaneItem.bind(atom.workspace)).map(function (paneItem) { if (atom.workspace.isTextEditor(paneItem)) { var textEditor = paneItem; return textEditor ? textEditor.getPath() : null; } }).distinctUntilChanged(); var sortedDiagnostics = (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.concat((_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.of([]), diagnosticsStream.map(function (diagnostics) { return diagnostics.slice().sort((_paneUtils2 || _paneUtils()).compareMessagesByFile); })); var filterByActiveTextEditorStream = new (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).BehaviorSubject(initialfilterByActiveTextEditor); var handleFilterByActiveTextEditorChange = function handleFilterByActiveTextEditorChange(filterByActiveTextEditor) { filterByActiveTextEditorStream.next(filterByActiveTextEditor); onFilterByActiveTextEditorChange(filterByActiveTextEditor); }; var widthStream = (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.of(DEFAULT_TABLE_WIDTH).concat((_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.fromEvent(win, 'resize').map(function () { return win.innerWidth; })); // $FlowFixMe: We haven't typed this function with this many args. return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.combineLatest(activeTextEditorPaths, sortedDiagnostics, warnAboutLinterStream, filterByActiveTextEditorStream, widthStream.first().concat(widthStream.skip(1).debounceTime(50))).map(function (_ref) { var _ref2 = _slicedToArray(_ref, 5); var pathToActiveTextEditor = _ref2[0]; var diagnostics = _ref2[1]; var warnAboutLinter = _ref2[2]; var filter = _ref2[3]; var width = _ref2[4]; return { pathToActiveTextEditor: pathToActiveTextEditor, diagnostics: diagnostics, warnAboutLinter: warnAboutLinter, disableLinter: disableLinter, filterByActiveTextEditor: filter, onFilterByActiveTextEditorChange: handleFilterByActiveTextEditorChange, width: width, initialHeight: initialHeight, onDismiss: onDismiss }; }); } module.exports = exports.default;