<commit_before>;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.dropdown = {
    name : 'dropdown',

    version : '5.1.1',

    settings : {
      active_class: 'open',
      is_hover: false,
      opened: function(){},
      closed: function(){}
    },

    init : function (scope, method, options) {
      Foundation.inherit(this, 'throttle');

      this.bindings(method, options);
    },

    events : function (scope) {
      var self = this,
          S = self.S;

      S(this.scope)
        .off('.dropdown')
        .on('click.fndtn.dropdown', '[' + this.attr_name() + ']', function (e) {
          var settings = S(this).data(self.attr_name(true) + '-init') || self.settings;
          e.preventDefault();
          if (!settings.is_hover || Modernizr.touch) self.toggle(S(this));
        })
        .on('mouseenter.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) {
          var $this = S(this);
          clearTimeout(self.timeout);

          if ($this.data(self.data_attr())) {
            var dropdown = S('#' + $this.data(self.data_attr())),
                target = $this;
          } else {
            var dropdown = $this;
                target = S("[" + self.attr_name() + "='" + dropdown.attr('id') + "']");
          }

          var settings = target.data(self.attr_name(true) + '-init') || self.settings;

          if(S(e.target).data(self.data_attr()) && settings.is_hover) {
            self.closeall.call(self);
          }

          if (settings.is_hover) self.open.apply(self, [dropdown, target]);
        })
        .on('mouseleave.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) {
          var $this = S(this);
          self.timeout = setTimeout(function () {
            if ($this.data(self.data_attr())) {
              var settings = $this.data(self.data_attr(true) + '-init') || self.settings;
              if (settings.is_hover) self.close.call(self, S('#' + $this.data(self.data_attr())));
            } else {
              var target = S('[' + self.attr_name() + '="' + S(this).attr('id') + '"]'),
                  settings = target.data(self.attr_name(true) + '-init') || self.settings;
              if (settings.is_hover) self.close.call(self, $this);
            }
          }.bind(this), 150);
        })
        .on('click.fndtn.dropdown', function (e) {
          var parent = S(e.target).closest('[' + self.attr_name() + '-content]');

          if (S(e.target).data(self.data_attr()) || S(e.target).parent().data(self.data_attr())) {
            return;
          }
          if (!(S(e.target).data('revealId')) &&
            (parent.length > 0 && (S(e.target).is('[' + self.attr_name() + '-content]') ||
              $.contains(parent.first()[0], e.target)))) {
            e.stopPropagation();
            return;
          }

          self.close.call(self, S('[' + self.attr_name() + '-content]'));
        })
        .on('opened.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () {
            self.settings.opened.call(this);
        })
        .on('closed.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () {
            self.settings.closed.call(this);
        });

      S(window)
        .off('.dropdown')
        .on('resize.fndtn.dropdown', self.throttle(function () {
          self.resize.call(self);
        }, 50)).trigger('resize');
    },

    close: function (dropdown) {
      var self = this;
      dropdown.each(function () {
        if (self.S(this).hasClass(self.settings.active_class)) {
          self.S(this)
            .css(Foundation.rtl ? 'right':'left', '-99999px')
            .removeClass(self.settings.active_class);
          self.S(this).trigger('closed');
        }
      });
    },

    closeall: function() {
      var self = this;
      $.each(self.S('[' + this.attr_name() + '-content]'), function() {
        self.close.call(self, self.S(this))
      });
    },

    open: function (dropdown, target) {
        this
          .css(dropdown
            .addClass(this.settings.active_class), target);
        dropdown.trigger('opened');
    },

    data_attr: function () {
      if (this.namespace.length > 0) {
        return this.namespace + '-' + this.name;
      }

      return this.name;
    },

    toggle : function (target) {
      var dropdown = this.S('#' + target.data(this.data_attr()));
      if (dropdown.length === 0) {
        // No dropdown found, not continuing
        return;
      }

      this.close.call(this, this.S('[' + this.attr_name() + '-content]').not(dropdown));

      if (dropdown.hasClass(this.settings.active_class)) {
        this.close.call(this, dropdown);
      } else {
        this.close.call(this, this.S('[' + this.attr_name() + '-content]'))
        this.open.call(this, dropdown, target);
      }
    },

    resize : function () {
      var dropdown = this.S('[' + this.attr_name() + '-content].open'),
          target = this.S("[" + this.attr_name() + "='" + dropdown.attr('id') + "']");

      if (dropdown.length && target.length) {
        this.css(dropdown, target);
      }
    },

    css : function (dropdown, target) {
      var offset_parent = dropdown.offsetParent(),
          position = target.offset();

      position.top -= offset_parent.offset().top;
      position.left -= offset_parent.offset().left;

      if (this.small()) {
        dropdown.css({
          position : 'absolute',
          width: '95%',
          'max-width': 'none',
          top: position.top + target.outerHeight()
        });
        dropdown.css(Foundation.rtl ? 'right':'left', '2.5%');
      } else {
        if (!Foundation.rtl && this.S(window).width() > dropdown.outerWidth() + target.offset().left) {
          var left = position.left;
          if (dropdown.hasClass('right')) {
            dropdown.removeClass('right');
          }
        } else {
          if (!dropdown.hasClass('right')) {
            dropdown.addClass('right');
          }
          var left = position.left - (dropdown.outerWidth() - target.outerWidth());
        }

        dropdown.attr('style', '').css({
          position : 'absolute',
          top: position.top + target.outerHeight(),
          left: left
        });
      }

      return dropdown;
    },

    small : function () {
      return matchMedia(Foundation.media_queries.small).matches &&
        !matchMedia(Foundation.media_queries.medium).matches;
    },

    off: function () {
      this.S(this.scope).off('.fndtn.dropdown');
      this.S('html, body').off('.fndtn.dropdown');
      this.S(window).off('.fndtn.dropdown');
      this.S('[data-dropdown-content]').off('.fndtn.dropdown');
      this.settings.init = false;
    },

    reflow : function () {}
  };
}(jQuery, this, this.document));
<commit_msg>Immediately fire resize method, don't trigger resize event, because faster.<commit_after>;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.dropdown = {
    name : 'dropdown',

    version : '5.1.1',

    settings : {
      active_class: 'open',
      is_hover: false,
      opened: function(){},
      closed: function(){}
    },

    init : function (scope, method, options) {
      Foundation.inherit(this, 'throttle');

      this.bindings(method, options);
    },

    events : function (scope) {
      var self = this,
          S = self.S;

      S(this.scope)
        .off('.dropdown')
        .on('click.fndtn.dropdown', '[' + this.attr_name() + ']', function (e) {
          var settings = S(this).data(self.attr_name(true) + '-init') || self.settings;
          e.preventDefault();
          if (!settings.is_hover || Modernizr.touch) self.toggle(S(this));
        })
        .on('mouseenter.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) {
          var $this = S(this);
          clearTimeout(self.timeout);

          if ($this.data(self.data_attr())) {
            var dropdown = S('#' + $this.data(self.data_attr())),
                target = $this;
          } else {
            var dropdown = $this;
                target = S("[" + self.attr_name() + "='" + dropdown.attr('id') + "']");
          }

          var settings = target.data(self.attr_name(true) + '-init') || self.settings;

          if(S(e.target).data(self.data_attr()) && settings.is_hover) {
            self.closeall.call(self);
          }

          if (settings.is_hover) self.open.apply(self, [dropdown, target]);
        })
        .on('mouseleave.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) {
          var $this = S(this);
          self.timeout = setTimeout(function () {
            if ($this.data(self.data_attr())) {
              var settings = $this.data(self.data_attr(true) + '-init') || self.settings;
              if (settings.is_hover) self.close.call(self, S('#' + $this.data(self.data_attr())));
            } else {
              var target = S('[' + self.attr_name() + '="' + S(this).attr('id') + '"]'),
                  settings = target.data(self.attr_name(true) + '-init') || self.settings;
              if (settings.is_hover) self.close.call(self, $this);
            }
          }.bind(this), 150);
        })
        .on('click.fndtn.dropdown', function (e) {
          var parent = S(e.target).closest('[' + self.attr_name() + '-content]');

          if (S(e.target).data(self.data_attr()) || S(e.target).parent().data(self.data_attr())) {
            return;
          }
          if (!(S(e.target).data('revealId')) &&
            (parent.length > 0 && (S(e.target).is('[' + self.attr_name() + '-content]') ||
              $.contains(parent.first()[0], e.target)))) {
            e.stopPropagation();
            return;
          }

          self.close.call(self, S('[' + self.attr_name() + '-content]'));
        })
        .on('opened.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () {
            self.settings.opened.call(this);
        })
        .on('closed.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () {
            self.settings.closed.call(this);
        });

      S(window)
        .off('.dropdown')
        .on('resize.fndtn.dropdown', self.throttle(function () {
          self.resize.call(self);
        }, 50));

      this.resize();
    },

    close: function (dropdown) {
      var self = this;
      dropdown.each(function () {
        if (self.S(this).hasClass(self.settings.active_class)) {
          self.S(this)
            .css(Foundation.rtl ? 'right':'left', '-99999px')
            .removeClass(self.settings.active_class);
          self.S(this).trigger('closed');
        }
      });
    },

    closeall: function() {
      var self = this;
      $.each(self.S('[' + this.attr_name() + '-content]'), function() {
        self.close.call(self, self.S(this))
      });
    },

    open: function (dropdown, target) {
        this
          .css(dropdown
            .addClass(this.settings.active_class), target);
        dropdown.trigger('opened');
    },

    data_attr: function () {
      if (this.namespace.length > 0) {
        return this.namespace + '-' + this.name;
      }

      return this.name;
    },

    toggle : function (target) {
      var dropdown = this.S('#' + target.data(this.data_attr()));
      if (dropdown.length === 0) {
        // No dropdown found, not continuing
        return;
      }

      this.close.call(this, this.S('[' + this.attr_name() + '-content]').not(dropdown));

      if (dropdown.hasClass(this.settings.active_class)) {
        this.close.call(this, dropdown);
      } else {
        this.close.call(this, this.S('[' + this.attr_name() + '-content]'))
        this.open.call(this, dropdown, target);
      }
    },

    resize : function () {
      var dropdown = this.S('[' + this.attr_name() + '-content].open'),
          target = this.S("[" + this.attr_name() + "='" + dropdown.attr('id') + "']");

      if (dropdown.length && target.length) {
        this.css(dropdown, target);
      }
    },

    css : function (dropdown, target) {
      var offset_parent = dropdown.offsetParent(),
          position = target.offset();

      position.top -= offset_parent.offset().top;
      position.left -= offset_parent.offset().left;

      if (this.small()) {
        dropdown.css({
          position : 'absolute',
          width: '95%',
          'max-width': 'none',
          top: position.top + target.outerHeight()
        });
        dropdown.css(Foundation.rtl ? 'right':'left', '2.5%');
      } else {
        if (!Foundation.rtl && this.S(window).width() > dropdown.outerWidth() + target.offset().left) {
          var left = position.left;
          if (dropdown.hasClass('right')) {
            dropdown.removeClass('right');
          }
        } else {
          if (!dropdown.hasClass('right')) {
            dropdown.addClass('right');
          }
          var left = position.left - (dropdown.outerWidth() - target.outerWidth());
        }

        dropdown.attr('style', '').css({
          position : 'absolute',
          top: position.top + target.outerHeight(),
          left: left
        });
      }

      return dropdown;
    },

    small : function () {
      return matchMedia(Foundation.media_queries.small).matches &&
        !matchMedia(Foundation.media_queries.medium).matches;
    },

    off: function () {
      this.S(this.scope).off('.fndtn.dropdown');
      this.S('html, body').off('.fndtn.dropdown');
      this.S(window).off('.fndtn.dropdown');
      this.S('[data-dropdown-content]').off('.fndtn.dropdown');
      this.settings.init = false;
    },

    reflow : function () {}
  };
}(jQuery, this, this.document));
<|endoftext|>


