<commit_before>/* Defines the items and connects the logic of the navigation bar.
 *
 * Requires:
 *   js/error.js
 */

// Defines a normal button
var Button = function(id) {
    var idSel = $(id);
    var _kDefaultColor = '#cccccc';
    var _kDisabledColor = '#404040';
    var _buttonIsEnabled = true;

    this.id = id;
    this.clickFn = null;

    var _this = this;
    var _paintColor = function() {
        idSel.css('fill', _kDefaultColor);
    };

    this.disableButton = function() {
        _buttonIsEnabled = false;
        idSel
            .css('opacity', '0.3')
            .css('fill', _kDisabledColor);
    };

    this.enableButton = function() {
        _buttonIsEnabled = true;
        idSel
            .css('opacity', '1')
            .css('fill', _kDefaultColor);
    };

    /* Parameters:
     *   clickFn : function()
     *     Callback function that is called upon clicking the button
     */
    this.onClick = function(clickFn) {
        this.clickFn = clickFn;
    };

    idSel.hover(function() {
        if (_buttonIsEnabled) {
            idSel.css('opacity', '0.5');
        }
    }, function() {
        if (_buttonIsEnabled) {
            idSel.css('opacity', '1');
        }
    });

    idSel.click(function() {
        if (_buttonIsEnabled) {
            if (_this.clickFn !== null) {
                _this.clickFn();
            } else {
                ErrorMetric.log(id + '.click => Button.clickFn not defined');
            }
        }

        idSel.blur();
    });

    _paintColor();

    return this;
};

// Defines a button that acts like a checkbox
var StatefulButton = function(id, selected) {
    var idSel = $(id);
    var _kSelectedColor = '#009966';
    var _kUnselectedColor = '#cc0033';
    var _buttonIsEnabled = true;

    this.id = id;
    this.selectedFn = null;
    this.unselectedFn = null;

    this.selected = selected;
    if (selected === undefined) {
        this.selected = false;
    }

    var _this = this;
    var _paintColor = function() {
        if (_this.selected) {
            idSel.css('fill', _kSelectedColor);
        } else {
            idSel.css('fill', _kUnselectedColor);
        }
    };

    var _toggleCallbacks = {};
    var _currentToggleId = 0;

    var _invokeToggleListenerCallbacks = function(newState) {
        for (var i in _toggleCallbacks) {
            _toggleCallbacks[i](newState);
        }
    };

    /*
     * Parameters:
     *   handler : function (newState)
     *     Callback function that gets called on a toggle with the new state as the argument
     *
     * Return:
     *   number
     *     The ID of the just registered event listener callback (to be used with removeToggleEventListener)
     */
    this.addToggleEventListener = function(handler) {
        _toggleCallbacks[_currentToggleId] = handler;
        return _currentToggleId++;
    };

    /*
     * Parameters:
     *   id : number
     *     ID of the toggle event listener to delete
     */
    this.removeToggleEventListener = function(id) {
        if (_toggleCallbacks[id] !== undefined) {
            delete _toggleCallbacks[id];
        } else {
            ErrorMetric.log('StatefulButton.removeToggleEventListener => bad id "' + id + '"');
        }
    };

    this.disableButton = function() {
        _buttonIsEnabled = false;
        idSel
            .css('opacity', '0.3')
            .attr('title', 'Button is disabled');
    };

    this.isEnabled = function() {
        return _buttonIsEnabled;
    };

    this.enableButton = function() {
        _buttonIsEnabled = true;
        idSel
            .css('opacity', '1')
            .removeAttr('title');
    };

    this.clickButton = function() {
        idSel.click();
    };

    /* Toggles the state of the button and repaints the button's icon color
     */
    this.toggle = function() {
        if (_buttonIsEnabled) {
            if (this.selected) {
                this.selected = false;
            } else {
                this.selected = true;
            }

            _invokeToggleListenerCallbacks(this.selected);
            _paintColor();
        }
    };

    /* Parameters:
     *   selectedFn  : function()
     *     Callback that is invoked when the button is clicked and the new state is SELECTED.
     *
     *   unselectedFn : function()
     *     Callback that is invoked when the button is clicked and the new state is UNSELECTED.
     */
    this.handle = function(selectedFn, unselectedFn) {
        this.selectedFn = selectedFn;
        this.unselectedFn = unselectedFn;
    };

    /* Returns the current state of the button
     */
    this.isSelected = function() {
        return this.selected;
    };

    idSel.hover(function() {
        if (_buttonIsEnabled) {
            idSel.css('opacity', '0.5');
        }
    }, function() {
        if (_buttonIsEnabled) {
            idSel.css('opacity', '1');
        }
    });

    idSel.click(function() {
        _this.toggle();

        if (_buttonIsEnabled) {
            if (_this.isSelected()) {
                if (_this.selectedFn !== null) {
                    _this.selectedFn();
                } else {
                    // FIXME: is this spamming my telemetry log?
                    ErrorMetric.log(id + '.click => StatefulButton.selectedFn not defined');
                }
            } else {
                if (_this.unselectedFn !== null) {
                    _this.unselectedFn();
                } else {
                    // FIXME: is this spamming my telemetry log?
                    ErrorMetric.log(id + '.click => StatefulButton.unselectedFn not defined');
                }
            }
        }

        idSel.blur();
    });

    _paintColor();

    return this;
};

var NavBar = {
    cameraBtn: null,
    micBtn: null,
    dashBtn: null,
    attrBtn: null,

    // Initializes the navBar buttons
    initialize: function() {
        this.cameraBtn = new StatefulButton('#cameraBtn', true);
        this.micBtn = new StatefulButton('#micBtn', true);
        this.dashBtn = new StatefulButton('#dashBtn');
        this.attrBtn = new Button('#attrBtn');
    },

    // Fades in the navBar
    show: function() {
        $('.navBar').fadeIn();
    }
};
<commit_msg>Lint public/js/navbar.js<commit_after>/**
 * @file Defines the items and connects the logic of the navigation bar.
 *
 * @requires module:js/error
 */

'use strict';

/**
 * Defines a normal button.
 *
 * @param {String} id - CSS ID selector.
 * @class
 */
var Button = function(id) {
    var idSel = $(id);
    var _kDefaultColor = '#cccccc';
    var _kDisabledColor = '#404040';
    var _buttonIsEnabled = true;

    this.id = id;
    this.clickFn = null;

    var _this = this;

    /**
     * Fills the element with the default color.
     *
     * @returns {undefined} undefined
     * @private
     */
    var _paintColor = function() {
        idSel.css('fill', _kDefaultColor);
    };

    /**
     * Disables the button.
     *
     * @returns {undefined} undefined
     * @public
     */
    this.disableButton = function() {
        _buttonIsEnabled = false;
        idSel
            .css('opacity', '0.3')
            .css('fill', _kDisabledColor);
    };

    /**
     * Enables the button.
     *
     * @returns {undefined} undefined
     * @public
     */
    this.enableButton = function() {
        _buttonIsEnabled = true;
        idSel
            .css('opacity', '1')
            .css('fill', _kDefaultColor);
    };

    /**
     * Click handler.
     *
     * @param {Function} clickFn - Callback function
     * that is called upon clicking the button.
     * @returns {undefined} undefined
     * @public
     */
    this.onClick = function(clickFn) {
        this.clickFn = clickFn;
    };

    idSel.hover(function() {
        if (_buttonIsEnabled) {
            idSel.css('opacity', '0.5');
        }
    }, function() {
        if (_buttonIsEnabled) {
            idSel.css('opacity', '1');
        }
    });

    idSel.click(function() {
        if (_buttonIsEnabled) {
            if (_this.clickFn !== null) {
                _this.clickFn();
            } else {
                ErrorMetric.log(id + '.click => Button.clickFn not defined');
            }
        }

        idSel.blur();
    });

    _paintColor();

    return this;
};

/**
 * Defines a button that acts like a checkbox.
 *
 * @param {String} id - CSS ID selector.
 * @param {Boolean} selected - True if selected,
 * false otherwise.
 * @class
 */
