<commit_before>module('lively.ide.SystemBrowserNodes').requires('lively.ide.BrowserFramework').toRun(function() {

lively.ide.BrowserNode.subclass('lively.ide.SourceControlNode', {

    documentation: 'The root node of the SystemBrowser. Represents a URL',

    initialize: function($super, target, browser, parent) {
        $super(target, browser, parent);
        this.allFiles = [];
        this.subNamespacePaths = [];
    },

    addFile: function(file) { this.allFiles.push(file) },

    removeFile: function(file) { this.allFiles = this.allFiles.without(file) },

    locationChanged: function() {
        var url = this.browser.getTargetURL(),
            subElements,
            fileURLs,
            dirs;
        
        this.browser.selectNothing();
        
        try {
            subElements = new WebResource(url).beSync().getSubElements();
            fileURLs = subElements.subDocuments.collect(function(ea) { return ea.getURL(); });
            this.allFiles = this.target.selectUniqueLKFileNamesFrom(fileURLs);
        } catch(e) {
            // can happen when a restored browser from a world that has been moved
            // uses a now incorrect relative URL
            this.statusMessage('Cannot get files for code browser with url '
                + url + ' error ' + e, Color.red, 6);
            this.allFiles = [];
        }
        
        var isUrlRootOfRepository = this.browser.codeBaseUrlString() == String(url);
        this.parentNamespacePath = isUrlRootOfRepository ? null : url.withFilename('../');
        
        dirs = subElements.subCollections || [];
        this.subNamespacePaths = dirs.collect(function(ea) { return ea.getURL(); });
    },



    childNodes: function() {
        // js files + OMeta files (.txt)
        //if (this._childNodes) return this._childNodes; // optimization
        var moduleNodes = [],
            nsNodes = [],
            srcDb = this.target,
            b = this.browser;

        // modules (files)
        if (this.allFiles.length == 0) this.locationChanged();
        if (!this.subNamespacePaths) this.subNamespacePaths = [];
        for (var i = 0; i < this.allFiles.length; i++) {
            var fn = this.allFiles[i];
            if (fn.endsWith('.js')) {
                moduleNodes.push(new lively.ide.CompleteFileFragmentNode(
                    srcDb.rootFragmentForModule(fn), b, this, fn));
            } else if (fn.endsWith('.ometa')) {
                moduleNodes.push(new lively.ide.CompleteOmetaFragmentNode(
                    srcDb.rootFragmentForModule(fn), b, this, fn));
            } else if (fn.endsWith('.css')) {
                moduleNodes.push(new lively.ide.CompleteCSSFragmentNode(
                    srcDb.rootFragmentForModule(fn), b, this, fn));
            } else if (fn.match(/\.(tm)?snippets$/)) {
                moduleNodes.push(new lively.ide.CompleteSnippet(
                    srcDb.rootFragmentForModule(fn), b, this, fn));
            }
        };
        moduleNodes = moduleNodes.sortBy(function(node) { return node.asString().toLowerCase() });

        // namespace nodes
        for (i = 0; i < this.subNamespacePaths.length; i++) {
            var relativePath = this.subNamespacePaths[i];
            nsNodes.push(new lively.ide.NamespaceNode(relativePath, b, this));
        }
        nsNodes = nsNodes.sortBy(function(node) { return node.asString() });
        if (this.parentNamespacePath) {
            nsNodes.push(new lively.ide.NamespaceNode(this.parentNamespacePath, b, this));
        }

        // add local changes
        var nodes = nsNodes;
        nodes = nodes.concat(moduleNodes);

        this._childNodes = nodes;

        return nodes;
    }
});

lively.ide.BrowserNode.subclass('lively.ide.FileFragmentNode', {

    doNotSerialize: ['savedSource'],

    toString: function() {
        return this.constructor.name + '<' + this.getName() + '>'
    },

    getName: function() { // not unique!
        return this.target.name || this.sourceString().truncate(22).replace('\n', '') + '(' + this.type + ')';
    },

    sourceString: function() {
        if (!this.target)
            return 'entity not loaded';
        this.savedSource = this.target.getSourceCode();
        return this.savedSource;
    },

    asString: function() {
        var name = this.getName();
        if (this.showLines()) name += ' (' + this.target.startLine() + '-' + this.target.stopLine() + ')';
        return name;
    },

    showLines: function() {
        return this.browser.showLines;
    },

    saveSource: function($super, newSource, sourceControl) {
        lively.ide.enableDebugFileParsing(this.browser.debugMode);
        this.target.putSourceCode(newSource);
        this.savedSource = this.target.getSourceCode(); // assume that users sees newSource after that
        lively.ide.enableDebugFileParsing(false);
        return true;
    },

    menuSpec: function($super) {
        var spec = $super(), node = this;

        spec.push(['add sibling below', function() {
            node.browser.ensureSourceNotAccidentlyDeleted(function() {
                var world = lively.morphic.World.current();
                world.prompt('Enter source code', function(input) {
                    if (input == null) return;
                    node.target.addSibling(input);
                    node.browser.allChanged();
                });
            });
        }]);

        spec.push(['remove', function() {
            node.browser.ensureSourceNotAccidentlyDeleted(function() {
                node.target.remove();
                node.browser.allChanged();
            });
        }]);

<commit_msg>SCB: cleanup after removal via menu, too<commit_after>module('lively.ide.SystemBrowserNodes').requires('lively.ide.BrowserFramework').toRun(function() {

lively.ide.BrowserNode.subclass('lively.ide.SourceControlNode', {

    documentation: 'The root node of the SystemBrowser. Represents a URL',

    initialize: function($super, target, browser, parent) {
        $super(target, browser, parent);
        this.allFiles = [];
        this.subNamespacePaths = [];
    },

    addFile: function(file) { this.allFiles.push(file) },

    removeFile: function(file) { this.allFiles = this.allFiles.without(file) },

    locationChanged: function() {
        var url = this.browser.getTargetURL(),
            subElements,
            fileURLs,
            dirs;
        
        this.browser.selectNothing();
        
        try {
            subElements = new WebResource(url).beSync().getSubElements();
            fileURLs = subElements.subDocuments.collect(function(ea) { return ea.getURL(); });
            this.allFiles = this.target.selectUniqueLKFileNamesFrom(fileURLs);
        } catch(e) {
            // can happen when a restored browser from a world that has been moved
            // uses a now incorrect relative URL
            this.statusMessage('Cannot get files for code browser with url '
                + url + ' error ' + e, Color.red, 6);
            this.allFiles = [];
        }
        
        var isUrlRootOfRepository = this.browser.codeBaseUrlString() == String(url);
        this.parentNamespacePath = isUrlRootOfRepository ? null : url.withFilename('../');
        
        dirs = subElements.subCollections || [];
        this.subNamespacePaths = dirs.collect(function(ea) { return ea.getURL(); });
    },



    childNodes: function() {
        // js files + OMeta files (.txt)
        //if (this._childNodes) return this._childNodes; // optimization
        var moduleNodes = [],
            nsNodes = [],
            srcDb = this.target,
            b = this.browser;

        // modules (files)
        if (this.allFiles.length == 0) this.locationChanged();
        if (!this.subNamespacePaths) this.subNamespacePaths = [];
        for (var i = 0; i < this.allFiles.length; i++) {
            var fn = this.allFiles[i];
            if (fn.endsWith('.js')) {
                moduleNodes.push(new lively.ide.CompleteFileFragmentNode(
                    srcDb.rootFragmentForModule(fn), b, this, fn));
            } else if (fn.endsWith('.ometa')) {
                moduleNodes.push(new lively.ide.CompleteOmetaFragmentNode(
                    srcDb.rootFragmentForModule(fn), b, this, fn));
            } else if (fn.endsWith('.css')) {
                moduleNodes.push(new lively.ide.CompleteCSSFragmentNode(
                    srcDb.rootFragmentForModule(fn), b, this, fn));
            } else if (fn.match(/\.(tm)?snippets$/)) {
                moduleNodes.push(new lively.ide.CompleteSnippet(
                    srcDb.rootFragmentForModule(fn), b, this, fn));
            }
        };
        moduleNodes = moduleNodes.sortBy(function(node) { return node.asString().toLowerCase() });

        // namespace nodes
        for (i = 0; i < this.subNamespacePaths.length; i++) {
            var relativePath = this.subNamespacePaths[i];
            nsNodes.push(new lively.ide.NamespaceNode(relativePath, b, this));
        }
        nsNodes = nsNodes.sortBy(function(node) { return node.asString() });
        if (this.parentNamespacePath) {
            nsNodes.push(new lively.ide.NamespaceNode(this.parentNamespacePath, b, this));
        }

        // add local changes
        var nodes = nsNodes;
        nodes = nodes.concat(moduleNodes);

        this._childNodes = nodes;

        return nodes;
    }
});

lively.ide.BrowserNode.subclass('lively.ide.FileFragmentNode', {

    doNotSerialize: ['savedSource'],

    toString: function() {
        return this.constructor.name + '<' + this.getName() + '>'
    },

    getName: function() { // not unique!
        return this.target.name || this.sourceString().truncate(22).replace('\n', '') + '(' + this.type + ')';
    },

    sourceString: function() {
        if (!this.target)
            return 'entity not loaded';
        this.savedSource = this.target.getSourceCode();
        return this.savedSource;
    },

    asString: function() {
        var name = this.getName();
        if (this.showLines()) name += ' (' + this.target.startLine() + '-' + this.target.stopLine() + ')';
        return name;
    },

    showLines: function() {
        return this.browser.showLines;
    },

    saveSource: function($super, newSource, sourceControl) {
        lively.ide.enableDebugFileParsing(this.browser.debugMode);
        this.target.putSourceCode(newSource);
        this.savedSource = this.target.getSourceCode(); // assume that users sees newSource after that
        lively.ide.enableDebugFileParsing(false);
        return true;
    },

    menuSpec: function($super) {
        var spec = $super(), node = this;

        spec.push(['add sibling below', function() {
            node.browser.ensureSourceNotAccidentlyDeleted(function() {
                var world = lively.morphic.World.current();
                world.prompt('Enter source code', function(input) {
                    if (input == null) return;
                    node.target.addSibling(input);
                    node.browser.allChanged();
                });
            });
        }]);

        spec.push(['remove', function() {
            node.browser.ensureSourceNotAccidentlyDeleted(function() {
                var prevDefinitions = node.getDefinitions();
                node.target.remove();
                node.cleanupSource(prevDefinitions, []);
                node.browser.allChanged();
            });
        }]);


{'fraction_non_alphanumeric': 0.1327981851496379, 'fraction_numerical': 0.0010470290550562778, 'mean_word_length': 2.115520521880946, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '805736', 'n_tokens_mistral': 3192, 'n_tokens_neox': 3071, 'n_words': 614}