<commit_before>IFS.core.accordion = (function () {
  'use strict'
  var accordions = []
  return {
    add: function (accordion) {
      accordions.push(accordion)
    },
    get: function ($accordion) {
      var found = ''
      jQuery.each(accordions, function (index, accordion) {
        if (accordion.$module === $accordion) {
          found = accordion
          return false
        }
      })
      return found
    }

  }
})()

IFS.core.accordion.oldInit = window.GOVUKFrontend.Accordion.prototype.init

window.GOVUKFrontend.Accordion.prototype.init = function () {
  IFS.core.accordion.oldInit.call(this)
  IFS.core.accordion.add(this)
  delete IFS.core.accordion.oldInit
}

window.GOVUKFrontend.Accordion.prototype.sectionChange = function () {
  var accordion = this
  var $newSections = accordion.$module.querySelectorAll('.govuk-accordion__section')
  var $oldSections = accordion.$sections
  accordion.$sections = $newSections

  jQuery.each($newSections, function (i, el) {
    var index = jQuery.inArray(el, $oldSections)
    if (index === -1) {
      accordion.addSection(el, index)
    }
  })
  jQuery.each($oldSections, function (i, el) {
    if (jQuery.inArray(el, $newSections) === -1) {
      accordion.removeSection(el)
    }
  })
}

// This code is copied from the GDS framework, in the initSectionHeaders method
window.GOVUKFrontend.Accordion.prototype.addSection = function ($section, index) {
  // Set header attributes
  var header = $section.querySelector('.' + this.sectionHeaderClass)
  this.initHeaderAttributes(header, index)

  this.setExpanded(this.isExpanded($section), $section)

  // Handle events
  header.addEventListener('click', this.onSectionToggle.bind(this, $section))

  // See if there is any state stored in sessionStorage and set the sections to
  // open or closed.
  this.setInitialState($section)
  jQuery('.govuk-accordion__icon').attr('aria-hidden', 'false')
}

window.GOVUKFrontend.Accordion.prototype.removeSection = function ($section) {
  // Nothing needed to remove section.
}
<commit_msg>IFS-8965 Fixed accordion.<commit_after>IFS.core.accordion = (function () {
  'use strict'
  var accordions = []
  return {
    add: function (accordion) {
      accordions.push(accordion)
    },
    get: function ($accordion) {
      var found = ''
      jQuery.each(accordions, function (index, accordion) {
        if (accordion.$module === $accordion) {
          found = accordion
          return false
        }
      })
      return found
    }

  }
})()

IFS.core.accordion.oldInit = window.GOVUKFrontend.Accordion.prototype.init

window.GOVUKFrontend.Accordion.prototype.init = function () {
  IFS.core.accordion.oldInit.call(this)
  IFS.core.accordion.add(this)
}

window.GOVUKFrontend.Accordion.prototype.sectionChange = function () {
  var accordion = this
  var $newSections = accordion.$module.querySelectorAll('.govuk-accordion__section')
  var $oldSections = accordion.$sections
  accordion.$sections = $newSections

  jQuery.each($newSections, function (i, el) {
    var index = jQuery.inArray(el, $oldSections)
    if (index === -1) {
      accordion.addSection(el, index)
    }
  })
  jQuery.each($oldSections, function (i, el) {
    if (jQuery.inArray(el, $newSections) === -1) {
      accordion.removeSection(el)
    }
  })
}

// This code is copied from the GDS framework, in the initSectionHeaders method
window.GOVUKFrontend.Accordion.prototype.addSection = function ($section, index) {
  // Set header attributes
  var header = $section.querySelector('.' + this.sectionHeaderClass)
  this.initHeaderAttributes(header, index)

  this.setExpanded(this.isExpanded($section), $section)

  // Handle events
  header.addEventListener('click', this.onSectionToggle.bind(this, $section))

  // See if there is any state stored in sessionStorage and set the sections to
  // open or closed.
  this.setInitialState($section)
  jQuery('.govuk-accordion__icon').attr('aria-hidden', 'false')
}

window.GOVUKFrontend.Accordion.prototype.removeSection = function ($section) {
  // Nothing needed to remove section.
}
<|endoftext|>


<commit_before>console.log("Op Codes loaded");

function loadAccConst(value){
  writeToOutputString("A9" + value);
}

function loadAccMem(address){
  writeToOutputString("AD" + address);
}

function storeAccMem(address){
  writeToOutputString("8D" + address);
}

function loadXConst(value){
  writeToOutputString("A2" + value);
}

function loadXMem(address){
  writeToOutputString("AE" + address);
}

function loadYConst(value){
  writeToOutputString("A0" + value);
}

function loadYMem(address){
  writeToOutputString("AC" + address);
}

function compareMemToX(address){
  writeToOutputString("EC" + address);
}

function jumpBytes(value){
  writeToOutputString("D0" + value);
}

function addAccToMem(address){
  writeToOutputString("6D" + address);
}

function sysCall(){
  writeToOutputString("FF");
}<commit_msg>fixed function name to be more accurate<commit_after>console.log("Op Codes loaded");

function loadAccConst(value){
  writeToOutputString("A9" + value);
}

function loadAccMem(address){
  writeToOutputString("AD" + address);
}

function storeAccMem(address){
  writeToOutputString("8D" + address);
}

function loadXConst(value){
  writeToOutputString("A2" + value);
}

function loadXMem(address){
  writeToOutputString("AE" + address);
}

function loadYConst(value){
  writeToOutputString("A0" + value);
}

function loadYMem(address){
  writeToOutputString("AC" + address);
}

function compareMemToX(address){
  writeToOutputString("EC" + address);
}

function jumpBytes(value){
  writeToOutputString("D0" + value);
}

function addMemToAcc(address){
  writeToOutputString("6D" + address);
}

function sysCall(){
  writeToOutputString("FF");
}<|endoftext|>


<commit_before>
function toggle_heat_status() {

    send_url("{%url 'toggle_heat_status'%}", function(data){
        $("#heat_on_btn").toggleClass("btn-success btn-danger")

        })
}

function toggle_manual() {
    send_url("{%url 'toggle_heat_manual'%}", function(data){
        if(data.manual){
            $("#heat_manual_btn").html("Manual")
        }else{
            $("#heat_manual_btn").html("Program")
        }})
}

function read_heat_status() {
    $.ajax({
        url: "{%url 'read_heat_status'%}",

        success: function(data){
            if (data.status == "ON") {
                $("#heat_on_btn").removeClass("btn-danger")
                $("#heat_on_btn").addClass("btn-success")
            }
            if (data.status == "OFF") {
                $("#heat_on_btn").removeClass("btn-success")
                $("#heat_on_btn").addClass("btn-danger")
            }
            $("#economic").html(data.economic + " º")
            $("#confort").html(data.confort + " º")
            $("#tuned_temp").html("Tunned... " + data.tuned + " º")
            $("#time").html(data.time)
            if (data.flame == true) {
                $("#flame").removeClass("label-default")
                $("#flame").addClass("label-danger")
            }else{
                $("#flame").removeClass("label-danger")
                $("#flame").addClass("label-default")
            }
            if(data.manual){
                $("#heat_manual_btn").html("Manual")
                $("#heat_manual_btn").addClass("btn-warning")
            }else{
                $("#heat_manual_btn").html("Program")
                $("#heat_manual_btn").removeClass("btn-warning")
                }

            },

        error: function(ob){show_msg(ob.responseText)}
        });

    $.ajax({
        url: "{%url 'temperature'%}",

        success: function(data){window.console.log(data);$("#internal_temp").html("Current... " + data.internal + " º")}})
}

function dim(temp) {
    send_url("{%url 'dim_temp'%}" + temp, function(data){
        if (temp == "confort") {
            $("#confort").val(data.confort)
        }
        if (temp == "economic"){
            $("#economic").val(data.economic)
        }
        })
}

function bri(temp) {
    send_url("{%url 'bri_temp'%}" + temp, function(data){
        if (temp == "confort") {
            $("#confort").val(data.confort)
        }
        if (temp == "economic"){
            $("#economic").val(data.economic)
        }
        })
}
<commit_msg>added js to new thermometer<commit_after>
function toggle_heat_status() {

    send_url("{%url 'toggle_heat_status'%}", function(data){
        $("#heat_on_btn").toggleClass("btn-success btn-danger")

        })
}

