<commit_before>/**
 * The BasemapsView selector view.
 *
 * @return BasemapsView instance (extends Backbone.View).
 */
define([
  'underscore',
  'handlebars',
  'enquire',
  'moment',
  'mps',
  'picker',
  'pickadate',
  'map/presenters/tabs/HighresolutionPresenter',
  'text!map/templates/tabs/highresolution.handlebars'
], function(_, Handlebars, enquire, moment, mps, picker, pickadate, Presenter, tpl) {

  'use strict';

  var SelectedDates = Backbone.Model.extend({
    // left blank on puropose, max min dates
  });

  var HighresolutionView = Backbone.View.extend({

    el: '#hd-tab',

    template: Handlebars.compile(tpl),

    events: {
      'change #hres-provider-select' : 'changeProvider',
      'click  .onoffswitch' : 'toggleLayer',
      'oninput #range-clouds' : 'setVisibleRange',
      'change #range-clouds' : 'setVisibleRange',
      'change input' : '_setParams',
      'change select' : '_setParams',
      'click button' : '_triggerChanges',
      'click .advanced-controls' : '_toggleAdvanced'
    },

    initialize: function(map) {
      this.presenter = new Presenter(this);
      this.map = map;
      this.params_new_url;
      this.previousZoom;
      this.selectedDates = new SelectedDates({
        startDateUC: moment().format('DD-MM-YYYY'),
        endDateUC: moment().subtract(3,'month').format('DD-MM-YYYY'),
      });
      this.render();
    },

    cacheVars: function() {
      this.$selects            = this.$el.find('.chosen-select');
      this.$hresSelectProvider = $('#hres-provider-select');
      this.$hresSelectProFil   = $('#hres-filter-select');
      this.$hresSelectFilter   = $('#hres-filter-select');
      this.$onoffswitch        = this.$el.find('.onoffswitch');
      this.$range              = $('#range-clouds');
      this.$progress           = $('#progress-clouds');
      this.$mindate            = this.$el.find("input[name='snd__mindate_submit']");
      this.$maxdate            = this.$el.find("input[name='snd__maxdate_submit']");
      this.$advanced_options   = this.$el.find('.advanced-options');
      this.$advanced_controls  = this.$el.find('.advanced-controls');
      this.$apply              = this.$el.find('.btn');
      this.$disclaimer         = this.$el.find('#disclaimer-zoom');
      this.$currentZoom        = this.$el.find('#currentZoom');
    },

    render: function() {
      this.$el.html(this.template({
        today: moment().format('DD-MM-YYYY'),
        mindate: moment().subtract(3,'month').format('YYYY-MM-DD'),
        zoom: this.map.getZoom()
      }));
      this.renderPickers();
      this.cacheVars();
      this.setListeners();
      this.printSelects();
    },

    setListeners: function() {
      google.maps.event.addListener(this.map, 'zoom_changed',
        _.bind(function() {
          this.setZoomConditions(this.map.getZoom());
        }, this)
      );
    },

    setZoomConditions: function(zoom) {
      this.zoom = zoom;
      if (isNaN(this.previousZoom)) this.previousZoom = zoom;
      this.$currentZoom.text(zoom);
      if(this.zoom >= 7) {
        this.$disclaimer.hide(0);
      } else {
        if (this.previousZoom >= 7) {
            this.presenter.notificate('not-zoom-not-reached');
        }
        if (!!this.$onoffswitch.hasClass('checked')) {
          this.$onoffswitch.click();
        }
        this.$disclaimer.show(0);
      }
      this.previousZoom = zoom;
    },

    _getParams: function(e) {
      var $objTarget = $(e.target).closest('.maptype');
      if(!!this.$onoffswitch.hasClass('checked')) {
        return {
          'zoom' : this.zoom,
          'satellite' : $objTarget.data('slug'),
          'color_filter': ($objTarget.find('#hres-filter-select').val().length > 0) ? $objTarget.find('#hres-filter-select').val() : 'rgb',
          'cloud': this.$range.val(),
          'mindate': (this.$mindate.val().length > 0) ? this.$mindate.val() : '2000-09-01',
          'maxdate': (this.$maxdate.val().length > 0) ? this.$maxdate.val() : '2015-09-01'
        };
      }
      return null;
    },

    _setParams: function(e) {
      if (! !!this.$onoffswitch.hasClass('checked')) {
        this.toggleLayer(e);
      } else {
        this.$apply.removeClass('disabled');
      }
      this.$apply.addClass('green').removeClass('gray');
      this.presenter.setHres(this._getParams(e));
    },

    _triggerChanges: function(e) {
      this.presenter.updateLayer($(e.target).closest('.maptype').data('slug'));
      this.$apply.removeClass('green').addClass('gray');
    },

    _fillParams: function(params) {
      this.$hresSelectProFil.val(params.color_filter).trigger("liszt:updated");
      this.$range.val(params.cloud);
      this.setVisibleRange();
      this.zoom = params.zoom;
      var that = this;
      this.params = params;
      window.setTimeout(_.bind(function(params) {
        this.renderPickers(this.params.mindate, this.params.maxdate);
        this.params = null;
      },this), 250)
    },

    toggleLayer: function(e) {
      if (this.zoom >= 7) {
        this.switchToggle();
        this.$apply.toggleClass('disabled');
        this.presenter.setHres(this._getParams(e));
        this.presenter.toggleLayer($(e.target).closest('.maptype').data('slug'));
      } else {
        if (!!this.$onoffswitch.hasClass('checked')) {
          this.switchToggle();
          this.$apply.toggleClass('disabled');
          this.presenter.setHres(this._getParams(e));
          this.presenter.toggleLayer($(e.target).closest('.maptype').data('slug'));
        } else {
          this.presenter.notificate('not-zoom-not-reached');
        }
      }
    },

    _toggleAdvanced: function(e) {
      this.$advanced_controls.toggleClass('active');
      this.$advanced_options.toggle('250');
    },

    switchToggle: function() {
      // this.$onoffswitch.toggleClass('checked');
      this.$el.find('.onoffswitch').toggleClass('checked');
    },

    printSelects: function() {
      this.printProviders();
      // this.printFilters();
      this.triggerChosen();
    },

    triggerChosen: function() {
      this.$selects.chosen({
        width: '100%',
        allow_single_deselect: true,
        inherit_select_classes: true,
        no_results_text: "Oops, nothing found!"
      });
    },

    printProviders: function() {
      var options = '<option value="urthe">Urthecast</option><option value="digiglobe">Digital Globe</option><option value="skybox">Skybox</option>';
      this.$hresSelectProvider.append(options);
      this.$hresSelectFilter.append('<option value="rgb">RGB (Red Green Blue)</option><option value="ndvi">NDVI (Normalized Difference Vegetation Index)</option><option value="evi">EVI (Enhanced vegetation index)</option><option value="ndwi">NDWI (Normalized Difference Water Index)</option><option value="false-color-nir">False Color NIR (Near Infra Red)</option>'); //temporary hardcoded

    },

    printFilters: function(options) {
      if (!!options) return;
      this.$hresSelectFilter.append(options);
      this.triggerChosen();
    },

    changeProvider: function(e) {
      return;
      var providers = {
        'urthe' : '<option value="ndvi">NDVI (Normalized Difference Vegetation Index)</option><option value="evi">EVI (Enhanced vegetation index)</option><option value="ndwi">NDWI (Normalized Difference Water Index)</option><option value="false-nir">False Color NIR (Near Infra Red)</option>',
        'digiglobe' : '',
        'skybox' : ''
      }
      this.printFilters(providers[$(e.currentTarget).val()]);
    },

    setVisibleRange: function(){
      var width = this.$range.val();
      this.$progress.width(width + '%')
    },

    renderPickers: function(minABSdate, maxABSdate) {
      var context = this;

      var onPickerOpen = function() {
        this.render();
      };

      var TODAY         = moment().toDate(),
          TODAY_TEXT    = 'Jump to Today',
          FORMAT        = 'dddd, dd mmm, yyyy',
          FORMATSUBMIT  = 'yyyy-mm-dd';

      var startHRdate = $('.timeline-date-picker-start').pickadate({
        today: TODAY_TEXT,
        min: moment('2013').toDate(),
        max: TODAY,
        selectYears: true,
        selectMonths: true,
        format: FORMAT,
        formatSubmit: FORMATSUBMIT,
        hiddenPrefix: 'snd__mindate',
        onOpen: onPickerOpen,
        onSet: function(event) {
          if ( event.select ) {
            endHRdate_picker.set('min', startHRdate_picker.get('select'))
          }
        }
      }),
      startHRdate_picker = startHRdate.pickadate('picker');

      var endHRdate = $('.timeline-date-picker-end').pickadate({
        today: TODAY_TEXT,
        min: moment().subtract(3,'month').toDate(),
        max: TODAY,
        selectYears: true,
        selectMonths: true,
        format: FORMAT,
        formatSubmit: FORMATSUBMIT,
        hiddenPrefix: 'snd__maxdate',
        onOpen: onPickerOpen,
        onSet: function(event) {
          if ( event.select ) {
            startHRdate_picker.set('max', endHRdate_picker.get('select'))
          }
        }
      });
      var endHRdate_picker = endHRdate.pickadate('picker');

      if (minABSdate && maxABSdate) {
        startHRdate_picker.set('select',  moment(minABSdate).toDate());
        endHRdate_picker.set('select',  moment(maxABSdate).toDate());
      }
    },

  });

  return HighresolutionView;

});

<commit_msg>keep HR Imagery open when loading hresolution<commit_after>/**
 * The BasemapsView selector view.
 *
 * @return BasemapsView instance (extends Backbone.View).
 */
