<commit_before>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

var d3 = require('../lib/').d3;
var _ = require('../lib/')._;

var log = require('../lib/').bows('Message');

module.exports = function(pool, opts) {

  opts = opts || {};

  var defaults = {
    imagesBaseUrl: pool.imagesBaseUrl(),
    highlightWidth: 4
  };

  _.defaults(opts, defaults);

  var mainGroup = pool.group();

  function message(selection) {
    opts.xScale = pool.xScale().copy();

    selection.each(function(currentData) {
      var messages = d3.select(this)
        .selectAll('g.d3-message-group')
        .data(currentData, function(d) {
          if (d.parentMessage === '' || d.parentMessage == null) {
            return d.id;
          }
        });

      var messageGroups = messages.enter()
        .append('g')
        .attr({
          'class': 'd3-message-group',
          id: function(d) {
            return 'message_' + d.id;
          },
          'clip-path': 'url(#mainClipPath)'
        });

      message.addMessageToPool(messageGroups);

      messages.exit().remove();
    });
  }

  message.addMessageToPool = function(selection) {
    opts.xScale = pool.xScale().copy();

    selection.append('rect')
      .attr({
        x: message.highlightXPosition,
        y: message.highlightYPosition,
        width: opts.size + opts.highlightWidth * 2,
        height: opts.size + opts.highlightWidth * 2,
        'class': 'd3-rect-message hidden'
      });

    selection.append('image')
      .attr({
        'xlink:href': opts.imagesBaseUrl + '/message/post_it.svg',
        x: message.xPosition,
        y: message.yPosition,
        width: opts.size,
        height: opts.size
      })
      .classed({'d3-image': true, 'd3-message': true});

    selection.on('click', function(d) {
      d3.event.stopPropagation(); // silence the click-and-drag listener
      opts.emitter.emit('messageThread', d.id);
      log('Message clicked!');
      d3.select(this).selectAll('.d3-rect-message').classed('hidden', false);
    });
  };

  message.updateMessageInPool = function(selection) {
    opts.xScale = pool.xScale().copy();

    selection.select('rect.d3-rect-message')
      .attr({
        x: message.highlightXPosition
      });

    selection.select('image')
      .attr({
        x: message.xPosition
      });
  };

  message.setUpMessageCreation = function() {
    log('Set up message creation listeners.');
    opts.emitter.on('clickTranslatesToDate', function(date) {
      log('Creating message at', date.toISOString().slice(0,-5));
      opts.emitter.emit('createMessage', date.toISOString());
    });

    opts.emitter.on('messageCreated', function(obj) {
      var messageGroup = mainGroup.select('#poolMessages_message')
        .append('g')
        .attr('class', 'd3-message-group d3-new')
        .attr('id', 'message_' + obj.id)
        .datum(obj);
      message.addMessageToPool(messageGroup);
    });

    opts.emitter.on('messageTimestampEdited', function(obj) {
      var messageGroup = mainGroup.select('g#message_' + obj.id)
        .datum(obj);
      message.updateMessageInPool(messageGroup);
    });
  };

  message.highlightXPosition = function(d) {
    return opts.xScale(Date.parse(d.normalTime)) - opts.size / 2 - opts.highlightWidth;
  };

  message.highlightYPosition = function(d) {
    return pool.height() / 2 - opts.size / 2 - opts.highlightWidth;
  };

  message.xPosition = function(d) {
    return opts.xScale(Date.parse(d.normalTime)) - opts.size / 2;
  };

  message.yPosition = function(d) {
    return pool.height() / 2 - opts.size / 2;
  };

  message.setUpMessageCreation();

  return message;
};<commit_msg>make cursor on current messages a pointer (like for a link)<commit_after>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

var d3 = require('../lib/').d3;
var _ = require('../lib/')._;

var log = require('../lib/').bows('Message');

module.exports = function(pool, opts) {

  opts = opts || {};

  var defaults = {
    imagesBaseUrl: pool.imagesBaseUrl(),
    highlightWidth: 4
  };

  _.defaults(opts, defaults);

  var mainGroup = pool.group();

  function message(selection) {
    opts.xScale = pool.xScale().copy();

    selection.each(function(currentData) {
      var messages = d3.select(this)
        .selectAll('g.d3-message-group')
        .data(currentData, function(d) {
          if (d.parentMessage === '' || d.parentMessage == null) {
            return d.id;
          }
        });

      var messageGroups = messages.enter()
        .append('g')
        .attr({
          'class': 'd3-message-group',
          id: function(d) {
            return 'message_' + d.id;
          },
          'clip-path': 'url(#mainClipPath)'
        });

      message.addMessageToPool(messageGroups);

      messages.exit().remove();
    });
  }

  message.addMessageToPool = function(selection) {
    opts.xScale = pool.xScale().copy();

    selection.append('rect')
      .attr({
        x: message.highlightXPosition,
        y: message.highlightYPosition,
        width: opts.size + opts.highlightWidth * 2,
        height: opts.size + opts.highlightWidth * 2,
        'class': 'd3-rect-message hidden'
      });

    selection.append('image')
      .attr({
        'xlink:href': opts.imagesBaseUrl + '/message/post_it.svg',
        cursor: 'pointer',
        x: message.xPosition,
        y: message.yPosition,
        width: opts.size,
        height: opts.size
      })
      .classed({'d3-image': true, 'd3-message': true});

    selection.on('click', function(d) {
      d3.event.stopPropagation(); // silence the click-and-drag listener
      opts.emitter.emit('messageThread', d.id);
      log('Message clicked!');
      d3.select(this).selectAll('.d3-rect-message').classed('hidden', false);
    });
  };

  message.updateMessageInPool = function(selection) {
    opts.xScale = pool.xScale().copy();

    selection.select('rect.d3-rect-message')
      .attr({
        x: message.highlightXPosition
      });

    selection.select('image')
      .attr({
        x: message.xPosition
      });
  };

  message.setUpMessageCreation = function() {
    log('Set up message creation listeners.');
    opts.emitter.on('clickTranslatesToDate', function(date) {
      log('Creating message at', date.toISOString().slice(0,-5));
      opts.emitter.emit('createMessage', date.toISOString());
    });

    opts.emitter.on('messageCreated', function(obj) {
      var messageGroup = mainGroup.select('#poolMessages_message')
        .append('g')
        .attr('class', 'd3-message-group d3-new')
        .attr('id', 'message_' + obj.id)
        .datum(obj);
      message.addMessageToPool(messageGroup);
    });

    opts.emitter.on('messageTimestampEdited', function(obj) {
      var messageGroup = mainGroup.select('g#message_' + obj.id)
        .datum(obj);
      message.updateMessageInPool(messageGroup);
    });
  };

  message.highlightXPosition = function(d) {
    return opts.xScale(Date.parse(d.normalTime)) - opts.size / 2 - opts.highlightWidth;
  };

  message.highlightYPosition = function(d) {
    return pool.height() / 2 - opts.size / 2 - opts.highlightWidth;
  };

  message.xPosition = function(d) {
    return opts.xScale(Date.parse(d.normalTime)) - opts.size / 2;
  };

  message.yPosition = function(d) {
    return pool.height() / 2 - opts.size / 2;
  };

  message.setUpMessageCreation();

  return message;
};<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Route.extend({
  meta: Ember.inject.service(),
  setupController(controller, model) {
    this._super(controller, model);

    this.set("meta.title", 'Post: ' + model.get("title"));
    if(!Ember.isBlank(model.get('description'))) {
      this.set("meta.description", model.get("description"));
    }
  }
});
<commit_msg>getting rid of "post:" preface<commit_after>import Ember from 'ember';

export default Ember.Route.extend({
  meta: Ember.inject.service(),
  setupController(controller, model) {
    this._super(controller, model);

    this.set("meta.title", model.get("title"));
    if(!Ember.isBlank(model.get('description'))) {
      this.set("meta.description", model.get("description"));
    }
  }
});
<|endoftext|>


<commit_before>/**
 * --------------------------------------------------------------------------
 * Bootstrap (v4.4.1): collapse.js
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * --------------------------------------------------------------------------
 */

import $ from 'jquery'
import Util from './util'

/**
 * ------------------------------------------------------------------------
 * Constants
 * ------------------------------------------------------------------------
 */

const NAME                = 'collapse'
const VERSION             = '4.4.1'
const DATA_KEY            = 'bs.collapse'
const EVENT_KEY           = `.${DATA_KEY}`
const DATA_API_KEY        = '.data-api'
const JQUERY_NO_CONFLICT  = $.fn[NAME]

const Default = {
  toggle : true,
  parent : ''
}

const DefaultType = {
  toggle : 'boolean',
  parent : '(string|element)'
}

