<commit_before>(function(global) {
  'use strict';
  var app = global.app || {};
  var m = global.m;
  var util = global.util;

  var TimelineController = app.TimelineController;

  var kebabCase = util.kebabCase;
  var loadData = util.loadData;
  var saveData = util.saveData;
  var windowWidth = util.windowWidth;

  var ActionController = function(option) {
    this.headerController = m.prop(option.headerController);
    this.timeAxisController = m.prop(option.timeAxisController);
    this.timelineListController = m.prop(option.timelineListController);
  };

  ActionController.prototype.start = function() {
    var headerController = this.headerController();
    var timeAxisController = this.timeAxisController();
    var timelineListController = this.timelineListController();

    var daysAgo = loadData('days-ago', 183);
    var daysAfter = loadData('days-after', 183);
    var pixelsPerDay = loadData('pixels-per-day' ,8);

    headerController.daysAgo(daysAgo);
    headerController.daysAfter(daysAfter);
    headerController.pixelsPerDay(pixelsPerDay);

    timeAxisController.daysAgo(daysAgo);
    timeAxisController.daysAfter(daysAfter);
    timeAxisController.pixelsPerDay(pixelsPerDay);

    timelineListController.timelineControllers(defaultTimelineListControllers({
      daysAgo: daysAgo,
      daysAfter: daysAfter,
      pixelsPerDay: pixelsPerDay
    }));

    headerController.onchange = onChangeHeaderController.bind(this);
    headerController.ontoday = onTodayHeaderController.bind(this);
    timelineListController.oninit = onInitTimelineListController.bind(this);
    timelineListController.onscroll = onScrollTimelineListController.bind(this);
  };

  var defaultTimelineListControllers = function(option) {
    var now = new Date();
    var year = now.getFullYear();
    var month = now.getMonth();

    return [
      new TimelineController({
        title: 'Line Chart',
        type: TimelineController.TYPE_LINE_CHART,
        data: [
          {date: new Date(year, month, 1), value: 500},
          {date: new Date(year, month, 5), value: 100},
          {date: new Date(year, month, 17), value: 2000},
          {date: new Date(year, month, 31), value: 700}
        ],
        daysAgo: option.daysAgo,
        daysAfter: option.daysAfter,
        pixelsPerDay: option.pixelsPerDay
      }),
      new TimelineController({
        title: 'Bar Chart',
        type: TimelineController.TYPE_BAR_CHART,
        data: [
          {date: new Date(year, month, 1), value: 100},
          {date: new Date(year, month, 2), value: 200},
          {date: new Date(year, month, 3), value: 500},
          {date: new Date(year, month, 8), value: 200}
        ],
        daysAgo: option.daysAgo,
        daysAfter: option.daysAfter,
        pixelsPerDay: option.pixelsPerDay
      }),
      new TimelineController({
        title: 'Schedule',
        type: TimelineController.TYPE_SCHEDULE,
        data: [
          {date: new Date(year, month - 1, 26), value: month + '/26 A', link: '#'},
          {date: new Date(year, month, 1), value: (month + 1) + '/1 B'},
          {date: new Date(year, month, 4), value: (month + 1) + '/4 C'},
          {date: new Date(year, month, 7), value: (month + 1) + '/7 D'},
          {date: new Date(year, month, 10), value: (month + 1) + '/10 E'},
          {date: new Date(year, month, 17), value: (month + 1) + '/17 F'},
          {date: new Date(year, month, 18), value: (month + 1) + '/18 G'},
          {date: new Date(year, month, 19), duration: 6, value: (month + 1) + '/19-24 H'},
          {date: new Date(year, month, 24), value: (month + 1) + '/24 I'},
          {date: new Date(year, month, 29), value: (month + 1) + '/29 J'}
        ],
        daysAgo: option.daysAgo,
        daysAfter: option.daysAfter,
        pixelsPerDay: option.pixelsPerDay
      }),
      new TimelineController({
        title: 'Gantt Chart',
        type: TimelineController.TYPE_GANTT_CHART,
        data: [
          {
            data: [
              {date: new Date(year, month, 16), duration: 5, value: 'a', color: 'pink'},
              {date: new Date(year, month, 21), duration: 3, value: 'b', color: 'gold'},
              {date: new Date(year, month, 24), duration: 3, value: 'c', color: 'lime'}
            ],
            deadline: new Date(year, month, 30),
            value: 'A',
            link: '#'
          },
          {
            data: [
              {date: new Date(year, month, 10), duration: 5, value: 'a'},
              {date: new Date(year, month, 15), duration: 3, value: 'b'},
              {date: new Date(year, month, 18), duration: 3, value: 'c'}
            ],
            value: 'B'
          },
          {
            data: [
              {date: new Date(year, month, 1), duration: 5, value: 'a'},
              {date: new Date(year, month, 6), duration: 3, value: 'b'},
              {date: new Date(year, month, 9), duration: 3, value: 'c'}
            ],
            value: 'C'
          },
          {
            data: [
              {date: new Date(year, month - 1, 21), duration: 5, value: 'a'},
              {date: new Date(year, month - 1, 26), duration: 3, value: 'b'},
              {date: new Date(year, month - 1, 29), duration: 3, value: 'c'}
            ],
            value: 'D'
          }
        ],
        daysAgo: option.daysAgo,
        daysAfter: option.daysAfter,
        pixelsPerDay: option.pixelsPerDay
      })
    ];
  };

  var updateScrollLeftPosition = function(ctrl, value) {
    var timelineListController = ctrl.timelineListController();

    // need only adjust timeline list scroll position
    // timeline list scroll event transferred to time axis
    timelineListController.scrollLeft(value);
  };

  var onChangeHeaderController = function(event) {
    var timeAxisController = this.timeAxisController();
    var timelineListController = this.timelineListController();

    // get values before change
    var daysAgo = timeAxisController.daysAgo();
    var pixelsPerDay = timeAxisController.pixelsPerDay();
    var scrollLeft = timelineListController.scrollLeft();

    var name = event.name;
    var value = event.value;

    timeAxisController[name](value);
    timelineListController[name](value);

    saveData(kebabCase(name), value);

    m.redraw();

    // adjust scroll position after redraw
    if (name === 'daysAgo') {
      scrollLeft += (value - daysAgo) * pixelsPerDay;
    } else if (name === 'pixelsPerDay') {
      var scrollDays = (scrollLeft + windowWidth() / 2) / pixelsPerDay;
      scrollLeft += scrollDays * (value - pixelsPerDay);
    }

    updateScrollLeftPosition(this, scrollLeft);
  };

  var onTodayHeaderController = function() {
    var headerController = this.headerController();
    var timelineListController = this.timelineListController();

    var daysAgo = headerController.daysAgo();
    var pixelsPerDay = headerController.pixelsPerDay();
    var scrollLeft = (daysAgo + 0.5) * pixelsPerDay - windowWidth() / 2;

    updateScrollLeftPosition(this, scrollLeft);
  };

  var onInitTimelineListController = function() {
    onTodayHeaderController.call(this);
  };

  var onScrollTimelineListController = function(event) {
    var timeAxisController = this.timeAxisController();
    timeAxisController.scrollLeft(event.scrollLeft);
  };

  app.ActionController = ActionController;
  global.app = app;
})(this);<commit_msg>Refactor action-controller<commit_after>(function(global) {
  'use strict';
  var app = global.app || {};
  var m = global.m;
  var util = global.util;

  var TimelineController = app.TimelineController;

  var kebabCase = util.kebabCase;
  var startOfDay = util.startOfDay;
  var loadData = util.loadData;
  var saveData = util.saveData;
  var windowWidth = util.windowWidth;

  var ActionController = function(option) {
    this.headerController = m.prop(option.headerController);
    this.timeAxisController = m.prop(option.timeAxisController);
    this.timelineListController = m.prop(option.timelineListController);
  };

  ActionController.prototype.start = function() {
    var headerController = this.headerController();
    var timeAxisController = this.timeAxisController();
    var timelineListController = this.timelineListController();

    var daysAgo = loadData('days-ago', 183);
    var daysAfter = loadData('days-after', 183);
    var pixelsPerDay = loadData('pixels-per-day' ,8);

    headerController.daysAgo(daysAgo);
    headerController.daysAfter(daysAfter);
    headerController.pixelsPerDay(pixelsPerDay);

    timeAxisController.daysAgo(daysAgo);
    timeAxisController.daysAfter(daysAfter);
    timeAxisController.pixelsPerDay(pixelsPerDay);

    timelineListController.timelineControllers(defaultTimelineListControllers({
      daysAgo: daysAgo,
      daysAfter: daysAfter,
      pixelsPerDay: pixelsPerDay
    }));

    headerController.onchange = onChangeHeaderController.bind(this);
    headerController.ontoday = onTodayHeaderController.bind(this);
    timelineListController.oninit = onInitTimelineListController.bind(this);
    timelineListController.onscroll = onScrollTimelineListController.bind(this);
  };

  var defaultTimelineListControllers = function(option) {
    var today = startOfDay();
    var year = today.getFullYear();
    var month = today.getMonth();

    return [
      new TimelineController({
        title: 'Line Chart',
        type: TimelineController.TYPE_LINE_CHART,
        data: [
          {date: new Date(year, month, 1), value: 500},
          {date: new Date(year, month, 5), value: 100},
          {date: new Date(year, month, 17), value: 2000},
          {date: new Date(year, month, 31), value: 700}
        ],
        daysAgo: option.daysAgo,
        daysAfter: option.daysAfter,
        pixelsPerDay: option.pixelsPerDay
      }),
      new TimelineController({
        title: 'Bar Chart',
        type: TimelineController.TYPE_BAR_CHART,
        data: [
          {date: new Date(year, month, 1), value: 100},
          {date: new Date(year, month, 2), value: 200},
          {date: new Date(year, month, 3), value: 500},
          {date: new Date(year, month, 8), value: 200}
        ],
        daysAgo: option.daysAgo,
        daysAfter: option.daysAfter,
        pixelsPerDay: option.pixelsPerDay
      }),
      new TimelineController({
        title: 'Schedule',
        type: TimelineController.TYPE_SCHEDULE,
        data: [
          {date: new Date(year, month - 1, 26), value: month + '/26 A', link: '#'},
          {date: new Date(year, month, 1), value: (month + 1) + '/1 B'},
          {date: new Date(year, month, 4), value: (month + 1) + '/4 C'},
          {date: new Date(year, month, 7), value: (month + 1) + '/7 D'},
          {date: new Date(year, month, 10), value: (month + 1) + '/10 E'},
          {date: new Date(year, month, 17), value: (month + 1) + '/17 F'},
          {date: new Date(year, month, 18), value: (month + 1) + '/18 G'},
          {date: new Date(year, month, 19), duration: 6, value: (month + 1) + '/19-24 H'},
          {date: new Date(year, month, 24), value: (month + 1) + '/24 I'},
          {date: new Date(year, month, 29), value: (month + 1) + '/29 J'}
        ],
        daysAgo: option.daysAgo,
        daysAfter: option.daysAfter,
        pixelsPerDay: option.pixelsPerDay
      }),
      new TimelineController({
        title: 'Gantt Chart',
        type: TimelineController.TYPE_GANTT_CHART,
        data: [
          {
            data: [
              {date: new Date(year, month, 16), duration: 5, value: 'a', color: 'pink'},
              {date: new Date(year, month, 21), duration: 3, value: 'b', color: 'gold'},
              {date: new Date(year, month, 24), duration: 3, value: 'c', color: 'lime'}
            ],
            deadline: new Date(year, month, 30),
            value: 'A',
            link: '#'
          },
          {
            data: [
              {date: new Date(year, month, 10), duration: 5, value: 'a'},
              {date: new Date(year, month, 15), duration: 3, value: 'b'},
              {date: new Date(year, month, 18), duration: 3, value: 'c'}
            ],
            value: 'B'
          },
          {
            data: [
              {date: new Date(year, month, 1), duration: 5, value: 'a'},
              {date: new Date(year, month, 6), duration: 3, value: 'b'},
              {date: new Date(year, month, 9), duration: 3, value: 'c'}
            ],
            value: 'C'
          },
          {
            data: [
              {date: new Date(year, month - 1, 21), duration: 5, value: 'a'},
              {date: new Date(year, month - 1, 26), duration: 3, value: 'b'},
              {date: new Date(year, month - 1, 29), duration: 3, value: 'c'}
            ],
            value: 'D'
          }
        ],
        daysAgo: option.daysAgo,
        daysAfter: option.daysAfter,
        pixelsPerDay: option.pixelsPerDay
      })
    ];
  };

  var updateScrollLeftPosition = function(ctrl, value) {
    var timelineListController = ctrl.timelineListController();

    // need only adjust timeline list scroll position
    // timeline list scroll event transferred to time axis
    timelineListController.scrollLeft(value);
  };

  var onChangeHeaderController = function(event) {
    var timeAxisController = this.timeAxisController();
    var timelineListController = this.timelineListController();

    // get values before change
    var daysAgo = timeAxisController.daysAgo();
    var pixelsPerDay = timeAxisController.pixelsPerDay();
    var scrollLeft = timelineListController.scrollLeft();

    var name = event.name;
    var value = event.value;

    timeAxisController[name](value);
    timelineListController[name](value);

    saveData(kebabCase(name), value);

    m.redraw();

    // adjust scroll position after redraw
    if (name === 'daysAgo') {
      scrollLeft += (value - daysAgo) * pixelsPerDay;
    } else if (name === 'pixelsPerDay') {
      var scrollDays = (scrollLeft + windowWidth() / 2) / pixelsPerDay;
      scrollLeft += scrollDays * (value - pixelsPerDay);
    }

    updateScrollLeftPosition(this, scrollLeft);
  };

  var onTodayHeaderController = function() {
    var headerController = this.headerController();

    var daysAgo = headerController.daysAgo();
    var pixelsPerDay = headerController.pixelsPerDay();
    var scrollLeft = (daysAgo + 0.5) * pixelsPerDay - windowWidth() / 2;

    updateScrollLeftPosition(this, scrollLeft);
  };

  var onInitTimelineListController = function() {
    onTodayHeaderController.call(this);
  };

  var onScrollTimelineListController = function(event) {
    var timeAxisController = this.timeAxisController();
    timeAxisController.scrollLeft(event.scrollLeft);
  };

  app.ActionController = ActionController;
  global.app = app;
})(this);<|endoftext|>