define([
  'underscore',
  'handlebars',
  'enquire',
  'moment',
  'mps',
  'picker',
  'pickadate',
  'map/presenters/tabs/HighresolutionPresenter',
  'text!map/templates/tabs/highresolution.handlebars'
], function(_, Handlebars, enquire, moment, mps, picker, pickadate, Presenter, tpl) {

  'use strict';

  var SelectedDates = Backbone.Model.extend({
    // left blank on puropose, max min dates
  });

  var HighresolutionView = Backbone.View.extend({

    el: '#hd-tab',

    template: Handlebars.compile(tpl),

    events: {
      'change #hres-provider-select' : 'changeProvider',
      'click  .onoffswitch' : 'toggleLayer',
      'oninput #range-clouds' : 'setVisibleRange',
      'change #range-clouds' : 'setVisibleRange',
      'change input' : '_setParams',
      'change select' : '_setParams',
      'click button' : '_triggerChanges',
      'click .advanced-controls' : '_toggleAdvanced'
    },

    initialize: function(map) {
      this.presenter = new Presenter(this);
      this.map = map;
      this.params_new_url;
      this.previousZoom;
      this.selectedDates = new SelectedDates({
        startDateUC: moment().format('DD-MM-YYYY'),
        endDateUC: moment().subtract(3,'month').format('DD-MM-YYYY'),
      });
      this.render();
    },

    cacheVars: function() {
      this.$selects            = this.$el.find('.chosen-select');
      this.$hresSelectProvider = $('#hres-provider-select');
      this.$hresSelectProFil   = $('#hres-filter-select');
      this.$hresSelectFilter   = $('#hres-filter-select');
      this.$onoffswitch        = this.$el.find('.onoffswitch');
      this.$range              = $('#range-clouds');
      this.$progress           = $('#progress-clouds');
      this.$mindate            = this.$el.find("input[name='snd__mindate_submit']");
      this.$maxdate            = this.$el.find("input[name='snd__maxdate_submit']");
      this.$advanced_options   = this.$el.find('.advanced-options');
      this.$advanced_controls  = this.$el.find('.advanced-controls');
      this.$apply              = this.$el.find('.btn');
      this.$disclaimer         = this.$el.find('#disclaimer-zoom');
      this.$currentZoom        = this.$el.find('#currentZoom');
    },

    render: function() {
      this.$el.html(this.template({
        today: moment().format('DD-MM-YYYY'),
        mindate: moment().subtract(3,'month').format('YYYY-MM-DD'),
        zoom: this.map.getZoom()
      }));
      this.renderPickers();
      this.cacheVars();
      this.setListeners();
      this.printSelects();
    },

    setListeners: function() {
      google.maps.event.addListener(this.map, 'zoom_changed',
        _.bind(function() {
          this.setZoomConditions(this.map.getZoom());
        }, this)
      );
    },

    setZoomConditions: function(zoom) {
      this.zoom = zoom;
      if (isNaN(this.previousZoom)) this.previousZoom = zoom;
      this.$currentZoom.text(zoom);
      if(this.zoom >= 7) {
        this.$disclaimer.hide(0);
      } else {
        if (this.previousZoom >= 7) {
            this.presenter.notificate('not-zoom-not-reached');
        }
        if (!!this.$onoffswitch.hasClass('checked')) {
          this.$onoffswitch.click();
        }
        this.$disclaimer.show(0);
      }
      this.previousZoom = zoom;
    },

    _getParams: function(e) {
      var $objTarget = $(e.target).closest('.maptype');
      mps.publish('Tab/open', ['#hd-tab-button']);
      if(!!this.$onoffswitch.hasClass('checked')) {
        return {
          'zoom' : this.zoom,
          'satellite' : $objTarget.data('slug'),
          'color_filter': ($objTarget.find('#hres-filter-select').val().length > 0) ? $objTarget.find('#hres-filter-select').val() : 'rgb',
          'cloud': this.$range.val(),
          'mindate': (this.$mindate.val().length > 0) ? this.$mindate.val() : '2000-09-01',
          'maxdate': (this.$maxdate.val().length > 0) ? this.$maxdate.val() : '2015-09-01'
        };
      }
      return null;
    },

    _setParams: function(e) {
      if (! !!this.$onoffswitch.hasClass('checked')) {
        this.toggleLayer(e);
      } else {
        this.$apply.removeClass('disabled');
      }
      this.$apply.addClass('green').removeClass('gray');
      this.presenter.setHres(this._getParams(e));
    },

    _triggerChanges: function(e) {
      this.presenter.updateLayer($(e.target).closest('.maptype').data('slug'));
      this.$apply.removeClass('green').addClass('gray');
    },

    _fillParams: function(params) {
      this.$hresSelectProFil.val(params.color_filter).trigger("liszt:updated");
      this.$range.val(params.cloud);
      this.setVisibleRange();
      this.zoom = params.zoom;
      var that = this;
      this.params = params;
      window.setTimeout(_.bind(function(params) {
        this.renderPickers(this.params.mindate, this.params.maxdate);
        this.params = null;
      },this), 250)
    },

    toggleLayer: function(e) {
      if (this.zoom >= 7) {
        this.switchToggle();
        this.$apply.toggleClass('disabled');
        this.presenter.setHres(this._getParams(e));
        this.presenter.toggleLayer($(e.target).closest('.maptype').data('slug'));
      } else {
        if (!!this.$onoffswitch.hasClass('checked')) {
          this.switchToggle();
          this.$apply.toggleClass('disabled');
          this.presenter.setHres(this._getParams(e));
          this.presenter.toggleLayer($(e.target).closest('.maptype').data('slug'));
        } else {
          this.presenter.notificate('not-zoom-not-reached');
        }
      }
    },

    _toggleAdvanced: function(e) {
      this.$advanced_controls.toggleClass('active');
      this.$advanced_options.toggle('250');
    },

    switchToggle: function() {
      // this.$onoffswitch.toggleClass('checked');
      this.$el.find('.onoffswitch').toggleClass('checked');
    },

    printSelects: function() {
      this.printProviders();
      // this.printFilters();
      this.triggerChosen();
    },

    triggerChosen: function() {
      this.$selects.chosen({
        width: '100%',
        allow_single_deselect: true,
        inherit_select_classes: true,
        no_results_text: "Oops, nothing found!"
      });
    },

    printProviders: function() {
      var options = '<option value="urthe">Urthecast</option><option value="digiglobe">Digital Globe</option><option value="skybox">Skybox</option>';
      this.$hresSelectProvider.append(options);
      this.$hresSelectFilter.append('<option value="rgb">RGB (Red Green Blue)</option><option value="ndvi">NDVI (Normalized Difference Vegetation Index)</option><option value="evi">EVI (Enhanced vegetation index)</option><option value="ndwi">NDWI (Normalized Difference Water Index)</option><option value="false-color-nir">False Color NIR (Near Infra Red)</option>'); //temporary hardcoded

    },

    printFilters: function(options) {
      if (!!options) return;
      this.$hresSelectFilter.append(options);
      this.triggerChosen();
    },

    changeProvider: function(e) {
      return;
      var providers = {
        'urthe' : '<option value="ndvi">NDVI (Normalized Difference Vegetation Index)</option><option value="evi">EVI (Enhanced vegetation index)</option><option value="ndwi">NDWI (Normalized Difference Water Index)</option><option value="false-nir">False Color NIR (Near Infra Red)</option>',
        'digiglobe' : '',
        'skybox' : ''
      }
      this.printFilters(providers[$(e.currentTarget).val()]);
    },

    setVisibleRange: function(){
      var width = this.$range.val();
      this.$progress.width(width + '%')
    },

    renderPickers: function(minABSdate, maxABSdate) {
      var context = this;

      var onPickerOpen = function() {
        this.render();
      };

      var TODAY         = moment().toDate(),
          TODAY_TEXT    = 'Jump to Today',
          FORMAT        = 'dddd, dd mmm, yyyy',
          FORMATSUBMIT  = 'yyyy-mm-dd';

      var startHRdate = $('.timeline-date-picker-start').pickadate({
        today: TODAY_TEXT,
        min: moment('2013').toDate(),
        max: TODAY,
        selectYears: true,
        selectMonths: true,
        format: FORMAT,
        formatSubmit: FORMATSUBMIT,
        hiddenPrefix: 'snd__mindate',
        onOpen: onPickerOpen,
        onSet: function(event) {
          if ( event.select ) {
            endHRdate_picker.set('min', startHRdate_picker.get('select'))
          }
        }
      }),
      startHRdate_picker = startHRdate.pickadate('picker');

      var endHRdate = $('.timeline-date-picker-end').pickadate({
        today: TODAY_TEXT,
        min: moment().subtract(3,'month').toDate(),
        max: TODAY,
        selectYears: true,
        selectMonths: true,
        format: FORMAT,
        formatSubmit: FORMATSUBMIT,
        hiddenPrefix: 'snd__maxdate',
        onOpen: onPickerOpen,
        onSet: function(event) {
          if ( event.select ) {
            startHRdate_picker.set('max', endHRdate_picker.get('select'))
          }
        }
      });
      var endHRdate_picker = endHRdate.pickadate('picker');

      if (minABSdate && maxABSdate) {
        startHRdate_picker.set('select',  moment(minABSdate).toDate());
        endHRdate_picker.set('select',  moment(maxABSdate).toDate());
      }
    },

  });

  return HighresolutionView;

});

<|endoftext|>


<commit_before>define(['app/Colour', 'app/ColourMap', 'app/ObservableValue'],
function (Colour, ColourMap, ObservableValue) {

    // ---------------------------------------------------------------------------------------------
    // Private functions
    // ---------------------------------------------------------------------------------------------

    function minMaxMedian(values)
    {
        return {
            min: values[0],
            max: values[values.length-1],
            med: values[Math.floor(values.length/2)]
        };
    }

    // ---------------------------------------------------------------------------------------------
    // StatsModel
    // ---------------------------------------------------------------------------------------------

    /**
     * @constructor
     */
    function StatsModel()
    {
        this._colourMap = new ColourMap();
        this._colourMap.setOutOfRangeColour(new Colour(64,64,64));
        /** @type {string[]} */
        this._colourKeyStrings = [];
        /** @type {ObservableValue.<StatsModel.Stat>} */
        this.stat = new ObservableValue(undefined);
    }

    /**
     * @param {StatsModel.Stat} stat
     * @param {Object[]} objects
     */
    StatsModel.prototype.setStat = function(stat, objects)
    {
        var stats =  minMaxMedian(stat.filterValidValues(objects.map(stat.getValue)).sort());

        this._colourMap.clear();
        this._colourMap.addColour(stats.min, new Colour(0,255,0));
        this._colourMap.addColour(stats.med, new Colour(0,0,255));
        this._colourMap.addColour(stats.max, new Colour(255,0,0));

        this._colourKeyStrings = [
            "Low (green): " + stat.formatValue(stats.min),
            "Median (blue): " + stat.formatValue(stats.med),
            "High (red): " + stat.formatValue(stats.max),
            "No data (grey)"
        ];

        this.stat.set(stat);
    };

    /**
     * @param {Object} object
     * @returns {Colour}
     */
    StatsModel.prototype.getColour = function(object)
    {
        if (this.stat.get() !== undefined) {
            return this._colourMap.colour(this.stat.get().getValue(object));
        }
        return new Colour(64,64,64);
    };

    /**
     * @returns {string[]}
     */
    StatsModel.prototype.getColourKeyStrings = function()
    {
        return this._colourKeyStrings;
    };

    // ---------------------------------------------------------------------------------------------
    // StatsModel.Stat
    // ---------------------------------------------------------------------------------------------

    /**
     * Abstract class representing a statistic.
     * @constructor
     */
    StatsModel.Stat = function() {};
    /**
     * Extracts the value from the object.
     * @param {Object} object
     * @returns {number}
     */
    StatsModel.Stat.prototype.getValue = function(object) {};
    /**
     * Formats a previously extracted value for presentation.
     * @param {number} value
     * @returns {string}
     */
    StatsModel.Stat.prototype.formatValue = function(value) {};
    /**
     * Filters a list of values down to only valid values.
     * @param {number[]} values
     * @returns {number[]}
     */
    StatsModel.Stat.prototype.filterValidValues = function(values) {};

    // ---------------------------------------------------------------------------------------------

    return StatsModel;

});
<commit_msg>Fix sorting bug.<commit_after>define(['app/Colour', 'app/ColourMap', 'app/ObservableValue'],
function (Colour, ColourMap, ObservableValue) {

    // ---------------------------------------------------------------------------------------------
    // Private functions
    // ---------------------------------------------------------------------------------------------

    function compareNumbers(a, b)
    {
        return a - b;
    }

    function minMaxMedian(values)
    {
        return {
            min: values[0],
            max: values[values.length-1],
            med: values[Math.floor(values.length/2)]
        };
    }

    // ---------------------------------------------------------------------------------------------
    // StatsModel
    // ---------------------------------------------------------------------------------------------

    /**
     * @constructor
     */
    function StatsModel()
    {
        this._colourMap = new ColourMap();
        this._colourMap.setOutOfRangeColour(new Colour(64,64,64));
        /** @type {string[]} */
        this._colourKeyStrings = [];
        /** @type {ObservableValue.<StatsModel.Stat>} */
        this.stat = new ObservableValue(undefined);
    }

    /**
     * @param {StatsModel.Stat} stat
     * @param {Object[]} objects
     */
    StatsModel.prototype.setStat = function(stat, objects)
    {
        var stats =  minMaxMedian(stat.filterValidValues(objects.map(stat.getValue)).sort(compareNumbers));

        this._colourMap.clear();
        this._colourMap.addColour(stats.min, new Colour(0,255,0));
        this._colourMap.addColour(stats.med, new Colour(0,0,255));
        this._colourMap.addColour(stats.max, new Colour(255,0,0));

        this._colourKeyStrings = [
            "Low (green): " + stat.formatValue(stats.min),
            "Median (blue): " + stat.formatValue(stats.med),
            "High (red): " + stat.formatValue(stats.max),
            "No data (grey)"
        ];

        this.stat.set(stat);
    };

    /**
     * @param {Object} object
     * @returns {Colour}
     */
    StatsModel.prototype.getColour = function(object)
    {
        if (this.stat.get() !== undefined) {
            return this._colourMap.colour(this.stat.get().getValue(object));
        }
        return new Colour(64,64,64);
    };

    /**
     * @returns {string[]}
     */
    StatsModel.prototype.getColourKeyStrings = function()
    {
        return this._colourKeyStrings;
    };

    // ---------------------------------------------------------------------------------------------
    // StatsModel.Stat
    // ---------------------------------------------------------------------------------------------

    /**
     * Abstract class representing a statistic.
     * @constructor
     */
    StatsModel.Stat = function() {};
    /**
     * Extracts the value from the object.
     * @param {Object} object
     * @returns {number}
     */
    StatsModel.Stat.prototype.getValue = function(object) {};
    /**
     * Formats a previously extracted value for presentation.
     * @param {number} value
     * @returns {string}
     */
    StatsModel.Stat.prototype.formatValue = function(value) {};
    /**
     * Filters a list of values down to only valid values.
     * @param {number[]} values
     * @returns {number[]}
     */
    StatsModel.Stat.prototype.filterValidValues = function(values) {};

    // ---------------------------------------------------------------------------------------------

    return StatsModel;

});
<|endoftext|>