const EVENT_SHOW           = `show${EVENT_KEY}`
const EVENT_SHOWN          = `shown${EVENT_KEY}`
const EVENT_HIDE           = `hide${EVENT_KEY}`
const EVENT_HIDDEN         = `hidden${EVENT_KEY}`
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`

const CLASS_NAME_SHOW       = 'show'
const CLASS_NAME_COLLAPSE   = 'collapse'
const CLASS_NAME_COLLAPSING = 'collapsing'
const CLASS_NAME_COLLAPSED  = 'collapsed'

const DIMENSION_WIDTH  = 'width'
const DIMENSION_HEIGHT = 'height'

const SELECTOR_ACTIVES     = '.show, .collapsing'
const SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]'

/**
 * ------------------------------------------------------------------------
 * Class Definition
 * ------------------------------------------------------------------------
 */

class Collapse {
  constructor(element, config) {
    this._isTransitioning = false
    this._element         = element
    this._config          = this._getConfig(config)
    this._triggerArray    = [].slice.call(document.querySelectorAll(
      `[data-toggle="collapse"][href="#${element.id}"],` +
      `[data-toggle="collapse"][data-target="#${element.id}"]`
    ))

    const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))
    for (let i = 0, len = toggleList.length; i < len; i++) {
      const elem = toggleList[i]
      const selector = Util.getSelectorFromElement(elem)
      const filterElement = [].slice.call(document.querySelectorAll(selector))
        .filter((foundElem) => foundElem === element)

      if (selector !== null && filterElement.length > 0) {
        this._selector = selector
        this._triggerArray.push(elem)
      }
    }

    this._parent = this._config.parent ? this._getParent() : null

    if (!this._config.parent) {
      this._addAriaAndCollapsedClass(this._element, this._triggerArray)
    }

    if (this._config.toggle) {
      this.toggle()
    }
  }

  // Getters

  static get VERSION() {
    return VERSION
  }

  static get Default() {
    return Default
  }

  // Public

  toggle() {
    if ($(this._element).hasClass(CLASS_NAME_SHOW)) {
      this.hide()
    } else {
      this.show()
    }
  }

  show() {
    if (this._isTransitioning ||
      $(this._element).hasClass(CLASS_NAME_SHOW)) {
      return
    }

    let actives
    let activesData

    if (this._parent) {
      actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))
        .filter((elem) => {
          if (typeof this._config.parent === 'string') {
            return elem.getAttribute('data-parent') === this._config.parent
          }

          return elem.classList.contains(CLASS_NAME_COLLAPSE)
        })

      if (actives.length === 0) {
        actives = null
      }
    }

    if (actives) {
      activesData = $(actives).not(this._selector).data(DATA_KEY)
      if (activesData && activesData._isTransitioning) {
        return
      }
    }

    const startEvent = $.Event(EVENT_SHOW)
    $(this._element).trigger(startEvent)
    if (startEvent.isDefaultPrevented()) {
      return
    }

    if (actives) {
      Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')
      if (!activesData) {
        $(actives).data(DATA_KEY, null)
      }
    }

    const dimension = this._getDimension()

    $(this._element)
      .removeClass(CLASS_NAME_COLLAPSE)
      .addClass(CLASS_NAME_COLLAPSING)

    this._element.style[dimension] = 0

    if (this._triggerArray.length) {
      $(this._triggerArray)
        .removeClass(CLASS_NAME_COLLAPSED)
        .attr('aria-expanded', true)
    }

    this.setTransitioning(true)

    const complete = () => {
      $(this._element)
        .removeClass(CLASS_NAME_COLLAPSING)
        .addClass(CLASS_NAME_COLLAPSE)
        .addClass(CLASS_NAME_SHOW)

      this._element.style[dimension] = ''

      this.setTransitioning(false)

      $(this._element).trigger(EVENT_SHOWN)
    }

    const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
    const scrollSize = `scroll${capitalizedDimension}`
    const transitionDuration = Util.getTransitionDurationFromElement(this._element)

    $(this._element)
      .one(Util.TRANSITION_END, complete)
      .emulateTransitionEnd(transitionDuration)

    this._element.style[dimension] = `${this._element[scrollSize]}px`
  }

  hide() {
    if (this._isTransitioning ||
      !$(this._element).hasClass(CLASS_NAME_SHOW)) {
      return
    }

    const startEvent = $.Event(EVENT_HIDE)
    $(this._element).trigger(startEvent)
    if (startEvent.isDefaultPrevented()) {
      return
    }

    const dimension = this._getDimension()

    this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`

    Util.reflow(this._element)

    $(this._element)
      .addClass(CLASS_NAME_COLLAPSING)
      .removeClass(CLASS_NAME_COLLAPSE)
      .removeClass(CLASS_NAME_SHOW)

    const triggerArrayLength = this._triggerArray.length
    if (triggerArrayLength > 0) {
      for (let i = 0; i < triggerArrayLength; i++) {
        const trigger = this._triggerArray[i]
        const selector = Util.getSelectorFromElement(trigger)

        if (selector !== null) {
          const $elem = $([].slice.call(document.querySelectorAll(selector)))
          if (!$elem.hasClass(CLASS_NAME_SHOW)) {
            $(trigger).addClass(CLASS_NAME_COLLAPSED)
              .attr('aria-expanded', false)
          }
        }
      }
    }

    this.setTransitioning(true)

    const complete = () => {
      this.setTransitioning(false)
      $(this._element)
        .removeClass(CLASS_NAME_COLLAPSING)
        .addClass(CLASS_NAME_COLLAPSE)
        .trigger(EVENT_HIDDEN)
    }

    this._element.style[dimension] = ''
    const transitionDuration = Util.getTransitionDurationFromElement(this._element)

    $(this._element)
      .one(Util.TRANSITION_END, complete)
      .emulateTransitionEnd(transitionDuration)
  }

  setTransitioning(isTransitioning) {
    this._isTransitioning = isTransitioning
  }

  dispose() {
    $.removeData(this._element, DATA_KEY)

    this._config          = null
    this._parent          = null
    this._element         = null
    this._triggerArray    = null
    this._isTransitioning = null
  }

  // Private

  _getConfig(config) {
    config = {
      ...Default,
      ...config
    }
    config.toggle = Boolean(config.toggle) // Coerce string values
    Util.typeCheckConfig(NAME, config, DefaultType)
    return config
  }

  _getDimension() {
    const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)
    return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT
  }

  _getParent() {
    let parent

    if (Util.isElement(this._config.parent)) {
      parent = this._config.parent

      // It's a jQuery object
      if (typeof this._config.parent.jquery !== 'undefined') {
        parent = this._config.parent[0]
      }
    } else {
      parent = document.querySelector(this._config.parent)
    }

    const selector = `[data-toggle="collapse"][data-parent="${this._config.parent}"]`
    const children = [].slice.call(parent.querySelectorAll(selector))

    $(children).each((i, element) => {
      this._addAriaAndCollapsedClass(
        Collapse._getTargetFromElement(element),
        [element]
      )
    })

    return parent
  }

  _addAriaAndCollapsedClass(element, triggerArray) {
    const isOpen = $(element).hasClass(CLASS_NAME_SHOW)

    if (triggerArray.length) {
      $(triggerArray)
        .toggleClass(CLASS_NAME_COLLAPSED, !isOpen)
        .attr('aria-expanded', isOpen)
    }
  }

  // Static

  static _getTargetFromElement(element) {
    const selector = Util.getSelectorFromElement(element)
    return selector ? document.querySelector(selector) : null
  }

  static _jQueryInterface(config) {
    return this.each(function () {
      const $this   = $(this)
      let data      = $this.data(DATA_KEY)
      const _config = {
        ...Default,
        ...$this.data(),
        ...typeof config === 'object' && config ? config : {}
      }

      if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
        _config.toggle = false
      }

      if (!data) {
        data = new Collapse(this, _config)
        $this.data(DATA_KEY, data)
      }

      if (typeof config === 'string') {
        if (typeof data[config] === 'undefined') {
          throw new TypeError(`No method named "${config}"`)
        }
        data[config]()
      }
    })
  }
}

/**
 * ------------------------------------------------------------------------
 * Data Api implementation
 * ------------------------------------------------------------------------
 */

$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
  // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
  if (event.currentTarget.tagName === 'A') {
    event.preventDefault()
  }

  const $trigger = $(this)
  const selector = Util.getSelectorFromElement(this)
  const selectors = [].slice.call(document.querySelectorAll(selector))

  $(selectors).each(function () {
    const $target = $(this)
    const data    = $target.data(DATA_KEY)
    const config  = data ? 'toggle' : $trigger.data()
    Collapse._jQueryInterface.call($target, config)
  })
})

/**
 * ------------------------------------------------------------------------
 * jQuery
 * ------------------------------------------------------------------------
 */

$.fn[NAME] = Collapse._jQueryInterface
$.fn[NAME].Constructor = Collapse
$.fn[NAME].noConflict = () => {
  $.fn[NAME] = JQUERY_NO_CONFLICT
  return Collapse._jQueryInterface
}

export default Collapse
<commit_msg>collapse.js: combine classes<commit_after>/**
 * --------------------------------------------------------------------------
 * Bootstrap (v4.4.1): collapse.js
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * --------------------------------------------------------------------------
 */

import $ from 'jquery'
import Util from './util'

/**
 * ------------------------------------------------------------------------
 * Constants
 * ------------------------------------------------------------------------
 */

const NAME                = 'collapse'
const VERSION             = '4.4.1'
const DATA_KEY            = 'bs.collapse'
const EVENT_KEY           = `.${DATA_KEY}`
const DATA_API_KEY        = '.data-api'
const JQUERY_NO_CONFLICT  = $.fn[NAME]

const Default = {
  toggle : true,
  parent : ''
}

const DefaultType = {
  toggle : 'boolean',
  parent : '(string|element)'
}

const EVENT_SHOW           = `show${EVENT_KEY}`
const EVENT_SHOWN          = `shown${EVENT_KEY}`
const EVENT_HIDE           = `hide${EVENT_KEY}`
const EVENT_HIDDEN         = `hidden${EVENT_KEY}`
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`

const CLASS_NAME_SHOW       = 'show'
const CLASS_NAME_COLLAPSE   = 'collapse'
const CLASS_NAME_COLLAPSING = 'collapsing'
const CLASS_NAME_COLLAPSED  = 'collapsed'

const DIMENSION_WIDTH  = 'width'
const DIMENSION_HEIGHT = 'height'

const SELECTOR_ACTIVES     = '.show, .collapsing'
const SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]'

/**
 * ------------------------------------------------------------------------
 * Class Definition
 * ------------------------------------------------------------------------
 */

class Collapse {
  constructor(element, config) {
    this._isTransitioning = false
    this._element         = element
    this._config          = this._getConfig(config)
    this._triggerArray    = [].slice.call(document.querySelectorAll(
      `[data-toggle="collapse"][href="#${element.id}"],` +
      `[data-toggle="collapse"][data-target="#${element.id}"]`
    ))

    const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))
    for (let i = 0, len = toggleList.length; i < len; i++) {
      const elem = toggleList[i]
      const selector = Util.getSelectorFromElement(elem)
      const filterElement = [].slice.call(document.querySelectorAll(selector))
        .filter((foundElem) => foundElem === element)

      if (selector !== null && filterElement.length > 0) {
        this._selector = selector
        this._triggerArray.push(elem)
      }
    }

    this._parent = this._config.parent ? this._getParent() : null

    if (!this._config.parent) {
      this._addAriaAndCollapsedClass(this._element, this._triggerArray)
    }

    if (this._config.toggle) {
      this.toggle()
    }
  }

  // Getters

  static get VERSION() {
    return VERSION
  }

  static get Default() {
    return Default
  }

  // Public

  toggle() {
    if ($(this._element).hasClass(CLASS_NAME_SHOW)) {
      this.hide()
    } else {
      this.show()
    }
  }

  show() {
    if (this._isTransitioning ||
      $(this._element).hasClass(CLASS_NAME_SHOW)) {
      return
    }

    let actives
    let activesData

    if (this._parent) {
      actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))
        .filter((elem) => {
          if (typeof this._config.parent === 'string') {
            return elem.getAttribute('data-parent') === this._config.parent
          }

          return elem.classList.contains(CLASS_NAME_COLLAPSE)
        })

      if (actives.length === 0) {
        actives = null
      }
    }

    if (actives) {
      activesData = $(actives).not(this._selector).data(DATA_KEY)
      if (activesData && activesData._isTransitioning) {
        return
      }
    }

    const startEvent = $.Event(EVENT_SHOW)
    $(this._element).trigger(startEvent)
    if (startEvent.isDefaultPrevented()) {
      return
    }

    if (actives) {
      Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')
      if (!activesData) {
        $(actives).data(DATA_KEY, null)
      }
    }

    const dimension = this._getDimension()

    $(this._element)
      .removeClass(CLASS_NAME_COLLAPSE)
      .addClass(CLASS_NAME_COLLAPSING)

    this._element.style[dimension] = 0

    if (this._triggerArray.length) {
      $(this._triggerArray)
        .removeClass(CLASS_NAME_COLLAPSED)
        .attr('aria-expanded', true)
    }

    this.setTransitioning(true)

    const complete = () => {
      $(this._element)
        .removeClass(CLASS_NAME_COLLAPSING)
        .addClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)

      this._element.style[dimension] = ''

      this.setTransitioning(false)

      $(this._element).trigger(EVENT_SHOWN)
    }

    const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
    const scrollSize = `scroll${capitalizedDimension}`
    const transitionDuration = Util.getTransitionDurationFromElement(this._element)

    $(this._element)
      .one(Util.TRANSITION_END, complete)
      .emulateTransitionEnd(transitionDuration)

    this._element.style[dimension] = `${this._element[scrollSize]}px`
  }

  hide() {
    if (this._isTransitioning ||
      !$(this._element).hasClass(CLASS_NAME_SHOW)) {
      return
    }

    const startEvent = $.Event(EVENT_HIDE)
    $(this._element).trigger(startEvent)
    if (startEvent.isDefaultPrevented()) {
      return
    }

    const dimension = this._getDimension()

    this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`

    Util.reflow(this._element)

    $(this._element)
      .addClass(CLASS_NAME_COLLAPSING)
      .removeClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)

    const triggerArrayLength = this._triggerArray.length
    if (triggerArrayLength > 0) {
      for (let i = 0; i < triggerArrayLength; i++) {
        const trigger = this._triggerArray[i]
        const selector = Util.getSelectorFromElement(trigger)

        if (selector !== null) {
          const $elem = $([].slice.call(document.querySelectorAll(selector)))
          if (!$elem.hasClass(CLASS_NAME_SHOW)) {
            $(trigger).addClass(CLASS_NAME_COLLAPSED)
              .attr('aria-expanded', false)
          }
        }
      }
    }

    this.setTransitioning(true)

    const complete = () => {
      this.setTransitioning(false)
      $(this._element)
        .removeClass(CLASS_NAME_COLLAPSING)
        .addClass(CLASS_NAME_COLLAPSE)
        .trigger(EVENT_HIDDEN)
    }

    this._element.style[dimension] = ''
    const transitionDuration = Util.getTransitionDurationFromElement(this._element)

    $(this._element)
      .one(Util.TRANSITION_END, complete)
      .emulateTransitionEnd(transitionDuration)
  }

  setTransitioning(isTransitioning) {
    this._isTransitioning = isTransitioning
  }

  dispose() {
    $.removeData(this._element, DATA_KEY)

    this._config          = null
    this._parent          = null
    this._element         = null
    this._triggerArray    = null
    this._isTransitioning = null
  }

  // Private

  _getConfig(config) {
    config = {
      ...Default,
      ...config
    }
    config.toggle = Boolean(config.toggle) // Coerce string values
    Util.typeCheckConfig(NAME, config, DefaultType)
    return config
  }

  _getDimension() {
    const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)
    return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT
  }

  _getParent() {
    let parent

    if (Util.isElement(this._config.parent)) {
      parent = this._config.parent

      // It's a jQuery object
      if (typeof this._config.parent.jquery !== 'undefined') {
        parent = this._config.parent[0]
      }
    } else {
      parent = document.querySelector(this._config.parent)
    }

    const selector = `[data-toggle="collapse"][data-parent="${this._config.parent}"]`
    const children = [].slice.call(parent.querySelectorAll(selector))

    $(children).each((i, element) => {
      this._addAriaAndCollapsedClass(
        Collapse._getTargetFromElement(element),
        [element]
      )
    })

    return parent
  }

  _addAriaAndCollapsedClass(element, triggerArray) {
    const isOpen = $(element).hasClass(CLASS_NAME_SHOW)

    if (triggerArray.length) {
      $(triggerArray)
        .toggleClass(CLASS_NAME_COLLAPSED, !isOpen)
        .attr('aria-expanded', isOpen)
    }
  }

  // Static

  static _getTargetFromElement(element) {
    const selector = Util.getSelectorFromElement(element)
    return selector ? document.querySelector(selector) : null
  }

  static _jQueryInterface(config) {
    return this.each(function () {
      const $this   = $(this)
      let data      = $this.data(DATA_KEY)
      const _config = {
        ...Default,
        ...$this.data(),
        ...typeof config === 'object' && config ? config : {}
      }

      if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
        _config.toggle = false
      }

      if (!data) {
        data = new Collapse(this, _config)
        $this.data(DATA_KEY, data)
      }

      if (typeof config === 'string') {
        if (typeof data[config] === 'undefined') {
          throw new TypeError(`No method named "${config}"`)
        }
        data[config]()
      }
    })
  }
}

