<commit_before>//  Backbone.vm.js 1.2.0

//  (c) 2013-2014 wangxian, DocumentCloud and Investigative Reporters & Editors
//  Backbone may be freely distributed under the MIT license.
//  For all details and documentation:
//  http://github.com/wangxian/backbone.vm

var $        = require("jquery");
var _        = require("underscore");
var Backbone = require("backbone");

// Cached regex for stripping vm node attributes. space, \r \n
var vmAttrStripper = /\s+/g;

// for:stuct replace && clear template string
// var forTplReplaceStripper = /<!--|-->|\n|'|{|}/g;

// for:struct match dom bind setting string
// var forTplOnStripper = /on:(\w+)=(\w+)/g;


// Handle all struct vm attribute tags,
// eg: html, text, on...
var VMhooks = {
  // VM->DOM, text, html, val, css
  simple: function($node, vmKey, filters) {
    return function(value) {
      _.each(filters, function(filter){ value = filter(value); });
      $node[vmKey](value);
    };
  },

  // DOM->VM, INPUT(except checkbox/radio) on change
  simpleOnChange: function(vm, name) {
    return function() { vm.set(name, this.value); };
  },

  // Show/Hide HTML element if vm item is true or false
  show: function($node) {
    return function(value) { $node[value ? 'show' : 'hide'](); };
  },

  // Remove HTML element if vm item value is true
  remove: function($node) {
    return function(value) { if(!!value) $node.remove(); };
  },

  // VM->DOM Set or clear Element's classList
  className: function($node, vmVal, filters) {
    return function(value, vm) {
      var oldValue;
      _.each(filters, function(filter){ value = filter(value); });
      if(!_.isArray(value)) { oldValue = vm.previous(vmVal);}
      else {
        // 支持从filter定义类切换，如 [之前的类， 新类名称]
        oldValue = value[0];
        value    = value[1];
      }
      if(!!oldValue) { $node.removeClass(oldValue); }
      if(!!value) { $node.addClass(value); }
    };
  },

  // DOM->VM, checkbox on click
  checkboxOnClick: function(vm, name) {
    return function() {
      var checkboxList = vm.get(name);
      var value   = this.value;
      if(! _.isArray(checkboxList)) checkboxList = [];

      if(!this.checked){
        checkboxList = _.filter(checkboxList, function(num){ return num !== value; });
      } else {
        checkboxList.push(value);
      }
      vm.set(name, checkboxList, {silent: true});

      // 修复 Model 触发 change 事件的要求
      var changed;
      (changed = {})[name] = checkboxList;
      vm._vm.changed = changed;

      vm.trigger("change:"+name);
    };
  },

  // VM->DOM, checkbox
  // Handle input checkbox
  checkbox: function(checkboxes) {
    return function(value) {
      if(! _.isArray(value)) return;
      for(var r in checkboxes) {
        if(! _.contains(value, r) ) {
          checkboxes[r].checked = false;
        } else {
          checkboxes[r].checked = true;
        }
      }
    };
  },

  // VM->DOM, radio
  // Handle input radio
  radio: function(radios) {
    return function(value) {
      value = value.toString();
      for(var r in radios) {
        if(r !== value) {
          radios[r].checked = false;
        } else {
          radios[r].checked = true;
        }
      }
    };
  },

  // Bind html dom Event to VM function
  bindEventListener: function(vm, funcName){
    if(typeof vm[funcName] === "function") {
      return _.bind(vm[funcName], vm);
    }
    return function(){};
  },

  /**
   * Bind for:struct each item delete element
   * callback function(e, key, $el) {}
   * @param Object vm vm object
   * @param String funcName bind function name in vm object
   * @param String itemKey bind current item vm key
   * @param Object $el root each item of jquery node wrapper
   */
  bindForListener: function(vm, funcName, itemKey, $el){
    if(typeof vm[funcName] === "function") {
      return function(e) {
        _.bind(vm[funcName], vm)( e, itemKey, $el );
      };
    } else {
      return function(){};
    }
  },

  // vm-for compile and render
  forTemplate: function($node, filters) {
    // Only match comments in for:struct
    var tpl = $node.html().match(/<!--([\s\S]*)-->/g);
    tpl = tpl !== null ? tpl[0].replace(/<!--|-->/g, "") : "";
    // console.log(tpl);

    // By default, Underscore uses ERB-style template delimiters, change the
    // following template settings to use alternative delimiters.
    // _.templateSettings = {
    //   evaluate    : /<%([\s\S]+?)%>/g,
    //   interpolate : /<%=([\s\S]+?)%>/g,
    //   escape      : /<%-([\s\S]+?)%>/g,
    //   variable    : "data"
    // };

    // @todo: underscore >= 1.7.0, _.template accept 2 args
    var render = _.template(tpl);

    // 传入 value 为变化的 vm 数组项的值
    return function(value, vm) {
      // Before re-render for vm's view, clean older dom
      $node.empty();

      // support filters
      _.each(filters, function(filter){ value = filter(value); });

      var args = _.clone(vm._filter);
      _.each(value, function(v, key) {
        args.$key = key;
        args.$value = v;
        // console.log(args);

        var $itemNode = $(render(args));
        $node.append($itemNode);

        // Fixed: 如果 for 模板里没有最外层的包装时，$(x) 是一个数组
        var $itemNodeHasVM = $itemNode.length > 1 ? $itemNode.filter("[vm]") : $itemNode.find("[vm]");

        // 绑定for:struct循环中的事件绑定
        $itemNodeHasVM.each(function(k, nodeHasVmAttr){
          var $nodeHasVmAttr = $(nodeHasVmAttr);
          var vmNodeAttrList = nodeHasVmAttr.getAttribute("vm").replace(vmAttrStripper, "").split(",");
          _.each(vmNodeAttrList, function(v){
            var arr   = v.split(":");
            var ev    = arr[1].split("=");
            // console.log(ev);
            if(arr[0] === "on") {
              // VMhooks.bindForListener()
              $nodeHasVmAttr.on(ev[0], VMhooks.bindForListener(vm, ev[1], key, $itemNode));
            }
          });
        });

      });
    };<commit_msg>CHANGED: forTemplate 修改变量名称<commit_after>//  Backbone.vm.js 1.2.0

//  (c) 2013-2014 wangxian, DocumentCloud and Investigative Reporters & Editors
//  Backbone may be freely distributed under the MIT license.
//  For all details and documentation:
//  http://github.com/wangxian/backbone.vm

var $        = require("jquery");
var _        = require("underscore");
var Backbone = require("backbone");

// Cached regex for stripping vm node attributes. space, \r \n
var vmAttrStripper = /\s+/g;

// for:stuct replace && clear template string
// var forTplReplaceStripper = /<!--|-->|\n|'|{|}/g;

// for:struct match dom bind setting string
// var forTplOnStripper = /on:(\w+)=(\w+)/g;


// Handle all struct vm attribute tags,
// eg: html, text, on...
var VMhooks = {
  // VM->DOM, text, html, val, css
  simple: function($node, vmKey, filters) {
    return function(value) {
      _.each(filters, function(filter){ value = filter(value); });
      $node[vmKey](value);
    };
  },

  // DOM->VM, INPUT(except checkbox/radio) on change
  simpleOnChange: function(vm, name) {
    return function() { vm.set(name, this.value); };
  },

  // Show/Hide HTML element if vm item is true or false
  show: function($node) {
    return function(value) { $node[value ? 'show' : 'hide'](); };
  },

  // Remove HTML element if vm item value is true
  remove: function($node) {
    return function(value) { if(!!value) $node.remove(); };
  },

  // VM->DOM Set or clear Element's classList
  className: function($node, vmVal, filters) {
    return function(value, vm) {
      var oldValue;
      _.each(filters, function(filter){ value = filter(value); });
      if(!_.isArray(value)) { oldValue = vm.previous(vmVal);}
      else {
        // 支持从filter定义类切换，如 [之前的类， 新类名称]
        oldValue = value[0];
        value    = value[1];
      }
      if(!!oldValue) { $node.removeClass(oldValue); }
      if(!!value) { $node.addClass(value); }
    };
  },

  // DOM->VM, checkbox on click
  checkboxOnClick: function(vm, name) {
    return function() {
      var checkboxList = vm.get(name);
      var value   = this.value;
      if(! _.isArray(checkboxList)) checkboxList = [];

      if(!this.checked){
        checkboxList = _.filter(checkboxList, function(num){ return num !== value; });
      } else {
        checkboxList.push(value);
      }
      vm.set(name, checkboxList, {silent: true});

      // 修复 Model 触发 change 事件的要求
      var changed;
      (changed = {})[name] = checkboxList;
      vm._vm.changed = changed;

      vm.trigger("change:"+name);
    };
  },

  // VM->DOM, checkbox
  // Handle input checkbox
  checkbox: function(checkboxes) {
    return function(value) {
      if(! _.isArray(value)) return;
      for(var r in checkboxes) {
        if(! _.contains(value, r) ) {
          checkboxes[r].checked = false;
        } else {
          checkboxes[r].checked = true;
        }
      }
    };
  },

  // VM->DOM, radio
  // Handle input radio
  radio: function(radios) {
    return function(value) {
      value = value.toString();
      for(var r in radios) {
        if(r !== value) {
          radios[r].checked = false;
        } else {
          radios[r].checked = true;
        }
      }
    };
  },

  // Bind html dom Event to VM function
  bindEventListener: function(vm, funcName){
    if(typeof vm[funcName] === "function") {
      return _.bind(vm[funcName], vm);
    }
    return function(){};
  },

  /**
   * Bind for:struct each item delete element
   * callback function(e, key, $el) {}
   * @param Object vm vm object
   * @param String funcName bind function name in vm object
   * @param String itemKey bind current item vm key
   * @param Object $el root each item of jquery node wrapper
   */
  bindForListener: function(vm, funcName, itemKey, $el){
    if(typeof vm[funcName] === "function") {
      return function(e) {
        _.bind(vm[funcName], vm)( e, itemKey, $el );
      };
    } else {
      return function(){};
    }
  },

  // vm-for compile and render
  forTemplate: function($node, filters) {
    // Only match comments in for:struct
    var tpl = $node.html().match(/<!--([\s\S]*)-->/g);
    tpl = tpl !== null ? tpl[0].replace(/<!--|-->/g, "") : "";
    // console.log(tpl);

    // By default, Underscore uses ERB-style template delimiters, change the
    // following template settings to use alternative delimiters.
    // _.templateSettings = {
    //   evaluate    : /<%([\s\S]+?)%>/g,
    //   interpolate : /<%=([\s\S]+?)%>/g,
    //   escape      : /<%-([\s\S]+?)%>/g,
    //   variable    : "data"
    // };

    // @todo: underscore >= 1.7.0, _.template accept 2 args
    var render = _.template(tpl);

    // 传入 value 为变化的 vm 数组项的值
    return function(value, vm) {
      // Before re-render for vm's view, clean older dom
      $node.empty();

      // support filters
      _.each(filters, function(filter){ value = filter(value); });

      var args = _.clone(vm._filter);
      _.each(value, function(v, key) {
        args.$key = key;
        args.$value = v;
        // console.log(args);

        var $rootNode = $(render(args));
        $node.append($rootNode);

        // Fixed: 如果 for 模板里没有最外层的包装时，$(x) 是一个数组
        var $nodesHasVM = $rootNode.length > 1 ? $rootNode.filter("[vm]") : $rootNode.find("[vm]");

        // 绑定for:struct循环中的事件绑定
        $nodesHasVM.each(function(k, nodeHasVM){
          var nodes = nodeHasVM.getAttribute("vm").replace(vmAttrStripper, "").split(",");
          _.each(nodes, function(v){
            var arr   = v.split(":");
            var ev    = arr[1].split("=");
            // console.log(ev);
            if(arr[0] === "on") {
              $(nodeHasVM).on(ev[0], VMhooks.bindForListener(vm, ev[1], key, $rootNode));
            }
          });
        });

      });
    };
{'fraction_non_alphanumeric': 0.16869326939544443, 'fraction_numerical': 0.003939030655934235, 'mean_word_length': 2.3273504273504275, 'pattern_counts': {'":': 2, '<': 15, '<?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': '5242952', 'n_tokens_mistral': 3912, 'n_tokens_neox': 3858, 'n_words': 934}