var StatefulButton = function(id, selected) {
    var idSel = $(id);
    var _kSelectedColor = '#009966';
    var _kUnselectedColor = '#cc0033';
    var _buttonIsEnabled = true;

    this.id = id;
    this.selectedFn = null;
    this.unselectedFn = null;

    this.selected = selected;
    if (selected === undefined) {
        this.selected = false;
    }

    var _this = this;

    /**
     * Fills the element with the appropriate color.
     *
     * @returns {undefined} undefined
     * @private
     */
    var _paintColor = function() {
        if (_this.selected) {
            idSel.css('fill', _kSelectedColor);
        } else {
            idSel.css('fill', _kUnselectedColor);
        }
    };

    var _toggleCallbacks = {};
    var _currentToggleId = 0;

    /**
     * Invokes all toggle listener callbacks.
     *
     * @param {Boolean} newState - The new state
     * to provide to the callbacks.
     * @returns {undefined} undefined
     * @private
     */
    var _invokeToggleListenerCallbacks = function(newState) {
        for (var cb in _toggleCallbacks) {
            if (_toggleCallbacks.hasOwnProperty(cb)) {
                _toggleCallbacks[cb](newState);
            }
        }
    };

    /**
     * Adds a toggle event listener.
     *
     * @param {Function} handler - Callback function that gets
     * called on a toggle with the new state as the argument.
     * @returns {Number} The ID of the just registered event
     * listener callback (to be used with removeToggleEventListener).
     * @public
     */
    this.addToggleEventListener = function(handler) {
        _toggleCallbacks[_currentToggleId] = handler;
        return _currentToggleId++;
    };

    /**
     * Removes a toggle event listener.
     *
     * @param {Number} id - ID of the toggle
     * event listener to delete.
     * @returns {undefined} undefined
     * @public
     */
    this.removeToggleEventListener = function(id) {
        if (_toggleCallbacks[id] !== undefined) {
            delete _toggleCallbacks[id];
        } else {
            ErrorMetric.log('StatefulButton.removeToggleEventListener => bad id "' + id + '"');
        }
    };

    /**
     * Disables the button.
     *
     * @returns {undefined} undefined
     * @public
     */
    this.disableButton = function() {
        _buttonIsEnabled = false;
        idSel
            .css('opacity', '0.3')
            .attr('title', 'Button is disabled');
    };

    /**
     * Checks whether the button is enabled.
     *
     * @returns {Boolean} True if enabled,
     * false otherwise.
     * @public
     */
    this.isEnabled = function() {
        return _buttonIsEnabled;
    };

    /**
     * Enables the button.
     *
     * @returns {undefined} undefined
     * @public
     */
    this.enableButton = function() {
        _buttonIsEnabled = true;
        idSel
            .css('opacity', '1')
            .removeAttr('title');
    };

    /**
     * Clicks the button.
     *
     * @returns {undefined} undefined
     * @public
     */
    this.clickButton = function() {
        idSel.click();
    };

    /**
     * Toggles the state of the button and
     * repaints the button's icon color.
     *
     * @returns {undefined} undefined
     * @public
     */
    this.toggle = function() {
        if (_buttonIsEnabled) {
            if (this.selected) {
                this.selected = false;
            } else {
                this.selected = true;
            }

            _invokeToggleListenerCallbacks(this.selected);
            _paintColor();
        }
    };

    /**
     * Handler that registers functions for button
     * selection and deselection.
     *
     * @param {Function} selectedFn - Callback that
     * is invoked when the button is clicked and the
     * new state is SELECTED.
     * @param {Function} unselectedFn - Callback that
     * is invoked when the button is clicked and the
     * new state is UNSELECTED.
     * @returns {undefined} undefined
     * @public
     */
    this.handle = function(selectedFn, unselectedFn) {
        this.selectedFn = selectedFn;
        this.unselectedFn = unselectedFn;
    };

    /**
     * Returns the current state of the button.
     *
     * @returns {Boolean} True if selected,
     * false otherwise.
     * @public
     */
    this.isSelected = function() {
        return this.selected;
    };

    idSel.hover(function() {
        if (_buttonIsEnabled) {
            idSel.css('opacity', '0.5');
        }
    }, function() {
        if (_buttonIsEnabled) {
            idSel.css('opacity', '1');
        }
    });

    idSel.click(function() {
        _this.toggle();

        if (_buttonIsEnabled) {
            if (_this.isSelected()) {
                if (_this.selectedFn !== null) {
                    _this.selectedFn();
                } else {
                    // FIXME: is this spamming my telemetry log?
                    ErrorMetric.log(id + '.click => StatefulButton.selectedFn not defined');
                }
            } else {
                if (_this.unselectedFn !== null) {
                    _this.unselectedFn();
                } else {
                    // FIXME: is this spamming my telemetry log?
                    ErrorMetric.log(id + '.click => StatefulButton.unselectedFn not defined');
                }
            }
        }

        idSel.blur();
    });

    _paintColor();

    return this;
};

var NavBar = {
    cameraBtn: null,
    micBtn: null,
    dashBtn: null,
    attrBtn: null,

    /**
     * Initializes the navBar buttons.
     *
     * @returns {undefined} undefined
     * @public
     */
    initialize: function() {
        this.cameraBtn = new StatefulButton('#cameraBtn', true);
        this.micBtn = new StatefulButton('#micBtn', true);
        this.dashBtn = new StatefulButton('#dashBtn');
        this.attrBtn = new Button('#attrBtn');
    },

    /**
     * Fades in the navBar.
     *
     * @returns {undefined} undefined
     * @public
     */
    show: function() {
        $('.navBar').fadeIn();
    }
};
<|endoftext|>


