<commit_before>import { tagForType } from '../util/namespace';
import ParentComponentMixin from '../mixins/parent';
import ChildComponentMixin from '../mixins/child';
import ActiveStateMixin from '../mixins/active-state';
import TransitionMixin from '../mixins/transition';
import Ember from 'ember';

var A             = Ember.A;
var Component     = Ember.Component;
var get           = Ember.get;
var set           = Ember.set;
var setProperties = Ember.setProperties;
var getProperties = Ember.getProperties;
var computed      = Ember.computed;
var observer      = Ember.observer;
var assert        = Ember.assert;

var typeKey = 'popover';
var positions = A([ 'top', 'right', 'bottom', 'left', 'top-left', 'top-right', 'bottom-left', 'bottom-right' ]);

/**
  Popover Component

  This component is a utility component for displaying and positioning a window of content
  with an arrow pointing to its anchor. It is constructed with an anchor and a preferred
  position. The position is subject to flip to remain in the frame.

  ```handlebars
  {{#lio-popover anchor='.jquery-selector' position='bottom'}}
    Freeform content
  {{/lio-popover}}
  ```
*/
export default Component.extend(ParentComponentMixin, ChildComponentMixin, ActiveStateMixin, TransitionMixin, {
  //
  // HTML Properties
  //

  tagName: tagForType(typeKey),

  classNameBindings: [ 'positionClassName' ],

  //
  // Handlebars Attributes
  //

  anchor: null,

  alignToParent: false,

  //
  // Internal Properties
  //

  typeKey: typeKey,

  allowedComponents: [ 'button' ],

  canBeTopLevel: true,

  renderedPosition: null,

  positionClassName: computed(function() {
    var position = get(this, 'renderedPosition');
    return position && position.replace('-', ' ');
  }).property('renderedPosition'),

  position: computed({
    get: function() {
      return positions[0];
    },
    set: function() {
      assert(Ember.String.fmt("Position must be one of %@", [ JSON.stringify(positions) ]), positions.contains(value));
      return value;
    }
  }).property(),

  offset: computed(function() {
    return {
      top: get(this, 'offsetTop'),
      left: get(this, 'offsetLeft')
    };
  }).property('offsetTop', 'offsetLeft').readOnly(),

  arrowOffset: computed(function() {
    return {
      top: get(this, 'arrowOffsetTop'),
      left: get(this, 'arrowOffsetLeft')
    };
  }).property('arrowOffsetTop', 'arrowOffsetLeft').readOnly(),

  positioners: {
    top: function(popover) {
      popover.adjustHorizontalPosition();
      setProperties(popover, {
        offsetTop: get(popover, 'offsetTop') - get(popover, 'height') - get(popover, 'arrowHeight'),
        arrowOffsetTop: get(popover, 'height')
      });
    },
    bottom: function(popover) {
      popover.adjustHorizontalPosition();
      setProperties(popover, {
        offsetTop: get(popover, 'offsetTop') + get(popover, 'anchorHeight') + get(popover, 'arrowHeight'),
        arrowOffsetTop: 0 - get(popover, 'arrowHeight')
      });
    },
    right: function(popover) {
      popover.adjustVerticalPosition();
      setProperties(popover, {
        offsetLeft: get(popover, 'offsetLeft') + get(popover, 'anchorWidth') + get(popover, 'arrowWidth'),
        arrowOffsetLeft:0 - get(popover, 'arrowWidth')
      });
    },
    left: function(popover) {
      popover.adjustVerticalPosition();
      setProperties(popover, {
        offsetLeft: get(popover, 'offsetLeft') - get(popover, 'width') - get(popover, 'arrowWidth'),
        arrowOffsetLeft: get(popover, 'width')
      });
    },
    'top-left': function(popover) {
      setProperties(popover, {
        offsetTop: get(popover, 'offsetTop') - get(popover, 'height') - get(popover, 'arrowHeight'),
        arrowOffsetTop: get(popover, 'height'),
        offsetLeft: get(popover, 'offsetLeft') - get(popover, 'arrowWidth'),
        arrowOffsetLeft: 0
      });
    },
    'top-right': function(popover) {
      setProperties(popover, {
        offsetTop: get(popover, 'offsetTop') - get(popover, 'height') - get(popover, 'arrowHeight'),
        arrowOffsetTop: get(popover, 'height'),
        offsetLeft: get(popover, 'offsetLeft') - get(popover, 'width') + get(popover, 'anchorWidth'),
        arrowOffsetLeft: get(popover, 'width') - get(popover, 'arrowWidth')
      });
    },
    'bottom-left': function(popover) {
      setProperties(popover, {
        offsetTop: get(popover, 'offsetTop') + get(popover, 'anchorHeight') + get(popover, 'arrowHeight'),
        arrowOffsetTop: 0 - get(popover, 'arrowHeight'),
        offsetLeft: get(popover, 'offsetLeft') - get(popover, 'arrowWidth'),
        arrowOffsetLeft: 0
      });
    },
    'bottom-right': function(popover) {
      setProperties(popover, {
        offsetTop: get(popover, 'offsetTop') + get(popover, 'anchorHeight') + get(popover, 'arrowHeight'),
        arrowOffsetTop: 0 - get(popover, 'arrowHeight'),
        offsetLeft: get(popover, 'offsetLeft') - get(popover, 'width') + get(popover, 'anchorWidth'),
        arrowOffsetLeft: get(popover, 'width') - get(popover, 'arrowWidth')
      });
    }
  },

  //
  // Hooks / Observers
  //

  // Add resize handler to window
  didInsertElement: function(view) {
    this._super(view);

    set(this, 'resizeHandler', $(window).on('resize', function() {
      this.reposition();
    }.bind(this)));
  },

  willDestroy: function() {
    this._super();

    $(window).unbind('resize', this.get('resizeHandler'));
  },

  //
  // Internal Methods
  //

  adjustPosition: function() {
    var position = get(this, 'position');
    var dimensions = getProperties(this, 'trueOffsetLeft', 'width', 'anchorWidth', 'windowWidth', 'trueOffsetTop', 'height', 'anchorHeight', 'windowHeight');

    // The rendered position is the opposite of the preferred position when there is no room where preferred
    // NOTE: this does not affect corner positions
    if (position === 'left' && dimensions.trueOffsetLeft - dimensions.width < 0) {
      position = 'right';
    } else if (position === 'right' && dimensions.trueOffsetLeft + dimensions.width + dimensions.anchorWidth > dimensions.windowWidth) {
      position = 'left';
    } else if (position === 'top' && dimensions.trueOffsetTop - dimensions.height < 0) {
      position = 'bottom';
    } else if (position === 'bottom' && dimensions.trueOffsetTop + dimensions.height + dimensions.anchorHeight > dimensions.windowHeight) {
      position = 'top';
    }

    set(this, 'renderedPosition', position);
  },

  reposition: observer('position', 'active', function() {
    if (get(this, 'active')) {
      var $el = this.$();
      var $arrow = $el.find('.arrow');
      var $anchor = $(get(this, 'anchor'));
      var trueAnchorOffset = $anchor.offset();
      var anchorOffset = get(this, 'alignToParent') ? $anchor.position() : trueAnchorOffset;
      trueAnchorOffset || (trueAnchorOffset = { top: 0, left: 0});
      anchorOffset || (anchorOffset = { top: 0, left: 0 });

      trueAnchorOffset.top -= $(document).scrollTop();

      setProperties(this, {
        offsetTop: anchorOffset.top,
        offsetLeft: anchorOffset.left,

        trueOffsetTop: trueAnchorOffset.top,
        trueOffsetLeft: trueAnchorOffset.left,

        windowWidth: $(window).width(),
        windowHeight: $(window).height(),

        width: $el.outerWidth(),
        height: $el.outerHeight(),

        anchorWidth: $anchor.width(),
        anchorHeight: $anchor.height(),

        arrowWidth: $arrow.outerWidth(),
        arrowHeight: $arrow.outerHeight(),
      });

      setProperties(this, {
        arrowOffsetTop: get(this, 'height') / 2 - get(this, 'arrowHeight') / 2,
        arrowOffsetLeft: get(this, 'width') / 2 - get(this, 'arrowWidth') / 2
      });

      // Flip if necessary
      this.adjustPosition();

      // Adjust based on position
      this.positioners[get(this, 'renderedPosition')](this);

      $el.css(get(this, 'offset'));
      $arrow.css(get(this, 'arrowOffset'));
    }
  }),

  adjustHorizontalPosition: function() {
    var dimensions = getProperties(this, 'arrowOffsetLeft', 'offsetLeft', 'width', 'anchorWidth', 'windowWidth');
    set(this, 'offsetLeft', adjustForEdges(dimensions.offsetLeft, dimensions.width, dimensions.anchorWidth, dimensions.windowWidth));
    set(this, 'arrowOffsetLeft', adjustArrowForEdges(dimensions.arrowOffsetLeft, dimensions.offsetLeft, dimensions.width, dimensions.anchorWidth, dimensions.windowWidth));
  },

  adjustVerticalPosition: function() {
    var dimensions = getProperties(this, 'arrowOffsetTop', 'offsetTop', 'height', 'anchorHeight', 'windowHeight');
    set(this, 'offsetTop', adjustForEdges(dimensions.offsetTop, dimensions.height, dimensions.anchorHeight, dimensions.windowHeight));
    set(this, 'arrowOffsetTop', adjustArrowForEdges(dimensions.arrowOffsetTop, dimensions.offsetTop, dimensions.height, dimensions.anchorHeight, dimensions.windowHeight));
  }
});

// Given the bounding dimensions, return the origin top/left component that keeps the popover in the frame
function adjustForEdges(start, box, anchor, frame) {
  var end = start - (box / 2 - anchor / 2);

  if (end < 0) {
    end = 0;
  }
  if (end + box > frame) {
    end = frame - box;
  }

  return end;
}

// Given the bounding dimensions, give the origin top/left component that keeps the arrow over the anchor regardless of the popover position
function adjustArrowForEdges(arrowStart, start, box, anchor, frame) {
  var end = start - (box / 2 - anchor / 2);
  var arrowEnd = arrowStart;

  if (end < 0) {
    arrowEnd = start + anchor / 2;
  }
  if (end + box > frame) {
    arrowEnd = box - (frame - start) + anchor / 2;
  }

  return arrowEnd;
}
<commit_msg>Adds missing arguments to broken computed property.<commit_after>import { tagForType } from '../util/namespace';
import ParentComponentMixin from '../mixins/parent';
import ChildComponentMixin from '../mixins/child';
import ActiveStateMixin from '../mixins/active-state';
import TransitionMixin from '../mixins/transition';
import Ember from 'ember';

var A             = Ember.A;
var Component     = Ember.Component;
var get           = Ember.get;
var set           = Ember.set;
var setProperties = Ember.setProperties;
var getProperties = Ember.getProperties;
var computed      = Ember.computed;
var observer      = Ember.observer;
var assert        = Ember.assert;