<commit_before>function contactController($scope, $http, vcRecaptchaService, EnvironmentConfig) {
    recaptchaId = null;
    $scope.setRecaptchaId = function (widgetId) {
        console.log(widgetId);
        recaptchaId = widgetId;
    };

    $scope.submit = function () {
        if (!vcRecaptchaService.getResponse(recaptchaId)) {
            $scope.od_captcha = null;
            vcRecaptchaService.reload(recaptchaId);
            alert('Por favor, completa el captcha.');
        } else {
          var formData = $("#contactForm").serialize();
          $.ajax({
            type: 'POST',
            url:  EnvironmentConfig.api + '/email/send',
            data: formData
          }).done(function(response) {
            showMsg(true);
          }).fail(function(data) {
            showMsg(false);
          });
        }
    }

    function showMsg(result) {
      if (result) {
        alert('El mensaje ha sido enviado correctamente');
      } else {
        alert('El mensaje no ha sido enviado, intente nuevamente más tarde');
      }
      document.location.href="/";
    }

}
<commit_msg>add authorization on post contact form<commit_after>function contactController($scope, $http, vcRecaptchaService, EnvironmentConfig,  $rootScope) {
    recaptchaId = null;
    $scope.setRecaptchaId = function (widgetId) {
        console.log(widgetId);
        recaptchaId = widgetId;
    };

    $scope.submit = function () {
      debugger;
        if (!vcRecaptchaService.getResponse(recaptchaId)) {
            $scope.od_captcha = null;
            vcRecaptchaService.reload(recaptchaId);
            alert('Por favor, completa el captcha.');
        } else {
          var token=$rootScope.globals.currentUser.token;
          var formData = $("#contactForm").serialize();
          $.ajax({
            headers: {
                'Authorization': 'Bearer ' + token
            },
            type: 'POST',
            url:  EnvironmentConfig.api + '/email/send',
            data: formData
          }).done(function(response) {
            showMsg(true);
          }).fail(function(data) {
            // showMsg(data);
            console.log(data);
          });
        }
    }

    function showMsg(result) {
      if (result) {
        alert('El mensaje ha sido enviado correctamente');
      } else {
        // alert('El mensaje no ha sido enviado, intente nuevamente más tarde');
      }
      document.location.href="/";
    }

}
<|endoftext|>


<commit_before>/*
* jQuery Mobile Framework : "listview" filter extension
* Copyright (c) jQuery Project
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
(function($, undefined ) {

$.mobile.listview.prototype.options.filter = false;
$.mobile.listview.prototype.options.filterPlaceholder = "Filter items...";
$.mobile.listview.prototype.options.filterTheme = "c";

$( ":jqmData(role='listview')" ).live( "listviewcreate", function() {
	var list = $( this ),
		listview = list.data( "listview" );

	if ( !listview.options.filter ) {
		return;
	}

	var wrapper = $( "<form>", { "class": "ui-listview-filter ui-bar-" + listview.options.filterTheme, "role": "search" } ),

		search = $( "<input>", {
				placeholder: listview.options.filterPlaceholder
			})
			.attr( "data-" + $.mobile.ns + "type", "search" )
			.jqmData( 'lastval', "" )
			.bind( "keyup change", function() {

				var val = this.value.toLowerCase(),
					listItems=null,
					lastval = $( this ).jqmData('lastval')+"";

				//change val as lastval for next execution
				$(this).jqmData( 'lastval' , val );

				change = val.replace( new RegExp( "^" + lastval ) , "" );

				if( val.length < lastval.length || change.length != ( val.length - lastval.length ) ){

					//removed chars or pasted something totaly different, check all items
					listItems = list.children();
				} else {

					//only chars added, not removed, only use visible subset
					listItems = list.children( ':not(.ui-screen-hidden)' );
				}

				if ( val ) {

					// This handles hiding regular rows without the text we search for
					// and any list dividers without regular rows shown under it
					var item,
						childItems = false,
						itemtext="";

					for ( var i = listItems.length - 1; i >= 0; i-- ) {
						item = $( listItems[i] );
						itemtext = item.jqmData( 'filtertext' ) || item.text();

						if ( item.is( "li:jqmData(role=list-divider)" ) ) {

							item.toggleClass( 'ui-filter-hidequeue' , !childItems );

							// New bucket!
							childItems = false;

						} else if ( itemtext.toLowerCase().indexOf( val ) === -1) {

							//mark to be hidden
							item.toggleClass( 'ui-filter-hidequeue' , true );
						} else {

							// There's a shown item in the bucket
							childItems = true;
						}
					}

					// show items, not marked to be hidden
					listItems
						.filter( ':not(.ui-filter-hidequeue)' )
						.toggleClass('ui-screen-hidden',false);

					// hide items, marked to be hidden
					listItems
						.filter( '.ui-filter-hidequeue' )
						.toggleClass('ui-screen-hidden',true)
						.toggleClass( 'ui-filter-hidequeue' , false );

				}else{

					//filtervalue is empty => show all
					listItems.toggleClass('ui-screen-hidden',false);
				}
			})
			.appendTo( wrapper )
			.textinput();

	if ($( this ).jqmData( "inset" ) ) {
		wrapper.addClass( "ui-listview-filter-inset" );
	}

	wrapper.insertBefore( list );
});

})( jQuery );<commit_msg>don't submit the filter form<commit_after>/*
* jQuery Mobile Framework : "listview" filter extension
* Copyright (c) jQuery Project
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
(function($, undefined ) {

$.mobile.listview.prototype.options.filter = false;
$.mobile.listview.prototype.options.filterPlaceholder = "Filter items...";
$.mobile.listview.prototype.options.filterTheme = "c";

$( ":jqmData(role='listview')" ).live( "listviewcreate", function() {
	var list = $( this ),
		listview = list.data( "listview" );

	if ( !listview.options.filter ) {
		return;
	}

	var wrapper = $( "<form>", { "class": "ui-listview-filter ui-bar-" + listview.options.filterTheme, "role": "search" } ),

		search = $( "<input>", {
				placeholder: listview.options.filterPlaceholder
			})
			.attr( "data-" + $.mobile.ns + "type", "search" )
			.jqmData( 'lastval', "" )
			.bind( "keyup change", function() {

				var val = this.value.toLowerCase(),
					listItems=null,
					lastval = $( this ).jqmData('lastval')+"";

				//change val as lastval for next execution
				$(this).jqmData( 'lastval' , val );

				change = val.replace( new RegExp( "^" + lastval ) , "" );

				if( val.length < lastval.length || change.length != ( val.length - lastval.length ) ){

					//removed chars or pasted something totaly different, check all items
					listItems = list.children();
				} else {

					//only chars added, not removed, only use visible subset
					listItems = list.children( ':not(.ui-screen-hidden)' );
				}

				if ( val ) {

					// This handles hiding regular rows without the text we search for
					// and any list dividers without regular rows shown under it
					var item,
						childItems = false,
						itemtext="";

					for ( var i = listItems.length - 1; i >= 0; i-- ) {
						item = $( listItems[i] );
						itemtext = item.jqmData( 'filtertext' ) || item.text();

						if ( item.is( "li:jqmData(role=list-divider)" ) ) {

							item.toggleClass( 'ui-filter-hidequeue' , !childItems );

							// New bucket!
							childItems = false;

						} else if ( itemtext.toLowerCase().indexOf( val ) === -1) {

							//mark to be hidden
							item.toggleClass( 'ui-filter-hidequeue' , true );
						} else {

							// There's a shown item in the bucket
							childItems = true;
						}
					}

					// show items, not marked to be hidden
					listItems
						.filter( ':not(.ui-filter-hidequeue)' )
						.toggleClass('ui-screen-hidden',false);

					// hide items, marked to be hidden
					listItems
						.filter( '.ui-filter-hidequeue' )
						.toggleClass('ui-screen-hidden',true)
						.toggleClass( 'ui-filter-hidequeue' , false );

				}else{

					//filtervalue is empty => show all
					listItems.toggleClass('ui-screen-hidden',false);
				}
			})
			.appendTo( wrapper )
			.textinput();

	if ($( this ).jqmData( "inset" ) ) {
		wrapper.addClass( "ui-listview-filter-inset" );
	}

	wrapper
		.bind( "submit", function() {
			return false;
		})
		.insertBefore( list );
});

})( jQuery );<|endoftext|>


<commit_before>// Copyright 2021, University of Colorado Boulder

/**
 * Dialog with preferences to enable or disable various features for the simulation. Groups of preferences are
 * organized and displayed in a tab panel.
 *
 * @author Jesse Greenberg (PhET Interactive Simulations)
 */

