<commit_before>
/**
    A collection of gui.Field objects
*/
gui.Form = function(conf) {
    conf = conf || {};
    this.fields = {};
    
    if(conf.fields) {
        if(!_.isArray(conf.fields))
            throw new TypeError('Expected fields to be a list of gui.Field objects');
    
        // Build a name -> <field object> map    
        for(var i=0,f; f=conf.fields[i]; i++) {
            if(!f.name) 
                throw new Error('Field must have a name');
            this.fields[f.name] = f;
        }
    }
};
_.extend(gui.Form.prototype, Backbone.Events, {    
    getValues: function() {
        var values = {};
        _.each(this.fields, function(f) {
            values[f.name] = f.getValue() || '';
        });
        return values;        
    },
    setValues: function(values) {
        _.each(this.fields, function(f, key) {
            f.setValue(f.interpret(values[key]));
            f.render();
        });        
    }
});
gui.Form.extend = Backbone.View.extend;

function pasteHtmlAtCaret(html) {
    var sel, range;
    if (window.getSelection) {
        // IE9 and non-IE
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();

            // Range.createContextualFragment() would be useful here but is
            // non-standard and not supported in all browsers (IE9, for one)
            var el = document.createElement("div");
            el.innerHTML = html;
            var frag = document.createDocumentFragment(), node, lastNode;
            while ( (node = el.firstChild) ) {
                lastNode = frag.appendChild(node);
            }
            range.insertNode(frag);

            // Preserve the selection
            if (lastNode) {
                range = range.cloneRange();
                range.setStartAfter(lastNode);
                range.collapse(true);
                sel.removeAllRanges();
                sel.addRange(range);
            }
        }
    } else if (document.selection && document.selection.type != "Control") {
        // IE < 9
        document.selection.createRange().pasteHTML(html);
    }
}