var typeKey = 'popover';
var positions = A([ 'top', 'right', 'bottom', 'left', 'top-left', 'top-right', 'bottom-left', 'bottom-right' ]);

/**
  Popover Component

  This component is a utility component for displaying and positioning a window of content
  with an arrow pointing to its anchor. It is constructed with an anchor and a preferred
  position. The position is subject to flip to remain in the frame.

  ```handlebars
  {{#lio-popover anchor='.jquery-selector' position='bottom'}}
    Freeform content
  {{/lio-popover}}
  ```
*/
export default Component.extend(ParentComponentMixin, ChildComponentMixin, ActiveStateMixin, TransitionMixin, {
  //
  // HTML Properties
  //

  tagName: tagForType(typeKey),

  classNameBindings: [ 'positionClassName' ],

  //
  // Handlebars Attributes
  //

  anchor: null,

  alignToParent: false,

  //
  // Internal Properties
  //

  typeKey: typeKey,

  allowedComponents: [ 'button' ],

  canBeTopLevel: true,

  renderedPosition: null,

  positionClassName: computed(function() {
    var position = get(this, 'renderedPosition');
    return position && position.replace('-', ' ');
  }).property('renderedPosition'),

  position: computed({
    get: function() {
      return positions[0];
    },
    set: function(key, value) {
      assert(Ember.String.fmt("Position must be one of %@", [ JSON.stringify(positions) ]), positions.contains(value));
      return value;
    }
  }).property(),

  offset: computed(function() {
    return {
      top: get(this, 'offsetTop'),
      left: get(this, 'offsetLeft')
    };
  }).property('offsetTop', 'offsetLeft').readOnly(),

  arrowOffset: computed(function() {
    return {
      top: get(this, 'arrowOffsetTop'),
      left: get(this, 'arrowOffsetLeft')
    };
  }).property('arrowOffsetTop', 'arrowOffsetLeft').readOnly(),

  positioners: {
    top: function(popover) {
      popover.adjustHorizontalPosition();
      setProperties(popover, {
        offsetTop: get(popover, 'offsetTop') - get(popover, 'height') - get(popover, 'arrowHeight'),
        arrowOffsetTop: get(popover, 'height')
      });
    },
    bottom: function(popover) {
      popover.adjustHorizontalPosition();
      setProperties(popover, {
        offsetTop: get(popover, 'offsetTop') + get(popover, 'anchorHeight') + get(popover, 'arrowHeight'),
        arrowOffsetTop: 0 - get(popover, 'arrowHeight')
      });
    },
    right: function(popover) {
      popover.adjustVerticalPosition();
      setProperties(popover, {
        offsetLeft: get(popover, 'offsetLeft') + get(popover, 'anchorWidth') + get(popover, 'arrowWidth'),
        arrowOffsetLeft:0 - get(popover, 'arrowWidth')
      });
    },
    left: function(popover) {
      popover.adjustVerticalPosition();
      setProperties(popover, {
        offsetLeft: get(popover, 'offsetLeft') - get(popover, 'width') - get(popover, 'arrowWidth'),
        arrowOffsetLeft: get(popover, 'width')
      });
    },
    'top-left': function(popover) {
      setProperties(popover, {
        offsetTop: get(popover, 'offsetTop') - get(popover, 'height') - get(popover, 'arrowHeight'),
        arrowOffsetTop: get(popover, 'height'),
        offsetLeft: get(popover, 'offsetLeft') - get(popover, 'arrowWidth'),
        arrowOffsetLeft: 0
      });
    },
    'top-right': function(popover) {
      setProperties(popover, {
        offsetTop: get(popover, 'offsetTop') - get(popover, 'height') - get(popover, 'arrowHeight'),
        arrowOffsetTop: get(popover, 'height'),
        offsetLeft: get(popover, 'offsetLeft') - get(popover, 'width') + get(popover, 'anchorWidth'),
        arrowOffsetLeft: get(popover, 'width') - get(popover, 'arrowWidth')
      });
    },
    'bottom-left': function(popover) {
      setProperties(popover, {
        offsetTop: get(popover, 'offsetTop') + get(popover, 'anchorHeight') + get(popover, 'arrowHeight'),
        arrowOffsetTop: 0 - get(popover, 'arrowHeight'),
        offsetLeft: get(popover, 'offsetLeft') - get(popover, 'arrowWidth'),
        arrowOffsetLeft: 0
      });
    },
    'bottom-right': function(popover) {
      setProperties(popover, {
        offsetTop: get(popover, 'offsetTop') + get(popover, 'anchorHeight') + get(popover, 'arrowHeight'),
        arrowOffsetTop: 0 - get(popover, 'arrowHeight'),
        offsetLeft: get(popover, 'offsetLeft') - get(popover, 'width') + get(popover, 'anchorWidth'),
        arrowOffsetLeft: get(popover, 'width') - get(popover, 'arrowWidth')
      });
    }
  },

  //
  // Hooks / Observers
  //

  // Add resize handler to window
  didInsertElement: function(view) {
    this._super(view);

    set(this, 'resizeHandler', $(window).on('resize', function() {
      this.reposition();
    }.bind(this)));
  },

  willDestroy: function() {
    this._super();

    $(window).unbind('resize', this.get('resizeHandler'));
  },

  //
  // Internal Methods
  //

  adjustPosition: function() {
    var position = get(this, 'position');
    var dimensions = getProperties(this, 'trueOffsetLeft', 'width', 'anchorWidth', 'windowWidth', 'trueOffsetTop', 'height', 'anchorHeight', 'windowHeight');

    // The rendered position is the opposite of the preferred position when there is no room where preferred
    // NOTE: this does not affect corner positions
    if (position === 'left' && dimensions.trueOffsetLeft - dimensions.width < 0) {
      position = 'right';
    } else if (position === 'right' && dimensions.trueOffsetLeft + dimensions.width + dimensions.anchorWidth > dimensions.windowWidth) {
      position = 'left';
    } else if (position === 'top' && dimensions.trueOffsetTop - dimensions.height < 0) {
      position = 'bottom';
    } else if (position === 'bottom' && dimensions.trueOffsetTop + dimensions.height + dimensions.anchorHeight > dimensions.windowHeight) {
      position = 'top';
    }

    set(this, 'renderedPosition', position);
  },

  reposition: observer('position', 'active', function() {
    if (get(this, 'active')) {
      var $el = this.$();
      var $arrow = $el.find('.arrow');
      var $anchor = $(get(this, 'anchor'));
      var trueAnchorOffset = $anchor.offset();
      var anchorOffset = get(this, 'alignToParent') ? $anchor.position() : trueAnchorOffset;
      trueAnchorOffset || (trueAnchorOffset = { top: 0, left: 0});
      anchorOffset || (anchorOffset = { top: 0, left: 0 });

      trueAnchorOffset.top -= $(document).scrollTop();

      setProperties(this, {
        offsetTop: anchorOffset.top,
        offsetLeft: anchorOffset.left,

        trueOffsetTop: trueAnchorOffset.top,
        trueOffsetLeft: trueAnchorOffset.left,

        windowWidth: $(window).width(),
        windowHeight: $(window).height(),

        width: $el.outerWidth(),
        height: $el.outerHeight(),

        anchorWidth: $anchor.width(),
        anchorHeight: $anchor.height(),

        arrowWidth: $arrow.outerWidth(),
        arrowHeight: $arrow.outerHeight(),
      });

      setProperties(this, {
        arrowOffsetTop: get(this, 'height') / 2 - get(this, 'arrowHeight') / 2,
        arrowOffsetLeft: get(this, 'width') / 2 - get(this, 'arrowWidth') / 2
      });

      // Flip if necessary
      this.adjustPosition();

      // Adjust based on position
      this.positioners[get(this, 'renderedPosition')](this);

      $el.css(get(this, 'offset'));
      $arrow.css(get(this, 'arrowOffset'));
    }
  }),

  adjustHorizontalPosition: function() {
    var dimensions = getProperties(this, 'arrowOffsetLeft', 'offsetLeft', 'width', 'anchorWidth', 'windowWidth');
    set(this, 'offsetLeft', adjustForEdges(dimensions.offsetLeft, dimensions.width, dimensions.anchorWidth, dimensions.windowWidth));
    set(this, 'arrowOffsetLeft', adjustArrowForEdges(dimensions.arrowOffsetLeft, dimensions.offsetLeft, dimensions.width, dimensions.anchorWidth, dimensions.windowWidth));
  },

  adjustVerticalPosition: function() {
    var dimensions = getProperties(this, 'arrowOffsetTop', 'offsetTop', 'height', 'anchorHeight', 'windowHeight');
    set(this, 'offsetTop', adjustForEdges(dimensions.offsetTop, dimensions.height, dimensions.anchorHeight, dimensions.windowHeight));
    set(this, 'arrowOffsetTop', adjustArrowForEdges(dimensions.arrowOffsetTop, dimensions.offsetTop, dimensions.height, dimensions.anchorHeight, dimensions.windowHeight));
  }
});

// Given the bounding dimensions, return the origin top/left component that keeps the popover in the frame
function adjustForEdges(start, box, anchor, frame) {
  var end = start - (box / 2 - anchor / 2);

  if (end < 0) {
    end = 0;
  }
  if (end + box > frame) {
    end = frame - box;
  }

  return end;
}

// Given the bounding dimensions, give the origin top/left component that keeps the arrow over the anchor regardless of the popover position
function adjustArrowForEdges(arrowStart, start, box, anchor, frame) {
  var end = start - (box / 2 - anchor / 2);
  var arrowEnd = arrowStart;

  if (end < 0) {
    arrowEnd = start + anchor / 2;
  }
  if (end + box > frame) {
    arrowEnd = box - (frame - start) + anchor / 2;
  }

  return arrowEnd;
}
<|endoftext|>


<commit_before>import Ember from 'ember';

export function isFieldValid(validationResult, field){
  if (Ember.isNone(validationResult)){
    return true;
  }
  Ember.assert('Field to get validation result is not provided for isFieldValid helper', Ember.isPresent(field));

  let fieldResult = validationResult.result.find((result) => {
    return isSingleFieldValidated(result.fields, field);
  });

  if (Ember.isNone(fieldResult)){
    return null;
  }

  if (fieldResult.result.length === 0){
    return true;
  }

  return fieldResult.result.every((res) => res === true);
}

export function isFieldValidHelper(params, hash) {

  Ember.assert(Ember.isPresent(hash), 'ValidationResult and field not specified - assign them in helper\'s hash');

  let validationResult = hash.validationResult;
  let field = hash.field;

  return isFieldValid(validationResult, field);
}

function isSingleFieldValidated(field, resultFields) {
  if (Array.isArray(field)) {
    return Ember.isPresent(field.find((f)=> f === resultFields));
  } else {
    return field === resultFields;
  }
}

export default Ember.Helper.helper(isFieldValidHelper);
<commit_msg>fixed is-field-valid helper so that is field is not in a validation result, mark it as valid<commit_after>import Ember from 'ember';

