alm
Version:
The best IDE for TypeScript
288 lines (287 loc) • 13.4 kB
JavaScript
;
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ui = require("../../ui");
var csx = require("../../base/csx");
var React = require("react");
var socketClient_1 = require("../../../socket/socketClient");
var commands = require("../../commands/commands");
var utils = require("../../../common/utils");
var styles = require("../../styles/styles");
var typeIcon = require("../../components/typeIcon");
var gls = require("../../base/gls");
var typestyle = require("typestyle");
var markdown_1 = require("../../markdown/markdown");
var styles_1 = require("../../styles/styles");
var DocumentationViewStyles;
(function (DocumentationViewStyles) {
DocumentationViewStyles.header = typestyle.style({
cursor: 'pointer',
$nest: {
'&:hover': {
textDecoration: 'underline'
}
}
});
DocumentationViewStyles.folderName = typestyle.style({
padding: "2px",
fontSize: '.5em',
'-webkit-user-select': 'none',
maxWidth: '200px', overflow: 'hidden', textOverflow: 'ellipsis'
});
})(DocumentationViewStyles = exports.DocumentationViewStyles || (exports.DocumentationViewStyles = {}));
var DocumentationView = /** @class */ (function (_super) {
__extends(DocumentationView, _super);
function DocumentationView(props) {
var _this = _super.call(this, props) || this;
_this.handleNodeClick = function (node) {
commands.doOpenOrFocusFile.emit({
filePath: node.location.filePath,
position: node.location.position
});
};
_this.handleRootSelected = function (node) {
_this.setState({ selected: node });
setTimeout(function () { return _this.filter(); });
};
_this.handleKey = function (e) {
var unicode = e.charCode;
if (String.fromCharCode(unicode).toLowerCase() === "r") {
_this.loadData();
}
};
_this.loadData = function () {
socketClient_1.server.getTopLevelModuleNames({}).then(function (res) {
_this.setState({ files: res.files, selected: null });
_this.filter();
});
};
_this.filter = function () {
var filter = (_this.state.filter || '').toLowerCase();
if (!filter) {
var filtered_1 = _this.state.files;
var selected_1 = _this.state.selected && filtered_1.find(function (f) { return f.name == _this.state.selected.name; });
_this.setState({ filtered: filtered_1, selected: selected_1, selectedDoesNotMatchFilter: false });
return;
}
/**
* Does the name match or does some subItem name match
*/
var doesNameMatchRecursive = function (type) {
return type.name.toLowerCase().indexOf(filter) !== -1 || type.subItems.some(function (t) { return doesNameMatchRecursive(t); });
};
/**
* Only leaves in the subItems that match
*/
var mapChildrenRecursive = function (item) {
var subItems = item.subItems
.filter(doesNameMatchRecursive)
.map(mapChildrenRecursive);
var result = {
name: item.name,
icon: item.icon,
comment: item.comment,
location: item.location,
subItems: subItems,
};
return result;
};
var filtered = _this.state.files
.filter(function (f) {
return doesNameMatchRecursive(f);
})
.map(mapChildrenRecursive);
_this.setState({ filtered: filtered });
// Also filter inside the selected if possible
var selected = _this.state.selected && filtered.find(function (f) { return f.name == _this.state.selected.name; });
if (_this.state.selected && !selected) {
_this.setState({ selectedDoesNotMatchFilter: true });
}
else {
_this.setState({ selected: selected, selectedDoesNotMatchFilter: false });
}
};
/**
* TAB implementation
*/
_this.resize = function () {
// Not needed
};
_this.focus = function () {
_this.refs.root.focus();
};
_this.save = function () {
};
_this.close = function () {
};
_this.gotoPosition = function (position) {
};
_this.search = {
doSearch: function (options) {
_this.setState({ filter: options.query });
_this.filter();
},
hideSearch: function () {
_this.setState({ filter: '' });
_this.filter();
},
findNext: function (options) {
},
findPrevious: function (options) {
},
replaceNext: function (_a) {
var newText = _a.newText;
},
replacePrevious: function (_a) {
var newText = _a.newText;
},
replaceAll: function (_a) {
var newText = _a.newText;
}
};
_this.filePath = utils.getFilePathFromUrl(props.url);
_this.state = {
filtered: [],
files: [],
selected: null,
};
return _this;
}
DocumentationView.prototype.componentDidMount = function () {
var _this = this;
/**
* Initial load + load on project change
*/
this.loadData();
this.disposible.add(socketClient_1.cast.activeProjectFilePathsUpdated.on(function () {
_this.loadData();
}));
/**
* If a file is selected and it gets edited, reload the file module information
*/
var isFilePathOfSignificance = function (filePath) { return !!_this.state.selected && _this.state.selected.location.filePath === filePath; };
var reloadSelectedDebounced = utils.debounce(function (filePath) {
if (!isFilePathOfSignificance(filePath))
return;
socketClient_1.server.getUpdatedModuleInformation({
filePath: filePath
}).then(function (res) {
if (!isFilePathOfSignificance(filePath))
return;
var files = _this.state.files.map(function (f) { return (f.location.filePath === filePath) ? res : f; });
_this.setState({ files: files, selected: res });
_this.filter();
});
}, 3000);
this.disposible.add(commands.fileContentsChanged.on(function (res) {
if (!isFilePathOfSignificance(res.filePath))
return;
reloadSelectedDebounced(res.filePath);
}));
/**
* Handle focus to inform tab container
*/
var focused = function () {
_this.props.onFocused();
};
this.refs.root.addEventListener('focus', focused);
this.disposible.add({
dispose: function () {
_this.refs.root.removeEventListener('focus', focused);
}
});
// Listen to tab events
var api = this.props.api;
this.disposible.add(api.resize.on(this.resize));
this.disposible.add(api.focus.on(this.focus));
this.disposible.add(api.save.on(this.save));
this.disposible.add(api.close.on(this.close));
this.disposible.add(api.gotoPosition.on(this.gotoPosition));
// Listen to search tab events
this.disposible.add(api.search.doSearch.on(this.search.doSearch));
this.disposible.add(api.search.hideSearch.on(this.search.hideSearch));
this.disposible.add(api.search.findNext.on(this.search.findNext));
this.disposible.add(api.search.findPrevious.on(this.search.findPrevious));
this.disposible.add(api.search.replaceNext.on(this.search.replaceNext));
this.disposible.add(api.search.replacePrevious.on(this.search.replacePrevious));
this.disposible.add(api.search.replaceAll.on(this.search.replaceAll));
};
DocumentationView.prototype.render = function () {
return (React.createElement("div", { ref: "root", tabIndex: 0, style: csx.extend(csx.vertical, csx.flex, csx.newLayerParent, styles.someChildWillScroll, { color: styles.textColor }), onKeyPress: this.handleKey },
React.createElement("div", { style: { overflow: 'hidden', padding: '10px 0px 10px 10px', display: 'flex' } },
React.createElement(gls.FlexHorizontal, { style: {} },
React.createElement(gls.Content, { style: { width: '200px', overflow: 'auto' } },
React.createElement(typeIcon.SectionHeader, { text: "Files" }),
React.createElement(gls.SmallVerticalSpace, null),
this.renderFiles()),
React.createElement(gls.FlexVertical, { style: { marginLeft: '5px', overflow: 'auto' } },
this.state.selected && this.state.selectedDoesNotMatchFilter &&
React.createElement(gls.Content, { style: { backgroundColor: '#111', padding: '5px' } }, "Note: Nothing in the selected module matches the filter, so showing it all"),
this.state.selected
? this.renderSelectedNode()
: 'Select a module from the left to view its documentation 🌹',
React.createElement("div", { style: { marginTop: '10px', marginRight: '10px' } },
React.createElement("hr", null),
React.createElement(typeIcon.TypeIconLegend, null)))))));
};
DocumentationView.prototype.renderFiles = function () {
var _this = this;
/** For two items in different file paths we render the folder name in between */
var toRender = [];
var lastKnownFolder = '';
this.state.filtered.forEach(function (type) {
var folder = utils.getDirectory(type.name);
if (folder !== lastKnownFolder) {
toRender.push({
folder: folder
});
lastKnownFolder = folder;
}
toRender.push({
type: type
});
});
return toRender.map(function (item, i) {
if (item.type) {
var file_1 = item.type;
var name_1 = utils.getFileName(file_1.name);
var backgroundColor = _this.state.selected && _this.state.selected.name === file_1.name
? styles_1.blackHighlightColor
: 'transparent';
return (React.createElement("div", { title: file_1.name, key: i, style: { cursor: 'pointer', backgroundColor: backgroundColor, paddingTop: '2px', paddingBottom: '2px', paddingLeft: '2px' }, onClick: function () { return _this.handleRootSelected(file_1); } },
React.createElement(typeIcon.DocumentedTypeHeader, { name: name_1, icon: file_1.icon })));
}
else {
var folder = item.folder;
return (React.createElement("div", { title: folder, key: i, className: DocumentationViewStyles.folderName }, folder));
}
});
};
DocumentationView.prototype.renderSelectedNode = function () {
var node = this.state.selected;
return this.renderNode(node);
};
DocumentationView.prototype.renderNode = function (node, i) {
var _this = this;
if (i === void 0) { i = 0; }
return (React.createElement("div", { key: i, style: { paddingTop: '5px' } },
React.createElement(gls.InlineBlock, { className: DocumentationViewStyles.header, onClick: function () { return _this.handleNodeClick(node); } },
React.createElement(typeIcon.DocumentedTypeHeader, { name: node.name, icon: node.icon })),
node.comment &&
React.createElement("div", { style: { padding: '5px', backgroundColor: styles_1.blackHighlightColor } },
React.createElement(markdown_1.MarkDown, { markdown: node.comment })),
node.subItems && !!node.subItems.length &&
React.createElement("div", { style: { border: '1px solid grey', marginTop: '5px', padding: '5px' } }, node.subItems.map(function (n, i) { return _this.renderNode(n, i); }))));
};
return DocumentationView;
}(ui.BaseComponent));
exports.DocumentationView = DocumentationView;