/**
 * ------------------------------------------------------------------------
 * Data Api implementation
 * ------------------------------------------------------------------------
 */

$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
  // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
  if (event.currentTarget.tagName === 'A') {
    event.preventDefault()
  }

  const $trigger = $(this)
  const selector = Util.getSelectorFromElement(this)
  const selectors = [].slice.call(document.querySelectorAll(selector))

  $(selectors).each(function () {
    const $target = $(this)
    const data    = $target.data(DATA_KEY)
    const config  = data ? 'toggle' : $trigger.data()
    Collapse._jQueryInterface.call($target, config)
  })
})

/**
 * ------------------------------------------------------------------------
 * jQuery
 * ------------------------------------------------------------------------
 */

$.fn[NAME] = Collapse._jQueryInterface
$.fn[NAME].Constructor = Collapse
$.fn[NAME].noConflict = () => {
  $.fn[NAME] = JQUERY_NO_CONFLICT
  return Collapse._jQueryInterface
}

export default Collapse
<|endoftext|>


<commit_before>'use strict';

$(document).ready(function() {
	// Sortable init
	$('table.sortable tbody').sortable({
		helper: fixWidthHelper
	}).disableSelection();

	// Helper to keep full width of sortable tr's
	function fixWidthHelper(e, ui) {
		ui.children().each(function() {
			$(this).width($(this).width());
		});

		return ui;
	}

	// If desktop AND cookie says so - show left nav
	if ($(window).width() > 768 && Cookies.get('leftNav') === '1') {
		location.hash = 'main_nav';
	}

	// If click hamburger AND left nav is hidden - set cookie AND show left nav
	$('a.open_menu').on('click', function(event) {
		event.preventDefault();
		Cookies.set('leftNav', '1');
		location.hash = 'main_nav';

		// Make sure stuff in the right place after DOM change
		if (typeof doResizeActions === 'function') {
			doResizeActions();
		}
	});

	// If click hamburger AND left nav is visible - remove cookie AND hide left nav
	$('a.close_menu').on('click', function(event) {
		event.preventDefault();
		Cookies.remove('leftNav');
		location.hash = '';

		// Make sure stuff in the right place after DOM change
		if (typeof doResizeActions === 'function') {
			doResizeActions();
		}
	});

	// Close msg_box
	window.addMsgBoxClose = function() {
		$('.msg_box a.close').on('click', function(event) {
			event.preventDefault();
			$(this).closest('.msg_box').remove();
		});
	};

	// Init close msg_box
	addMsgBoxClose();

	$('.cp_nav').each(function(item) {
		if (Cookies.get($(this).attr('id')) !== undefined)
		//$(item).removeAttr('checked');
	});
});<commit_msg>cookies storing closed state main nav top lvls<commit_after>'use strict';

$(document).ready(function() {
	// Sortable init
	$('table.sortable tbody').sortable({
		helper: fixWidthHelper
	}).disableSelection();

	// Helper to keep full width of sortable tr's
	function fixWidthHelper(e, ui) {
		ui.children().each(function() {
			$(this).width($(this).width());
		});

		return ui;
	}

	// If desktop AND cookie says so - show left nav
	if ($(window).width() > 768 && Cookies.get('leftNav') === '1') {
		location.hash = 'main_nav';
	}

	// If click hamburger AND left nav is hidden - set cookie AND show left nav
	$('a.open_menu').on('click', function(event) {
		event.preventDefault();
		Cookies.set('leftNav', '1');
		location.hash = 'main_nav';

		// Make sure stuff in the right place after DOM change
		if (typeof doResizeActions === 'function') {
			doResizeActions();
		}
	});

	// If click hamburger AND left nav is visible - remove cookie AND hide left nav
	$('a.close_menu').on('click', function(event) {
		event.preventDefault();
		Cookies.remove('leftNav');
		location.hash = '';

		// Make sure stuff in the right place after DOM change
		if (typeof doResizeActions === 'function') {
			doResizeActions();
		}
	});

	// Close msg_box
	window.addMsgBoxClose = function() {
		$('.msg_box a.close').on('click', function(event) {
			event.preventDefault();
			$(this).closest('.msg_box').remove();
		});
	};

	// Init close msg_box
	addMsgBoxClose();

	// Cookies storing closed state main nav top lvls
	$('.cp_nav').each(function() {
		// If cookie says so, collapse this item
		if (Cookies.get($(this).attr('id')) === '1') {
			$(this).removeAttr('checked');
		}
		$(this).on('click', function() {
			if ($(this).is(':checked')) {
				// If cookie with this id exists, remove it
				Cookies.remove($(this).attr('id'));
			} else {
				// Store cookie to keep this item collapsed
				Cookies.set($(this).attr('id'), '1');
			}
		});
	});

});<|endoftext|>


<commit_before>import Util from './util'

/**
 * --------------------------------------------------------------------------
 * Bootstrap (v4.0.0): dropdown.js
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * --------------------------------------------------------------------------
 */