export function isFieldValid(validationResult, field){
  if (Ember.isNone(validationResult)){
    return true;
  }
  Ember.assert('Field to get validation result is not provided for isFieldValid helper', Ember.isPresent(field));

  let fieldResult = validationResult.result.find((result) => {
    return isSingleFieldValidated(result.fields, field);
  });

  if (Ember.isNone(fieldResult)){
    return true;
  }

  if (fieldResult.result.length === 0){
    return true;
  }

  return fieldResult.result.every((res) => res === true);
}

export function isFieldValidHelper(params, hash) {

  Ember.assert(Ember.isPresent(hash), 'ValidationResult and field not specified - assign them in helper\'s hash');

  let validationResult = hash.validationResult;
  let field = hash.field;

  return isFieldValid(validationResult, field);
}

function isSingleFieldValidated(field, resultFields) {
  if (Array.isArray(field)) {
    return Ember.isPresent(field.find((f)=> f === resultFields));
  } else {
    return field === resultFields;
  }
}

export default Ember.Helper.helper(isFieldValidHelper);
<|endoftext|>


<commit_before>openerp.pad = function(instance) {

instance.web.Sidebar = instance.web.Sidebar.extend({
    init: function(parent) {
        this._super(parent);
        this.add_items('other',[{ label: "Pad", callback: this.on_add_pad }]);
    },
    on_attachments_loaded: function(attachments) {
        this._super(attachments);
        var self = this;
        var $padbtn = self.$element.find('button.pad');
        var is_pad = function(a) {
            return a.type == 'url' && a.name == 'Pad';
        };
    },
    on_add_pad: function() {
        var self = this;
        var view = this.getParent();
        view.dataset.call_button('pad_get', [[view.datarecord.id], view.dataset.get_context()], function(r) {
            self.do_update();
            self.do_action(r.result);
        });
    }
});

};
<commit_msg>[FIX] pad action<commit_after>openerp.pad = function(instance) {

instance.web.Sidebar = instance.web.Sidebar.extend({
    init: function(parent) {
        this._super(parent);
        this.add_items('other',[{ label: "Pad", callback: this.on_add_pad }]);
    },
    on_add_pad: function() {
        var self = this;
        var view = this.getParent();
        var model = new instance.web.Model('ir.attachment');
        model.call('pad_get', [view.model ,view.datarecord.id],{}).then(function(r) {
            self.do_action({ type: "ir.actions.act_url", url: r });
        });
    }
});

};
<|endoftext|>


<commit_before>/**
 * Initialization script for Realtime Web Apps
 */
(function($) {

    channel.bind('close',  function(data){ room.close(data);      });
    channel.bind('open',   function(data){ room.open(data);       });
    channel.bind('ask',    function(data){ question.ask(data);    });
    channel.bind('vote',   function(data){ question.vote(data);   });
    channel.bind('answer', function(data){ question.answer(data); });

    var nonce = $('input[name=nonce]:eq(0)').val(),
        room = {
            open: function(data){
                location.reload();
            },
            close: function(data){
                location.reload();
            }
        },
        question = {
            ask: function(data){
                console.log(data);
                $(data.markup)
                    .find('input[name=nonce]').val(nonce).end()
                    .hide().prependTo('#questions').slideDown('slow');
            },
            vote: function(data){
                var question  = $('#question-'+data.question_id),
                    cur_count = question.data('count'),
                    new_count = cur_count+1;

                // Updates the count
                question
                    .attr('data-count', new_count)
                    .data('count', new_count)
                    .addClass('new-vote');

                setTimeout(1000, function(){
                    question.removeClass('new-vote');
                });
            },
            answer: function(data){
                var question = $("#question-"+data.question_id),
                    detach_me = function() {
                        question
                            .detach()
                            .appendTo('#questions')
                            .slideDown(500);
                    }

                question
                    .addClass('answered')
                    .delay(1000)
                    .slideUp(500, detach_me);
            }
        };

})(jQuery);
<commit_msg>Removed an errant call to console.log().<commit_after>/**
 * Initialization script for Realtime Web Apps
 */
(function($) {

    channel.bind('close',  function(data){ room.close(data);      });
    channel.bind('open',   function(data){ room.open(data);       });
    channel.bind('ask',    function(data){ question.ask(data);    });
    channel.bind('vote',   function(data){ question.vote(data);   });
    channel.bind('answer', function(data){ question.answer(data); });

    var nonce = $('input[name=nonce]:eq(0)').val(),
        room = {
            open: function(data){
                location.reload();
            },
            close: function(data){
                location.reload();
            }
        },
        question = {
            ask: function(data){
                $(data.markup)
                    .find('input[name=nonce]').val(nonce).end()
                    .hide().prependTo('#questions').slideDown('slow');
            },
            vote: function(data){
                var question  = $('#question-'+data.question_id),
                    cur_count = question.data('count'),
                    new_count = cur_count+1;

                // Updates the count
                question
                    .attr('data-count', new_count)
                    .data('count', new_count)
                    .addClass('new-vote');

                setTimeout(1000, function(){
                    question.removeClass('new-vote');
                });
            },
            answer: function(data){
                var question = $("#question-"+data.question_id),
                    detach_me = function() {
                        question
                            .detach()
                            .appendTo('#questions')
                            .slideDown(500);
                    }

                question
                    .addClass('answered')
                    .delay(1000)
                    .slideUp(500, detach_me);
            }
        };

})(jQuery);
<|endoftext|>


<commit_before>(function() {

var GameComponent = {};
GameComponent.view = function () {
  return [
    m(GridComponent, new Grid({
        columnCount: 7,
        rowCount: 6,
        chipSize: 50,
        chipMargin: 6
      })
    )
  ];
};

function Grid(args) {
  this.columnCount = args.columnCount;
  this.rowCount = args.rowCount;
  this.chipSize = args.chipSize;
  this.chipMargin = args.chipMargin;
  // The columns array where columns containing placed chips are stored
  this.columns = [];
  this.resetGrid();
}
// Reset the grid by removing all placed chips
Grid.prototype.resetGrid = function () {
  this.columns.length = 0;
  var p1 = new Player({color: 'red'});
  for (var c = 0; c < this.columnCount; c += 1) {
    this.columns.push([]);
  }
};

function Chip(args) {
  this.player = args.player;
}

function Player(args) {
  this.color = args.color;
}

var GridComponent = {};
GridComponent.controller = function () {
  return {
    getColumnStyle: function (grid) {
      var gridWidth = grid.chipSize + (grid.chipMargin * 2);
      var gridHeight = grid.rowCount * (grid.chipSize + (grid.chipMargin * 2));
      return {
        width: gridWidth + 'px',
        height: gridHeight + 'px'
      };
    },
    getChipStyle: function (c, r, grid) {
      var chipX = c * (grid.chipSize + (grid.chipMargin * 2)) + grid.chipMargin;
      var chipY = r * (grid.chipSize + (grid.chipMargin * 2)) + grid.chipMargin;
      return {
        width: grid.chipSize + 'px',
        height: grid.chipSize + 'px',
        transform: 'translate(' + chipX + 'px,' + chipY + 'px)'
      };
    }
  };
};
GridComponent.view = function (ctrl, grid) {
  return m('div', {id: 'grid'},
    _.times(grid.columnCount, function (c) {
      return m('div', {class: 'grid-column', style: ctrl.getColumnStyle(grid)}, _.times(grid.rowCount, function (r) {
        return m('div', {
          class: 'chip-placeholder',
          style: ctrl.getChipStyle(c, r, grid)
        });
      }).concat(_.forEach(grid.columns[c], function (chip, r) {
        return m('div', {
          class: ['chip', chip.player.color].join(' '),
          style: ctrl.getChipStyle(c, r, grid)
        });
      })));
    })
  );
};

m.mount(document.getElementById('game'), GameComponent);

}());
<commit_msg>Add constructor for a new Game class<commit_after>(function() {

var GameComponent = {};
GameComponent.controller = function () {
    return {
        game: new Game({
            ai: false,
            grid: new Grid({
                columnCount: 7,
                rowCount: 6,
                chipSize: 50,
                chipMargin: 6
            })
        })
    };
};
GameComponent.view = function (ctrl) {
  return m(GridComponent, ctrl.game);
};

function Game(args) {
    this.grid = args.grid;
    this.players = [
        // Player 1 (a human)
        new Player({color: 'red'}),
        // Player 2 (another human or the AI)
        new Player({color: 'blue'})
    ];
    // The current player is null when a game is not in progress
    this.currentPlayer = null;
}

function Grid(args) {
  this.columnCount = args.columnCount;
  this.rowCount = args.rowCount;
  this.chipSize = args.chipSize;
  this.chipMargin = args.chipMargin;
  // The columns array where columns containing placed chips are stored
  this.columns = [];
  this.resetGrid();
}
// Reset the grid by removing all placed chips
Grid.prototype.resetGrid = function () {
  this.columns.length = 0;
  var p1 = new Player({color: 'red'});
  for (var c = 0; c < this.columnCount; c += 1) {
    this.columns.push([]);
  }
};

function Chip(args) {
  this.player = args.player;
}

function Player(args) {
  this.color = args.color;
}

var GridComponent = {};
GridComponent.controller = function () {
  return {
    getColumnStyle: function (grid) {
      var gridWidth = grid.chipSize + (grid.chipMargin * 2);
      var gridHeight = grid.rowCount * (grid.chipSize + (grid.chipMargin * 2));
      return {
        width: gridWidth + 'px',
        height: gridHeight + 'px'
      };
    },
    getChipStyle: function (c, r, grid) {
      var chipX = c * (grid.chipSize + (grid.chipMargin * 2)) + grid.chipMargin;
      var chipY = r * (grid.chipSize + (grid.chipMargin * 2)) + grid.chipMargin;
      return {
        width: grid.chipSize + 'px',
        height: grid.chipSize + 'px',
        transform: 'translate(' + chipX + 'px,' + chipY + 'px)'
      };
    }
  };
};
GridComponent.view = function (ctrl, game) {
  var grid = game.grid;
  return m('div', {id: 'grid'},
    _.times(grid.columnCount, function (c) {
      return m('div', {class: 'grid-column', style: ctrl.getColumnStyle(grid)}, _.times(grid.rowCount, function (r) {
        return m('div', {
          class: 'chip-placeholder',
          style: ctrl.getChipStyle(c, r, grid)
        });
      }).concat(_.forEach(grid.columns[c], function (chip, r) {
        return m('div', {
          class: ['chip', chip.player.color].join(' '),
          style: ctrl.getChipStyle(c, r, grid)
        });
      })));
    })
  );
};

m.mount(document.getElementById('game'), GameComponent);

}());
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */
/*global define, $, FileError, brackets, window */

/**
 * LiveDevelopment manages the Inspector, all Agents, and the active LiveDocument
 *
 * # STARTING
 *
 * To start a session call `open`. This will read the currentDocument from brackets,
 * launch the LiveBrowser (currently Chrome) with the remote debugger port open,
 * establish the Inspector connection to the remote debugger, and finally load all
 * agents.
 *
 * # STOPPING
 *
 * To stop a session call `close`. This will close the active browser window,
 * disconnect the Inspector, unload all agents, and clean up.
 *
 * # STATUS
 *
 * Status updates are dispatched as `statusChange` jQuery events. The status
 * codes are:
 *
 * -1: Error
 * 0: Inactive
 * 1: Connecting to the remote debugger
 * 2: Loading agents
 * 3: Active
 */