<commit_before>var tabStatus = {};
var data = {};
var nodeIndex = 1;
var selectedTree = {};

// required JSON object structure for using with JIT and d3.js
/*
json = {
	"id" : , "node00",
	"name" : "name",
	"data" : {},
	"children" : [ array of child nodes ]
	}
}
*/

// function to request page data from a tab and record it appropriately
function savePageData(pageData) {
	var page = { data: {} };
	var tabId = pageData.tabId;
	var openerId = pageData.openerId;

	page.name = pageData.title;
	page.data.url = pageData.url;
	page.data.ref = pageData.ref;
	page.data.date = pageData.date;
	page.children = [];

	console.log('tabId' + tabStatus[tabId]);
	console.log('openerId' + tabStatus[openerId]);
	// if both tabs are not in tabStatus, it is a root page
	if (tabStatus[tabId] == undefined && tabStatus[openerId] == undefined) {
		recordRootNode(page, tabId);
	}
	// if tabId is in tabStatus, then it is the same tab
	else if (tabStatus[tabId] != undefined) {
		recordChildNode(page, tabId, tabId);
	// if openerId is in tabStatus, then it is a new tab
	}
	else if (tabStatus[openerId] != undefined) {
		recordChildNode(page, tabId, openerId);
	}
}

// function to record a new root node
function recordRootNode(page, tabId) {
	console.log('recording root node');
	page.id = nodeIndex;
	setTabStatus(tabId, page);
	data = page;
	localStorage.setItem(page.data.date, JSON.stringify(data));
	nodeIndex += 1;
}

// function to record a new child node
function recordChildNode(page, tabId, refTabId) {
	console.log('recording child node');
	// assign page an id from nodeIndex counter
	page.id = nodeIndex;
	// lookup parent node id from tabStatus, then find the parent node in the tree
	var parentNodeId = tabStatus[refTabId].id;
	parentNode = findNode(data, parentNodeId);
	// and update the children of the parent
	parentNode.children.push(page);
	localStorage.setItem(data.data.date, JSON.stringify(data));
	nodeIndex += 1;
	setTabStatus(tabId, page);
}

// function to update the tab status object with the page contents of tabId
function setTabStatus(tabId, page) {
	tabStatus[tabId] = page;
	console.log(tabStatus);
}

// recursively look through the JSON tree for the specified node and return it
function findNode(tree, nodeId) {
   if (tree.id === nodeId) return tree;

   var result;
   for (var i = 0; i < tree.children.length; i++) {
      result = findNode(tree.children[i], nodeId);
      if (result !== undefined) return result;
   }
}

function deleteHistoryItem(key) {
	localStorage.removeItem(key);
}

// clears all history including current in-memory tree
function clearHistory() {
	tabStatus = {};
	data = {};
	localStorage.clear();
}

// message listener
chrome.runtime.onMessage.addListener(function(request, sender, response) {
	switch (request.payload) {
		// wikipedia page data sent from injected content script
		case "pageData":
			chrome.tabs.get(sender.tab.id, function(tab) {
				request.pageData.openerId = tab.openerTabId;
				request.pageData.tabId = sender.tab.id;
				console.log(request.pageData);
				savePageData(request.pageData);
			});
		break;

		case "set":
			if (request.key) {
				selectedTree = JSON.parse(localStorage.getItem(request.key));
			}
			else {
				selectedTree = data;
			}
			response();
		break;

		// page requesting json tree object
		case "load":
			response(selectedTree)
		break;

		// history page requesting localStorage object
		case "localStorage":
			response(localStorage);
		break;

		// history page requestion to remove a specific tree by key
		case "delete":
			deleteHistoryItem(request.key);
			response("Tree Deleted");
		break;

		// history page requesting to clear all history
		case "clear":
			clearHistory();
			response("History Cleared");
		break;
	}
})

// listener for when the user clicks on the Wikimapper button
chrome.browserAction.onClicked.addListener(function(tab) {
  chrome.tabs.create({'url': chrome.extension.getURL('html/index.html')}, function(tab) {
  });
});<commit_msg>Corrected error in comment for function savePageData<commit_after>var tabStatus = {};
var data = {};
var nodeIndex = 1;
var selectedTree = {};

// required JSON object structure for using with JIT and d3.js
/*
json = {
	"id" : , "node00",
	"name" : "name",
	"data" : {},
	"children" : [ array of child nodes ]
	}
}
*/

// function to receive page data from a tab and record it appropriately
function savePageData(pageData) {
	var page = { data: {} };
	var tabId = pageData.tabId;
	var openerId = pageData.openerId;

	// populate page data json object
	page.name = pageData.title;
	page.data.url = pageData.url;
	page.data.ref = pageData.ref;
	page.data.date = pageData.date;
	page.children = [];

	console.log('tabId' + tabStatus[tabId]);
	console.log('openerId' + tabStatus[openerId]);
	// if both tabs are not in tabStatus, it is a root page
	if (tabStatus[tabId] == undefined && tabStatus[openerId] == undefined) {
		recordRootNode(page, tabId);
	}
	// if tabId is in tabStatus, then it is the same tab
	else if (tabStatus[tabId] != undefined) {
		recordChildNode(page, tabId, tabId);
	// if openerId is in tabStatus, then it is a new tab
	}
	else if (tabStatus[openerId] != undefined) {
		recordChildNode(page, tabId, openerId);
	}
}

// function to record a new root node
function recordRootNode(page, tabId) {
	console.log('recording root node');
	page.id = nodeIndex;
	setTabStatus(tabId, page);
	data = page;
	localStorage.setItem(page.data.date, JSON.stringify(data));
	nodeIndex += 1;
}

// function to record a new child node
function recordChildNode(page, tabId, refTabId) {
	console.log('recording child node');
	// assign page an id from nodeIndex counter
	page.id = nodeIndex;
	// lookup parent node id from tabStatus, then find the parent node in the tree
	var parentNodeId = tabStatus[refTabId].id;
	parentNode = findNode(data, parentNodeId);
	// and update the children of the parent
	parentNode.children.push(page);
	localStorage.setItem(data.data.date, JSON.stringify(data));
	nodeIndex += 1;
	setTabStatus(tabId, page);
}

// function to update the tab status object with the page contents of tabId
function setTabStatus(tabId, page) {
	tabStatus[tabId] = page;
	console.log(tabStatus);
}

// recursively look through the JSON tree for the specified node and return it
function findNode(tree, nodeId) {
   if (tree.id === nodeId) return tree;

   var result;
   for (var i = 0; i < tree.children.length; i++) {
      result = findNode(tree.children[i], nodeId);
      if (result !== undefined) return result;
   }
}

function deleteHistoryItem(key) {
	localStorage.removeItem(key);
}

// clears all history including current in-memory tree
function clearHistory() {
	tabStatus = {};
	data = {};
	localStorage.clear();
}

// message listener
chrome.runtime.onMessage.addListener(function(request, sender, response) {
	switch (request.payload) {
		// wikipedia page data sent from injected content script
		case "pageData":
			chrome.tabs.get(sender.tab.id, function(tab) {
				request.pageData.openerId = tab.openerTabId;
				request.pageData.tabId = sender.tab.id;
				console.log(request.pageData);
				savePageData(request.pageData);
			});
		break;

		case "set":
			if (request.key) {
				selectedTree = JSON.parse(localStorage.getItem(request.key));
			}
			else {
				selectedTree = data;
			}
			response();
		break;

		// page requesting json tree object
		case "load":
			response(selectedTree)
		break;

		// history page requesting localStorage object
		case "localStorage":
			response(localStorage);
		break;

		// history page requestion to remove a specific tree by key
		case "delete":
			deleteHistoryItem(request.key);
			response("Tree Deleted");
		break;

		// history page requesting to clear all history
		case "clear":
			clearHistory();
			response("History Cleared");
		break;
	}
})

// listener for when the user clicks on the Wikimapper button
chrome.browserAction.onClicked.addListener(function(tab) {
  chrome.tabs.create({'url': chrome.extension.getURL('html/index.html')}, function(tab) {
  });
});<|endoftext|>


<commit_before>/**
@module ember
@submodule ember-views
*/

import { _Metamorph } from "ember-views/views/metamorph_view";
import { read, chain, subscribe, unsubscribe } from "ember-metal/streams/utils";
import { readComponentFactory } from "ember-views/streams/utils";
import mergeViewBindings from "ember-htmlbars/system/merge-view-bindings";
import EmberError from "ember-metal/error";
import ContainerView from "ember-views/views/container_view";

export default ContainerView.extend(_Metamorph, {
  init: function() {
    this._super.apply(this, arguments);
    var componentNameStream = this._boundComponentOptions.componentNameStream;
    var container = this.container;
    this.componentClassStream = chain(componentNameStream, function() {
      return readComponentFactory(componentNameStream, container);
    });

    subscribe(this.componentClassStream, this._updateBoundChildComponent, this);
    this._updateBoundChildComponent();
  },
  willDestroy: function() {
    unsubscribe(this.componentClassStream, this._updateBoundChildComponent, this);
    this._super.apply(this, arguments);
  },
  _updateBoundChildComponent: function() {
    this.replace(0, 1, [this._createNewComponent()]);
  },
  _createNewComponent: function() {
    var componentClass = read(this.componentClassStream);
    if (!componentClass) {
      throw new EmberError('HTMLBars error: Could not find component named "' + read(this._boundComponentOptions.componentNameStream) + '".');
    }
    var hash    = this._boundComponentOptions;
    var ignore  = ["_boundComponentOptions", "componentClassStream"];
    var hashForComponent = {};

    var prop;
    for (prop in hash) {
      if (ignore.indexOf(prop) !== -1) { continue; }
      hashForComponent[prop] = hash[prop];
    }

    var props   = {};
    mergeViewBindings(this, props, hashForComponent);
    return this.createChildView(componentClass, props);
  }
});
<commit_msg>Do not use `Array.prototype.indexOf` in BoundComponentView.<commit_after>/**
@module ember
@submodule ember-views
*/

import { _Metamorph } from "ember-views/views/metamorph_view";
import { read, chain, subscribe, unsubscribe } from "ember-metal/streams/utils";
import { readComponentFactory } from "ember-views/streams/utils";
import mergeViewBindings from "ember-htmlbars/system/merge-view-bindings";
import EmberError from "ember-metal/error";
import ContainerView from "ember-views/views/container_view";