<commit_before>$(document).ready(function() {
  var parser;

  var buildAndParseTimer = null;
  var parseTimer         = null;

  var oldGrammar   = null;
  var oldParserVar = null;
  var oldStartRule = null;
  var oldInput     = null;

  function build() {
    oldGrammar   = $("#grammar").val();
    oldParserVar = $("#parser-var").val();
    oldStartRule = $("#start-rule").val();

    try {
      var timeBefore = Date.now();
      parser = PEG.buildParser($("#grammar").val(), $("#start-rule").val());
      var timeAfter = Date.now();

      $("#build-message")
        .attr("class", "message info")
        .html("Parser built successfully.")
        .append(
          ""
          + (timeAfter - timeBefore)
          + " ms, "
          + ($("#grammar").val().length / (timeAfter - timeBefore)).toPrecision(2)
          + " kB/s"
          + ""
        );
      var parserUrl = "data:text/plain;charset=utf-8;base64,"
        + Base64.encode($("#parser-var").val() + " = " + parser.toSource() + ";\n");
      $("#parser-download").show().attr("href", parserUrl);
      $("#input").removeAttr("disabled");

      return true;
    } catch (e) {
      var message = e.line !== undefined && e.column !== undefined
        ? "Line " + e.line + ", column " + e.column + ": " + e.message
        : e.message;

      $("#build-message")
        .attr("class", "message error")
        .text(message);
      var parserUrl = "data:text/plain;charset=utf-8;base64,"
        + Base64.encode("Parser not available.");
      $("#parser-download").hide();
      $("#input").attr("disabled", "disabled");
      $("#parse-message")
        .attr("class", "message disabled")
        .text("Parser not available.");
      $("#output").addClass("not-available").text("(no output available)");
    }
  }

  function parse() {
    oldInput = $("#input").val();

    try {
      var timeBefore = Date.now();
      var output = parser.parse($("#input").val());
      var timeAfter = Date.now();

      $("#parse-message")
        .attr("class", "message info")
        .text("Input parsed successfully.")
        .append(
          ""
          + (timeAfter - timeBefore)
          + " ms, "
          + ($("#input").val().length / (timeAfter - timeBefore)).toPrecision(2)
          + " kB/s"
          + ""
        );
      $("#output").removeClass("not-available").html(jsDump.parse(output));

      return true;
    } catch (e) {
      var message = e.line !== undefined && e.column !== undefined
        ? "Line " + e.line + ", column " + e.column + ": " + e.message
        : e.message;

      $("#parse-message")
        .attr("class", "message error")
        .text(message)
      $("#output").addClass("not-available").text("(no output available)");

      return false;
    }
  }

  function buildAndParse() {
    build() && parse();
  }

  function scheduleBuildAndParse() {
    var nothingChanged = $("#grammar").val() === oldGrammar
      && $("#parser-var").val() === oldParserVar
      && $("#start-rule").val() === oldStartRule;
    if (nothingChanged) { return; }

    if (buildAndParseTimer !== null) {
      clearTimeout(buildAndParseTimer);
      buildAndParseTimer = null;
    }
    if (parseTimer !== null) {
      clearTimeout(parseTimer);
      parseTimer = null;
    }

    buildAndParseTimer = setTimeout(function() {
      buildAndParse();
      buildAndParseTimer = null;
    }, 500);
  }

  function scheduleParse() {
    if ($("#input").val() === oldInput) { return; }
    if (buildAndParseTimer !== null) { return; }

    if (parseTimer !== null) {
      clearTimeout(parseTimer);
      parseTimer = null;
    }

    parseTimer = setTimeout(function() {
      parse();
      parseTimer = null;
    }, 500);
  }

  jsDump.HTML = true;

  $("#grammar, #start-rule, #parser-var")
    .change(scheduleBuildAndParse)
    .mousedown(scheduleBuildAndParse)
    .mouseup(scheduleBuildAndParse)
    .click(scheduleBuildAndParse)
    .keydown(scheduleBuildAndParse)
    .keyup(scheduleBuildAndParse)
    .keypress(scheduleBuildAndParse);

  $("#input")
    .change(scheduleParse)
    .mousedown(scheduleParse)
    .mouseup(scheduleParse)
    .click(scheduleParse)
    .keydown(scheduleParse)
    .keyup(scheduleParse)
    .keypress(scheduleParse);

  $("#settings-link").toggle(function() {
    $(this).html("« Detailed settings");
    $("#settings").slideDown();
    return false;
  }, function() {
    $(this).html("Detailed settings »");
    $("#settings").slideUp();
    return false;
  });

  $("#grammar").focus();

  buildAndParse();
});
<commit_msg>Replace |Date.now()| with |(new Date).getTime()| (Opera needs this)<commit_after>$(document).ready(function() {
  var parser;

  var buildAndParseTimer = null;
  var parseTimer         = null;

  var oldGrammar   = null;
  var oldParserVar = null;
  var oldStartRule = null;
  var oldInput     = null;

  function build() {
    oldGrammar   = $("#grammar").val();
    oldParserVar = $("#parser-var").val();
    oldStartRule = $("#start-rule").val();

    try {
      var timeBefore = (new Date).getTime();
      parser = PEG.buildParser($("#grammar").val(), $("#start-rule").val());
      var timeAfter = (new Date).getTime();

      $("#build-message")
        .attr("class", "message info")
        .html("Parser built successfully.")
        .append(
          ""
          + (timeAfter - timeBefore)
          + " ms, "
          + ($("#grammar").val().length / (timeAfter - timeBefore)).toPrecision(2)
          + " kB/s"
          + ""
        );
      var parserUrl = "data:text/plain;charset=utf-8;base64,"
        + Base64.encode($("#parser-var").val() + " = " + parser.toSource() + ";\n");
      $("#parser-download").show().attr("href", parserUrl);
      $("#input").removeAttr("disabled");

      return true;
    } catch (e) {
      var message = e.line !== undefined && e.column !== undefined
        ? "Line " + e.line + ", column " + e.column + ": " + e.message
        : e.message;

      $("#build-message")
        .attr("class", "message error")
        .text(message);
      var parserUrl = "data:text/plain;charset=utf-8;base64,"
        + Base64.encode("Parser not available.");
      $("#parser-download").hide();
      $("#input").attr("disabled", "disabled");
      $("#parse-message")
        .attr("class", "message disabled")
        .text("Parser not available.");
      $("#output").addClass("not-available").text("(no output available)");
    }
  }

  function parse() {
    oldInput = $("#input").val();

    try {
      var timeBefore = (new Date).getTime();
      var output = parser.parse($("#input").val());
      var timeAfter = (new Date).getTime();

      $("#parse-message")
        .attr("class", "message info")
        .text("Input parsed successfully.")
        .append(
          ""
          + (timeAfter - timeBefore)
          + " ms, "
          + ($("#input").val().length / (timeAfter - timeBefore)).toPrecision(2)
          + " kB/s"
          + ""
        );
      $("#output").removeClass("not-available").html(jsDump.parse(output));

      return true;
    } catch (e) {
      var message = e.line !== undefined && e.column !== undefined
        ? "Line " + e.line + ", column " + e.column + ": " + e.message
        : e.message;

      $("#parse-message")
        .attr("class", "message error")
        .text(message)
      $("#output").addClass("not-available").text("(no output available)");

      return false;
    }
  }

  function buildAndParse() {
    build() && parse();
  }

  function scheduleBuildAndParse() {
    var nothingChanged = $("#grammar").val() === oldGrammar
      && $("#parser-var").val() === oldParserVar
      && $("#start-rule").val() === oldStartRule;
    if (nothingChanged) { return; }

    if (buildAndParseTimer !== null) {
      clearTimeout(buildAndParseTimer);
      buildAndParseTimer = null;
    }
    if (parseTimer !== null) {
      clearTimeout(parseTimer);
      parseTimer = null;
    }

    buildAndParseTimer = setTimeout(function() {
      buildAndParse();
      buildAndParseTimer = null;
    }, 500);
  }

  function scheduleParse() {
    if ($("#input").val() === oldInput) { return; }
    if (buildAndParseTimer !== null) { return; }

    if (parseTimer !== null) {
      clearTimeout(parseTimer);
      parseTimer = null;
    }

    parseTimer = setTimeout(function() {
      parse();
      parseTimer = null;
    }, 500);
  }

  jsDump.HTML = true;

  $("#grammar, #start-rule, #parser-var")
    .change(scheduleBuildAndParse)
    .mousedown(scheduleBuildAndParse)
    .mouseup(scheduleBuildAndParse)
    .click(scheduleBuildAndParse)
    .keydown(scheduleBuildAndParse)
    .keyup(scheduleBuildAndParse)
    .keypress(scheduleBuildAndParse);

  $("#input")
    .change(scheduleParse)
    .mousedown(scheduleParse)
    .mouseup(scheduleParse)
    .click(scheduleParse)
    .keydown(scheduleParse)
    .keyup(scheduleParse)
    .keypress(scheduleParse);

  $("#settings-link").toggle(function() {
    $(this).html("« Detailed settings");
    $("#settings").slideDown();
    return false;
  }, function() {
    $(this).html("Detailed settings »");
    $("#settings").slideUp();
    return false;
  });

  $("#grammar").focus();

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


<commit_before>var io = require('./socket.io');
var socket = io();

socket.on('action', function(data) {
    switch (data.action) {
        case 'play_pause':
            $('#play').click();
            break;
        case 'back':
            $('#previous').click();
            break;
        case 'stop':
            $('#stop').click();
            break;
        case 'next':
            $('#next').click();
            break;
        case 'random':
            $('#random').click();
            break;
        case 'repeat':
            $('#repeat').click();
            break;
    };
});

socket.on('volume', function(data) {
    switch (data.volume) {
        case 'up':
            $('#volume_up').click();
            break;
        case 'down':
            $('#volume_down').click();
            break;
        case 'mute':
            $('#volume_off').click();
            break;
    };
});
<commit_msg>updated<commit_after>var io = require('./socket.io');
var socket = io();

socket.on('action', function(data) {
    switch (data.action) {
        case 'play_pause':
            $('#play').click();
            break;
        case 'back':
            $('#previous').click();
            break;
        case 'stop':
            $('#stop').click();
            break;
        case 'next':
            $('#next').click();
            break;
        case 'random':
            $('#random').click();
            break;
        case 'repeat':
            $('#repeat').click();
            break;
        case 'single':
            $('#single').click();
            break;
    };
});

socket.on('volume', function(data) {
    switch (data.volume) {
        case 'up':
            $('#volume_up').click();
            break;
        case 'down':
            $('#volume_down').click();
            break;
        case 'mute':
            $('#volume_off').click();
            break;
    };
});
<|endoftext|>


<commit_before>// Sticky Plugin v1.0.0 for jQuery
// =============
// Author: Anthony Garand
// Improvements by German M. Bravo (Kronuz) and Ruud Kamphuis (ruudk)
// Improvements by Leonardo C. Daronco (daronco)
// Created: 2/14/2011
// Date: 2/12/2012
// Website: http://labs.anthonygarand.com/sticky
// Description: Makes an element on the page stick on the screen as you scroll
//       It will only set the 'top' and 'position' of your element, you
//       might need to adjust the width in some cases.

(function($) {
  var defaults = {
      topSpacing: 0,
      bottomSpacing: 0,
      className: 'is-sticky',
      wrapperClassName: 'sticky-wrapper',
      center: false,
      getWidthFrom: ''
    },
    $window = $(window),
    $document = $(document),
    sticked = [],
    windowHeight = $window.height(),
    scroller = function() {
      var scrollTop = $window.scrollTop(),
        documentHeight = $document.height(),
        dwh = documentHeight - windowHeight,
        extra = (scrollTop > dwh) ? dwh - scrollTop : 0;

      for (var i = 0; i < sticked.length; i++) {
        var s = sticked[i],
          elementTop = s.stickyWrapper.offset().top,
          etse = elementTop - s.topSpacing - extra;

        if (scrollTop <= etse) {
          if (s.currentTop !== null) {
            s.stickyElement
              .css('position', '')
              .css('top', '');
            s.stickyElement.parent().removeClass(s.className);
            s.currentTop = null;
          }
        }
        else {
          var newTop = documentHeight - s.stickyElement.outerHeight()
            - s.topSpacing - s.bottomSpacing - scrollTop - extra;
          if (newTop < 0) {
            newTop = newTop + s.topSpacing;
          } else {
            newTop = s.topSpacing;
          }
          if (s.currentTop != newTop) {
            s.stickyElement
              .css('position', 'fixed')
              .css('top', newTop);

            if (typeof s.getWidthFrom !== 'undefined') {
              s.stickyElement.css('width', $(s.getWidthFrom).width());
            }

            s.stickyElement.parent().addClass(s.className);
            s.currentTop = newTop;
          }
        }
      }
    },
    resizer = function() {
      windowHeight = $window.height();
    },
    methods = {
      init: function(options) {
        var o = $.extend(defaults, options);
        return this.each(function() {
          var stickyElement = $(this);

          stickyId = stickyElement.attr('id');
          wrapper = $('

')
            .attr('id', stickyId + '-sticky-wrapper')
            .addClass(o.wrapperClassName);
          stickyElement.wrapAll(wrapper);

          if (o.center) {
            stickyElement.parent().css({width:stickyElement.outerWidth(),marginLeft:"auto",marginRight:"auto"});
          }

          if (stickyElement.css("float") == "right") {
            stickyElement.css({"float":"none"}).parent().css({"float":"right"});
          }

          var stickyWrapper = stickyElement.parent();
          stickyWrapper.css('height', stickyElement.outerHeight());
          sticked.push({
            topSpacing: o.topSpacing,
            bottomSpacing: o.bottomSpacing,
            stickyElement: stickyElement,
            currentTop: null,
            stickyWrapper: stickyWrapper,
            className: o.className,
            getWidthFrom: o.getWidthFrom
          });
        });
      },
      update: scroller
    };

  // should be more efficient than using $window.scroll(scroller) and $window.resize(resizer):
  if (window.addEventListener) {
    window.addEventListener('scroll', scroller, false);
    window.addEventListener('resize', resizer, false);
  } else if (window.attachEvent) {
    window.attachEvent('onscroll', scroller);
    window.attachEvent('onresize', resizer);
  }

  $.fn.sticky = 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 );
    } else {
      $.error('Method ' + method + ' does not exist on jQuery.sticky');
    }
  };
  $(function() {
    setTimeout(scroller, 0);
  });
})(jQuery);
<commit_msg>declare variable<commit_after>// Sticky Plugin v1.0.0 for jQuery
// =============
// Author: Anthony Garand
// Improvements by German M. Bravo (Kronuz) and Ruud Kamphuis (ruudk)
// Improvements by Leonardo C. Daronco (daronco)
// Created: 2/14/2011
// Date: 2/12/2012
// Website: http://labs.anthonygarand.com/sticky
// Description: Makes an element on the page stick on the screen as you scroll
//       It will only set the 'top' and 'position' of your element, you
//       might need to adjust the width in some cases.

(function($) {
  var defaults = {
      topSpacing: 0,
      bottomSpacing: 0,
      className: 'is-sticky',
      wrapperClassName: 'sticky-wrapper',
      center: false,
      getWidthFrom: ''
    },
    $window = $(window),
    $document = $(document),
    sticked = [],
    windowHeight = $window.height(),
    scroller = function() {
      var scrollTop = $window.scrollTop(),
        documentHeight = $document.height(),
        dwh = documentHeight - windowHeight,
        extra = (scrollTop > dwh) ? dwh - scrollTop : 0;

      for (var i = 0; i < sticked.length; i++) {
        var s = sticked[i],
          elementTop = s.stickyWrapper.offset().top,
          etse = elementTop - s.topSpacing - extra;

        if (scrollTop <= etse) {
          if (s.currentTop !== null) {
            s.stickyElement
              .css('position', '')
              .css('top', '');
            s.stickyElement.parent().removeClass(s.className);
            s.currentTop = null;
          }
        }
        else {
          var newTop = documentHeight - s.stickyElement.outerHeight()
            - s.topSpacing - s.bottomSpacing - scrollTop - extra;
          if (newTop < 0) {
            newTop = newTop + s.topSpacing;
          } else {
            newTop = s.topSpacing;
          }
          if (s.currentTop != newTop) {
            s.stickyElement
              .css('position', 'fixed')
              .css('top', newTop);

            if (typeof s.getWidthFrom !== 'undefined') {
              s.stickyElement.css('width', $(s.getWidthFrom).width());
            }

            s.stickyElement.parent().addClass(s.className);
            s.currentTop = newTop;
          }
        }
      }
    },
    resizer = function() {
      windowHeight = $window.height();
    },
    methods = {
      init: function(options) {
        var o = $.extend(defaults, options);
        return this.each(function() {
          var stickyElement = $(this);

          var stickyId = stickyElement.attr('id');
          var wrapper = $('

')
            .attr('id', stickyId + '-sticky-wrapper')
            .addClass(o.wrapperClassName);
          stickyElement.wrapAll(wrapper);

          if (o.center) {
            stickyElement.parent().css({width:stickyElement.outerWidth(),marginLeft:"auto",marginRight:"auto"});
          }

          if (stickyElement.css("float") == "right") {
            stickyElement.css({"float":"none"}).parent().css({"float":"right"});
          }

          var stickyWrapper = stickyElement.parent();
          stickyWrapper.css('height', stickyElement.outerHeight());
          sticked.push({
            topSpacing: o.topSpacing,
            bottomSpacing: o.bottomSpacing,
            stickyElement: stickyElement,
            currentTop: null,
            stickyWrapper: stickyWrapper,
            className: o.className,
            getWidthFrom: o.getWidthFrom
          });
        });
      },
      update: scroller
    };

  // should be more efficient than using $window.scroll(scroller) and $window.resize(resizer):
  if (window.addEventListener) {
    window.addEventListener('scroll', scroller, false);
    window.addEventListener('resize', resizer, false);
  } else if (window.attachEvent) {
    window.attachEvent('onscroll', scroller);
    window.attachEvent('onresize', resizer);
  }

  $.fn.sticky = 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 );
    } else {
      $.error('Method ' + method + ' does not exist on jQuery.sticky');
    }
  };
  $(function() {
    setTimeout(scroller, 0);
  });
})(jQuery);
<|endoftext|>