import EnumerationProperty from '../../../axon/js/EnumerationProperty.js';
import Enumeration from '../../../phet-core/js/Enumeration.js';
import merge from '../../../phet-core/js/merge.js';
import PhetFont from '../../../scenery-phet/js/PhetFont.js';
import Node from '../../../scenery/js/nodes/Node.js';
import Text from '../../../scenery/js/nodes/Text.js';
import Dialog from '../../../sun/js/Dialog.js';
import HSeparator from '../../../sun/js/HSeparator.js';
import joist from '../joist.js';
import joistStrings from '../joistStrings.js';
import PreferencesPanels from './PreferencesPanels.js';
import PreferencesTabs from './PreferencesTabs.js';

// constants
const preferencesTitleString = joistStrings.preferences.title;

const TAB_FONT = new PhetFont( 20 );
const TITLE_FONT = new PhetFont( { size: 24, weight: 'bold' } );
const CONTENT_FONT = new PhetFont( 16 );
const PANEL_SECTION_LABEL_FONT = new PhetFont( { weight: 'bold', size: 16 } );

// tabs available in this Dialog
const PreferencesTab = Enumeration.byKeys( [ 'GENERAL', 'VISUAL', 'AUDIO', 'INPUT' ] );

class PreferencesDialog extends Dialog {

  /**
   * @param {PreferencesConfiguration} preferencesConfiguration
   * @param {PreferencesProperties} preferencesProperties
   * @param {BooleanProperty}simSoundProperty
   * @param {Object} [options]
   */
  constructor( preferencesConfiguration, preferencesProperties, simSoundProperty, options ) {

    const titleText = new Text( preferencesTitleString, {
      font: TITLE_FONT,

      // pdom
      tagName: 'h1',
      innerContent: preferencesTitleString
    } );

    options = merge( {
      titleAlign: 'center',
      title: titleText
    }, options );

    // determine which tabs will be supported in this Dialog, true if any entry in a configuration has content
    const supportedTabs = [];
    supportedTabs.push( PreferencesTab.GENERAL ); // There is always a "General" tab
    _.some( preferencesConfiguration.visualOptions, entry => !!entry ) && supportedTabs.push( PreferencesTab.VISUAL );
    _.some( preferencesConfiguration.audioOptions, entry => !!entry ) && supportedTabs.push( PreferencesTab.AUDIO );
    _.some( preferencesConfiguration.inputOptions, entry => !!entry ) && supportedTabs.push( PreferencesTab.INPUT );
    assert && assert( supportedTabs.length > 0, 'Trying to create a PreferencesDialog with no tabs, check PreferencesConfiguration' );

    // the selected PreferencesTab, indicating which tab is visible in the Dialog
    const selectedTabProperty = new EnumerationProperty( PreferencesTab, PreferencesTab.GENERAL );

    // the set of tabs you can can click to activate a tab panel
    const preferencesTabs = new PreferencesTabs( preferencesConfiguration, supportedTabs, selectedTabProperty );

    // the panels of content with UI components to select preferences, only one is displayed at a time
    const preferencesPanels = new PreferencesPanels( preferencesConfiguration, supportedTabs, selectedTabProperty, simSoundProperty, preferencesProperties );

    // visual separator between tabs and panels
    const tabPanelSeparator = new HSeparator( preferencesPanels.width, { lineWidth: 1 } );

    const content = new Node( {
      children: [ preferencesTabs, tabPanelSeparator, preferencesPanels ]
    } );

    // layout
    tabPanelSeparator.centerTop = preferencesTabs.centerBottom;
    preferencesPanels.centerTop = tabPanelSeparator.centerBottom.plusXY( 0, 20 );

    super( content, options );

    // @private {PreferencesTabs}
    this.preferencesTabs = preferencesTabs;
  }

  /**
   * Move focus to the selected tab. Generally to be used when opening the dialog.
   * @private
   */
  focusSelectedTab() {
    this.preferencesTabs.focusSelectedTab();
  }
}

// @public
// @static
PreferencesDialog.PreferencesTab = PreferencesTab;
PreferencesDialog.CONTENT_FONT = CONTENT_FONT;
PreferencesDialog.TAB_FONT = TAB_FONT;
PreferencesDialog.PANEL_SECTION_LABEL_FONT = PANEL_SECTION_LABEL_FONT;

joist.register( 'PreferencesDialog', PreferencesDialog );
export default PreferencesDialog;<commit_msg>mark as dynamic element for CT<commit_after>// Copyright 2021, University of Colorado Boulder

/**
 * Dialog with preferences to enable or disable various features for the simulation. Groups of preferences are
 * organized and displayed in a tab panel.
 *
 * @author Jesse Greenberg (PhET Interactive Simulations)
 */

import EnumerationProperty from '../../../axon/js/EnumerationProperty.js';
import Enumeration from '../../../phet-core/js/Enumeration.js';
import merge from '../../../phet-core/js/merge.js';
import PhetFont from '../../../scenery-phet/js/PhetFont.js';
import Node from '../../../scenery/js/nodes/Node.js';
import Text from '../../../scenery/js/nodes/Text.js';
import Dialog from '../../../sun/js/Dialog.js';
import HSeparator from '../../../sun/js/HSeparator.js';
import joist from '../joist.js';
import joistStrings from '../joistStrings.js';
import PreferencesPanels from './PreferencesPanels.js';
import PreferencesTabs from './PreferencesTabs.js';

// constants
const preferencesTitleString = joistStrings.preferences.title;

const TAB_FONT = new PhetFont( 20 );
const TITLE_FONT = new PhetFont( { size: 24, weight: 'bold' } );
const CONTENT_FONT = new PhetFont( 16 );
const PANEL_SECTION_LABEL_FONT = new PhetFont( { weight: 'bold', size: 16 } );

// tabs available in this Dialog
const PreferencesTab = Enumeration.byKeys( [ 'GENERAL', 'VISUAL', 'AUDIO', 'INPUT' ] );

class PreferencesDialog extends Dialog {

  /**
   * @param {PreferencesConfiguration} preferencesConfiguration
   * @param {PreferencesProperties} preferencesProperties
   * @param {BooleanProperty}simSoundProperty
   * @param {Object} [options]
   */
  constructor( preferencesConfiguration, preferencesProperties, simSoundProperty, options ) {

    const titleText = new Text( preferencesTitleString, {
      font: TITLE_FONT,

      // pdom
      tagName: 'h1',
      innerContent: preferencesTitleString
    } );

    options = merge( {
      titleAlign: 'center',
      title: titleText,

      // phet-io
      phetioDynamicElement: true
    }, options );

    // determine which tabs will be supported in this Dialog, true if any entry in a configuration has content
    const supportedTabs = [];
    supportedTabs.push( PreferencesTab.GENERAL ); // There is always a "General" tab
    _.some( preferencesConfiguration.visualOptions, entry => !!entry ) && supportedTabs.push( PreferencesTab.VISUAL );
    _.some( preferencesConfiguration.audioOptions, entry => !!entry ) && supportedTabs.push( PreferencesTab.AUDIO );
    _.some( preferencesConfiguration.inputOptions, entry => !!entry ) && supportedTabs.push( PreferencesTab.INPUT );
    assert && assert( supportedTabs.length > 0, 'Trying to create a PreferencesDialog with no tabs, check PreferencesConfiguration' );

    // the selected PreferencesTab, indicating which tab is visible in the Dialog
    const selectedTabProperty = new EnumerationProperty( PreferencesTab, PreferencesTab.GENERAL );

    // the set of tabs you can can click to activate a tab panel
    const preferencesTabs = new PreferencesTabs( preferencesConfiguration, supportedTabs, selectedTabProperty );

    // the panels of content with UI components to select preferences, only one is displayed at a time
    const preferencesPanels = new PreferencesPanels( preferencesConfiguration, supportedTabs, selectedTabProperty, simSoundProperty, preferencesProperties );

    // visual separator between tabs and panels
    const tabPanelSeparator = new HSeparator( preferencesPanels.width, { lineWidth: 1 } );

    const content = new Node( {
      children: [ preferencesTabs, tabPanelSeparator, preferencesPanels ]
    } );

    // layout
    tabPanelSeparator.centerTop = preferencesTabs.centerBottom;
    preferencesPanels.centerTop = tabPanelSeparator.centerBottom.plusXY( 0, 20 );

    super( content, options );

    // @private {PreferencesTabs}
    this.preferencesTabs = preferencesTabs;
  }

  /**
   * Move focus to the selected tab. Generally to be used when opening the dialog.
   * @private
   */
  focusSelectedTab() {
    this.preferencesTabs.focusSelectedTab();
  }
}

// @public
// @static
PreferencesDialog.PreferencesTab = PreferencesTab;
PreferencesDialog.CONTENT_FONT = CONTENT_FONT;
PreferencesDialog.TAB_FONT = TAB_FONT;
PreferencesDialog.PANEL_SECTION_LABEL_FONT = PANEL_SECTION_LABEL_FONT;

joist.register( 'PreferencesDialog', PreferencesDialog );
export default PreferencesDialog;<|endoftext|>


<commit_before>import { parser as saxParser } from 'sax';

function isAllowedType(type) {
  switch(type) {
    case 'text': case 'opentag': case 'closetag': case 'doctype':
    case 'processinginstruction': case 'attribute': case 'comment':
    case 'opencdata': case 'closecdata': case 'opennamespace':
    case 'closenamespace': return true;
    default: return false;
  }
}

