Modules (181)

FileTreeView

Description

This is the view layer (template) for the file tree in the sidebar. It takes a FileTreeViewModel and renders it to the given element using React. User actions are signaled via an ActionCreator (in the Flux sense).

Dependencies

Variables

Private

_extensions

Type
Immutable.Map
Private
    var _extensions = Immutable.Map();

    // Constants

    // Time range from first click to second click to invoke renaming.
    var CLICK_RENAME_MINIMUM  = 500,
        RIGHT_MOUSE_BUTTON    = 2,
        LEFT_MOUSE_BUTTON     = 0;

    var INDENTATION_WIDTH     = 10;
Private

contextSettable

Private
    var contextSettable = {
Private

directoryRenameInput

Private
    var directoryRenameInput = React.createFactory(React.createClass({
        mixins: [renameBehavior],

extendable

Mixin for components that support the "icons" and "addClass" extension points. fileNode and directoryNode support this.

    var extendable = {
Private

fileNode

Private
    var fileNode = React.createFactory(React.createClass({
        mixins: [contextSettable, pathComputer, extendable],
Private

fileRenameInput

Private
    var fileRenameInput = React.createFactory(React.createClass({
        mixins: [renameBehavior],

fileSelectionBox

Displays the absolutely positioned box for the selection or context in the file tree. Its position is determined by passed-in info about the scroller in which the tree resides and the top of the selected node (as reported by the node itself).

Props:

  • selectionViewInfo: Immutable.Map with width, scrollTop, scrollLeft and offsetTop for the tree container
  • visible: should this be visible now
  • selectedClassName: class name applied to the element that is selected
    var fileSelectionBox = React.createFactory(React.createClass({
Private

fileTreeView

Private
    var fileTreeView = React.createFactory(React.createClass({

pathComputer

Mixin that allows a component to compute the full path to its directory entry.

    var pathComputer = {

renameBehavior

This is a mixin that provides rename input behavior. It is responsible for taking keyboard input and invoking the correct action based on that input.

    var renameBehavior = {

selectionExtension

On Windows and Linux, the selection bar in the tree does not extend over the scroll bar. The selectionExtension sits on top of the scroll bar to make the selection bar appear to span the whole width of the sidebar.

Props:

  • selectionViewInfo: Immutable.Map with width, scrollTop, scrollLeft and offsetTop for the tree container
  • visible: should this be visible now
  • selectedClassName: class name applied to the element that is selected
  • className: class to be applied to the extension element
    var selectionExtension = React.createFactory(React.createClass({

Functions

Private

_addExtension

category string
Category to which the extension is being added
callback function
The extension function itself
    function _addExtension(category, callback) {
        if (!callback || typeof callback !== "function") {
            console.error("Attempt to add FileTreeView", category, "extension without a callback function");
            return;
        }
        var callbackList = _extensions.get(category);
        if (!callbackList) {
            callbackList = Immutable.List();
        }
        callbackList = callbackList.push(callback);
        _extensions = _extensions.set(category, callbackList);
    }
Private

_buildDirsFirstComparator

contents Immutable.Map
The directory's contents
Returns: function(string,string)
Comparator that sorts directories first.
    function _buildDirsFirstComparator(contents) {
        function _dirsFirstCompare(a, b) {
            var aIsFile = FileTreeViewModel.isFile(contents.get(a)),
                bIsFile = FileTreeViewModel.isFile(contents.get(b));

            if (!aIsFile && bIsFile) {
                return -1;
            } else if (aIsFile && !bIsFile) {
                return 1;
            } else {
                return FileUtils.compareFilenames(a, b);
            }
        }
        return _dirsFirstCompare;
    }
Private

_createAlignedIns

depth int
The depth of the current node.
Returns: ReactComponent
The resulting ins.
    function _createAlignedIns(depth) {
        return DOM.ins({
            className: "jstree-icon",
            style: {
                marginLeft: INDENTATION_WIDTH * depth
            }
        });
    }
Private

_createThickness

depth int
The depth of the current node.
Returns: ReactComponent
The resulting div.
    function _createThickness(depth) {
        return DOM.div({
            style: {
                display: "inline-block",
                width: INDENTATION_WIDTH * depth
            }
        });
    }
Private

_getName

fullname string
The complete name of the file (not including the rest of the path)
extension string
The file extension
Returns: string
The fullname without the extension
    function _getName(fullname, extension) {
        return extension !== "" ? fullname.substring(0, fullname.length - extension.length - 1) : fullname;
    }
Private

_measureText

text string
Text to measure
Returns: int
Width to use
    function _measureText(text) {
        var measuringElement = $("<span />", { css : { "position" : "absolute", "top" : "-200px", "left" : "-1000px", "visibility" : "hidden", "white-space": "pre" } }).appendTo("body");
        measuringElement.text("pW" + text);
        var width = measuringElement.width();
        measuringElement.remove();
        return width;
    }
Private

_sortDirectoryContents

contents Immutable.Map
the directory's contents
dirsFirst boolean
true to sort subdirectories first
Returns: Immutable.Map
sorted mapping
    function _sortDirectoryContents(contents, dirsFirst) {
        if (dirsFirst) {
            return contents.keySeq().sort(_buildDirsFirstComparator(contents));
        } else {
            return contents.keySeq().sort(FileUtils.compareFilenames);
        }
    }

    // Forward references to keep JSLint happy.
    var directoryNode, directoryContents;
Public API

addClassesProvider

    function addClassesProvider(callback) {
        _addExtension("addClass", callback);
    }

    // Private API for testing
    exports._sortFormattedDirectory = _sortDirectoryContents;
    exports._fileNode = fileNode;
    exports._directoryNode = directoryNode;
    exports._directoryContents = directoryContents;
    exports._fileTreeView = fileTreeView;

    // Public API
    exports.addIconProvider = addIconProvider;
    exports.addClassesProvider = addClassesProvider;
    exports.render = render;
});
Public API

addIconProvider

    function addIconProvider(callback) {
        _addExtension("icons", callback);
    }
Private

isDefined

value Object
value to test
Returns: boolean
true if value is defined
    function isDefined(value) {
        return value !== undefined;
    }
Public API

render

Renders the file tree to the given element.

element DOMNode,jQuery
Element in which to render this file tree
viewModel FileTreeViewModel
the data container
projectRoot Directory
Directory object from which the fullPath of the project root is extracted
actions ActionCreator
object with methods used to communicate events that originate from the user
forceRender boolean
Run render on the entire tree (useful if an extension has new data that it needs rendered)
platform string
mac, win, linux
    function render(element, viewModel, projectRoot, actions, forceRender, platform) {
        if (!projectRoot) {
            return;
        }

        ReactDOM.render(fileTreeView({
            treeData: viewModel.treeData,
            selectionViewInfo: viewModel.selectionViewInfo,
            sortDirectoriesFirst: viewModel.sortDirectoriesFirst,
            parentPath: projectRoot.fullPath,
            actions: actions,
            extensions: _extensions,
            platform: platform,
            forceRender: forceRender
        }),
              element);
    }