const Dropdown = (($) => {

  /**
   * ------------------------------------------------------------------------
   * Constants
   * ------------------------------------------------------------------------
   */

  const NAME                = 'dropdown'
  const VERSION             = '4.0.0'
  const DATA_KEY            = 'bs.dropdown'
  const EVENT_KEY           = `.${DATA_KEY}`
  const DATA_API_KEY        = '.data-api'
  const JQUERY_NO_CONFLICT  = $.fn[NAME]

  const Event = {
    HIDE             : `hide${EVENT_KEY}`,
    HIDDEN           : `hidden${EVENT_KEY}`,
    SHOW             : `show${EVENT_KEY}`,
    SHOWN            : `shown${EVENT_KEY}`,
    CLICK            : `click${EVENT_KEY}`,
    CLICK_DATA_API   : `click${EVENT_KEY}${DATA_API_KEY}`,
    KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`
  }

  const ClassName = {
    BACKDROP : 'dropdown-backdrop',
    DISABLED : 'disabled',
    OPEN     : 'open'
  }

  const Selector = {
    BACKDROP      : '.dropdown-backdrop',
    DATA_TOGGLE   : '[data-toggle="dropdown"]',
    FORM_CHILD    : '.dropdown form',
    ROLE_MENU     : '[role="menu"]',
    ROLE_LISTBOX  : '[role="listbox"]',
    NAVBAR_NAV    : '.navbar-nav',
    VISIBLE_ITEMS : '[role="menu"] li:not(.disabled) a, '
                  + '[role="listbox"] li:not(.disabled) a'
  }

  /**
   * ------------------------------------------------------------------------
   * Class Definition
   * ------------------------------------------------------------------------
   */

  class Dropdown {

    constructor(element) {
      this._element = element

      this._addEventListeners()
    }

    // getters

    static get VERSION() {
      return VERSION
    }

    // public

    toggle() {
      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
        return false
      }

      let parent   = Dropdown._getParentFromElement(this)
      let isActive = $(parent).hasClass(ClassName.OPEN)

      Dropdown._clearMenus()

      if (isActive) {
        return false
      }

      if ('ontouchstart' in document.documentElement &&
         (!$(parent).closest(Selector.NAVBAR_NAV).length)) {

        // if mobile we use a backdrop because click events don't delegate
        let dropdown       = document.createElement('div')
        dropdown.className = ClassName.BACKDROP
        $(dropdown).insertBefore(this)
        $(dropdown).on('click', Dropdown._clearMenus)
      }

      let relatedTarget = { relatedTarget : this }
      let showEvent     = $.Event(Event.SHOW, relatedTarget)

      $(parent).trigger(showEvent)

      if (showEvent.isDefaultPrevented()) {
        return false
      }

      this.focus()
      this.setAttribute('aria-expanded', 'true')

      $(parent).toggleClass(ClassName.OPEN)
      $(parent).trigger($.Event(Event.SHOWN, relatedTarget))

      return false
    }

    dispose() {
      $.removeData(this._element, DATA_KEY)
      $(this._element).off(EVENT_KEY)
      this._element = null
    }

    // private

    _addEventListeners() {
      $(this._element).on(Event.CLICK, this.toggle)
    }

    // static

    static _jQueryInterface(config) {
      return this.each(function () {
        let data  = $(this).data(DATA_KEY)

        if (!data) {
          $(this).data(DATA_KEY, (data = new Dropdown(this)))
        }

        if (typeof config === 'string') {
          if (data[config] === undefined) {
            throw new Error(`No method named "${config}"`)
          }
          data[config].call(this)
        }
      })
    }

    static _clearMenus(event) {
      if (event && event.which === 3) {
        return
      }

      let backdrop = $(Selector.BACKDROP)[0]
      if (backdrop) {
        backdrop.parentNode.removeChild(backdrop)
      }

      let toggles = $.makeArray($(Selector.DATA_TOGGLE))

      for (let i = 0; i < toggles.length; i++) {
        let parent        = Dropdown._getParentFromElement(toggles[i])
        let relatedTarget = { relatedTarget : toggles[i] }

        if (!$(parent).hasClass(ClassName.OPEN)) {
          continue
        }

        if (event && event.type === 'click' &&
           (/input|textarea/i.test(event.target.tagName)) &&
           ($.contains(parent, event.target))) {
          continue
        }

        let hideEvent = $.Event(Event.HIDE, relatedTarget)
        $(parent).trigger(hideEvent)
        if (hideEvent.isDefaultPrevented()) {
          continue
        }

        toggles[i].setAttribute('aria-expanded', 'false')

        $(parent)
          .removeClass(ClassName.OPEN)
          .trigger($.Event(Event.HIDDEN, relatedTarget))
      }
    }

    static _getParentFromElement(element) {
      let parent
      let selector = Util.getSelectorFromElement(element)

      if (selector) {
        parent = $(selector)[0]
      }

      return parent || element.parentNode
    }

    static _dataApiKeydownHandler(event) {
      if (!/(38|40|27|32)/.test(event.which) ||
         /input|textarea/i.test(event.target.tagName)) {
        return
      }

      event.preventDefault()
      event.stopPropagation()

      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
        return
      }

      let parent   = Dropdown._getParentFromElement(this)
      let isActive = $(parent).hasClass(ClassName.OPEN)

      if ((!isActive && event.which !== 27) ||
           (isActive && event.which === 27)) {

        if (event.which === 27) {
          let toggle = $(parent).find(Selector.DATA_TOGGLE)[0]
          $(toggle).trigger('focus')
        }

        $(this).trigger('click')
        return
      }

      let items = $.makeArray($(Selector.VISIBLE_ITEMS))

      items = items.filter((item) => {
        return item.offsetWidth || item.offsetHeight
      })

      if (!items.length) {
        return
      }

      let index = items.indexOf(event.target)

      if (event.which === 38 && index > 0) { // up
        index--
      }

      if (event.which === 40 && index < items.length - 1) { // down
        index++
      }

      if (!~index) {
        index = 0
      }

      items[index].focus()
    }

  }

  /**
   * ------------------------------------------------------------------------
   * Data Api implementation
   * ------------------------------------------------------------------------
   */

  $(document)
    .on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE,  Dropdown._dataApiKeydownHandler)
    .on(Event.KEYDOWN_DATA_API, Selector.ROLE_MENU,    Dropdown._dataApiKeydownHandler)
    .on(Event.KEYDOWN_DATA_API, Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler)
    .on(Event.CLICK_DATA_API, Dropdown._clearMenus)
    .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, Dropdown.prototype.toggle)
    .on(Event.CLICK_DATA_API, Selector.FORM_CHILD, (e) => {
      e.stopPropagation()
    })

  /**
   * ------------------------------------------------------------------------
   * jQuery
   * ------------------------------------------------------------------------
   */

  $.fn[NAME]             = Dropdown._jQueryInterface
  $.fn[NAME].Constructor = Dropdown
  $.fn[NAME].noConflict  = function () {
    $.fn[NAME] = JQUERY_NO_CONFLICT
    return Dropdown._jQueryInterface
  }

  return Dropdown

})(jQuery)

export default Dropdown
<commit_msg>dropdown.js: Use more straightforward phrasing for index lower bound check<commit_after>import Util from './util'

/**
 * --------------------------------------------------------------------------
 * Bootstrap (v4.0.0): dropdown.js
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * --------------------------------------------------------------------------
 */

const Dropdown = (($) => {

  /**
   * ------------------------------------------------------------------------
   * Constants
   * ------------------------------------------------------------------------
   */

  const NAME                = 'dropdown'
  const VERSION             = '4.0.0'
  const DATA_KEY            = 'bs.dropdown'
  const EVENT_KEY           = `.${DATA_KEY}`
  const DATA_API_KEY        = '.data-api'
  const JQUERY_NO_CONFLICT  = $.fn[NAME]

  const Event = {
    HIDE             : `hide${EVENT_KEY}`,
    HIDDEN           : `hidden${EVENT_KEY}`,
    SHOW             : `show${EVENT_KEY}`,
    SHOWN            : `shown${EVENT_KEY}`,
    CLICK            : `click${EVENT_KEY}`,
    CLICK_DATA_API   : `click${EVENT_KEY}${DATA_API_KEY}`,
    KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`
  }

  const ClassName = {
    BACKDROP : 'dropdown-backdrop',
    DISABLED : 'disabled',
    OPEN     : 'open'
  }

  const Selector = {
    BACKDROP      : '.dropdown-backdrop',
    DATA_TOGGLE   : '[data-toggle="dropdown"]',
    FORM_CHILD    : '.dropdown form',
    ROLE_MENU     : '[role="menu"]',
    ROLE_LISTBOX  : '[role="listbox"]',
    NAVBAR_NAV    : '.navbar-nav',
    VISIBLE_ITEMS : '[role="menu"] li:not(.disabled) a, '
                  + '[role="listbox"] li:not(.disabled) a'
  }

  /**
   * ------------------------------------------------------------------------
   * Class Definition
   * ------------------------------------------------------------------------
   */

  class Dropdown {

    constructor(element) {
      this._element = element

      this._addEventListeners()
    }

    // getters

    static get VERSION() {
      return VERSION
    }

    // public

    toggle() {
      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
        return false
      }

      let parent   = Dropdown._getParentFromElement(this)
      let isActive = $(parent).hasClass(ClassName.OPEN)

      Dropdown._clearMenus()

      if (isActive) {
        return false
      }

      if ('ontouchstart' in document.documentElement &&
         (!$(parent).closest(Selector.NAVBAR_NAV).length)) {

        // if mobile we use a backdrop because click events don't delegate
        let dropdown       = document.createElement('div')
        dropdown.className = ClassName.BACKDROP
        $(dropdown).insertBefore(this)
        $(dropdown).on('click', Dropdown._clearMenus)
      }

      let relatedTarget = { relatedTarget : this }
      let showEvent     = $.Event(Event.SHOW, relatedTarget)

      $(parent).trigger(showEvent)

      if (showEvent.isDefaultPrevented()) {
        return false
      }

      this.focus()
      this.setAttribute('aria-expanded', 'true')

      $(parent).toggleClass(ClassName.OPEN)
      $(parent).trigger($.Event(Event.SHOWN, relatedTarget))

      return false
    }

    dispose() {
      $.removeData(this._element, DATA_KEY)
      $(this._element).off(EVENT_KEY)
      this._element = null
    }

    // private

    _addEventListeners() {
      $(this._element).on(Event.CLICK, this.toggle)
    }

    // static

    static _jQueryInterface(config) {
      return this.each(function () {
        let data  = $(this).data(DATA_KEY)

        if (!data) {
          $(this).data(DATA_KEY, (data = new Dropdown(this)))
        }

        if (typeof config === 'string') {
          if (data[config] === undefined) {
            throw new Error(`No method named "${config}"`)
          }
          data[config].call(this)
        }
      })
    }

    static _clearMenus(event) {
      if (event && event.which === 3) {
        return
      }

      let backdrop = $(Selector.BACKDROP)[0]
      if (backdrop) {
        backdrop.parentNode.removeChild(backdrop)
      }

      let toggles = $.makeArray($(Selector.DATA_TOGGLE))

      for (let i = 0; i < toggles.length; i++) {
        let parent        = Dropdown._getParentFromElement(toggles[i])
        let relatedTarget = { relatedTarget : toggles[i] }

        if (!$(parent).hasClass(ClassName.OPEN)) {
          continue
        }

        if (event && event.type === 'click' &&
           (/input|textarea/i.test(event.target.tagName)) &&
           ($.contains(parent, event.target))) {
          continue
        }

        let hideEvent = $.Event(Event.HIDE, relatedTarget)
        $(parent).trigger(hideEvent)
        if (hideEvent.isDefaultPrevented()) {
          continue
        }

        toggles[i].setAttribute('aria-expanded', 'false')

        $(parent)
          .removeClass(ClassName.OPEN)
          .trigger($.Event(Event.HIDDEN, relatedTarget))
      }
    }

    static _getParentFromElement(element) {
      let parent
      let selector = Util.getSelectorFromElement(element)

      if (selector) {
        parent = $(selector)[0]
      }

      return parent || element.parentNode
    }

    static _dataApiKeydownHandler(event) {
      if (!/(38|40|27|32)/.test(event.which) ||
         /input|textarea/i.test(event.target.tagName)) {
        return
      }

      event.preventDefault()
      event.stopPropagation()

      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
        return
      }

      let parent   = Dropdown._getParentFromElement(this)
      let isActive = $(parent).hasClass(ClassName.OPEN)

      if ((!isActive && event.which !== 27) ||
           (isActive && event.which === 27)) {

        if (event.which === 27) {
          let toggle = $(parent).find(Selector.DATA_TOGGLE)[0]
          $(toggle).trigger('focus')
        }

        $(this).trigger('click')
        return
      }

      let items = $.makeArray($(Selector.VISIBLE_ITEMS))

      items = items.filter((item) => {
        return item.offsetWidth || item.offsetHeight
      })

      if (!items.length) {
        return
      }

      let index = items.indexOf(event.target)

      if (event.which === 38 && index > 0) { // up
        index--
      }

      if (event.which === 40 && index < items.length - 1) { // down
        index++
      }

      if (index < 0) {
        index = 0
      }

      items[index].focus()
    }

  }

  /**
   * ------------------------------------------------------------------------
   * Data Api implementation
   * ------------------------------------------------------------------------
   */

  $(document)
    .on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE,  Dropdown._dataApiKeydownHandler)
    .on(Event.KEYDOWN_DATA_API, Selector.ROLE_MENU,    Dropdown._dataApiKeydownHandler)
    .on(Event.KEYDOWN_DATA_API, Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler)
    .on(Event.CLICK_DATA_API, Dropdown._clearMenus)
    .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, Dropdown.prototype.toggle)
    .on(Event.CLICK_DATA_API, Selector.FORM_CHILD, (e) => {
      e.stopPropagation()
    })

  /**
   * ------------------------------------------------------------------------
   * jQuery
   * ------------------------------------------------------------------------
   */

  $.fn[NAME]             = Dropdown._jQueryInterface
  $.fn[NAME].Constructor = Dropdown
  $.fn[NAME].noConflict  = function () {
    $.fn[NAME] = JQUERY_NO_CONFLICT
    return Dropdown._jQueryInterface
  }

  return Dropdown

})(jQuery)

export default Dropdown
<|endoftext|>


<commit_before>var socket = io.connect('http://localhost:3000');

FastClick.attach(document.body);

$('html').bind('keypress', function(e) {
   if(e.keyCode == 13) {
      return false;
   }
});

$('.js-ip-config').bind('click', function(e) {
    e.preventDefault();
    showIpConfig();
});

if(localStorage.getItem('ipAddress') === null) {
    showIpConfig();
} else {
    socket.emit('setIpAddress', localStorage.getItem('ipAddress'));
    start();
}