function toggle_manual() {
    send_url("{%url 'toggle_heat_manual'%}", function(data){
        if(data.manual){
            $("#heat_manual_btn").html("Manual")
        }else{
            $("#heat_manual_btn").html("Program")
        }})
}

function read_heat_status() {
    $.ajax({
        url: "{%url 'read_heat_status'%}",

        success: function(data){
            if (data.status == "ON") {
                $("#heat_on_btn").removeClass("btn-danger")
                $("#heat_on_btn").addClass("btn-success")
            }
            if (data.status == "OFF") {
                $("#heat_on_btn").removeClass("btn-success")
                $("#heat_on_btn").addClass("btn-danger")
            }
            $("#economic").html(data.economic + " º")
            $("#confort").html(data.confort + " º")
            $("#tuned_temp").html("Tunned... " + data.tuned + " º")
            $("#time").html(data.time)
            if (data.flame == true) {
                $("#flame").removeClass("label-default")
                $("#flame").addClass("label-danger")
            }else{
                $("#flame").removeClass("label-danger")
                $("#flame").addClass("label-default")
            }
            if(data.manual){
                $("#heat_manual_btn").html("Manual")
                $("#heat_manual_btn").addClass("btn-warning")
            }else{
                $("#heat_manual_btn").html("Program")
                $("#heat_manual_btn").removeClass("btn-warning")
                }

            },

        error: function(ob){show_msg(ob.responseText)}
        });

    $.ajax({
        url: "{%url 'temperature' 'in'%}",

        success: function(data){window.console.log(data);$("#internal_temp").html("Current... " + data.internal + " º")}})
}

function dim(temp) {
    send_url("{%url 'dim_temp'%}" + temp, function(data){
        if (temp == "confort") {
            $("#confort").val(data.confort)
        }
        if (temp == "economic"){
            $("#economic").val(data.economic)
        }
        })
}

function bri(temp) {
    send_url("{%url 'bri_temp'%}" + temp, function(data){
        if (temp == "confort") {
            $("#confort").val(data.confort)
        }
        if (temp == "economic"){
            $("#economic").val(data.economic)
        }
        })
}
<|endoftext|>


<commit_before>// ==UserScript==
// @name                Calculate Hours
// @include     https://your-jira-domain.com/issues/*
// @namespace   http://toomasr.com/
// @version             0.1
// @description Shows the total of hours in the footer
// @copyright   2014+, Toomas Römer
// @author    Toomas Römer
// ==/UserScript==
"use strict";

jQuery(document).ready(function() {
    // Perform initial calculation on page load.
    addEstimatesFooter();

    // Monitor .navigator-content for changes.
    // When #issuetable is rewritten, recalculate estimates footer.
    var oldTable = jQuery("#issuetable").get(0);
    jQuery(".navigator-content").bind('DOMSubtreeModified', function(e) {
        var newTable = jQuery("#issuetable").get(0);
        if (newTable !== oldTable) {
            oldTable = newTable;
            addEstimatesFooter();
        }
    });
});

