<commit_before>var CalSelect = Class.create({

  initialize: function(dateField) {
    this.dateField = $(dateField);
    this.insertCalendar();
    this.registerObservers();
  },

  insertCalendar: function() {
    this.calendar = new Element('div', { className: 'calendar' });
    this.calendar.observe('calSelect:dateClicked', function(event) {
      this.setDate(event.memo.date);
    }.bindAsEventListener(this));
    this.calendar.hide();
    this.dateField.insert({after: this.calendar});
  },

  registerObservers: function() {
    this.dateField.observe('focus', this.show.bind(this));
    this.dateField.observe('keydown', function(event) {
      if (event.keyCode == Event.KEY_TAB) { this.hide(); }
    }.bindAsEventListener(this));

    // TODO: this works, but perhaps we should only observe on show and stop on hide
    document.observe('click', function(event) {
      var element = event.element();
      if (element != this.dateField && !element.descendantOf(this.calendar)) {
        this.hide();
      }
    }.bindAsEventListener(this));
  },

  show: function() {
    this.dateField.select();
    var selectedDate = this.getDate();
    var pageDate = selectedDate ? selectedDate.clone() : new Date();
    var calPage = new CalSelect.Page(pageDate, selectedDate);
    this.calendar.update(calPage);
    this.setPosition();
    this.calendar.show();
  },

  hide: function() {
    this.calendar.hide();
  },

  setPosition: function() {
    var offset = this.dateField.positionedOffset();
    offset.top += this.dateField.getHeight();
    this.calendar.setStyle({left: offset.left+'px', top: offset.top+'px'});    
  },

  getDate: function() {
    var dateStr = $F(this.dateField);
    var dateMatch = dateStr.match(/^\s*(\d{1,2})\/(\d{1,2})\/(\d{2}(\d{2})?)\s*$/);
    if (dateMatch) {
      var month = dateMatch[1] - 1;
      var day   = dateMatch[2];
      var year  = dateMatch[3];
      if (!dateMatch[4]) { year = '20' + year; }
      return new Date(year, month, day);
    } else {
      return null;
    }
  },

  setDate: function(date) {
    this.dateField.setValue(date.toShortString());
    this.hide();
  }

});
CalSelect.Version = '0.1';

CalSelect.Page = Class.create({

  initialize: function(pageDate, selectedDate) {
    this.pageDate = pageDate.startOfMonth();<commit_msg>observe/stopObserving document click handler on show/hide<commit_after>var CalSelect = Class.create({

  initialize: function(dateField) {
    this.dateField = $(dateField);
    this.insertCalendar();
    this.registerFieldObservers();
    this.documentClickHandler = this._documentClickHandler.bindAsEventListener(this);
  },

  insertCalendar: function() {
    this.calendar = new Element('div', { className: 'calendar' });
    this.calendar.observe('calSelect:dateClicked', function(event) {
      this.setDate(event.memo.date);
    }.bindAsEventListener(this));
    this.calendar.hide();
    this.dateField.insert({after: this.calendar});
  },

  registerFieldObservers: function() {
    this.dateField.observe('focus', this.show.bind(this));
    this.dateField.observe('keydown', function(event) {
      if (event.keyCode == Event.KEY_TAB) { this.hide(); }
    }.bindAsEventListener(this));
  },

  show: function() {
    if (!this.calendar.visible()) {
      this.dateField.select();
      var selectedDate = this.getDate();
      var pageDate = selectedDate ? selectedDate.clone() : new Date();
      var calPage = new CalSelect.Page(pageDate, selectedDate);
      this.calendar.update(calPage);
      this.setPosition();
      document.observe('click', this.documentClickHandler);
      this.calendar.show();
    }
  },

  hide: function() {
    document.stopObserving('click', this.documentClickHandler);
    this.calendar.hide();
  },

  setPosition: function() {
    var offset = this.dateField.positionedOffset();
    offset.top += this.dateField.getHeight();
    this.calendar.setStyle({left: offset.left+'px', top: offset.top+'px'});    
  },

  _documentClickHandler: function(event) {
    var element = event.element();
    if (element != this.dateField && !element.descendantOf(this.calendar)) {
      this.hide();
    }
  },

  getDate: function() {
    var dateStr = $F(this.dateField);
    var dateMatch = dateStr.match(/^\s*(\d{1,2})\/(\d{1,2})\/(\d{2}(\d{2})?)\s*$/);
    if (dateMatch) {
      var month = dateMatch[1] - 1;
      var day   = dateMatch[2];
      var year  = dateMatch[3];
      if (!dateMatch[4]) { year = '20' + year; }
      return new Date(year, month, day);
    } else {
      return null;
    }
  },

  setDate: function(date) {
    this.dateField.setValue(date.toShortString());
    this.hide();
  }

});
CalSelect.Version = '0.1';

CalSelect.Page = Class.create({

  initialize: function(pageDate, selectedDate) {
    this.pageDate = pageDate.startOfMonth();
{'fraction_non_alphanumeric': 0.16780893042575284, 'fraction_numerical': 0.006230529595015576, 'mean_word_length': 3.36231884057971, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '1154939', 'n_tokens_mistral': 1553, 'n_tokens_neox': 1529, 'n_words': 276}