function showIpConfig() {
    $("#ipModal").modal();
    $(".js-ip-save").on("click", function(e) {
        e.preventDefault();

        socket.emit('setIpAddress', $('#ipField').val());
        socket.on('ipAddressSetResult', function (result) {
            if(result.ip) {
                localStorage.setItem('ipAddress', ipAddress);
                $("#ipModal").modal("hide");
            } else if (result.error) {
                alert("Invalid IP address");
            }
        });
    });
}

function start() {
    $(".btn-action").on("click", function(e) {
        e.preventDefault();
        $(this).blur();

        socket.emit('action', {action: $(this).data('action')});
    });

    socket.on('volume', function(result) {
        $(".vol").text("Volume - " + result.volume);
    });
}
<commit_msg>Use vanilla JS selectors and event listeners<commit_after>var socket = io.connect(window.location.href);

var ipConfigButton = document.querySelector('.js-ip-config')
    , actionButtons = document.querySelectorAll('.btn-action')
    , ipModal = document.querySelector('#ipModal')
    , ipModalField = document.querySelector('#ipField')
    , ipModalSave = document.querySelector('.js-ip-save')
    , statusText = document.querySelector('.vol')

// Helper event function
function addEvent(evnt, elem, func) {
    if (elem.addEventListener) {
        elem.addEventListener(evnt, func, false);
    } else if (elem.attachEvent) {
        elem.attachEvent("on" + evnt, func);
    } else {
        elem[evnt] = func;
    }
}

FastClick.attach(document.body);

addEvent('keypress', document, function(e) {
   if(e.keyCode == 13) {
      return false;
   }
});

addEvent("click", ipConfigButton, function(e) {
    e.preventDefault();
    showIpConfig();
});

if(localStorage.getItem('ipAddress') === null) {
    showIpConfig();
} else {
    socket.emit('setIpAddress', localStorage.getItem('ipAddress'));
    start();
}

function showIpConfig() {
    $("ipModal").modal();
    addEvent('click', ipModalSave, function(e) {
        e.preventDefault();

        socket.emit('setIpAddress', ipModalField.value);
        socket.on('ipAddressSetResult', function (result) {
            if(result.ip) {
                localStorage.setItem('ipAddress', ipAddress);
                $("#ipModal").modal("hide");
            } else if (result.error) {
                alert("Invalid IP address");
            }
        });
    });
}

function start() {
    Array.prototype.forEach.call(actionButtons, function(button) {
        addEvent('click', button, function(e) {
            e.preventDefault();
            button.blur();

            socket.emit('action', { action: button.getAttribute('data-action') });
        });
    });

    socket.on('volume', function(result) {
        statusText.textContent = "Volume - " + result.volume;
    });
}
<|endoftext|>


<commit_before>jQuery.fn.extend({
    disable: function(state) {
        return this.each(function() {
            this.disabled = state;
        });
    }
});
var content = "<form id = 'form' method = 'post' action = '" + baseURL + "/scaffold/guipost/'><input type = 'hidden' name = '_token' value = '" + token + "'>\

\

\

\
            <input id = 'TableName' name='TableName' required='' aria-required='true' type='text'>\
            TableName	\

\

\

\
        <button type = 'submit' class = 'val btn green col s12'>doneDone</button>
\
        </form>";

var i = 0;

var j = 0;

function option(i) {
    var options = '
\
    <select id = "opt' + i + '" name = "opt' + i + '">\
        <option value = "String">String</option>\
        <option value = "longText">longText</option>\
        <option value = "Date">Date</option>\
        <option value = "boolean">boolean</option>\
        <option value = "binary">binary</option>\
        <option value = "float">float</option>\
        <option value = "integer">integer</option>\
        <option value = "bigInteger">bigInteger</option>\
        <option value = "json">json</option>\
     </select>\
    Select Type\

'
    return options;
}

function relation(i)
{
    var relations = '
\
    <select id = "tbl' + i+'" name = "tbl' + i+'">\
        ';
jQuery.each(TableData, function(index, item) {
    relations += '<option value = "'+index+'">'+index+'</option>'
});
    relations +='\
     </select>\
    Select Model\

';
    return relations;

}

var actions = "
\

Rows
\

\
               addnew\
               deleteremove\
               layersready\

";

$(document).on('click', '.createNewTable', function() {
    $('.new').html(content);
    $('.actions').html(actions);
    $('#form').validate();
    $('.val').hide();
    $('.readyy').hide();

})