function addEstimatesFooter() {
    // Clone last row and clean it from content
    var resultRow = jQuery("#issuetable .issuerow:last").clone();
    resultRow.find("td").html("");
    // Calculate sums for the estimate columns
    resultRow.find(".timeoriginalestimate").html(formatEstimate(sumMinutes(".timeoriginalestimate")));
    resultRow.find(".timeestimate").html(formatEstimate(sumMinutes(".timeestimate")));

    var footer = jQuery("

").append(resultRow);
    jQuery("#issuetable").append(footer);
}

function formatEstimate(minutes) {
    if (minutes < 60) {
        return minutes + " minutes";
    }

    var hours = minutes / 60;
    if (hours < 8) {
        return roundTo(hours, 1) + " hours";
    }

    var days = hours / 8;
    if (days < 5) {
        return roundTo(days, 1) + " days";
    }

    var weeks = days / 5;
    return roundTo(weeks, 1) + " weeks";
}

function roundTo(number, decimals) {
    var pow = Math.pow(10, decimals);
    return Math.round(number*pow) / pow;
}

function sumMinutes(field) {
    var minutes = 0;
    jQuery(field).each(function(key,val) {
        var time = jQuery(val).text();
        if (time) {
            minutes += parseToMinutes(time);
        }
    });

    return minutes;
}

function parseToMinutes(timeStr) {
    var times = timeStr.split(",") ;
    var rtrn = 0;
    for (var i = 0; i < times.length; i++) {
        var time = times[i];
        var match;
        if ((match = /([0-9]+)\s*minutes?/.exec(time))) {
            rtrn+=parseInt(match[1], 10);
        }
        else if ((match = /([0-9]+)\s*hours?/.exec(time))) {
            rtrn+=parseInt(match[1]*60);
        }
        else if ((match = /([0-9]+)\s*days?/.exec(time))) {
            rtrn+=parseInt(match[1]*8*60);
        }
        else if ((match = /([0-9]+)\s*weeks?/.exec(time))) {
            rtrn+=parseInt(match[1]*8*60*5);
        }
        else {
            throw ("The string didn't match" + timeStr);
        }
    }
    return rtrn;
}
<commit_msg>Showing the totals in hours - easier to compare to other estimates<commit_after>// ==UserScript==
// @name                Calculate Hours
// @include     https://your-jira-domain.com/issues/*
// @namespace   http://toomasr.com/
// @version             0.1
// @description Shows the total of hours in the footer
// @copyright   2014+, Toomas Römer
// @author    Toomas Römer
// ==/UserScript==
"use strict";

jQuery(document).ready(function() {
    // Perform initial calculation on page load.
    addEstimatesFooter();

    // Monitor .navigator-content for changes.
    // When #issuetable is rewritten, recalculate estimates footer.
    var oldTable = jQuery("#issuetable").get(0);
    jQuery(".navigator-content").bind('DOMSubtreeModified', function(e) {
        var newTable = jQuery("#issuetable").get(0);
        if (newTable !== oldTable) {
            oldTable = newTable;
            addEstimatesFooter();
        }
    });
});

function addEstimatesFooter() {
    // Clone last row and clean it from content
    var resultRow = jQuery("#issuetable .issuerow:last").clone();
    resultRow.find("td").html("");
    // Calculate sums for the estimate columns
    resultRow.find(".timeoriginalestimate").html(formatEstimate(sumMinutes(".timeoriginalestimate")));
    resultRow.find(".timeestimate").html(formatEstimate(sumMinutes(".timeestimate")));

    var footer = jQuery("

").append(resultRow);
    jQuery("#issuetable").append(footer);
}

function formatEstimate(minutes) {
    if (minutes < 60) {
        return minutes + " minutes";
    }

    var hours = minutes / 60;
    return roundTo(hours, 1) + " hours";
}

function roundTo(number, decimals) {
    var pow = Math.pow(10, decimals);
    return Math.round(number*pow) / pow;
}

function sumMinutes(field) {
    var minutes = 0;
    jQuery(field).each(function(key,val) {
        var time = jQuery(val).text();
        if (time) {
            minutes += parseToMinutes(time);
        }
    });

    return minutes;
}

function parseToMinutes(timeStr) {
    var times = timeStr.split(",") ;
    var rtrn = 0;
    for (var i = 0; i < times.length; i++) {
        var time = times[i];
        var match;
        if ((match = /([0-9]+)\s*minutes?/.exec(time))) {
            rtrn+=parseInt(match[1], 10);
        }
        else if ((match = /([0-9]+)\s*hours?/.exec(time))) {
            rtrn+=parseInt(match[1]*60);
        }
        else if ((match = /([0-9]+)\s*days?/.exec(time))) {
            rtrn+=parseInt(match[1]*8*60);
        }
        else if ((match = /([0-9]+)\s*weeks?/.exec(time))) {
            rtrn+=parseInt(match[1]*8*60*5);
        }
        else {
            throw ("The string didn't match" + timeStr);
        }
    }
    return rtrn;
}
<|endoftext|>


<commit_before>/*
	Name: autoComplete
	Author: Raymond Camden & Andy Matthews
	Contributors: Jim Pease (@jmpease)
	Website: http://raymondcamden.com/
			http://andyMatthews.net
	Packed With: http://jsutility.pjoneil.net/
	Version: 1.3
 */
(function($) {

	"use strict";

	var defaults = {
		target: $(),
		source: null,
		callback: null,
		link: null,
		minLength: 0,
		transition: 'fade'
	},
	buildItems = function($this, data, settings) {
		var str = [];
		$.each(data, function(index, value) {
			var urlParam, text;
			// are we working with objects or strings?
			if ($.isPlainObject(value)) {
				urlParam = encodeURIComponent(value.value);
				text = value.label;
			} else {
				urlParam = encodeURIComponent(value);
				text = value;
			}
			urlParam = urlParam.replace('\'', '%27').replace('(', '%28').replace(')', '%29');
			str.push('
' + text + '
');
		});
		$(settings.target).html(str.join('')).listview("refresh");

		// is there a callback?
		if (settings.callback !== null && $.isFunction(settings.callback)) {
			attachCallback(settings);
		}

		if (str.length > 0) {
			$this.trigger("targetUpdated.autocomplete");
		} else {
			$this.trigger("targetCleared.autocomplete");
		}
	},
	attachCallback = function(settings) {
		$('li a', $(settings.target)).bind('click.autocomplete',function(e){
			e.stopPropagation();
			e.preventDefault();
			settings.callback(e);
		});
	},
	clearTarget = function($this, $target) {
		$target.html('').listview('refresh');
		$this.trigger("targetCleared.autocomplete");
	},
	handleInput = function(e) {
		var $this = $(this), text, data, settings = $this.jqmData("autocomplete");
		if (settings) {
			// get the current text of the input field
			text = $this.val();
			// if we don't have enough text zero out the target
			if (text.length < settings.minLength) {
				clearTarget($this, $(settings.target));
			} else {
				// are we looking at a source array or remote data?
				if ($.isArray(settings.source)) {
					data = settings.source.sort().filter(function(element) {
						var element_text, re = new RegExp('^' + text, 'i');
						if ($.isPlainObject(element)) {
							element_text = element.label;
						} else {
							element_text = element;
						}
						return re.test(element_text);
					});
					buildItems($this, data, settings);
				}
				// Accept a function as source.
				// Function needs to call the callback, which is the first parameter.
				// source:function(callback) { mydata = [1,2]; callback(mydata); }
				else if (typeof settings.source === 'function') {

					settings.source(function(data){
						buildItems($this, data, settings);
					});

				} else {
					$.get(settings.source, { term: text }, function(data) {
						buildItems($this, data, settings);
					},"json");
				}
			}
		}
	},
	methods = {
		init: function(options) {
			this.jqmData("autocomplete", $.extend({}, defaults, options));
			return this.unbind("input.autocomplete").bind("input.autocomplete", handleInput);
		},
		// Allow dynamic update of source and link
		update: function(options) {
			var settings = this.jqmData("autocomplete");
			if (settings) {
				this.jqmData("autocomplete", $.extend(settings, options));
			}
			return this;
		},
		// Method to forcibly clear our target
		clear: function() {
			var settings = this.jqmData("autocomplete");
			if (settings) {
				clearTarget(this, $(settings.target));
			}
			return this;
		},
		// Method to destroy (cleanup) plugin
		destroy: function() {
			var settings = this.jqmData("autocomplete");
			if (settings) {
				clearTarget(this, $(settings.target));
				this.jqmRemoveData("autocomplete");
				this.unbind(".autocomplete");
			}
			return this;
		}
	};

	$.fn.autocomplete = function(method) {
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		}
	};

})(jQuery);
<commit_msg>Add text parameters to be able to query an API with the input value<commit_after>/*
	Name: autoComplete
	Author: Raymond Camden & Andy Matthews
	Contributors: Jim Pease (@jmpease)
	Website: http://raymondcamden.com/
			http://andyMatthews.net
	Packed With: http://jsutility.pjoneil.net/
	Version: 1.3
 */
(function($) {

	"use strict";

	var defaults = {
		target: $(),
		source: null,
		callback: null,
		link: null,
		minLength: 0,
		transition: 'fade'
	},
	buildItems = function($this, data, settings) {
		var str = [];
		$.each(data, function(index, value) {
			var urlParam, text;
			// are we working with objects or strings?
			if ($.isPlainObject(value)) {
				urlParam = encodeURIComponent(value.value);
				text = value.label;
			} else {
				urlParam = encodeURIComponent(value);
				text = value;
			}
			urlParam = urlParam.replace('\'', '%27').replace('(', '%28').replace(')', '%29');
			str.push('
' + text + '
');
		});
		$(settings.target).html(str.join('')).listview("refresh");

		// is there a callback?
		if (settings.callback !== null && $.isFunction(settings.callback)) {
			attachCallback(settings);
		}

		if (str.length > 0) {
			$this.trigger("targetUpdated.autocomplete");
		} else {
			$this.trigger("targetCleared.autocomplete");
		}
	},
	attachCallback = function(settings) {
		$('li a', $(settings.target)).bind('click.autocomplete',function(e){
			e.stopPropagation();
			e.preventDefault();
			settings.callback(e);
		});
	},
	clearTarget = function($this, $target) {
		$target.html('').listview('refresh');
		$this.trigger("targetCleared.autocomplete");
	},
	handleInput = function(e) {
		var $this = $(this), text, data, settings = $this.jqmData("autocomplete");
		if (settings) {
			// get the current text of the input field
			text = $this.val();
			// if we don't have enough text zero out the target
			if (text.length < settings.minLength) {
				clearTarget($this, $(settings.target));
			} else {
				// are we looking at a source array or remote data?
				if ($.isArray(settings.source)) {
					data = settings.source.sort().filter(function(element) {
						var element_text, re = new RegExp('^' + text, 'i');
						if ($.isPlainObject(element)) {
							element_text = element.label;
						} else {
							element_text = element;
						}
						return re.test(element_text);
					});
					buildItems($this, data, settings);
				}
				// Accept a function as source.
				// Function needs to call the callback, which is the first parameter.
				// source:function(text,callback) { mydata = [1,2]; callback(mydata); }
				else if (typeof settings.source === 'function') {

					settings.source(text,function(data){
						buildItems($this, data, settings);
					});

				} else {
					$.get(settings.source, { term: text }, function(data) {
						buildItems($this, data, settings);
					},"json");
				}
			}
		}
	},
	methods = {
		init: function(options) {
			this.jqmData("autocomplete", $.extend({}, defaults, options));
			return this.unbind("input.autocomplete").bind("input.autocomplete", handleInput);
		},
		// Allow dynamic update of source and link
		update: function(options) {
			var settings = this.jqmData("autocomplete");
			if (settings) {
				this.jqmData("autocomplete", $.extend(settings, options));
			}
			return this;
		},
		// Method to forcibly clear our target
		clear: function() {
			var settings = this.jqmData("autocomplete");
			if (settings) {
				clearTarget(this, $(settings.target));
			}
			return this;
		},
		// Method to destroy (cleanup) plugin
		destroy: function() {
			var settings = this.jqmData("autocomplete");
			if (settings) {
				clearTarget(this, $(settings.target));
				this.jqmRemoveData("autocomplete");
				this.unbind(".autocomplete");
			}
			return this;
		}
	};

	$.fn.autocomplete = function(method) {
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		}
	};

})(jQuery);
<|endoftext|>


<commit_before>(function($) {
    $.isScrollToFixed = function(el) {
        return $(el).data('ScrollToFixed') !== undefined;
    };

    $.ScrollToFixed = function(el, options) {
        // To avoid scope issues, use 'base' instead of 'this' to reference this
        // class from internal events and functions.
        var base = this;

        // Access to jQuery and DOM versions of element.
        base.$el = $(el);
        base.el = el;

        // Add a reverse reference to the DOM object.
        base.$el.data('ScrollToFixed', base);

        // A flag so we know if the scroll has been reset.
        var isReset = false;

        // The element that was given to us to fix if scrolled above the top of
        // the page.
        var target = base.$el;

        var position;
        var originalPosition;

        // The offset top of the element when resetScroll was called. This is
        // used to determine if we have scrolled past the top of the element.
        var offsetTop = 0;

        // The offset left of the element when resetScroll was called. This is
        // used to move the element left or right relative to the horizontal
        // scroll.
        var offsetLeft = 0;
        var originalOffsetLeft = -1;

        // This last offset used to move the element horizontally. This is used
        // to determine if we need to move the element because we would not want
        // to do that for no reason.
        var lastOffsetLeft = -1;

        // This is the element used to fill the void left by the target element
        // when it goes fixed; otherwise, everything below it moves up the page.
        var spacer = null;

        var spacerClass;

        var className;

        // Capture the original offsets for the target element. This needs to be
        // called whenever the page size changes or when the page is first
        // scrolled. For some reason, calling this before the page is first
        // scrolled causes the element to become fixed too late.
        function resetScroll() {
            // Set the element to it original positioning.
            target.trigger('preUnfixed.ScrollToFixed');
            setUnfixed();
            target.trigger('unfixed.ScrollToFixed');

            // Reset the last offset used to determine if the page has moved
            // horizontally.
            lastOffsetLeft = -1;

            // Capture the offset top of the target element.
            offsetTop = target.offset().top;

            // Capture the offset left of the target element.
            offsetLeft = target.offset().left;

            // If the offsets option is on, alter the left offset.
            if (base.options.offsets) {
                offsetLeft += (target.offset().left - target.position().left);
            }

            if (originalOffsetLeft == -1) {
                originalOffsetLeft = offsetLeft;
            }

            position = target.css('position');

            // Set that this has been called at least once.
            isReset = true;

            if (base.options.bottom != -1) {
                target.trigger('preFixed.ScrollToFixed');
                setFixed();
                target.trigger('fixed.ScrollToFixed');
            }
        }

        function getLimit() {
            var limit = base.options.limit;
            if (!limit) return 0;

            if (typeof(limit) === 'function') {
                return limit();
            }
            return limit;
        }

        // Returns whether the target element is fixed or not.
        function isFixed() {
            return position === 'fixed';
        }

        // Returns whether the target element is absolute or not.
        function isAbsolute() {
            return position === 'absolute';
        }

        function isUnfixed() {
            return !(isFixed() || isAbsolute());
        }

        // Sets the target element to fixed. Also, sets the spacer to fill the
        // void left by the target element.
        function setFixed() {
            // Only fix the target element and the spacer if we need to.
            if (!isFixed()) {
                // Set the spacer to fill the height and width of the target
                // element, then display it.
                spacer.css({
                    'display' : target.css('display'),
                    'width' : target.outerWidth(true),
                    'height' : target.outerHeight(true),
                    'float' : target.css('float')
                });

                // Set the target element to fixed and set its width so it does
                // not fill the rest of the page horizontally. Also, set its top
                // to the margin top specified in the options.
                target.css({
                    'width' : target.width(),
                    'position' : 'fixed',
                    'top' : base.options.bottom == -1?getMarginTop():'',
                    'bottom' : base.options.bottom == -1?'':base.options.bottom,
                    'margin-left' : '0px'
                });

                if (base.options.className) {
                    target.addClass(base.options.className);
                }

                position = 'fixed';
            }
        }

        function setAbsolute() {
            target.css({
                'width' : target.width(),
                'position' : 'absolute',
                'top' : getLimit(),
                'left' : offsetLeft,
                'margin-left' : '0px',
                'bottom' : ''
            });

            position = 'absolute';
        }

        // Sets the target element back to unfixed. Also, hides the spacer.
        function setUnfixed() {
            // Only unfix the target element and the spacer if we need to.
            if (!isUnfixed()) {
                lastOffsetLeft = -1;

                // Hide the spacer now that the target element will fill the
                // space.
                spacer.css('display', 'none');

                // Remove the style attributes that were added to the target.
                // This will reverse the target back to the its original style.
                target.css({
                    'width' : '',
                    'position' : '',
                    'left' : '',
                    'top' : '',
                    'margin-left' : ''
                });

                if (base.options.className) {
                    target.removeClass(base.options.className);
                }

                position = null;
            }
        }

        // Moves the target element left or right relative to the horizontal
        // scroll position.
        function setLeft(x) {
            // Only if the scroll is not what it was last time we did this.
            if (x != lastOffsetLeft) {
                // Move the target element horizontally relative to its original
                // horizontal position.
                target.css('left', offsetLeft - x);

                // Hold the last horizontal position set.
                lastOffsetLeft = x;
            }
        }

        function getMarginTop() {
            return base.options.marginTop;
        }

        // Checks to see if we need to do something based on new scroll position
        // of the page.
        function checkScroll() {
            if (!$.isScrollToFixed(target)) return;
            var wasReset = isReset;

            // If resetScroll has not yet been called, call it. This only
            // happens once.
            if (!isReset) {
                resetScroll();
            }

            // Grab the current horizontal scroll position.
            var x = $(window).scrollLeft();

            // Grab the current vertical scroll position.
            var y = $(window).scrollTop();

            // Get the limit, if there is one.
            var limit = getLimit();

            // If the vertical scroll position, plus the optional margin, would
            // put the target element at the specified limit, set the target
            // element to absolute.
            if (base.options.minWidth && $(window).width() < base.options.minWidth) {
                if (!isUnfixed() || !wasReset) {
                    postPosition();
                    target.trigger('preUnfixed.ScrollToFixed');
                    setUnfixed();
                    target.trigger('unfixed.ScrollToFixed');
                }
            } else if (base.options.bottom == -1) {
                // If the vertical scroll position, plus the optional margin, would
                // put the target element at the specified limit, set the target
                // element to absolute.
                if (limit > 0 && y >= limit - getMarginTop()) {
                    if (!isAbsolute() || !wasReset) {
                        postPosition();
                        target.trigger('preAbsolute.ScrollToFixed');
                        setAbsolute();
                        target.trigger('unfixed.ScrollToFixed');
                    }
                // If the vertical scroll position, plus the optional margin, would
                // put the target element above the top of the page, set the target
                // element to fixed.
                } else if (y >= offsetTop - getMarginTop()) {
                    if (!isFixed() || !wasReset) {
                        postPosition();
                        target.trigger('preFixed.ScrollToFixed');

                        // Set the target element to fixed.
                        setFixed();

                        // Reset the last offset left because we just went fixed.
                        lastOffsetLeft = -1;

                        target.trigger('fixed.ScrollToFixed');
                    }
                    // If the page has been scrolled horizontally as well, move the
                    // target element accordingly.
                    setLeft(x);
                } else {
                    // Set the target element to unfixed, placing it where it was
                    // before.
                    if (!isUnfixed() || !wasReset) {
                        postPosition();
                        target.trigger('preUnfixed.ScrollToFixed');
                        setUnfixed();
                        target.trigger('unfixed.ScrollToFixed');
                    }
                }
            } else {
                if (limit > 0) {
                    if (y + $(window).height() - target.outerHeight(true) >= limit - (getMarginTop() || -getBottom())) {
                        if (isFixed()) {
                            postPosition();
                            target.trigger('preUnfixed.ScrollToFixed');

                            if (originalPosition === 'absolute') {
                                setAbsolute();
                            } else {
                                setUnfixed();
                            }

                            target.trigger('unfixed.ScrollToFixed');
                        }
                    } else {
                        if (!isFixed()) {
                            postPosition();
                            target.trigger('preFixed.ScrollToFixed');
                            setFixed();
                        }
                        setLeft(x);
                        target.trigger('fixed.ScrollToFixed');
                    }
                } else {
                    setLeft(x);
                }
            }
        }

        function getBottom() {
            if (!base.options.bottom) return 0;
            return base.options.bottom;
        }

        function postPosition() {
            var position = target.css('position');

            if (position == 'absolute') {
                target.trigger('postAbsolute.ScrollToFixed');
            } else if (position == 'fixed') {
                target.trigger('postFixed.ScrollToFixed');
            } else {
                target.trigger('postUnfixed.ScrollToFixed');
            }
        }

        var windowResize = function(event) {
            // Check if the element is visible before updating it's position, which
            // improves behavior with responsive designs where this element is hidden.
            if(target.is(':visible')) {
                isReset = false;
                checkScroll();
			}
        }

        var windowScroll = function(event) {
            checkScroll();
        }

        var isPositionFixedSupported = function() {
            var container = document.body;

            if (document.createElement && container && container.appendChild && container.removeChild) {
                var el = document.createElement('div');

                if (!el.getBoundingClientRect) return null;

                el.innerHTML = 'x';
                el.style.cssText = 'position:fixed;top:100px;';
                container.appendChild(el);

                var originalHeight = container.style.height,
                originalScrollTop = container.scrollTop;

                container.style.height = '3000px';
                container.scrollTop = 500;

                var elementTop = el.getBoundingClientRect().top;
                container.style.height = originalHeight;

                var isSupported = (elementTop === 100);
                container.removeChild(el);
                container.scrollTop = originalScrollTop;

                return isSupported;
            }

            return null;
        }

        // Initializes this plugin. Captures the options passed in, turns this
        // off for devices that do not support fixed position, adds the spacer,
        // and binds to the window scroll and resize events.
        base.init = function() {
            // Capture the options for this plugin.
            base.options = $
                    .extend({}, $.ScrollToFixed.defaultOptions, options);

            // Turn off this functionality for devices that do not support it.
            if (!(base.options && base.options.dontCheckForPositionFixedSupport)) {
                var fixedSupported = isPositionFixedSupported();
                if (!fixedSupported) return;
            }

            // Put the target element on top of everything that could be below
            // it. This reduces flicker when the target element is transitioning
            // to fixed.
            base.$el.css('z-index', base.options.zIndex);

            // Create a spacer element to fill the void left by the target
            // element when it goes fixed.
            spacer = $('<div />');

            position = target.css('position');
            originalPosition = target.css('position');

            // Place the spacer right after the target element.
            if (isUnfixed()) base.$el.after(spacer);

            // Reset the target element offsets when the window is resized, then
            // check to see if we need to fix or unfix the target element.
            $(window).bind('resize.ScrollToFixed', windowResize);

            // When the window scrolls, check to see if we need to fix or unfix
            // the target element.
            $(window).bind('scroll.ScrollToFixed', windowScroll);

            if (base.options.preFixed) {
                target.bind('preFixed.ScrollToFixed', base.options.preFixed);
            }
            if (base.options.postFixed) {
                target.bind('postFixed.ScrollToFixed', base.options.postFixed);
            }
            if (base.options.preUnfixed) {
                target.bind('preUnfixed.ScrollToFixed', base.options.preUnfixed);
            }
            if (base.options.postUnfixed) {
                target.bind('postUnfixed.ScrollToFixed', base.options.postUnfixed);
            }
            if (base.options.preAbsolute) {
                target.bind('preAbsolute.ScrollToFixed', base.options.preAbsolute);
            }
            if (base.options.postAbsolute) {
                target.bind('postAbsolute.ScrollToFixed', base.options.postAbsolute);
            }
            if (base.options.fixed) {
                target.bind('fixed.ScrollToFixed', base.options.fixed);
            }
            if (base.options.unfixed) {
                target.bind('unfixed.ScrollToFixed', base.options.unfixed);
            }

            if (base.options.spacerClass) {
                spacer.addClass(base.options.spacerClass);
            }

            target.bind('resize.ScrollToFixed', function() {
                spacer.height(target.height());
            });

            target.bind('scroll.ScrollToFixed', function() {
                target.trigger('preUnfixed.ScrollToFixed');
                setUnfixed();
                target.trigger('unfixed.ScrollToFixed');
                checkScroll();
            });

            target.bind('remove.ScrollToFixed', function() {
                target.trigger('preUnfixed.ScrollToFixed');
                setUnfixed();
                target.trigger('unfixed.ScrollToFixed');

                $(window).unbind('resize.ScrollToFixed', windowResize);
                $(window).unbind('scroll.ScrollToFixed', windowScroll);

                target.unbind('.ScrollToFixed');
                base.$el.removeData('ScrollToFixed');
            });

            // Reset everything.
            windowResize();
        };

        // Initialize the plugin.
        base.init();
    };

    // Sets the option defaults.
    $.ScrollToFixed.defaultOptions = {
        marginTop : 0,
        limit : 0,
        bottom : -1,
        zIndex : 1000
    };

    // Returns enhanced elements that will fix to the top of the page when the
    // page is scrolled.
    $.fn.scrollToFixed = function(options) {
        return this.each(function() {
            (new $.ScrollToFixed(this, options));
        });
    };
})(jQuery);
<commit_msg>See #64: Implemented the preventDefault code suggested by @stefandroog to workaround Chrome's new 'remove' DOM feature.  Thank you for your contribution!<commit_after>(function($) {
    $.isScrollToFixed = function(el) {
        return $(el).data('ScrollToFixed') !== undefined;
    };

    $.ScrollToFixed = function(el, options) {
        // To avoid scope issues, use 'base' instead of 'this' to reference this
        // class from internal events and functions.
        var base = this;

        // Access to jQuery and DOM versions of element.
        base.$el = $(el);
        base.el = el;

        // Add a reverse reference to the DOM object.
        base.$el.data('ScrollToFixed', base);

        // A flag so we know if the scroll has been reset.
        var isReset = false;

        // The element that was given to us to fix if scrolled above the top of
        // the page.
        var target = base.$el;

        var position;
        var originalPosition;

        // The offset top of the element when resetScroll was called. This is
        // used to determine if we have scrolled past the top of the element.
        var offsetTop = 0;

        // The offset left of the element when resetScroll was called. This is
        // used to move the element left or right relative to the horizontal
        // scroll.
        var offsetLeft = 0;
        var originalOffsetLeft = -1;

        // This last offset used to move the element horizontally. This is used
        // to determine if we need to move the element because we would not want
        // to do that for no reason.
        var lastOffsetLeft = -1;

        // This is the element used to fill the void left by the target element
        // when it goes fixed; otherwise, everything below it moves up the page.
        var spacer = null;

        var spacerClass;

        var className;

        // Capture the original offsets for the target element. This needs to be
        // called whenever the page size changes or when the page is first
        // scrolled. For some reason, calling this before the page is first
        // scrolled causes the element to become fixed too late.
        function resetScroll() {
            // Set the element to it original positioning.
            target.trigger('preUnfixed.ScrollToFixed');
            setUnfixed();
            target.trigger('unfixed.ScrollToFixed');

            // Reset the last offset used to determine if the page has moved
            // horizontally.
            lastOffsetLeft = -1;

            // Capture the offset top of the target element.
            offsetTop = target.offset().top;

            // Capture the offset left of the target element.
            offsetLeft = target.offset().left;

            // If the offsets option is on, alter the left offset.
            if (base.options.offsets) {
                offsetLeft += (target.offset().left - target.position().left);
            }

            if (originalOffsetLeft == -1) {
                originalOffsetLeft = offsetLeft;
            }

            position = target.css('position');

            // Set that this has been called at least once.
            isReset = true;

            if (base.options.bottom != -1) {
                target.trigger('preFixed.ScrollToFixed');
                setFixed();
                target.trigger('fixed.ScrollToFixed');
            }
        }

        function getLimit() {
            var limit = base.options.limit;
            if (!limit) return 0;

            if (typeof(limit) === 'function') {
                return limit();
            }
            return limit;
        }

        // Returns whether the target element is fixed or not.
        function isFixed() {
            return position === 'fixed';
        }

        // Returns whether the target element is absolute or not.
        function isAbsolute() {
            return position === 'absolute';
        }

        function isUnfixed() {
            return !(isFixed() || isAbsolute());
        }

        // Sets the target element to fixed. Also, sets the spacer to fill the
        // void left by the target element.
        function setFixed() {
            // Only fix the target element and the spacer if we need to.
            if (!isFixed()) {
                // Set the spacer to fill the height and width of the target
                // element, then display it.
                spacer.css({
                    'display' : target.css('display'),
                    'width' : target.outerWidth(true),
                    'height' : target.outerHeight(true),
                    'float' : target.css('float')
                });

                // Set the target element to fixed and set its width so it does
                // not fill the rest of the page horizontally. Also, set its top
                // to the margin top specified in the options.
                target.css({
                    'width' : target.width(),
                    'position' : 'fixed',
                    'top' : base.options.bottom == -1?getMarginTop():'',
                    'bottom' : base.options.bottom == -1?'':base.options.bottom,
                    'margin-left' : '0px'
                });

                if (base.options.className) {
                    target.addClass(base.options.className);
                }

                position = 'fixed';
            }
        }

        function setAbsolute() {
            target.css({
                'width' : target.width(),
                'position' : 'absolute',
                'top' : getLimit(),
                'left' : offsetLeft,
                'margin-left' : '0px',
                'bottom' : ''
            });

            position = 'absolute';
        }

        // Sets the target element back to unfixed. Also, hides the spacer.
        function setUnfixed() {
            // Only unfix the target element and the spacer if we need to.
            if (!isUnfixed()) {
                lastOffsetLeft = -1;

                // Hide the spacer now that the target element will fill the
                // space.
                spacer.css('display', 'none');

                // Remove the style attributes that were added to the target.
                // This will reverse the target back to the its original style.
                target.css({
                    'width' : '',
                    'position' : '',
                    'left' : '',
                    'top' : '',
                    'margin-left' : ''
                });

                if (base.options.className) {
                    target.removeClass(base.options.className);
                }

                position = null;
            }
        }

        // Moves the target element left or right relative to the horizontal
        // scroll position.
        function setLeft(x) {
            // Only if the scroll is not what it was last time we did this.
            if (x != lastOffsetLeft) {
                // Move the target element horizontally relative to its original
                // horizontal position.
                target.css('left', offsetLeft - x);

                // Hold the last horizontal position set.
                lastOffsetLeft = x;
            }
        }

        function getMarginTop() {
            return base.options.marginTop;
        }

        // Checks to see if we need to do something based on new scroll position
        // of the page.
        function checkScroll() {
            if (!$.isScrollToFixed(target)) return;
            var wasReset = isReset;

            // If resetScroll has not yet been called, call it. This only
            // happens once.
            if (!isReset) {
                resetScroll();
            }

            // Grab the current horizontal scroll position.
            var x = $(window).scrollLeft();

            // Grab the current vertical scroll position.
            var y = $(window).scrollTop();

            // Get the limit, if there is one.
            var limit = getLimit();

            // If the vertical scroll position, plus the optional margin, would
            // put the target element at the specified limit, set the target
            // element to absolute.
            if (base.options.minWidth && $(window).width() < base.options.minWidth) {
                if (!isUnfixed() || !wasReset) {
                    postPosition();
                    target.trigger('preUnfixed.ScrollToFixed');
                    setUnfixed();
                    target.trigger('unfixed.ScrollToFixed');
                }
            } else if (base.options.bottom == -1) {
                // If the vertical scroll position, plus the optional margin, would
                // put the target element at the specified limit, set the target
                // element to absolute.
                if (limit > 0 && y >= limit - getMarginTop()) {
                    if (!isAbsolute() || !wasReset) {
                        postPosition();
                        target.trigger('preAbsolute.ScrollToFixed');
                        setAbsolute();
                        target.trigger('unfixed.ScrollToFixed');
                    }
                // If the vertical scroll position, plus the optional margin, would
                // put the target element above the top of the page, set the target
                // element to fixed.
                } else if (y >= offsetTop - getMarginTop()) {
                    if (!isFixed() || !wasReset) {
                        postPosition();
                        target.trigger('preFixed.ScrollToFixed');

                        // Set the target element to fixed.
                        setFixed();

                        // Reset the last offset left because we just went fixed.
                        lastOffsetLeft = -1;

                        target.trigger('fixed.ScrollToFixed');
                    }
                    // If the page has been scrolled horizontally as well, move the
                    // target element accordingly.
                    setLeft(x);
                } else {
                    // Set the target element to unfixed, placing it where it was
                    // before.
                    if (!isUnfixed() || !wasReset) {
                        postPosition();
                        target.trigger('preUnfixed.ScrollToFixed');
                        setUnfixed();
                        target.trigger('unfixed.ScrollToFixed');
                    }
                }
            } else {
                if (limit > 0) {
                    if (y + $(window).height() - target.outerHeight(true) >= limit - (getMarginTop() || -getBottom())) {
                        if (isFixed()) {
                            postPosition();
                            target.trigger('preUnfixed.ScrollToFixed');

                            if (originalPosition === 'absolute') {
                                setAbsolute();
                            } else {
                                setUnfixed();
                            }

                            target.trigger('unfixed.ScrollToFixed');
                        }
                    } else {
                        if (!isFixed()) {
                            postPosition();
                            target.trigger('preFixed.ScrollToFixed');
                            setFixed();
                        }
                        setLeft(x);
                        target.trigger('fixed.ScrollToFixed');
                    }
                } else {
                    setLeft(x);
                }
            }
        }

        function getBottom() {
            if (!base.options.bottom) return 0;
            return base.options.bottom;
        }

        function postPosition() {
            var position = target.css('position');

            if (position == 'absolute') {
                target.trigger('postAbsolute.ScrollToFixed');
            } else if (position == 'fixed') {
                target.trigger('postFixed.ScrollToFixed');
            } else {
                target.trigger('postUnfixed.ScrollToFixed');
            }
        }

        var windowResize = function(event) {
            // Check if the element is visible before updating it's position, which
            // improves behavior with responsive designs where this element is hidden.
            if(target.is(':visible')) {
                isReset = false;
                checkScroll();
			}
        }

        var windowScroll = function(event) {
            checkScroll();
        }

        var isPositionFixedSupported = function() {
            var container = document.body;

            if (document.createElement && container && container.appendChild && container.removeChild) {
                var el = document.createElement('div');

                if (!el.getBoundingClientRect) return null;

                el.innerHTML = 'x';
                el.style.cssText = 'position:fixed;top:100px;';
                container.appendChild(el);

                var originalHeight = container.style.height,
                originalScrollTop = container.scrollTop;

                container.style.height = '3000px';
                container.scrollTop = 500;

                var elementTop = el.getBoundingClientRect().top;
                container.style.height = originalHeight;

                var isSupported = (elementTop === 100);
                container.removeChild(el);
                container.scrollTop = originalScrollTop;

                return isSupported;
            }

            return null;
        }

        var preventDefault = function(e) {
            e = e || window.event;
            if (e.preventDefault) {
                e.preventDefault();
            }
            e.returnValue = false;
        }

        // Initializes this plugin. Captures the options passed in, turns this
        // off for devices that do not support fixed position, adds the spacer,
        // and binds to the window scroll and resize events.
        base.init = function() {
            // Capture the options for this plugin.
            base.options = $
                    .extend({}, $.ScrollToFixed.defaultOptions, options);

            // Turn off this functionality for devices that do not support it.
            if (!(base.options && base.options.dontCheckForPositionFixedSupport)) {
                var fixedSupported = isPositionFixedSupported();
                if (!fixedSupported) return;
            }

            // Put the target element on top of everything that could be below
            // it. This reduces flicker when the target element is transitioning
            // to fixed.
            base.$el.css('z-index', base.options.zIndex);

            // Create a spacer element to fill the void left by the target
            // element when it goes fixed.
            spacer = $('<div />');

            position = target.css('position');
            originalPosition = target.css('position');

            // Place the spacer right after the target element.
            if (isUnfixed()) base.$el.after(spacer);

            // Reset the target element offsets when the window is resized, then
            // check to see if we need to fix or unfix the target element.
            $(window).bind('resize.ScrollToFixed', windowResize);

            // When the window scrolls, check to see if we need to fix or unfix
            // the target element.
            $(window).bind('scroll.ScrollToFixed', windowScroll);

            if (base.options.preFixed) {
                target.bind('preFixed.ScrollToFixed', base.options.preFixed);
            }
            if (base.options.postFixed) {
                target.bind('postFixed.ScrollToFixed', base.options.postFixed);
            }
            if (base.options.preUnfixed) {
                target.bind('preUnfixed.ScrollToFixed', base.options.preUnfixed);
            }
            if (base.options.postUnfixed) {
                target.bind('postUnfixed.ScrollToFixed', base.options.postUnfixed);
            }
            if (base.options.preAbsolute) {
                target.bind('preAbsolute.ScrollToFixed', base.options.preAbsolute);
            }
            if (base.options.postAbsolute) {
                target.bind('postAbsolute.ScrollToFixed', base.options.postAbsolute);
            }
            if (base.options.fixed) {
                target.bind('fixed.ScrollToFixed', base.options.fixed);
            }
            if (base.options.unfixed) {
                target.bind('unfixed.ScrollToFixed', base.options.unfixed);
            }

            if (base.options.spacerClass) {
                spacer.addClass(base.options.spacerClass);
            }

            target.bind('resize.ScrollToFixed', function() {
                spacer.height(target.height());
            });

            target.bind('scroll.ScrollToFixed', function() {
                target.trigger('preUnfixed.ScrollToFixed');
                setUnfixed();
                target.trigger('unfixed.ScrollToFixed');
                checkScroll();
            });

            target.bind('remove.ScrollToFixed', function(ev) {
                preventDefault(ev);

                target.trigger('preUnfixed.ScrollToFixed');
                setUnfixed();
                target.trigger('unfixed.ScrollToFixed');

                $(window).unbind('resize.ScrollToFixed', windowResize);
                $(window).unbind('scroll.ScrollToFixed', windowScroll);

                target.unbind('.ScrollToFixed');
                base.$el.removeData('ScrollToFixed');
            });

            // Reset everything.
            windowResize();
        };

        // Initialize the plugin.
        base.init();
    };

    // Sets the option defaults.
    $.ScrollToFixed.defaultOptions = {
        marginTop : 0,
        limit : 0,
        bottom : -1,
        zIndex : 1000
    };

    // Returns enhanced elements that will fix to the top of the page when the
    // page is scrolled.
    $.fn.scrollToFixed = function(options) {
        return this.each(function() {
            (new $.ScrollToFixed(this, options));
        });
    };
})(jQuery);
<|endoftext|>