gui.Field = {
    /**
    A field is an input point for the user. Its value is stored in $(this.el).data('value').
    The stored value is always in a json-transportable format. eg "test", 123, {a:1, b:2}, 
    but not a <object Date>.
        
    Example "form":
    -------------------------
    var SignupView = Backbone.View.extend({
        render: function() {
            // Create a form
            this.form = new gui.Form({fields:
                new gui.TextField({name: 'title', value: 'I am a value'}),
                new gui.TextArea({name: 'description'})
            });
            
            // Change the value of the title
            var fields = this.form.fields;
            fields.title.setValue('The new value');
            
            // ..or set many values from a dict
            this.form.setValues({
                title: 'Test title',
                description: 'Bla bla bla'
            });
          
            // Log all current values
            console.log(this.form.getValues());
        },
    });
    
    
    Different versions describing the same value:
    - A pretty version. 
    - The value deserialized into javascript land
    - The value serialized into something that can be 
      transported (as json in most cases)
    
    Rendering the value
    - format and shove string into a <div..></div>
    - The value could deserialize into a Collection of Models, which
      is fed to a view, which in turn renders a list of stuff.
    
    setValue/getValue:
    - Implement as you like, as log as the stored value is json serializable.
    - setValue and getValue only deal with the json transportable 
      format. (eg a js Date object is never returned from a .getValue())
    - setValue does not trigger an implicit re-render.
    
    interpret(v):
    - Accepts a string (or other types?) and returns an interpreted value 
      in its trasportable format.


    nodeField.getValue()
    >>> ['1234', '38272']
    dateField.setFormat('epoch');
    dateField.getValue()
    >>> 1338887000000
    dateField.setFormat('YYYY-MM-DD');
    dateField.getValue()
    >>> '2012-06-05'
    */    
    initialize: function(config) {
        config = config || {};
        this.name = config.name || '';
        if(config.value !== undefined) {
            this.setValue(config.value);
        }
    },
    interpret: function(value) {
        if(value === '') 
            return undefined;
        return value;
    },    
    setValue: function(value, options) {
        options = options || {};
        var old = $(this.el).data('value');
        if(old !== value) {
            if(value === undefined)
                $(this.el).removeData('value', value);
            else 
                $(this.el).data('value', value);
            if(!options.silent)
                this.trigger('change', {field: this, value: value});
        }
    },
    unsetValue: function() {
        var old = this.data('value');
        if(old !== undefined) {
            $(this.el).removeData('value');
            if(!options.silent)
                this.trigger('change', {field: this, value: value});            
        }        
    },
    getValue: function() {      
        return $(this.el).data('value');
    }<commit_msg>Fields now triggers a DOM bubbling event "fieldchange" (in addition to the view object's existing "change" event)<commit_after>
/**
    A collection of gui.Field objects
*/
gui.Form = function(conf) {
    conf = conf || {};
    this.fields = {};
    
    if(conf.fields) {
        if(!_.isArray(conf.fields))
            throw new TypeError('Expected fields to be a list of gui.Field objects');
    
        // Build a name -> <field object> map    
        for(var i=0,f; f=conf.fields[i]; i++) {
            if(!f.name) 
                throw new Error('Field must have a name');
            this.fields[f.name] = f;
        }
    }
};
_.extend(gui.Form.prototype, Backbone.Events, {    
    getValues: function() {
        var values = {};
        _.each(this.fields, function(f) {
            values[f.name] = f.getValue() || '';
        });
        return values;        
    },
    setValues: function(values) {
        _.each(this.fields, function(f, key) {
            f.setValue(f.interpret(values[key]));
            f.render();
        });        
    }
});
gui.Form.extend = Backbone.View.extend;

function pasteHtmlAtCaret(html) {
    var sel, range;
    if (window.getSelection) {
        // IE9 and non-IE
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();

            // Range.createContextualFragment() would be useful here but is
            // non-standard and not supported in all browsers (IE9, for one)
            var el = document.createElement("div");
            el.innerHTML = html;
            var frag = document.createDocumentFragment(), node, lastNode;
            while ( (node = el.firstChild) ) {
                lastNode = frag.appendChild(node);
            }
            range.insertNode(frag);

            // Preserve the selection
            if (lastNode) {
                range = range.cloneRange();
                range.setStartAfter(lastNode);
                range.collapse(true);
                sel.removeAllRanges();
                sel.addRange(range);
            }
        }
    } else if (document.selection && document.selection.type != "Control") {
        // IE < 9
        document.selection.createRange().pasteHTML(html);
    }
}


gui.Field = {
    /**
    A field is an input point for the user. Its value is stored in $(this.el).data('value').
    The stored value is always in a json-transportable format. eg "test", 123, {a:1, b:2}, 
    but not a <object Date>.
        
    Example "form":
    -------------------------
    var SignupView = Backbone.View.extend({
        render: function() {
            // Create a form
            this.form = new gui.Form({fields:
                new gui.TextField({name: 'title', value: 'I am a value'}),
                new gui.TextArea({name: 'description'})
            });
            
            // Change the value of the title
            var fields = this.form.fields;
            fields.title.setValue('The new value');
            
            // ..or set many values from a dict
            this.form.setValues({
                title: 'Test title',
                description: 'Bla bla bla'
            });
          
            // Log all current values
            console.log(this.form.getValues());
        },
    });
    
    
    Different versions describing the same value:
    - A pretty version. 
    - The value deserialized into javascript land
    - The value serialized into something that can be 
      transported (as json in most cases)
    
    Rendering the value
    - format and shove string into a <div..></div>
    - The value could deserialize into a Collection of Models, which
      is fed to a view, which in turn renders a list of stuff.
    
    setValue/getValue:
    - Implement as you like, as log as the stored value is json serializable.
    - setValue and getValue only deal with the json transportable 
      format. (eg a js Date object is never returned from a .getValue())
    - setValue does not trigger an implicit re-render.
    
    interpret(v):
    - Accepts a string (or other types?) and returns an interpreted value 
      in its trasportable format.


    nodeField.getValue()
    >>> ['1234', '38272']
    dateField.setFormat('epoch');
    dateField.getValue()
    >>> 1338887000000
    dateField.setFormat('YYYY-MM-DD');
    dateField.getValue()
    >>> '2012-06-05'
    */    
    initialize: function(config) {
        config = config || {};
        this.name = config.name || '';
        if(config.value !== undefined) {
            this.setValue(config.value);
        }
    },
    interpret: function(value) {
        if(value === '') 
            return undefined;
        return value;
    },    
    setValue: function(value, options) {
        options = options || {};
        var old = $(this.el).data('value');
        if(old !== value) {
            if(value === undefined)
                $(this.el).removeData('value', value);
            else 
                $(this.el).data('value', value);
            if(!options.silent) {
                this.trigger('change', {field: this, value: value});
                this.$el.trigger('fieldchange', {field: this, value: value, name: this.name})
            }
        }
    },
    unsetValue: function() {
        var old = this.data('value');
        if(old !== undefined) {
            $(this.el).removeData('value');
            if(!options.silent) {
                this.trigger('change', {field: this, value: value});            
                this.$el.trigger('fieldchange', {field: this, value: value, name: this.name})
            }
        }
    },
    getValue: function() {      
        return $(this.el).data('value');
    }
{'fraction_non_alphanumeric': 0.12975809320526502, 'fraction_numerical': 0.007114905727499111, 'mean_word_length': 1.6895479550346808, 'pattern_counts': {'":': 2, '<': 13, '<?xml version=': 0, '>': 31, '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': '3977520', 'n_tokens_mistral': 3151, 'n_tokens_neox': 3036, 'n_words': 854}