<commit_before>;(function () {
/* jshint browser:true, evil:true */

// 1. create iframe pointing to script on jsconsole.com domain
// 2. create console object with: log, dir, etc?
// 3. console.log runs postMessage with json.stringified content
// 4. jsconsole.com/remote/?id.onMessage = send to server, and wait for response.

function sortci(a, b) {
  return a.toLowerCase() < b.toLowerCase() ? -1 : 1;
}

// from console.js
function stringify(o, simple) {
  var json = '', i, type = ({}).toString.call(o), parts = [], names = [];

  if (type === '[object String]') {
    json = '"' + o.replace(/\n/g, '\\n').replace(/"/g, '\\"') + '"';
  } else if (type === '[object Array]') {
    json = '[';
    for (i = 0; i < o.length; i++) {
      parts.push(stringify(o[i], simple));
    }
    json += parts.join(', ') + ']';
  } else if (type === '[object Object]') {
    json = '{';
    for (i in o) {
      names.push(i);
    }
    names.sort(sortci);
    for (i = 0; i < names.length; i++) {
      parts.push(stringify(names[i]) + ': ' + stringify(o[names[i] ], simple));
    }
    json += parts.join(', ') + '}';
  } else if (type === '[object Number]') {
    json = o+'';
  } else if (type === '[object Boolean]') {
    json = o ? 'true' : 'false';
  } else if (type === '[object Function]') {
    json = o.toString();
  } else if (o === null) {
    json = 'null';
  } else if (o === undefined) {
    json = 'undefined';
  } else if (simple === undefined) {
    json = type + '{\n';
    for (i in o) {
      names.push(i);
    }
    names.sort(sortci);
    for (i = 0; i < names.length; i++) {
      // safety from max stack
      parts.push(names[i] + ': ' + stringify(o[names[i]], true));
    }
    json += parts.join(',\n') + '\n}';
  } else {
    try {
      json = o+''; // should look like an object
    } catch (e) {}
  }
  return json;
}

function getRemoteScript() {
  var scripts = document.getElementsByTagName('script');
  var remoteScript = scripts[scripts.length-1];
  var re = /jsconsole\..*(:\d+)?\/js\/remote.js/;
  for (var i = 0; i < scripts.length; i++) {
    if (re.test(scripts[i].src)) {
      remoteScript = scripts[i];
      break;
    }
  }

  return remoteScript;
}

var last = getRemoteScript();

var lastSrc = last.getAttribute('src'),
    id = lastSrc.replace(/.*\?/, ''),
    origin = document.location.protocol + '//' + lastSrc.substr(7).replace(/\/.*$/, ''),
    remoteWindow = null,
    queue = [],
    msgType = '';

var remoteFrame = document.createElement('iframe');
remoteFrame.style.display = 'none';
remoteFrame.src = origin + '/remote.html?' + id;

// an attempt to allow this code to be included in the head element
document.documentElement.appendChild(remoteFrame);

window.addEventListener('message', function (event) {
  if (event.origin !== origin) {
    return;
  }

  // this isn't for us
  if (typeof event.data !== 'string') {
    return;
  }

  // eval the event.data command
  try {
    if (event.data.indexOf('console.log') === 0) {
      eval('remote.echo(' + event.data.match(/console.log\((.*)\);?/)[1] + ', "' + event.data + '", true)');
    } else {
      // must be undefined to work
      remote.echo(eval(event.data), event.data, undefined);
    }
  } catch (e) {
    _console.log(e.stack, event);
    remote.error(e, event.data);
  }
}, false);

var timers = {}; // timers for console.time and console.timeEnd

var remote = {
  log: function () {
    // var argsObj = stringify(arguments.length === 1 ? arguments[0] : [].slice.call(arguments, 0));
    var response = [];
    [].forEach.call(arguments, function (args) {
      response.push(stringify(args, true));
    });

    var msg = JSON.stringify({ response: response, cmd: 'remote console.log', type: msgType });

    if (remoteWindow) {
      remoteWindow.postMessage(msg, origin);
    } else {
      queue.push(msg);
    }

    msgType = '';
  },
  info: function () {
    msgType = 'info';
    remote.log.apply(this, arguments);
  },
  echo: function () {
    var args = [].slice.call(arguments, 0),
        plain = args.pop(),
        cmd = args.pop(),
        response = args;

    var argsObj = stringify(response, plain),
        msg = JSON.stringify({ response: argsObj, cmd: cmd });
    if (remoteWindow) {
      remoteWindow.postMessage(msg, origin);
    } else {
      queue.push(msg);
    }
  },
  error: function (error, cmd) {
    var msg = JSON.stringify({ response: error.message, cmd: cmd, type: 'error' });
    if (remoteWindow) {
      remoteWindow.postMessage(msg, origin);
    } else {
      queue.push(msg);
    }
  },
  time: function(title){
    if(typeof title !== 'string') {
      return;
    }
    timers[title] = +new Date();
  },
  timeEnd: function(title){
    if (typeof title !== 'string' || !timers[title]) {
      return;
    }
    var execTime = +new Date() - timers[title];
    delete timers[title];
    var plain = title + ': ' + execTime + 'ms';
    var msg = JSON.stringify({ response: plain, cmd:  'remote console.log', type: '' });
    if (remoteWindow) {
      remoteWindow.postMessage(msg, origin);
    } else {
      queue.push(msg);
    }
  }
};

// just for extra support
remote.debug = remote.dir = remote.log;
remote.warn = remote.info;

remoteFrame.onload = function () {
  remoteWindow = remoteFrame.contentWindow;
  remoteWindow.postMessage('__init__', origin);

  remoteWindow.postMessage(stringify({ response: 'Connection established with ' + window.location.toString() + '\n' + navigator.userAgent, type: 'info' }), origin);

  for (var i = 0; i < queue.length; i++) {
    remoteWindow.postMessage(queue[i], origin);
  }
};

window.remote = remote;

if (window.addEventListener) {
  window.addEventListener('error', function (event) {
    remote.error({ message: event.message }, event.filename + ':' + event.lineno);
  }, false);
}

try {
  window._console = window.console;
  window.console = remote;
} catch (e) {
  console.log('cannot overwrite existing console object');
}

function warnUsage() {
  var useSS = false;
  try {
    sessionStorage.getItem('foo');
    useSS = true;
  } catch (e) {}
  if (!(useSS ? sessionStorage.jsconsole : window.name)) {
    if (useSS) {
      sessionStorage.jsconsole = 1;
    } else {
      window.name = 1;
    }
    alert('You will see this warning once per session.\n\nYou are using a remote control script on this site - if you accidently push it to production, anyone will have control of your visitor\'s browser. Remember to remove this script.');
  }
}

warnUsage();

})();
<commit_msg>fix: origin to work with http & https urls (#78)<commit_after>;(function () {
/* jshint browser:true, evil:true */

// 1. create iframe pointing to script on jsconsole.com domain
// 2. create console object with: log, dir, etc?
// 3. console.log runs postMessage with json.stringified content
// 4. jsconsole.com/remote/?id.onMessage = send to server, and wait for response.

function sortci(a, b) {
  return a.toLowerCase() < b.toLowerCase() ? -1 : 1;
}

// from console.js
function stringify(o, simple) {
  var json = '', i, type = ({}).toString.call(o), parts = [], names = [];

  if (type === '[object String]') {
    json = '"' + o.replace(/\n/g, '\\n').replace(/"/g, '\\"') + '"';
  } else if (type === '[object Array]') {
    json = '[';
    for (i = 0; i < o.length; i++) {
      parts.push(stringify(o[i], simple));
    }
    json += parts.join(', ') + ']';
  } else if (type === '[object Object]') {
    json = '{';
    for (i in o) {
      names.push(i);
    }
    names.sort(sortci);
    for (i = 0; i < names.length; i++) {
      parts.push(stringify(names[i]) + ': ' + stringify(o[names[i] ], simple));
    }
    json += parts.join(', ') + '}';
  } else if (type === '[object Number]') {
    json = o+'';
  } else if (type === '[object Boolean]') {
    json = o ? 'true' : 'false';
  } else if (type === '[object Function]') {
    json = o.toString();
  } else if (o === null) {
    json = 'null';
  } else if (o === undefined) {
    json = 'undefined';
  } else if (simple === undefined) {
    json = type + '{\n';
    for (i in o) {
      names.push(i);
    }
    names.sort(sortci);
    for (i = 0; i < names.length; i++) {
      // safety from max stack
      parts.push(names[i] + ': ' + stringify(o[names[i]], true));
    }
    json += parts.join(',\n') + '\n}';
  } else {
    try {
      json = o+''; // should look like an object
    } catch (e) {}
  }
  return json;
}

function getRemoteScript() {
  var scripts = document.getElementsByTagName('script');
  var remoteScript = scripts[scripts.length-1];
  var re = /jsconsole\..*(:\d+)?\/js\/remote.js/;
  for (var i = 0; i < scripts.length; i++) {
    if (re.test(scripts[i].src)) {
      remoteScript = scripts[i];
      break;
    }
  }

  return remoteScript;
}

var last = getRemoteScript();

var lastSrc = last.getAttribute('src'),
    id = lastSrc.replace(/.*\?/, ''),
    protocol = /https?:\/\//.exec(lastSrc)[0],
    origin = protocol + lastSrc.substr(protocol.length).replace(/\/.*$/, ''),
    remoteWindow = null,
    queue = [],
    msgType = '';

var remoteFrame = document.createElement('iframe');
remoteFrame.style.display = 'none';
remoteFrame.src = origin + '/remote.html?' + id;

// an attempt to allow this code to be included in the head element
document.documentElement.appendChild(remoteFrame);

window.addEventListener('message', function (event) {
  if (event.origin !== origin) {
    return;
  }

  // this isn't for us
  if (typeof event.data !== 'string') {
    return;
  }

  // eval the event.data command
  try {
    if (event.data.indexOf('console.log') === 0) {
      eval('remote.echo(' + event.data.match(/console.log\((.*)\);?/)[1] + ', "' + event.data + '", true)');
    } else {
      // must be undefined to work
      remote.echo(eval(event.data), event.data, undefined);
    }
  } catch (e) {
    _console.log(e.stack, event);
    remote.error(e, event.data);
  }
}, false);

var timers = {}; // timers for console.time and console.timeEnd

var remote = {
  log: function () {
    // var argsObj = stringify(arguments.length === 1 ? arguments[0] : [].slice.call(arguments, 0));
    var response = [];
    [].forEach.call(arguments, function (args) {
      response.push(stringify(args, true));
    });

    var msg = JSON.stringify({ response: response, cmd: 'remote console.log', type: msgType });

    if (remoteWindow) {
      remoteWindow.postMessage(msg, origin);
    } else {
      queue.push(msg);
    }

    msgType = '';
  },
  info: function () {
    msgType = 'info';
    remote.log.apply(this, arguments);
  },
  echo: function () {
    var args = [].slice.call(arguments, 0),
        plain = args.pop(),
        cmd = args.pop(),
        response = args;

    var argsObj = stringify(response, plain),
        msg = JSON.stringify({ response: argsObj, cmd: cmd });
    if (remoteWindow) {
      remoteWindow.postMessage(msg, origin);
    } else {
      queue.push(msg);
    }
  },
  error: function (error, cmd) {
    var msg = JSON.stringify({ response: error.message, cmd: cmd, type: 'error' });
    if (remoteWindow) {
      remoteWindow.postMessage(msg, origin);
    } else {
      queue.push(msg);
    }
  },
  time: function(title){
    if(typeof title !== 'string') {
      return;
    }
    timers[title] = +new Date();
  },
  timeEnd: function(title){
    if (typeof title !== 'string' || !timers[title]) {
      return;
    }
    var execTime = +new Date() - timers[title];
    delete timers[title];
    var plain = title + ': ' + execTime + 'ms';
    var msg = JSON.stringify({ response: plain, cmd:  'remote console.log', type: '' });
    if (remoteWindow) {
      remoteWindow.postMessage(msg, origin);
    } else {
      queue.push(msg);
    }
  }
};

// just for extra support
remote.debug = remote.dir = remote.log;
remote.warn = remote.info;

remoteFrame.onload = function () {
  remoteWindow = remoteFrame.contentWindow;
  remoteWindow.postMessage('__init__', origin);

  remoteWindow.postMessage(stringify({ response: 'Connection established with ' + window.location.toString() + '\n' + navigator.userAgent, type: 'info' }), origin);

  for (var i = 0; i < queue.length; i++) {
    remoteWindow.postMessage(queue[i], origin);
  }
};

window.remote = remote;

if (window.addEventListener) {
  window.addEventListener('error', function (event) {
    remote.error({ message: event.message }, event.filename + ':' + event.lineno);
  }, false);
}

try {
  window._console = window.console;
  window.console = remote;
} catch (e) {
  console.log('cannot overwrite existing console object');
}

function warnUsage() {
  var useSS = false;
  try {
    sessionStorage.getItem('foo');
    useSS = true;
  } catch (e) {}
  if (!(useSS ? sessionStorage.jsconsole : window.name)) {
    if (useSS) {
      sessionStorage.jsconsole = 1;
    } else {
      window.name = 1;
    }
    alert('You will see this warning once per session.\n\nYou are using a remote control script on this site - if you accidently push it to production, anyone will have control of your visitor\'s browser. Remember to remove this script.');
  }
}

warnUsage();

})();
<|endoftext|>


<commit_before>/*
 * tksweb - Web UI for timesheet entry
 *
 * Copyright (c) 2011-2013 Grant McLean (grant@mclean.net.nz)
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 */

(function($) {
    'use strict';

    var TKSWeb = window.TKSWeb = {
        day_name          : [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ],
        month_name        : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
        hour_label_width  : 50,
        hour_label_height : 48,
        day_label_width   : 200,
        day_label_height  : 28
    };
    var week_days, hours, column_for_date;

    function init_hours() {
        hours = [ '' ];
        for(var i = 1; i < 24; i++) {
            hours.push({ hour: pad2(i) + ':00' });
        }
    }

    function init_week_days(days) {
        column_for_date = {};
        week_days       = [];
        for(var i = 0; i < 7; i++) {
            column_for_date[ days[i] ] = i;
            var part = days[i].split('-');
            week_days.push({
                date      : days[i],
                day       : part[2],
                month     : part[1],
                year      : part[0],
                day_name  : TKSWeb.day_name[ i ],
                month_name: TKSWeb.month_name[ parseInt(part[1], 10) - 1 ],
            });
        }
    };

    function pad2(num) {
        return num < 10 ? '0' + num : '' + num;
    }

    var Activity = Backbone.Model.extend({
        defaults: {
            date          : '',
            start_time    : 0,
            duration      : 60,
            wr_number     : '',
            description   : ''
        },
        initialize: function() {
            this.set('column', column_for_date[ this.get('date') ]);
        },
        select: function() {
            this.trigger('selection_changed', this);
            this.set('selected', true);
        },
        unselect: function() {
            this.set('selected', false);
        },
        for_edit_dialog: function() {
            var data = this.toJSON();
            data.duration = data.duration / 60;
            return data;
        },
        update_from_editor: function(data) {
            this.set('wr_number', data.wr_number);
            this.set('description', data.description);
            var duration = Math.floor(4 * data.duration) * 15;
            this.set('duration', duration);
            this.save();
        }
    });

    var Activities = Backbone.Collection.extend({
        model: Activity,
        url: '/activity',

        initialize: function() {
            this.on("selection_changed", this.selection_changed);
        },
        comparator: function(activity) {
            return activity.get("date") + ' ' +
                   ('0000' + activity.get("start_time")).substr(-4);
        },
        selection_changed: function(new_selection) {
            if(this.current_activity) {
                this.current_activity.unselect();
            }
            this.current_activity = new_selection;
        },
        editor_active: function() {
            return this.editor.active;
        },
        save_from_editor: function(data) {
            var activity = this.current_activity;
            if(activity) {
                return activity.update_from_editor(data);
            }
            else {
                alert('Need to create from dialog');
            }
        }
    });

    var ActivityView = Backbone.View.extend({
        tagName: 'div',
        className: 'activity',

        events: {
            "click": "select_activity",
            "dblclick": "edit_activity"
        },

        initialize: function() {
            this.week_view = this.model.collection.view;
            this.listenTo(this.model, "change:wr_number change:description", this.render);
            this.listenTo(this.model, "change:duration", this.size_element);
            this.listenTo(this.model, "change:selected", this.show_selection);
            this.position_element();
            this.size_element();
        },

        render: function() {
            var context = this.model.toJSON();
            this.$el.html( this.week_view.activity_template(context) );
            return this;
        },
        position_element: function() {
            var activity = this.model;
            this.$el.css({
                left: activity.get('column') * 200,
                top:  (activity.get('start_time') * TKSWeb.hour_label_height) / 60
            });
        },
        size_element: function() {
            var activity = this.model;
            this.$el.height(activity.get('duration') * TKSWeb.hour_label_height / 60 - 2);
        },
        week_view: function() {
            return this.collection.view;
        },
        select_activity: function() {
            this.model.select();
        },
        show_selection: function() {
            this.$el.toggleClass('selected', this.model.get('selected'));
        },
        edit_activity: function() {
            this.model.trigger('start_activity_edit', this.model);
        }
    });

    var ActivityEditor = Backbone.View.extend({
        tagName: 'form',
        className: 'tksweb-activity-dialog',

        events: {
            "submit": "enter_pressed"
        },

        initialize: function() {
            this.create_edit_dialog();
            this.activity_dialog_template = Handlebars.compile( $('#activity-dialog-template').html() );
            this.collection.on('start_activity_edit', this.start_activity_edit, this);
        },
        create_edit_dialog: function() {
            var editor = this;
            this.$el.dialog({
                autoOpen:      false,
                resizable:     false,
                closeOnEscape: true,
                width:         360,
                height:        230,
                modal:         true,
                open:          function() { editor.active = true;  },
                close:         function() { editor.active = false; },
                buttons:       {
                    "Ok":     function() { editor.save_activity(); },
                    "Cancel": function() { editor.close(); }
                }

            });
        },
        open: function() {
            this.$el.dialog("open");
        },
        close: function() {
            this.$el.dialog("close");
        },
        start_activity_edit: function(activity) {
            var data = activity.for_edit_dialog();
            this.$el.html( this.activity_dialog_template(data) );
            this.set_title(data.id ? 'Edit Activity' : 'Add Activity');
            this.set_focus(data.wr_number ? '.activity-dc input' : '.activity-wr input');
            this.open();
        },
        set_title: function(new_title) {
            this.$el.dialog('option', 'title', new_title);
        },
        set_focus: function(selector) {
            this.$(selector).focus();
        },
        enter_pressed: function(e) {
            e.preventDefault();
            this.save_activity();
        },
        save_activity: function() {
            this.collection.save_from_editor({
                wr_number   : this.$('.activity-wr input').val(),
                duration    : this.$('.activity-hr input').val(),
                description : this.$('.activity-dc input').val()
            });
            this.close();
        }
    });

    var WeekView = Backbone.View.extend({
        events: {
            "mousewheel .activities": "mousewheel"
        },
        initialize: function(options) {
            var view = this;
            this.compile_templates();
            this.render();
            this.collection.on('add', this.add_activity, this);
            $(window).resize( $.proxy(view.resize, view) );
        },
        compile_templates: function() {
            this.template = Handlebars.compile( $('#week-view-template').html() );
            this.activity_template = Handlebars.compile( $('#activity-template').html() );
        },
        render: function() {
            var context = {
                week_days: week_days,
                hours: hours
            };
            this.$el.html( this.template(context) );
            this.size_activities();
            this.enable_workspace_drag();
            this.resize();
            this.set_initial_scroll();
        },
        size_activities: function() {
            this.activities_width  = TKSWeb.day_label_width * 7;
            this.activities_height = TKSWeb.hour_label_height * 24;
            this.$('.activities')
                .width(this.activities_width)
                .height(this.activities_height);
            this.$('.day-labels')
                .width(this.activities_width);
            this.$('.hour-labels')
                .height(this.activities_height);
        },
        enable_workspace_drag: function() {
            var view = this;
            this.$('.activities').draggable({
                distance: 5,
                drag: function(event, ui) { view.drag( ui.position ); }
            });
        },
        resize: function() {
            this.app_width  = Math.min(this.activities_width, window.innerWidth);
            this.app_height = Math.min(this.activities_height, window.innerHeight);
            this.$el.width( this.app_width ).height( this.app_height );
            this.set_drag_constraints();
        },
        set_drag_constraints: function() {
            this.min_y = this.app_height - this.activities_height - TKSWeb.day_label_height;
            this.max_y = 0;
            this.$('.activities').draggable("option", {
                containment: [
                    this.app_width - this.activities_width - TKSWeb.hour_label_width,
                    this.min_y,
                    1,
                    this.max_y + 1
                ]
            });
        },
        drag: function(pos) {
            this.$('.day-labels ul').css('left', pos.left);
            this.$('.hour-labels ul').css('top', pos.top);
        },
        set_initial_scroll: function() {
            var $activities = this.$('.activities');
            var day_height = (18 - 8) * TKSWeb.hour_label_height;
            var y = -8 * TKSWeb.hour_label_height;
            if(day_height < this.app_height) {
                y = y + (this.app_height - day_height) / 2
            }
            $activities.css('top', y);
            this.$('.hour-labels ul').css('top', y);
        },
        mousewheel: function(e, delta) {
            var $activities = this.$('.activities');
            var y = parseInt($activities.css('top'), 10) + delta * 12;
            y = Math.min( Math.max(y, this.min_y), this.max_y);
            $activities.css('top', y);
            this.$('.hour-labels ul').css('top', y);
        },
        add_activity: function(activity) {
            this.$('.activities').append(
                new ActivityView({
                    model: activity
                }).render().el
            );
        }
    });

    TKSWeb.show_week = function (el, days, activities_data) {
        init_week_days(days);
        init_hours();
        var activities = new Activities();
        activities.view = new WeekView({
            el: el,
            monday: days[0],
            collection: activities
        });
        activities.add(activities_data);
        var activity_editor = new ActivityEditor({ collection: activities });
    };

})(jQuery);
<commit_msg>stop tracking current activity when it is unselected<commit_after>/*
 * tksweb - Web UI for timesheet entry
 *
 * Copyright (c) 2011-2013 Grant McLean (grant@mclean.net.nz)
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 */

(function($) {
    'use strict';

    var TKSWeb = window.TKSWeb = {
        day_name          : [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ],
        month_name        : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
        hour_label_width  : 50,
        hour_label_height : 48,
        day_label_width   : 200,
        day_label_height  : 28
    };
    var week_days, hours, column_for_date;

    function init_hours() {
        hours = [ '' ];
        for(var i = 1; i < 24; i++) {
            hours.push({ hour: pad2(i) + ':00' });
        }
    }

    function init_week_days(days) {
        column_for_date = {};
        week_days       = [];
        for(var i = 0; i < 7; i++) {
            column_for_date[ days[i] ] = i;
            var part = days[i].split('-');
            week_days.push({
                date      : days[i],
                day       : part[2],
                month     : part[1],
                year      : part[0],
                day_name  : TKSWeb.day_name[ i ],
                month_name: TKSWeb.month_name[ parseInt(part[1], 10) - 1 ],
            });
        }
    };

    function pad2(num) {
        return num < 10 ? '0' + num : '' + num;
    }

    var Activity = Backbone.Model.extend({
        defaults: {
            date          : '',
            start_time    : 0,
            duration      : 60,
            wr_number     : '',
            description   : ''
        },
        initialize: function() {
            this.set('column', column_for_date[ this.get('date') ]);
        },
        select: function() {
            this.trigger('selection_changed', this);
            this.set('selected', true);
        },
        unselect: function() {
            this.set('selected', false);
            this.trigger('clear_selection');
        },
        for_edit_dialog: function() {
            var data = this.toJSON();
            data.duration = data.duration / 60;
            return data;
        },
        update_from_editor: function(data) {
            this.set('wr_number', data.wr_number);
            this.set('description', data.description);
            var duration = Math.floor(4 * data.duration) * 15;
            this.set('duration', duration);
            this.save();
        }
    });

    var Activities = Backbone.Collection.extend({
        model: Activity,
        url: '/activity',

        initialize: function() {
            this.on("selection_changed", this.selection_changed);
            this.on("clear_selection", this.clear_selection);
        },
        comparator: function(activity) {
            return activity.get("date") + ' ' +
                   ('0000' + activity.get("start_time")).substr(-4);
        },
        selection_changed: function(new_selection) {
            if(this.current_activity) {
                this.current_activity.unselect();
            }
            this.current_activity = new_selection;
        },
        clear_selection: function() {
            this.current_activity = null;
        },
        editor_active: function() {
            return this.editor.active;
        },
        save_from_editor: function(data) {
            var activity = this.current_activity;
            if(activity) {
                return activity.update_from_editor(data);
            }
            else {
                alert('Need to create from dialog');
            }
        }
    });

    var ActivityView = Backbone.View.extend({
        tagName: 'div',
        className: 'activity',

        events: {
            "click": "select_activity",
            "dblclick": "edit_activity"
        },

        initialize: function() {
            this.week_view = this.model.collection.view;
            this.listenTo(this.model, "change:wr_number change:description", this.render);
            this.listenTo(this.model, "change:duration", this.size_element);
            this.listenTo(this.model, "change:selected", this.show_selection);
            this.position_element();
            this.size_element();
        },

        render: function() {
            var context = this.model.toJSON();
            this.$el.html( this.week_view.activity_template(context) );
            return this;
        },
        position_element: function() {
            var activity = this.model;
            this.$el.css({
                left: activity.get('column') * 200,
                top:  (activity.get('start_time') * TKSWeb.hour_label_height) / 60
            });
        },
        size_element: function() {
            var activity = this.model;
            this.$el.height(activity.get('duration') * TKSWeb.hour_label_height / 60 - 2);
        },
        week_view: function() {
            return this.collection.view;
        },
        select_activity: function() {
            this.model.select();
        },
        show_selection: function() {
            this.$el.toggleClass('selected', this.model.get('selected'));
        },
        edit_activity: function() {
            this.model.trigger('start_activity_edit', this.model);
        }
    });

    var ActivityEditor = Backbone.View.extend({
        tagName: 'form',
        className: 'tksweb-activity-dialog',

        events: {
            "submit": "enter_pressed"
        },

        initialize: function() {
            this.create_edit_dialog();
            this.activity_dialog_template = Handlebars.compile( $('#activity-dialog-template').html() );
            this.collection.on('start_activity_edit', this.start_activity_edit, this);
        },
        create_edit_dialog: function() {
            var editor = this;
            this.$el.dialog({
                autoOpen:      false,
                resizable:     false,
                closeOnEscape: true,
                width:         360,
                height:        230,
                modal:         true,
                open:          function() { editor.active = true;  },
                close:         function() { editor.active = false; },
                buttons:       {
                    "Ok":     function() { editor.save_activity(); },
                    "Cancel": function() { editor.close(); }
                }

            });
        },
        open: function() {
            this.$el.dialog("open");
        },
        close: function() {
            this.$el.dialog("close");
        },
        start_activity_edit: function(activity) {
            var data = activity.for_edit_dialog();
            this.$el.html( this.activity_dialog_template(data) );
            this.set_title(data.id ? 'Edit Activity' : 'Add Activity');
            this.set_focus(data.wr_number ? '.activity-dc input' : '.activity-wr input');
            this.open();
        },
        set_title: function(new_title) {
            this.$el.dialog('option', 'title', new_title);
        },
        set_focus: function(selector) {
            this.$(selector).focus();
        },
        enter_pressed: function(e) {
            e.preventDefault();
            this.save_activity();
        },
        save_activity: function() {
            this.collection.save_from_editor({
                wr_number   : this.$('.activity-wr input').val(),
                duration    : this.$('.activity-hr input').val(),
                description : this.$('.activity-dc input').val()
            });
            this.close();
        }
    });

    var WeekView = Backbone.View.extend({
        events: {
            "mousewheel .activities": "mousewheel"
        },
        initialize: function(options) {
            var view = this;
            this.compile_templates();
            this.render();
            this.collection.on('add', this.add_activity, this);
            $(window).resize( $.proxy(view.resize, view) );
        },
        compile_templates: function() {
            this.template = Handlebars.compile( $('#week-view-template').html() );
            this.activity_template = Handlebars.compile( $('#activity-template').html() );
        },
        render: function() {
            var context = {
                week_days: week_days,
                hours: hours
            };
            this.$el.html( this.template(context) );
            this.size_activities();
            this.enable_workspace_drag();
            this.resize();
            this.set_initial_scroll();
        },
        size_activities: function() {
            this.activities_width  = TKSWeb.day_label_width * 7;
            this.activities_height = TKSWeb.hour_label_height * 24;
            this.$('.activities')
                .width(this.activities_width)
                .height(this.activities_height);
            this.$('.day-labels')
                .width(this.activities_width);
            this.$('.hour-labels')
                .height(this.activities_height);
        },
        enable_workspace_drag: function() {
            var view = this;
            this.$('.activities').draggable({
                distance: 5,
                drag: function(event, ui) { view.drag( ui.position ); }
            });
        },
        resize: function() {
            this.app_width  = Math.min(this.activities_width, window.innerWidth);
            this.app_height = Math.min(this.activities_height, window.innerHeight);
            this.$el.width( this.app_width ).height( this.app_height );
            this.set_drag_constraints();
        },
        set_drag_constraints: function() {
            this.min_y = this.app_height - this.activities_height - TKSWeb.day_label_height;
            this.max_y = 0;
            this.$('.activities').draggable("option", {
                containment: [
                    this.app_width - this.activities_width - TKSWeb.hour_label_width,
                    this.min_y,
                    1,
                    this.max_y + 1
                ]
            });
        },
        drag: function(pos) {
            this.$('.day-labels ul').css('left', pos.left);
            this.$('.hour-labels ul').css('top', pos.top);
        },
        set_initial_scroll: function() {
            var $activities = this.$('.activities');
            var day_height = (18 - 8) * TKSWeb.hour_label_height;
            var y = -8 * TKSWeb.hour_label_height;
            if(day_height < this.app_height) {
                y = y + (this.app_height - day_height) / 2
            }
            $activities.css('top', y);
            this.$('.hour-labels ul').css('top', y);
        },
        mousewheel: function(e, delta) {
            var $activities = this.$('.activities');
            var y = parseInt($activities.css('top'), 10) + delta * 12;
            y = Math.min( Math.max(y, this.min_y), this.max_y);
            $activities.css('top', y);
            this.$('.hour-labels ul').css('top', y);
        },
        add_activity: function(activity) {
            this.$('.activities').append(
                new ActivityView({
                    model: activity
                }).render().el
            );
        }
    });

    TKSWeb.show_week = function (el, days, activities_data) {
        init_week_days(days);
        init_hours();
        var activities = new Activities();
        activities.view = new WeekView({
            el: el,
            monday: days[0],
            collection: activities
        });
        activities.add(activities_data);
        var activity_editor = new ActivityEditor({ collection: activities });
    };

})(jQuery);
<|endoftext|>


<commit_before>(function () {

  // Configuraiton
  var
    H = Humble.Vis,
    E = Flotr.EventAdapter,

    container = document.getElementById('vis'),

    start = 4218,
    ymax = 10000 - start,
    xmax = 10000 - start,

    cumulativeOptions = {
      name    : 'cumulative',
      height  : 240,
      width   : 600,
      data    : totals,
      flotr   : {
        lines : {
          fill : true,
          fillOpacity : .2
        },
        yaxis : {
          noTicks : 3,
          showLabels : true,
          min : 0,
          max : ymax,
          ticks : [
              [0, '
'+start+'h
'],
              [ymax - 4000, '
6000h
'],
              [ymax - 2000, '
8000h
'],
              [ymax, '
10000h
']
          ]

          /*,
          tickFormatter : function (n) {
            return (n == this.max ? false : '$'+n);
          }
          */
        },
        xaxis : {
          max : xmax,
          min: 0,
          showLabels : true,
          tickFormatter : function (n) {
            if (n == 0) return '';
            var tickDate = (new Date(Date.parse(dates[1]) + n * 1000 * 60 * 60 * 24)); // Double check this index please
            return tickDate.getMonth()+'/'+tickDate.getDate()+'/'+tickDate.getFullYear();
          }
        }
      }
    },

    practiceOptions = {
      name    : 'practice',
      height  : 80,
      width   : 600,
      data    : practices,
      skipPreprocess : true,
      flotr   : {
        title : 'Daily Time by Category:',
        bars : { show : true, stacked : true },
        mouse: {
          track: true,
          trackY: false,
          position: 'ne',
          trackDecimals: 0
        },
        legend : {
          position : 'ne',
          show : true
        }
      }
    },

    summaryOptions = {
      name    : 'summary',
      height  : 80,
      width   : 600,
      data    : totals,
      flotr   : {
        lines : {
          fill : true,
          fillOpacity : .2
        },
        mouse : {
          track: true,
          trackY: false,
          sensibility: 1,
          trackDecimals: 4,
          trackFormatter: function (o) {
            /*
            var data = jsonData[o.nearest.x];
            return data.date + " Price: " + data.close + " Vol: " + data.volume;
            */
          },
          position: 'ne'
        },
        xaxis : {
          noTicks: 5,
          showLabels : true
          /*,
          tickFormatter : function (n) {
            return jsonData[n].date.split(' ')[2];
            return (parseInt(n) === 0 ? false : jsonData[n].date.split(' ')[2]);
          }
          */
        },
        handles   : { show : true },
        selection : { mode : 'x'},
        grid : {
          verticalLines : false
        }
      }
    },

    vis, price, volume, summary, selection, hit;

  // Application

  vis = new H.Visualization();
  cumulative = new H.Child(cumulativeOptions);
  practice = new H.Child(practiceOptions);
  summary = new H.Child(summaryOptions);
  selection = new H.Interaction({leader : summary});
  hit = new H.Interaction();

  vis.add(cumulative);
  vis.add(practice);
  vis.add(summary);
  vis.render(container);

  selection.add(H.Action.Selection);
  selection.follow(practice);

  hit.add(H.Action.Hit);
  hit.group([practice, summary]);
})();

<commit_msg>Removed junky tick formatters.<commit_after>(function () {

  // Configuraiton
  var
    H = Humble.Vis,
    E = Flotr.EventAdapter,

    container = document.getElementById('vis'),

    start = 4218,
    ymax = 10000 - start,
    xmax = 10000 - start,

    cumulativeOptions = {
      name    : 'cumulative',
      height  : 240,
      width   : 600,
      data    : totals,
      flotr   : {
        lines : {
          fill : true,
          fillOpacity : .2
        },
        yaxis : {
          noTicks : 3,
          showLabels : true,
          min : 0,
          max : ymax,
          ticks : [
              [0, '
'+start+'h
'],
              [ymax - 4000, '
6000h
'],
              [ymax - 2000, '
8000h
'],
              [ymax, '
10000h
']
          ]
        },
        xaxis : {
          max : xmax,
          min: 0,
          showLabels : true,
          tickFormatter : function (n) {
            if (n == 0) return '';
            var tickDate = (new Date(Date.parse(dates[1]) + n * 1000 * 60 * 60 * 24)); // Double check this index please
            return tickDate.getMonth()+'/'+tickDate.getDate()+'/'+tickDate.getFullYear();
          }
        }
      }
    },

    practiceOptions = {
      name    : 'practice',
      height  : 80,
      width   : 600,
      data    : practices,
      skipPreprocess : true,
      flotr   : {
        title : 'Daily Time by Category:',
        bars : { show : true, stacked : true },
        mouse: {
          track: true,
          trackY: false,
          position: 'ne',
          trackDecimals: 0
        },
        legend : {
          position : 'ne',
          show : true
        }
      }
    },

    summaryOptions = {
      name    : 'summary',
      height  : 80,
      width   : 600,
      data    : totals,
      flotr   : {
        lines : {
          fill : true,
          fillOpacity : .2
        },
        mouse : {
          track: true,
          trackY: false,
          sensibility: 1,
          trackDecimals: 4,
          trackFormatter: function (o) {
            /*
            var data = jsonData[o.nearest.x];
            return data.date + " Price: " + data.close + " Vol: " + data.volume;
            */
          },
          position: 'ne'
        },
        xaxis : {
          noTicks: 5,
          showLabels : true
        },
        handles   : { show : true },
        selection : { mode : 'x'},
        grid : {
          verticalLines : false
        }
      }
    },

    vis, price, volume, summary, selection, hit;

  // Application

  vis = new H.Visualization();
  cumulative = new H.Child(cumulativeOptions);
  practice = new H.Child(practiceOptions);
  summary = new H.Child(summaryOptions);
  selection = new H.Interaction({leader : summary});
  hit = new H.Interaction();

  vis.add(cumulative);
  vis.add(practice);
  vis.add(summary);
  vis.render(container);

  selection.add(H.Action.Selection);
  selection.follow(practice);

  hit.add(H.Action.Hit);
  hit.group([practice, summary]);
})();

<|endoftext|>


<commit_before>(function($) {
    'use strict';

    var TKSWeb = window.TKSWeb = {
        day_name          : [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ],
        month_name        : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
        hour_label_width  : 50,
        hour_label_height : 48,
        day_label_width   : 200,
        day_label_height  : 28
    };
    var week_days, hours, column_for_date;

    function init_hours() {
        hours = [ '' ];
        for(var i = 1; i < 24; i++) {
            hours.push({ hour: pad2(i) + ':00' });
        }
    }

    function init_week_days(days) {
        column_for_date = {};
        week_days       = [];
        for(var i = 0; i < 7; i++) {
            column_for_date[ days[i] ] = i;
            var part = days[i].split('-');
            week_days.push({
                date      : days[i],
                day       : part[2],
                month     : part[1],
                year      : part[0],
                day_name  : TKSWeb.day_name[ i ],
                month_name: TKSWeb.month_name[ parseInt(part[1], 10) - 1 ],
            });
        }
    };

    function pad2(num) {
        return num < 10 ? '0' + num : '' + num;
    }

    var Activity = Backbone.Model.extend({
        defaults: {
            date          : '',
            start_time    : 0,
            duration      : 60,
            wr_number     : '',
            description   : ''
        },
        initialize: function() {
            this.set('column', column_for_date[ this.get('date') ]);
        }
    });

    var Activities = Backbone.Collection.extend({
        model: Activity,
        url: '/activity',
        comparator: function(activity) {
            return activity.get("date") + ' ' +
                   ('0000' + activity.get("start_time")).substr(-4);
        }
    });

    var ActivityView = Backbone.View.extend({
        tagName: 'div',
        className: 'activity',

        initialize: function() {
            this.week_view = this.model.collection.view;
            this.listenTo(this.model, "change:wr_number change:description", this.render);
            this.position_element();
            this.size_element();
        },

        render: function() {
            var context = this.model.toJSON();
            this.$el.html( this.week_view.activity_template(context) );
            return this;
        },
        position_element: function() {
            var activity = this.model;
            this.$el.css({
                left: activity.get('column') * 200,
                top:  (activity.get('start_time') * TKSWeb.hour_label_height) / 60
            });
        },
        size_element: function() {
            var activity = this.model;
            this.$el.height(activity.get('duration') * TKSWeb.hour_label_height / 60);
        }
    });

    var WeekView = Backbone.View.extend({
        initialize: function(options) {
            var view = this;
            this.compile_templates();
            this.render();
            this.collection.on('add', this.add_activity, this);
            this.$('.activities').on('mousewheel', $.proxy(this.mousewheel, this));
            $(window).resize( $.proxy(view.resize, view) );
        },
        compile_templates: function() {
            this.template = Handlebars.compile( $('#week-view-template').html() );
            this.activity_template = Handlebars.compile( $('#activity-template').html() );
        },
        render: function() {
            var context = {
                week_days: week_days,
                hours: hours
            };
            this.$el.html( this.template(context) );
            this.size_activities();
            this.enable_workspace_drag();
            this.resize();
            this.set_initial_scroll();
        },
        size_activities: function() {
            this.activities_width  = TKSWeb.day_label_width * 7;
            this.activities_height = TKSWeb.hour_label_height * 24;
            this.$('.activities')
                .width(this.activities_width)
                .height(this.activities_height);
            this.$('.day-labels')
                .width(this.activities_width);
            this.$('.hour-labels')
                .height(this.activities_height);
        },
        enable_workspace_drag: function() {
            var view = this;
            this.$('.activities').draggable({
                drag: function(event, ui) { view.drag( ui.position ); }
            });
        },
        resize: function() {
            this.app_width  = Math.min(this.activities_width + TKSWeb.hour_label_width, window.innerWidth);
            this.app_height = Math.min(this.activities_height + TKSWeb.day_label_height, window.innerHeight);
            this.$el.width( this.app_width ).height( this.app_height );
            this.set_drag_constraints();
        },
        set_drag_constraints: function() {
            this.min_y = this.app_height - this.activities_height;
            this.max_y = TKSWeb.day_label_height + 1;
            this.$('.activities').draggable("option", {
                containment: [
                    this.app_width - this.activities_width,
                    this.min_y,
                    TKSWeb.hour_label_width + 1,
                    this.max_y
                ]
            });
        },
        drag: function(pos) {
            this.$('.day-labels ul').css('left', pos.left - TKSWeb.hour_label_width);
            this.$('.hour-labels ul').css('top', pos.top - TKSWeb.day_label_height);
        },
        set_initial_scroll: function() {
            var $activities = this.$('.activities');
            var day_height = (18 - 8) * TKSWeb.hour_label_height;
            var y = -8 * TKSWeb.hour_label_height;
            if(day_height < this.app_height) {
                y = y + (this.app_height - day_height) / 2
            }
            $activities.css('top', y);
            this.$('.hour-labels ul').css('top', y - TKSWeb.day_label_height);
        },
        mousewheel: function(e, delta) {
            var $activities = this.$('.activities');
            var y = parseInt($activities.css('top'), 10) + delta * 12;
            y = Math.min( Math.max(y, this.min_y), this.max_y);
            $activities.css('top', y);
            this.$('.hour-labels ul').css('top', y - TKSWeb.day_label_height);
        },
        add_activity: function(activity) {
            this.$('.activities').append(
                new ActivityView({
                    model: activity
                }).render().el
            );
        }
    });

    TKSWeb.show_week = function (el, days, activities_data) {
        init_week_days(days);
        init_hours();
        var activities = new Activities();
        activities.view = new WeekView({
            el: el,
            monday: days[0],
            collection: activities
        });
        activities.add(activities_data);
    };

})(jQuery);
<commit_msg>add event delegation hash to main view<commit_after>(function($) {
    'use strict';

    var TKSWeb = window.TKSWeb = {
        day_name          : [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ],
        month_name        : [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
        hour_label_width  : 50,
        hour_label_height : 48,
        day_label_width   : 200,
        day_label_height  : 28
    };
    var week_days, hours, column_for_date;

    function init_hours() {
        hours = [ '' ];
        for(var i = 1; i < 24; i++) {
            hours.push({ hour: pad2(i) + ':00' });
        }
    }

    function init_week_days(days) {
        column_for_date = {};
        week_days       = [];
        for(var i = 0; i < 7; i++) {
            column_for_date[ days[i] ] = i;
            var part = days[i].split('-');
            week_days.push({
                date      : days[i],
                day       : part[2],
                month     : part[1],
                year      : part[0],
                day_name  : TKSWeb.day_name[ i ],
                month_name: TKSWeb.month_name[ parseInt(part[1], 10) - 1 ],
            });
        }
    };

    function pad2(num) {
        return num < 10 ? '0' + num : '' + num;
    }

    var Activity = Backbone.Model.extend({
        defaults: {
            date          : '',
            start_time    : 0,
            duration      : 60,
            wr_number     : '',
            description   : ''
        },
        initialize: function() {
            this.set('column', column_for_date[ this.get('date') ]);
        }
    });

    var Activities = Backbone.Collection.extend({
        model: Activity,
        url: '/activity',
        comparator: function(activity) {
            return activity.get("date") + ' ' +
                   ('0000' + activity.get("start_time")).substr(-4);
        }
    });

    var ActivityView = Backbone.View.extend({
        tagName: 'div',
        className: 'activity',

        initialize: function() {
            this.week_view = this.model.collection.view;
            this.listenTo(this.model, "change:wr_number change:description", this.render);
            this.position_element();
            this.size_element();
        },

        render: function() {
            var context = this.model.toJSON();
            this.$el.html( this.week_view.activity_template(context) );
            return this;
        },
        position_element: function() {
            var activity = this.model;
            this.$el.css({
                left: activity.get('column') * 200,
                top:  (activity.get('start_time') * TKSWeb.hour_label_height) / 60
            });
        },
        size_element: function() {
            var activity = this.model;
            this.$el.height(activity.get('duration') * TKSWeb.hour_label_height / 60);
        }
    });

    var WeekView = Backbone.View.extend({
        events: {
            "mousewheel .activities": "mousewheel"
        },
        initialize: function(options) {
            var view = this;
            this.compile_templates();
            this.render();
            this.collection.on('add', this.add_activity, this);
            $(window).resize( $.proxy(view.resize, view) );
        },
        compile_templates: function() {
            this.template = Handlebars.compile( $('#week-view-template').html() );
            this.activity_template = Handlebars.compile( $('#activity-template').html() );
        },
        render: function() {
            var context = {
                week_days: week_days,
                hours: hours
            };
            this.$el.html( this.template(context) );
            this.size_activities();
            this.enable_workspace_drag();
            this.resize();
            this.set_initial_scroll();
        },
        size_activities: function() {
            this.activities_width  = TKSWeb.day_label_width * 7;
            this.activities_height = TKSWeb.hour_label_height * 24;
            this.$('.activities')
                .width(this.activities_width)
                .height(this.activities_height);
            this.$('.day-labels')
                .width(this.activities_width);
            this.$('.hour-labels')
                .height(this.activities_height);
        },
        enable_workspace_drag: function() {
            var view = this;
            this.$('.activities').draggable({
                drag: function(event, ui) { view.drag( ui.position ); }
            });
        },
        resize: function() {
            this.app_width  = Math.min(this.activities_width + TKSWeb.hour_label_width, window.innerWidth);
            this.app_height = Math.min(this.activities_height + TKSWeb.day_label_height, window.innerHeight);
            this.$el.width( this.app_width ).height( this.app_height );
            this.set_drag_constraints();
        },
        set_drag_constraints: function() {
            this.min_y = this.app_height - this.activities_height;
            this.max_y = TKSWeb.day_label_height + 1;
            this.$('.activities').draggable("option", {
                containment: [
                    this.app_width - this.activities_width,
                    this.min_y,
                    TKSWeb.hour_label_width + 1,
                    this.max_y
                ]
            });
        },
        drag: function(pos) {
            this.$('.day-labels ul').css('left', pos.left - TKSWeb.hour_label_width);
            this.$('.hour-labels ul').css('top', pos.top - TKSWeb.day_label_height);
        },
        set_initial_scroll: function() {
            var $activities = this.$('.activities');
            var day_height = (18 - 8) * TKSWeb.hour_label_height;
            var y = -8 * TKSWeb.hour_label_height;
            if(day_height < this.app_height) {
                y = y + (this.app_height - day_height) / 2
            }
            $activities.css('top', y);
            this.$('.hour-labels ul').css('top', y - TKSWeb.day_label_height);
        },
        mousewheel: function(e, delta) {
            var $activities = this.$('.activities');
            var y = parseInt($activities.css('top'), 10) + delta * 12;
            y = Math.min( Math.max(y, this.min_y), this.max_y);
            $activities.css('top', y);
            this.$('.hour-labels ul').css('top', y - TKSWeb.day_label_height);
        },
        add_activity: function(activity) {
            this.$('.activities').append(
                new ActivityView({
                    model: activity
                }).render().el
            );
        }
    });

    TKSWeb.show_week = function (el, days, activities_data) {
        init_week_days(days);
        init_hours();
        var activities = new Activities();
        activities.view = new WeekView({
            el: el,
            monday: days[0],
            collection: activities
        });
        activities.add(activities_data);
    };

})(jQuery);
<|endoftext|>


<commit_before>angular.module('myApp.values', [])
    .value('appTitle', 'Wasserqualität der Badeseen im Umkreis Gießens')
    .value('labInfo', {
        'name': 'Code for Gießen',
        'website': 'http://codefor.de/giessen/',
        'logoPath': 'public/img/cfgi-black.svg'
    })
    .value('contributors', [{
        'name': 'Christian Schulze',
        'website': 'http://andinfinity.de',
        'mail': 'chris@andinfinity.de'
    }])
    .value('footNotice', 'Dies ist ein Projekt des OK Lab Gießen. Die Inhalte stehen unter der MIT-Lizenz auf GitHub zur Verfügung.')
    .value('mapCenter',
        // this is the position the map will be centered from
        {
            'lat': 50.583732,
            'lng': 8.678344,
            'zoom': 11
        })
    .value('fallbackMarker',
        // this is the position the red marker is set to
        {
            'lat': 50.583732,
            'lng': 8.678344
        });
<commit_msg>changed to strict mode (always preferred!)<commit_after>'use strict';

angular.module('myApp.values', [])
    .value('appTitle', 'Wasserqualität der Badeseen im Umkreis Gießens')
    .value('labInfo', {
        'name': 'Code for Gießen',
        'website': 'http://codefor.de/giessen/',
        'logoPath': 'public/img/cfgi-black.svg'
    })
    .value('contributors', [{
        'name': 'Christian Schulze',
        'website': 'http://andinfinity.de',
        'mail': 'chris@andinfinity.de'
    }])
    .value('footNotice', 'Dies ist ein Projekt des OK Lab Gießen. Die Inhalte stehen unter der MIT-Lizenz auf GitHub zur Verfügung.')
    .value('mapCenter',
        // this is the position the map will be centered from
        {
            'lat': 50.583732,
            'lng': 8.678344,
            'zoom': 11
        })
    .value('fallbackMarker',
        // this is the position the red marker is set to
        {
            'lat': 50.583732,
            'lng': 8.678344
        });
<|endoftext|>


<commit_before><commit_msg>sorting blast outputs test2<commit_after><|endoftext|>