export function makePulley(xml, options) {
  let self;

  if(!options) options = {};
  let types = options.types || ['opentag', 'closetag', 'text'];
  let queue = [];
  let parser = saxParser(true, {
    xmlns: options.xmlns,
    position: false
  });
  let skipWS = options.skipWhitespaceOnly;
  let trim = options.trim, normalize = options.normalize;
  let textOpts = (t) => {
    if(trim)
      t = t.trim();
    if(normalize)
      t = t.replace(/\s+/g, " ")
    return t;
  };
  let text = null, rawText = null, wsText = null, wsRawText = null;
  let flushText = () => {
    if(text !== null) {
      if(skipWS) {
        queue.push({
          type: 'wstext',
          text: wsText,
          rawText: wsRawText
        });
        wsText = wsRawText = null;
      }
      queue.push({
        type: 'text',
        text,
        rawText
      });
      text = rawText = null;
    }
  };
  parser.onerror = (err) => {
    throw err;
  };
  types.forEach((type) => {
    if(type === 'text') {
      parser.ontext = (t) => {
        let pt = textOpts(t);
        if(skipWS) {
          if(wsText) {
            wsText += pt; wsRawText += t;
          } else {
            wsText = pt; wsRawText = t;
          }
        }
        if(!skipWS || /\S/.test(t)) {
          if(text) {
            text += pt; rawText += t;
          } else {
            text = pt; rawText = t;
          }
        }
      };
      parser.oncdata = (t) => {
        if(text) {
          text += t; rawText += t;
        } else {
          text = rawText = t;
        }
      };
    } else if(type === 'comment') {
      parser.oncomment = (t) => {
        flushText();
        queue.push({
          type: 'comment',
          text: textOpts(t),
          rawText: t
        });
      }
    } else if(type === 'doctype') {
      parser.ondoctype = (t) => {
        flushText();
        queue.push({
          type: 'doctype',
          text: t
        });
      }
    } else if(type === 'closetag') {
      parser.onclosetag = (t) => {
        flushText();
        queue.push({
          type: 'closetag',
          name: t
        });
      }
    } else if(type === 'opencdata' || type === 'closecdata' ||
              type === 'opennamespace' || type === 'closenamespace') {
      parser['on'+type] = (data) => {
        flushText();
        queue.push({ type: type });
      }
    } else if(isAllowedType(type)) {
      parser['on'+type] = (data) => {
        flushText();
        data.type = type;
        queue.push(data);
      }
    } else {
      throw new Error(`${type} isn't an allowed type!`);
    }
  });
  parser.write(xml).close();
  flushText();
  queue.reverse();

  let next = skipWS ? () => {
    let out;
    while((out = queue.pop()) && out.type === 'wstext') {  }
    return out;
  } : () => queue.pop();
  let peek = skipWS ? () => {
    for(let i = queue.length - 1; i >= 0; --i) {
      let v = queue[i];
      if(v.type !== 'wstext') return v;
    }
  } : () => queue[queue.length - 1];
  let nextText = () => {
    let v = queue[queue.length - 1];
    if(v && v.type === 'text') {
      return queue.pop();
    } else if(v && v.type === 'wstext') {
      queue.pop(); queue.pop();
      v.type = 'text';
      return v;
    } else {
      return { type: 'text', text: '', rawText: '' };
    }
  }
  let peekText = () => {
    let v = queue[queue.length - 1];
    if(v && v.type === 'text') {
      return v;
    } else if(v && v.type === 'wstext') {
      return { type: 'text', text: v.text, rawText: v.rawText };
    } else {
      return { type: 'text', text: '', rawText: '' };
    }
  }
  let check = (type, error) => {
    let out = peek();
    assertType(out, type, error);
    return out;
  }
  let checkName = (name, type, wrongNameError, wrongTypeError) => {
    type = type || 'opentag';
    let out = peek();
    assertType(out, type, wrongTypeError || wrongNameError);
    assertName(out, name, wrongNameError);
    return out;
  }
  let expect = (type, error) => {
    let out = check(type, error);
    next();
    return out;
  }
  let expectName = (name, type, wrongNameError, wrongTypeError) => {
    let out = checkName(name, type, wrongNameError, wrongTypeError);
    next();
    return out;
  }
  let loop = (callback, endType) => {
    endType = endType || 'closetag';
    let node;
    while((node = peek()) && node.type !== endType) {
      if(callback(self))
        break;
    }
  }
  let loopTag = (callback, name) => {
    let tag = name ? expectName(name) : expect('opentag');
    let node;
    while((node = peek()) && node.type !== 'closetag') {
      callback(self, tag);
    }
    expectName(tag.name, 'closetag');
    return tag;
  }
  let skipTag = (name) => {
    return loopTag((pulley) => {
      let tag = pulley.peek();
      if(tag.type === 'opentag') {
        pulley.skipTag(tag.name);
      } else {
        pulley.next();
      }
    }, name);
  }
  return self = {
    next,
    peek,
    nextText,
    peekText,
    check,
    checkName,
    expect,
    expectName,
    loop,
    loopTag,
    skipTag
  };
}

export function assertType(node, type, error) {
  if(node === undefined) {
    throw error || new Error(`Expected ${type}; got end of file!`);
  } else if(node.type !== type) {
    throw error || new Error(`Expected ${type}; got ${node.type}: ${nodeRepr(node)}!`);
  }
}
export function assertName(tag, name, error) {
  if(tag.name !== name) {
    throw error ||
          new Error(`${tag.type} had name ${tag.name} instead of ${name}!`);
  }
}

export function nodeRepr(tag) {
  switch(tag.type) {
    case 'text': case 'comment': return `"${tag.text}"`;
    case 'opentag': return `<${tag.name}>`;
    case 'closetag': return `</${tag.name}>`;
    case 'doctype': return `<!${tag.text}>`;
    case 'processinginstruction': return `<?${tag.name} ${tag.body}?>`;
    case 'attribute': return `${tag.name}="${tag.value}"`;
    default:
  }
}
<commit_msg>Fixed the texty stuff some more<commit_after>import { parser as saxParser } from 'sax';

function isAllowedType(type) {
  switch(type) {
    case 'text': case 'opentag': case 'closetag': case 'doctype':
    case 'processinginstruction': case 'attribute': case 'comment':
    case 'opencdata': case 'closecdata': case 'opennamespace':
    case 'closenamespace': return true;
    default: return false;
  }
}

export function makePulley(xml, options) {
  let self;

  if(!options) options = {};
  let types = options.types || ['opentag', 'closetag', 'text'];
  let queue = [];
  let parser = saxParser(true, {
    xmlns: options.xmlns,
    position: false
  });
  let skipWS = options.skipWhitespaceOnly;
  let trim = options.trim, normalize = options.normalize;
  let textOpts = (t) => {
    if(trim)
      t = t.trim();
    if(normalize)
      t = t.replace(/\s+/g, " ")
    return t;
  };
  let text = null, rawText = null, wsText = null, wsRawText = null;
  let flushText = () => {
    if(skipWS && wsText !== null) {
      queue.push({
        type: 'wstext',
        text: wsText,
        rawText: wsRawText,
        wsHasNext: text !== null
      });
      wsText = wsRawText = null;
    }
    if(text !== null) {
      queue.push({
        type: 'text',
        text,
        rawText
      });
      text = rawText = null;
    }
  };
  parser.onerror = (err) => {
    throw err;
  };
  types.forEach((type) => {
    if(type === 'text') {
      parser.ontext = (t) => {
        let pt = textOpts(t);
        if(skipWS) {
          if(wsText) {
            wsText += pt; wsRawText += t;
          } else {
            wsText = pt; wsRawText = t;
          }
        }
        if(!skipWS || /\S/.test(t)) {
          if(text) {
            text += pt; rawText += t;
          } else {
            text = pt; rawText = t;
          }
        }
      };
      parser.oncdata = (t) => {
        if(text) {
          text += t; rawText += t;
        } else {
          text = rawText = t;
        }
      };
    } else if(type === 'comment') {
      parser.oncomment = (t) => {
        flushText();
        queue.push({
          type: 'comment',
          text: textOpts(t),
          rawText: t
        });
      }
    } else if(type === 'doctype') {
      parser.ondoctype = (t) => {
        flushText();
        queue.push({
          type: 'doctype',
          text: t
        });
      }
    } else if(type === 'closetag') {
      parser.onclosetag = (t) => {
        flushText();
        queue.push({
          type: 'closetag',
          name: t
        });
      }
    } else if(type === 'opencdata' || type === 'closecdata' ||
              type === 'opennamespace' || type === 'closenamespace') {
      parser['on'+type] = (data) => {
        flushText();
        queue.push({ type: type });
      }
    } else if(isAllowedType(type)) {
      parser['on'+type] = (data) => {
        flushText();
        data.type = type;
        queue.push(data);
      }
    } else {
      throw new Error(`${type} isn't an allowed type!`);
    }
  });
  parser.write(xml).close();
  flushText();
  queue.reverse();

  let next = skipWS ? () => {
    let out;
    while((out = queue.pop()) && out.type === 'wstext') {  }
    return out;
  } : () => queue.pop();
  let peek = skipWS ? () => {
    for(let i = queue.length - 1; i >= 0; --i) {
      let v = queue[i];
      if(v.type !== 'wstext') return v;
    }
  } : () => queue[queue.length - 1];
  let nextText = () => {
    let v = queue[queue.length - 1];
    if(v && v.type === 'text') {
      return queue.pop();
    } else if(v && v.type === 'wstext') {
      queue.pop();
      if(v.wsHasNext) queue.pop();
      v.type = 'text';
      delete v.wsHasNext;
      return v;
    } else {
      return { type: 'text', text: '', rawText: '' };
    }
  }
  let peekText = () => {
    let v = queue[queue.length - 1];
    if(v && v.type === 'text') {
      return v;
    } else if(v && v.type === 'wstext') {
      return { type: 'text', text: v.text, rawText: v.rawText };
    } else {
      return { type: 'text', text: '', rawText: '' };
    }
  }
  let check = (type, error) => {
    let out = peek();
    assertType(out, type, error);
    return out;
  }
  let checkName = (name, type, wrongNameError, wrongTypeError) => {
    type = type || 'opentag';
    let out = peek();
    assertType(out, type, wrongTypeError || wrongNameError);
    assertName(out, name, wrongNameError);
    return out;
  }
  let expect = (type, error) => {
    let out = check(type, error);
    next();
    return out;
  }
  let expectName = (name, type, wrongNameError, wrongTypeError) => {
    let out = checkName(name, type, wrongNameError, wrongTypeError);
    next();
    return out;
  }
  let loop = (callback, endType) => {
    endType = endType || 'closetag';
    let node;
    while((node = peek()) && node.type !== endType) {
      if(callback(self))
        break;
    }
  }
  let loopTag = (callback, name) => {
    let tag = name ? expectName(name) : expect('opentag');
    let node;
    while((node = peek()) && node.type !== 'closetag') {
      callback(self, tag);
    }
    expectName(tag.name, 'closetag');
    return tag;
  }
  let skipTag = (name) => {
    return loopTag((pulley) => {
      let tag = pulley.peek();
      if(tag.type === 'opentag') {
        pulley.skipTag(tag.name);
      } else {
        pulley.next();
      }
    }, name);
  }
  return self = {
    next,
    peek,
    nextText,
    peekText,
    check,
    checkName,
    expect,
    expectName,
    loop,
    loopTag,
    skipTag
  };
}

export function assertType(node, type, error) {
  if(node === undefined) {
    throw error || new Error(`Expected ${type}; got end of file!`);
  } else if(node.type !== type) {
    throw error || new Error(`Expected ${type}; got ${node.type}: ${nodeRepr(node)}!`);
  }
}
export function assertName(tag, name, error) {
  if(tag.name !== name) {
    throw error ||
          new Error(`${tag.type} had name ${tag.name} instead of ${name}!`);
  }
}