define(function LiveDevelopment(require, exports, module) {
    "use strict";

    var DocumentManager = require("document/DocumentManager");
    var EditorManager = require("editor/EditorManager");
    var NativeApp = require("utils/NativeApp");
    var Dialogs = require("widgets/Dialogs");
    var Strings = require("strings");
    var StringUtils = require("utils/StringUtils");

    // Inspector
    var Inspector = require("LiveDevelopment/Inspector/Inspector");

    // Documents
    var HTMLDocument = require("LiveDevelopment/Documents/HTMLDocument");
    var CSSDocument = require("LiveDevelopment/Documents/CSSDocument");
    var JSDocument = require("LiveDevelopment/Documents/JSDocument");

    // Agents
    var agents = {
        "console": require("LiveDevelopment/Agents/ConsoleAgent"),
        "remote": require("LiveDevelopment/Agents/RemoteAgent"),
        "network": require("LiveDevelopment/Agents/NetworkAgent"),
        "dom": require("LiveDevelopment/Agents/DOMAgent"),
        "css": require("LiveDevelopment/Agents/CSSAgent"),
        "script": require("LiveDevelopment/Agents/ScriptAgent"),
        "highlight": require("LiveDevelopment/Agents/HighlightAgent"),
        "goto": require("LiveDevelopment/Agents/GotoAgent"),
        "edit": require("LiveDevelopment/Agents/EditAgent")
    };

    // Some agents are still experimental, so we don't enable them all by default
    // However, extensions can enable them by calling enableAgent()
    var _enabledAgents = {
        "console": true,
        "remote": true,
        "network": true,
        "dom": true,
        "css": true
    };
    var _loadedAgents = [];

    var _htmlDocumentPath; // the path of the html file open for live development
    var _liveDocument; // the document open for live editing.
    var _relatedDocuments; // CSS and JS documents that are used by the live HTML document

    /** Augments the given Brackets document with information that's useful for live development. */
    function _setDocInfo(doc) {
        // FUTURE: some of these things should just be moved into core Document; others should
        // be in a LiveDevelopment-specific object attached to the doc.
        var matches = /^(.*\/)(.+\.([^.]+))$/.exec(doc.file.fullPath);
        if (matches) {
            var prefix = "file://";

            // The file.fullPath on Windows starts with a drive letter ("C:").
            // In order to make it a valid file: URL we need to add an
            // additional slash to the prefix.
            if (brackets.platform === "win") {
                prefix += "/";
            }

            doc.extension = matches[3];
            doc.url = encodeURI(prefix + doc.file.fullPath);

            // the root represents the document that should be displayed in the browser
            // for live development (the file for HTML files, index.html for others)
            var fileName = /^html?$/.test(matches[3]) ? matches[2] : "index.html";
            doc.root = {url: encodeURI(prefix + matches[1] + fileName)};
        }
    }

    /** Get the current document from the document manager
     * _adds extension, url and root to the document
     */
    function _getCurrentDocument() {
        var doc = DocumentManager.getCurrentDocument();
        if (doc) {
            _setDocInfo(doc);
        }
        return doc;
    }

    /** Determine which document class should be used for a given document
     * @param {Document} document
     */
    function _classForDocument(doc) {
        switch (doc.extension) {
        case "css":
            return CSSDocument;
        /* FUTURE:
        case "js":
            return JSDocument;
        case "html":
        case "htm":
            return HTMLDocument;
        default:
            throw "Invalid document type: " + doc.extension;
        */
        }

        return null;
    }

    /**
     * Removes the given CSS/JSDocument from _relatedDocuments. Signals that the
     * given file is no longer associated with the HTML document that is live (e.g.
     * if the related file has been deleted on disk).
     */
    function _handleRelatedDocumentDeleted(event, liveDoc) {
        var index = _relatedDocuments.indexOf(liveDoc);
        if (index !== -1) {
            $(liveDoc).on("deleted", _handleRelatedDocumentDeleted);
            _relatedDocuments.splice(index, 1);
        }
    }

    /** Close a live document */
    function _closeDocument() {
        if (_liveDocument) {
            _liveDocument.close();
            _liveDocument = undefined;
        }
        if (_relatedDocuments) {
            _relatedDocuments.forEach(function (liveDoc) {
                liveDoc.close();
                $(liveDoc).off("deleted", _handleRelatedDocumentDeleted);
            });
            _relatedDocuments = undefined;
        }
    }

    /** Create a live version of a Brackets document */
    function _createDocument(doc, editor) {
        var DocClass = _classForDocument(doc);
        if (DocClass) {
            return new DocClass(doc, editor);
        } else {
            return null;
        }
    }

    /** Convert a file: URL to a local full file path */
    function _urlToPath(url) {
        var path;
        if (url.indexOf("file://") === 0) {
            path = url.slice(7);
            if (path && brackets.platform === "win" && path.charAt(0) === "/") {
                path = path.slice(1);
            }
        }
        return decodeURI(path);
    }

    /** Open a live document
     * @param {Document} source document to open
     */
    function _openDocument(doc, editor) {
        _closeDocument();
        _liveDocument = _createDocument(doc, editor);

        // Gather related CSS documents.
        // FUTURE: Gather related JS documents as well.
        _relatedDocuments = [];
        agents.css.getStylesheetURLs().forEach(function (url) {
            // FUTURE: when we get truly async file handling, we might need to prevent other
            // stuff from happening while we wait to add these listeners
            DocumentManager.getDocumentForPath(_urlToPath(url))
                .done(function (doc) {
                    _setDocInfo(doc);
                    var liveDoc = _createDocument(doc);
                    if (liveDoc) {
                        _relatedDocuments.push(liveDoc);
                        $(liveDoc).on("deleted", _handleRelatedDocumentDeleted);
                    }
                });
        });
    }

    /** Unload the agents */
    function unloadAgents() {
        _loadedAgents.forEach(function (i) {
            if (agents.hasOwnProperty(i) && agents[i].unload) {
                agents[i].unload();
            }
        });
        _loadedAgents = [];
    }

    /** Load the agents */
    function loadAgents() {
        var i, promises = [];
        for (i in _enabledAgents) {
            if (_enabledAgents.hasOwnProperty(i) && agents.hasOwnProperty(i) && agents[i].load) {
                promises.push(agents[i].load());
                _loadedAgents.push(i);
            }
        }
        return promises;
    }

    /** Enable an agent. Takes effect next time a connection is made. Does not affect
     *  current live development sessions.
     *
     *  @param {string} name of agent to enable
     */
    function enableAgent(name) {
        if (!_enabledAgents.hasOwnProperty(name)) {
            _enabledAgents[name] = true;
        }
    }

    /** Disable an agent. Takes effect next time a connection is made. Does not affect
     *  current live development sessions.
     *
     *  @param {string} name of agent to disable
     */
    function disableAgent(name) {
        if (_enabledAgents.hasOwnProperty(name)) {
            delete _enabledAgents[name];
        }
    }

    /** Update the status
     * @param {integer} new status
     */
    function _setStatus(status) {
        exports.status = status;
        $(exports).triggerHandler("statusChange", status);
    }

    /** Triggered by Inspector.error */
    function _onError(error) {
        var message = error.message;

        // Additional information, like exactly which parameter could not be processed.
        var data = error.data;
        if (Array.isArray(data)) {
            message += "\n" + data.join("\n");
        }

        // Show the message, but include the error object for further information (e.g. error code)
        console.error(message, error);
    }

    /** Run when all agents are loaded */
    function _onLoad() {
        var doc = _getCurrentDocument();
        if (doc) {
            var editor = EditorManager.getCurrentFullEditor();
            _openDocument(doc, editor);
        }
        _setStatus(3);
    }

    /** Triggered by Inspector.connect */
    function _onConnect() {
        var promises = loadAgents();
        _setStatus(2);
        $.when.apply(undefined, promises).then(_onLoad, _onError);
    }

    /** Triggered by Inspector.disconnect */
    function _onDisconnect() {
        unloadAgents();
        _closeDocument();
        _setStatus(0);
    }

    /** Open the Connection and go live */
    function open() {
        var doc = _getCurrentDocument();
        var browserStarted = false;
        var retryCount = 0;

        function showWrongDocError() {
            Dialogs.showModalDialog(
                Dialogs.DIALOG_ID_ERROR,
                Strings.LIVE_DEVELOPMENT_ERROR_TITLE,
                Strings.LIVE_DEV_NEED_HTML_MESSAGE
            );
        }

        if (!doc || !doc.root) {
            showWrongDocError();

        } else {
            // For Sprint 6, we only open live development connections for HTML files
            // FUTURE: Remove this test when we support opening connections for different
            // file types.
            if (!doc.extension || doc.extension.indexOf("htm") !== 0) {
                showWrongDocError();
                return;
            }

            _setStatus(1);
            Inspector.connectToURL(doc.root.url).fail(function onConnectFail(err) {
                if (err === "CANCEL") {
                    return;
                }
                if (retryCount > 6) {
                    _setStatus(-1);
                    Dialogs.showModalDialog(
                        Dialogs.DIALOG_ID_LIVE_DEVELOPMENT,
                        Strings.LIVE_DEVELOPMENT_ERROR_TITLE,
                        Strings.LIVE_DEVELOPMENT_ERROR_MESSAGE
                    ).done(function (id) {
                        if (id === Dialogs.DIALOG_BTN_OK) {
                            // User has chosen to reload Chrome, quit the running instance
                            _setStatus(0);
                            NativeApp.closeLiveBrowser()
                                .done(function () {
                                    browserStarted = false;
                                    window.setTimeout(open);
                                })
                                .fail(function (err) {
                                    // Report error?
                                    _setStatus(-1);
                                    browserStarted = false;
                                });
                        }
                    });
                    return;
                }
                retryCount++;

                if (!browserStarted && exports.status !== -1) {
                    // If err === FileError.ERR_NOT_FOUND, it means a remote debugger connection
                    // is available, but the requested URL is not loaded in the browser. In that
                    // case we want to launch the live browser (to open the url in a new tab)
                    // without using the --remote-debugging-port flag. This works around issues
                    // on Windows where Chrome can't be opened more than once with the
                    // --remote-debugging-port flag set.
                    NativeApp.openLiveBrowser(
                        doc.root.url,
                        err !== FileError.ERR_NOT_FOUND
                    )
                        .done(function () {
                            browserStarted = true;
                        })
                        .fail(function (err) {
                            var message;

                            _setStatus(-1);
                            if (err === FileError.NOT_FOUND_ERR) {
                                message = Strings.ERROR_CANT_FIND_CHROME;
                            } else {
                                message = StringUtils.format(Strings.ERROR_LAUNCHING_BROWSER, err);
                            }

                            Dialogs.showModalDialog(
                                Dialogs.DIALOG_ID_ERROR,
                                Strings.ERROR_LAUNCHING_BROWSER_TITLE,
                                message
                            );
                        });
                }

                if (exports.status !== -1) {
                    window.setTimeout(function retryConnect() {
                        Inspector.connectToURL(doc.root.url).fail(onConnectFail);
                    }, 500);
                }
            });
        }
    }

    /** Close the Connection */
    function close() {
        if (Inspector.connected()) {
            Inspector.Runtime.evaluate("window.close()");
        }
        Inspector.disconnect();
        _setStatus(0);
    }

    /** Triggered by a document change from the DocumentManager */
    function _onDocumentChange() {
        var doc = _getCurrentDocument();
        if (!doc) {
            return;
        }

        if (Inspector.connected()) {
            if (agents.network && agents.network.wasURLRequested(doc.url)) {
                _closeDocument();
                var editor = EditorManager.getCurrentFullEditor();
                _openDocument(doc, editor);
            } else {
                /* FUTURE: support live connections for docments other than html */
                if (doc.extension && doc.extension.indexOf("htm") === 0 && doc.file.fullPath !== _htmlDocumentPath) {
                    close();
                    window.setTimeout(open);
                    _htmlDocumentPath = doc.file.fullPath;
                }
            }
        } else if (exports.config.autoconnect) {
            window.setTimeout(open);
        }
    }

    function getLiveDocForPath(path) {
        var docsToSearch = [];
        if (_relatedDocuments) {
            docsToSearch = docsToSearch.concat(_relatedDocuments);
        }
        if (_liveDocument) {
            docsToSearch = docsToSearch.concat(_liveDocument);
        }
        var foundDoc;
        docsToSearch.some(function matchesPath(ele) {
            if (ele.doc.file.fullPath === path) {
                foundDoc = ele;
                return true;
            }
            return false;
        });

        return foundDoc;
    }

    /** Hide any active highlighting */
    function hideHighlight() {
        if (Inspector.connected() && agents.highlight) {
            agents.highlight.hide();
        }
    }

    /** Initialize the LiveDevelopment Session */
    function init(theConfig) {
        exports.config = theConfig;
        Inspector.on("connect", _onConnect);
        Inspector.on("disconnect", _onDisconnect);
        Inspector.on("error", _onError);
        Inspector.on("load", _onLoad);
        $(DocumentManager).on("currentDocumentChange", _onDocumentChange);
    }

    // Export public functions
    exports.agents = agents;
    exports.open = open;
    exports.close = close;
    exports.enableAgent = enableAgent;
    exports.disableAgent = disableAgent;
    exports.getLiveDocForPath = getLiveDocForPath;
    exports.hideHighlight = hideHighlight;
    exports.init = init;
});<commit_msg>improve variable names and add a few comments<commit_after>/*
 * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */
/*global define, $, FileError, brackets, window */

/**
 * LiveDevelopment manages the Inspector, all Agents, and the active LiveDocument
 *
 * # STARTING
 *
 * To start a session call `open`. This will read the currentDocument from brackets,
 * launch the LiveBrowser (currently Chrome) with the remote debugger port open,
 * establish the Inspector connection to the remote debugger, and finally load all
 * agents.
 *
 * # STOPPING
 *
 * To stop a session call `close`. This will close the active browser window,
 * disconnect the Inspector, unload all agents, and clean up.
 *
 * # STATUS
 *
 * Status updates are dispatched as `statusChange` jQuery events. The status
 * codes are:
 *
 * -1: Error
 * 0: Inactive
 * 1: Connecting to the remote debugger
 * 2: Loading agents
 * 3: Active
 */
define(function LiveDevelopment(require, exports, module) {
    "use strict";

    var DocumentManager = require("document/DocumentManager");
    var EditorManager = require("editor/EditorManager");
    var NativeApp = require("utils/NativeApp");
    var Dialogs = require("widgets/Dialogs");
    var Strings = require("strings");
    var StringUtils = require("utils/StringUtils");

    // Inspector
    var Inspector = require("LiveDevelopment/Inspector/Inspector");

    // Documents
    var HTMLDocument = require("LiveDevelopment/Documents/HTMLDocument");
    var CSSDocument = require("LiveDevelopment/Documents/CSSDocument");
    var JSDocument = require("LiveDevelopment/Documents/JSDocument");

    // Agents
    var agents = {
        "console": require("LiveDevelopment/Agents/ConsoleAgent"),
        "remote": require("LiveDevelopment/Agents/RemoteAgent"),
        "network": require("LiveDevelopment/Agents/NetworkAgent"),
        "dom": require("LiveDevelopment/Agents/DOMAgent"),
        "css": require("LiveDevelopment/Agents/CSSAgent"),
        "script": require("LiveDevelopment/Agents/ScriptAgent"),
        "highlight": require("LiveDevelopment/Agents/HighlightAgent"),
        "goto": require("LiveDevelopment/Agents/GotoAgent"),
        "edit": require("LiveDevelopment/Agents/EditAgent")
    };

    // Some agents are still experimental, so we don't enable them all by default
    // However, extensions can enable them by calling enableAgent().
    // This object is used as a set (thus all properties have the value 'true').
    // Property names should match property names in the 'agents' object.
    var _enabledAgentNames = {
        "console": true,
        "remote": true,
        "network": true,
        "dom": true,
        "css": true
    };
    // store the names (matching property names in the 'agent' object) of agents that we've loaded
    var _loadedAgentNames = [];

    var _htmlDocumentPath; // the path of the html file open for live development
    var _liveDocument; // the document open for live editing.
    var _relatedDocuments; // CSS and JS documents that are used by the live HTML document

    /** Augments the given Brackets document with information that's useful for live development. */
    function _setDocInfo(doc) {
        // FUTURE: some of these things should just be moved into core Document; others should
        // be in a LiveDevelopment-specific object attached to the doc.
        var matches = /^(.*\/)(.+\.([^.]+))$/.exec(doc.file.fullPath);
        if (matches) {
            var prefix = "file://";

            // The file.fullPath on Windows starts with a drive letter ("C:").
            // In order to make it a valid file: URL we need to add an
            // additional slash to the prefix.
            if (brackets.platform === "win") {
                prefix += "/";
            }

            doc.extension = matches[3];
            doc.url = encodeURI(prefix + doc.file.fullPath);

            // the root represents the document that should be displayed in the browser
            // for live development (the file for HTML files, index.html for others)
            var fileName = /^html?$/.test(matches[3]) ? matches[2] : "index.html";
            doc.root = {url: encodeURI(prefix + matches[1] + fileName)};
        }
    }

    /** Get the current document from the document manager
     * _adds extension, url and root to the document
     */
    function _getCurrentDocument() {
        var doc = DocumentManager.getCurrentDocument();
        if (doc) {
            _setDocInfo(doc);
        }
        return doc;
    }

    /** Determine which document class should be used for a given document
     * @param {Document} document
     */
    function _classForDocument(doc) {
        switch (doc.extension) {
        case "css":
            return CSSDocument;
        /* FUTURE:
        case "js":
            return JSDocument;
        case "html":
        case "htm":
            return HTMLDocument;
        default:
            throw "Invalid document type: " + doc.extension;
        */
        }

        return null;
    }

    /**
     * Removes the given CSS/JSDocument from _relatedDocuments. Signals that the
     * given file is no longer associated with the HTML document that is live (e.g.
     * if the related file has been deleted on disk).
     */
    function _handleRelatedDocumentDeleted(event, liveDoc) {
        var index = _relatedDocuments.indexOf(liveDoc);
        if (index !== -1) {
            $(liveDoc).on("deleted", _handleRelatedDocumentDeleted);
            _relatedDocuments.splice(index, 1);
        }
    }

    /** Close a live document */
    function _closeDocument() {
        if (_liveDocument) {
            _liveDocument.close();
            _liveDocument = undefined;
        }
        if (_relatedDocuments) {
            _relatedDocuments.forEach(function (liveDoc) {
                liveDoc.close();
                $(liveDoc).off("deleted", _handleRelatedDocumentDeleted);
            });
            _relatedDocuments = undefined;
        }
    }

    /** Create a live version of a Brackets document */
    function _createDocument(doc, editor) {
        var DocClass = _classForDocument(doc);
        if (DocClass) {
            return new DocClass(doc, editor);
        } else {
            return null;
        }
    }

    /** Convert a file: URL to a local full file path */
    function _urlToPath(url) {
        var path;
        if (url.indexOf("file://") === 0) {
            path = url.slice(7);
            if (path && brackets.platform === "win" && path.charAt(0) === "/") {
                path = path.slice(1);
            }
        }
        return decodeURI(path);
    }

    /** Open a live document
     * @param {Document} source document to open
     */
    function _openDocument(doc, editor) {
        _closeDocument();
        _liveDocument = _createDocument(doc, editor);

        // Gather related CSS documents.
        // FUTURE: Gather related JS documents as well.
        _relatedDocuments = [];
        agents.css.getStylesheetURLs().forEach(function (url) {
            // FUTURE: when we get truly async file handling, we might need to prevent other
            // stuff from happening while we wait to add these listeners
            DocumentManager.getDocumentForPath(_urlToPath(url))
                .done(function (doc) {
                    _setDocInfo(doc);
                    var liveDoc = _createDocument(doc);
                    if (liveDoc) {
                        _relatedDocuments.push(liveDoc);
                        $(liveDoc).on("deleted", _handleRelatedDocumentDeleted);
                    }
                });
        });
    }

    /** Unload the agents */
    function unloadAgents() {
        _loadedAgentNames.forEach(function (i) {
            agents[i].unload();
        });
        _loadedAgentNames = [];
    }

    /** Load the agents */
    function loadAgents() {
        var i, promises = [];
        for (i in _enabledAgentNames) {
            if (_enabledAgentNames.hasOwnProperty(i) && agents.hasOwnProperty(i) && agents[i].load) {
                promises.push(agents[i].load());
                _loadedAgentNames.push(i);
            }
        }
        return promises;
    }

    /** Enable an agent. Takes effect next time a connection is made. Does not affect
     *  current live development sessions.
     *
     *  @param {string} name of agent to enable
     */
    function enableAgent(name) {
        if (!_enabledAgentNames.hasOwnProperty(name)) {
            _enabledAgentNames[name] = true;
        }
    }

    /** Disable an agent. Takes effect next time a connection is made. Does not affect
     *  current live development sessions.
     *
     *  @param {string} name of agent to disable
     */
    function disableAgent(name) {
        if (_enabledAgentNames.hasOwnProperty(name)) {
            delete _enabledAgentNames[name];
        }
    }

    /** Update the status
     * @param {integer} new status
     */
    function _setStatus(status) {
        exports.status = status;
        $(exports).triggerHandler("statusChange", status);
    }

    /** Triggered by Inspector.error */
    function _onError(error) {
        var message = error.message;

        // Additional information, like exactly which parameter could not be processed.
        var data = error.data;
        if (Array.isArray(data)) {
            message += "\n" + data.join("\n");
        }

        // Show the message, but include the error object for further information (e.g. error code)
        console.error(message, error);
    }

    /** Run when all agents are loaded */
    function _onLoad() {
        var doc = _getCurrentDocument();
        if (doc) {
            var editor = EditorManager.getCurrentFullEditor();
            _openDocument(doc, editor);
        }
        _setStatus(3);
    }

    /** Triggered by Inspector.connect */
    function _onConnect() {
        var promises = loadAgents();
        _setStatus(2);
        $.when.apply(undefined, promises).then(_onLoad, _onError);
    }

    /** Triggered by Inspector.disconnect */
    function _onDisconnect() {
        unloadAgents();
        _closeDocument();
        _setStatus(0);
    }

    /** Open the Connection and go live */
    function open() {
        var doc = _getCurrentDocument();
        var browserStarted = false;
        var retryCount = 0;

        function showWrongDocError() {
            Dialogs.showModalDialog(
                Dialogs.DIALOG_ID_ERROR,
                Strings.LIVE_DEVELOPMENT_ERROR_TITLE,
                Strings.LIVE_DEV_NEED_HTML_MESSAGE
            );
        }

        if (!doc || !doc.root) {
            showWrongDocError();

        } else {
            // For Sprint 6, we only open live development connections for HTML files
            // FUTURE: Remove this test when we support opening connections for different
            // file types.
            if (!doc.extension || doc.extension.indexOf("htm") !== 0) {
                showWrongDocError();
                return;
            }

            _setStatus(1);
            Inspector.connectToURL(doc.root.url).fail(function onConnectFail(err) {
                if (err === "CANCEL") {
                    return;
                }
                if (retryCount > 6) {
                    _setStatus(-1);
                    Dialogs.showModalDialog(
                        Dialogs.DIALOG_ID_LIVE_DEVELOPMENT,
                        Strings.LIVE_DEVELOPMENT_ERROR_TITLE,
                        Strings.LIVE_DEVELOPMENT_ERROR_MESSAGE
                    ).done(function (id) {
                        if (id === Dialogs.DIALOG_BTN_OK) {
                            // User has chosen to reload Chrome, quit the running instance
                            _setStatus(0);
                            NativeApp.closeLiveBrowser()
                                .done(function () {
                                    browserStarted = false;
                                    window.setTimeout(open);
                                })
                                .fail(function (err) {
                                    // Report error?
                                    _setStatus(-1);
                                    browserStarted = false;
                                });
                        }
                    });
                    return;
                }
                retryCount++;

                if (!browserStarted && exports.status !== -1) {
                    // If err === FileError.ERR_NOT_FOUND, it means a remote debugger connection
                    // is available, but the requested URL is not loaded in the browser. In that
                    // case we want to launch the live browser (to open the url in a new tab)
                    // without using the --remote-debugging-port flag. This works around issues
                    // on Windows where Chrome can't be opened more than once with the
                    // --remote-debugging-port flag set.
                    NativeApp.openLiveBrowser(
                        doc.root.url,
                        err !== FileError.ERR_NOT_FOUND
                    )
                        .done(function () {
                            browserStarted = true;
                        })
                        .fail(function (err) {
                            var message;

                            _setStatus(-1);
                            if (err === FileError.NOT_FOUND_ERR) {
                                message = Strings.ERROR_CANT_FIND_CHROME;
                            } else {
                                message = StringUtils.format(Strings.ERROR_LAUNCHING_BROWSER, err);
                            }

                            Dialogs.showModalDialog(
                                Dialogs.DIALOG_ID_ERROR,
                                Strings.ERROR_LAUNCHING_BROWSER_TITLE,
                                message
                            );
                        });
                }

                if (exports.status !== -1) {
                    window.setTimeout(function retryConnect() {
                        Inspector.connectToURL(doc.root.url).fail(onConnectFail);
                    }, 500);
                }
            });
        }
    }

    /** Close the Connection */
    function close() {
        if (Inspector.connected()) {
            Inspector.Runtime.evaluate("window.close()");
        }
        Inspector.disconnect();
        _setStatus(0);
    }

    /** Triggered by a document change from the DocumentManager */
    function _onDocumentChange() {
        var doc = _getCurrentDocument();
        if (!doc) {
            return;
        }

        if (Inspector.connected()) {
            if (agents.network && agents.network.wasURLRequested(doc.url)) {
                _closeDocument();
                var editor = EditorManager.getCurrentFullEditor();
                _openDocument(doc, editor);
            } else {
                /* FUTURE: support live connections for docments other than html */
                if (doc.extension && doc.extension.indexOf("htm") === 0 && doc.file.fullPath !== _htmlDocumentPath) {
                    close();
                    window.setTimeout(open);
                    _htmlDocumentPath = doc.file.fullPath;
                }
            }
        } else if (exports.config.autoconnect) {
            window.setTimeout(open);
        }
    }

    function getLiveDocForPath(path) {
        var docsToSearch = [];
        if (_relatedDocuments) {
            docsToSearch = docsToSearch.concat(_relatedDocuments);
        }
        if (_liveDocument) {
            docsToSearch = docsToSearch.concat(_liveDocument);
        }
        var foundDoc;
        docsToSearch.some(function matchesPath(ele) {
            if (ele.doc.file.fullPath === path) {
                foundDoc = ele;
                return true;
            }
            return false;
        });

        return foundDoc;
    }

    /** Hide any active highlighting */
    function hideHighlight() {
        if (Inspector.connected() && agents.highlight) {
            agents.highlight.hide();
        }
    }

    /** Initialize the LiveDevelopment Session */
    function init(theConfig) {
        exports.config = theConfig;
        Inspector.on("connect", _onConnect);
        Inspector.on("disconnect", _onDisconnect);
        Inspector.on("error", _onError);
        Inspector.on("load", _onLoad);
        $(DocumentManager).on("currentDocumentChange", _onDocumentChange);
    }

    // Export public functions
    exports.agents = agents;
    exports.open = open;
    exports.close = close;
    exports.enableAgent = enableAgent;
    exports.disableAgent = disableAgent;
    exports.getLiveDocForPath = getLiveDocForPath;
    exports.hideHighlight = hideHighlight;
    exports.init = init;
});<|endoftext|>