export default ContainerView.extend(_Metamorph, {
  init: function() {
    this._super.apply(this, arguments);
    var componentNameStream = this._boundComponentOptions.componentNameStream;
    var container = this.container;
    this.componentClassStream = chain(componentNameStream, function() {
      return readComponentFactory(componentNameStream, container);
    });

    subscribe(this.componentClassStream, this._updateBoundChildComponent, this);
    this._updateBoundChildComponent();
  },
  willDestroy: function() {
    unsubscribe(this.componentClassStream, this._updateBoundChildComponent, this);
    this._super.apply(this, arguments);
  },
  _updateBoundChildComponent: function() {
    this.replace(0, 1, [this._createNewComponent()]);
  },
  _createNewComponent: function() {
    var componentClass = read(this.componentClassStream);
    if (!componentClass) {
      throw new EmberError('HTMLBars error: Could not find component named "' + read(this._boundComponentOptions.componentNameStream) + '".');
    }
    var hash    = this._boundComponentOptions;
    var hashForComponent = {};

    var prop;
    for (prop in hash) {
      if (prop === '_boundComponentOptions' || prop === 'componentClassStream') { continue; }
      hashForComponent[prop] = hash[prop];
    }

    var props   = {};
    mergeViewBindings(this, props, hashForComponent);
    return this.createChildView(componentClass, props);
  }
});
<|endoftext|>


<commit_before>const OPENCGA_CLINICAL_REVIEW_CASES_SETTINGS = {
    title: "Case Portal",
    icon: "fas fa-window-restore",
    menu: {
        // merge criterium: internal sections and filters are used to hydrates the external filters list for each section (which is a list of string). Sections and filter order is respected.
        sections: [
            {
                // filters: ["case", "sample", "proband", "family", "disorder", "status", "priority", "type", "assignee"]
                filters: ["id", "family", "proband", "sample", "status", "priority", "type", "date"]
            }
        ],
        // merge criterium: full outer join-like. it adds objects presents in internal array only and in external array only. In case of same id, the external value overwrite the internal.
        examples: [
            /* {
                id: "Intellectual disability2",
                active: false,
                query: {
                    disorder: "Intellectual disability"
                }
            }*/
        ]
    },
    table: {
        // merge criterium: spread operator
        toolbar: {
            showColumns: true,
            showCreate: true,
            showExport: false,
            showDownload: true
            // columns list for the dropdown will be added in grid components based on settings.table.columns
        },
        // merge criterium: uses this array as filter for internal 1D/2D array. It handles row/col span
        // It is supported either columns[] or hiddenColumns[].
        // TODO NOTE this refers to clinical-analysis-grid (same list in clinical-analysis-browser.settings)
        // columns: ["caseId", "probandId", "familyId", "disorderId", "interpretation", "actions"]
    },
    // details: ["clinical-analysis-view", "proband-view"]
    details: ["clinical-analysis-view", "json-view"],
};
<commit_msg>iva: deprecate clinical-review-cases settings #TASK-616<commit_after>// Josemi NOTE 2022-05-02
// DEPRECATED: use clinical-analysis-portal.settings.js instead
const OPENCGA_CLINICAL_REVIEW_CASES_SETTINGS = {
    menu: {
        // merge criterium: internal sections and filters are used to hydrates the external filters list for each section (which is a list of string). Sections and filter order is respected.
        sections: [
            {
                filters: ["case", "sample", "proband", "family", "disorder", "status", "priority", "type", "assignee"]
            }
        ],
        // merge criterium: full outer join-like. it adds objects presents in internal array only and in external array only. In case of same id, the external value overwrite the internal.
        examples: [
            /* {
                id: "Intellectual disability2",
                active: false,
                query: {
                    disorder: "Intellectual disability"
                }
            }*/
        ]
    },
    table: {
        // merge criterium: spread operator
        toolbar: {
            showColumns: true,
            showCreate: true,
            showExport: false,
            showDownload: true
            // columns list for the dropdown will be added in grid components based on settings.table.columns
        },
        // merge criterium: uses this array as filter for internal 1D/2D array. It handles row/col span
        // It is supported either columns[] or hiddenColumns[].
        // TODO NOTE this refers to clinical-analysis-grid (same list in clinical-analysis-browser.settings)
        // columns: ["caseId", "probandId", "familyId", "disorderId", "interpretation", "actions"]
    },
    // details: ["clinical-analysis-view", "proband-view"]
};
<|endoftext|>


<commit_before>'use strict';

var FinanceApp = angular.module('FinanceApp', []);

FinanceApp.controller('FinanceController', function ($scope) {
	$scope.title = 'Stock Market';
	$scope.stocks = [
		{"company": "google", "name": "goog", "value": 1000.0},
		{"company": "facebook", "name": "fb", "value": 900.0},
		{"company": "twitter", "name": "tw", "value": 800.0},
	];
});<commit_msg>counted filtered items<commit_after>'use strict';

var FinanceApp = angular.module('FinanceApp', []);

FinanceApp.controller('FinanceController', function ($scope) {
	$scope.title = 'Stock Market';
	$scope.stocks = [
		{"company": "google", "name": "goog", "value": 1000.0},
		{"company": "facebook", "name": "fb", "value": 900.0},
		{"company": "twitter", "name": "tw", "value": 800.0}
	];
});<|endoftext|>


<commit_before>/* Copyright (c) 2015-2016 The TagSpaces Authors. All rights reserved.
 * Use of this source code is governed by a AGPL3 license that
 * can be found in the LICENSE file. */