export function nodeRepr(tag) {
  switch(tag.type) {
    case 'text': case 'comment': return `"${tag.text}"`;
    case 'opentag': return `<${tag.name}>`;
    case 'closetag': return `</${tag.name}>`;
    case 'doctype': return `<!${tag.text}>`;
    case 'processinginstruction': return `<?${tag.name} ${tag.body}?>`;
    case 'attribute': return `${tag.name}="${tag.value}"`;
    default:
  }
}
<|endoftext|>


<commit_before>/*
 *   Copyright 2012 OSBI Ltd
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

/**
 * Object which handles sessionworkspace and stores connections and cubes
 * @param username
 * @param password
 * @returns {Session}
 */
var SessionWorkspace = Backbone.Model.extend({

    initialize: function(args, options) {
        // Attach a custom event bus to this model
        _.extend(this, Backbone.Events);
        _.bindAll(this, "process_datasources", "prefetch_dimensions");
        this.initialized = false;
        this.first = true;
        // Check expiration on localStorage
        if (typeof localStorage !== "undefined" && localStorage) {
            if (!Settings.LOCALSTORAGE_EXPIRATION || Settings.LOCALSTORAGE_EXPIRATION === 0) {
                localStorage.clear();
            }
            if (localStorage.getItem('expiration') && localStorage.getItem('expiration') <= (new Date()).getTime()) {
                localStorage.clear();
            } else if (!localStorage.getItem('saiku-version') || (localStorage.getItem('saiku-version') !== Settings.VERSION) ) {
                localStorage.clear();
                localStorage.setItem('saiku-version', Settings.VERSION);
            }
        }
        Saiku.ui.block("Loading datasources....");
        this.fetch({success:this.process_datasources},{});

    },

    refresh: function() {
        typeof localStorage !== "undefined" && localStorage && localStorage.clear();
        this.clear();
        typeof localStorage !== "undefined" && localStorage && localStorage.setItem('saiku-version', Settings.VERSION);
        this.fetch({success:this.process_datasources},{});
    },

    destroy: function() {
        typeof localStorage !== "undefined" && localStorage && localStorage.clear();
        return false;
    },

    process_datasources: function(model, response) {
        // Save session in localStorage for other tabs to use
        if (typeof localStorage !== "undefined" && localStorage && localStorage.getItem('session') === null) {
            localStorage.setItem('session', JSON.stringify(response));

            // Set expiration on localStorage to one day in the future
            var expires = (new Date()).getTime() +  Settings.LOCALSTORAGE_EXPIRATION;
            typeof localStorage !== "undefined" && localStorage && localStorage.setItem('expiration', expires);
        }

        // Generate cube navigation for reuse
        this.cube_navigation = _.template($("#template-cubes").html())({
            connections: response
        });

        // Create cube objects
        this.cube = {};
        this.connections = response;
        _.delay(this.prefetch_dimensions, 20);

        if (!this.initialized) {
            // Show UI
            $(Saiku.toolbar.el).prependTo($("#header"));
            $("#header").show();
            Saiku.ui.unblock();
            // Add initial tab
            Saiku.tabs.render();
            if (!Settings.INITIAL_QUERY) {
                Saiku.tabs.add(new Workspace());
            }
            // Notify the rest of the application that login was successful
            Saiku.events.trigger('session:new', {
                session: this
            });
        } else {
            if (!Settings.INITIAL_QUERY) {
                Saiku.tabs.add(new Workspace());
            }

        }
    },

    prefetch_dimensions: function() {
        for(var i = 0, iLen = this.connections.length; i < iLen; i++) {
            var connection = this.connections[i];
            for(var j = 0, jLen = connection.catalogs.length; j < jLen; j++) {
                var catalog = connection.catalogs[j];
                for(var k = 0, kLen = catalog.schemas.length; k < kLen; k++) {
                    var schema = catalog.schemas[k];
                    for(var l = 0, lLen = schema.cubes.length; l < lLen; l++) {
                        var cube = schema.cubes[l];
                        var key = connection.name + "/" + catalog.name + "/"
                            + ((schema.name == "" || schema.name == null) ? "null" : schema.name)
                            + "/" + encodeURIComponent(cube.name);

                        if (typeof localStorage !== "undefined" && localStorage &&
                            localStorage.getItem("cube." + key) !== null) {
                            this.cube[key] = new Cube(JSON.parse(localStorage.getItem("cube." + key)));
                        } else {
                            this.cube[key] = new Cube({ key: key });
                            if (Settings.DIMENSION_PREFETCH === true) {
                                this.cube[key].fetch();
                            }
                        }
                    }
                }
            }
        }

        // Start routing
        if (!this.initialized && Backbone.history) {
            Backbone.history.start();
            this.initialized = true;
        }
    },

    url: function() {
        if (this.first) {
            this.first = false;
            return encodeURI(Saiku.session.username + "/discover");
        }
        else {
            return encodeURI(Saiku.session.username + "/discover/refresh");
        }
    }
});
<commit_msg>implement session id check for server restarts etc<commit_after>/*
 *   Copyright 2012 OSBI Ltd
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

/**
 * Object which handles sessionworkspace and stores connections and cubes
 * @param username
 * @param password
 * @returns {Session}
 */
var SessionWorkspace = Backbone.Model.extend({

    initialize: function(args, options) {
        // Attach a custom event bus to this model
        _.extend(this, Backbone.Events);
        _.bindAll(this, "process_datasources", "prefetch_dimensions");
        this.initialized = false;
        this.first = true;
        // Check expiration on localStorage
        if (typeof localStorage !== "undefined" && localStorage) {
            if (!Settings.LOCALSTORAGE_EXPIRATION || Settings.LOCALSTORAGE_EXPIRATION === 0) {
                localStorage.clear();
            }
            if (localStorage.getItem('expiration') && localStorage.getItem('expiration') <= (new Date()).getTime()) {
                localStorage.clear();
            } else if (!localStorage.getItem('saiku-version') || (localStorage.getItem('saiku-version') !== Settings.VERSION) ) {
                localStorage.clear();
                localStorage.setItem('saiku-version', Settings.VERSION);
            } else if (!localStorage.getItem('saiku-session') || (localStorage.getItem('saiku-session') !== Saiku.session.get('sessionid')) ) {
                localStorage.clear();
                localStorage.setItem('saiku-session', Saiku.session.get('sessionid'));
            }
        }
        Saiku.ui.block("Loading datasources....");
        this.fetch({success:this.process_datasources},{});

    },

    refresh: function() {
        typeof localStorage !== "undefined" && localStorage && localStorage.clear();
        this.clear();
        typeof localStorage !== "undefined" && localStorage && localStorage.setItem('saiku-version', Settings.VERSION);
        this.fetch({success:this.process_datasources},{});
    },

    destroy: function() {
        typeof localStorage !== "undefined" && localStorage && localStorage.clear();
        return false;
    },

    process_datasources: function(model, response) {
        // Save session in localStorage for other tabs to use
        if (typeof localStorage !== "undefined" && localStorage && localStorage.getItem('session') === null) {
            localStorage.setItem('session', JSON.stringify(response));

            // Set expiration on localStorage to one day in the future
            var expires = (new Date()).getTime() +  Settings.LOCALSTORAGE_EXPIRATION;
            typeof localStorage !== "undefined" && localStorage && localStorage.setItem('expiration', expires);
        }

        // Generate cube navigation for reuse
        this.cube_navigation = _.template($("#template-cubes").html())({
            connections: response
        });

        // Create cube objects
        this.cube = {};
        this.connections = response;
        _.delay(this.prefetch_dimensions, 20);

        if (!this.initialized) {
            // Show UI
            $(Saiku.toolbar.el).prependTo($("#header"));
            $("#header").show();
            Saiku.ui.unblock();
            // Add initial tab
            Saiku.tabs.render();
            if (!Settings.INITIAL_QUERY) {
                Saiku.tabs.add(new Workspace());
            }
            // Notify the rest of the application that login was successful
            Saiku.events.trigger('session:new', {
                session: this
            });
        } else {
            if (!Settings.INITIAL_QUERY) {
                Saiku.tabs.add(new Workspace());
            }

        }
    },

    prefetch_dimensions: function() {
        for(var i = 0, iLen = this.connections.length; i < iLen; i++) {
            var connection = this.connections[i];
            for(var j = 0, jLen = connection.catalogs.length; j < jLen; j++) {
                var catalog = connection.catalogs[j];
                for(var k = 0, kLen = catalog.schemas.length; k < kLen; k++) {
                    var schema = catalog.schemas[k];
                    for(var l = 0, lLen = schema.cubes.length; l < lLen; l++) {
                        var cube = schema.cubes[l];
                        var key = connection.name + "/" + catalog.name + "/"
                            + ((schema.name == "" || schema.name == null) ? "null" : schema.name)
                            + "/" + encodeURIComponent(cube.name);

                        if (typeof localStorage !== "undefined" && localStorage &&
                            localStorage.getItem("cube." + key) !== null) {
                            this.cube[key] = new Cube(JSON.parse(localStorage.getItem("cube." + key)));
                        } else {
                            this.cube[key] = new Cube({ key: key });
                            if (Settings.DIMENSION_PREFETCH === true) {
                                this.cube[key].fetch();
                            }
                        }
                    }
                }
            }
        }

        // Start routing
        if (!this.initialized && Backbone.history) {
            Backbone.history.start();
            this.initialized = true;
        }
    },

    url: function() {
        if (this.first) {
            this.first = false;
            return encodeURI(Saiku.session.username + "/discover");
        }
        else {
            return encodeURI(Saiku.session.username + "/discover/refresh");
        }
    }
});
<|endoftext|>


<commit_before>/* global describe, it, xit */
/* jslint node: true, esnext: true */

"use strict";

const chai = require('chai'),
  assert = chai.assert,
  expect = chai.expect,
  should = chai.should();

chai.use(require('chai-as-promised'));

const flow = require('kronos-flow'),
  kronos = require('../lib/manager.js'),
  someStepFactory = require('./fixtures/steps1/someStep');

const flowDecl = {
  "name": "flow1",
  "type": "kronos-flow",
  "steps": {
    "s1": {
      "type": "some-step"
    }
  }
};