<commit_before>$(document).ready(function() {

    // page is now ready, initialize the calendar...

    $('#calendar').fullCalendar({
         events: [
        {
            title  : 'event2',
            start  : '2015-10-05',
            end    : '2015-10-08',
            url: 'http://google.com/'
        },
        {
            title  : 'event2.1',
            start  : '2015-10-05',
            end    : '2015-10-08',
            url: 'http://google.com/'
        },
        {
            title  : 'event3',
            start  : '2015-10-09T12:30:00',
            allDay : false // will make the time show
        }
    ],
    eventClick: function(event) {
        if (event.url) {
            window.open(event.url);
            return false;
        }
    },

    dayClick: function(date, jsEvent, view) {
        // change the day's background color just for fun
        $(this).css('background-color', 'red');

    },

    })

});
<commit_msg>changing colors of calendar events<commit_after>$(document).ready(function() {

    // page is now ready, initialize the calendar...

    $('#calendar').fullCalendar({
         events: [
        {
            title  : 'event2',
            start  : '2015-10-05',
            end    : '2015-10-08',
            url: 'http://google.com/'

        },
        {
            title  : 'event2.1',
            start  : '2015-10-05',
            end    : '2015-10-08',
            url: 'http://google.com/'
        },
        {
            title  : 'event3',
            start  : '2015-10-09T12:30:00',
            allDay : false // will make the time show
        }
    ],
    eventBorderColor: '#FFF',
    eventBackgroundColor: '#0198E1',

    eventClick: function(event) {
        if (event.url) {
            window.open(event.url);
            return false;
        }
    },

    dayClick: function(date, jsEvent, view) {
        // change the day's background color just for fun
        $(this).css('background-color', 'red');

    },

    })

});
<|endoftext|>


<commit_before>/*jshint -W083 */

// Shared utils lib
go.utils = {

    is_none_msisdn: function (content) {
      if (content == 'none') {
        return true;
      }
    },

    is_valid_msisdn: function (content) {
        return !isNaN(content) &&
            parseInt(content[0], 10) === 0 &&
            content.length == 10;
    },

    validate_id_sa: function(id) {
        var i, c,
            even = '',
            sum = 0,
            check = id.slice(-1);

        if (id.length != 13 || id.match(/\D/)) {
            return false;
        }
        id = id.substr(0, id.length - 1);
        for (i = 0; id.charAt(i); i += 2) {
            c = id.charAt(i);
            sum += +c;
            even += id.charAt(i + 1);
        }
        even = '' + even * 2;
        for (i = 0; even.charAt(i); i++) {
            c = even.charAt(i);
            sum += +c;
        }
        sum = 10 - ('' + sum).charAt(1);
        return ('' + sum).slice(-1) == check;
    },

    // Handy to leave at the bottom to ensure trailing commas in objects
    // don't become syntax errors.
    "commas": "commas"
};
<commit_msg>Added toLowerCase() for msisdn check<commit_after>/*jshint -W083 */

// Shared utils lib
go.utils = {

    is_none_msisdn: function (content) {
      if (content.toLowerCase() == 'none') {
        return true;
      }
    },

    is_valid_msisdn: function (content) {
        return !isNaN(content) &&
            parseInt(content[0], 10) === 0 &&
            content.length == 10;
    },

    validate_id_sa: function(id) {
        var i, c,
            even = '',
            sum = 0,
            check = id.slice(-1);

        if (id.length != 13 || id.match(/\D/)) {
            return false;
        }
        id = id.substr(0, id.length - 1);
        for (i = 0; id.charAt(i); i += 2) {
            c = id.charAt(i);
            sum += +c;
            even += id.charAt(i + 1);
        }
        even = '' + even * 2;
        for (i = 0; even.charAt(i); i++) {
            c = even.charAt(i);
            sum += +c;
        }
        sum = 10 - ('' + sum).charAt(1);
        return ('' + sum).slice(-1) == check;
    },

    // Handy to leave at the bottom to ensure trailing commas in objects
    // don't become syntax errors.
    "commas": "commas"
};
<|endoftext|>


<commit_before>/*
 * Tests EasyAutocomplete - plugin
 *
 * @author Łukasz Pawełczak
 */
QUnit.test( "JQuery method exists", function( assert ) {

	//assert
	assert.ok($.fn.easyAutocomplete, "Method $.easyAutocomplete exists");
	assert.ok($.fn.getSelectedItemIndex, "Method $.getSelectedItemIndex exists");
	expect(2);
});
<commit_msg>Closes #86. Tests where input field has no id<commit_after>/*
 * Tests EasyAutocomplete - plugin
 *
 * @author Łukasz Pawełczak
 */
QUnit.test( "JQuery method exists", function( assert ) {

	//assert
	assert.ok($.fn.easyAutocomplete, "Method $.easyAutocomplete exists");
	assert.ok($.fn.getSelectedItemIndex, "Method $.getSelectedItemIndex exists");
	assert.ok($.fn.getItemData, "Method $.getItemData exists");
	assert.ok($.fn.getSelectedItemData, "Method $.getSelectedItemData exists");
	expect(4);
});

QUnit.test("Input field has no id property", function( assert ) {

	//given
	var completerOne = $(".inputOne").easyAutocomplete({

		data: ["black", "white", "magenta", "yellow"],

	});

	//execute
	var e = $.Event('keyup');
	e.keyCode = 50;
	$(".inputOne").val("more").trigger(e);

	//assert
	var elements = $(".inputOne").next().find("ul li");

	assert.equal(4, elements.length, "Response size");
	assert.equal("black", elements.eq(0).text(), "First element is 'black'");
	assert.equal("white", elements.eq(1).text(), "Second element is 'white'");
	assert.equal("magenta", elements.eq(2).text(), "Third element is 'magenta'");
	assert.equal("yellow", elements.eq(3).text(), "Fourth element is 'yellow'");

	expect(5);
});
<|endoftext|>


<commit_before>// Copyright 2014-2017, University of Colorado Boulder

/**
 * Node that represents a "beaker container" in the view.  A beaker container
 * is a beaker that contains fluid, and in which other objects can be placed,
 * generally displacing the fluid.
 *
 * See the header comments in the parent class for some important information
 * about how this class is used on the canvas.
 *
 * @author John Blanco
 * @author Jesse Greenberg
 * @author Andrew Adare
 */
define( function( require ) {
  'use strict';

  // modules
  var BeakerView = require( 'ENERGY_FORMS_AND_CHANGES/common/view/BeakerView' );
  var energyFormsAndChanges = require( 'ENERGY_FORMS_AND_CHANGES/energyFormsAndChanges' );
  var inherit = require( 'PHET_CORE/inherit' );
  var ThermalElementDragHandler = require( 'ENERGY_FORMS_AND_CHANGES/intro/view/ThermalElementDragHandler' );

  /**
   * Constructor for a BeakerContainerView.
   *
   * @param {EFACIntroModel} model
   * @param {Bounds2} stageBounds
   * @param {ModelViewTransform2} modelViewTransform
   */
  function BeakerContainerView( model, stageBounds, modelViewTransform ) {

    var self = this; // Extend scope for nested callbacks.
    BeakerView.call( this, model.beaker, model.energyChunksVisibleProperty, modelViewTransform );

    // Update the clipping mask when any of the blocks move.  The clipping
    // mask hides energy chunks that overlap with blocks.
    model.getBlockList().forEach( function( block ) {
      block.positionProperty.link( function() {
        self.updateEnergyChunkClipMask( model, self.energyChunkClipNode );
      } );
    } );

    // Update the clipping mask when the position of the beaker moves.
    model.beaker.positionProperty.link( function( position ) {
      self.updateEnergyChunkClipMask( model, self.energyChunkClipNode );
    } );

    this.grabNode.addInputListener( new ThermalElementDragHandler( model.beaker, this.grabNode, modelViewTransform ) );

    // Add the drag handler.
    this.addInputListener( new ThermalElementDragHandler( model.beaker, this, modelViewTransform ) );
  }

  energyFormsAndChanges.register( 'BeakerContainerView', BeakerContainerView );

  return inherit( BeakerView, BeakerContainerView, {

    // Update the clipping mask that hides energy chunks behind blocks that are in the beaker.
    updateEnergyChunkClipMask: function( model, clip ) {

      // TODO: Come up with an alternative clipping solution.

      //var forwardPerspectiveOffset = EFACConstants.MAP_Z_TO_XY_OFFSET.apply( EFACConstants.BLOCK_SURFACE_WIDTH / 2 );
      //var backwardPerspectiveOffset = EFACConstants.MAP_Z_TO_XY_OFFSET.apply( -EFACConstants.BLOCK_SURFACE_WIDTH / 2 );

      //var clippingMask

    }
  } );
} );

<commit_msg>code cleanup<commit_after>// Copyright 2014-2017, University of Colorado Boulder

/**
 * Node that represents a "beaker container" in the view.  A beaker container is a beaker that contains fluid, and in
 * which other objects can be placed, generally displacing the fluid.
 *
 * See the header comments in the parent class for some important information about how this class is used on the
 * canvas.
 *
 * @author John Blanco
 * @author Jesse Greenberg
 * @author Andrew Adare
 */
define( function( require ) {
  'use strict';

  // modules
  var BeakerView = require( 'ENERGY_FORMS_AND_CHANGES/common/view/BeakerView' );
  var energyFormsAndChanges = require( 'ENERGY_FORMS_AND_CHANGES/energyFormsAndChanges' );
  var inherit = require( 'PHET_CORE/inherit' );
  var ThermalElementDragHandler = require( 'ENERGY_FORMS_AND_CHANGES/intro/view/ThermalElementDragHandler' );

  /**
   * @param {EFACIntroModel} model
   * @param {Bounds2} stageBounds
   * @param {ModelViewTransform2} modelViewTransform
   */
  function BeakerContainerView( model, stageBounds, modelViewTransform ) {

    var self = this;
    BeakerView.call( this, model.beaker, model.energyChunksVisibleProperty, modelViewTransform );

    // For each block that can go in the beaker we need to add a listener that will update the clipping mask.  The
    // clipping mask hides energy chunks that overlap with blocks.  TODO: Clarify this.
    model.getBlockList().forEach( function( block ) {
      block.positionProperty.link( function() {
        self.updateEnergyChunkClipMask( model, self.energyChunkClipNode );
      } );
    } );

    // update the clipping mask when the position of the beaker moves
    model.beaker.positionProperty.link( function( position ) {
      self.updateEnergyChunkClipMask( model, self.energyChunkClipNode );
    } );

    // TODO: Document why two drag listeners are added or, if both aren't needed, remove one of them.
    this.grabNode.addInputListener( new ThermalElementDragHandler( model.beaker, this.grabNode, modelViewTransform ) );
    this.addInputListener( new ThermalElementDragHandler( model.beaker, this, modelViewTransform ) );
  }

  energyFormsAndChanges.register( 'BeakerContainerView', BeakerContainerView );

  return inherit( BeakerView, BeakerContainerView, {

    /**
     * @param {EFACIntroModel} model
     * @param {Node} clip
     * @private
     */
    updateEnergyChunkClipMask: function( model, clip ) {

      // TODO: Come up with an alternative clipping solution.

      //var forwardPerspectiveOffset = EFACConstants.MAP_Z_TO_XY_OFFSET.apply( EFACConstants.BLOCK_SURFACE_WIDTH / 2 );
      //var backwardPerspectiveOffset = EFACConstants.MAP_Z_TO_XY_OFFSET.apply( -EFACConstants.BLOCK_SURFACE_WIDTH / 2 );

      //var clippingMask
    }
  } );
} );