$(document).on('click', '.newattr', function() {
    $('select').material_select();
    $('.t tr:last').after("
" + option(i) + "
<input id = 'atr" + i + "' name = 'atr" + i + "' type='text' class='validate' required = '' aria-required = 'true'>Attribute

\
    ")
    i++;
    $('select').material_select();
    $('.readyy').show();
})

$(document).on('click', '.readyy', function() {
    $('.val').show();
    $('.actionRow').html('')
    $('.actionRow').html("arrow_backback\
        device_hubOne To Many
");
})

$(document).on('click','.relations',function(){

    $('.t tr:last').after("
"+relation(j)+"
<input id = 'on" + j + "' name = 'on" + j + "' type='text' class='validate' required = '' aria-required = 'true'>On Column

");
    j++;
    $('select').material_select();
})

$(document).on('click', '.rmattr', function() {
    $('.t tr:last').remove();
})

$(document).on('click', '.editt', function() {
    $('.actions').html(actions);
    $('.val').hide();
})

$(document).ready(function() {
    $('.valide').hide();
    $('.newattr').hide();
    $('.rmattr').hide();
    $('.rollback').hide();
    $('select').material_select();
});

$(document).on('dblclick', '.msg', function() {
    $('.msg').remove();
});

$.validator.setDefaults({
    errorClass: 'invalid',
    validClass: "valid",
    errorPlacement: function(error, element) {
        $(element).closest("#form").find("label[for='" + element.attr("id") + "']").attr('data-error', error.text());
    }
});

$("#form").validate({
    rules: {
        dateField: {
            date: true
        }
    }
});
<commit_msg>add select to spec data<commit_after>jQuery.fn.extend({
    disable: function(state) {
        return this.each(function() {
            this.disabled = state;
        });
    }
});
var content = "<form id = 'form' method = 'post' action = '" + baseURL + "/scaffold/guipost/'><input type = 'hidden' name = '_token' value = '" + token + "'>\

\

\

\
            <input id = 'TableName' name='TableName' required='' aria-required='true' type='text'>\
            TableName	\

\

\

\
        <button type = 'submit' class = 'val btn green col s12'>doneDone</button>
\
        </form>";
var i = 0;
var j = 0;

function option(i) {
    var options = '
\
    <select id = "opt' + i + '" name = "opt' + i + '" data-id = "' + i + '">\
        <option value = "String">String</option>\
        <option value = "longText">longText</option>\
        <option value = "Date">Date</option>\
        <option value = "boolean">boolean</option>\
        <option value = "binary">binary</option>\
        <option value = "float">float</option>\
        <option value = "integer">integer</option>\
        <option value = "bigInteger">bigInteger</option>\
        <option value = "json">json</option>\
     </select>\
    Select Type\

'
    return options;
}

function relation(i) {
    var relations = '
\
    <select id = "tbl' + i + '" name = "tbl' + i + '" class = "parent" data-id = "' + i + '">\
        ';
    jQuery.each(TableData, function(index, item) {
        relations += '<option value = "' + index + '">' + index + '</option>'
    });
    relations += '\
     </select>\
    Select Model\

';
    return relations;
}
var actions = "
\

Rows
\

\
               addnew\
               deleteremove\
               layersready\

";
$(document).on('click', '.createNewTable', function() {
    $('.new').html(content);
    $('.actions').html(actions);
    $('#form').validate();
    $('.val').hide();
    $('.readyy').hide();
})
$(document).on('click', '.newattr', function() {
    $('select').material_select();
    $('.t tr:last').after("
" + option(i) + "
<input id = 'atr" + i + "' name = 'atr" + i + "' type='text' class='validate' required = '' aria-required = 'true'>Attribute

\
    ")
    i++;
    $('select').material_select();
    $('.readyy').show();
})
$(document).on('click', '.readyy', function() {
    $('.val').show();
    $('.actionRow').html('')
    $('.actionRow').html("arrow_backback\
        device_hubOne To Many
");
})
$(document).on('click', '.relations', function() {
    $('.t tr:last').after("
" + relation(j) + "
<select class = 'class' id = 'on" + j + "' name = 'on" + j + "'><option></option>Select Attributes</select>

");
    j++;
    $('select').material_select();
})
$(document).on('click', '.rmattr', function() {
    $('.t tr:last').remove();
})
$(document).on('click', '.editt', function() {
    $('.actions').html(actions);
    $('.val').hide();
})
$(document).ready(function() {
    $('.valide').hide();
    $('.newattr').hide();
    $('.rmattr').hide();
    $('.rollback').hide();
    $('select').material_select();
});
$(document).on('dblclick', '.msg', function() {
    $('.msg').remove();
});
$.validator.setDefaults({
    errorClass: 'invalid',
    validClass: "valid",
    errorPlacement: function(error, element) {
        $(element).closest("#form").find("label[for='" + element.attr("id") + "']").attr('data-error', error.text());
    }
});
$("#form").validate({
    rules: {
        dateField: {
            date: true
        }
    }
});
/*************************************TEST - TEST - TEST ************************/
$(document).on("change", ".parent", function() {
    var value = $(this).val()
    var id = $(this).data('id')
    $.ajax({
        async: true,
        type: 'get',
        url: baseURL + '/scaffold/getAttributes/' + value + '/',
        success: function(response) {
            $("#on" + id).html(Attributes(response));
            $("#on" + id).material_select();
        }
    })
})

function Attributes(TableData) {
    var relations = '';
    jQuery.each(TableData, function(index, item) {
        relations += '<option value = "' + item + '">' + item + '</option>'
    });
    return relations;
}<|endoftext|>


<commit_before>'use strict';

var Backbone = require('backbone');
var Marionette = require('backbone.marionette');
var NUSMods = require('./nusmods');
var NavigationCollection = require('./common/collections/NavigationCollection');
var NavigationView = require('./common/views/NavigationView');
var Promise = require('bluebird'); // jshint ignore:line
var SelectedModulesController = require('./common/controllers/SelectedModulesController');
var TimetableModuleCollection = require('./common/collections/TimetableModuleCollection');
var _ = require('underscore');
var config = require('./common/config');
var localforage = require('localforage');
require('qTip2');

// Set Backbone.History.initialRoute to allow route handlers to find out if they
// were called from the initial route.
var loadUrl = Backbone.History.prototype.loadUrl;
Backbone.History.prototype.loadUrl = function() {
  if (!Backbone.History.initialRoute) {
    Backbone.History.initialRoute = true;
  } else {
    Backbone.History.initialRoute = false;
    // No longer initial route, restore original loadUrl.
    Backbone.History.prototype.loadUrl = loadUrl;
  }
  return loadUrl.apply(this, arguments);
};

var App = new Marionette.Application();

App.addRegions({
  mainRegion: '.content',
  navigationRegion: '#nav',
  selectRegion: '.navbar-form',
  bookmarksRegion: '.nm-bookmarks'
});

var navigationCollection = new NavigationCollection();
var navigationView = new NavigationView({collection: navigationCollection});
App.navigationRegion.show(navigationView);

App.reqres.setHandler('addNavigationItem', function (navigationItem) {
  return navigationCollection.add(navigationItem);
});

NUSMods.setConfig(config);

var selectedModulesControllers = [];

for (var i = 0; i < 5; i++) {
  selectedModulesControllers[i] = new SelectedModulesController({
    semester: i + 1
  });
}

App.reqres.setHandler('selectedModules', function (sem) {
  return selectedModulesControllers[sem - 1].selectedModules;
});
App.reqres.setHandler('addModule', function (sem, id, options) {
  return selectedModulesControllers[sem - 1].selectedModules.add({
    ModuleCode: id,
    Semester: sem
  }, options);
});
App.reqres.setHandler('removeModule', function (sem, id) {
  var selectedModules = selectedModulesControllers[sem - 1].selectedModules;
  return selectedModules.remove(selectedModules.get(id));
});
App.reqres.setHandler('isModuleSelected', function (sem, id) {
  return !!selectedModulesControllers[sem - 1].selectedModules.get(id);
});
App.reqres.setHandler('displayLessons', function (sem, id, display) {
  _.each(selectedModulesControllers[sem - 1].timetable.where({
    ModuleCode: id
  }), function (lesson) {
    lesson.set('display', display);
  });
});

var bookmarkedModulesNamespace = config.namespaces.bookmarkedModules + ':';

App.reqres.setHandler('getBookmarks', function (callback) {
  if (!callback) {
    return;
  }
  localforage.getItem(bookmarkedModulesNamespace, function (modules) {
    callback(modules);
  });
});
App.reqres.setHandler('addBookmark', function (id) {
  localforage.getItem(bookmarkedModulesNamespace, function (modules) {
    if (!_.contains(modules, id)) {
      modules.push(id);
    }
    localforage.setItem(bookmarkedModulesNamespace, modules);
  });
});
App.reqres.setHandler('deleteBookmark', function (id) {
  localforage.getItem(bookmarkedModulesNamespace, function (modules) {
    var index = modules.indexOf(id);
    if (index > -1) {
      modules.splice(index, 1);
      localforage.setItem(bookmarkedModulesNamespace, modules);
    }
  });
});

App.on('start', function () {
  var AppView = require('./common/views/AppView');

  new Marionette.AppRouter({
    routes: {
      '*default': function () {
        Backbone.history.navigate('timetable', {trigger: true, replace: true});
      }
    }
  });

  // header modules
  require('./timetable');
  require('./modules');
  // require('ivle');
  require('./barenus');
  require('./friends');
  require('./venues');
  require('./nusessities');
  require('./preferences');
  require('./blog');

  // footer modules
  require('./about');
  require('./contribute');
  require('./help');
  require('./support');

  Promise.all(_.map(_.range(1, 5), function(semester) {
    var semTimetableFragment = config.semTimetableFragment(semester);
    return localforage.getItem(semTimetableFragment + ':queryString')
      .then(function (savedQueryString) {
      if ('/' + semTimetableFragment === window.location.pathname) {
        var queryString = window.location.search.slice(1);
        if (queryString) {
          if (savedQueryString !== queryString) {
            // If initial query string does not match saved query string,
            // timetable is shared.
            App.request('selectedModules', semester).shared = true;
          }
          // If there is a query string for timetable, return so that it will
          // be used instead of saved query string.
          return;
        }
      }
      var selectedModules = TimetableModuleCollection.fromQueryStringToJSON(savedQueryString);
      return Promise.all(_.map(selectedModules, function (module) {
        return App.request('addModule', semester, module.ModuleCode, module);
      }));
    });
  }).concat([NUSMods.generateModuleCodes()])).then(function () {
    new AppView();

    Backbone.history.start({pushState: true});
  });

  localforage.getItem(bookmarkedModulesNamespace, function (modules) {
    if (!modules) {
      localforage.setItem(bookmarkedModulesNamespace, []);
    }
  });
});

module.exports = App;
<commit_msg>Remove more barenus stuff<commit_after>'use strict';

var Backbone = require('backbone');
var Marionette = require('backbone.marionette');
var NUSMods = require('./nusmods');
var NavigationCollection = require('./common/collections/NavigationCollection');
var NavigationView = require('./common/views/NavigationView');
var Promise = require('bluebird'); // jshint ignore:line
var SelectedModulesController = require('./common/controllers/SelectedModulesController');
var TimetableModuleCollection = require('./common/collections/TimetableModuleCollection');
var _ = require('underscore');
var config = require('./common/config');
var localforage = require('localforage');
require('qTip2');

// Set Backbone.History.initialRoute to allow route handlers to find out if they
// were called from the initial route.
var loadUrl = Backbone.History.prototype.loadUrl;
Backbone.History.prototype.loadUrl = function() {
  if (!Backbone.History.initialRoute) {
    Backbone.History.initialRoute = true;
  } else {
    Backbone.History.initialRoute = false;
    // No longer initial route, restore original loadUrl.
    Backbone.History.prototype.loadUrl = loadUrl;
  }
  return loadUrl.apply(this, arguments);
};

var App = new Marionette.Application();

App.addRegions({
  mainRegion: '.content',
  navigationRegion: '#nav',
  selectRegion: '.navbar-form',
  bookmarksRegion: '.nm-bookmarks'
});

var navigationCollection = new NavigationCollection();
var navigationView = new NavigationView({collection: navigationCollection});
App.navigationRegion.show(navigationView);

App.reqres.setHandler('addNavigationItem', function (navigationItem) {
  return navigationCollection.add(navigationItem);
});

NUSMods.setConfig(config);

var selectedModulesControllers = [];

for (var i = 0; i < 5; i++) {
  selectedModulesControllers[i] = new SelectedModulesController({
    semester: i + 1
  });
}

App.reqres.setHandler('selectedModules', function (sem) {
  return selectedModulesControllers[sem - 1].selectedModules;
});
App.reqres.setHandler('addModule', function (sem, id, options) {
  return selectedModulesControllers[sem - 1].selectedModules.add({
    ModuleCode: id,
    Semester: sem
  }, options);
});
App.reqres.setHandler('removeModule', function (sem, id) {
  var selectedModules = selectedModulesControllers[sem - 1].selectedModules;
  return selectedModules.remove(selectedModules.get(id));
});
App.reqres.setHandler('isModuleSelected', function (sem, id) {
  return !!selectedModulesControllers[sem - 1].selectedModules.get(id);
});
App.reqres.setHandler('displayLessons', function (sem, id, display) {
  _.each(selectedModulesControllers[sem - 1].timetable.where({
    ModuleCode: id
  }), function (lesson) {
    lesson.set('display', display);
  });
});

var bookmarkedModulesNamespace = config.namespaces.bookmarkedModules + ':';

App.reqres.setHandler('getBookmarks', function (callback) {
  if (!callback) {
    return;
  }
  localforage.getItem(bookmarkedModulesNamespace, function (modules) {
    callback(modules);
  });
});
App.reqres.setHandler('addBookmark', function (id) {
  localforage.getItem(bookmarkedModulesNamespace, function (modules) {
    if (!_.contains(modules, id)) {
      modules.push(id);
    }
    localforage.setItem(bookmarkedModulesNamespace, modules);
  });
});
App.reqres.setHandler('deleteBookmark', function (id) {
  localforage.getItem(bookmarkedModulesNamespace, function (modules) {
    var index = modules.indexOf(id);
    if (index > -1) {
      modules.splice(index, 1);
      localforage.setItem(bookmarkedModulesNamespace, modules);
    }
  });
});

App.on('start', function () {
  var AppView = require('./common/views/AppView');

  new Marionette.AppRouter({
    routes: {
      '*default': function () {
        Backbone.history.navigate('timetable', {trigger: true, replace: true});
      }
    }
  });

  // header modules
  require('./timetable');
  require('./modules');
  // require('ivle');
  require('./barenus');
  require('./friends');
  require('./venues');
  require('./preferences');
  require('./blog');

  // footer modules
  require('./about');
  require('./contribute');
  require('./help');
  require('./support');

  Promise.all(_.map(_.range(1, 5), function(semester) {
    var semTimetableFragment = config.semTimetableFragment(semester);
    return localforage.getItem(semTimetableFragment + ':queryString')
      .then(function (savedQueryString) {
      if ('/' + semTimetableFragment === window.location.pathname) {
        var queryString = window.location.search.slice(1);
        if (queryString) {
          if (savedQueryString !== queryString) {
            // If initial query string does not match saved query string,
            // timetable is shared.
            App.request('selectedModules', semester).shared = true;
          }
          // If there is a query string for timetable, return so that it will
          // be used instead of saved query string.
          return;
        }
      }
      var selectedModules = TimetableModuleCollection.fromQueryStringToJSON(savedQueryString);
      return Promise.all(_.map(selectedModules, function (module) {
        return App.request('addModule', semester, module.ModuleCode, module);
      }));
    });
  }).concat([NUSMods.generateModuleCodes()])).then(function () {
    new AppView();

    Backbone.history.start({pushState: true});
  });

  localforage.getItem(bookmarkedModulesNamespace, function (modules) {
    if (!modules) {
      localforage.setItem(bookmarkedModulesNamespace, []);
    }
  });
});

module.exports = App;
<|endoftext|>


<commit_before>
(function($) {
  var isMobile = {
    Mobile: function() {
        return navigator.userAgent.match(/Mobile/i);
    },
    Android: function() {
        return navigator.userAgent.match(/Android/i);
    },
    Kindle: function() {
        return navigator.userAgent.match(/Kindle/i);
    },
    BlackBerry: function() {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS: function() {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
    },
    Opera: function() {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Omobile: function() {
        return navigator.userAgent.match(/Opera Mobi/i);
    },
    Windows: function() {
        return navigator.userAgent.match(/IEMobile/i);
    },
    any: function() {
        return (isMobile.Mobile() || isMobile.Kindle() || isMobile.Omobile() || isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
  };

  $(document).ready(function() {
    var $pageURL = $('.share-wrapper').attr('data-url');

    if (location.pathname === "/") {
      var anchor_offset = $(window).height() * 0.6 ;
      $(window).on('scroll', function() {
        if ( $(window).scrollTop() > anchor_offset ) {
          $('.navbar').addClass('sticky');
        } else {
          if(isMobile.any()) { return };

          $('.navbar').removeClass('sticky');
        };
      });
    }

    $('[data-toggle="tooltip"]').tooltip();

    wow = new WOW({
      boxClass:     'wow',      // default
      animateClass: 'animated', // default
      offset:       0,          // default
      mobile:       true,       // default
      live:         true        // default
    });
    wow.init();

    // Submit Form
    var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
    var phoneReg = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;

    jQuery("form#contact-form").submit(function(){
      console.log(window.location.origin);
      var error = false;
      var that = jQuery(this)
      jQuery(this).find('.require-field').each(function(){
        if(jQuery.trim(jQuery(this).val()) == '') {
          error = true;
          $(this).tooltip('show');
        } else if(jQuery(this).hasClass('email')) {
          if(!emailReg.test(jQuery.trim(jQuery(this).val()))) {
            error = true;
            $(this).tooltip('show');
          }
        } else if(jQuery(this).hasClass('phone')) {
          if(!phoneReg.test(jQuery.trim(jQuery(this).val()))) {
            error = true;
            $(this).tooltip('show');
          }
        }
      });

      if(error) return false;

      var send_data = jQuery(this).serialize();
      $(this).find('.btn-reserve').append("

")

      jQuery.post(window.location.origin + '/contact_mailer', send_data, function(data){
        if( data.success == '1' ){
          that.hide();
          $('.success').show();
          dataLayer.push({
            'event':'VirtualPageview',
            'virtualPageURL':'/speedtest/done',
            'virtualPageTitle' : 'Order Complete'
          });
        }else{
          $('.failure').show();
        }
      }, 'json');

      return false;
    });

    //Thank You Page

    $('.require-field').on('focus', function(e) {
      $(this).tooltip('hide');
    });

    $('#thankyouform').submit(function(e) {
      e.preventDefault();
      var the_form = $(this);
      var error = false;

      $(this).find('.require-field').each(function(){
        if($.trim($(this).val()) == '') {
          error = true;
          $(this).tooltip('show');
        }
      });

      if(error) return false;
      var send_data = $(this).serialize();
      var url = $(this).attr('action')
      $.post(url, send_data, function(data){
        if( data.success == '1' ){
          the_form.parent().remove();
          $('.success').show();
          dataLayer.push({
            'event':'VirtualPageview',
            'virtualPageURL':'/wireframe/thank-you-done',
            'virtualPageTitle' : 'Order Complete'
          });
        }else{
          $('.failure').show();
        }
      }, 'json');

    });

    $('.website-url').change(function(e){
      var val = $(this).val();
      $(this).val(val.replace(/.*?:\/\//g, ""))
    });

    function getRandomInt(min, max) {
      return Math.floor(Math.random() * (max - min)) + min;
    };

    function analize(form, time){

      var max_errors = getRandomInt(8,16),
        xx = false,
        percent = 0.0,
        errors = 0,
        i = 0,
        j = 0,
        jj = 0,
        k = 0,
        bar = document.getElementById('progressbar'),
        aa  = document.getElementById('analyzer-errors'),
        times = [];

        for( i = 0; i <= max_errors; i++) {
          times.push(getRandomInt(5,25)*time)
        }

        times.sort(function() {
            return .2 - Math.random();
        });

        var progress = setInterval(function() {
          if( ++i < 25*time || ( i > 50*time && i < 85*time ) || i > 135*time ){
            percent = Math.round( (percent+1/time) * 10 ) / 10;
            j++;
            bar.style.width = percent+'%';

            if( xx && errors < max_errors && j>=jj ){
              errors++;
              jj += times[k++]*time/max_errors;
              text = (errors > 1) ? "errors" : "error";
              aa.innerHTML = errors+" "+text+" found…";
            }
          }

          if( !xx && i > 40 ){
            xx= true;
            jj =j;
            aa.classList.remove("hide");
          }

          if ( percent >= 100 ) {
            clearInterval(progress);
            $('.analyzer .warning-title').html('Preparing your report please be patient...')
            form.submit();
          }

        }, 5);

      };
    $('#speedtest button').on('click', function(e) {
      e.preventDefault();
      var form = $('#speedtest');
      var error = false;
      console.log('test');
      form.find('.require-field').each(function(){
        if($.trim($(this).val()) == '') {
          error = true;
          $(this).tooltip('show');
        }
      });

      if(error) return false;
      form.hide();
      form.parent('.analyzer').append('
Analyzing your website…

1 error found…
');
      analize(form, 9.5);

    });

    // Social Counter
    if ($('#social').length > 0 ) {
      (function(){
        var position = $('.post-title').offset();
        var width = $('.post-title').width();

        $('#social').css({
          'top': position.top,
          'left': position.left + width + 20
        });

        $(window).on('scroll', function() {
          if ( $(window).scrollTop() > (position.top - 100) ) {
            $('#social').addClass('fixed');
          } else {

            $('#social').removeClass('fixed');
          };
        });

        // Facebook counter
        $.getJSON('https://graph.facebook.com/?id=' + $pageURL, function (data) {
          $('.facebook .count').text(data.shares);
        });
         // Twitter counter
        $.getJSON('httpss://cdn.api.twitter.com/1/urls/count.json?url=' + $pageURL +'&callback=?', function (data) {
          $('.twitter .count').text(data.count);
        });
         // Linkedin counter
        $.getJSON('https://www.linkedin.com/countserv/count/share?url=' + $pageURL +'&callback=?', function (data) {
          $('.linkedin .count').text(data.count);
        });
        // Google Plus counter
        $.getJSON('https://anyorigin.com/get?callback=?&url=' + encodeURIComponent('https://plusone.google.com/_/+1/fastbutton?url=' +  $pageURL), function (data){
          var gcount = (data.contents.match(/{c: (\d+)/) != null)  ? data.contents.match(/{c: (\d+)/)[1] : '0';
          $('.gplus .count').text(gcount);
        });
      })();
    }
    // Socail Share
    $('.post-share .share').on('click', function(e) {
      var fShare = 'https://www.facebook.com/sharer/sharer.php?';
      var tShare = 'https://twitter.com/intent/tweet?';
      var lShare = 'https://www.linkedin.com/cws/share?';
      var gShare = 'https://plus.google.com/share?url=';
      var tHandle = $('.post-share .twitter').attr('data-handle');
      var pageTitle = $('.post-title h1').html();
      var url = '';

      if ($(this).hasClass('facebook')) {
        url = fShare + 'u=' + encodeURIComponent($pageURL) + '&t=' + encodeURIComponent(pageTitle);
      } else if ($(this).hasClass('twitter')) {
        url = tShare + 'text=' + encodeURIComponent(pageTitle) + '&url=' + encodeURIComponent($pageURL) + '&via=' + tHandle;
      } else if ($(this).hasClass('linkedin')) {
        url = lShare + 'url=' + encodeURIComponent($pageURL) + '&token=&isFramed=true';
      } else if ($(this).hasClass('gplus')) {
        url = gShare + encodeURIComponent($pageURL)
      }

      window.open(url, '_blank', 'location=yes,height=570,width=520,scrollbars=yes,status=yes');
    });
  });

})(jQuery);<commit_msg>minor fix blog<commit_after>
(function($) {
  var isMobile = {
    Mobile: function() {
        return navigator.userAgent.match(/Mobile/i);
    },
    Android: function() {
        return navigator.userAgent.match(/Android/i);
    },
    Kindle: function() {
        return navigator.userAgent.match(/Kindle/i);
    },
    BlackBerry: function() {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS: function() {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
    },
    Opera: function() {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Omobile: function() {
        return navigator.userAgent.match(/Opera Mobi/i);
    },
    Windows: function() {
        return navigator.userAgent.match(/IEMobile/i);
    },
    any: function() {
        return (isMobile.Mobile() || isMobile.Kindle() || isMobile.Omobile() || isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
  };

  $(document).ready(function() {
    var $pageURL = $('.share-wrapper').attr('data-url');

    if (location.pathname === "/") {
      var anchor_offset = $(window).height() * 0.6 ;
      $(window).on('scroll', function() {
        if ( $(window).scrollTop() > anchor_offset ) {
          $('.navbar').addClass('sticky');
        } else {
          if(isMobile.any()) { return };

          $('.navbar').removeClass('sticky');
        };
      });
    }

    $('[data-toggle="tooltip"]').tooltip();

    wow = new WOW({
      boxClass:     'wow',      // default
      animateClass: 'animated', // default
      offset:       0,          // default
      mobile:       true,       // default
      live:         true        // default
    });
    wow.init();

    // Submit Form
    var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
    var phoneReg = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;

    jQuery("form#contact-form").submit(function(){
      console.log(window.location.origin);
      var error = false;
      var that = jQuery(this)
      jQuery(this).find('.require-field').each(function(){
        if(jQuery.trim(jQuery(this).val()) == '') {
          error = true;
          $(this).tooltip('show');
        } else if(jQuery(this).hasClass('email')) {
          if(!emailReg.test(jQuery.trim(jQuery(this).val()))) {
            error = true;
            $(this).tooltip('show');
          }
        } else if(jQuery(this).hasClass('phone')) {
          if(!phoneReg.test(jQuery.trim(jQuery(this).val()))) {
            error = true;
            $(this).tooltip('show');
          }
        }
      });

      if(error) return false;

      var send_data = jQuery(this).serialize();
      $(this).find('.btn-reserve').append("

")

      jQuery.post(window.location.origin + '/contact_mailer', send_data, function(data){
        if( data.success == '1' ){
          that.hide();
          $('.success').show();
          dataLayer.push({
            'event':'VirtualPageview',
            'virtualPageURL':'/speedtest/done',
            'virtualPageTitle' : 'Order Complete'
          });
        }else{
          $('.failure').show();
        }
      }, 'json');

      return false;
    });

    //Thank You Page

    $('.require-field').on('focus', function(e) {
      $(this).tooltip('hide');
    });

    $('#thankyouform').submit(function(e) {
      e.preventDefault();
      var the_form = $(this);
      var error = false;

      $(this).find('.require-field').each(function(){
        if($.trim($(this).val()) == '') {
          error = true;
          $(this).tooltip('show');
        }
      });

      if(error) return false;
      var send_data = $(this).serialize();
      var url = $(this).attr('action')
      $.post(url, send_data, function(data){
        if( data.success == '1' ){
          the_form.parent().remove();
          $('.success').show();
          dataLayer.push({
            'event':'VirtualPageview',
            'virtualPageURL':'/wireframe/thank-you-done',
            'virtualPageTitle' : 'Order Complete'
          });
        }else{
          $('.failure').show();
        }
      }, 'json');

    });

    $('.website-url').change(function(e){
      var val = $(this).val();
      $(this).val(val.replace(/.*?:\/\//g, ""))
    });

    function getRandomInt(min, max) {
      return Math.floor(Math.random() * (max - min)) + min;
    };

    function analize(form, time){

      var max_errors = getRandomInt(8,16),
        xx = false,
        percent = 0.0,
        errors = 0,
        i = 0,
        j = 0,
        jj = 0,
        k = 0,
        bar = document.getElementById('progressbar'),
        aa  = document.getElementById('analyzer-errors'),
        times = [];

        for( i = 0; i <= max_errors; i++) {
          times.push(getRandomInt(5,25)*time)
        }

        times.sort(function() {
            return .2 - Math.random();
        });

        var progress = setInterval(function() {
          if( ++i < 25*time || ( i > 50*time && i < 85*time ) || i > 135*time ){
            percent = Math.round( (percent+1/time) * 10 ) / 10;
            j++;
            bar.style.width = percent+'%';

            if( xx && errors < max_errors && j>=jj ){
              errors++;
              jj += times[k++]*time/max_errors;
              text = (errors > 1) ? "errors" : "error";
              aa.innerHTML = errors+" "+text+" found…";
            }
          }

          if( !xx && i > 40 ){
            xx= true;
            jj =j;
            aa.classList.remove("hide");
          }

          if ( percent >= 100 ) {
            clearInterval(progress);
            $('.analyzer .warning-title').html('Preparing your report please be patient...')
            form.submit();
          }

        }, 5);

      };
    $('#speedtest button').on('click', function(e) {
      e.preventDefault();
      var form = $('#speedtest');
      var error = false;
      console.log('test');
      form.find('.require-field').each(function(){
        if($.trim($(this).val()) == '') {
          error = true;
          $(this).tooltip('show');
        }
      });

      if(error) return false;
      form.hide();
      form.parent('.analyzer').append('
Analyzing your website…

1 error found…
');
      analize(form, 9.5);

    });

    // Social Counter
    if ($('#social').length > 0 ) {
      (function(){
        var position = $('.post-title').offset();
        var width = $('.post-title').width();

        $('#social').css({
          'top': position.top,
          'left': position.left + width + 20
        });

        $(window).on('scroll', function() {
          if ( $(window).scrollTop() > (position.top - 100) ) {
            $('#social').addClass('fixed');
          } else {

            $('#social').removeClass('fixed');
          };
        });

        // Facebook counter
        $.getJSON('https://graph.facebook.com/?id=' + $pageURL, function (data) {
          $('.facebook .count').text(data.shares);
        });
         // Twitter counter
        $.getJSON('https://cdn.api.twitter.com/1/urls/count.json?url=' + $pageURL +'&callback=?', function (data) {
          $('.twitter .count').text(data.count);
        });
         // Linkedin counter
        $.getJSON('https://www.linkedin.com/countserv/count/share?url=' + $pageURL +'&callback=?', function (data) {
          $('.linkedin .count').text(data.count);
        });
        // Google Plus counter
        $.getJSON('http://anyorigin.com/get?callback=?&url=' + encodeURIComponent('https://plusone.google.com/_/+1/fastbutton?url=' +  $pageURL), function (data){
          var gcount = (data.contents.match(/{c: (\d+)/) != null)  ? data.contents.match(/{c: (\d+)/)[1] : '0';
          $('.gplus .count').text(gcount);
        });
      })();
    }
    // Socail Share
    $('.post-share .share').on('click', function(e) {
      var fShare = 'https://www.facebook.com/sharer/sharer.php?';
      var tShare = 'https://twitter.com/intent/tweet?';
      var lShare = 'https://www.linkedin.com/cws/share?';
      var gShare = 'https://plus.google.com/share?url=';
      var tHandle = $('.post-share .twitter').attr('data-handle');
      var pageTitle = $('.post-title h1').html();
      var url = '';

      if ($(this).hasClass('facebook')) {
        url = fShare + 'u=' + encodeURIComponent($pageURL) + '&t=' + encodeURIComponent(pageTitle);
      } else if ($(this).hasClass('twitter')) {
        url = tShare + 'text=' + encodeURIComponent(pageTitle) + '&url=' + encodeURIComponent($pageURL) + '&via=' + tHandle;
      } else if ($(this).hasClass('linkedin')) {
        url = lShare + 'url=' + encodeURIComponent($pageURL) + '&token=&isFramed=true';
      } else if ($(this).hasClass('gplus')) {
        url = gShare + encodeURIComponent($pageURL)
      }

      window.open(url, '_blank', 'location=yes,height=570,width=520,scrollbars=yes,status=yes');
    });
  });

})(jQuery);<|endoftext|>


<commit_before>//
// Please update "commments" to "submit point"
//

'use strict';

var assertionUrl = 'https://3pp.io:4343/persona';
var postPointUrl = 'https://3pp.io:4343/post/point';
var serviceListUrl = 'https://tosdr.org/index/services.json';

$(document).ready(function(){
  var loggedInUser = null;
  var loadTimer = setTimeout(function() {
    showPersona();
  }, 3000);
  function logout(){
    loggedInUser = null;
    var response = $.post(assertionUrl + '/logout');
    response.always(showPersona);
  }

  function verify(assertion){
    if (loadTimer) {
      clearTimeout(loadTimer);
      loadTimer = null;
    }
    showSigningIn();
    var response = $.ajax(assertionUrl + '/verify', {data: {assertion: assertion}, type: 'POST', xhrFields: {withCredentials: true}});
    response.done(login);
    response.fail(function(){
      navigator.id.logout();
    });
  }

  function login(data){
    showSubmitForm(data.email);
  }

  navigator.id.watch({
    loggedInUser: loggedInUser,
    onlogin: verify,
    onlogout: logout
  });

  function showPersona(){
    $('#submit-point-form').html('

To submit a point, please sign in with your email address.

');
    $('.signinButton').click(function(){ navigator.id.request(); }).css('cursor', 'pointer');
  }

  function showSigningIn(){
    $('#submit-point-form').html('

signing you in...

');
  }

  function showLoading(){
    $('#submit-point-form').html('

loading...

');
  }

  // This is ugly, too much html here
  //
  //

  var numServices = 1;
  function showServiceFields() {
    var str = '';
    for(var i=0; i<numServices; i++) {
      str += '<input type="text" placeholder="service">';
    }
    $('#serviceFields').html(str);
  }
  function showSubmitForm(email){
    $('#submit-point-form').html('<form class="submitForm">' +
        '' +
        '<fieldset>' +
        '<legend>Submit a point about a clause</legend>' +

        'Title<input type="text" id="titleField" name="title" required />' +

        '<input type="radio" name="point" id="pointGood" value="good" />Good<input type="radio" name="point" id="pointNeutral" value="neutral" />Neutral<input type="radio" required name="point" id="pointBad" value="bad" />Bad<input type="radio" name="point" id="pointBlocker" value="blocker" />Blocker' +

        'Please summarise this clause Parsed as Markdown<textarea name="summary" id="summaryField" required class="input-xxlarge" placeholder="What the clause in the terms does. Try not to make more than 5 sentences, but sometimes more is needed. Be creative. Feel free to include some quotes from the terms directly. It is very important that it is easy to understand and written in plain English."></textarea>' +

        'Service(s)<input id="servicesField" name="services" required class="input-large" />' +

'          Service(s) to which the point applies' +
'                                       ' +
'          <button class="btn btn-inline" type="button" id="addServiceField">Add one</button>' +
'' +

        'Source<input type="url" id="sourceField" name="source" placeholder="http://www.example.com/tos" />' +

        'Topic<input id="topicsField" name="topics" required class="input-large" />' +

'          <select id="topics">' +
'            <option>Select a topic</option>' +
'            <option>Scope of the copyright license</option>' +
'            <option>Changes</option>' +
'          </select>' +

        '</fieldset>' +
        '
' +
        '<button class="btn btn-primary btn-large" id="postPoint">Send</button>' +
        'Submitting as ' + email + ' (Not your email address? Log out!)' +

        '
' +
        '</form>');
    showServiceFields();
    $('#addServiceField').click(function() {
      numServices++;
      showServiceFields();
    });
    var response = $.get(serviceListUrl, 'json');
    response.done(function(services){
      services = $.map(services, function(value, key){
        return key;
      });
      // Note: the width should be 'element', but for some reason it receives a different width than other input elements
      $('#servicesField').select2({tags: services, width: '220px', containerCss: {'border-radius': '4px'}});
    });

    $('.submitForm').submit(function(e){
      var response = $.ajax(postPointUrl, {data: {title: $('#titleField').val(), point: $('input[name=point]:checked', '.submitForm').val(), services: $('#servicesField').val(), summary: $('#summaryField').val()}, type: 'POST', xhrFields: {withCredentials: true}});
      response.done(showConfirmation);
      response.fail(showError);
      e.preventDefault();
    });
    $('.signoutButton').click(function(){ navigator.id.logout(); });
  }

  function showConfirmation(){
    $('#submit-point-form').html('Your point has been submitted. Thank you! '
        +'submit another one or '
        +'see the list.');
  }

  function showError(){
    $('#submit-point-form').prepend('
<button type="button" class="close" data-dismiss="alert">×</button>Something went wrong saving your point, did you fill in all the fields?
');
  }
  showLoading();
});
<commit_msg>try to fix dropdown selects<commit_after>//
// Please update "commments" to "submit point"
//

'use strict';

var assertionUrl = 'https://3pp.io:4343/persona';
var postPointUrl = 'https://3pp.io:4343/post/point';
var serviceListUrl = 'https://tosdr.org/index/services.json';

$(document).ready(function(){
  var loggedInUser = null;
  var loadTimer = setTimeout(function() {
    showPersona();
  }, 3000);
  function logout(){
    loggedInUser = null;
    var response = $.post(assertionUrl + '/logout');
    response.always(showPersona);
  }

  function verify(assertion){
    if (loadTimer) {
      clearTimeout(loadTimer);
      loadTimer = null;
    }
    showSigningIn();
    var response = $.ajax(assertionUrl + '/verify', {data: {assertion: assertion}, type: 'POST', xhrFields: {withCredentials: true}});
    response.done(login);
    response.fail(function(){
      navigator.id.logout();
    });
  }

  function login(data){
    showSubmitForm(data.email);
  }

  navigator.id.watch({
    loggedInUser: loggedInUser,
    onlogin: verify,
    onlogout: logout
  });

  function showPersona(){
    $('#submit-point-form').html('

To submit a point, please sign in with your email address.

');
    $('.signinButton').click(function(){ navigator.id.request(); }).css('cursor', 'pointer');
  }

  function showSigningIn(){
    $('#submit-point-form').html('

signing you in...

');
  }

  function showLoading(){
    $('#submit-point-form').html('

loading...

');
  }

  // This is ugly, too much html here
  //
  //

  var numServices = 1;
  function showServiceFields() {
    var str = '';
    for(var i=0; i<numServices; i++) {
      str += '          <select id="service'+i+'">' +
'            <option>Select a service</option>' +
'            <option>Facebook</option>' +
'            <option>Google</option>' +
'          </select>';
    }
    $('#serviceFields').html(str);
  }
  function showSubmitForm(email){
    $('#submit-point-form').html('<form class="submitForm">' +
        '' +
        '<fieldset>' +
        '<legend>Submit a point about a clause</legend>' +

        'Title<input type="text" id="titleField" name="title" required />' +

        '<input type="radio" name="point" id="pointGood" value="good" />Good<input type="radio" name="point" id="pointNeutral" value="neutral" />Neutral<input type="radio" required name="point" id="pointBad" value="bad" />Bad<input type="radio" name="point" id="pointBlocker" value="blocker" />Blocker' +

        'Please summarise this clause Parsed as Markdown<textarea name="summary" id="summaryField" required class="input-xxlarge" placeholder="What the clause in the terms does. Try not to make more than 5 sentences, but sometimes more is needed. Be creative. Feel free to include some quotes from the terms directly. It is very important that it is easy to understand and written in plain English."></textarea>' +

'          Service(s) to which the point applies' +
'                                       ' +
'          <button class="btn btn-inline" type="button" id="addServiceField">Add one</button>' +
'' +

        'Source<input type="url" id="sourceField" name="source" placeholder="http://www.example.com/tos" />' +

        'Topic' +

'          <select id="topics">' +
'            <option>Select a topic</option>' +
'            <option>Scope of the copyright license</option>' +
'            <option>Changes</option>' +
'          </select>' +

        '</fieldset>' +
        '
' +
        '<button class="btn btn-primary btn-large" id="postPoint">Send</button>' +
        'Submitting as ' + email + ' (Not your email address? Log out!)' +

        '
' +
        '</form>');
    showServiceFields();
    $('#addServiceField').click(function() {
      numServices++;
      showServiceFields();
    });
    var response = $.get(serviceListUrl, 'json');
    response.done(function(services){
      services = $.map(services, function(value, key){
        return key;
      });
      // Note: the width should be 'element', but for some reason it receives a different width than other input elements
      $('#servicesField').select2({tags: services, width: '220px', containerCss: {'border-radius': '4px'}});
    });

    $('.submitForm').submit(function(e){
      var response = $.ajax(postPointUrl, {data: {title: $('#titleField').val(), point: $('input[name=point]:checked', '.submitForm').val(), services: $('#servicesField').val(), summary: $('#summaryField').val()}, type: 'POST', xhrFields: {withCredentials: true}});
      response.done(showConfirmation);
      response.fail(showError);
      e.preventDefault();
    });
    $('.signoutButton').click(function(){ navigator.id.logout(); });
  }

  function showConfirmation(){
    $('#submit-point-form').html('Your point has been submitted. Thank you! '
        +'submit another one or '
        +'see the list.');
  }

  function showError(){
    $('#submit-point-form').prepend('
<button type="button" class="close" data-dismiss="alert">×</button>Something went wrong saving your point, did you fill in all the fields?
');
  }
  showLoading();
});
<|endoftext|>