<commit_before>/* ========================================================================
* DOM-based Routing
* Based on http://goo.gl/EUTi53 by Paul Irish
*
* Only fires on body classes that match. If a body class contains a dash,
* replace the dash with an underscore when adding it to the object below.
*
* .noConflict()
* The routing is enclosed within an anonymous function so that you can
* always reference jQuery with $, even when in .noConflict() mode.
*
* Google CDN, Latest jQuery
* To use the default WordPress version of jQuery, go to lib/config.php and
* remove or comment out: add_theme_support('jquery-cdn');
* ======================================================================== */

(function($) {

    // Use this variable to set up the common and page specific functions. If you
    // rename this variable, you will also need to rename the namespace below.
    var Sage = {
        // All pages
        'common': {
            init: function() {
                $('.gallery').owlCarousel({
                    //navigation : true, // Show next and prev buttons
                    slideSpeed : 300,
                    paginationSpeed : 400,
                    items : 1
                    //singleItem:true
                });

                $("#promotions-crousel").owlCarousel({
                    items : 3,
                    itemsDesktop : [1199,3],
                    itemsDesktopSmall : [979,3]
                });

                $('a[href*=#]:not([href=#])').click(function() {
                    if (location.pathname.replace(/^\//,'') === this.pathname.replace(/^\//,'') && location.hostname === this.hostname) {
                        var target = $(this.hash);
                        target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
                        if (target.length) {
                            $('html,body').animate({
                                scrollTop: (target.offset().top) - ($("header").outerHeight())
                            }, 1000);
                            return false;
                        }
                    }
                });

                $(window).scroll(function() {
                    if ($(this).scrollTop() > 1){
                        $('header').addClass("stick");
                    }
                    else{
                        $('header').removeClass("stick");
                    }
                });

                var frominput = $('#departure').pickadate({
                    min : 1
                });
                var toinput = $('#return').pickadate();

                var frompicker = frominput.pickadate('picker');
                var topicker = toinput.pickadate('picker');

                if ( frompicker.get('value') ) {
                    topicker.set('min', frompicker.get('select'));
                }
                if ( topicker.get('value') ) {
                    frompicker.set('max', topicker.get('select'));
                }

                // When something is selected, update the “from” and “to” limits.
                frompicker.on('set', function(event) {
                    console.log(event);
                    if ( event.select ) {
                        topicker.set('min', frompicker.get('select'));
                    }
                });

                topicker.on('set', function(event) {
                    if ( event.select ) {
                        frompicker.set('max', topicker.get('select'));
                    }
                });

                $('#sidebar-toggle').on('click', function(event){
                    $('.left.sidebar').sidebar('toggle');
                });

                $('.left.sidebar .item').on('click', function(event){
                    $('.left.sidebar').sidebar('hide');
                });

                $('.ui .checkbox').checkbox();

                $('select.dropdown').dropdown();

                $(function(){
                    $('.mobile-menu').on('click', function(){
                        $('#mobile-sidebar').sidebar('toggle');
                    });
                    $('#side-menu').on('click', function(){
                        $('.book.sidebar').sidebar('toggle');
                    });
                });

                $('.tabular.menu .item').tab();

            },
            finalize: function() {

                // JavaScript to be fired on all pages, after page specific JS is fired
            }
        },
        // Home page
        'home': {
            init: function() {

            },
            finalize: function() {
                // JavaScript to be fired on the home page, after the init JS
            }
        },
        // About us page, note the change from about-us to about_us.
        'about_us': {
            init: function() {
                // JavaScript to be fired on the about us page
            }
        },
        'catalog': {
            init: function() {
                $('.dimmable-image .image').dimmer({ on: 'hover' });
            }
        },
        'single-product': {
            init: function() {
                alert('hello');
            }
        }
    };

    // The routing fires all common scripts, followed by the page specific scripts.
    // Add additional events for more control over timing e.g. a finalize event
    var UTIL = {
        fire: function(func, funcname, args) {
            var fire;
            var namespace = Sage;
            funcname = (funcname === undefined) ? 'init' : funcname;
            fire = func !== '';
            fire = fire && namespace[func];
            fire = fire && typeof namespace[func][funcname] === 'function';

            if (fire) {
                namespace[func][funcname](args);
            }
        },
        loadEvents: function() {
            // Fire common init JS
            UTIL.fire('common');

            // Fire page-specific init JS, and then finalize JS
            $.each(document.body.className.replace(/-/g, '_').split(/\s+/), function(i, classnm) {
                UTIL.fire(classnm);
                UTIL.fire(classnm, 'finalize');
            });

            // Fire common finalize JS
            UTIL.fire('common', 'finalize');
        }
    };

    // Load Events
    $(document).ready(UTIL.loadEvents);

})(jQuery); // Fully reference jQuery after this point.
<commit_msg>Form and message script<commit_after>/* ========================================================================
* DOM-based Routing
* Based on http://goo.gl/EUTi53 by Paul Irish
*
* Only fires on body classes that match. If a body class contains a dash,
* replace the dash with an underscore when adding it to the object below.
*
* .noConflict()
* The routing is enclosed within an anonymous function so that you can
* always reference jQuery with $, even when in .noConflict() mode.
*
* Google CDN, Latest jQuery
* To use the default WordPress version of jQuery, go to lib/config.php and
* remove or comment out: add_theme_support('jquery-cdn');
* ======================================================================== */

(function($) {

    // Use this variable to set up the common and page specific functions. If you
    // rename this variable, you will also need to rename the namespace below.
    var Sage = {
        // All pages
        'common': {
            init: function() {
                $('.gallery').owlCarousel({
                    //navigation : true, // Show next and prev buttons
                    slideSpeed : 300,
                    paginationSpeed : 400,
                    items : 1
                    //singleItem:true
                });

                $("#promotions-crousel").owlCarousel({
                    items : 3,
                    itemsDesktop : [1199,3],
                    itemsDesktopSmall : [979,3]
                });

                $('a[href*=#]:not([href=#])').click(function() {
                    if (location.pathname.replace(/^\//,'') === this.pathname.replace(/^\//,'') && location.hostname === this.hostname) {
                        var target = $(this.hash);
                        target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
                        if (target.length) {
                            $('html,body').animate({
                                scrollTop: (target.offset().top) - ($("header").outerHeight())
                            }, 1000);
                            return false;
                        }
                    }
                });

                $(window).scroll(function() {
                    if ($(this).scrollTop() > 1){
                        $('header').addClass("stick");
                    }
                    else{
                        $('header').removeClass("stick");
                    }
                });

                var frominput = $('#departure').pickadate({
                    min : 1
                });
                var toinput = $('#return').pickadate();

                var frompicker = frominput.pickadate('picker');
                var topicker = toinput.pickadate('picker');

                if ( frompicker.get('value') ) {
                    topicker.set('min', frompicker.get('select'));
                }
                if ( topicker.get('value') ) {
                    frompicker.set('max', topicker.get('select'));
                }

                // When something is selected, update the “from” and “to” limits.
                frompicker.on('set', function(event) {
                    console.log(event);
                    if ( event.select ) {
                        topicker.set('min', frompicker.get('select'));
                    }
                });

                topicker.on('set', function(event) {
                    if ( event.select ) {
                        frompicker.set('max', topicker.get('select'));
                    }
                });

                $('#sidebar-toggle').on('click', function(event){
                    $('.left.sidebar').sidebar('toggle');
                });

                $('.left.sidebar .item').on('click', function(event){
                    $('.left.sidebar').sidebar('hide');
                });

                $('.ui .checkbox').checkbox();

                $('select.dropdown').dropdown();

                $(function(){
                    $('.mobile-menu').on('click', function(){
                        $('#mobile-sidebar').sidebar('toggle');
                    });
                    $('#side-menu').on('click', function(){
                        $('.book.sidebar').sidebar('toggle');
                    });
                });

                $('.tabular.menu .item').tab();

                $('.message .close').on('click', function() {
                    $(this).closest('.message').fadeOut();
                });

            },
            finalize: function() {

                // JavaScript to be fired on all pages, after page specific JS is fired
            }
        },
        // Home page
        'home': {
            init: function() {
                validationRules =
                {
                    destination: {
                        identifier  : 'destination',
                        rules: [
                            {
                                type   : 'empty',
                                prompt : 'Please enter your destination'
                            }
                        ]
                    },
                    departure: {
                        identifier  : 'departure',
                        rules: [
                            {
                                type   : 'empty',
                                prompt : 'Please enter the departure date'
                            }
                        ]
                    },
                    return: {
                        identifier  : 'return',
                        rules: [
                            {
                                type   : 'empty',
                                prompt : 'Please enter the return date'
                            }
                        ]
                    },
                    adults: {
                        identifier  : 'adults',
                        rules: [
                            {
                                type   : 'empty',
                                prompt : 'Please enter the number of adults'
                            }
                        ]
                    },
                    kids: {
                        identifier  : 'kids',
                        rules: [
                            {
                                type   : 'empty',
                                prompt : 'Please enter the number of kids'
                            }
                        ]
                    },
                    travel: {
                        identifier  : 'travel',
                        rules: [
                            {
                                type   : 'checked',
                                prompt : 'Please select at least one type of travel'
                            }
                        ]
                    }
                };

                $('.ui.form')
                    .form(validationRules,
                    {
                        onSuccess : function(){
                            var form = $('.ui.form');
                            var submitButton = $('#request-submit');
                            allFields = form.form('get values');
                            submitButton.addClass('loading');
                            $.ajax({
                                method: "POST",
                                url: sage_vars.ajaxurl,
                                data: allFields
                            })
                                .done(function( msg ) {
                                    submitButton.removeClass('loading');
                                    $('.positive-request').removeClass('hidden');
                                    form.form('clear');
                                });
                            return false;
                        }
                    });

            },
            finalize: function() {
                // JavaScript to be fired on the home page, after the init JS
            }
        },
        // About us page, note the change from about-us to about_us.
        'about_us': {
            init: function() {
                // JavaScript to be fired on the about us page
            }
        },
        'catalog': {
            init: function() {
                $('.dimmable-image .image').dimmer({ on: 'hover' });
            }
        },
        'single-product': {
            init: function() {
                alert('hello');
            }
        }
    };

    // The routing fires all common scripts, followed by the page specific scripts.
    // Add additional events for more control over timing e.g. a finalize event
    var UTIL = {
        fire: function(func, funcname, args) {
            var fire;
            var namespace = Sage;
            funcname = (funcname === undefined) ? 'init' : funcname;
            fire = func !== '';
            fire = fire && namespace[func];
            fire = fire && typeof namespace[func][funcname] === 'function';

            if (fire) {
                namespace[func][funcname](args);
            }
        },
        loadEvents: function() {
            // Fire common init JS
            UTIL.fire('common');

            // Fire page-specific init JS, and then finalize JS
            $.each(document.body.className.replace(/-/g, '_').split(/\s+/), function(i, classnm) {
                UTIL.fire(classnm);
                UTIL.fire(classnm, 'finalize');
            });

            // Fire common finalize JS
            UTIL.fire('common', 'finalize');
        }
    };

    // Load Events
    $(document).ready(UTIL.loadEvents);

})(jQuery); // Fully reference jQuery after this point.
<|endoftext|>


<commit_before>define(['globals','jquery'], function (Globals,$) {
  'use strict';

  var MGUI = function(){};

  MGUI.prototype.init = function(){
    Globals.currentClient.delegate = this;

  	this.minescontainer = document.getElementById('minesweeper-container');
  	if(!this.minescontainer) {
  		throw 'container doesnt exist';
  	}
  	this.minescontainer.innerHTML = this.renderHTML();

  	window.setTimeout(this.setOnFieldClickListener.bind(this), 0);
  	window.setTimeout(this.setControlListener.bind(this), 0);
  	window.setTimeout(this.timerUpdate.bind(this), 0);
  }
  MGUI.prototype.constructor = MGUI;

  var HTMLRenderingFunctions = (function(){
    function renderHTML() {
      var htmlControls = this.renderHTMLControls();
      var htmlFields = this.renderHTMLFields();
      return htmlControls + htmlFields;
    }
    function renderHTMLControls() {
      var html = '
';

      html += this.renderHTMLControlLevelSelector();
      html += '

';
      html += '

0:00
';
      html += '

';
      html += '

99
';

      html += '

';
      return html;
    }
    function renderHTMLControlLevelSelector() {
      var maxLevel = 5;
      var html = '<select id="assist-level-selector" style="float:left">';
      for(var i=0; i<=maxLevel; ++i){
        html += '<option value="' + i + '"'+(i===maxLevel?' selected':'')+'>Assist Level ' + i + '</option>';
      }
      html += '</select>';
      return html;
    }
    function renderHTMLFields() {
      var rows = Globals.currentClient.mMap.rows;
      var cols = Globals.currentClient.mMap.cols;

      var htmlmap = '
';
      var i=0;
      for(var y=0; y<rows; y++){
        htmlmap += '
';
        for(var x=0; x<cols; ++x, ++i){
          htmlmap += '

';
        }
        htmlmap += '

';
      }
      htmlmap += '
';
      return htmlmap;
    }
    return function() {
      this.renderHTML = renderHTML;
      this.renderHTMLControls = renderHTMLControls;
      this.renderHTMLControlLevelSelector = renderHTMLControlLevelSelector;
      this.renderHTMLFields = renderHTMLFields;
      return this;
    }
  })();

	/** Client Callbacks **/
  var MClientCallbackFunctions = (function() {
    function onOpenFieldListener(fieldsToOpen, fieldsToOpenNext) {
      for(var i=fieldsToOpen.length-1; i>=0; --i){
        var mField = fieldsToOpen[i];
        var div = this.getFieldOnPosition(mField.x, mField.y);
        div.addClass('mopen');
        if(mField.isMine) div.addClass("mmine");
        else if(mField.isFlag) alert("shouldn't be called here oO");
        else div.addClass('m' + mField.minesAround);
      }

      if(fieldsToOpenNext.length > 0){
        window.setTimeout(function(){
          Globals.currentClient.openFields(fieldsToOpenNext);
        },200);
      }
    }
    function onFlagFieldListener(fieldToFlag) {
      console.log('field got flagged'+fieldToFlag);
      var div = this.getFieldOnPosition(fieldToFlag.x, fieldToFlag.y);
      if(fieldToFlag.isFlagged) div.addClass('mflag');
      else div.removeClass('mflag');
    }
    function onLose() {
      window.setTimeout(function(){
        alert("you lose!");
      },0);
    }
    function onWin() {
      window.setTimeout(function(){
        alert("gratulations! you win!");
      },0);
    }
    function onReset() {
      console.log('reset was executed');
    }
    function onFlagAmountChanged(flagsLeft) {
      console.log('amount of flags changed to: '+flagsLeft);

      // TODO: getting the elements should ne done in an init method
      document.getElementById('mmine-counter').innerHTML = flagsLeft;
    }
    return function() {
      this.onOpenFieldListener = onOpenFieldListener;
      this.onFlagFieldListener = onFlagFieldListener;
      this.onLose = onLose;
      this.onWin = onWin;
      this.onReset = onReset;
      this.onFlagAmountChanged = onFlagAmountChanged;
      return this;
    }
  })();

  var MinesGUIClientUtilFunctions = (function(){
    function getFieldOnPosition(x,y) {
      var row = $('#' + y + '.mrow');
      return $('#' + x + '.mfield', row);
    }
    return function(){
      this.getFieldOnPosition = getFieldOnPosition;
      return this;
    }
  })();

  var HTMLListenerFunctions = (function(){
    function setControlListener() {
      $('#assist-level-selector').change(this.setChangeAssistLevelListener);
    }
    function setChangeAssistLevelListener() {
      var newSelectedLevel = parseInt($('#assist-level-selector option:selected').attr('value'));
      Globals.currentClient.assistLevel = newSelectedLevel;
    }
    function onFieldClickListener(event) {
      var button = event.target;
      var mFieldX = parseInt(button.getAttribute('mfieldx'));
      var mFieldY = parseInt(button.getAttribute('mfieldy'));

      console.log('GUI: left click on Cell[X:'+mFieldX+', Y:'+mFieldY+']');
      Globals.currentClient.clickedAtField(mFieldX,mFieldY);
    }
    function onRightClickListener(event) {
      event.preventDefault();

      var button = event.target;
      var mFieldX = parseInt(button.getAttribute('mfieldx'));
      var mFieldY = parseInt(button.getAttribute('mfieldy'));

      console.log('GUI: right click on Cell[X:' + mFieldX + ', Y:' + mFieldY + ']');
      Globals.currentClient.flagField(mFieldX,mFieldY);
    }
    function onDoubleClickListener(event) {
      var button = event.target;
      var mFieldX = parseInt(button.getAttribute('mfieldx'));
      var mFieldY = parseInt(button.getAttribute('mfieldy'));
      Globals.currentClient.openMinesAroundOpenField(mFieldX,mFieldY);
    }
    function onDoubleClickListener(event) {
      var button = event.target;
      var mFieldX = parseInt(button.getAttribute('mfieldx'));
      var mFieldY = parseInt(button.getAttribute('mfieldy'));
      Globals.currentClient.openMinesAroundOpenField(mFieldX,mFieldY);
    }
    function setOnFieldClickListener() {
      var jFields = $('.mfield');

      // Left click
      jFields.unbind('click');
      jFields.click(this.onFieldClickListener);

      // Right click
      jFields.unbind('contextmenu');
      jFields.bind('contextmenu', this.onRightClickListener);

      // Double click
      jFields.unbind('dblclick');
      jFields.dblclick(this.onDoubleClickListener);
    }
    return function(){
      this.setControlListener = setControlListener;
      this.setChangeAssistLevelListener = setChangeAssistLevelListener;
      this.onFieldClickListener = onFieldClickListener;
      this.onRightClickListener = onRightClickListener;
      this.onDoubleClickListener = onDoubleClickListener;
      this.onDoubleClickListener = onDoubleClickListener;
      this.setOnFieldClickListener = setOnFieldClickListener;
      return this;
    }
  })();

	MGUI.prototype.timerUpdate = function(){
  	var secondsPassed = Globals.currentClient.getSecondsPassed();

  	var seconds = secondsPassed % 60;
		var minutes = Math.floor(secondsPassed / 60);
		var secondsStr = seconds < 10 ? '0'+seconds : seconds;
		$('#mtime-counter').html(minutes + ':' + secondsStr);

  	setTimeout(this.timerUpdate, 1000);
  }

  HTMLRenderingFunctions.call(MGUI.prototype);
  MClientCallbackFunctions.call(MGUI.prototype);
  MinesGUIClientUtilFunctions.call(MGUI.prototype);
  HTMLListenerFunctions.call(MGUI.prototype);

  return MGUI;
});
<commit_msg>loosened jQuery Bindings<commit_after>define(['globals','jquery'], function (Globals,$) {
  'use strict';

  var MGUI = function(){};

  MGUI.prototype.init = function(){
    Globals.currentClient.delegate = this;

  	this.minescontainer = document.getElementById('minesweeper-container');
  	if(!this.minescontainer) {
  		throw 'container doesnt exist';
  	}
  	this.minescontainer.innerHTML = this.renderHTML();

  	window.setTimeout(this.setOnFieldClickListener.bind(this), 0);
  	window.setTimeout(this.setControlListener.bind(this), 0);
  	window.setTimeout(this.timerUpdate.bind(this), 0);
  }
  MGUI.prototype.constructor = MGUI;

  var HTMLRenderingFunctions = (function(){
    function renderHTML() {
      var htmlControls = this.renderHTMLControls();
      var htmlFields = this.renderHTMLFields();
      return htmlControls + htmlFields;
    }
    function renderHTMLControls() {
      var html = '
';

      html += this.renderHTMLControlLevelSelector();
      html += '

';
      html += '

0:00
';
      html += '

';
      html += '

99
';

      html += '

';
      return html;
    }
    function renderHTMLControlLevelSelector() {
      var maxLevel = 5;
      var html = '<select id="assist-level-selector" style="float:left">';
      for(var i=0; i<=maxLevel; ++i){
        html += '<option value="' + i + '"'+(i===maxLevel?' selected':'')+'>Assist Level ' + i + '</option>';
      }
      html += '</select>';
      return html;
    }
    function renderHTMLFields() {
      var rows = Globals.currentClient.mMap.rows;
      var cols = Globals.currentClient.mMap.cols;

      var htmlmap = '
';
      var i=0;
      for(var y=0; y<rows; y++){
        htmlmap += '
';
        for(var x=0; x<cols; ++x, ++i){
          htmlmap += '

';
        }
        htmlmap += '

';
      }
      htmlmap += '
';
      return htmlmap;
    }
    return function() {
      this.renderHTML = renderHTML;
      this.renderHTMLControls = renderHTMLControls;
      this.renderHTMLControlLevelSelector = renderHTMLControlLevelSelector;
      this.renderHTMLFields = renderHTMLFields;
      return this;
    }
  })();

	/** Client Callbacks **/
  var MClientCallbackFunctions = (function() {
    function addClass(elem, c) {
      elem.className += ' '+c;
    }
    function removeClass(elem, c) {
      elem.className.replace(c, '');
    }
    function onOpenFieldListener(fieldsToOpen, fieldsToOpenNext) {
      for(var i=fieldsToOpen.length-1; i>=0; --i){
        var mField = fieldsToOpen[i];
        var div = this.getFieldOnPosition(mField.x, mField.y);
        addClass(div,'mopen');
        if(mField.isMine) addClass(div, 'mmine');
        else if(mField.isFlag) alert("shouldn't be called here oO");
        else addClass(div, 'm' + mField.minesAround);
      }

      if(fieldsToOpenNext.length > 0){
        window.setTimeout(function(){
          Globals.currentClient.openFields(fieldsToOpenNext);
        },200);
      }
    }
    function onFlagFieldListener(fieldToFlag) {
      console.log('field got flagged'+fieldToFlag);
      var div = this.getFieldOnPosition(fieldToFlag.x, fieldToFlag.y);
      if(fieldToFlag.isFlagged) addClass(div,'mflag');
      else removeClass(div,'mflag');
    }
    function onLose() {
      window.setTimeout(function(){
        alert("you lose!");
      },0);
    }
    function onWin() {
      window.setTimeout(function(){
        alert("gratulations! you win!");
      },0);
    }
    function onReset() {
      console.log('reset was executed');
    }
    function onFlagAmountChanged(flagsLeft) {
      console.log('amount of flags changed to: '+flagsLeft);

      // TODO: getting the elements should ne done in an init method
      document.getElementById('mmine-counter').innerHTML = flagsLeft;
    }
    return function() {
      this.onOpenFieldListener = onOpenFieldListener;
      this.onFlagFieldListener = onFlagFieldListener;
      this.onLose = onLose;
      this.onWin = onWin;
      this.onReset = onReset;
      this.onFlagAmountChanged = onFlagAmountChanged;
      return this;
    }
  })();

  var MinesGUIClientUtilFunctions = (function(){
    function getFieldOnPosition(x,y) {
      var row = document.getElementById('mrow'+y);
      return row.children[x];
    }
    return function(){
      this.getFieldOnPosition = getFieldOnPosition;
      return this;
    }
  })();

  var HTMLListenerFunctions = (function(){
    function setControlListener() {
      var assistLevelControl = document.getElementById('assist-level-selector');
      assistLevelControl.onchange = this.setChangeAssistLevelListener;
    }
    function setChangeAssistLevelListener() {
      var assistLevelControl = document.getElementById('assist-level-selector');
      var newSelectedLevel = parseInt(e.options[e.selectedIndex].value);
      Globals.currentClient.assistLevel = newSelectedLevel;
    }
    function onFieldClickListener(event) {
      var button = event.target;
      var mFieldX = parseInt(button.getAttribute('mfieldx'));
      var mFieldY = parseInt(button.getAttribute('mfieldy'));

      console.log('GUI: left click on Cell[X:'+mFieldX+', Y:'+mFieldY+']');
      Globals.currentClient.clickedAtField(mFieldX,mFieldY);
    }
    function onRightClickListener(event) {
      event.preventDefault();

      var button = event.target;
      var mFieldX = parseInt(button.getAttribute('mfieldx'));
      var mFieldY = parseInt(button.getAttribute('mfieldy'));

      console.log('GUI: right click on Cell[X:' + mFieldX + ', Y:' + mFieldY + ']');
      Globals.currentClient.flagField(mFieldX,mFieldY);
    }
    function onDoubleClickListener(event) {
      var button = event.target;
      var mFieldX = parseInt(button.getAttribute('mfieldx'));
      var mFieldY = parseInt(button.getAttribute('mfieldy'));
      Globals.currentClient.openMinesAroundOpenField(mFieldX,mFieldY);
    }
    function onDoubleClickListener(event) {
      var button = event.target;
      var mFieldX = parseInt(button.getAttribute('mfieldx'));
      var mFieldY = parseInt(button.getAttribute('mfieldy'));
      Globals.currentClient.openMinesAroundOpenField(mFieldX,mFieldY);
    }
    function setOnFieldClickListener() {
      var jFields = $('.mfield');

      // Left click
      jFields.unbind('click');
      jFields.click(this.onFieldClickListener);

      // Right click
      jFields.unbind('contextmenu');
      jFields.bind('contextmenu', this.onRightClickListener);

      // Double click
      jFields.unbind('dblclick');
      jFields.dblclick(this.onDoubleClickListener);
    }
    return function(){
      this.setControlListener = setControlListener;
      this.setChangeAssistLevelListener = setChangeAssistLevelListener;
      this.onFieldClickListener = onFieldClickListener;
      this.onRightClickListener = onRightClickListener;
      this.onDoubleClickListener = onDoubleClickListener;
      this.onDoubleClickListener = onDoubleClickListener;
      this.setOnFieldClickListener = setOnFieldClickListener;
      return this;
    }
  })();

	MGUI.prototype.timerUpdate = function(){
  	var secondsPassed = Globals.currentClient.getSecondsPassed();

  	var seconds = secondsPassed % 60;
		var minutes = Math.floor(secondsPassed / 60);
		var secondsStr = seconds < 10 ? '0'+seconds : seconds;
		$('#mtime-counter').html(minutes + ':' + secondsStr);

  	setTimeout(this.timerUpdate, 1000);
  }

  HTMLRenderingFunctions.call(MGUI.prototype);
  MClientCallbackFunctions.call(MGUI.prototype);
  MinesGUIClientUtilFunctions.call(MGUI.prototype);
  HTMLListenerFunctions.call(MGUI.prototype);

  return MGUI;
});
<|endoftext|>