<|endoftext|>


<commit_before>// jQuery.instance
// ---------------

;(function($) {
  $.fn.instance = function (type) {
    var $this = this.first();
    var $this = $this.data('instance') || ($this.data('instance', $this) && $this);

    // Tip: Implement a 'klass' property to make sure extending doesn't happen twice.
    if ((type) && ((!$this.klass) || (!type.klass) || ($this.klass != type.klass))) {
      $this.extend(type);
    }

    return $this;
  };
})(jQuery);

/* Quick usage guide:
 *
 *   var $one = $("#sidebar").instance();
 *   var $two = $("#sidebar").instance();
 *   $one.abc = 42;
 *   $two.abc; //=> 42
 *
 *   var Rule = {
 *     expand: function () { ... }
 *   };
 *
 *   var $one = $("#sidebar").instance(Rule);
 *   $one.expand();
 */

<commit_msg>Updated to auto track extensions so not to extend the same mixin twice.<commit_after>// jQuery.instance
// ---------------

;(function($) {
  $.fn.instance = function (type) {
    var $this = this.first();
    var $this = $this.data('instance') || ($this.data('instance', $this) && $this);

    if ((type) && ((!$this._className) || ($this._className != type))) {
      $this.extend(type);
      $this._className = type;
    }

    return $this;
  };
})(jQuery);

/* Quick usage guide:
 *
 *   var $one = $("#sidebar").instance();
 *   var $two = $("#sidebar").instance();
 *   $one.abc = 42;
 *   $two.abc; //=> 42
 *
 *   var Rule = {
 *     expand: function () { ... }
 *   };
 *
 *   var $one = $("#sidebar").instance(Rule);
 *   $one.expand();
 */

<|endoftext|>


<commit_before>window.prefs = {};

window.prefs.openModal = function(feature) {
	$("#prefs-feature-name").text(window.utils.getLongNameForFeature(feature));
	$(".prefs-modal-body").addClass("hidden");
	$("#prefs-" + feature + "-body").removeClass("hidden");
	$("#prefs-modal").attr("data-feature", feature);
	$("#prefs-modal").modal({
		backdrop: "static",
		keyboard: false
	});
};

window.prefs.get = function(name, callback) {
	window.api.get("prefs/get/" + name, function(data) {
		callback(data.val);
	});
};