<commit_before>/*
 * jQuery Social Buttons Plugin v0.1
 * http://
 *
 * Copyright (c) 2010 Bearded Studio LLC
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 */
(function($, undefined){
  var services = {
    facebook: {
      display_name: 'Facebook',
      data_url: 'http://api.facebook.com/restserver.php?method=links.getStats&format=json-strings&urls=',
      count_key: 'total_count'
    },
    twitter: {
      display_name: 'Twitter',
      data_url: 'http://urls.api.twitter.com/1/urls/count.json?url=',
      count_key: 'count'
    }
  };

  var socialStats = {};
  var serviceKeys = [];
  $.each(services, function(key) {
    socialStats[key] = {};
    serviceKeys[serviceKeys.length] = key;
  });

  function totalForUrl(url) {
    var total = 0;
    for (service_name in socialStats) {
      if (socialStats[service_name][url]) {
        total += parseInt(socialStats[service_name][url].count);
      }
    }
    return total;
  }

  function friendlyNumberFormat(number) {
    if (number > 1000) {
      number = Math.round(number/1000) + 'K';
    }
    return number;
  }

  $.fn.socialButtons = function(options){
    options = $.extend({
      url: window.location.href,
      // url: 'http://www.kickstarter.com/projects/bearded/new-digital-fonts-from-rare-letterpress-wood-type',
      services: serviceKeys,
      forceRequest: false,
      friendlyCounts: true,
      friendlyTotal: true
    }, options);

    // loop over the selected elements
    this.each(function(){

      var $buttons = $(this).addClass('social-buttons');

      var $label = $('
Share
')
        .appendTo($buttons);

      var $total_wrap = $('
')
        .append('Total')
        .append('')
        .appendTo($buttons);

      var $total = $total_wrap.find('.value');

      // set the statistics
      $.each(options.services, function(key, service_name){
        if (services[service_name]) {
          var service = services[service_name];

          var $count_wrap = $('
')
            .addClass(service_name)
            .append(''+service.display_name+'')
            .append('')
            .insertBefore($total_wrap);

          var $count = $count_wrap.find('.value');

          // don't make another request if we already have the stats
          if (socialStats[service_name][options.url] == undefined || options.forceRequest) {
            // get from the jsonp url
            $.ajax(service.data_url+escape(options.url), {
              dataType: 'jsonp',
              success: function(data){
                // facebook returns an array, but we want a single object
                if (data.length) {
                  data = data[0];
                }
                var count = data[service.count_key];

                // facebook normalizes file:// urls to 'www.' and you get a crazy high count!
                if (data['normalized_url'] == 'www.') {
                  count = 0;
                }

                socialStats[service_name][options.url] = {
                  count: count,
                  raw: data
                };

                // set count for display
                $count_wrap.attr('title', count);
                if (options.friendlyCounts) {
                  $count.html(friendlyNumberFormat(count));
                } else {
                  $count.html(count);
                }

                // set total for display
                var total = totalForUrl(options.url);
                $total_wrap.attr('title', total);
                if (options.friendlyTotal) {
                  $total.html(friendlyNumberFormat(total));
                } else {
                  $total.html(total);
                }
              }
            });
          }

        }
      });

    })
  }
})(jQuery);
<commit_msg>added like links (facebook's is pretty rudimentary)<commit_after>/*
 * jQuery Social Buttons Plugin v0.1
 * http://
 *
 * Copyright (c) 2010 Bearded Studio LLC
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 */
(function($, undefined){
  var services = {
    facebook: {
      display_name: 'Facebook',
      data_url: 'http://api.facebook.com/restserver.php?method=links.getStats&format=json-strings&urls={{url}}',
      like_url: 'http://www.facebook.com/plugins/like.php?origin={{url}}&relation=parent.parent&transport=postmessage&font=lucida%20grande&href={{url}}&layout=standard&node_type=link&sdk=joey&show_faces=false',
      count_key: 'total_count'
    },
    twitter: {
      display_name: 'Twitter',
      data_url: 'http://urls.api.twitter.com/1/urls/count.json?url={{url}}',
      like_url: 'http://twitter.com/share?original_referer={{url}}&url={{url}}&via=',
      count_key: 'count'
    }
  };

  var socialStats = {};
  var serviceKeys = [];
  $.each(services, function(key) {
    socialStats[key] = {};
    serviceKeys[serviceKeys.length] = key;
  });

  function totalForUrl(url) {
    var total = 0;
    for (service_name in socialStats) {
      if (socialStats[service_name][url]) {
        total += parseInt(socialStats[service_name][url].count);
      }
    }
    return total;
  }

  function friendlyNumberFormat(number) {
    if (number > 1000) {
      number = Math.round(number/1000) + 'K';
    }
    return number;
  }

  $.fn.socialButtons = function(options){
    options = $.extend({
      url: window.location.href,
      services: serviceKeys,
      forceRequest: false,
      friendlyCounts: true,
      friendlyTotal: true
    }, options);

    // loop over the selected elements
    this.each(function(){

      var $buttons = $(this).addClass('social-buttons');

      var $label = $('Share')
        .appendTo($buttons);

      var $total_wrap = $('')
        .append('Total')
        .append('')
        .appendTo($buttons);

      var $total = $total_wrap.find('.value');

      // set the statistics
      $.each(options.services, function(key, service_name){
        if (services[service_name]) {
          var service = services[service_name];

          var $count_wrap = $('')
            .addClass(service_name)
            .attr('href', service.like_url.replace(/{{url}}/g, options.url))
            .append(''+service.display_name+'')
            .append('')
            .insertBefore($total_wrap);

          var $count = $count_wrap.find('.value');

          // don't make another request if we already have the stats
          if (socialStats[service_name][options.url] == undefined || options.forceRequest) {
            // get from the jsonp url
            $.ajax(service.data_url.replace(/{{url}}/g, options.url), {
              dataType: 'jsonp',
              success: function(data){
                // facebook returns an array, but we want a single object
                if (data.length) {
                  data = data[0];
                }
                var count = data[service.count_key];

                // facebook normalizes file:// urls to 'www.' and you get a crazy high count!
                if (data['normalized_url'] == 'www.') {
                  count = 0;
                }

                socialStats[service_name][options.url] = {
                  count: count,
                  raw: data
                };

                console.log(data);

                // set count for display
                $count_wrap.attr('title', count);
                if (options.friendlyCounts) {
                  $count.html(friendlyNumberFormat(count));
                } else {
                  $count.html(count);
                }

                // set total for display
                var total = totalForUrl(options.url);
                $total_wrap.attr('title', total);
                if (options.friendlyTotal) {
                  $total.html(friendlyNumberFormat(total));
                } else {
                  $total.html(total);
                }
              }
            });
          }

        }
      });

    })
  }
})(jQuery);
<|endoftext|>


<commit_before>/**
 *  Plugin para carregar comboboxes via ajax.
 *  @author: Igor Brites (@igorbrites)
 *  @license: MIT Licence
 */

;(function ($, window, undefined) {
	$.isChosen = function(obj) {
		return document.getElementById(obj.id.replace('-', '_') + '_chosen') !== null;
	};

	var
        defaults = {
            url: '',
            args: {},
            selectedValue: false,
            comboLabel: 'Selecione',
            callback: false,
            cache: null
        },

        setFirstOption = function($obj, message) {
	        var isChosen = $.isChosen($obj[0]);
            $obj[0].options.length = 0;

            if (isChosen) {
	            $obj[0].options[0] = new Option('', '');
	            $obj.attr('data-placeholder', message).trigger("chosen:updated");
            } else {
                $obj[0].options[0] = new Option(message, '');
            }
        },

        doPopulate = function(json, parameters, $obj) {
            var opt = $obj[0].options,
                isChosen = $.isChosen($obj[0]),
                node,
                value,
                label,
                option,
                k;

            if (typeof (json) !== 'object') {
                setFirstOption($obj, 'Erro na resposta');
            } else if (json.error === true) {
                setFirstOption($obj, json.errorMessage);
            } else {
                setFirstOption($obj, parameters.comboLabel);

                for (k in json.options) {
                    node = json.options[k];
                    value = node.value;
                    label = node.label;
                    option = new Option(label, value);

                    for (var i in node) {
                        if(i !== 'value' && i !== 'label') {
                            option.setAttribute('data-' + i, node[i]);
                        }
                    }

                    opt[opt.length] = option;
                }

                if (parameters.selectedValue) {
                    $obj[0].value = parameters.selectedValue;
                } else if ($obj.data('value')) {
                    $obj[0].value = $obj.data('value');
                }

                isChosen && $obj.trigger("chosen:updated");

                typeof parameters.callback === 'function' && parameters.callback();
            }
        };

	$.populateCombo = function (obj, params) {
		params = $.extend({}, defaults, params);

        if (params.cache !== null) {
            if (params.cache.object.has(params.cache.key)) {
                doPopulate(params.cache.object.get(params.cache.key), params, $(obj));
                return true;
            }
        }

		var comboOptions = obj.options,
            $obj = $(obj),
			isChosen = $.isChosen($obj[0]);

		$.ajax({
			type: 'post',
			url: params.url,
			dataType: 'json',
			data: params.args,

			beforeSend: function () {
				comboOptions.length = 0;

				if (isChosen) {
					$obj.attr('data-placeholder', 'Carregando...').trigger("chosen:updated");
				} else {
					comboOptions[0] = new Option('Carregando...', '');
				}
			},

			/**
			 * @param {Object} json
			 * @example {
			 *      error: false,
			 *      errorMessage: '',
			 *      options: {
			 *          {label: 'Option 01', value: 1},
			 *          {label: 'Option 02', value: 2},
			 *          {label: 'Option 03', value: 3},
			 *          {label: 'Option 04', value: 4},
			 *          {label: 'Option 05', value: 5},
			 *          {label: 'Option 06', value: 6}
			 *      }
			 *  }
			 */
			success: function (json) {
                params.cache.object.set(params.cache.key, json);
                doPopulate(json, params, $obj);
			},

			error: function (xhr, textStatus, errorThrown) {
				comboOptions.length = 0;

				if (isChosen) {
					$obj.attr('data-placeholder', 'Erro no servidor').trigger("chosen:updated");
				} else {
					comboOptions[0] = new Option('Erro no servidor', '');
				}
			}
		});

		return $obj;
	};

	$.fn.loadComboAjax = function (params) {
		return this.each(function () {
			$.populateCombo(this, params);
		});
	}
})(jQuery, window);
<commit_msg>Correção do cache<commit_after>/**
 *  Plugin para carregar comboboxes via ajax.
 *  @author: Igor Brites (@igorbrites)
 *  @license: MIT Licence
 */

;(function ($, window, undefined) {
	$.isChosen = function(obj) {
		return document.getElementById(obj.id.replace('-', '_') + '_chosen') !== null;
	};

	var
        defaults = {
            url: '',
            args: {},
            selectedValue: false,
            comboLabel: 'Selecione',
            callback: false,
            cache: null
        },

        setFirstOption = function($obj, message) {
	        var isChosen = $.isChosen($obj[0]);
            $obj[0].options.length = 0;

            if (isChosen) {
	            $obj[0].options[0] = new Option('', '');
	            $obj.attr('data-placeholder', message).trigger("chosen:updated");
            } else {
                $obj[0].options[0] = new Option(message, '');
            }
        },

        doPopulate = function(json, parameters, $obj) {
            var opt = $obj[0].options,
                isChosen = $.isChosen($obj[0]),
                node,
                value,
                label,
                option,
                k;

            if (typeof (json) !== 'object') {
                setFirstOption($obj, 'Erro na resposta');
            } else if (json.error === true) {
                setFirstOption($obj, json.errorMessage);
            } else {
                setFirstOption($obj, parameters.comboLabel);

                for (k in json.options) {
                    node = json.options[k];
                    value = node.value;
                    label = node.label;
                    option = new Option(label, value);

                    for (var i in node) {
                        if(i !== 'value' && i !== 'label') {
                            option.setAttribute('data-' + i, node[i]);
                        }
                    }

                    opt[opt.length] = option;
                }

                if (parameters.selectedValue) {
                    $obj[0].value = parameters.selectedValue;
                } else if ($obj.data('value')) {
                    $obj[0].value = $obj.data('value');
                }

                isChosen && $obj.trigger("chosen:updated");

                typeof parameters.callback === 'function' && parameters.callback();
            }
        };

	$.populateCombo = function (obj, params) {
		params = $.extend({}, defaults, params);

        if (params.cache !== null) {
            if (params.cache.object.has(params.cache.key)) {
                doPopulate(params.cache.object.get(params.cache.key), params, $(obj));
                return true;
            }
        }

		var comboOptions = obj.options,
            $obj = $(obj),
			isChosen = $.isChosen($obj[0]);

		$.ajax({
			type: 'post',
			url: params.url,
			dataType: 'json',
			data: params.args,

			beforeSend: function () {
				comboOptions.length = 0;

				if (isChosen) {
					$obj.attr('data-placeholder', 'Carregando...').trigger("chosen:updated");
				} else {
					comboOptions[0] = new Option('Carregando...', '');
				}
			},

			/**
			 * @param {Object} json
			 * @example {
			 *      error: false,
			 *      errorMessage: '',
			 *      options: {
			 *          {label: 'Option 01', value: 1},
			 *          {label: 'Option 02', value: 2},
			 *          {label: 'Option 03', value: 3},
			 *          {label: 'Option 04', value: 4},
			 *          {label: 'Option 05', value: 5},
			 *          {label: 'Option 06', value: 6}
			 *      }
			 *  }
			 */
			success: function (json) {
                params.cache && params.cache.object.set(params.cache.key, json);
                doPopulate(json, params, $obj);
			},

			error: function (xhr, textStatus, errorThrown) {
				comboOptions.length = 0;

				if (isChosen) {
					$obj.attr('data-placeholder', 'Erro no servidor').trigger("chosen:updated");
				} else {
					comboOptions[0] = new Option('Erro no servidor', '');
				}
			}
		});

		return $obj;
	};

	$.fn.loadComboAjax = function (params) {
		return this.each(function () {
			$.populateCombo(this, params);
		});
	}
})(jQuery, window);
<|endoftext|>


<commit_before>import version from '../version'
import appPkg from '../../../package'

describe('VERSION route', () => {
  describe('GET', () => {
    it('returns 204', () => {
      const req = {}
      const res = {}
      const next = jest.fn()
      res.send = jest.fn()

      version.get(req, res, next)
      expect(res.send.mock.calls.length).toBe(1)
      expect(res.send).toBeCalledWith({appVersion: '1.0.0'})
      expect(next.mock.calls.length).toBe(1)
    })
  })
})
<commit_msg>fix: removed unused package<commit_after>import version from '../version'

describe('VERSION route', () => {
  describe('GET', () => {
    it('returns 204', () => {
      const req = {}
      const res = {}
      const next = jest.fn()
      res.send = jest.fn()

      version.get(req, res, next)
      expect(res.send.mock.calls.length).toBe(1)
      expect(res.send).toBeCalledWith({appVersion: '1.0.0'})
      expect(next.mock.calls.length).toBe(1)
    })
  })
})
<|endoftext|>