describe('service manager', function () {
  describe('std attributes', function () {
    it('should have a name', function (done) {
      kronos.manager({
        name: 'myName',
        logLevel: 'trace'
      }).then(function (manager) {
        try {
          assert.equal(manager.name, 'myName');
          assert.equal(manager.toString(), 'myName');

          // test if there is a log level entry point
          manager.info(level => 'level ');
          assert.equal(manager.logLevel, 'trace');
          done();
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });
  });

  describe('shutdown', function () {
    it('empty', function (done) {
      kronos.manager().then(function (manager) {
        try {
          manager.shutdown().then(
            function (manager) {
              done();
            }, done
          );
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });

    it('with flows', function (done) {
      kronos.manager().then(function (manager) {
        try {
          manager.registerStep(someStepFactory);
          flow.registerWithManager(manager);
          const aFlow = manager.getStepInstance(flowDecl);
          manager.registerFlow(aFlow);
          aFlow.start().then(function () {
            manager.shutdown().then(
              function (manager) {
                done();
              }, done
            );
          });
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });

  });

  describe('step registration', function () {
    it('registers steps present', function (done) {
      kronos.manager().then(function (manager) {
        try {
          let stepFromEvent;
          manager.addListener('stepRegistered', step => stepFromEvent = step);

          manager.registerStep(someStepFactory);
          const myStep = manager.steps['some-step'];
          expect(myStep.name, 'step name').to.equal('some-step');
          assert.equal(stepFromEvent, myStep);

          // do not fire a 2nd. time stepRegistered
          stepFromEvent = undefined;
          manager.registerStep(someStepFactory);
          assert.equal(stepFromEvent, undefined);

          done();
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });

    describe('getStepInstance', function () {
      it('not registerd should throw', function (done) {
        kronos.manager().then(function (manager) {
          try {
            assert.throws(function () {
              manager.getStepInstance({
                type: "not-already-registered"
              });
            });
            done();
          } catch (e) {
            done(e);
          }
        }, function () {
          done("Manager not created");
        });
      });
    });
  });

  describe('interceptors', function () {
    it('has interceptors', function (done) {
      kronos.manager().then(function (myManager) {

        assert.isDefined(myManager.interceptors);
        done();
      });
    });
  });

  describe('flows', function () {
    const flowName = 'flow1';

    it('registered should be present', function (done) {
      kronos.manager().then(function (myManager) {
        try {
          let flowFromEvent;
          myManager.addListener('flowRegistered', flow => flowFromEvent = flow);

          flow.registerWithManager(myManager);
          myManager.registerStep(someStepFactory);
          myManager.registerFlow(myManager.getStepInstance(flowDecl));

          const aFlow = myManager.flows[flowName];
          should.exist(aFlow);
          expect(aFlow.name).to.equal(flowName);
          expect(aFlow.state).to.equal("stopped");

          assert.equal(flowFromEvent, aFlow);
          done();
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });

    it('can be removed again', function (done) {
      kronos.manager().then(function (myManager) {
        try {
          let removedStepFromEventDone = false;

          myManager.addListener('stepStateChanged', (step, oldState, newState) => {
            if (newState === 'removed' && step.name === 'flow1') {
              removedStepFromEventDone = true;
            }
          });

          flow.registerWithManager(myManager);
          myManager.registerStep(someStepFactory);
          myManager.registerFlow(myManager.getStepInstance(flowDecl));

          myManager.deleteFlow(flowName).then(function () {
            try {
              assert.equal(myManager.flows.flow1, undefined);

              // stepStateChanged may get fired late ??
              setTimeout(function () {
                assert.isTrue(removedStepFromEventDone);
                done();
              }, 10);
            } catch (e) {
              done(e);
            }
          }, done);
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });

    it('deleting unknown flow rejects', function (done) {
      kronos.manager().then(function (myManager) {
        try {
          myManager.deleteFlow("unknownFlow").then(function () {
            done(new Error("shouldn fullfill: deletion of an unknown flow"));
          }, function (reject) {
            done();
          });
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });
  });
});
<commit_msg>test: use arrow functions<commit_after>/* global describe, it, xit */
/* jslint node: true, esnext: true */

"use strict";

const chai = require('chai'),
  assert = chai.assert,
  expect = chai.expect,
  should = chai.should();

chai.use(require('chai-as-promised'));

const flow = require('kronos-flow'),
  kronos = require('../lib/manager.js'),
  someStepFactory = require('./fixtures/steps1/someStep');

const flowDecl = {
  "name": "flow1",
  "type": "kronos-flow",
  "steps": {
    "s1": {
      "type": "some-step"
    }
  }
};

describe('service manager', () => {
  describe('std attributes', () => {
    it('should have a name', done => {
      kronos.manager({
        name: 'myName',
        logLevel: 'trace'
      }).then(function (manager) {
        try {
          assert.equal(manager.name, 'myName');
          assert.equal(manager.toString(), 'myName');

          // test if there is a log level entry point
          manager.info(level => 'level ');
          assert.equal(manager.logLevel, 'trace');
          done();
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });
  });

  describe('shutdown', () => {
    it('empty', done => {
      kronos.manager().then(manager => {
        try {
          manager.shutdown().then(
            function (manager) {
              done();
            }, done
          );
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });

    it('with flows', done => {
      kronos.manager().then(manager => {
        try {
          manager.registerStep(someStepFactory);
          flow.registerWithManager(manager);
          const aFlow = manager.getStepInstance(flowDecl);
          manager.registerFlow(aFlow);
          aFlow.start().then(function () {
            manager.shutdown().then(
              function (manager) {
                done();
              }, done
            );
          });
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });

  });

  describe('step registration', () => {
    it('registers steps present', done => {
      kronos.manager().then(manager => {
        try {
          let stepFromEvent;
          manager.addListener('stepRegistered', step => stepFromEvent = step);

          manager.registerStep(someStepFactory);
          const myStep = manager.steps['some-step'];
          expect(myStep.name, 'step name').to.equal('some-step');
          assert.equal(stepFromEvent, myStep);

          // do not fire a 2nd. time stepRegistered
          stepFromEvent = undefined;
          manager.registerStep(someStepFactory);
          assert.equal(stepFromEvent, undefined);

          done();
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });

    describe('getStepInstance', () => {
      it('not registerd should throw', done => {
        kronos.manager().then(manager => {
          try {
            assert.throws(function () {
              manager.getStepInstance({
                type: "not-already-registered"
              });
            });
            done();
          } catch (e) {
            done(e);
          }
        }, function () {
          done("Manager not created");
        });
      });
    });
  });

  describe('interceptors', () => {
    it('has interceptors', done => {
      kronos.manager().then(myManager => {

        assert.isDefined(myManager.interceptors);
        done();
      });
    });
  });

  describe('flows', () => {
    const flowName = 'flow1';

    it('registered should be present', done => {
      kronos.manager().then(myManager => {
        try {
          let flowFromEvent;
          myManager.addListener('flowRegistered', flow => flowFromEvent = flow);

          flow.registerWithManager(myManager);
          myManager.registerStep(someStepFactory);
          myManager.registerFlow(myManager.getStepInstance(flowDecl));

          const aFlow = myManager.flows[flowName];
          should.exist(aFlow);
          expect(aFlow.name).to.equal(flowName);
          expect(aFlow.state).to.equal("stopped");

          assert.equal(flowFromEvent, aFlow);
          done();
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });

    it('can be removed again', done => {
      kronos.manager().then(myManager => {
        try {
          let removedStepFromEventDone = false;

          myManager.addListener('stepStateChanged', (step, oldState, newState) => {
            if (newState === 'removed' && step.name === 'flow1') {
              removedStepFromEventDone = true;
            }
          });

          flow.registerWithManager(myManager);
          myManager.registerStep(someStepFactory);
          myManager.registerFlow(myManager.getStepInstance(flowDecl));

          myManager.deleteFlow(flowName).then(() => {
            try {
              assert.equal(myManager.flows.flow1, undefined);

              // stepStateChanged may get fired late ??
              setTimeout(function () {
                assert.isTrue(removedStepFromEventDone);
                done();
              }, 10);
            } catch (e) {
              done(e);
            }
          }, done);
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });

    it('deleting unknown flow rejects', done => {
      kronos.manager().then(myManager => {
        try {
          myManager.deleteFlow("unknownFlow").then(function () {
            done(new Error("shouldn fullfill: deletion of an unknown flow"));
          }, function (reject) {
            done();
          });
        } catch (e) {
          done(e);
        }
      }, function () {
        done("Manager not created");
      });
    });
  });
});
<|endoftext|>


<commit_before>import React from 'react';

export const addEvent = function(elem, type, eventHandle) {
  if (elem === null || typeof elem === 'undefined') {
    return;
  }
  if (elem.addEventListener) {
    elem.addEventListener(type, eventHandle, false);
  } else if (elem.attachEvent) {
    elem.attachEvent(`on${type}`, eventHandle);
  } else {
    elem[`on${type}`] = eventHandle;
  }
};

export const removeEvent = function(elem, type, eventHandle) {
  if (elem === null || typeof elem === 'undefined') {
    return;
  }
  if (elem.removeEventListener) {
    elem.removeEventListener(type, eventHandle, false);
  } else if (elem.detachEvent) {
    elem.detachEvent(`on${type}`, eventHandle);
  } else {
    elem[`on${type}`] = null;
  }
};

export const addAccessibility = (children, slidesToShow, currentSlide) => {
  let needsTabIndex;
  if (slidesToShow > 1) {
    return React.Children.map(children, (child, index) => {
      const firstVisibleSlide = index >= currentSlide;
      const lastVisibleSlide = index < slidesToShow + currentSlide;
      needsTabIndex = firstVisibleSlide && lastVisibleSlide;
      const ariaProps = needsTabIndex
        ? { 'aria-hidden': 'false', tabIndex: 0 }
        : { 'aria-hidden': 'true' };
      return React.cloneElement(child, {
        ...child.props,
        ...ariaProps
      });
    });
  } else {
    return React.Children.map(children, (child, index) => {
      needsTabIndex = index !== currentSlide;
      const ariaProps = needsTabIndex
        ? { 'aria-hidden': 'true' }
        : { 'aria-hidden': 'false', tabIndex: 0 };
      return React.cloneElement(child, {
        ...child.props,
        ...ariaProps
      });
    });
  }
};

export const getPropsByTransitionMode = (props, keys) => {
  const { slidesToShow, transitionMode } = props;
  const updatedDefaults = {};
  if (transitionMode === 'fade') {
    keys.forEach(key => {
      switch (key) {
        case 'slidesToShow':
          updatedDefaults[key] = Math.max(parseInt(slidesToShow), 1);
          break;
        case 'slidesToScroll':
          updatedDefaults[key] = Math.max(parseInt(slidesToShow), 1);
          break;
        case 'cellAlign':
          updatedDefaults[key] = 'left';
          break;
        default:
          updatedDefaults[key] = props[key];
          break;
      }
    });
  } else {
    keys.forEach(key => {
      updatedDefaults[key] = props[key];
    });
  }

  return updatedDefaults;
};

export const swipeDirection = (x1, x2, y1, y2, vertical) => {
  const xDist = x1 - x2;
  const yDist = y1 - y2;
  const r = Math.atan2(yDist, xDist);
  let swipeAngle = Math.round((r * 180) / Math.PI);

  if (swipeAngle < 0) {
    swipeAngle = 360 - Math.abs(swipeAngle);
  }
  if (swipeAngle <= 45 && swipeAngle >= 0) {
    return 1;
  }
  if (swipeAngle <= 360 && swipeAngle >= 315) {
    return 1;
  }
  if (swipeAngle >= 135 && swipeAngle <= 225) {
    return -1;
  }
  if (vertical === true) {
    if (swipeAngle >= 35 && swipeAngle <= 135) {
      return 1;
    } else {
      return -1;
    }
  }
  return 0;
};

export const shouldUpdate = (curr, next, keys) => {
  let update = false;

  for (let i = 0; i < keys.length; i++) {
    if (curr[keys[i]] !== next[keys[i]]) {
      update = true;
      break;
    }
  }

  return update;
};

export const calcSomeInitialState = props => {
  const result = getPropsByTransitionMode(props, ['slidesToScroll', 'slidesToShow', 'cellAlign']);

  const { slidesToScroll, slidesToShow, cellAlign } = result;

  const slideWidth = props.vertical
    ? props.initialSlideHeight || 0
    : props.initialSlideWidth || 0;
  const slideHeight = props.vertical
    ? (props.initialSlideHeight || 0) * props.slidesToShow
    : props.initialSlideHeight || 0;

  const frameHeight = slideHeight + props.cellSpacing * (slidesToShow - 1);

  const frameWidth = props.vertical ? frameHeight : '100%';
  return {
    slideWidth,
    slideHeight,
    frameWidth,
    slidesToScroll,
    slidesToShow,
    cellAlign
  };
};
<commit_msg>some changes reverted<commit_after>import React from 'react';

export const addEvent = function(elem, type, eventHandle) {
  if (elem === null || typeof elem === 'undefined') {
    return;
  }
  if (elem.addEventListener) {
    elem.addEventListener(type, eventHandle, false);
  } else if (elem.attachEvent) {
    elem.attachEvent(`on${type}`, eventHandle);
  } else {
    elem[`on${type}`] = eventHandle;
  }
};

export const removeEvent = function(elem, type, eventHandle) {
  if (elem === null || typeof elem === 'undefined') {
    return;
  }
  if (elem.removeEventListener) {
    elem.removeEventListener(type, eventHandle, false);
  } else if (elem.detachEvent) {
    elem.detachEvent(`on${type}`, eventHandle);
  } else {
    elem[`on${type}`] = null;
  }
};

export const addAccessibility = (children, slidesToShow, currentSlide) => {
  let needsTabIndex;
  if (slidesToShow > 1) {
    return React.Children.map(children, (child, index) => {
      const firstVisibleSlide = index >= currentSlide;
      const lastVisibleSlide = index < slidesToShow + currentSlide;
      needsTabIndex = firstVisibleSlide && lastVisibleSlide;
      const ariaProps = needsTabIndex
        ? { 'aria-hidden': 'false', tabIndex: 0 }
        : { 'aria-hidden': 'true' };
      return React.cloneElement(child, {
        ...child.props,
        ...ariaProps
      });
    });
  } else {
    return React.Children.map(children, (child, index) => {
      needsTabIndex = index !== currentSlide;
      const ariaProps = needsTabIndex
        ? { 'aria-hidden': 'true' }
        : { 'aria-hidden': 'false', tabIndex: 0 };
      return React.cloneElement(child, {
        ...child.props,
        ...ariaProps
      });
    });
  }
};

export const getPropsByTransitionMode = (props, keys) => {
  const { slidesToShow, transitionMode } = props;
  const updatedDefaults = {};
  if (transitionMode === 'fade') {
    keys.forEach(key => {
      switch (key) {
        case 'slidesToShow':
          updatedDefaults[key] = Math.max(parseInt(slidesToShow), 1);
          break;
        case 'slidesToScroll':
          updatedDefaults[key] = Math.max(parseInt(slidesToShow), 1);
          break;
        case 'cellAlign':
          updatedDefaults[key] = 'left';
          break;
        default:
          updatedDefaults[key] = props[key];
          break;
      }
    });
  } else {
    keys.forEach(key => {
      updatedDefaults[key] = props[key];
    });
  }

  return updatedDefaults;
};

export const swipeDirection = (x1, x2, y1, y2, vertical) => {
  const xDist = x1 - x2;
  const yDist = y1 - y2;
  const r = Math.atan2(yDist, xDist);
  let swipeAngle = Math.round((r * 180) / Math.PI);

  if (swipeAngle < 0) {
    swipeAngle = 360 - Math.abs(swipeAngle);
  }
  if (swipeAngle <= 45 && swipeAngle >= 0) {
    return 1;
  }
  if (swipeAngle <= 360 && swipeAngle >= 315) {
    return 1;
  }
  if (swipeAngle >= 135 && swipeAngle <= 225) {
    return -1;
  }
  if (vertical === true) {
    if (swipeAngle >= 35 && swipeAngle <= 135) {
      return 1;
    } else {
      return -1;
    }
  }
  return 0;
};

export const shouldUpdate = (curr, next, keys) => {
  let update = false;

  for (let i = 0; i < keys.length; i++) {
    if (curr[keys[i]] !== next[keys[i]]) {
      update = true;
      break;
    }
  }

  return update;
};

export const calcSomeInitialState = props => {
  const { slidesToScroll, slidesToShow, cellAlign } = getPropsByTransitionMode(
    props,
    ['slidesToScroll', 'slidesToShow', 'cellAlign']
  );

  const slideWidth = props.vertical
    ? props.initialSlideHeight || 0
    : props.initialSlideWidth || 0;
  const slideHeight = props.vertical
    ? (props.initialSlideHeight || 0) * props.slidesToShow
    : props.initialSlideHeight || 0;

  const frameHeight = slideHeight + props.cellSpacing * (slidesToShow - 1);

  const frameWidth = props.vertical ? frameHeight : '100%';
  return {
    slideWidth,
    slideHeight,
    frameWidth,
    slidesToScroll,
    slidesToShow,
    cellAlign
  };
};
<|endoftext|>


<commit_before>/**
 * Created by lundfall on 06/07/16.
 */
import Timer                 from 'famous/utilities/Timer';
import AnimationController   from 'famous-flex/AnimationController';
import Surface               from 'famous/core/Surface';
import FamousContext         from 'famous/core/Context.js';

import {View}                from 'arva-js/core/View.js';
import {ObjectHelper}        from 'arva-js/utils/ObjectHelper';

import {Injection}           from './Injection.js';
import {Router}              from '../core/Router.js';
import {layout}              from '../layout/decorators.js';

@layout.scrollable
class DialogWrapper extends View {
    @layout.size((size) => Math.min(480, size - 32), true)
    @layout.place('center')
    dialog = this.options.dialog;

    onNewParentSize(parentSize) {
        this._parentSize = parentSize;
    }

    getSize() {
        if(!this._parentSize){
            return [undefined, undefined];
        }
        let dialogHeight = this.dialog.getSize()[1];
        return this._parentSize[1] > dialogHeight ? [undefined, undefined] : [undefined, dialogHeight];
    }

}

export class DialogManager extends View {

    @layout.fullscreen
    @layout.animate({showInitially: false, animation: AnimationController.Animation.Fade})
    @layout.translate(0, 0, 250)
    background = new Surface({
        properties: {
            /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#000000+0,000000+100&0.2+0,0.6+100 */
            background: 'radial-gradient(ellipse at center, rgba(0,0,0,0.2) 0%,rgba(0,0,0,0.6) 100%)', /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
            filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#33000000', endColorstr='#99000000',GradientType=1 )" /* IE6-9 fallback on horizontal gradient */
        }
    });

    @layout.translate(0, 0, 1000)
    @layout.fullscreen
    @layout.animate({
        animation: AnimationController.Animation.Slide.Up,
        showInitially: false
    })
        /* Empty content until filled */
    dialog = {};

    constructor(options = {}) {
        super(options);
        /* For ionic-plugin-keyboard */
        if (window.Keyboard) {
            /* Prevent keyboard from showing */
            window.addEventListener('native.keyboardshow', () => {
                /* Hides the keyboard when a dialog is  shown */
                if (this._hasOpenDialog) {
                    Keyboard.hide();
                }
            });
        }
        this.router = Injection.get(Router);
        let famousContext = Injection.get(FamousContext);
        famousContext.add(this);

        this.layout.on('layoutstart', ({size}) => {
            if(this.dialog.onNewParentSize){
                this.dialog.onNewParentSize(size);
                this._savedParentSize = null;
            } else {
                this._savedParentSize = size;
            }
        });

        document.addEventListener("backbutton", this._onClose);
        this.renderables.background.on('click', this._onClose);
    }

    /**
     *
     * @param dialog
     * @param canCancel
     * @param killOldDialog
     * @returns {*}
     */
    show({dialog, canCancel = false, killOldDialog = true}) {
        if (this._hasOpenDialog) {
            /* If already open dialog we should either close that one, or just keep the current one, depending on the settings */
            if (!killOldDialog) {
                return;
            }
            this.close();
        }
        this._hasOpenDialog = true;

        /* Replace whatever non-showing dialog we have right now with the new dialog */
        this.replaceRenderable('dialog', new DialogWrapper({dialog}));
        if(this._savedParentSize){
            this.dialog.onNewParentSize(this._savedParentSize);
        }
        this._canCancel = canCancel;
        if (canCancel) {
            /* Disable existing default behavior of backbutton going back to previous route */
            this.initialBackButtonState = this.router.isBackButtonEnabled();
            this.router.setBackButtonEnabled(false);
        }

        /* Show the dialog */
        this.showRenderable('dialog');

        this.dialog.on('closeDialog', (function () {
            /* Forward the arguments coming from the event emitter when closing */
            this.close(...arguments)
        }).bind(this));

        /* Showing the background immediately propagates user's click event that triggered the show() directly to the background,
         * closing the dialog again. Delaying showing the background circumvents this issue. */
        Timer.setTimeout(() => {
            if (this._hasOpenDialog) {
                this.showRenderable('background');
            }
        }, 10);
        return this.dialogComplete();
    }

    _onClose() {
        if (this._canCancel) {
            this.close();
        }
    }

    hasOpenDialog() {
        return this._hasOpenDialog;
    }

    dialogComplete() {
        if(!this._resolveDialogComplete){
            return this._resolveDialogPromise = new Promise((resolve) => {
                this._resolveDialogComplete = resolve
            });
        } else {
            return this._resolveDialogPromise;
        }

    }

    close() {
        if (this._hasOpenDialog) {

            /* Restore back button state */
            if (this._canCancel) {
                this.router.setBackButtonEnabled(this.initialBackButtonState);
            }
            /* Resolve promise if necessary */
            if (this._resolveDialogComplete) {
                this._resolveDialogComplete(arguments);
                this._resolveDialogComplete = null;
            }
            this._hasOpenDialog = false;

            this.hideRenderable('dialog');
            this.hideRenderable('background');
            this._eventOutput.emit('close', ...arguments);
        }
    }
}
<commit_msg>Changed the size of the DialogWrapper<commit_after>/**
 * Created by lundfall on 06/07/16.
 */
import Timer                 from 'famous/utilities/Timer';
import AnimationController   from 'famous-flex/AnimationController';
import Surface               from 'famous/core/Surface';
import FamousContext         from 'famous/core/Context.js';

import {View}                from 'arva-js/core/View.js';
import {ObjectHelper}        from 'arva-js/utils/ObjectHelper';

import {Injection}           from './Injection.js';
import {Router}              from '../core/Router.js';
import {layout}              from '../layout/decorators.js';

@layout.scrollable
class DialogWrapper extends View {
    @layout.size((size) => Math.min(480, size - 32), true)
    @layout.place('center')
    dialog = this.options.dialog;

    onNewParentSize(parentSize) {
        this._parentSize = parentSize;
    }

    getSize() {
        if(!this._parentSize){
            return [undefined, undefined];
        }
        let dialogHeight = this.dialog.getSize()[1];
        return this._parentSize[1] > dialogHeight ? [undefined, this._parentSize[1]] : [undefined, dialogHeight];
    }

}

export class DialogManager extends View {

    @layout.fullscreen
    @layout.animate({showInitially: false, animation: AnimationController.Animation.Fade})
    @layout.translate(0, 0, 250)
    background = new Surface({
        properties: {
            /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#000000+0,000000+100&0.2+0,0.6+100 */
            background: 'radial-gradient(ellipse at center, rgba(0,0,0,0.2) 0%,rgba(0,0,0,0.6) 100%)', /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
            filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#33000000', endColorstr='#99000000',GradientType=1 )" /* IE6-9 fallback on horizontal gradient */
        }
    });

    @layout.translate(0, 0, 1000)
    @layout.fullscreen
    @layout.animate({
        animation: AnimationController.Animation.Slide.Up,
        showInitially: false
    })
        /* Empty content until filled */
    dialog = {};

    constructor(options = {}) {
        super(options);
        /* For ionic-plugin-keyboard */
        if (window.Keyboard) {
            /* Prevent keyboard from showing */
            window.addEventListener('native.keyboardshow', () => {
                /* Hides the keyboard when a dialog is  shown */
                if (this._hasOpenDialog) {
                    Keyboard.hide();
                }
            });
        }
        this.router = Injection.get(Router);
        let famousContext = Injection.get(FamousContext);
        famousContext.add(this);

        this.layout.on('layoutstart', ({size}) => {
            if(this.dialog.onNewParentSize){
                this.dialog.onNewParentSize(size);
                this._savedParentSize = null;
            } else {
                this._savedParentSize = size;
            }
        });

        document.addEventListener("backbutton", this._onClose);
        this.renderables.background.on('click', this._onClose);
    }

    /**
     *
     * @param dialog
     * @param canCancel
     * @param killOldDialog
     * @returns {*}
     */
    show({dialog, canCancel = false, killOldDialog = true}) {
        if (this._hasOpenDialog) {
            /* If already open dialog we should either close that one, or just keep the current one, depending on the settings */
            if (!killOldDialog) {
                return;
            }
            this.close();
        }
        this._hasOpenDialog = true;

        /* Replace whatever non-showing dialog we have right now with the new dialog */
        this.replaceRenderable('dialog', new DialogWrapper({dialog}));
        if(this._savedParentSize){
            this.dialog.onNewParentSize(this._savedParentSize);
        }
        this._canCancel = canCancel;
        if (canCancel) {
            /* Disable existing default behavior of backbutton going back to previous route */
            this.initialBackButtonState = this.router.isBackButtonEnabled();
            this.router.setBackButtonEnabled(false);
        }

        /* Show the dialog */
        this.showRenderable('dialog');

        this.dialog.on('closeDialog', (function () {
            /* Forward the arguments coming from the event emitter when closing */
            this.close(...arguments)
        }).bind(this));

        /* Showing the background immediately propagates user's click event that triggered the show() directly to the background,
         * closing the dialog again. Delaying showing the background circumvents this issue. */
        Timer.setTimeout(() => {
            if (this._hasOpenDialog) {
                this.showRenderable('background');
            }
        }, 10);
        return this.dialogComplete();
    }

    _onClose() {
        if (this._canCancel) {
            this.close();
        }
    }

    hasOpenDialog() {
        return this._hasOpenDialog;
    }

    dialogComplete() {
        if(!this._resolveDialogComplete){
            return this._resolveDialogPromise = new Promise((resolve) => {
                this._resolveDialogComplete = resolve
            });
        } else {
            return this._resolveDialogPromise;
        }

    }

    close() {
        if (this._hasOpenDialog) {

            /* Restore back button state */
            if (this._canCancel) {
                this.router.setBackButtonEnabled(this.initialBackButtonState);
            }
            /* Resolve promise if necessary */
            if (this._resolveDialogComplete) {
                this._resolveDialogComplete(arguments);
                this._resolveDialogComplete = null;
            }
            this._hasOpenDialog = false;

            this.hideRenderable('dialog');
            this.hideRenderable('background');
            this._eventOutput.emit('close', ...arguments);
        }
    }
}
<|endoftext|>


<commit_before>var assert = require('assert');

var ERRS = {
  '!app': 'mapCla requires a top level namespace containing' +
    ' an argv property',
  '!app.argv': 'mapCla requires the app namespace to contain an argv array'
};

describe('mapCla', function () {

  describe('#requiring the module', function () {
    it('returns a function', function () {
      assert.equal(typeof require('../../lib/mapCla'), 'function');
    });
  });

  describe('#calling the module', function () {
    describe('##without an |app| object', function () {
      it('throws ' + ERRS['!app'], function () {
        try {
          require('../../lib/mapCla')();
        }
        catch(e) {
          assert.equal(e.message, ERRS['!app']);
        }
      });
    });
    describe('##with an |app| object not containing an argv property', function () {
      it('throws ' + ERRS['!app.argv'], function () {
        try {
          require('../../lib/mapCla')({});
        }
        catch(e) {
          assert.equal(e.message, ERRS['!app.argv']);
        }
      });
    });
    describe('##with an |app| object containing an argv property', function () {
      it('maps using the following structure: cd: argv[2], custom_commands: argv[3(and up)]', function () {
        var mapped_commands = require('../../lib/mapCla')([
          'will be cd',
          'custom_commands_1',
          'custom_commands_2'
        ]);

        assert.equal(mapped_commands.cd, 'will be cd');

        console.log(mapped_commands);
      })
    });

  });

});<commit_msg>mapCla tests and coverage 100%<commit_after>var assert = require('assert');

var ERRS = {
  '!app': 'mapCla requires a top level namespace containing' +
    ' an argv property',
  '!app.argv': 'mapCla requires the app namespace to contain an argv array'
};

describe('mapCla', function () {

  describe('#requiring the module', function () {
    it('returns a function', function () {
      assert.equal(typeof require('../../lib/mapCla'), 'function');
    });
  });

  describe('#calling the module', function () {
    describe('##without an |app| object', function () {
      it('throws ' + ERRS['!app'], function () {
        try {
          require('../../lib/mapCla')();
        }
        catch(e) {
          assert.equal(e.message, ERRS['!app']);
        }
      });
    });
    describe('##with an |app| object not containing an argv property', function () {
      it('throws ' + ERRS['!app.argv'], function () {
        try {
          require('../../lib/mapCla')({});
        }
        catch(e) {
          assert.equal(e.message, ERRS['!app.argv']);
        }
      });
    });
    describe('##with an |app| object containing an argv property', function () {
      it('maps using the following structure: cd: argv[2], custom_commands: argv[3(and up)]', function () {
        var mapped_commands = require('../../lib/mapCla')({
          argv: [
            'not mapped',
            'not mapped',
            'will be cd',
            'custom_commands_0',
            'custom_commands_1'
          ]
        });

        assert.equal(mapped_commands.cd, 'will be cd');

        assert.equal(mapped_commands.custom_commands[0], 'custom_commands_0');
        assert.equal(mapped_commands.custom_commands[1], 'custom_commands_1');
      })
    });

  });

});<|endoftext|>


<commit_before>/* eslint-disable */
import _ from 'lodash';
import Immutable from 'seamless-immutable';
import { typeInvariant } from 're-app/utils';
import invariant from 'invariant';
import t from 'tcomb';
import { INIT } from 're-app/utils/actions';

export default function createReducer(stateType, initialState, handlers) {
	if (arguments.length < 3) {
		handlers = initialState;
		initialState = stateType;
		stateType = null;
	} else {
		invariant(t.isType(stateType), 'When creating checked reducer, first argument of createReducer should be a tcomb type.');
	}

	invariant(!_.isUndefined(initialState), 'First argument of `createReducer` should be value representing initial state of reducer.');
	invariant(_.isUndefined(handlers) || _.isObject(handlers), 'Second argument of `createReducer` should be object containing reducer functions keyed by redux action type which they handle.');

	return function reducer(state = initialState, action) {
		if (action.type === INIT) {
			state = Immutable.from({...initialState, ...state});

			if (stateType && process.env.NODE_ENV !== 'production') {
				typeInvariant(state, stateType, 'Invalid state after @@re-app/INIT');
			}
			return state;
		}

		if (handlers && handlers.hasOwnProperty(action.type)) {

			const handlerDefinition = handlers[action.type];
			let handler = handlerDefinition;
			let actionPayloadType = null;
			if (_.isArray(handler)) {
				handler = handlerDefinition[1] || (state => state);
				actionPayloadType = handlerDefinition[0];
			}
			if (actionPayloadType && process.env.NODE_ENV !== 'production') {
				actionPayloadType(action.payload);
			}

			state = handler(state, action);

			if (stateType && process.env.NODE_ENV !== 'production') {
				invariant(_.isFunction(state.asMutable), 'Reducer returned mutable state for action %s.', action.type);
				typeInvariant(state, stateType, 'Reducer returned invalid state for action %s.', action.type);
			}
		}
		return state;
	};
}
<commit_msg>fix(createReducer): fix error message when reducer returns invalid state.<commit_after>/* eslint-disable */
import _ from 'lodash';
import Immutable from 'seamless-immutable';
import { typeInvariant } from 're-app/utils';
import invariant from 'invariant';
import t from 'tcomb';
import { INIT } from 're-app/utils/actions';

export default function createReducer(stateType, initialState, handlers) {
	if (arguments.length < 3) {
		handlers = initialState;
		initialState = stateType;
		stateType = null;
	} else {
		invariant(t.isType(stateType), 'When creating checked reducer, first argument of createReducer should be a tcomb type.');
	}

	invariant(!_.isUndefined(initialState), 'First argument of `createReducer` should be value representing initial state of reducer.');
	invariant(_.isUndefined(handlers) || _.isObject(handlers), 'Second argument of `createReducer` should be object containing reducer functions keyed by redux action type which they handle.');

	return function reducer(state = initialState, action) {
		if (action.type === INIT) {
			state = Immutable.from({...initialState, ...state});

			if (stateType && process.env.NODE_ENV !== 'production') {
				typeInvariant(state, stateType, 'Invalid state after ' + INIT);
			}
			return state;
		}

		if (handlers && handlers.hasOwnProperty(action.type)) {

			const handlerDefinition = handlers[action.type];
			let handler = handlerDefinition;
			let actionPayloadType = null;
			if (_.isArray(handler)) {
				handler = handlerDefinition[1] || (state => state);
				actionPayloadType = handlerDefinition[0];
			}
			if (actionPayloadType && process.env.NODE_ENV !== 'production') {
				actionPayloadType(action.payload);
			}

			state = handler(state, action);

			if (stateType && process.env.NODE_ENV !== 'production') {
				invariant(_.isFunction(state.asMutable), 'Reducer returned mutable state for action %s.', action.type);
				typeInvariant(state, stateType, 'Reducer returned invalid state for action %s.', action.type);
			}
		}
		return state;
	};
}
<|endoftext|>