window.prefs.checkToggle = function($checkbox, prefsId) {
	window.prefs.get(prefsId, function(result) {
		var toggled = false;
		if (parseInt(result) == 1) {
			toggled = true;
		}
		$checkbox.prop("checked", toggled);
		$checkbox.change(function() {
			var prefsVal = ($(this).prop("checked") ? "1" : "0");
			window.api.post("prefs/set", { name: prefsId, value: prefsVal}, function() {});
		});
	});
};
window.prefs.getJSONPref = function(name, callback) {
    window.prefs.get(name, function(val) {
    	if (val === undefined) {
    		callback(undefined);
    		return;
    	}
        callback(JSON.parse(val));
    });
};
$(document).ready(function() {
	$("#prefs-done").click(function() {
		$("#prefs-modal").modal("hide");
		setPage($("#prefs-modal").attr("data-feature"));
	});
	$("#titles-new").click(function() {
		var $liThingy = $('

');
			$liThingy.attr("id", "title");
			var $inputBox = $('<input></input>')
				$inputBox.val("title");
				$inputBox.change(function(){
					$(this).parent().attr("id", $(this).val());
					var setList = JSON.stringify($("#title-sorting").sortable("toArray"));
					window.api.post("prefs/set", {name: "titleOrder", value:setList}, function() {});
				});
			$liThingy.append($inputBox);
			var $deleteButton = $('<button class="btn btn-xs btn-danger"></button>')
				$deleteButton.click(function() {
					$(this).parent().remove();
					var setList = JSON.stringify($("#title-sorting").sortable("toArray"));
					window.api.post("prefs/set", {name: "titleOrder", value:setList}, function() {});
				});
			$liThingy.append($deleteButton);
		$("#title-sorting").append($liThingy)
	});
	window.prefs.getJSONPref("titleOrder", function(val) {
		if(val == undefined) {
			val = ["HW","Read","Reading","Project","Report","Essay","Paper","Quiz","Test","Final","Exam","Midterm","Lab","Study","DocID","None","NoHW","subjectName"]
		}
		for(title in val) {
			var $titleLi = $('

');
				$titleLi.attr("id", val[title]);
				var $titleWord = $('<input></input>');
					$titleWord.val(val[title]);
					$titleWord.change(function() {
						$(this).parent().attr("id", $(this).val());
						var setList = JSON.stringify($("#title-sorting").sortable("toArray"));
						window.api.post("prefs/set", {name: "titleOrder", value:setList}, function() {});
					});
				$titleLi.append($titleWord);
				var $deleteThem = $('<button class="btn btn-xs btn-danger"></button>');
					$deleteThem.click(function() {
						$(this).parent().remove();
						var setList = JSON.stringify($("#title-sorting").sortable("toArray"));
						window.api.post("prefs/set", {name: "titleOrder", value:setList}, function() {});
					});
				$titleLi.append($deleteThem);
			$("#title-sorting").append($titleLi);
		};
		$("#title-sorting").sortable({
			stop: function (event, ui) {
				var setList = JSON.stringify($("#title-sorting").sortable("toArray"));
				window.api.post("prefs/set", {name: "titleOrder", value:setList}, function() {});
			}
		});
		$("#title-sorting").disableSelection();
	});

	// Homework View
	window.prefs.checkToggle($("#prefs-hwView-swap"), "name-subj");
	window.prefs.checkToggle($("#prefs-hwView-color"), "titleclr");
	window.prefs.checkToggle($("#prefs-hwView-checkboxes"), "hwView-checkboxes");

	// Connected accounts
	$("#schedules-connect").click(function() {
		$("#login-to-schedules-modal").modal();
	});

	$("#schedules-sign-in").click(function() {
		window.api.post("connected/schedules/connect", { username: $("#schedules-username").val(), password: $("#schedules-pw").val() }, function() {

		});
	})
});
<commit_msg>log it<commit_after>window.prefs = {};

window.prefs.openModal = function(feature) {
	$("#prefs-feature-name").text(window.utils.getLongNameForFeature(feature));
	$(".prefs-modal-body").addClass("hidden");
	$("#prefs-" + feature + "-body").removeClass("hidden");
	$("#prefs-modal").attr("data-feature", feature);
	$("#prefs-modal").modal({
		backdrop: "static",
		keyboard: false
	});
};

window.prefs.get = function(name, callback) {
	window.api.get("prefs/get/" + name, function(data) {
		callback(data.val);
	});
};

window.prefs.checkToggle = function($checkbox, prefsId) {
	window.prefs.get(prefsId, function(result) {
		var toggled = false;
		if (parseInt(result) == 1) {
			toggled = true;
		}
		$checkbox.prop("checked", toggled);
		$checkbox.change(function() {
			var prefsVal = ($(this).prop("checked") ? "1" : "0");
			window.api.post("prefs/set", { name: prefsId, value: prefsVal}, function() {});
		});
	});
};
window.prefs.getJSONPref = function(name, callback) {
    window.prefs.get(name, function(val) {
    	if (val === undefined) {
    		callback(undefined);
    		return;
    	}
        callback(JSON.parse(val));
    });
};
$(document).ready(function() {
	$("#prefs-done").click(function() {
		$("#prefs-modal").modal("hide");
		setPage($("#prefs-modal").attr("data-feature"));
	});
	$("#titles-new").click(function() {
		var $liThingy = $('

');
			$liThingy.attr("id", "title");
			var $inputBox = $('<input></input>')
				$inputBox.val("title");
				$inputBox.change(function(){
					$(this).parent().attr("id", $(this).val());
					var setList = JSON.stringify($("#title-sorting").sortable("toArray"));
					window.api.post("prefs/set", {name: "titleOrder", value:setList}, function() {});
				});
			$liThingy.append($inputBox);
			var $deleteButton = $('<button class="btn btn-xs btn-danger"></button>')
				$deleteButton.click(function() {
					$(this).parent().remove();
					var setList = JSON.stringify($("#title-sorting").sortable("toArray"));
					window.api.post("prefs/set", {name: "titleOrder", value:setList}, function() {});
				});
			$liThingy.append($deleteButton);
		$("#title-sorting").append($liThingy)
	});
	window.prefs.getJSONPref("titleOrder", function(val) {
		if(val == undefined) {
			val = ["HW","Read","Reading","Project","Report","Essay","Paper","Quiz","Test","Final","Exam","Midterm","Lab","Study","DocID","None","NoHW","subjectName"]
		}
		for(title in val) {
			var $titleLi = $('

');
				$titleLi.attr("id", val[title]);
				var $titleWord = $('<input></input>');
					$titleWord.val(val[title]);
					$titleWord.change(function() {
						$(this).parent().attr("id", $(this).val());
						var setList = JSON.stringify($("#title-sorting").sortable("toArray"));
						window.api.post("prefs/set", {name: "titleOrder", value:setList}, function() {});
					});
				$titleLi.append($titleWord);
				var $deleteThem = $('<button class="btn btn-xs btn-danger"></button>');
					$deleteThem.click(function() {
						$(this).parent().remove();
						var setList = JSON.stringify($("#title-sorting").sortable("toArray"));
						window.api.post("prefs/set", {name: "titleOrder", value:setList}, function() {});
					});
				$titleLi.append($deleteThem);
			$("#title-sorting").append($titleLi);
		};
		$("#title-sorting").sortable({
			stop: function (event, ui) {
				var setList = JSON.stringify($("#title-sorting").sortable("toArray"));
				window.api.post("prefs/set", {name: "titleOrder", value:setList}, function() {});
			}
		});
		$("#title-sorting").disableSelection();
	});

	// Homework View
	window.prefs.checkToggle($("#prefs-hwView-swap"), "name-subj");
	window.prefs.checkToggle($("#prefs-hwView-color"), "titleclr");
	window.prefs.checkToggle($("#prefs-hwView-checkboxes"), "hwView-checkboxes");

	// Connected accounts
	$("#schedules-connect").click(function() {
		$("#login-to-schedules-modal").modal();
	});

	$("#schedules-sign-in").click(function() {
		window.api.post("connected/schedules/connect", { username: $("#schedules-username").val(), password: $("#schedules-pw").val() }, function(resp) {
			console.log(resp);
		});
	})
});
<|endoftext|>


<commit_before>/*
 _        _         _
| \      (_)       | |
| |       _  ____  | |  _   ___
| |      | ||  _ \ | |_/ ) / _ \
| |_____ | || | | ||  _ ( | (_) |
\_______)|_||_| |_||_| \_) \___/

 * jqScroll v1.3 - jQuery Plugin for Infinite Scrolling
 * http://blog.ddmweb.it/
 *
 * Copyright 2013-2014, Davide Di Modica
 * http://ddmweb.it/
 * Dual licensed under the MIT and GPL Version 2 licenses.
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl-2.0.html
 *
 * @author Davide Di Modica
 * @requires jQuery v1.4.3+

*/

//plugin infinite scroll super!!!

//dichiaro la variabile globale per le opzioni
window.jqScroll = {};
window.jqScroll.opts = {};
(function($){

	//start plugin
	$.fn.jqScroll = function(options) {
		//aggiorno le opzioni
		var opts = $.extend($.fn.jqScroll.defaults, options);
		var target = opts.scrollTarget;
		if (target == null){
			target = $(window);
		}
		opts.scrollTarget = target;

		window.jqScroll.opts = opts;

		if (opts.loading != null && opts.firstLoad){
			opts.loading();
		}

		//associo il plugin ad ogni elemento corrispondente al selettore
		return this.each(function() {
			$.fn.jqScroll.init($(this), opts);
		});
	};

	//disabilito il plugin
	$.fn.jqScrollStopScroll = function(){
		return this.each(function() {
			$(this).attr('jqScroll', 'disabled');
		});
	};

	//riabilito il plugin
	$.fn.jqScrollRestartScroll = function(){
		return this.each(function() {
			$(this).attr('jqScroll', 'enabled');
			$.fn.jqScroll.init($(this), window.jqScroll.opts);
		});
	};

	// fade-in per i nuovi elementi
	$.fn.jqScrollfadeInWithDelay = function(){
		var delay = 0;
		return this.each(function(){
			$(this).delay(delay).animate({opacity:1}, 400);
			delay += 200;
		});
	};

	//carico i contenuti
	$.fn.jqScroll.loadContent = function(obj, opts){
		if ($(obj).attr('jqScroll') == 'enabled'){
			var target = opts.scrollTarget;
			//verifico se sono arrivato a fondo pagina più eventuale offset
			var mayLoadContent = $(target).scrollTop()+opts.heightOffset >= $(document).height() - $(target).height();
			if (mayLoadContent){
				if (opts.beforeLoad != null){
					opts.beforeLoad();
				}
				$(obj).children().attr('rel', 'loaded');

				if (opts.loading != null){
					opts.loading();
					//restituisco i nuovi elementi
					var objectsRendered = $(obj).children('[rel!=loaded]');
					if (opts.afterLoad != null){
						opts.afterLoad(objectsRendered);
					}
				}else{// qui posso avviare una funzione predefinita ajax
					$.ajax({
						type: opts.typeRequest,
						url: opts.contentPage,
						data: opts.contentData,
						dataType: opts.dataType,
						success: function(data){
							if (opts.ajaxCallback != null){
								opts.ajaxCallback(data);
							}else{
								$(obj).append(data);
							}
							var objectsRendered = $(obj).children('[rel!=loaded]');

							if (opts.afterLoad != null){
								opts.afterLoad(objectsRendered);
							}
						}
					});
				}
				//aggiungo elementi fino a riempire tutto l'elemento contenitore,
				//così da poter riabilitare lo scroll
				while($(target).scrollTop()+opts.heightOffset > $(document).height() - $(target).height() && $(obj).attr('jqScroll') == 'enabled'){
					$.fn.jqScroll.loadContent(obj, opts);
				}
			}
		}
	};

	//ascolto l'evento scroll e carico i contenuti
	$.fn.jqScroll.init = function(obj, opts){
		console.log(opts);
		var target = opts.scrollTarget;
		$(obj).attr('jqScroll', 'enabled');

		$(target).scroll(function(event){
			if ($(obj).attr('jqScroll') == 'enabled'){
				console.log('scroll');
				$.fn.jqScroll.loadContent(obj, opts);
			}
			else {
				event.stopPropagation();
			}
		});

		//while($(target).scrollTop()+opts.heightOffset > $(document).height() - $(target).height()){
			$.fn.jqScroll.loadContent(obj, opts);
		//}
	};

	//opzioni di default
	$.fn.jqScroll.defaults = {
		'contentPage' : null,//url per funzione ajax predefinita, es: http://miosito.com/page.php
		'contentData' : {},//parametri da inviare all'url, es: {'key1': val1, 'key2': val2}
		'typeRequest': null,//tipo di richiesta, es: POST, GET, PUT, DELETE
		'dataType': null,//tipo di dato in ascolto, es: json
		'beforeLoad': null,//funzione prima del caricamento
		'loading': null,//funzione per il caricamento (se è valida non viene eseguita la funzione ajax predefinita)
		'afterLoad': null,//funzione dopo il caricamento (alla quale vengono restituiti i nuovi elementi)
		'ajaxCallback': null,//callback della funzione ajax predefinita
		'scrollTarget': null,//elemento per il quale si deve ascoltare l'evento scroll
		'heightOffset': 0,//(integer) serve a caricare gli elementi prima di arrivare a fondo pagina, es: 200, $('#footer').height()
		'firstLoad': true//viene effettuato un primo caricamento a priori
	};
})( jQuery );
<commit_msg>add resize event<commit_after>/*
 _        _         _
| \      (_)       | |
| |       _  ____  | |  _   ___
| |      | ||  _ \ | |_/ ) / _ \
| |_____ | || | | ||  _ ( | (_) |
\_______)|_||_| |_||_| \_) \___/

 * jqScroll v1.3 - jQuery Plugin for Infinite Scrolling
 * http://blog.ddmweb.it/
 *
 * Copyright 2013-2014, Davide Di Modica
 * http://ddmweb.it/
 * Dual licensed under the MIT and GPL Version 2 licenses.
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl-2.0.html
 *
 * @author Davide Di Modica
 * @requires jQuery v1.4.3+

*/

//plugin infinite scroll super!!!

//dichiaro la variabile globale per le opzioni
window.jqScroll = {};
window.jqScroll.opts = {};
(function($){

	//start plugin
	$.fn.jqScroll = function(options) {
		//aggiorno le opzioni
		var opts = $.extend($.fn.jqScroll.defaults, options);
		var target = opts.scrollTarget;
		if (target == null){
			target = $(window);
		}
		opts.scrollTarget = target;

		window.jqScroll.opts = opts;

		if (opts.loading != null && opts.firstLoad){
			opts.loading();
		}

		//associo il plugin ad ogni elemento corrispondente al selettore
		return this.each(function() {
			$.fn.jqScroll.init($(this), opts);
		});
	};

	//disabilito il plugin
	$.fn.jqScrollStopScroll = function(){
		return this.each(function() {
			$(this).attr('jqScroll', 'disabled');
		});
	};

	//riabilito il plugin
	$.fn.jqScrollRestartScroll = function(){
		return this.each(function() {
			$(this).attr('jqScroll', 'enabled');
			$.fn.jqScroll.init($(this), window.jqScroll.opts);
		});
	};

	// fade-in per i nuovi elementi
	$.fn.jqScrollfadeInWithDelay = function(){
		var delay = 0;
		return this.each(function(){
			$(this).delay(delay).animate({opacity:1}, 400);
			delay += 200;
		});
	};

	//carico i contenuti
	$.fn.jqScroll.loadContent = function(obj, opts){
		if ($(obj).attr('jqScroll') == 'enabled'){
			var target = opts.scrollTarget;
			//verifico se sono arrivato a fondo pagina più eventuale offset
			var mayLoadContent = $(target).scrollTop()+opts.heightOffset >= $(document).height() - $(target).height();
			if (mayLoadContent){
				if (opts.beforeLoad != null){
					opts.beforeLoad();
				}
				$(obj).children().attr('rel', 'loaded');

				if (opts.loading != null){
					opts.loading();
					//restituisco i nuovi elementi
					var objectsRendered = $(obj).children('[rel!=loaded]');
					if (opts.afterLoad != null){
						opts.afterLoad(objectsRendered);
					}
				}else{// qui posso avviare una funzione predefinita ajax
					$.ajax({
						type: opts.typeRequest,
						url: opts.contentPage,
						data: opts.contentData,
						dataType: opts.dataType,
						success: function(data){
							if (opts.ajaxCallback != null){
								opts.ajaxCallback(data);
							}else{
								$(obj).append(data);
							}
							var objectsRendered = $(obj).children('[rel!=loaded]');

							if (opts.afterLoad != null){
								opts.afterLoad(objectsRendered);
							}
						}
					});
				}
				//aggiungo elementi fino a riempire tutto l'elemento contenitore,
				//così da poter riabilitare lo scroll
				while($(target).scrollTop()+opts.heightOffset > $(document).height() - $(target).height() && $(obj).attr('jqScroll') == 'enabled'){
					$.fn.jqScroll.loadContent(obj, opts);
				}
			}
		}
	};

	//ascolto l'evento scroll e carico i contenuti
	$.fn.jqScroll.init = function(obj, opts){
		console.log(opts);
		var target = opts.scrollTarget;
		$(obj).attr('jqScroll', 'enabled');

		//leggo evento scroll
		$(target).scroll(function(event){
			if ($(obj).attr('jqScroll') == 'enabled'){
				console.log('scroll');
				$.fn.jqScroll.loadContent(obj, opts);
			}
			else {
				event.stopPropagation();
			}
		});

		//leggo evento resize
		$(target).resize(function(event){
			if ($(obj).attr('jqScroll') == 'enabled'){
				console.log('resize');
				$.fn.jqScroll.loadContent(obj, opts);
			}
			else {
				event.stopPropagation();
			}
		});

		//while($(target).scrollTop()+opts.heightOffset > $(document).height() - $(target).height()){
			$.fn.jqScroll.loadContent(obj, opts);
		//}
	};

	//opzioni di default
	$.fn.jqScroll.defaults = {
		'contentPage' : null,//url per funzione ajax predefinita, es: http://miosito.com/page.php
		'contentData' : {},//parametri da inviare all'url, es: {'key1': val1, 'key2': val2}
		'typeRequest': null,//tipo di richiesta, es: POST, GET, PUT, DELETE
		'dataType': null,//tipo di dato in ascolto, es: json
		'beforeLoad': null,//funzione prima del caricamento
		'loading': null,//funzione per il caricamento (se è valida non viene eseguita la funzione ajax predefinita)
		'afterLoad': null,//funzione dopo il caricamento (alla quale vengono restituiti i nuovi elementi)
		'ajaxCallback': null,//callback della funzione ajax predefinita
		'scrollTarget': null,//elemento per il quale si deve ascoltare l'evento scroll
		'heightOffset': 0,//(integer) serve a caricare gli elementi prima di arrivare a fondo pagina, es: 200, $('#footer').height()
		'firstLoad': true//viene effettuato un primo caricamento a priori
	};
})( jQuery );
<|endoftext|>


<commit_before>window.prefs = {};

window.prefs.openModal = function(feature) {
	$("#prefs-feature-name").text(window.utils.getLongNameForFeature(feature));
	$(".prefs-modal-body").addClass("hidden");
	$("#prefs-" + feature + "-body").removeClass("hidden");
	$("#prefs-modal").attr("data-feature", feature);
	$("#prefs-modal").modal({
		backdrop: "static",
		keyboard: false
	});
};

window.prefs.get = function(name, callback) {
	window.api.get("prefs/get/" + name, function(data) {
		callback(data.val);
	});
};

window.prefs.checkToggle = function($checkbox, prefsId) {
	window.prefs.get(prefsId, function(result) {
		var toggled = false;
		if (parseInt(result) == 1) {
			toggled = true;
		}
		$checkbox.prop("checked", toggled);
		$checkbox.change(function() {
			var prefsVal = ($(this).prop("checked") ? "1" : "0");
			window.api.post("prefs/set", { name: prefsId, value: prefsVal}, function() {});
		});
	});
};
window.prefs.getJSONPref = function(name, callback) {
    window.prefs.get(name, function(val) {
    	if (val === undefined) {
    		callback(undefined);
    		return;
    	}
        callback(JSON.parse(val));
    });
};
$(document).ready(function() {
	$("#prefs-done").click(function() {
		$("#prefs-modal").modal("hide");
		setPage($("#prefs-modal").attr("data-feature"));
	});
	$("#usr-btn").click(function() {
		var usrname = $("#usr-name").val();
		window.api.post("prefs/setName", { name: usrname }, function() {
			window.page.showLoading();
			window.location.reload();
		});
	});
	window.prefs.getJSONPref("titleOrder", function(val) {
		if(val == undefined) {
			val = ["HW","Read","Reading","Project","Report","Essay","Paper","Quiz","Test","Final","Exam","Midterm","Lab","Study","DocID","None","NoHW","subjectName"]
		}
		for(title in val) {
			var $titleLi = $('

');
				$titleLi.attr("id", val[title]);
				var $titleWord = $('');
					$titleWord.text(val[title]);
				$titleLi.append($titleWord);
			$("#title-sorting").append($titleLi);
		};
		$("#title-sorting").sortable({
			stop: function (event, ui) {
				var setList = JSON.stringify($("#title-sorting").sortable("toArray"));
				window.api.post("prefs/set", {name: "titleOrder", value:setList}, function() {});
			}
		});
		$("#title-sorting").disableSelection();
	});
	// Homework View
	window.prefs.checkToggle($("#prefs-hwView-swap"), "name-subj");
	window.prefs.checkToggle($("#prefs-hwView-color"), "titleclr");
	window.prefs.checkToggle($("#prefs-hwView-checkboxes"), "hwView-checkboxes");
});
<commit_msg>maybe?<commit_after>window.prefs = {};

window.prefs.openModal = function(feature) {
	$("#prefs-feature-name").text(window.utils.getLongNameForFeature(feature));
	$(".prefs-modal-body").addClass("hidden");
	$("#prefs-" + feature + "-body").removeClass("hidden");
	$("#prefs-modal").attr("data-feature", feature);
	$("#prefs-modal").modal({
		backdrop: "static",
		keyboard: false
	});
};

window.prefs.get = function(name, callback) {
	window.api.get("prefs/get/" + name, function(data) {
		callback(data.val);
	});
};

window.prefs.checkToggle = function($checkbox, prefsId) {
	window.prefs.get(prefsId, function(result) {
		var toggled = false;
		if (parseInt(result) == 1) {
			toggled = true;
		}
		$checkbox.prop("checked", toggled);
		$checkbox.change(function() {
			var prefsVal = ($(this).prop("checked") ? "1" : "0");
			window.api.post("prefs/set", { name: prefsId, value: prefsVal}, function() {});
		});
	});
};
window.prefs.getJSONPref = function(name, callback) {
    window.prefs.get(name, function(val) {
    	if (val === undefined) {
    		callback(undefined);
    		return;
    	}
        callback(JSON.parse(val));
    });
};
$(document).ready(function() {
	$("#prefs-done").click(function() {
		$("#prefs-modal").modal("hide");
		setPage($("#prefs-modal").attr("data-feature"));
	});
	$("#usr-btn").click(function() {
		var usrname = $("#usr-name").val();
		window.api.post("prefs/setName", { name: usrname }, function() {
			window.page.showLoading();
			window.location.reload();
		});
	});
	window.prefs.getJSONPref("titleOrder", function(val) {
		if(val == undefined) {
			val = ["HW","Read","Reading","Project","Report","Essay","Paper","Quiz","Test","Final","Exam","Midterm","Lab","Study","DocID","None","NoHW","subjectName"]
		}
		for(title in val) {
			var $titleLi = $('

');
				$titleLi.attr("id", val[title]);
				var $titleWord = $('<input></input>');
					$titleWord.text(val[title]);
				$titleLi.append($titleWord);
			$("#title-sorting").append($titleLi);
		};
		$("#title-sorting").sortable({
			stop: function (event, ui) {
				var setList = JSON.stringify($("#title-sorting").sortable("toArray"));
				window.api.post("prefs/set", {name: "titleOrder", value:setList}, function() {});
			}
		});
		$("#title-sorting").disableSelection();
	});
	// Homework View
	window.prefs.checkToggle($("#prefs-hwView-swap"), "name-subj");
	window.prefs.checkToggle($("#prefs-hwView-color"), "titleclr");
	window.prefs.checkToggle($("#prefs-hwView-checkboxes"), "hwView-checkboxes");
});
<|endoftext|>


<commit_before>/**
 * jQuery PowerTip Plugin
 *
 * @fileoverview jQuery plugin that creates hover tooltips.
 * @link https://github.com/stevenbenner/jquery-powertip
 * @author Steven Benner
 * @version 1.0.1
 * @requires jQuery 1.7 or later
 * @license jQuery PowerTip Plugin
 * <https://github.com/stevenbenner/jquery-powertip>
 * Copyright (c) 2012 Steven Benner, http://stevenbenner.com/
 * Released under the MIT license.
 * <https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt>
 */

(function($) {
	'use strict';

	// useful private variables
	var $window = $(window),
		$body = $('body');

	/**
	 * Session data
	 * Private properties global to all powerTip instances
	 * @type Object
	 */
	var session = {
		isPopOpen: false,
		isFixedPopOpen: false,
		popOpenImminent: false,
		activeHover: null,
		mouseTarget: null,
		currentX: 0,
		currentY: 0,
		previousX: 0,
		previousY: 0,
		desyncTimeout: null
	};

	/**
	 * Display hover tooltips on the matched elements.
	 * @param {Object} opts The options object to use for the plugin.
	 * @return {Object} jQuery object for the matched selectors.
	 */
	$.fn.powerTip = function(opts) {

		// don't do any work if there were no matched elements
		if (!this.length) {
			return this;
		}

		// extend options
		var options = $.extend({}, $.fn.powerTip.defaults, opts);

		// hook mouse tracking, once
		hookOnMoveOnce();

		// build and append popup div if it does not already exist
		var tipElement = $('#' + options.popupId);
		if (tipElement.length === 0) {
			tipElement = $('

', { id: options.popupId });
			$body.append(tipElement);
		}

		// hook mousemove for cursor follow tooltips
		if (options.followMouse) {
			// only one movePop hook per popup element, please
			if (!tipElement.data('hasMouseMove')) {
				$window.on('mousemove', movePop);
			}
			tipElement.data('hasMouseMove', true);
		}

		// attempt to use title attribute text if there is no data-powertip,
		// data-powertipjq or data-powertiptarget. If we do use the title
		// attribute, delete the attribute so the browser will not show it
		this.each(function() {
			var $this = $(this),
				dataPowertip = $this.data('powertip'),
				dataElem = $this.data('powertipjq'),
				dataTarget = $this.data('powertiptarget'),
				title = $this.attr('title');

			if (!dataPowertip && !dataTarget && !dataElem && title) {
				$this.data('powertip', title);
				$this.removeAttr('title');
			}
		});

		// if we want to be able to mouse onto the popup then we need to attach
		// hover events to the popup that will cancel a close request on hover
		// and start a new close request on mouseleave
		if (options.followMouse || options.mouseOnToPopup) {
			tipElement.on({
				mouseenter: function() {
					if (tipElement.data('followMouse') || tipElement.data('mouseOnToPopup')) {
						cancelHoverTimer(session.activeHover);
						session.mouseTarget = session.activeHover;
					}
				},
				mouseleave: function() {
					if (tipElement.data('mouseOnToPopup')) {
						cancelHoverTimer(session.activeHover);
						setHoverTimer(session.activeHover, 'hide');
						session.mouseTarget = null;
					}
				}
			});
		}

		// attach hover events to all matched elements
		return this.on({
			mouseenter: function(event) {
				var element = $(this);
				cancelHoverTimer(element);
				session.mouseTarget = element;
				session.previousX = event.pageX;
				session.previousY = event.pageY;
				if (!element.data('hasActiveHover')) {
					session.popOpenImminent = true;
					setHoverTimer(element, 'show');
				}
			},
			mouseleave: function() {
				var element = $(this);
				cancelHoverTimer(element);
				session.mouseTarget = null;
				session.popOpenImminent = false;
				if (element.data('hasActiveHover')) {
					setHoverTimer(element, 'hide');
				}
			}
		});

		///////////// PRIVATE FUNCTIONS /////////////

		/**
		 * Checks mouse position to make sure
		 * @private
		 * @param {Object} element The element that the popup should target.
		 */
		function checkForIntent(element) {
			cancelHoverTimer(element);

			// calculate mouse position difference
			var xDifference = Math.abs(session.previousX - session.currentX),
				yDifference = Math.abs(session.previousY - session.currentY),
				totalDifference = xDifference + yDifference;

			// check if difference has passed the sensitivity threshold
			if (totalDifference < options.intentSensitivity) {
				element.data('hasActiveHover', true);
				// show popup, asap
				showTip(element);
			} else {
				// try again
				session.previousX = session.currentX;
				session.previousY = session.currentY;
				setHoverTimer(element, 'show');
			}
		}

		/**
		 * Shows the tooltip popup, as soon as possible.
		 * @private
		 * @param {Object} element The element that the popup should target.
		 */
		function showTip(element) {
			// if the popup is open and we got asked to open another one then
			// the old one is still in its fadeOut cycle, so wait and try again
			if (session.isPopOpen) {
				setTimeout(function() {
					showTip(element);
				}, options.closeDelay);
				return;
			}

			var tipText = element.data('powertip'),
				tipTarget = element.data('powertiptarget'),
				tipElem = element.data('powertipjq'),
				tipContent = tipTarget ? $('#' + tipTarget) : [];

			// set popup content
			if (tipText) {
				tipElement.html(tipText);
			} else if (tipElem.length > 0) {
				tipElement.empty();
				tipElem.clone(true, true).appendTo(tipElement);
			} else if (tipContent.length > 0) {
				tipElement.html($('#' + tipTarget).html());
			} else {
				// we have no content to display, give up
				return;
			}

			session.activeHover = element;
			session.isPopOpen = true;

			// set popup position
			if (!options.followMouse) {
				setPopPosition(element);
				session.isFixedPopOpen = true;
			}

			tipElement.data('followMouse', options.followMouse);
			tipElement.data('mouseOnToPopup', options.mouseOnToPopup);

			// fadein
			tipElement.stop(true, true).fadeIn(options.fadeInTime, function() {
				// start desync polling
				if (!session.desyncTimeout) {
					session.desyncTimeout = setInterval(closeDesyncedTip, 500);
				}
			});
		}

		/**
		 * Hides the tooltip popup, immediately.
		 * @private
		 * @param {Object} element The element that the popup should target.
		 */
		function hideTip(element) {
			element.data('hasActiveHover', false);
			tipElement.fadeOut(options.fadeOutTime, function() {
				session.activeHover = null;
				session.isPopOpen = false;
				session.isFixedPopOpen = false;
				tipElement.removeClass(options.placement);
				// support mouse-follow and fixed position pops at the same
				// time by moving the popup to the last known cursor location
				// after it is hidden
				tipElement.css('left', session.currentX + options.offset + 'px');
				tipElement.css('top', session.currentY + options.offset + 'px');
				// stop desync polling
				session.desyncTimeout = clearInterval(session.desyncTimeout);
			});
		}

		/**
		 * Checks for a tooltip desync and closes the tooltip if one occurs.
		 * @private
		 */
		function closeDesyncedTip() {
			// It is possible for the mouse cursor to leave an element without
			// firing the mouseleave event. This seems to happen (in FF) if the
			// element is disabled under mouse cursor, the element is moved out
			// from under the mouse cursor (such as a slideDown() occurring
			// above it), or if the browser is resized by code moving the
			// element from under the mouse cursor. If this happens it will
			// result in a desynced tooltip because we wait for any exiting
			// open tooltips to close before opening a new one. So we should
			// periodically check for a desync situation and close the tip if
			// such a situation arises.
			if (session.isPopOpen) {
				var isDesynced = false;

				// case 1: user already moused onto another tip - easy test
				if (session.activeHover.data('hasActiveHover') === false) {
					isDesynced = true;
				} else {
					// case 2: hanging tip - have to test if mouse position is
					// not over the active hover and not over a tooltip set to
					// let the user interact with it
					if (!isMouseOver(session.activeHover)) {
						if (tipElement.data('mouseOnToPopup')) {
							if (!isMouseOver(tipElement)) {
								isDesynced = true;
							}
						} else {
							isDesynced = true;
						}
					}
				}

				if (isDesynced) {
					// close the desynced tip
					hideTip(session.activeHover);
				}
			}
		}

		/**
		 * Moves the tooltip popup to the users mouse cursor.
		 * @private
		 * @param {Object} event The window or document mousemove event.
		 */
		function movePop(event) {
			// to support having fixed powertips on the same page as cursor
			// powertips, where both instances are referencing the same popup
			// element, we need to keep track of the mouse position constantly,
			// but we should only set the pop location if a fixed pop is not
			// currently open, a pop open is imminent or active, and the popup
			// element in question does have a mouse-follow using it.
			if ((session.isPopOpen && !session.isFixedPopOpen) || (session.popOpenImminent && !session.isFixedPopOpen && tipElement.data('hasMouseMove'))) {
				// grab measurements
				var scrollTop = $window.scrollTop(),
					windowWidth = $window.width(),
					windowHeight = $window.height(),
					popWidth = tipElement.outerWidth(),
					popHeight = tipElement.outerHeight(),
					x = 0,
					y = 0;

				// constrain pop to browser viewport
				if ((popWidth + event.pageX + options.offset) < windowWidth) {
					x = event.pageX + options.offset;
				} else {
					x = windowWidth - popWidth;
				}
				if ((popHeight + event.pageY + options.offset) < (scrollTop + windowHeight)) {
					y = event.pageY + options.offset;
				} else {
					y = scrollTop + windowHeight - popHeight;
				}

				// set the css
				tipElement.css('left', x + 'px');
				tipElement.css('top', y + 'px');
			}
		}

		/**
		 * Sets the tooltip popup too the correct position relative to the
		 * specified target element. Based on options settings.
		 * @private
		 * @param {Object} element The element that the popup should target.
		 */
		function setPopPosition(element) {
			// grab measurements
			var objectOffset = element.offset(),
				objectWidth = element.outerWidth(),
				objectHeight = element.outerHeight(),
				popWidth = tipElement.outerWidth(),
				popHeight = tipElement.outerHeight(),
				x = 0,
				y = 0;

			// calculate the appropriate x and y position in the document
			switch (options.placement) {
			case 'n':
				x = (objectOffset.left + (objectWidth / 2)) - (popWidth / 2);
				y = objectOffset.top - popHeight - options.offset;
				break;
			case 'e':
				x = objectOffset.left + objectWidth + options.offset;
				y = (objectOffset.top + (objectHeight / 2)) - (popHeight / 2);
				break;
			case 's':
				x = (objectOffset.left + (objectWidth / 2)) - (popWidth / 2);
				y = objectOffset.top + objectHeight + options.offset;
				break;
			case 'w':
				x = objectOffset.left - popWidth - options.offset;
				y = (objectOffset.top + (objectHeight / 2)) - (popHeight / 2);
				break;
			}

			tipElement.addClass(options.placement);

			// set the css position
			tipElement.css('left', Math.round(x) + 'px');
			tipElement.css('top', Math.round(y) + 'px');
		}

		/**
		 * Sets up a hover timer on the specified element.
		 * @private
		 * @param {Object} element The element that the popup should target.
		 * @param {String} action The hover timer action ('show' or 'hide').
		 */
		function setHoverTimer(element, action) {
			if (action === 'show') {
				element.data('hoverTimer', setTimeout(
					function() {
						element.data('hoverTimer', null);
						checkForIntent(element);
					},
					options.intentPollInterval
				));
			} else if (action === 'hide') {
				element.data('hoverTimer', setTimeout(
					function() {
						element.data('hoverTimer', null);
						hideTip(element);
					},
					options.closeDelay
				));
			}
		}

	};

	/**
	 * Default options for the powerTip plugin.
	 * @type Object
	 */
	$.fn.powerTip.defaults = {
		fadeInTime: 200,
		fadeOutTime: 200,
		followMouse: false,
		popupId: 'powerTip',
		intentSensitivity: 7,
		intentPollInterval: 100,
		closeDelay: 200,
		placement: 's',
		offset: 10,
		mouseOnToPopup: false
	};

	var onMoveHooked = false;
	/**
	 * Hooks the trackMouse() function to the window's mousemove event.
	 * Prevents attaching the event more than once.
	 * @private
	 */
	function hookOnMoveOnce() {
		if (!onMoveHooked) {
			onMoveHooked = true;
			$window.on('mousemove', trackMouse);
		}
	}

	/**
	 * Saves the current mouse coordinates to the powerTip session object.
	 * @private
	 * @param {Object} event The mousemove event for the document.
	 */
	function trackMouse(event) {
		session.currentX = event.pageX;
		session.currentY = event.pageY;
	}

	/**
	 * Cancels active hover timer.
	 * @private
	 * @param {Object} element The element that the popup should target.
	 */
	function cancelHoverTimer(element) {
		if (element.data('hoverTimer')) {
			clearTimeout(element.data('hoverTimer'));
			element.data('hoverTimer', null);
		}
	}

	/**
	 * Tests if the mouse is currently over the specified element.
	 * @private
	 * @param {Object} element The element to check for hover.
	 * @return {Boolean}
	 */
	function isMouseOver(element) {
		var elementPosition = element.offset();
		return session.currentX >= elementPosition.left &&
			session.currentX <= elementPosition.left + element.outerWidth() &&
			session.currentY >= elementPosition.top &&
			session.currentY <= elementPosition.top + element.outerHeight();
	}

}(jQuery));
<commit_msg>Changed removeClass call to remove all classes.<commit_after>/**
 * jQuery PowerTip Plugin
 *
 * @fileoverview jQuery plugin that creates hover tooltips.
 * @link https://github.com/stevenbenner/jquery-powertip
 * @author Steven Benner
 * @version 1.0.1
 * @requires jQuery 1.7 or later
 * @license jQuery PowerTip Plugin
 * <https://github.com/stevenbenner/jquery-powertip>
 * Copyright (c) 2012 Steven Benner, http://stevenbenner.com/
 * Released under the MIT license.
 * <https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt>
 */

(function($) {
	'use strict';

	// useful private variables
	var $window = $(window),
		$body = $('body');

	/**
	 * Session data
	 * Private properties global to all powerTip instances
	 * @type Object
	 */
	var session = {
		isPopOpen: false,
		isFixedPopOpen: false,
		popOpenImminent: false,
		activeHover: null,
		mouseTarget: null,
		currentX: 0,
		currentY: 0,
		previousX: 0,
		previousY: 0,
		desyncTimeout: null
	};

	/**
	 * Display hover tooltips on the matched elements.
	 * @param {Object} opts The options object to use for the plugin.
	 * @return {Object} jQuery object for the matched selectors.
	 */
	$.fn.powerTip = function(opts) {

		// don't do any work if there were no matched elements
		if (!this.length) {
			return this;
		}

		// extend options
		var options = $.extend({}, $.fn.powerTip.defaults, opts);

		// hook mouse tracking, once
		hookOnMoveOnce();

		// build and append popup div if it does not already exist
		var tipElement = $('#' + options.popupId);
		if (tipElement.length === 0) {
			tipElement = $('

', { id: options.popupId });
			$body.append(tipElement);
		}

		// hook mousemove for cursor follow tooltips
		if (options.followMouse) {
			// only one movePop hook per popup element, please
			if (!tipElement.data('hasMouseMove')) {
				$window.on('mousemove', movePop);
			}
			tipElement.data('hasMouseMove', true);
		}

		// attempt to use title attribute text if there is no data-powertip,
		// data-powertipjq or data-powertiptarget. If we do use the title
		// attribute, delete the attribute so the browser will not show it
		this.each(function() {
			var $this = $(this),
				dataPowertip = $this.data('powertip'),
				dataElem = $this.data('powertipjq'),
				dataTarget = $this.data('powertiptarget'),
				title = $this.attr('title');

			if (!dataPowertip && !dataTarget && !dataElem && title) {
				$this.data('powertip', title);
				$this.removeAttr('title');
			}
		});

		// if we want to be able to mouse onto the popup then we need to attach
		// hover events to the popup that will cancel a close request on hover
		// and start a new close request on mouseleave
		if (options.followMouse || options.mouseOnToPopup) {
			tipElement.on({
				mouseenter: function() {
					if (tipElement.data('followMouse') || tipElement.data('mouseOnToPopup')) {
						cancelHoverTimer(session.activeHover);
						session.mouseTarget = session.activeHover;
					}
				},
				mouseleave: function() {
					if (tipElement.data('mouseOnToPopup')) {
						cancelHoverTimer(session.activeHover);
						setHoverTimer(session.activeHover, 'hide');
						session.mouseTarget = null;
					}
				}
			});
		}

		// attach hover events to all matched elements
		return this.on({
			mouseenter: function(event) {
				var element = $(this);
				cancelHoverTimer(element);
				session.mouseTarget = element;
				session.previousX = event.pageX;
				session.previousY = event.pageY;
				if (!element.data('hasActiveHover')) {
					session.popOpenImminent = true;
					setHoverTimer(element, 'show');
				}
			},
			mouseleave: function() {
				var element = $(this);
				cancelHoverTimer(element);
				session.mouseTarget = null;
				session.popOpenImminent = false;
				if (element.data('hasActiveHover')) {
					setHoverTimer(element, 'hide');
				}
			}
		});

		///////////// PRIVATE FUNCTIONS /////////////

		/**
		 * Checks mouse position to make sure
		 * @private
		 * @param {Object} element The element that the popup should target.
		 */
		function checkForIntent(element) {
			cancelHoverTimer(element);

			// calculate mouse position difference
			var xDifference = Math.abs(session.previousX - session.currentX),
				yDifference = Math.abs(session.previousY - session.currentY),
				totalDifference = xDifference + yDifference;

			// check if difference has passed the sensitivity threshold
			if (totalDifference < options.intentSensitivity) {
				element.data('hasActiveHover', true);
				// show popup, asap
				showTip(element);
			} else {
				// try again
				session.previousX = session.currentX;
				session.previousY = session.currentY;
				setHoverTimer(element, 'show');
			}
		}

		/**
		 * Shows the tooltip popup, as soon as possible.
		 * @private
		 * @param {Object} element The element that the popup should target.
		 */
		function showTip(element) {
			// if the popup is open and we got asked to open another one then
			// the old one is still in its fadeOut cycle, so wait and try again
			if (session.isPopOpen) {
				setTimeout(function() {
					showTip(element);
				}, options.closeDelay);
				return;
			}

			var tipText = element.data('powertip'),
				tipTarget = element.data('powertiptarget'),
				tipElem = element.data('powertipjq'),
				tipContent = tipTarget ? $('#' + tipTarget) : [];

			// set popup content
			if (tipText) {
				tipElement.html(tipText);
			} else if (tipElem.length > 0) {
				tipElement.empty();
				tipElem.clone(true, true).appendTo(tipElement);
			} else if (tipContent.length > 0) {
				tipElement.html($('#' + tipTarget).html());
			} else {
				// we have no content to display, give up
				return;
			}

			session.activeHover = element;
			session.isPopOpen = true;

			// set popup position
			if (!options.followMouse) {
				setPopPosition(element);
				session.isFixedPopOpen = true;
			}

			tipElement.data('followMouse', options.followMouse);
			tipElement.data('mouseOnToPopup', options.mouseOnToPopup);

			// fadein
			tipElement.stop(true, true).fadeIn(options.fadeInTime, function() {
				// start desync polling
				if (!session.desyncTimeout) {
					session.desyncTimeout = setInterval(closeDesyncedTip, 500);
				}
			});
		}

		/**
		 * Hides the tooltip popup, immediately.
		 * @private
		 * @param {Object} element The element that the popup should target.
		 */
		function hideTip(element) {
			element.data('hasActiveHover', false);
			tipElement.fadeOut(options.fadeOutTime, function() {
				session.activeHover = null;
				session.isPopOpen = false;
				session.isFixedPopOpen = false;
				tipElement.removeClass();
				// support mouse-follow and fixed position pops at the same
				// time by moving the popup to the last known cursor location
				// after it is hidden
				tipElement.css('left', session.currentX + options.offset + 'px');
				tipElement.css('top', session.currentY + options.offset + 'px');
				// stop desync polling
				session.desyncTimeout = clearInterval(session.desyncTimeout);
			});
		}

		/**
		 * Checks for a tooltip desync and closes the tooltip if one occurs.
		 * @private
		 */
		function closeDesyncedTip() {
			// It is possible for the mouse cursor to leave an element without
			// firing the mouseleave event. This seems to happen (in FF) if the
			// element is disabled under mouse cursor, the element is moved out
			// from under the mouse cursor (such as a slideDown() occurring
			// above it), or if the browser is resized by code moving the
			// element from under the mouse cursor. If this happens it will
			// result in a desynced tooltip because we wait for any exiting
			// open tooltips to close before opening a new one. So we should
			// periodically check for a desync situation and close the tip if
			// such a situation arises.
			if (session.isPopOpen) {
				var isDesynced = false;

				// case 1: user already moused onto another tip - easy test
				if (session.activeHover.data('hasActiveHover') === false) {
					isDesynced = true;
				} else {
					// case 2: hanging tip - have to test if mouse position is
					// not over the active hover and not over a tooltip set to
					// let the user interact with it
					if (!isMouseOver(session.activeHover)) {
						if (tipElement.data('mouseOnToPopup')) {
							if (!isMouseOver(tipElement)) {
								isDesynced = true;
							}
						} else {
							isDesynced = true;
						}
					}
				}

				if (isDesynced) {
					// close the desynced tip
					hideTip(session.activeHover);
				}
			}
		}

		/**
		 * Moves the tooltip popup to the users mouse cursor.
		 * @private
		 * @param {Object} event The window or document mousemove event.
		 */
		function movePop(event) {
			// to support having fixed powertips on the same page as cursor
			// powertips, where both instances are referencing the same popup
			// element, we need to keep track of the mouse position constantly,
			// but we should only set the pop location if a fixed pop is not
			// currently open, a pop open is imminent or active, and the popup
			// element in question does have a mouse-follow using it.
			if ((session.isPopOpen && !session.isFixedPopOpen) || (session.popOpenImminent && !session.isFixedPopOpen && tipElement.data('hasMouseMove'))) {
				// grab measurements
				var scrollTop = $window.scrollTop(),
					windowWidth = $window.width(),
					windowHeight = $window.height(),
					popWidth = tipElement.outerWidth(),
					popHeight = tipElement.outerHeight(),
					x = 0,
					y = 0;

				// constrain pop to browser viewport
				if ((popWidth + event.pageX + options.offset) < windowWidth) {
					x = event.pageX + options.offset;
				} else {
					x = windowWidth - popWidth;
				}
				if ((popHeight + event.pageY + options.offset) < (scrollTop + windowHeight)) {
					y = event.pageY + options.offset;
				} else {
					y = scrollTop + windowHeight - popHeight;
				}

				// set the css
				tipElement.css('left', x + 'px');
				tipElement.css('top', y + 'px');
			}
		}

		/**
		 * Sets the tooltip popup too the correct position relative to the
		 * specified target element. Based on options settings.
		 * @private
		 * @param {Object} element The element that the popup should target.
		 */
		function setPopPosition(element) {
			// grab measurements
			var objectOffset = element.offset(),
				objectWidth = element.outerWidth(),
				objectHeight = element.outerHeight(),
				popWidth = tipElement.outerWidth(),
				popHeight = tipElement.outerHeight(),
				x = 0,
				y = 0;

			// calculate the appropriate x and y position in the document
			switch (options.placement) {
			case 'n':
				x = (objectOffset.left + (objectWidth / 2)) - (popWidth / 2);
				y = objectOffset.top - popHeight - options.offset;
				break;
			case 'e':
				x = objectOffset.left + objectWidth + options.offset;
				y = (objectOffset.top + (objectHeight / 2)) - (popHeight / 2);
				break;
			case 's':
				x = (objectOffset.left + (objectWidth / 2)) - (popWidth / 2);
				y = objectOffset.top + objectHeight + options.offset;
				break;
			case 'w':
				x = objectOffset.left - popWidth - options.offset;
				y = (objectOffset.top + (objectHeight / 2)) - (popHeight / 2);
				break;
			}

			tipElement.addClass(options.placement);

			// set the css position
			tipElement.css('left', Math.round(x) + 'px');
			tipElement.css('top', Math.round(y) + 'px');
		}

		/**
		 * Sets up a hover timer on the specified element.
		 * @private
		 * @param {Object} element The element that the popup should target.
		 * @param {String} action The hover timer action ('show' or 'hide').
		 */
		function setHoverTimer(element, action) {
			if (action === 'show') {
				element.data('hoverTimer', setTimeout(
					function() {
						element.data('hoverTimer', null);
						checkForIntent(element);
					},
					options.intentPollInterval
				));
			} else if (action === 'hide') {
				element.data('hoverTimer', setTimeout(
					function() {
						element.data('hoverTimer', null);
						hideTip(element);
					},
					options.closeDelay
				));
			}
		}

	};

	/**
	 * Default options for the powerTip plugin.
	 * @type Object
	 */
	$.fn.powerTip.defaults = {
		fadeInTime: 200,
		fadeOutTime: 200,
		followMouse: false,
		popupId: 'powerTip',
		intentSensitivity: 7,
		intentPollInterval: 100,
		closeDelay: 200,
		placement: 's',
		offset: 10,
		mouseOnToPopup: false
	};

	var onMoveHooked = false;
	/**
	 * Hooks the trackMouse() function to the window's mousemove event.
	 * Prevents attaching the event more than once.
	 * @private
	 */
	function hookOnMoveOnce() {
		if (!onMoveHooked) {
			onMoveHooked = true;
			$window.on('mousemove', trackMouse);
		}
	}

	/**
	 * Saves the current mouse coordinates to the powerTip session object.
	 * @private
	 * @param {Object} event The mousemove event for the document.
	 */
	function trackMouse(event) {
		session.currentX = event.pageX;
		session.currentY = event.pageY;
	}

	/**
	 * Cancels active hover timer.
	 * @private
	 * @param {Object} element The element that the popup should target.
	 */
	function cancelHoverTimer(element) {
		if (element.data('hoverTimer')) {
			clearTimeout(element.data('hoverTimer'));
			element.data('hoverTimer', null);
		}
	}

	/**
	 * Tests if the mouse is currently over the specified element.
	 * @private
	 * @param {Object} element The element to check for hover.
	 * @return {Boolean}
	 */
	function isMouseOver(element) {
		var elementPosition = element.offset();
		return session.currentX >= elementPosition.left &&
			session.currentX <= elementPosition.left + element.outerWidth() &&
			session.currentY >= elementPosition.top &&
			session.currentY <= elementPosition.top + element.outerHeight();
	}

}(jQuery));
<|endoftext|>


<commit_before>
var SessionView = Marionette.ItemView.extend({
	template: '#session-template',
	className: 'session span3',
	firstUserView: null,

	ui: {
		attend: '.attend',
		start:'.start',
		joinDialog:'.started-modal'
	},

	events: {
		'click .attend':'attend',
		'click .start':'start',
		'click a.join-chosen-session':'joined'
	},

	initialize: function() {
		console.log("initializing session view, model: " + JSON.stringify(this.model));
		if(!_.isNull(this.model.get("firstAttendee"))) {
			console.log("setting up first user view");
			this.firstUserView = new UserView({model:new models.User(this.model.get("firstAttendee"))});
		} else {
			console.log("Missing first attendee.");
		}

		this.listenTo(this.model, 'change', this.render, this);
		this.listenTo(this.model, 'change:firstAttendee', function() {
			this.firstUserView = new UserView({model:new models.User(this.model.get("firstAttendee"))});
		}, this);
		this.listenTo(this.model, 'change:session-key', function() {
			console.log("got start message!");
			this.ui.joinDialog.find("a").attr("href", "/session/" + this.model.get("session-key"));
			this.ui.joinDialog.modal('show');
			setTimeout(_.bind(function() {
				console.log("running hide");
				$(".modal.in").modal("hide");
				// this.ui.joinDialog.modal('hide');
			}, this), 10000);

		}, this);

	},

	onRender: function() {
		console.log("on render FOR SESSION");
		// things to do here:
		// 1. Hide attending if no one is attending
		// 2. If numAttending > 0, pick the first person and put their icon in .first
		// 3. manage the counter bars for the rest of the count.
		var numAttendees = this.model.numAttendees();
		if(numAttendees==0) {
			this.$el.find(".attending").hide();
			this.$el.find(".empty").show();
		} else {
			this.$el.find(".attending").show();
			this.$el.find(".empty").hide();

			// console.log("about to make a user view for the firstUser: " + JSON.stringify(this.model.get("firstAttendee")));
			// var firstUserView = new UserView({model:new models.User(this.model.get("firstAttendee"))});
			if(!_.isNull(this.firstUserView)) {
				if(!_.isUndefined(this.firstUserView.model.get("picture"))) {
					this.$el.find(".first").append(this.firstUserView.render().el);
				}
			}

			var count = 0;
			this.$el.find(".attending").children().each(function(index, el) {
				if(count < numAttendees) {
					$(el).addClass("selected");
				} else {
					$(el).removeClass("selected");
				}

				count ++;
			});
		}

		if(this.model.get("started")) {
			this.$el.find(".started").show();
		} else {
			this.$el.find(".started").hide();
		}

		if(this.model.numAttendees()==this.model.MAX_ATTENDEES) {
			this.$el.find(".full").show();
		} else {
			this.$el.find(".full").hide();
		}

		if(IS_ADMIN) {
			// show the admin UI. obviously, requests generated here are authenticated
			// on the server, so doesn't matter if users mess around and show these
			// buttons covertly.
			this.$el.find(".admin").show();
		} else {
			this.$el.find(".admin").hide();
		}

		if(this.model.isAttending(USER_ID)) {
			this.ui.attend.addClass("active");
			this.ui.attend.find(".text").text("JOINED");
		} else {
			this.ui.attend.removeClass("active");
			this.ui.attend.find(".text").text("JOIN");
		}
	},

	destroy: function() {
		this.model.destroy();
	},

	attend: function() {
		console.log("attend pressed on " + this.model.id);

		if(this.ui.attend.hasClass("active")) {
			this.ui.attend.text("JOIN");
			var message = {type:"unattend", args:{id:this.model.id}};
			sock.send(JSON.stringify(message));
		} else {
			var message = {type:"attend", args:{id:this.model.id}};
			sock.send(JSON.stringify(message));
		}
	},

	start: function() {
		var message = {type:"start", args:{id:this.model.id}};
		sock.send(JSON.stringify(message));
	},

	joined: function() {
		console.log("joined event cliked")
		this.ui.joinDialog.modal('hide');
	}
});

var SessionListView = Backbone.Marionette.CompositeView.extend({
	template: "#session-list-template",
	itemView: SessionView,
	itemViewContainer: '#session-list-container',
	id: "session-list",

	initialize: function() {
		this.listenTo(this.collection, 'all', this.update, this);
	},

	onRender: function() {
		this.update();
	},

	update: function() {
		// ?? don't think we need this.
	},
})

var UserView = Marionette.ItemView.extend({
	template: '#user-template',
	className: 'user',

	events: {
		'click' : 'click'
	},

	initialize: function() {
		this.listenTo(this.model, 'change', this.render, this);
	},

	click: function() {
		console.log("user clicked: " + this.model.get("displayName"));
	},

	onRender: function() {
		// add in the tooltip attributes
		this.$el.attr("data-toggle", "tooltip");
		this.$el.attr("title", this.model.get("displayName"));
		this.$el.tooltip();
	}
});

var UserListView = Backbone.Marionette.CompositeView.extend({
	template: '#user-list-template',
	itemView: UserView,
	itemViewContainer: "#user-list-container",
	id: "user-list",

	initialize: function() {
		this.listenTo(this.collection, 'all', this.update, this);
	}
});

var ChatMessageView = Marionette.ItemView.extend({
	template: '#chat-message-template',
	className: 'chat-message',

});

var ChatView = Marionette.CompositeView.extend({
	template: '#chat-template',
	itemView: ChatMessageView,
	itemViewContainer: "#chat-list-container",
	id: "chat",

	ui: {
		chatInput: "#chat-input"
	},

	events: {
		'submit form':'chat'
	},

	initialize: function() {
		this.listenTo(this.collection, 'all', this.update, this);
	},

	update: function() {
		this.$el.find("#chat-container").scrollTop($("#chat-container")[0].scrollHeight);
	},

	chat: function(e) {
		var msg = this.ui.chatInput.val();
		sock.send(JSON.stringify({type:"chat", args:{text:msg}}));
		this.ui.chatInput.val("");
		e.preventDefault();
		return false;
	}
});

<commit_msg>Clicking join after the event has started how sends you to the hangout.<commit_after>
var SessionView = Marionette.ItemView.extend({
	template: '#session-template',
	className: 'session span3',
	firstUserView: null,

	ui: {
		attend: '.attend',
		start:'.start',
		joinDialog:'.started-modal'
	},

	events: {
		'click .attend':'attend',
		'click .start':'start',
		'click a.join-chosen-session':'joined'
	},

	initialize: function() {
		console.log("initializing session view, model: " + JSON.stringify(this.model));
		if(!_.isNull(this.model.get("firstAttendee"))) {
			console.log("setting up first user view");
			this.firstUserView = new UserView({model:new models.User(this.model.get("firstAttendee"))});
		} else {
			console.log("Missing first attendee.");
		}

		this.listenTo(this.model, 'change', this.render, this);
		this.listenTo(this.model, 'change:firstAttendee', function() {
			this.firstUserView = new UserView({model:new models.User(this.model.get("firstAttendee"))});
		}, this);
		this.listenTo(this.model, 'change:session-key', function() {
			console.log("got start message!");
			this.ui.joinDialog.find("a").attr("href", "/session/" + this.model.get("session-key"));
			this.ui.joinDialog.modal('show');
			setTimeout(_.bind(function() {
				console.log("running hide");
				$(".modal.in").modal("hide");
				// this.ui.joinDialog.modal('hide');
			}, this), 10000);

		}, this);

	},

	onRender: function() {
		console.log("on render FOR SESSION");
		// things to do here:
		// 1. Hide attending if no one is attending
		// 2. If numAttending > 0, pick the first person and put their icon in .first
		// 3. manage the counter bars for the rest of the count.
		var numAttendees = this.model.numAttendees();
		if(numAttendees==0) {
			this.$el.find(".attending").hide();
			this.$el.find(".empty").show();
		} else {
			this.$el.find(".attending").show();
			this.$el.find(".empty").hide();

			// console.log("about to make a user view for the firstUser: " + JSON.stringify(this.model.get("firstAttendee")));
			// var firstUserView = new UserView({model:new models.User(this.model.get("firstAttendee"))});
			if(!_.isNull(this.firstUserView)) {
				if(!_.isUndefined(this.firstUserView.model.get("picture"))) {
					this.$el.find(".first").append(this.firstUserView.render().el);
				}
			}

			var count = 0;
			this.$el.find(".attending").children().each(function(index, el) {
				if(count < numAttendees) {
					$(el).addClass("selected");
				} else {
					$(el).removeClass("selected");
				}

				count ++;
			});
		}

		if(this.model.get("started")) {
			this.$el.find(".started").show();
		} else {
			this.$el.find(".started").hide();
		}

		if(this.model.numAttendees()==this.model.MAX_ATTENDEES) {
			this.$el.find(".full").show();
		} else {
			this.$el.find(".full").hide();
		}

		if(IS_ADMIN) {
			// show the admin UI. obviously, requests generated here are authenticated
			// on the server, so doesn't matter if users mess around and show these
			// buttons covertly.
			this.$el.find(".admin").show();
		} else {
			this.$el.find(".admin").hide();
		}

		if(this.model.isAttending(USER_ID)) {
			this.ui.attend.addClass("active");
			this.ui.attend.find(".text").text("JOINED");
		} else {
			this.ui.attend.removeClass("active");
			this.ui.attend.find(".text").text("JOIN");
		}
	},

	destroy: function() {
		this.model.destroy();
	},

	attend: function() {
		console.log("attend pressed on " + this.model.id);

		if(this.model.get("started")) {
			// make this load the hangout directly.
			window.open("/session/" + this.model.get("session-key"), "_blank");
			return;
		}

		if(this.ui.attend.hasClass("active")) {
			this.ui.attend.text("JOIN");
			var message = {type:"unattend", args:{id:this.model.id}};
			sock.send(JSON.stringify(message));
		} else {
			var message = {type:"attend", args:{id:this.model.id}};
			sock.send(JSON.stringify(message));
		}
	},

	start: function() {
		var message = {type:"start", args:{id:this.model.id}};
		sock.send(JSON.stringify(message));
	},

	joined: function() {
		console.log("joined event cliked")
		this.ui.joinDialog.modal('hide');
	}
});

var SessionListView = Backbone.Marionette.CompositeView.extend({
	template: "#session-list-template",
	itemView: SessionView,
	itemViewContainer: '#session-list-container',
	id: "session-list",

	initialize: function() {
		this.listenTo(this.collection, 'all', this.update, this);
	},

	onRender: function() {
		this.update();
	},

	update: function() {
		// ?? don't think we need this.
	},
})

var UserView = Marionette.ItemView.extend({
	template: '#user-template',
	className: 'user',

	events: {
		'click' : 'click'
	},

	initialize: function() {
		this.listenTo(this.model, 'change', this.render, this);
	},

	click: function() {
		console.log("user clicked: " + this.model.get("displayName"));
	},

	onRender: function() {
		// add in the tooltip attributes
		this.$el.attr("data-toggle", "tooltip");
		this.$el.attr("title", this.model.get("displayName"));
		this.$el.tooltip();
	}
});

var UserListView = Backbone.Marionette.CompositeView.extend({
	template: '#user-list-template',
	itemView: UserView,
	itemViewContainer: "#user-list-container",
	id: "user-list",

	initialize: function() {
		this.listenTo(this.collection, 'all', this.update, this);
	}
});

var ChatMessageView = Marionette.ItemView.extend({
	template: '#chat-message-template',
	className: 'chat-message',

});

var ChatView = Marionette.CompositeView.extend({
	template: '#chat-template',
	itemView: ChatMessageView,
	itemViewContainer: "#chat-list-container",
	id: "chat",

	ui: {
		chatInput: "#chat-input"
	},

	events: {
		'submit form':'chat'
	},

	initialize: function() {
		this.listenTo(this.collection, 'all', this.update, this);
	},

	update: function() {
		this.$el.find("#chat-container").scrollTop($("#chat-container")[0].scrollHeight);
	},

	chat: function(e) {
		var msg = this.ui.chatInput.val();
		sock.send(JSON.stringify({type:"chat", args:{text:msg}}));
		this.ui.chatInput.val("");
		e.preventDefault();
		return false;
	}
});

<|endoftext|>