/* global define, Handlebars, isNode */
define(function(require, exports, module) {
  'use strict';
  console.log('Loading audiorecorder.ui.js ...');
  var TSCORE = require('tscore');
  var fileContent;
  var fileType;

  var initUI = function() {

    $('#audioRecordingConfirmButton').click(function() {
      saveAudioVideoFile();
    });

  };

  function saveAudioVideoFile() {
    var fileTags = '';
    var rawTags = $('#newFileNameTagsAudioRecorder').val().split(',');
    rawTags.forEach(function(value, index) {
      if (index === 0) {
        fileTags = value;
      } else {
        fileTags = fileTags + TSCORE.Config.getTagDelimiter() + value;
      }
    });
    //if ($('#tagWithCurrentDate').prop('checked')) {
    //  if (fileTags.length < 1) {
    //    fileTags = TSCORE.TagUtils.formatDateTime4Tag(new Date());
    //  } else {
    //    fileTags = fileTags + TSCORE.Config.getTagDelimiter() + TSCORE.TagUtils.formatDateTime4Tag(new Date());
    //  }
    //}
    if (fileTags.length > 0) {
      fileTags = TSCORE.TagUtils.beginTagContainer + fileTags + TSCORE.TagUtils.endTagContainer;
    }

    console.log(fileContent);

    var filePath = TSCORE.currentPath + TSCORE.dirSeparator + $('#newFileNameAudioRecorder').val() + fileTags + '.' + fileType;
    TSCORE.IO.saveBinaryFilePromise(filePath, fileContent).then(function() {
      TSCORE.showSuccessDialog("File saved successfully.");

    }, function(error) {
      TSCORE.hideLoadingAnimation();
      TSCORE.showAlertDialog("Saving " + filePath + " failed.");
      console.error("Save to file " + filePath + " failed " + error);
    });
  }

  // Navigator.getUserMedia shim
  navigator.getUserMedia =
          navigator.getUserMedia ||
          navigator.webkitGetUserMedia ||
          navigator.mozGetUserMedia ||
          navigator.msGetUserMedia;

  // URL shim
  window.URL = window.URL || window.webkitURL;

  // audio context + .createScriptProcessor shim
  var audioContext = new AudioContext;
  if (audioContext.createScriptProcessor == null) {
    audioContext.createScriptProcessor = audioContext.createJavaScriptNode;
  }

  // Elements (jQuery objects)
  var $testToneLevel = $('#testToneLevel'),
          $microphone = $('#microphone'),
          $microphoneLevel = $('#microphoneLevel'),
  //$timeLimit = $('#time-limit'),
          $encoding = $('input[name="encoding"]'),
          $encodingOption = $('#encoding-option'),
  //$encodingProcess = $('input[name="encoding-process"]'),
  //$reportInterval = $('#report-interval'),
  //$bufferSize = $('#buffer-size'),
          $recording = $('#recording'),
          $timeDisplay = $('#time-display'),
          $record = $('#record'),
          $cancel = $('#cancel'),
          $dateTime = $('#date-time'),
          $recordingList = $('#recordingList'),
          $modalLoading = $('#modal-loading'),
          $modalProgress = $('#modal-progress'),
          $modalError = $('#modal-error');

  // Initialize input element states (required for reloading page on Firefox)
  $testToneLevel.attr('disabled', false);
  $testToneLevel[0].valueAsNumber = 0;
  $microphone.attr('disabled', false);
  $microphone[0].checked = false;
  $microphoneLevel.attr('disabled', false);
  $microphoneLevel[0].valueAsNumber = 0;
//  $timeLimit.attr('disabled', false);
//  $timeLimit[0].valueAsNumber = 3;
  $encoding.attr('disabled', false);
  $encoding[0].checked = true;
  //$encodingProcess.attr('disabled', false);
  //$encodingProcess[0].checked = true;
  //$reportInterval.attr('disabled', false);
  //$reportInterval[0].valueAsNumber = 1;
  //$bufferSize.attr('disabled', false);

  var testTone = (function() {
    var osc = audioContext.createOscillator(),
            lfo = audioContext.createOscillator(),
            ampMod = audioContext.createGain(),
            output = audioContext.createGain();
    lfo.type = 'square';
    lfo.frequency.value = 2;
    osc.connect(ampMod);
    lfo.connect(ampMod.gain);
    output.gain.value = 0.5;
    ampMod.connect(output);
    osc.start();
    lfo.start();
    return output;
  })();

  var testToneLevel = audioContext.createGain(),
          microphone = undefined,     // obtained by user click
          microphoneLevel = audioContext.createGain(),
          mixer = audioContext.createGain();
  testTone.connect(testToneLevel);
  testToneLevel.gain.value = 0;
  testToneLevel.connect(mixer);
  microphoneLevel.gain.value = 0;
  microphoneLevel.connect(mixer);
  mixer.connect(audioContext.destination);

  // Audio recorder object
  var audioRecorder = new WebAudioRecorder(mixer, {
    workerDir: 'libs/audio-record/',
    onEncoderLoading: function(recorder, encoding) {
      $modalLoading.find('.modal-title').html("Loading " + encoding.toUpperCase() + " encoder ...");
      $modalLoading.modal('show');
    },
    onEncoderLoaded: function() {
      $modalLoading.modal('hide');
    }
  });

  // Mixer levels
  $testToneLevel.on('input', function() {
    var level = $testToneLevel[0].valueAsNumber / 100;
    testToneLevel.gain.value = level * level;
  });

  $microphoneLevel.on('input', function() {
    var level = $microphoneLevel[0].valueAsNumber / 100;
    microphoneLevel.gain.value = level * level;
  });

  // Obtaining microphone input
  $microphone.click(function() {
    if (microphone == null)
      navigator.getUserMedia({audio: true},
              function(stream) {
                microphone = audioContext.createMediaStreamSource(stream);
                microphone.connect(microphoneLevel);
                $microphone.attr('disabled', true);
                $microphoneLevel.removeClass('hidden');
              },
              function(error) {
                $microphone[0].checked = false;
                audioRecorder.onError(audioRecorder, "Could not get audio input.");
              });
  });

  // Recording time limit
  function plural(n) {
    return n > 1 ? "s" : "";
  }

  /*$timeLimit.on('input', function() {
   var min = $timeLimit[0].valueAsNumber;
   $('#time-limit-text').html("" + min + " minute" + plural(min));
   });*/

  // Encoding selector + encoding options
  var OGG_QUALITY = [-0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
          OGG_KBPS = [45, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 500],
          MP3_BIT_RATE = [64, 80, 96, 112, 128, 160, 192, 224, 256, 320],
          ENCODING_OPTION = {
            wav: {
              label: '',
              hidden: true,
              max: 1,
              text: function(val) {
                return '';
              }
            },
            ogg: {
              label: 'Quality',
              hidden: false,
              max: OGG_QUALITY.length - 1,
              text: function(val) {
                return OGG_QUALITY[val].toFixed(1) +
                        " (~" + OGG_KBPS[val] + "kbps)";
              }
            },
            mp3: {
              label: 'Bit rate',
              hidden: false,
              max: MP3_BIT_RATE.length - 1,
              text: function(val) {
                return "" + MP3_BIT_RATE[val] + "kbps";
              }
            }
          },
          optionValue = {
            wav: null,
            ogg: 6,
            mp3: 5
          };

  $encoding.click(function(event) {
    var encoding = $(event.target).attr('encoding'),
            option = ENCODING_OPTION[encoding];
    audioRecorder.setEncoding(encoding);
    $('#encoding-option-label').html(option.label);
    $('#encoding-option-text').html(option.text(optionValue[encoding]));
    $encodingOption.toggleClass('hidden', option.hidden).attr('max', option.max);
    $encodingOption[0].valueAsNumber = optionValue[encoding];
  });

//  $encodingOption.on('input', function() {
//    var encoding = audioRecorder.encoding,
//            option = ENCODING_OPTION[encoding];
//    optionValue[encoding] = $encodingOption[0].value;
//    $('#encoding-option-text').html(option.text(optionValue[encoding]));
//  });
//
//// encoding process selector
//  var encodingProcess = 'background';
//
//  $encodingProcess.click(function(event) {
//    encodingProcess = $(event.target).attr('mode');
//    var hidden = encodingProcess === 'background';
//    $('#report-interval-label').toggleClass('hidden', hidden);
//    //$reportInterval.toggleClass('hidden', hidden);
//    $('#report-interval-text').toggleClass('hidden', hidden);
//  });

  /*$reportInterval.on('input', function() {
   var sec = $reportInterval[0].valueAsNumber;
   $('#report-interval-text').html("" + sec + " second" + (plural(sec)));
   });*/

  // Processor buffer size
  var BUFFER_SIZE = [256, 512, 1024, 2048, 4096, 8192, 16384];

  var defaultBufSz = (function() {
    var processor = audioContext.createScriptProcessor(undefined, 2, 2);
    return processor.bufferSize;
  })();

  var iDefBufSz = BUFFER_SIZE.indexOf(defaultBufSz);

  //$bufferSize[0].valueAsNumber = iDefBufSz;   // initialize with browser default

  function updateBufferSizeText() {
    //var iBufSz = $bufferSize[0].valueAsNumber, text = "" + BUFFER_SIZE[iBufSz];
    var iBufSz = iDefBufSz;
    var text = "" + BUFFER_SIZE[iBufSz];
    if (iBufSz === iDefBufSz)
      text += ' (browser default)';
    $('#buffer-size-text').html(text);
  }

  updateBufferSizeText();         // initialize text

  /*$bufferSize.on('input', function() {
   updateBufferSizeText();
   });*/

  // Save/Delete recording
  function saveRecording(blob, encoding) {
    var time = new Date();
    var url = URL.createObjectURL(blob);
    //var html = "
"+
    //        "<audio controls src='" + url + "'></audio> " +//" ("+encoding.toUpperCase()+")"+time
    //        " Save " +
    //        "<button class='btn btn-danger' style='margin-top:-15px' recording='" + url + "'>Delete</button>"+"
";
    //
    //if ($recordingList.empty()) {
    //  $recordingList.append($(html));
    //} else {
    //  $recordingList.removeAttribute(html);
    //}

    $('#recordingUrl').prop('recording', url);
    $('#formFileCreateAudioRecorder').prop('recording', url);
    $('#audioRecordingUrl').attr('src', url);
    $('#deleteAudioRecording').prop('recording', url);

    fileContent = blob;
    // Default new file in text file
    fileType = 'wav' || 'ogg';
    $('#newFileNameTagsAudioRecorder').select2('data', null);
    $('#newFileNameTagsAudioRecorder').select2({
      multiple: true,
      tags: TSCORE.Config.getAllTags(),
      tokenSeparators: [
        ',',
        ' '
      ],
      minimumInputLength: 1,
      selectOnBlur: true
    });
    $('#newFileNameAudioRecorder').val('');
    //$('#tagWithCurrentDate').prop('checked', false);
    $('#txtFileTypeButtonAudioRecorder').button('toggle');
    $('#formFileCreateAudioRecorder').validator();
    $('#formFileCreateAudioRecorder').submit(function(e) {
      e.preventDefault();
    });
    $('#formFileCreateAudioRecorder').on('invalid.bs.validator', function() {
      $('#audioRecordingConfirmButton').prop('disabled', true);
    });
    $('#formFileCreateAudioRecorder').on('valid.bs.validator', function() {
      $('#audioRecordingConfirmButton').prop('disabled', false);
    });
    $('#audioRecordingDialog').on('shown.bs.modal', function() {
      $('#newFileNameAudioRecorder').select2().focus();
    });
  }

  $recordingList.on('click', 'button', function(event) {
    var url = $(event.target).attr('recording');
    $("p[recording='" + url + "']").remove();
    URL.revokeObjectURL(url);
  });

  // Time indicator
  function minSecStr(n) {
    return (n < 10 ? "0" : "") + n;
  }

  function updateDateTime() {
    var sec = audioRecorder.recordingTime() | 0;
    $timeDisplay.html(minSecStr(sec / 60 | 0) + ":" + minSecStr(sec % 60));
    $dateTime.html((new Date).toString());
  }

  window.setInterval(updateDateTime, 200);

  // Encoding progress report modal
  var progressComplete = false;

  function setProgress(progress) {
    var percent = (progress * 100).toFixed(1) + "%";
    $modalProgress.find('.progress-bar').attr('style', "width: " + percent + ";");
    $modalProgress.find('.text-center').html(percent);
    progressComplete = progress === 1;
  }

  $modalProgress.on("hide.bs.modal", function() {
    if (!progressComplete)
      audioRecorder.cancelEncoding();
  });

  // record | stop | cancel buttons
  function disableControlsOnRecord(disabled) {
    if (microphone == null)
      $microphone.attr('disabled', disabled);
    //$timeLimit.attr('disabled', disabled);
    $encoding.attr('disabled', disabled);
    $encodingOption.attr('disabled', disabled);
    //$encodingProcess.attr('disabled', disabled);
    //$reportInterval.attr('disabled', disabled);
    //$bufferSize.attr('disabled', disabled);
  }

  function startRecording() {
    $recording.removeClass('hidden');
    $record.html('STOP');
    $cancel.removeClass('hidden');
    disableControlsOnRecord(true);
    audioRecorder.setOptions({
      //timeLimit: $timeLimit[0].valueAsNumber * 60,
      //encodeAfterRecord: encodingProcess === 'separate',
      //progressInterval: $reportInterval[0].valueAsNumber * 1000,
      ogg: {quality: OGG_QUALITY[optionValue.ogg]},
    });
    audioRecorder.startRecording();
    setProgress(0);
  }

  function stopRecording(finish) {
    $recording.addClass('hidden');
    $record.html('RECORD');
    $cancel.addClass('hidden');
    disableControlsOnRecord(false);
    if (finish) {
      audioRecorder.finishRecording();
      if (audioRecorder.options.encodeAfterRecord) {
        $modalProgress.find('.modal-title').html("Encoding " + audioRecorder.encoding.toUpperCase());
        $modalProgress.modal('show');
      }
    } else
      audioRecorder.cancelRecording();
  }

  $record.click(function() {
    if (audioRecorder.isRecording())
      stopRecording(true);
    else
      startRecording();
  });

  $cancel.click(function() {
    stopRecording(false);
  });

  // Event handlers
  audioRecorder.onTimeout = function(recorder) {
    stopRecording(true);
  };

  audioRecorder.onEncodingProgress = function(recorder, progress) {
    setProgress(progress);
  };

  audioRecorder.onComplete = function(recorder, blob) {
    if (recorder.options.encodeAfterRecord)
      $modalProgress.modal('hide');
    saveRecording(blob, recorder.encoding);
  };

  audioRecorder.onError = function(recorder, message) {
    $modalError.find('.alert').html(message);
    $modalError.modal('show');
  };

  // Public API definition
  exports.initUI = initUI;

});
<commit_msg>clean code<commit_after>/* Copyright (c) 2015-2016 The TagSpaces Authors. All rights reserved.
 * Use of this source code is governed by a AGPL3 license that
 * can be found in the LICENSE file. */

/* global define, Handlebars, isNode */
define(function(require, exports, module) {
  'use strict';
  console.log('Loading audiorecorder.ui.js ...');
  var TSCORE = require('tscore');
  var fileContent;
  var fileType;

  var initUI = function() {

    $('#audioRecordingConfirmButton').click(function() {
      saveAudioVideoFile();
    });

  };

  function saveAudioVideoFile() {
    var fileTags = '';
    var rawTags = $('#newFileNameTagsAudioRecorder').val().split(',');
    rawTags.forEach(function(value, index) {
      if (index === 0) {
        fileTags = value;
      } else {
        fileTags = fileTags + TSCORE.Config.getTagDelimiter() + value;
      }
    });
    //if ($('#tagWithCurrentDate').prop('checked')) {
    //  if (fileTags.length < 1) {
    //    fileTags = TSCORE.TagUtils.formatDateTime4Tag(new Date());
    //  } else {
    //    fileTags = fileTags + TSCORE.Config.getTagDelimiter() + TSCORE.TagUtils.formatDateTime4Tag(new Date());
    //  }
    //}
    if (fileTags.length > 0) {
      fileTags = TSCORE.TagUtils.beginTagContainer + fileTags + TSCORE.TagUtils.endTagContainer;
    }

    console.log(fileContent);

    var filePath = TSCORE.currentPath + TSCORE.dirSeparator + $('#newFileNameAudioRecorder').val() + fileTags + '.' + fileType;
    TSCORE.IO.saveBinaryFilePromise(filePath, fileContent).then(function() {
      TSCORE.showSuccessDialog("File saved successfully.");

    }, function(error) {
      TSCORE.hideLoadingAnimation();
      TSCORE.showAlertDialog("Saving " + filePath + " failed.");
      console.error("Save to file " + filePath + " failed " + error);
    });
  }

  // Navigator.getUserMedia shim
  navigator.getUserMedia =
          navigator.getUserMedia ||
          navigator.webkitGetUserMedia ||
          navigator.mozGetUserMedia ||
          navigator.msGetUserMedia;

  // URL shim
  window.URL = window.URL || window.webkitURL;

  // audio context + .createScriptProcessor shim
  var audioContext = new AudioContext();
  if (audioContext.createScriptProcessor === null) {
    audioContext.createScriptProcessor = audioContext.createJavaScriptNode;
  }

  // Elements (jQuery objects)
  var $testToneLevel = $('#testToneLevel'),
          $microphone = $('#microphone'),
          $microphoneLevel = $('#microphoneLevel'),
  //$timeLimit = $('#time-limit'),
          $encoding = $('input[name="encoding"]'),
          $encodingOption = $('#encoding-option'),
  //$encodingProcess = $('input[name="encoding-process"]'),
  //$reportInterval = $('#report-interval'),
  //$bufferSize = $('#buffer-size'),
          $recording = $('#recording'),
          $timeDisplay = $('#time-display'),
          $record = $('#record'),
          $cancel = $('#cancel'),
          $dateTime = $('#date-time'),
          $recordingList = $('#recordingList'),
          $modalLoading = $('#modal-loading'),
          $modalProgress = $('#modal-progress'),
          $modalError = $('#modal-error');

  // Initialize input element states (required for reloading page on Firefox)
  $testToneLevel.attr('disabled', false);
  $testToneLevel[0].valueAsNumber = 0;
  $microphone.attr('disabled', false);
  $microphone[0].checked = false;
  $microphoneLevel.attr('disabled', false);
  $microphoneLevel[0].valueAsNumber = 0;
//  $timeLimit.attr('disabled', false);
//  $timeLimit[0].valueAsNumber = 3;
  $encoding.attr('disabled', false);
  $encoding[0].checked = true;
  //$encodingProcess.attr('disabled', false);
  //$encodingProcess[0].checked = true;
  //$reportInterval.attr('disabled', false);
  //$reportInterval[0].valueAsNumber = 1;
  //$bufferSize.attr('disabled', false);

  var testTone = (function() {
    var osc = audioContext.createOscillator(),
            lfo = audioContext.createOscillator(),
            ampMod = audioContext.createGain(),
            output = audioContext.createGain();
    lfo.type = 'square';
    lfo.frequency.value = 2;
    osc.connect(ampMod);
    lfo.connect(ampMod.gain);
    output.gain.value = 0.5;
    ampMod.connect(output);
    osc.start();
    lfo.start();
    return output;
  })();

  var testToneLevel = audioContext.createGain(),
          microphone,     // obtained by user click
          microphoneLevel = audioContext.createGain(),
          mixer = audioContext.createGain();
  testTone.connect(testToneLevel);
  testToneLevel.gain.value = 0;
  testToneLevel.connect(mixer);
  microphoneLevel.gain.value = 0;
  microphoneLevel.connect(mixer);
  mixer.connect(audioContext.destination);

  // Audio recorder object
  var audioRecorder = new WebAudioRecorder(mixer, {
    workerDir: 'libs/audio-record/',
    onEncoderLoading: function(recorder, encoding) {
      $modalLoading.find('.modal-title').html("Loading " + encoding.toUpperCase() + " encoder ...");
      $modalLoading.modal('show');
    },
    onEncoderLoaded: function() {
      $modalLoading.modal('hide');
    }
  });

  // Mixer levels
  $testToneLevel.on('input', function() {
    var level = $testToneLevel[0].valueAsNumber / 100;
    testToneLevel.gain.value = level * level;
  });

  $microphoneLevel.on('input', function() {
    var level = $microphoneLevel[0].valueAsNumber / 100;
    microphoneLevel.gain.value = level * level;
  });

  // Obtaining microphone input
  $microphone.click(function() {
    if (microphone === null) {
      navigator.getUserMedia({audio: true},
              function(stream) {
                microphone = audioContext.createMediaStreamSource(stream);
                microphone.connect(microphoneLevel);
                $microphone.attr('disabled', true);
                $microphoneLevel.removeClass('hidden');
              },
              function(error) {
                $microphone[0].checked = false;
                audioRecorder.onError(audioRecorder, "Could not get audio input.");
              });
    }
  });

  // Recording time limit
  function plural(n) {
    return n > 1 ? "s" : "";
  }

  /*$timeLimit.on('input', function() {
   var min = $timeLimit[0].valueAsNumber;
   $('#time-limit-text').html("" + min + " minute" + plural(min));
   });*/

  // Encoding selector + encoding options
  var OGG_QUALITY = [-0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
          OGG_KBPS = [45, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 500],
          MP3_BIT_RATE = [64, 80, 96, 112, 128, 160, 192, 224, 256, 320],
          ENCODING_OPTION = {
            wav: {
              label: '',
              hidden: true,
              max: 1,
              text: function(val) {
                return '';
              }
            },
            ogg: {
              label: 'Quality',
              hidden: false,
              max: OGG_QUALITY.length - 1,
              text: function(val) {
                return OGG_QUALITY[val].toFixed(1) +
                        " (~" + OGG_KBPS[val] + "kbps)";
              }
            },
            mp3: {
              label: 'Bit rate',
              hidden: false,
              max: MP3_BIT_RATE.length - 1,
              text: function(val) {
                return "" + MP3_BIT_RATE[val] + "kbps";
              }
            }
          },
          optionValue = {
            wav: null,
            ogg: 6,
            mp3: 5
          };

  $encoding.click(function(event) {
    var encoding = $(event.target).attr('encoding'),
            option = ENCODING_OPTION[encoding];
    audioRecorder.setEncoding(encoding);
    $('#encoding-option-label').html(option.label);
    $('#encoding-option-text').html(option.text(optionValue[encoding]));
    $encodingOption.toggleClass('hidden', option.hidden).attr('max', option.max);
    $encodingOption[0].valueAsNumber = optionValue[encoding];
  });

//  $encodingOption.on('input', function() {
//    var encoding = audioRecorder.encoding,
//            option = ENCODING_OPTION[encoding];
//    optionValue[encoding] = $encodingOption[0].value;
//    $('#encoding-option-text').html(option.text(optionValue[encoding]));
//  });
//
//// encoding process selector
//  var encodingProcess = 'background';
//
//  $encodingProcess.click(function(event) {
//    encodingProcess = $(event.target).attr('mode');
//    var hidden = encodingProcess === 'background';
//    $('#report-interval-label').toggleClass('hidden', hidden);
//    //$reportInterval.toggleClass('hidden', hidden);
//    $('#report-interval-text').toggleClass('hidden', hidden);
//  });

  /*$reportInterval.on('input', function() {
   var sec = $reportInterval[0].valueAsNumber;
   $('#report-interval-text').html("" + sec + " second" + (plural(sec)));
   });*/

  // Processor buffer size
  var BUFFER_SIZE = [256, 512, 1024, 2048, 4096, 8192, 16384];

  var defaultBufSz = (function() {
    var processor = audioContext.createScriptProcessor(undefined, 2, 2);
    return processor.bufferSize;
  })();

  var iDefBufSz = BUFFER_SIZE.indexOf(defaultBufSz);

  //$bufferSize[0].valueAsNumber = iDefBufSz;   // initialize with browser default

  function updateBufferSizeText() {
    //var iBufSz = $bufferSize[0].valueAsNumber, text = "" + BUFFER_SIZE[iBufSz];
    var iBufSz = iDefBufSz;
    var text = "" + BUFFER_SIZE[iBufSz];
    if (iBufSz === iDefBufSz) {
      text += ' (browser default)';
    }
    $('#buffer-size-text').html(text);
  }

  updateBufferSizeText();         // initialize text

  /*$bufferSize.on('input', function() {
   updateBufferSizeText();
   });*/

  // Save/Delete recording
  function saveRecording(blob, encoding) {
    var time = new Date();
    var url = URL.createObjectURL(blob);
    //var html = "
"+
    //        "<audio controls src='" + url + "'></audio> " +//" ("+encoding.toUpperCase()+")"+time
    //        " Save " +
    //        "<button class='btn btn-danger' style='margin-top:-15px' recording='" + url + "'>Delete</button>"+"
";
    //
    //if ($recordingList.empty()) {
    //  $recordingList.append($(html));
    //} else {
    //  $recordingList.removeAttribute(html);
    //}

    $('#recordingUrl').prop('recording', url);
    $('#formFileCreateAudioRecorder').prop('recording', url);
    $('#audioRecordingUrl').attr('src', url);
    $('#deleteAudioRecording').prop('recording', url);

    fileContent = blob;
    // Default new file in text file
    fileType = 'wav' || 'ogg';
    $('#newFileNameTagsAudioRecorder').select2('data', null);
    $('#newFileNameTagsAudioRecorder').select2({
      multiple: true,
      tags: TSCORE.Config.getAllTags(),
      tokenSeparators: [
        ',',
        ' '
      ],
      minimumInputLength: 1,
      selectOnBlur: true
    });
    $('#newFileNameAudioRecorder').val('');
    //$('#tagWithCurrentDate').prop('checked', false);
    $('#txtFileTypeButtonAudioRecorder').button('toggle');
    $('#formFileCreateAudioRecorder').validator();
    $('#formFileCreateAudioRecorder').submit(function(e) {
      e.preventDefault();
    });
    $('#formFileCreateAudioRecorder').on('invalid.bs.validator', function() {
      $('#audioRecordingConfirmButton').prop('disabled', true);
    });
    $('#formFileCreateAudioRecorder').on('valid.bs.validator', function() {
      $('#audioRecordingConfirmButton').prop('disabled', false);
    });
    $('#audioRecordingDialog').on('shown.bs.modal', function() {
      $('#newFileNameAudioRecorder').select2().focus();
    });
  }

  $recordingList.on('click', 'button', function(event) {
    var url = $(event.target).attr('recording');
    $("p[recording='" + url + "']").remove();
    URL.revokeObjectURL(url);
  });

  // Time indicator
  function minSecStr(n) {
    return (n < 10 ? "0" : "") + n;
  }

  function updateDateTime() {
    var sec = audioRecorder.recordingTime() | 0;
    $timeDisplay.html(minSecStr(sec / 60 | 0) + ":" + minSecStr(sec % 60));
    $dateTime.html((new Date()).toString());
  }

  window.setInterval(updateDateTime, 200);

  // Encoding progress report modal
  var progressComplete = false;

  function setProgress(progress) {
    var percent = (progress * 100).toFixed(1) + "%";
    $modalProgress.find('.progress-bar').attr('style', "width: " + percent + ";");
    $modalProgress.find('.text-center').html(percent);
    progressComplete = progress === 1;
  }

  $modalProgress.on("hide.bs.modal", function() {
    if (!progressComplete) {
      audioRecorder.cancelEncoding();
    }
  });

  // record | stop | cancel buttons
  function disableControlsOnRecord(disabled) {
    if (microphone === null) {
      $microphone.attr('disabled', disabled);
      //$timeLimit.attr('disabled', disabled);
      $encoding.attr('disabled', disabled);
      $encodingOption.attr('disabled', disabled);
      //$encodingProcess.attr('disabled', disabled);
      //$reportInterval.attr('disabled', disabled);
      //$bufferSize.attr('disabled', disabled);
    }
  }

  function startRecording() {
    $recording.removeClass('hidden');
    $record.html('STOP');
    $cancel.removeClass('hidden');
    disableControlsOnRecord(true);
    audioRecorder.setOptions({
      //timeLimit: $timeLimit[0].valueAsNumber * 60,
      //encodeAfterRecord: encodingProcess === 'separate',
      //progressInterval: $reportInterval[0].valueAsNumber * 1000,
      ogg: {quality: OGG_QUALITY[optionValue.ogg]},
    });
    audioRecorder.startRecording();
    setProgress(0);
  }

  function stopRecording(finish) {
    $recording.addClass('hidden');
    $record.html('RECORD');
    $cancel.addClass('hidden');
    disableControlsOnRecord(false);
    if (finish) {
      audioRecorder.finishRecording();
      if (audioRecorder.options.encodeAfterRecord) {
        $modalProgress.find('.modal-title').html("Encoding " + audioRecorder.encoding.toUpperCase());
        $modalProgress.modal('show');
      }
    } else {
      audioRecorder.cancelRecording();
    }
  }

  $record.click(function() {
    if (audioRecorder.isRecording()) {
      stopRecording(true);
    }
    else {
      startRecording();
    }
  });

  $cancel.click(function() {
    stopRecording(false);
  });

  // Event handlers
  audioRecorder.onTimeout = function(recorder) {
    stopRecording(true);
  };

  audioRecorder.onEncodingProgress = function(recorder, progress) {
    setProgress(progress);
  };

  audioRecorder.onComplete = function(recorder, blob) {
    if (recorder.options.encodeAfterRecord) {
      $modalProgress.modal('hide');
    }
    saveRecording(blob, recorder.encoding);
  };

  audioRecorder.onError = function(recorder, message) {
    $modalError.find('.alert').html(message);
    $modalError.modal('show');
  };

  // Public API definition
  exports.initUI = initUI;

});
<|endoftext|>


<commit_before>
var _ = require('underscore');
var Backbone = require('backbone');

// Methods in the collection prototype that we won't expose
var blacklistedMethods = [
  "_onModelEvent", "_prepareModel", "_removeReference", "_reset", "add",
  "initialize", "sync", "remove", "reset", "set", "push", "pop", "unshift",
  "shift", "sort", "parse", "fetch", "create", "model", "off", "on",
  "listenTo", "listenToOnce", "bind", "trigger", "once", "stopListening"
];

var eventWhiteList = [
  'add', 'remove', 'reset', 'sort', 'destroy'
];

function proxyCollection(from, target) {

  function updateLength() {
    target.length = from.length;
  }

  function pipeEvents(eventName) {
    var args = _.toArray(arguments);
    var isChangeEvent = eventName === 'change' ||
                        eventName.slice(0, 7) === 'change:';

    // In the case of a `reset` event, the Collection.models reference
    // is updated to a new array, so we need to update our reference.
    if (eventName === 'reset') {
      target.models = from.models;
    }

    if (_.contains(eventWhiteList, eventName)) {
      if (_.contains(['add', 'remove', 'destroy'], eventName)) {
        args[2] = target;
      } else if (_.contains(['reset', 'sort'], eventName)) {
        args[1] = target;
      }
      target.trigger.apply(this, args);
    } else if (isChangeEvent) {
      // In some cases I was seeing change events fired after the model
      // had already been removed from the collection.
      if (target.contains(args[1])) {
        target.trigger.apply(this, args);
      }
    }
  }

  var methods = {};

  _.each(_.functions(Backbone.Collection.prototype), function(method) {
    if (!_.contains(blacklistedMethods, method)) {
      methods[method] = function() {
        return from[method].apply(from, arguments);
      };
    }
  });

  _.extend(target, Backbone.Events, methods);

  target.listenTo(from, 'all', updateLength);
  target.listenTo(from, 'all', pipeEvents);
  target.models = from.models;

  updateLength();
  return target;
}

module.exports = proxyCollection;

<commit_msg>Also add the missing events to index.js for browserify users.<commit_after>
var _ = require('underscore');
var Backbone = require('backbone');

// Methods in the collection prototype that we won't expose
var blacklistedMethods = [
  "_onModelEvent", "_prepareModel", "_removeReference", "_reset", "add",
  "initialize", "sync", "remove", "reset", "set", "push", "pop", "unshift",
  "shift", "sort", "parse", "fetch", "create", "model", "off", "on",
  "listenTo", "listenToOnce", "bind", "trigger", "once", "stopListening"
];

var eventWhiteList = [
  'add', 'remove', 'reset', 'sort', 'destroy', 'sync', 'request', 'error'
];

function proxyCollection(from, target) {

  function updateLength() {
    target.length = from.length;
  }

  function pipeEvents(eventName) {
    var args = _.toArray(arguments);
    var isChangeEvent = eventName === 'change' ||
                        eventName.slice(0, 7) === 'change:';

    // In the case of a `reset` event, the Collection.models reference
    // is updated to a new array, so we need to update our reference.
    if (eventName === 'reset') {
      target.models = from.models;
    }

    if (_.contains(eventWhiteList, eventName)) {
      if (_.contains(['add', 'remove', 'destroy'], eventName)) {
        args[2] = target;
      } else if (_.contains(['reset', 'sort'], eventName)) {
        args[1] = target;
      }
      target.trigger.apply(this, args);
    } else if (isChangeEvent) {
      // In some cases I was seeing change events fired after the model
      // had already been removed from the collection.
      if (target.contains(args[1])) {
        target.trigger.apply(this, args);
      }
    }
  }

  var methods = {};

  _.each(_.functions(Backbone.Collection.prototype), function(method) {
    if (!_.contains(blacklistedMethods, method)) {
      methods[method] = function() {
        return from[method].apply(from, arguments);
      };
    }
  });

  _.extend(target, Backbone.Events, methods);

  target.listenTo(from, 'all', updateLength);
  target.listenTo(from, 'all', pipeEvents);
  target.models = from.models;

  updateLength();
  return target;
}

module.exports = proxyCollection;

<|endoftext|>


<commit_before>pageflow.EditorView = Backbone.View.extend({
  events: {
    'click a': function(event) {
      // prevent default for all links
      if (!$(event.currentTarget).attr('target') &&
          !$(event.currentTarget).attr('download') &&
          !$(event.currentTarget).attr('href')) {
        return false;
      }
    }
  },

  initialize: function() {
    $(window).on('beforeunload', function(event) {
      if (pageflow.entry.get('uploading_files_count') > 0)  {
        return I18n.t('pageflow.editor.views.editor_views.files_pending_warning');
      }
    });
  },

  render: function() {
    this.$el.layout({
      minSize: 300,
      togglerTip_closed: I18n.t('pageflow.editor.views.editor_views.show_editor'),
      togglerTip_open: I18n.t('pageflow.editor.views.editor_views.hide_editor'),
      resizerTip: I18n.t('pageflow.editor.views.editor_views.resize_editor'),
      enableCursorHotkey: false,
      fxName: 'none',

      onresize: function() {
        pageflow.app.trigger('resize');
      }
    });

    new pageflow.UploaderView().render();

    this.$el.append(new pageflow.LockedView({
      model: pageflow.editLock
    }).render().el);

    this.$el.append(new pageflow.HelpView().render().el);
  }
});<commit_msg>Prevent scrolling preview while forus in sidebar<commit_after>pageflow.EditorView = Backbone.View.extend({
  scrollNavigationKeys: _.values({
    pageUp: 33,
    pageDown: 34,
    end: 35,
    home: 36,
    left: 37,
    up: 38,
    right: 39,
    down: 40
  }),

  events: {
    'click a': function(event) {
      // prevent default for all links
      if (!$(event.currentTarget).attr('target') &&
          !$(event.currentTarget).attr('download') &&
          !$(event.currentTarget).attr('href')) {
        return false;
      }
    },

    'keydown sidebar': function(event) {
      this.preventScrollingPreviewWhileFocusInSidebar(event);
    }
  },

  initialize: function() {
    $(window).on('beforeunload', function(event) {
      if (pageflow.entry.get('uploading_files_count') > 0)  {
        return I18n.t('pageflow.editor.views.editor_views.files_pending_warning');
      }
    });
  },

  render: function() {
    this.$el.layout({
      minSize: 300,
      togglerTip_closed: I18n.t('pageflow.editor.views.editor_views.show_editor'),
      togglerTip_open: I18n.t('pageflow.editor.views.editor_views.hide_editor'),
      resizerTip: I18n.t('pageflow.editor.views.editor_views.resize_editor'),
      enableCursorHotkey: false,
      fxName: 'none',

      onresize: function() {
        pageflow.app.trigger('resize');
      }
    });

    new pageflow.UploaderView().render();

    this.$el.append(new pageflow.LockedView({
      model: pageflow.editLock
    }).render().el);

    this.$el.append(new pageflow.HelpView().render().el);
  },

  preventScrollingPreviewWhileFocusInSidebar: function(event) {
    if (this.scrollNavigationKeys.indexOf(event.which) >= 0) {
      event.stopPropagation();
    }
  }
});<|endoftext|>


<commit_before>/**
 * Helpers and utils for working with GCM push.
 */

var angular = require('angular');

var constants = require('./constants');

var GCMNotificationService = function (
  $state, $cordovaLocalNotification, acmUserDefaults, acmAPI, acmPushNotificationHelpers) {

  var handleMessage = function (e) {
    var isForeground = e.foreground;

    acmPushNotificationHelpers.updateUserDefaults(e.payload);

    var currentState = $state.current.name;
    if (isForeground) {
      var message = acmUserDefaults.getUserDefault(acmUserDefaults.keys.ACTION);
      message = acmPushNotificationHelpers.truncateString(message, 140);

      // parameter documentation:
      // https://github.com/katzer/cordova-plugin-local-notifications#further-informations-1
      window.plugin.notification.local.add({
        icon: 'notification_icon',
        id: constants.PUSH_RECEIVED_FOREGROUND_NOTIFICATION_ID,
        title: acmUserDefaults.getUserDefault(acmUserDefaults.keys.ACTION_TITLE),
        message: message,
        autoCancel: true
      });
      $state.go('acm.homeTabs.home', {}, {reload: true});
    } else {
      // If the app's backgrounded, any push notification received redirects the user to the action
      // page, updated for the most recent action, irrespective of whether they've completed the
      // welcome carousel.
      $state.go('acm.homeTabs.home', {}, {reload: true});
      // Force-set the has completed welcome flag, to avoid sending the user back to the carousel
      // if they've ever been to the action page via this handler.
      acmUserDefaults.setUserDefault(acmUserDefaults.keys.USER_HAS_COMPLETED_WELCOME, true);
    }
  };

  var handlerLookup = {
    'registered': function (e) {
      acmPushNotificationHelpers.registerDeviceId(e.regid);
    },
    'message': handleMessage
  };

  return {
    handleNotification: function (e) {

      var error = function (err) {
        console.error('GCM error received: ' + err.msg);
        // Not a lot that can be done here
      };

      // Default to firing the error handler if it's an unrecognized event type.
      (handlerLookup[e.event] || error)(e);
    },

    registrationSuccess: function (event) {
      // No-op, as the registration is handled via the event interface
      // NOTE: this doesn't actually indicate that the device registered remotely, it will fire even
      //       if the device is in airplane mode etc.
    },

    registrationError: function (err) {
      console.error('Unable to register for GCM push: ' + err);
    }

  };

};

module.exports = GCMNotificationService;
<commit_msg>use eff logo instead of default bell icon fixes #54 and silence notifications if notifications are disabled while app is in foreground refs #56<commit_after>/**
 * Helpers and utils for working with GCM push.
 */

var angular = require('angular');

var constants = require('./constants');

var GCMNotificationService = function (
  $state, $cordovaLocalNotification, acmUserDefaults, acmAPI, acmPushNotificationHelpers) {

  var handleMessage = function (e) {
    var isForeground = e.foreground;

    acmPushNotificationHelpers.updateUserDefaults(e.payload);

    var currentState = $state.current.name;
    if (isForeground) {
      var message = acmUserDefaults.getUserDefault(acmUserDefaults.keys.ACTION);
      message = acmPushNotificationHelpers.truncateString(message, 140);

      if (acmUserDefaults.getUserDefault(acmUserDefaults.keys.PUSH_ENABLED) !== false) {
        // parameter documentation:
        // https://github.com/katzer/cordova-plugin-local-notifications#further-informations-1
        window.plugin.notification.local.add({
          smallIcon: 'res://notification_icon',
          id: constants.PUSH_RECEIVED_FOREGROUND_NOTIFICATION_ID,
          title: acmUserDefaults.getUserDefault(acmUserDefaults.keys.ACTION_TITLE),
          message: message,
          autoCancel: true
        });
      }
      $state.go('acm.homeTabs.home', {}, {reload: true});
    } else {
      // If the app's backgrounded, any push notification received redirects the user to the action
      // page, updated for the most recent action, irrespective of whether they've completed the
      // welcome carousel.
      $state.go('acm.homeTabs.home', {}, {reload: true});
      // Force-set the has completed welcome flag, to avoid sending the user back to the carousel
      // if they've ever been to the action page via this handler.
      acmUserDefaults.setUserDefault(acmUserDefaults.keys.USER_HAS_COMPLETED_WELCOME, true);
    }
  };

  var handlerLookup = {
    'registered': function (e) {
      acmPushNotificationHelpers.registerDeviceId(e.regid);
    },
    'message': handleMessage
  };

  return {
    handleNotification: function (e) {

      var error = function (err) {
        console.error('GCM error received: ' + err.msg);
        // Not a lot that can be done here
      };

      // Default to firing the error handler if it's an unrecognized event type.
      (handlerLookup[e.event] || error)(e);
    },

    registrationSuccess: function (event) {
      // No-op, as the registration is handled via the event interface
      // NOTE: this doesn't actually indicate that the device registered remotely, it will fire even
      //       if the device is in airplane mode etc.
    },

    registrationError: function (err) {
      console.error('Unable to register for GCM push: ' + err);
    }

  };

};

module.exports = GCMNotificationService;
<|endoftext|>


<commit_before>var pollInterval = 1000 * 10; // 1 minute, in milliseconds
var timerId;

function updateBadge() {
    // check updates
    checkHowManyNewUpdate();
}

function checkHowManyNewUpdate() {
    var lastUpdateTime = "";

    chrome.storage.local.get('lastUpdateTime', function(result) {
        console.log(result)
        // if undefined
        if (!result.lastUpdateTime) {
            setLastUpdateTime();
        }

        getNumberOfNotRead(result.lastUpdateTime, function(count) {
            if (count !== 0) {
                chrome.browserAction.setBadgeText({ text: count.toString() });
            }
        });
    });
}

// set lastUpdateTime
function setLastUpdateTime() {
    updater.getAllBlogs(function(postList) {
        var firstPost = postList[0];

        if (firstPost) {
            var meta = firstPost.meta;
            chrome.storage.local.set({ 'lastUpdateTime': meta });
        }
    });
}

// get number of not read
function getNumberOfNotRead(lastUpdateTime, callback) {
    var count = 0;

    updater.getAllBlogs(function(postList) {
        var post = {};
        for (var i = 0; i < postList.length; i++) {
            post = postList[i];

            if (post.meta === lastUpdateTime) {
                callback(count);
                return;
            } else {
                count++;
            }
        }

        callback(count);
    });

}

function startRequest() {
    updateBadge();
    timerId = window.setTimeout(startRequest, pollInterval);
}

function stopRequest() {
    window.clearTimeout(timerId);
}

// startRequest
startRequest();

<commit_msg>1. check how many not read in background 2. show the update number in tthe icon<commit_after>var pollInterval = 1000 * 60 * 60; // 1 minute, in milliseconds
var timerId;

function updateBadge() {
    // check updates
    checkHowManyNewUpdate();
}

function checkHowManyNewUpdate() {
    var lastUpdateTime = "";

    chrome.storage.local.get('lastUpdateTime', function(result) {
        console.log(result)
        // if undefined
        if (!result.lastUpdateTime) {
            setLastUpdateTime();
        }

        getNumberOfNotRead(result.lastUpdateTime, function(count) {
            if (count !== 0) {
                chrome.browserAction.setBadgeText({ text: count.toString() });
            }
        });
    });
}

// set lastUpdateTime
function setLastUpdateTime() {
    updater.getAllBlogs(function(postList) {
        var firstPost = postList[0];

        if (firstPost) {
            var meta = firstPost.meta;
            chrome.storage.local.set({ 'lastUpdateTime': meta });
        }
    });
}

// get number of not read
function getNumberOfNotRead(lastUpdateTime, callback) {
    var count = 0;

    updater.getAllBlogs(function(postList) {
        var post = {};
        for (var i = 0; i < postList.length; i++) {
            post = postList[i];

            if (post.meta === lastUpdateTime) {
                callback(count);
                return;
            } else {
                count++;
            }
        }

        callback(count);
    });

}

function startRequest() {
    updateBadge();
    timerId = window.setTimeout(startRequest, pollInterval);
}

function stopRequest() {
    window.clearTimeout(timerId);
}

// startRequest
startRequest();

<|endoftext|>


<commit_before>'use strict';

var strValue = String.prototype.valueOf;

module.exports = function isString(value) {
	if (typeof value === 'string') { return true; }
	if (typeof value !== 'object') { return false; }
	try {
		strValue.call(value);
		return true;
	} catch (e) {
		return false;
	}
};
<commit_msg>Refactor to aid optimization of non-try/catch code.<commit_after>'use strict';

var strValue = String.prototype.valueOf;
var tryStringObject = function tryStringObject(value) {
	try {
		strValue.call(value);
		return true;
	} catch (e) {
		return false;
	}
};

module.exports = function isString(value) {
	if (typeof value === 'string') { return true; }
	if (typeof value !== 'object') { return false; }
	return tryStringObject(value);
};
<|endoftext|>


<commit_before>function RegularOrderForm() {

  var that = this;
  this.initialize = function(){
    $("#recurring-order-form a.delete").click(function(){
      var ids = this.attributes["id"].value.replace("delete_","").split('_');
      var listId = ids[0];
      var itemId = ids[1];

      $.ajax({
        url: 'api/recurring_lists/' + itemId,
        type: 'PUT',
        data: {recurring_list_item: {id: itemId, destroy: true}},
        complete: function(result){
          window.location.reload(true);
        }
      });
    });
  }

}

$(document).ready(function() {
  var regularOrderForm = new RegularOrderForm();
  regularOrderForm.initialize();
})
<commit_msg>Making delete work for recurring lists<commit_after>function RegularOrderForm() {

  var that = this;
  this.initialize = function(){
    $("#recurring-order-form a.delete").click(function(){
      var ids = this.attributes["id"].value.replace("delete_","").split('_');
      var listId = ids[0];
      var itemId = ids[1];

      Spree.ajax({
        url: 'api/recurring_lists/' + listId,
        type: 'PUT',
        headers: {'X-Spree-Token': Spree.api_key},
        data: {recurring_list_item: {id: itemId, destroy: true}},
        complete: function(result){
          window.location.reload(true);
        }
      });
    });
  }

}

$(document).ready(function() {
  var regularOrderForm = new RegularOrderForm();
  regularOrderForm.initialize();
})
<|endoftext|>


<commit_before>/*
 * Copyright 2014, Digium, Inc.
 * All rights reserved.
 *
 * This source code is licensed under The MIT License found in the
 * LICENSE file in the root directory of this source tree.
 *
 * For all details and documentation:  https://www.respoke.io
 */

/*
 * Respoke Chrome Screen Sharing
 * This extension provides screen sharing functionality for the Respoke client library.
 */

var mediaSources = ["screen", "window"];

chrome.extension.onConnect.addListener(function (port) {
    console.assert(port.name === "respoke-port");

    port.onMessage.addListener(function (msg) {
        switch (msg) {
            case "bg-respoke-available":
                port.postMessage({type: "ct-respoke-available", available: true});
                break;
            case "bg-respoke-source-id":
                chrome.desktopCapture.chooseDesktopMedia(mediaSources, port.sender.tab, function (sourceId) {
                    if (!sourceId) {
                        port.postMessage({type: "ct-respoke-source-id", error: 'PermissionDeniedError'});
                        return;
                    }

                    port.postMessage({
                        type: "ct-respoke-source-id",
                        sourceId: sourceId
                    });
                });
                break;
        }
    });
});

/*
 * The below section is added so that the extension starts working after installation/reloading of the extension
 * For this section to work, you must add the "tabs" permission in the manifest
 */

chrome.manifest = chrome.app.getDetails();

var injectIntoTab = function (tab) {
    var scripts = chrome.manifest.content_scripts[0].js;
    scripts.forEach(function(script){
        // this script is going to throw an exception in the console for the extension
        // it'll throw the exception if you inject into a tab it's not allowed access to
        // you can't catch that exception with a try/catch
        // it doesn't stop anything from working and doesn't show up in the tab's console either
        chrome.tabs.executeScript(tab.id, {
            file: script
        });
    });
}

chrome.windows.getAll({
    populate: true
}, function (windows) {
    windows.forEach(function(){
        currentWindow.tabs.forEach(function(currentTab){
            // Skip chrome:// and http:// (except localhost) pages
            // if you have a very specific domain(s) that you're running the extension on, you could change
            // this if statement to match those domains to save on extra work and injecting into tabs that you have
            // no rights to
            if( ! currentTab.url.match(/(chrome|http):\/\//gi) || currentTab.url.match(/http:\/\/localhost/gi)) {
                injectIntoTab(currentTab);
            }
        })
    });
});
<commit_msg>add currentWindow var into scope<commit_after>/*
 * Copyright 2014, Digium, Inc.
 * All rights reserved.
 *
 * This source code is licensed under The MIT License found in the
 * LICENSE file in the root directory of this source tree.
 *
 * For all details and documentation:  https://www.respoke.io
 */

/*
 * Respoke Chrome Screen Sharing
 * This extension provides screen sharing functionality for the Respoke client library.
 */

var mediaSources = ["screen", "window"];

chrome.extension.onConnect.addListener(function (port) {
    console.assert(port.name === "respoke-port");

    port.onMessage.addListener(function (msg) {
        switch (msg) {
            case "bg-respoke-available":
                port.postMessage({type: "ct-respoke-available", available: true});
                break;
            case "bg-respoke-source-id":
                chrome.desktopCapture.chooseDesktopMedia(mediaSources, port.sender.tab, function (sourceId) {
                    if (!sourceId) {
                        port.postMessage({type: "ct-respoke-source-id", error: 'PermissionDeniedError'});
                        return;
                    }

                    port.postMessage({
                        type: "ct-respoke-source-id",
                        sourceId: sourceId
                    });
                });
                break;
        }
    });
});

/*
 * The below section is added so that the extension starts working after installation/reloading of the extension
 * For this section to work, you must add the "tabs" permission in the manifest
 */

chrome.manifest = chrome.app.getDetails();

var injectIntoTab = function (tab) {
    var scripts = chrome.manifest.content_scripts[0].js;
    scripts.forEach(function(script){
        // this script is going to throw an exception in the console for the extension
        // it'll throw the exception if you inject into a tab it's not allowed access to
        // you can't catch that exception with a try/catch
        // it doesn't stop anything from working and doesn't show up in the tab's console either
        chrome.tabs.executeScript(tab.id, {
            file: script
        });
    });
}

chrome.windows.getAll({
    populate: true
}, function (windows) {
    windows.forEach(function(currentWindow){
        currentWindow.tabs.forEach(function(currentTab){
            // Skip chrome:// and http:// (except localhost) pages
            // if you have a very specific domain(s) that you're running the extension on, you could change
            // this if statement to match those domains to save on extra work and injecting into tabs that you have
            // no rights to
            if( ! currentTab.url.match(/(chrome|http):\/\//gi) || currentTab.url.match(/http:\/\/localhost/gi)) {
                injectIntoTab(currentTab);
            }
        })
    });
});
<|endoftext|>


<commit_before>import test from 'ava';
import React from 'react';
import { shallow } from 'enzyme';
import { ForecastTile } from './ForecastTile';

const setup = () => {
  const spies = {
  };
  const props = {
    address: {
      city: 'Austin',
      state: 'Texas',
      country: 'US',
      latitude: 30.22,
      longitude: -97.74,
    },
  };
  const component = shallow(<ForecastTile {...props.address} />);

  return { spies, props, component };
};

test.todo('write tests for ForecastTile once complete.');
test('(Component) Renders with expected elements', t => {
  const { component } = setup();

  t.true(component.is('Table'),
    'is wrapped by a Table');
});
<commit_msg>update forecast test<commit_after>import test from 'ava';
import React from 'react';
import { shallow } from 'enzyme';
import { ForecastTile } from './ForecastTile';

const setup = () => {
  const spies = {
  };
  const props = {
    address: {
      city: 'Austin',
      state: 'Texas',
      country: 'US',
      latitude: 30.22,
      longitude: -97.74,
    },
  };
  const component = shallow(<ForecastTile {...props} />);

  return { spies, props, component };
};

test.todo('write tests for ForecastTile once complete.');
test('(Component) Renders with expected elements', t => {
  const { component } = setup();

  t.true(component.is('Table'),
    'is wrapped by a Table');
});
<|endoftext|>