<commit_before>import Ember from 'ember';

import I18nService from 'ember-i18n/services/i18n';
import I18nRuLocale from 'ember-flexberry/locales/ru/translations';
import I18nEnLocale from 'ember-flexberry/locales/en/translations';

import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

const animationDuration = Ember.$.fn.dropdown.settings.duration + 100;

moduleForComponent('flexberry-dropdown', 'Integration | Component | flexberry dropdown', {
  integration: true,

  beforeEach: function () {
    this.register('locale:ru/translations', I18nRuLocale);
    this.register('locale:en/translations', I18nEnLocale);
    this.register('service:i18n', I18nService);

    this.inject.service('i18n', { as: 'i18n' });
    Ember.Component.reopen({
      i18n: Ember.inject.service('i18n')
    });

    // Set 'ru' as initial locale.
    this.set('i18n.locale', 'ru');
  }
});

test('it renders properly', function(assert) {
  assert.expect(15);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    class=class
  }}`);

  // Retrieve component.
  let $component = this.$().children();
  let $dropdownIcon = $component.children('i.icon');
  let $dropdownText = $component.children('div.text');
  let $dropdownMenu = $component.children('div.menu');

  // Check wrapper <div>.
  assert.strictEqual($component.prop('tagName'), 'DIV', 'Component\'s wrapper is a <div>');
  assert.strictEqual($component.hasClass('flexberry-dropdown'), true, 'Component\'s wrapper has \' flexberry-dropdown\' css-class');
  assert.strictEqual($component.hasClass('ui'), true, 'Component\'s wrapper has \'ui\' css-class');
  assert.strictEqual($component.hasClass('selection'), true, 'Component\'s wrapper has \'selection\' css-class');
  assert.strictEqual($component.hasClass('ember-view'), true, 'Component\'s wrapper has \'ember-view\' css-class');
  assert.strictEqual($component.hasClass('dropdown'), true, 'Component\'s wrapper has \'dropdown\' css-class');
  assert.strictEqual($dropdownIcon.hasClass('dropdown icon'), true, 'Component\'s wrapper has \'dropdown icon\' css-class');
  assert.strictEqual($dropdownText.hasClass('default text'), true, 'Component\'s wrapper has \'default text\' css-class');
  assert.strictEqual($dropdownMenu.hasClass('menu'), true, 'Component\'s wrapper has \'menu\' css-class');

  // Check wrapper's additional CSS-classes.
  let additioanlCssClasses = 'scrolling compact fluid';
  this.set('class', additioanlCssClasses);
  Ember.A(additioanlCssClasses.split(' ')).forEach((cssClassName, index) => {
    assert.strictEqual(
    $component.hasClass(cssClassName),
    true,
    'Component\'s wrapper has additional css class \'' + cssClassName + '\'');
  });

  // Clean up wrapper's additional CSS-classes.
  this.set('class', '');
  Ember.A(additioanlCssClasses.split(' ')).forEach((cssClassName, index) => {
    assert.strictEqual(
    $component.hasClass(cssClassName),
    false,
    'Component\'s wrapper hasn\'t additional css class \'' + cssClassName + '\'');
  });
});

test('placeholder', function (assert) {

});

test('readonly mode works properly', function(assert) {
  assert.expect(3);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    class=class
  }}`);

  // Retrieve component.
  let $component = this.$().children();

  // Check that readonly (disabled) attribute doesn't exist yet.
  assert.strictEqual($component.hasClass('disabled'), false, 'Component\'s hasn\'t readonly');

  // Activate readonly mode & check that readonly (disabled) attribute exists now & has value equals to 'readonly'.
  this.set('class', 'disabled');
  assert.strictEqual($component.hasClass('disabled'), true, 'Component\'s has readonly');

  // Check that readonly (disabled) attribute doesn't exist now.
  this.set('class', '');
  assert.strictEqual($component.hasClass('disabled'), false, 'Component\'s hasn\'t readonly');
});

test('itemsObject render properly', function(assert) {
  assert.expect(4);

  // Create objects for testing.
  let itemsObject = {
    item1: 'Caption1',
    item2: 'Caption2',
    item3: 'Caption3'
  };
  this.set('itemsObject', itemsObject);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    items=itemsObject
  }}`);

  // Retrieve component.
  let $component = this.$().children();
  let $dropdownMenu = $component.children('div.menu');
  let $dropdomnItem = $dropdownMenu.children('div.item');

  // Check that  class 'item' in <menu> exist.
  assert.strictEqual($dropdomnItem.hasClass('item'), true, 'Component\'s has class');

  // Check component's captions and objects.
  let itemsObjectKeys = Object.keys(itemsObject);
  $dropdomnItem.each(function(i) {
    let $item = Ember.$(this);
    let itemKey = itemsObjectKeys[i];
    let itemCaption = itemsObject[itemKey];

    // Check that the captions matches the objects.
    assert.strictEqual($item.attr('data-value'), itemCaption, 'Component\'s item\'s сaptions matches the objects');
  });
});

test('itemsArray render properly', function(assert) {
  assert.expect(4);

  // Create array for testing.
  let itemsArray = ['Caption1', 'Caption2', 'Caption3'];
  this.set('itemsArray', itemsArray);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    items=itemsArray
  }}`);

  // Retrieve component.
  let $component = this.$().children();
  let $dropdownMenu = $component.children('div.menu');
  let $dropdomnItem = $dropdownMenu.children('div.item');

  // Check that  class 'item' in <menu> exist.
  assert.strictEqual($dropdomnItem.hasClass('item'), true, 'Component\'s has class');

  // Check component's captions and array.
  $dropdomnItem.each(function(i) {
    let $item = Ember.$(this);
    let itemCaption = itemsArray[i];

    // Check that the captions matches the array.
    assert.strictEqual($item.attr('data-value'), itemCaption, 'Component\'s item\'s сaptions matches the array');
  });
});

test('animation dropdown without selecting a value', function(assert) {
  assert.expect(10);

  // Create array for testing.
  let itemsArray = ['Caption1', 'Caption2', 'Caption3'];
  this.set('itemsArray', itemsArray);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    items=itemsArray
  }}`);

  // Retrieve component.
  let $component = this.$().children();
  let $dropdownMenu = $component.children('div.menu');

  // Check that component is collapsed by default.
  assert.strictEqual($component.hasClass('upward'), false, 'net');
  assert.strictEqual($component.hasClass('active'), false, 'net');
  assert.strictEqual($component.hasClass('visible'), false, 'net');
  assert.strictEqual($dropdownMenu.hasClass('transition'), false, 'net');
  assert.strictEqual($dropdownMenu.hasClass('visible'), false, 'net');

  let menuAnimationCompleted = new Ember.RSVP.Promise((resolve, reject) => {
    // Try to expand component.
    // Semantic UI will start asynchronous animation after click, so we need Ember.run here.
    Ember.run(() => {
      $component.click();
    });

    // Wait animation to check component's state.
    Ember.run(() => {
      let animation = assert.async();
      setTimeout(() => {
        // Check that component is animating now.
        assert.strictEqual($dropdownMenu.hasClass('animating'), true);

        // Tell to test method that asynchronous operation completed.
        animation();

      }, animationDuration / 2);
    });

    // Wait for expand animation to be completed & check component's state.
    Ember.run(() => {
      let animationCompleted = assert.async();
      setTimeout(() => {
        // Check that component is expanded now.
        assert.strictEqual($component.hasClass('active'), true);
        assert.strictEqual($dropdownMenu.hasClass('visible'), true);

        // Tell to test method that asynchronous operation completed.
        animationCompleted();

        // Resolve 'menuAnimationCompleted' promise.
        resolve();
      }, animationDuration);
    });
  });

  // Wait animation to be completed (when resolve will be called inside previous timeout).
  // Then try to collapse component.
  menuAnimationCompleted.then(() => {
    // Semantic UI will start asynchronous animation after click, so we need Ember.run here.
    Ember.run(() => {
      $component.click();
    });

    // Wait for collapse animation to be completed & check component's state.
    Ember.run(() => {
      let animationCompleted = assert.async();
      setTimeout(() => {
        // Check that component is expanded now.
        assert.strictEqual($component.hasClass('active'), false);
        assert.strictEqual($dropdownMenu.hasClass('visible'), false);

        animationCompleted();
      }, animationDuration);
    });
  });
});

test('animation dropdown with selecting a value', function(assert) {

  // Create array for testing.
  let itemsArray = ['Caption1'];
  this.set('itemsArray', itemsArray);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    items=itemsArray
  }}`);

  // Retrieve component.
  let $component = this.$().children();
  let $dropdownMenu = $component.children('div.menu');
  let $dropdownText = $component.children('div.text');
  let $dropdomnItem = $dropdownMenu.children('div.item');

  let menuAnimationCompleted = new Ember.RSVP.Promise((resolve, reject) => {
    // Try to expand component.
    // Semantic UI will start asynchronous animation after click, so we need Ember.run here.
    Ember.run(() => {
      $component.click();
    });

    // Wait animation to check component's state.
    Ember.run(() => {
      let animation = assert.async();
      setTimeout(() => {
        // Check that component is animating now.
        assert.strictEqual($dropdownMenu.hasClass('animating'), true);

        // Tell to test method that asynchronous operation completed.
        animation();

      }, animationDuration / 2);
    });

    // Wait for expand animation to be completed & check component's state.
    Ember.run(() => {
      let animationCompleted = assert.async();
      setTimeout(() => {

        // Tell to test method that asynchronous operation completed.
        animationCompleted();

        // Resolve 'menuAnimationCompleted' promise.
        resolve();
      }, animationDuration);
    });
  });

  let itemAnimationCompleted = new Ember.RSVP.Promise((resolve, reject) => {
    // Try to expand component.
    // Semantic UI will start asynchronous animation after click, so we need Ember.run here.
    Ember.run(() => {
      $dropdomnItem.click();
    });

    // Wait animation to check component's state.
    Ember.run(() => {
      let animation = assert.async();
      setTimeout(() => {
        // Check that component is animating now.
        assert.strictEqual($dropdownMenu.hasClass('animating'), true);

        // Tell to test method that asynchronous operation completed.
        animation();

      }, animationDuration / 2);
    });

    // Wait for expand animation to be completed & check component's state.
    Ember.run(() => {
      let animationCompleted = assert.async();
      setTimeout(() => {
        // Check that component is expanded now.
        assert.strictEqual($dropdownMenu.hasClass('visible'), true);
        assert.strictEqual($dropdomnItem.hasClass('active'), true);
        assert.strictEqual($dropdomnItem.hasClass('selected'), true);

        // Tell to test method that asynchronous operation completed.
        animationCompleted();

        // Resolve 'menuAnimationCompleted' promise.
        resolve();
      }, animationDuration);
    });
  });

  // Wait animation to be completed (when resolve will be called inside previous timeout).
  // Then try to collapse component.
  itemAnimationCompleted.then(() => {
    // Wait for collapse animation to be completed & check component's state.
    Ember.run(() => {
      let animationCompleted = assert.async();
      setTimeout(() => {
        // Check that component is expanded now.
        assert.strictEqual($dropdownText.hasClass('default text'), false);
        assert.strictEqual($dropdownText.hasClass('text'), true);
        assert.strictEqual($dropdownMenu.hasClass('hidden'), true);
        assert.strictEqual($dropdomnItem.hasClass('active'), true);
        assert.strictEqual($dropdomnItem.hasClass('selected'), true);

        animationCompleted();
      }, animationDuration);
    });
  });
});
<commit_msg>Add tests.<commit_after>import Ember from 'ember';

import I18nService from 'ember-i18n/services/i18n';
import I18nRuLocale from 'ember-flexberry/locales/ru/translations';
import I18nEnLocale from 'ember-flexberry/locales/en/translations';

import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

const animationDuration = Ember.$.fn.dropdown.settings.duration + 100;

moduleForComponent('flexberry-dropdown', 'Integration | Component | flexberry dropdown', {
  integration: true,

  beforeEach: function () {
    this.register('locale:ru/translations', I18nRuLocale);
    this.register('locale:en/translations', I18nEnLocale);
    this.register('service:i18n', I18nService);

    this.inject.service('i18n', { as: 'i18n' });
    Ember.Component.reopen({
      i18n: Ember.inject.service('i18n')
    });

    // Set 'ru' as initial locale.
    this.set('i18n.locale', 'ru');
  }
});

test('it renders properly', function(assert) {
  assert.expect(15);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    class=class
  }}`);

  // Retrieve component.
  let $component = this.$().children();
  let $dropdownIcon = $component.children('i.icon');
  let $dropdownText = $component.children('div.text');
  let $dropdownMenu = $component.children('div.menu');

  // Check wrapper <div>.
  assert.strictEqual($component.prop('tagName'), 'DIV', 'Component\'s wrapper is a <div>');
  assert.strictEqual($component.hasClass('flexberry-dropdown'), true, 'Component\'s wrapper has \' flexberry-dropdown\' css-class');
  assert.strictEqual($component.hasClass('ui'), true, 'Component\'s wrapper has \'ui\' css-class');
  assert.strictEqual($component.hasClass('selection'), true, 'Component\'s wrapper has \'selection\' css-class');
  assert.strictEqual($component.hasClass('ember-view'), true, 'Component\'s wrapper has \'ember-view\' css-class');
  assert.strictEqual($component.hasClass('dropdown'), true, 'Component\'s wrapper has \'dropdown\' css-class');
  assert.strictEqual($dropdownIcon.hasClass('dropdown icon'), true, 'Component\'s wrapper has \'dropdown icon\' css-class');
  assert.strictEqual($dropdownText.hasClass('default text'), true, 'Component\'s wrapper has \'default text\' css-class');
  assert.strictEqual($dropdownMenu.hasClass('menu'), true, 'Component\'s wrapper has \'menu\' css-class');

  // Check wrapper's additional CSS-classes.
  let additioanlCssClasses = 'scrolling compact fluid';
  this.set('class', additioanlCssClasses);
  Ember.A(additioanlCssClasses.split(' ')).forEach((cssClassName, index) => {
    assert.strictEqual(
    $component.hasClass(cssClassName),
    true,
    'Component\'s wrapper has additional css class \'' + cssClassName + '\'');
  });

  // Clean up wrapper's additional CSS-classes.
  this.set('class', '');
  Ember.A(additioanlCssClasses.split(' ')).forEach((cssClassName, index) => {
    assert.strictEqual(
    $component.hasClass(cssClassName),
    false,
    'Component\'s wrapper hasn\'t additional css class \'' + cssClassName + '\'');
  });
});

test('it renders i18n-ed placeholder', function(assert) {
  assert.expect(2);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    class=class
  }}`);

  // Retrieve component.
  let $component = this.$().children();
  let $dropdownText = $component.children('div.default.text');

  // Check <dropdown>'s placeholder.
  assert.strictEqual(
    Ember.$.trim($dropdownText.text()),
    Ember.get(I18nRuLocale, 'components.flexberry-dropdown.placeholder'),
    'Component\'s inner <dropdown>\'s placeholder is equals to it\'s default value from i18n locales/ru/translations');

  // Change current locale to 'en' & check <dropdown>'s placeholder again.
  this.set('i18n.locale', 'en');
  assert.strictEqual(
    Ember.$.trim($dropdownText.text()),
    Ember.get(I18nEnLocale, 'components.flexberry-dropdown.placeholder'),
    'Component\'s inner <dropdown>\'s placeholder is equals to it\'s value from i18n locales/en/translations');
});

test('it renders manually defined placeholder', function(assert) {
  assert.expect(2);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    placeholder=placeholder
  }}`);

  // Set <dropdown>'s placeholder' & render component.
  let placeholder = 'please type some text';
  this.set('placeholder', placeholder);

  // Retrieve component.
  let $component = this.$().children();
  let $dropdownText = $component.children('div.default.text');

  // Check <dropdown>'s placeholder.
  assert.strictEqual(
    Ember.$.trim($dropdownText.text()), placeholder);

  // Change placeholder's value & check <dropdown>'s placeholder again.
  placeholder = 'dropdown has no value';
  this.set('placeholder', placeholder);
  assert.strictEqual(Ember.$.trim($dropdownText.text()), placeholder);
});

test('readonly mode works properly', function(assert) {
  assert.expect(4);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    class=class
  }}`);

  // Retrieve component.
  let $component = this.$().children();
  let $dropdownMenu = $component.children('div.menu');

  // Check that readonly (disabled) attribute doesn't exist yet.
  assert.strictEqual($component.hasClass('disabled'), false, 'Component\'s hasn\'t readonly');

  // Activate readonly mode & check that readonly (disabled) attribute exists now & has value equals to 'readonly'.
  this.set('class', 'disabled');
  assert.strictEqual($component.hasClass('disabled'), true, 'Component\'s has readonly');

  // Check that readonly (disabled) attribute doesn't exist now.
  this.set('class', '');
  assert.strictEqual($component.hasClass('disabled'), false, 'Component\'s hasn\'t readonly');

  // Check that component is disabled.
  new Ember.RSVP.Promise((resolve, reject) => {
    Ember.run(() => {
      $component.click();
    });

    Ember.run(() => {
      let animation = assert.async();
      setTimeout(() => {
        assert.strictEqual($dropdownMenu.hasClass('animating'), false, 'Component is not active');

        animation();

      }, animationDuration / 2);
    });
  });
});

test('itemsObject render properly', function(assert) {
  assert.expect(4);

  // Create objects for testing.
  let itemsObject = {
    item1: 'Caption1',
    item2: 'Caption2',
    item3: 'Caption3'
  };
  this.set('itemsObject', itemsObject);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    items=itemsObject
  }}`);

  // Retrieve component.
  let $component = this.$().children();
  let $dropdownMenu = $component.children('div.menu');
  let $dropdomnItem = $dropdownMenu.children('div.item');

  // Check that  class 'item' in <menu> exist.
  assert.strictEqual($dropdomnItem.hasClass('item'), true, 'Component\'s has class');

  // Check component's captions and objects.
  let itemsObjectKeys = Object.keys(itemsObject);
  $dropdomnItem.each(function(i) {
    let $item = Ember.$(this);
    let itemKey = itemsObjectKeys[i];
    let itemCaption = itemsObject[itemKey];

    // Check that the captions matches the objects.
    assert.strictEqual($item.attr('data-value'), itemCaption, 'Component\'s item\'s сaptions matches the objects');
  });
});

test('itemsArray render properly', function(assert) {
  assert.expect(4);

  // Create array for testing.
  let itemsArray = ['Caption1', 'Caption2', 'Caption3'];
  this.set('itemsArray', itemsArray);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    items=itemsArray
  }}`);

  // Retrieve component.
  let $component = this.$().children();
  let $dropdownMenu = $component.children('div.menu');
  let $dropdomnItem = $dropdownMenu.children('div.item');

  // Check that  class 'item' in <menu> exist.
  assert.strictEqual($dropdomnItem.hasClass('item'), true, 'Component\'s has class');

  // Check component's captions and array.
  $dropdomnItem.each(function(i) {
    let $item = Ember.$(this);
    let itemCaption = itemsArray[i];

    // Check that the captions matches the array.
    assert.strictEqual($item.attr('data-value'), itemCaption, 'Component\'s item\'s сaptions matches the array');
  });
});

test('animation dropdown without selecting a value', function(assert) {
  assert.expect(12);

  // Create array for testing.
  let itemsArray = ['Caption1', 'Caption2', 'Caption3'];
  this.set('itemsArray', itemsArray);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    items=itemsArray
  }}`);

  // Retrieve component.
  let $component = this.$().children();
  let $dropdownText = $component.children('div.text');
  let $dropdownMenu = $component.children('div.menu');

  // Check that component is collapsed by default.
  assert.strictEqual($component.hasClass('upward'), false, 'Component hasn\'t class \'upward\'');
  assert.strictEqual($component.hasClass('active'), false, 'Component hasn\'t class \'active\'');
  assert.strictEqual($component.hasClass('visible'), false, 'Component hasn\'t class \'visible\'');
  assert.strictEqual($dropdownText.hasClass('default'), true, 'Component\'s text has class \'default\'');
  assert.strictEqual($dropdownMenu.hasClass('transition'), false, 'Component\'s menu hasn\'t class \'transition\'');
  assert.strictEqual($dropdownMenu.hasClass('visible'), false, 'Component\'s menu hasn\'t class \'visible\'');

  let menuAnimationCompleted = new Ember.RSVP.Promise((resolve, reject) => {
    // Try to expand component.
    // Semantic UI will start asynchronous animation after click, so we need Ember.run here.
    Ember.run(() => {
      $component.click();
    });

    // Wait animation to check component's state.
    Ember.run(() => {
      let animation = assert.async();
      setTimeout(() => {
        // Check that component is animating now.
        assert.strictEqual($dropdownMenu.hasClass('animating'), true, 'Component has class \'animating\'');

        // Tell to test method that asynchronous operation completed.
        animation();

      }, animationDuration / 2);
    });

    // Wait for expand animation to be completed & check component's state.
    Ember.run(() => {
      let animationCompleted = assert.async();
      setTimeout(() => {
        // Check that component is expanded now.
        assert.strictEqual($component.hasClass('active'), true, 'Component has class \'active\'');
        assert.strictEqual($dropdownMenu.hasClass('visible'), true, 'Component\'s menu has class \'visible\'');

        // Tell to test method that asynchronous operation completed.
        animationCompleted();

        // Resolve 'menuAnimationCompleted' promise.
        resolve();
      }, animationDuration);
    });
  });

  // Wait animation to be completed (when resolve will be called inside previous timeout).
  // Then try to collapse component.
  menuAnimationCompleted.then(() => {
    // Semantic UI will start asynchronous animation after click, so we need Ember.run here.
    Ember.run(() => {
      $component.click();
    });

    // Wait for collapse animation to be completed & check component's state.
    Ember.run(() => {
      let animationCompleted = assert.async();
      setTimeout(() => {
        // Check that component is expanded now.
        assert.strictEqual($component.hasClass('active'), false, 'Component hasn\'t class \'active\'');
        assert.strictEqual($dropdownMenu.hasClass('visible'), false, 'Component\'s menu hasn\'t class \'visible\'');
        assert.strictEqual($dropdownText.hasClass('default'), true, 'Component\'s text has class \'default\'');

        animationCompleted();
      }, animationDuration);
    });
  });
});

test('animation dropdown with selecting a value', function(assert) {
  assert.expect(13);

  // Create array for testing.
  let itemsArray = ['Caption1', 'Caption2', 'Caption3'];
  this.set('itemsArray', itemsArray);

  // Render component.
  this.render(hbs`{{flexberry-dropdown
    items=itemsArray
  }}`);

  // Retrieve component.
  let $component = this.$().children();
  let $dropdownMenu = $component.children('div.menu');
  let $dropdownText = $component.children('div.text');
  let $dropdomnItem = $dropdownMenu.children('div.item');

  assert.strictEqual($dropdownText.hasClass('default'), true, 'Component\'s text has class \'default\'');

  new Ember.RSVP.Promise((resolve, reject) => {
    // Try to expand component.
    // Semantic UI will start asynchronous animation after click, so we need Ember.run here.
    Ember.run(() => {
      $component.click();
    });

    // Wait animation to check component's state.
    Ember.run(() => {
      let animation = assert.async();
      setTimeout(() => {
        // Check that component is animating now.
        assert.strictEqual($dropdownMenu.hasClass('animating'), true, 'Component has class \'animating\'');

        // Tell to test method that asynchronous operation completed.
        animation();

      }, animationDuration / 2);
    });

    // Wait for expand animation to be completed & check component's state.
    Ember.run(() => {
      let animationCompleted = assert.async();
      setTimeout(() => {

        // Tell to test method that asynchronous operation completed.
        animationCompleted();

        // Resolve 'menuAnimationCompleted' promise.
        resolve();
      }, animationDuration);
    });
  });

  let itemAnimationCompleted = new Ember.RSVP.Promise((resolve, reject) => {
    let $items = Ember.$('div.item', $dropdownMenu);

    // Try to expand component.
    // Semantic UI will start asynchronous animation after click, so we need Ember.run here.
    Ember.run(() => {
      Ember.$($items[2]).click();
    });

    // Wait animation to check component's state.
    Ember.run(() => {
      let animation = assert.async();
      setTimeout(() => {
        // Check that component is animating now.
        assert.strictEqual($dropdownMenu.hasClass('animating'), true, 'Component\'class \'menu\' has class \'animating\'');

        // Tell to test method that asynchronous operation completed.
        animation();

      }, animationDuration / 2);
    });

    // Wait for expand animation to be completed & check component's state.
    Ember.run(() => {
      let animationCompleted = assert.async();
      setTimeout(() => {
        // Check that component is expanded now.
        assert.strictEqual($dropdownMenu.hasClass('visible'), true, 'Component\'s menu has class \'visible\'');
        assert.strictEqual($dropdomnItem.hasClass('active'), true, 'Component\'s item has class \'active\'');
        assert.strictEqual($dropdomnItem.hasClass('selected'), true, 'Component\'s item has class \'selected\'');

        // Tell to test method that asynchronous operation completed.
        animationCompleted();

        // Resolve 'menuAnimationCompleted' promise.
        resolve();
      }, animationDuration);
    });
  });

  // Wait animation to be completed (when resolve will be called inside previous timeout).
  // Then try to collapse component.
  itemAnimationCompleted.then(() => {
    // Wait for collapse animation to be completed & check component's state.
    Ember.run(() => {
      let animationCompleted = assert.async();
      setTimeout(() => {
        let $dropdownChangeText = $component.children('div.text');

        // Check that component is expanded now.
        assert.strictEqual($dropdownText.hasClass('default text'), false, 'Component\'s text hasn\'t class \'default\'');
        assert.strictEqual($dropdownText.hasClass('text'), true, 'Component\'s text has class \'text\'');
        assert.strictEqual($dropdownMenu.hasClass('transition'), true, 'Component\'s menu has class \'transition\'');
        assert.strictEqual($dropdownMenu.hasClass('hidden'), true, 'Component\'s menu has class \'hidden\'');
        assert.strictEqual($dropdomnItem.hasClass('active'), true, 'Component\'s item has class \'active\'');
        assert.strictEqual($dropdomnItem.hasClass('selected'), true, 'Component\'s item has class \'selected\'');
        assert.strictEqual($dropdownChangeText.text(), 'Caption3', 'Component\'s default text is chanes');
        animationCompleted();
      }, animationDuration);
    });
  });
});
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */

// @flow

import { isOriginalId } from "devtools-source-map";
import { getSource } from "../selectors";
import type { Location, Source } from "../types";

export async function getGeneratedLocation(
  state: Object,
  source: Source,
  location: Location,
  sourceMaps: Object
): Promise<Location> {
  if (!isOriginalId(location.sourceId)) {
    return location;
  }

  const { line, sourceId, column } = await sourceMaps.getGeneratedLocation(
    location,
    source
  );

  const generatedSource = getSource(state, sourceId);
  if (!generatedSource) {
    return location;
  }

  return {
    line,
    sourceId,
    column: column === 0 ? undefined : column,
    sourceUrl: generatedSource.url
  };
}

export async function getMappedLocation(
  state: Object,
  sourceMaps: Object,
  location: Location
): Promise<Location> {
  const source = getSource(state, location.sourceId);

  if (!source) {
    throw new Error("Unknown source for location");
  }

  if (isOriginalId(location.sourceId)) {
    return getGeneratedLocation(state, source, location, sourceMaps);
  }

  return sourceMaps.getOriginalLocation(location, source);
}
<commit_msg>Avoid risk of thrown error in location mapping. (#7176)<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */

// @flow

import { isOriginalId } from "devtools-source-map";
import { getSource } from "../selectors";
import type { Location, Source } from "../types";

export async function getGeneratedLocation(
  state: Object,
  source: Source,
  location: Location,
  sourceMaps: Object
): Promise<Location> {
  if (!isOriginalId(location.sourceId)) {
    return location;
  }

  const { line, sourceId, column } = await sourceMaps.getGeneratedLocation(
    location,
    source
  );

  const generatedSource = getSource(state, sourceId);
  if (!generatedSource) {
    return location;
  }

  return {
    line,
    sourceId,
    column: column === 0 ? undefined : column,
    sourceUrl: generatedSource.url
  };
}

export async function getMappedLocation(
  state: Object,
  sourceMaps: Object,
  location: Location
): Promise<Location> {
  const source = getSource(state, location.sourceId);

  if (!source) {
    return location;
  }

  if (isOriginalId(location.sourceId)) {
    return getGeneratedLocation(state, source, location, sourceMaps);
  }

  return sourceMaps.getOriginalLocation(location, source);
}
<|endoftext|>


<commit_before>"use strict";

/**
 * @module Config
 */

/**
 * Retrieve sources from configuration files.
 *
 * @param {module:Spring~ConfigData} data - spring response data.
 * @return {Array<module:Spring~ConfigSource>} list of sources.
 */
function getSources(data) {
  return data.propertySources.map((file) => file.source);
}

/**
 * Configuration handler
 * @class
 */
class Config {
  /**
   * Function to apply to every property in configuration
   *
   * @callback forEachFunc
   * @param {string} key - property key
   * @param {*} value - property value
   */

  /**
   * Create config object.
   *
   * @param {module:Spring~ConfigData} data - spring response data
   */
  constructor(data) {
    this._raw = data;
    this._properties = getSources(this._raw).reduce((accum, value) => Object.assign({}, value, accum), {});
  }

  /**
   * Computed configuration properties
   *
   * @public
   * @type {module:Spring~ConfigSource}
   */
  get properties() {
    return Object.assign({}, this._properties);
  }

  /**
   * Raw spring response data
   *
   * @public
   * @type {module:Spring~ConfigData}
   */
  get raw() {
    return JSON.parse(JSON.stringify(this._raw));
  }

  /**
   * Retrieve a configuration property by key
   *
   * @public
   * @param {...string} keyParts - parts to join as key
   * @return {*} property value
   */
  get(keyParts) {
    const key = Array.prototype.slice.call(arguments).join('.');

    return this._properties[key];
  }

  /**
   * Iterate over configuration properties
   *
   * @public
   * @param {module:Config~forEachFunc} callback - function to apply to every property
   * @param {boolean} [includeOverridden=false] whether to include overridden properties
   */
  forEach(callback, includeOverridden) {
    const _include = includeOverridden || false;
    const sources = _include ? getSources(this._raw) : [this._properties];

    sources.forEach((source) => {
      for (let prop in source ) {
        if (source.hasOwnProperty(prop)) {
          callback(prop, source[prop]);
        }
      }
    });
  }

  /**
   * Returns a string representation of raw response data
   *
   * @public
   * @param {number} spaces - number spaces to use in formatting
   * @returns {string} - raw response data as string
   */
  toString(spaces) {
    return JSON.stringify(this._raw, null, spaces);
  }
}

module.exports = Config;
<commit_msg>Since annotations<commit_after>"use strict";

/**
 * @module Config
 */

/**
 * Retrieve sources from configuration files.
 *
 * @param {module:Spring~ConfigData} data - spring response data.
 * @return {Array<module:Spring~ConfigSource>} list of sources.
 */
function getSources(data) {
  return data.propertySources.map((file) => file.source);
}

/**
 * Configuration handler
 * @class
 */
class Config {
  /**
   * Function to apply to every property in configuration
   *
   * @callback forEachFunc
   * @param {string} key - property key
   * @param {*} value - property value
   */

  /**
   * Create config object.
   *
   * @param {module:Spring~ConfigData} data - spring response data
   */
  constructor(data) {
    this._raw = data;
    this._properties = getSources(this._raw).reduce((accum, value) => Object.assign({}, value, accum), {});
  }

  /**
   * Computed configuration properties
   *
   * @public
   * @type {module:Spring~ConfigSource}
   *
   * @since 1.0.0
   */
  get properties() {
    return Object.assign({}, this._properties);
  }

  /**
   * Raw spring response data
   *
   * @public
   * @type {module:Spring~ConfigData}
   *
   * @since 1.0.0
   */
  get raw() {
    return JSON.parse(JSON.stringify(this._raw));
  }

  /**
   * Retrieve a configuration property by key
   *
   * @public
   * @param {...string} keyParts - parts to join as key
   * @return {*} property value
   *
   * @since 1.0.0
   */
  get(keyParts) {
    const key = Array.prototype.slice.call(arguments).join('.');

    return this._properties[key];
  }

  /**
   * Iterate over configuration properties
   *
   * @public
   * @param {module:Config~forEachFunc} callback - function to apply to every property
   * @param {boolean} [includeOverridden=false] whether to include overridden properties
   *
   * @since 1.0.0
   */
  forEach(callback, includeOverridden) {
    const _include = includeOverridden || false;
    const sources = _include ? getSources(this._raw) : [this._properties];

    sources.forEach((source) => {
      for (let prop in source ) {
        if (source.hasOwnProperty(prop)) {
          callback(prop, source[prop]);
        }
      }
    });
  }

  /**
   * Returns a string representation of raw response data
   *
   * @public
   * @param {number} spaces - number spaces to use in formatting
   * @returns {string} - raw response data as string
   *
   * @since 1.0.0
   */
  toString(spaces) {
    return JSON.stringify(this._raw, null, spaces);
  }
}

module.exports = Config;
<|endoftext|>


<commit_before>var express = require('express');
var bodyParser = require('body-parser');
var AccessRequest = require('../models/accessRequest');
var Verify = require('./verify');

var router = express.Router();
router.use(bodyParser.json());

//#################################################################################################
//#################################################################################################
router.route('/')

//get all access requests:
.get(function(req, res) {
    AccessRequest.find({})
        .populate('user')
        .populate('club')
        .populate('role')
        .populate('team')
        .populate('approver')
        .exec(function(err, accessRequests) {
            if(err) throw err;
            res.json(accessRequests);
    });
})

//add a new access request to the system:
.post(Verify.verifyOrdinaryUser, function(req, res, next) {
    AccessRequest.create(req.body, function(err, accessRequest) {
        if(err) return next(err);
        console.log("New access request created");
        res.json(accessRequest);
    });
})

.delete(Verify.verifyOrdinaryUser, function(req, res, next) {
    AccessRequest.remove({}, function(err, accessRequests) {
        if(err) return next(err);
        console.log("Removed: \n" + accessRequests);
        res.json("All access requests removed.");
    });
});

//#################################################################################################
//#################################################################################################
router.route('/:accessRequestId')

///GET access request by ID
.get(Verify.verifyOrdinaryUser, function(req, res) {
    AccessRequest.findById(req.params.accessRequestId)
        .populate('user')
        .populate('club')
        .populate('role')
        .populate('team')
        .populate('owner')
        .exec(function(err, accessRequest) {
            if(err) throw err;
            res.json(accessRequest);
    });
})

//PUT update access request by ID
.put(Verify.verifyOrdinaryUser, function(req, res) {
    AccessRequest.findByIdAndUpdate(req.params.accessRequestId, {$set: req.body}, {new: true})
        .exec(function(err, accessRequest) {
            if(err) throw err;
            res.json(accessRequest);
    });
})

///DELETE access request by ID
.delete(Verify.verifyOrdinaryUser, function(req, res) {
    var accessRequestName;
    AccessRequest.findById(req.params.accessRequestId)
        .populate('user')
        .populate('club')
        .populate('role')
        .populate('team')
        .populate('approver')
        .exec(function(err, accessRequest) {
            if(err) throw err;
            if(accessRequest != null) {
                accessRequestName = accessRequest.user.getFullName() + "/" + accessRequest.club.name + "/" + accessRequest.role.name;
                if(accessRequest.team != null) {
                    accessRequestName = accessRequestName + "/" + accessRequest.team.name;
                }
                accessRequest.remove();
                res.json("Successfully removed access request " + accessRequestName );
            } else {
                res.json("No access request found to delete.")
            }

    });
});

//#################################################################################################
//#################################################################################################
router.route('/findByApprover/:userId')

///GET all access requests pending review by this user
.get(Verify.verifyOrdinaryUser, function(req, res) {
    AccessRequest.find({approver: req.params.userId, status: "PENDING"})
        .populate('user')
        .populate('club')
        .populate('role')
        .populate('team')
        .populate('approver')
        .exec(function(err, accessRequests) {
            if(err) throw err;
            res.json(accessRequests);
    });

});

//#################################################################################################
//#################################################################################################
router.route('/findByStatus/:status')

///GET all access requests with the provided status
.get(Verify.verifyOrdinaryUser, function(req, res) {
    AccessRequest.find({status: req.params.status})
        .populate('user')
        .populate('club')
        .populate('role')
        .populate('team')
        .populate('approver')
        .exec(function(err, accessRequests) {
            if(err) throw err;
            res.json(accessRequests);
    });
});

module.exports = router;<commit_msg>addition of req.query to GET /access_requests<commit_after>var express = require('express');
var bodyParser = require('body-parser');
var AccessRequest = require('../models/accessRequest');
var Verify = require('./verify');

var router = express.Router();
router.use(bodyParser.json());

//#################################################################################################
//#################################################################################################
router.route('/')

//get all access requests:
.get(function(req, res) {
    AccessRequest.find(req.query)
        .populate('user')
        .populate('club')
        .populate('role')
        .populate('team')
        .populate('approver')
        .exec(function(err, accessRequests) {
            if(err) throw err;
            res.json(accessRequests);
    });
})

//add a new access request to the system:
.post(Verify.verifyOrdinaryUser, function(req, res, next) {
    AccessRequest.create(req.body, function(err, accessRequest) {
        if(err) return next(err);
        console.log("New access request created");
        res.json(accessRequest);
    });
})

.delete(Verify.verifyOrdinaryUser, function(req, res, next) {
    AccessRequest.remove({}, function(err, accessRequests) {
        if(err) return next(err);
        console.log("Removed: \n" + accessRequests);
        res.json("All access requests removed.");
    });
});

//#################################################################################################
//#################################################################################################
router.route('/:accessRequestId')

///GET access request by ID
.get(Verify.verifyOrdinaryUser, function(req, res) {
    AccessRequest.findById(req.params.accessRequestId)
        .populate('user')
        .populate('club')
        .populate('role')
        .populate('team')
        .populate('owner')
        .exec(function(err, accessRequest) {
            if(err) throw err;
            res.json(accessRequest);
    });
})

//PUT update access request by ID
.put(Verify.verifyOrdinaryUser, function(req, res) {
    AccessRequest.findByIdAndUpdate(req.params.accessRequestId, {$set: req.body}, {new: true})
        .exec(function(err, accessRequest) {
            if(err) throw err;
            res.json(accessRequest);
    });
})

///DELETE access request by ID
.delete(Verify.verifyOrdinaryUser, function(req, res) {
    var accessRequestName;
    AccessRequest.findById(req.params.accessRequestId)
        .populate('user')
        .populate('club')
        .populate('role')
        .populate('team')
        .populate('approver')
        .exec(function(err, accessRequest) {
            if(err) throw err;
            if(accessRequest != null) {
                accessRequestName = accessRequest.user.getFullName() + "/" + accessRequest.club.name + "/" + accessRequest.role.name;
                if(accessRequest.team != null) {
                    accessRequestName = accessRequestName + "/" + accessRequest.team.name;
                }
                accessRequest.remove();
                res.json("Successfully removed access request " + accessRequestName );
            } else {
                res.json("No access request found to delete.")
            }

    });
});

//#################################################################################################
//#################################################################################################
router.route('/findByApprover/:userId')

///GET all access requests pending review by this user
.get(Verify.verifyOrdinaryUser, function(req, res) {
    AccessRequest.find({approver: req.params.userId, status: "PENDING"})
        .populate('user')
        .populate('club')
        .populate('role')
        .populate('team')
        .populate('approver')
        .exec(function(err, accessRequests) {
            if(err) throw err;
            res.json(accessRequests);
    });

});

//#################################################################################################
//#################################################################################################
router.route('/findByStatus/:status')

///GET all access requests with the provided status
.get(Verify.verifyOrdinaryUser, function(req, res) {
    AccessRequest.find({status: req.params.status})
        .populate('user')
        .populate('club')
        .populate('role')
        .populate('team')
        .populate('approver')
        .exec(function(err, accessRequests) {
            if(err) throw err;
            res.json(accessRequests);
    });
});

module.exports = router;<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');
const { Octokit } = require('@octokit/rest');
const octokit = new Octokit({ auth: process.env.GH_PR_TOKEN });
const surge = require('surge');
const publishFn = surge().publish();

const owner = process.env.CIRCLE_PROJECT_USERNAME; // patternfly
const repo = process.env.CIRCLE_PROJECT_REPONAME;
const prnum = process.env.CIRCLE_PR_NUMBER;
const prbranch = process.env.CIRCLE_BRANCH;

const uploadFolder = process.argv[2];
if (!uploadFolder) {
  console.log('Usage: upload-preview uploadFolder');
  process.exit(1);
}

const uploadFolderName = path.basename(uploadFolder);
let uploadURL = `${repo}${prnum ? `-pr-${prnum || prbranch}` : ''}`.replace(/[\/|\.]/g, '-');

switch(uploadFolderName) {
  case 'coverage':
    fs.copyFileSync(
      path.join(uploadFolder, 'report.html'),
      path.join(uploadFolder, 'index.html')
    );
    uploadURL += '.surge.sh';
    break;
  case 'public':
    if (!prnum && prbranch === 'master') {
      uploadURL = 'pf4.patternfly.org';
      fs.writeFileSync(path.join(__dirname, '../public/CNAME'), uploadURL);
    }
    else {
      uploadURL += '.surge.sh';
    }
    break;
  default:
    uploadURL += `-${uploadFolderName}`;
    uploadURL += '.surge.sh';
    break;
}

publishFn({
  project: uploadFolder,
  p: uploadFolder,
  domain: uploadURL,
  d: uploadURL,
  e: 'https://surge.surge.sh',
  endpoint: 'https://surge.surge.sh'
});

function tryAddComment(comment, commentBody) {
  if (!commentBody.includes(comment)) {
    return comment;
  }
  return '';
}

if (prnum) {
  octokit.issues.listComments({
    owner,
    repo,
    issue_number: prnum
  })
    .then(res => res.data)
    .then(comments => {
      let commentBody = '';
      const existingComment = comments.find(comment => comment.user.login === 'patternfly-build');
      if (existingComment) {
        commentBody += existingComment.body.trim();
        commentBody += '\n\n';
      }

      if (uploadFolderName === 'public') {
        commentBody += tryAddComment(`Preview: https://${uploadURL}`, commentBody);
      }
      else if (uploadFolderName === 'coverage') {
        commentBody += tryAddComment(`A11y report: https://${uploadURL}`, commentBody);
      }

      if (existingComment) {
        octokit.issues.updateComment({
          owner,
          repo,
          comment_id: existingComment.id,
          body: commentBody
        }).then(() => console.log('Updated comment!'));
      } else {
        octokit.issues.createComment({
          owner,
          repo,
          issue_number: prnum,
          body: commentBody
        }).then(() => console.log('Created comment!'));
      }
    });
}
<commit_msg>feat(nothing): try a minor version bump (#2784)<commit_after>const fs = require('fs');
const path = require('path');
const { Octokit } = require('@octokit/rest');
const octokit = new Octokit({ auth: process.env.GH_PR_TOKEN });
const surge = require('surge');
const publishFn = surge().publish();

const owner = process.env.CIRCLE_PROJECT_USERNAME; // patternfly
const repo = process.env.CIRCLE_PROJECT_REPONAME; // patternfly-next
const prnum = process.env.CIRCLE_PR_NUMBER;
const prbranch = process.env.CIRCLE_BRANCH;

const uploadFolder = process.argv[2];
if (!uploadFolder) {
  console.log('Usage: upload-preview uploadFolder');
  process.exit(1);
}

const uploadFolderName = path.basename(uploadFolder);
let uploadURL = `${repo}${prnum ? `-pr-${prnum || prbranch}` : ''}`.replace(/[\/|\.]/g, '-');

switch(uploadFolderName) {
  case 'coverage':
    fs.copyFileSync(
      path.join(uploadFolder, 'report.html'),
      path.join(uploadFolder, 'index.html')
    );
    uploadURL += '.surge.sh';
    break;
  case 'public':
    if (!prnum && prbranch === 'master') {
      uploadURL = 'pf4.patternfly.org';
      fs.writeFileSync(path.join(__dirname, '../public/CNAME'), uploadURL);
    }
    else {
      uploadURL += '.surge.sh';
    }
    break;
  default:
    uploadURL += `-${uploadFolderName}`;
    uploadURL += '.surge.sh';
    break;
}

publishFn({
  project: uploadFolder,
  p: uploadFolder,
  domain: uploadURL,
  d: uploadURL,
  e: 'https://surge.surge.sh',
  endpoint: 'https://surge.surge.sh'
});

function tryAddComment(comment, commentBody) {
  if (!commentBody.includes(comment)) {
    return comment;
  }
  return '';
}

if (prnum) {
  octokit.issues.listComments({
    owner,
    repo,
    issue_number: prnum
  })
    .then(res => res.data)
    .then(comments => {
      let commentBody = '';
      const existingComment = comments.find(comment => comment.user.login === 'patternfly-build');
      if (existingComment) {
        commentBody += existingComment.body.trim();
        commentBody += '\n\n';
      }

      if (uploadFolderName === 'public') {
        commentBody += tryAddComment(`Preview: https://${uploadURL}`, commentBody);
      }
      else if (uploadFolderName === 'coverage') {
        commentBody += tryAddComment(`A11y report: https://${uploadURL}`, commentBody);
      }

      if (existingComment) {
        octokit.issues.updateComment({
          owner,
          repo,
          comment_id: existingComment.id,
          body: commentBody
        }).then(() => console.log('Updated comment!'));
      } else {
        octokit.issues.createComment({
          owner,
          repo,
          issue_number: prnum,
          body: commentBody
        }).then(() => console.log('Created comment!'));
      }
    });
}
<|endoftext|>


<commit_before>// Digital Signatures with Web Cryptography API
//
// Copyright 2014 Info Tech, Inc.
// Provided under the MIT license.
// See LICENSE file for details.

// Will create a random key pair for digital signing and
// verification. A file can be selected and then signed, or
// a signed file can be verified, with that key pair.

document.addEventListener("DOMContentLoaded", function() {
    "use strict";

    if (!window.crypto || !window.crypto.subtle) {
        alert("Your current browser does not support the Web Cryptography API! This page will not work.");
        return;
    }

    var keyPair;    // Used by several handlers later

    createAndSaveAKeyPair().
    then(function() {
        // Only enable the cryptographic operation buttons if a key pair can be created
        document.getElementById("sign").addEventListener("click", signTheFile);
        document.getElementById("verify").addEventListener("click", verifyTheFile);
    }).
    catch(function(err) {
        alert("Could not create a keyPair or enable buttons: " + err.message + "\n" + err.stack);
    });

    // Key pair creation:

    function createAndSaveAKeyPair() {
        // Returns a promise.
        // Takes no input, yields a key pair to the then handler.
        // Side effect: updates keyPair in enclosing scope with new value.

        return window.crypto.subtle.generateKey(
            {
                name: "RSASSA-PKCS1-v1_5",
                modulusLength: 2048,
                publicExponent: new Uint8Array([1, 0, 1]),  // 24 bit representation of 65537
                hash: {name: "SHA-256"}
            },
            true,   // can extract it later if we want
            ["sign", "verify"]).
        then(function (key) {
            keyPair = key;
            return key;
        });
    }

    // Click handlers to sign or verify the given file:

    function signTheFile() {
        // Click handler. Reads the selected file, then signs it to
        // the random key pair's private key. Creates a Blob with the result,
        // and places a link to that Blob in the download-results section.

        var sourceFile = document.getElementById("source-file").files[0];

        var reader = new FileReader();
        reader.onload = processTheFile;
        reader.readAsArrayBuffer(sourceFile);

        // Asynchronous handler:
        function processTheFile() {
            // Load handler for file reader. Needs to reference keyPair from
            // enclosing scope.

            var reader = this;              // Was invoked by the reader object
            var plaintext = reader.result;

            sign(plaintext, keyPair.privateKey).
            then(function(blob) {
                var url = URL.createObjectURL(blob);
                document.getElementById("download-links").insertAdjacentHTML(
                    'beforeEnd',
                    '
Signed file
');
            }).
            catch(function(err) {
                alert("Something went wrong signing: " + err.message + "\n" + err.stack);
            });

            function sign(plaintext, privateKey) {
                // Returns a Promise that yields a Blob to its
                // then handler. The Blob points to an signed
                // representation of the file. The structure of the
                // Blob's content's structure:
                //    16 bit integer length of the digital signature
                //    Digital signature
                //    Original plaintext

                return window.crypto.subtle.sign(
                    {name: "RSASSA-PKCS1-v1_5"},
                    privateKey,
                    plaintext).
                then(packageResults);

                function packageResults(signature) {
                    // Returns a Blob representing the package of
                    // the signature it is provided and the original
                    // plaintext (in an enclosing scope).

                    var length = new Uint16Array([signature.byteLength]);
                    return new Blob(
                        [
                            length,     // Always a 2 byte unsigned integer
                            signature,  // "length" bytes long
                            plaintext   // Remainder is the original plaintext
                        ],
                        {type: "application/octet-stream"}
                    );
                }

            } // End of sign
        } // end of processTheFile
    } // end of signTheFile click handler

    function verifyTheFile() {
        // Click handler. Reads the selected file, then verify the digital
        // signature using the random key pair's public key. Shows an alert
        // saying whether the signature is valid or not. If the signature is
        // valid, it also creates a Blob with the original file
        // and places a link to that Blob in the download-results section.

        var sourceFile = document.getElementById("source-file").files[0];

        var reader = new FileReader();
        reader.onload = processTheFile;
        reader.readAsArrayBuffer(sourceFile);

        function processTheFile() {
            // Load handler for file reader. Needs to reference keyPair from
            // enclosing scope.
            var reader = this;              // Invoked by the reader object
            var data = reader.result;

            // First, separate out the relevant pieces from the file.
            var signatureLength = new Uint16Array(data, 0, 2)[0];   // First 16 bit integer
            var signature       = new Uint8Array( data, 2, signatureLength);
            var plaintext       = new Uint8Array( data, 2 + signatureLength);

            verify(plaintext, signature, keyPair.publicKey).
            then(function(blob) {
                if (blob === null) {
                    alert("Invalid signature!");
                } else {
                    alert("Signature is valid.");
                    var url = URL.createObjectURL(blob);
                    document.getElementById("download-links").insertAdjacentHTML(
                        'beforeEnd',
                        '
Verified file
');
                }
            }).
            catch(function(err) {
                alert("Something went wrong verifying: " + err.message + "\n" + err.stack);
            });

            function verify(plaintext, signature, publicKey) {
                // Shows an alert stating whether the signature is
                // valid or not, and returns a Promise the yields
                // either a Blob containing the original plaintext
                // or null if the signature was invalid.

                return window.crypto.subtle.verify(
                    {name: "RSASSA-PKCS1-v1_5"},
                    publicKey,
                    signature,
                    plaintext
                ).
                then(handleVerification);

                function handleVerification(successful) {
                    // Returns either a Blob containing the original plaintext
                    // (if verification was successful) or null (if not).
                    if (successful) {
                        return new Blob([plaintext], {type: "application/octet-stream"});
                    } else {
                        return null;
                    }
                }

            } // end of verify
        } // end of processTheFile
    } // end of decryptTheFile

});
<commit_msg>Naive way to get around Apple prefixed implementation<commit_after>// Digital Signatures with Web Cryptography API
//
// Copyright 2014 Info Tech, Inc.
// Provided under the MIT license.
// See LICENSE file for details.

// Will create a random key pair for digital signing and
// verification. A file can be selected and then signed, or
// a signed file can be verified, with that key pair.

document.addEventListener("DOMContentLoaded", function() {
    "use strict";

    // Fix Apple prefix if needed
    if (window.crypto && !window.crypto.subtle && window.crypto.webkitSubtle) {
        window.crypto.subtle = window.crypto.webkitSubtle;  // Won't work if subtle already exists
    }

    if (!window.crypto || !window.crypto.subtle) {
        alert("Your current browser does not support the Web Cryptography API! This page will not work.");
        return;
    }

    var keyPair;    // Used by several handlers later

    createAndSaveAKeyPair().
    then(function() {
        // Only enable the cryptographic operation buttons if a key pair can be created
        document.getElementById("sign").addEventListener("click", signTheFile);
        document.getElementById("verify").addEventListener("click", verifyTheFile);
    }).
    catch(function(err) {
        alert("Could not create a keyPair or enable buttons: " + err.message + "\n" + err.stack);
    });

    // Key pair creation:

    function createAndSaveAKeyPair() {
        // Returns a promise.
        // Takes no input, yields a key pair to the then handler.
        // Side effect: updates keyPair in enclosing scope with new value.

        return window.crypto.subtle.generateKey(
            {
                name: "RSASSA-PKCS1-v1_5",
                modulusLength: 2048,
                publicExponent: new Uint8Array([1, 0, 1]),  // 24 bit representation of 65537
                hash: {name: "SHA-256"}
            },
            true,   // can extract it later if we want
            ["sign", "verify"]).
        then(function (key) {
            keyPair = key;
            return key;
        });
    }

    // Click handlers to sign or verify the given file:

    function signTheFile() {
        // Click handler. Reads the selected file, then signs it to
        // the random key pair's private key. Creates a Blob with the result,
        // and places a link to that Blob in the download-results section.

        var sourceFile = document.getElementById("source-file").files[0];

        var reader = new FileReader();
        reader.onload = processTheFile;
        reader.readAsArrayBuffer(sourceFile);

        // Asynchronous handler:
        function processTheFile() {
            // Load handler for file reader. Needs to reference keyPair from
            // enclosing scope.

            var reader = this;              // Was invoked by the reader object
            var plaintext = reader.result;

            sign(plaintext, keyPair.privateKey).
            then(function(blob) {
                var url = URL.createObjectURL(blob);
                document.getElementById("download-links").insertAdjacentHTML(
                    'beforeEnd',
                    '
Signed file
');
            }).
            catch(function(err) {
                alert("Something went wrong signing: " + err.message + "\n" + err.stack);
            });

            function sign(plaintext, privateKey) {
                // Returns a Promise that yields a Blob to its
                // then handler. The Blob points to an signed
                // representation of the file. The structure of the
                // Blob's content's structure:
                //    16 bit integer length of the digital signature
                //    Digital signature
                //    Original plaintext

                return window.crypto.subtle.sign(
                    {name: "RSASSA-PKCS1-v1_5"},
                    privateKey,
                    plaintext).
                then(packageResults);

                function packageResults(signature) {
                    // Returns a Blob representing the package of
                    // the signature it is provided and the original
                    // plaintext (in an enclosing scope).

                    var length = new Uint16Array([signature.byteLength]);
                    return new Blob(
                        [
                            length,     // Always a 2 byte unsigned integer
                            signature,  // "length" bytes long
                            plaintext   // Remainder is the original plaintext
                        ],
                        {type: "application/octet-stream"}
                    );
                }

            } // End of sign
        } // end of processTheFile
    } // end of signTheFile click handler

    function verifyTheFile() {
        // Click handler. Reads the selected file, then verify the digital
        // signature using the random key pair's public key. Shows an alert
        // saying whether the signature is valid or not. If the signature is
        // valid, it also creates a Blob with the original file
        // and places a link to that Blob in the download-results section.

        var sourceFile = document.getElementById("source-file").files[0];

        var reader = new FileReader();
        reader.onload = processTheFile;
        reader.readAsArrayBuffer(sourceFile);

        function processTheFile() {
            // Load handler for file reader. Needs to reference keyPair from
            // enclosing scope.
            var reader = this;              // Invoked by the reader object
            var data = reader.result;

            // First, separate out the relevant pieces from the file.
            var signatureLength = new Uint16Array(data, 0, 2)[0];   // First 16 bit integer
            var signature       = new Uint8Array( data, 2, signatureLength);
            var plaintext       = new Uint8Array( data, 2 + signatureLength);

            verify(plaintext, signature, keyPair.publicKey).
            then(function(blob) {
                if (blob === null) {
                    alert("Invalid signature!");
                } else {
                    alert("Signature is valid.");
                    var url = URL.createObjectURL(blob);
                    document.getElementById("download-links").insertAdjacentHTML(
                        'beforeEnd',
                        '
Verified file
');
                }
            }).
            catch(function(err) {
                alert("Something went wrong verifying: " + err.message + "\n" + err.stack);
            });

            function verify(plaintext, signature, publicKey) {
                // Shows an alert stating whether the signature is
                // valid or not, and returns a Promise the yields
                // either a Blob containing the original plaintext
                // or null if the signature was invalid.

                return window.crypto.subtle.verify(
                    {name: "RSASSA-PKCS1-v1_5"},
                    publicKey,
                    signature,
                    plaintext
                ).
                then(handleVerification);

                function handleVerification(successful) {
                    // Returns either a Blob containing the original plaintext
                    // (if verification was successful) or null (if not).
                    if (successful) {
                        return new Blob([plaintext], {type: "application/octet-stream"});
                    } else {
                        return null;
                    }
                }

            } // end of verify
        } // end of processTheFile
    } // end of decryptTheFile

});
<|endoftext|>


<commit_before>

(function() {
    "use strict";
    // alert("utils created");
    define([],

        function() {

        var alreadyCalculated = false;
        var topRowHeight = 0;

        var hgtComponents = {
            "totalHgt" : null,
            "idMasterSite" : null,
            "idMasterSiteExpander": null,
            "idMasterSiteSummary" : null,
            "idSiteTopRow" : null,
            "idFooter" : null,
        };

        var prevTotalHgt = 0;

        function showHeights(prev, now){
            var prevStr = "Previous total height : " + prev;
            var nowStr = " New total height : " + now;
            //alert(prevStr + nowStr);
        }

        function showRelativeHeights(totTot, tot, elem){
            var totTotStr = "grand total height : " + totTot;
            var totStr = " total height : " + tot;
            var elemStr = " element height : " + elem;
            //alert(totTotStr + totStr + elemStr);
        }

        function displayHeights(purpose){
            console.log(purpose);
            var fullString = " ";
            var counter = 0;
            for (var key in hgtComponents) {
                if (hgtComponents.hasOwnProperty(key)) {
                    counter += 1;
                    // console.log(key, hgtComponents[key]);
                    var hstr = String.format("{0} : {1} ", key, hgtComponents[key]);
                    fullString += hstr;
                    if(counter % 3 == 0){
                        console.log(fullString);
                        fullString = "";
                    }
                }
            }
            console.log(fullString);
        }

        function getDocHeight() {
        // return Math.max(
            // document.body.scrollHeight, document.documentElement.scrollHeight,
            // document.body.offsetHeight, document.documentElement.offsetHeight,
            // document.body.clientHeight, document.documentElement.clientHeight
        // );
        return window.innerHeight;
        }

        function getRootElementFontSize( ) {
            // Returns a number
            var fontSize = parseFloat(
                // of the computed font-size, so in px
                getComputedStyle(
                    // for the root <html> element
                    document.documentElement
                )
                .fontSize
            );
            return fontSize;
        }

        function convertRem(value) {
            return value * getRootElementFontSize();
        }

        function getButtonHeight(m){
            var btnHeight = convertRem(m);
            btnHeight = btnHeight; // / 16;
            return btnHeight;
        }
        /*
        function getButtonHeight(id){
            var btnHeight = getElemHeight(id);
            return btnHeight * 0.6;
        }
           */
        function getElemHeight(itm){
            var elem = document.getElementById(itm);
            var elemHeight = elem.clientHeight;
            return elemHeight;
        }

        function setElementHeight(itm, hgt, units){
            // var elem = angular.element(document.getElementById(itm))[0];
            if(typeof(units)==='undefined') units = 'px';
            var elem = document.getElementById(itm);
            var hstr = String.format("{0}{1}", hgt, units);
            // elem.css({"height": hstr});
            elem.setAttribute("style","height:" + hstr);
        }

        function setVisible(itm, flexnone){
            var elem = document.getElementById(itm);
            elem.visible = flexnone == 'flex' ? 'visible' : 'none';
        }

        function recalculateTopRow(flexnone){
            if(flexnone == 'none'){
                setVisible('idSiteTopRow', 'flex');
                topRowHeight = getElemHeight("idSiteTopRow");
                setVisible('idSiteTopRow', 'none');
            }
            else{
                topRowHeight = getElemHeight("idSiteTopRow");
            }
        }

        function getTopRowHeight(){
            console.log("top row height ||||||||||||||  " + hgtComponents.idSiteTopRow);
            return hgtComponents.idSiteTopRow;
        }

        function getFooterHeight(){
            return hgtComponents.idFooter;
        }

        function getMasterSiteHeight(){
            return hgtComponents.idMasterSite - hgtComponents.idMasterSiteExpander;
        }

              //
            //   function getComponentHeights(sumVis, siteVis){
            //     var totalHgt = 0;
            //     if(sumVis == "inline"){
            //       if(siteVis == 'none'){
            //         totalHgt = hgtComponents.totalHgt - hgtComponents.idSiteTopRow - hgtComponents.idFooter;
            //       }
            //       else{
            //         totalHgt = hgtComponents.totalHgt;
            //       }
            //     }
            //     else{  // sumVis == "none"
            //       if(siteVis == 'none'){
            //         totalHgt = hgtComponents.idMasterSiteExpander;
            //       }
            //       else{
            //         totalHgt = hgtComponents.totalHgt - hgtComponents.idMasterSiteSummary;
            //       }
            //     }
              //
            //     return totalHgt;
            //   }

        function calculateComponentHeights(sumvis, sitevis){
            var totalHgt = 0;
            var hgt = 0;
            setVisible("idSiteTopRow", sitevis);
            var currentTopRowHeight = 0;
            if(alreadyCalculated == false){
                topRowHeight = getElemHeight("idSiteTopRow");
                alreadyCalculated = true;
            }
            currentTopRowHeight = sitevis == 'flex' ? topRowHeight : 0;
            hgtComponents.idMasterSite = getDocHeight(); // - 30;
            hgtComponents.idMasterSiteExpander =  hgt = getElemHeight("idMasterSiteControlRow"); totalHgt += hgt;
            hgtComponents.idMasterSiteSummary =  hgt = getElemHeight("idMasterSiteSummary"); totalHgt += hgt;
            hgtComponents.idSiteTopRow =  hgt = currentTopRowHeight; totalHgt += hgt;
            hgtComponents.idFooter =  hgt = getElemHeight("idFooter") + 10;  totalHgt += hgt;
            hgtComponents.totalHgt = totalHgt;
            console.log("calculateComponentHeights : sitevis, " + sitevis);
            console.log("calculateComponentHeights : master site height, " + hgtComponents.idMasterSite);
            console.log("calculateComponentHeights : top row height, " + hgtComponents.idSiteTopRow)
            // displayHeights("####calculateComponentHeights###");
        }

      function getAvailableSiteColumnHeights( sumVis, siteVis){
        var colHgt = 0;
        if( sumVis == "inline"){
          if(siteVis == 'none'){
            var colHgtBB = hgtComponents.idMasterSite -  hgtComponents.idMasterSiteExpander
              - hgtComponents.idMasterSiteSummary;
            colHgt = colHgtBB;
            }
            else{
              var colHgtB = hgtComponents.idMasterSite - hgtComponents.totalHgt;
              colHgt = colHgtB;
          }
        }
        else{ // sumVis == "none"
          if(siteVis == 'none'){
            var colHgtAA = hgtComponents.idMasterSite - hgtComponents.idMasterSiteExpander
               - hgtComponents.idFooter;
            colHgt = colHgtAA;
          }
          else{ // siteVis == "flex, etc."
            var colHgtA = hgtComponents.idMasterSite - hgtComponents.idMasterSiteExpander
               - hgtComponents.idSiteTopRow - hgtComponents.idFooter;
            colHgt = colHgtA
          }
        }
        showRelativeHeights(colHgt, hgtComponents.idMasterSite, hgtComponents.idMasterSiteSummary);
        // displayHeights("####getAvailableSiteColumnHeights###");
        return colHgt;
      }

        function toFixedTwo (x, y, precision)
        {
            var fixed = {
                lon : toFixedOne(x, precision),
                lat : toFixedOne(y, precision)
            }
            return fixed;
        };

        function toFixedOne(value, precision)
        {
            var precision = precision || 0,
                neg = value < 0,
                power = Math.pow(10, precision),
                value = Math.round(value * power),
                integral = String((neg ? Math.ceil : Math.floor)(value / power)),
                fraction = String((neg ? -value : value) % power),
                padding = new Array(Math.max(precision - fraction.length, 0) + 1).join('0');
            var sign = neg ? "-" : "";
            if(integral[0] == '-')
                sign = "";

            return sign + (precision ? integral + '.' +  padding + fraction : integral);
        };
        function showLoading ()
        {
            console.log("show loading");
            esri.show(loading);

        };

        function hideLoading(error)
        {
            console.log("hide loading");
            esri.hide(loading);
        };

        function getRandomInt(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }
        return {
            showHeights : showHeights,
            getDocHeight : getDocHeight,
            getButtonHeight : getButtonHeight,
            displayHeights : displayHeights,
            calculateComponentHeights : calculateComponentHeights,
//            getComponentHeights : getComponentHeights,
            getAvailableSiteColumnHeights : getAvailableSiteColumnHeights,
            getTopRowHeight : getTopRowHeight,
            getFooterHeight : getFooterHeight,
            getMasterSiteHeight : getMasterSiteHeight,
            getElemHeight : getElemHeight,
            setElementHeight : setElementHeight,
            toFixed : toFixedTwo,
            toFixedOne: toFixedOne,
            showLoading : showLoading,
            hideLoading : hideLoading,
            getRandomInt : getRandomInt,
            recalculateTopRow : recalculateTopRow
        }
    });
}).call(this);
<commit_msg>scrollHeight might be the answer for topRow,<commit_after>

(function() {
    "use strict";
    // alert("utils created");
    define([],

        function() {

        var alreadyCalculated = false;
        var topRowHeight = 0;

        var hgtComponents = {
            "totalHgt" : null,
            "idMasterSite" : null,
            "idMasterSiteExpander": null,
            "idMasterSiteSummary" : null,
            "idSiteTopRow" : null,
            "idFooter" : null,
        };

        var prevTotalHgt = 0;

        function showHeights(prev, now){
            var prevStr = "Previous total height : " + prev;
            var nowStr = " New total height : " + now;
            //alert(prevStr + nowStr);
        }

        function showRelativeHeights(totTot, tot, elem){
            var totTotStr = "grand total height : " + totTot;
            var totStr = " total height : " + tot;
            var elemStr = " element height : " + elem;
            //alert(totTotStr + totStr + elemStr);
        }

        function displayHeights(purpose){
            console.log(purpose);
            var fullString = " ";
            var counter = 0;
            for (var key in hgtComponents) {
                if (hgtComponents.hasOwnProperty(key)) {
                    counter += 1;
                    // console.log(key, hgtComponents[key]);
                    var hstr = String.format("{0} : {1} ", key, hgtComponents[key]);
                    fullString += hstr;
                    if(counter % 3 == 0){
                        console.log(fullString);
                        fullString = "";
                    }
                }
            }
            console.log(fullString);
        }

        function getDocHeight() {
        // return Math.max(
            // document.body.scrollHeight, document.documentElement.scrollHeight,
            // document.body.offsetHeight, document.documentElement.offsetHeight,
            // document.body.clientHeight, document.documentElement.clientHeight
        // );
        return window.innerHeight;
        }

        function getRootElementFontSize( ) {
            // Returns a number
            var fontSize = parseFloat(
                // of the computed font-size, so in px
                getComputedStyle(
                    // for the root <html> element
                    document.documentElement
                )
                .fontSize
            );
            return fontSize;
        }

        function convertRem(value) {
            return value * getRootElementFontSize();
        }

        function getButtonHeight(m){
            var btnHeight = convertRem(m);
            btnHeight = btnHeight; // / 16;
            return btnHeight;
        }
        /*
        function getButtonHeight(id){
            var btnHeight = getElemHeight(id);
            return btnHeight * 0.6;
        }
           */
        function getElemHeight(itm){
            var elem = document.getElementById(itm);
            var elemHeight = elem.clientHeight;
            return elemHeight;
        }

        function setElementHeight(itm, hgt, units){
            // var elem = angular.element(document.getElementById(itm))[0];
            if(typeof(units)==='undefined') units = 'px';
            var elem = document.getElementById(itm);
            var hstr = String.format("{0}{1}", hgt, units);
            // elem.css({"height": hstr});
            elem.setAttribute("style","height:" + hstr);
        }

        function setVisible(itm, flexnone){
            var elem = document.getElementById(itm);
            elem.visible = flexnone == 'flex' ? 'visible' : 'none';
            elem.style.display = flexnone == 'flex' ? 'visible' : 'none';
        }

        function recalculateTopRow(flexnone){
            var topRow = document.getElementById("idSiteTopRow");
            console.log("initial height : " + getElemHeight("idSiteTopRow") + ", " + topRow.clientHeight);
            if(flexnone == 'none'){
                console.log("recalculateTopRow setting to none")
                setVisible('idSiteTopRow', 'flex');
                topRowHeight = topRow.clientHeight;
                console.log("set topRowHeight to interim value " + topRowHeight);
                setVisible('idSiteTopRow', 'none');
            }
            else{
                console.log("recalculateTopRow setting to flex")
                topRowHeight = getElemHeight("idSiteTopRow");
                setVisible('idSiteTopRow', 'none');
                topRowHeight = topRow.scrollHeight; //getElemHeight("idSiteTopRow");
                console.log("set topRowHeight to interim value " + topRowHeight);
                setVisible('idSiteTopRow', 'flex');
                setTimeout(function(){
                    console.log("???????????? in timeout for recalc");
                    var tpr = document.getElementById("idSiteTopRow");
                    topRowHeight = tpr.scrollHeight; //getElemHeight("idSiteTopRow");
                }, 5000);
            }
            console.log("final height : " + getElemHeight("idSiteTopRow") + ", " + topRow.scrollHeight);
        }

        function getTopRowHeight(){
            console.log("top row height ||||||||||||||  " + hgtComponents.idSiteTopRow);
            return hgtComponents.idSiteTopRow;
        }

        function getFooterHeight(){
            return hgtComponents.idFooter;
        }

        function getMasterSiteHeight(){
            return hgtComponents.idMasterSite - hgtComponents.idMasterSiteExpander;
        }

              //
            //   function getComponentHeights(sumVis, siteVis){
            //     var totalHgt = 0;
            //     if(sumVis == "inline"){
            //       if(siteVis == 'none'){
            //         totalHgt = hgtComponents.totalHgt - hgtComponents.idSiteTopRow - hgtComponents.idFooter;
            //       }
            //       else{
            //         totalHgt = hgtComponents.totalHgt;
            //       }
            //     }
            //     else{  // sumVis == "none"
            //       if(siteVis == 'none'){
            //         totalHgt = hgtComponents.idMasterSiteExpander;
            //       }
            //       else{
            //         totalHgt = hgtComponents.totalHgt - hgtComponents.idMasterSiteSummary;
            //       }
            //     }
              //
            //     return totalHgt;
            //   }

        function calculateComponentHeights(sumvis, sitevis){
            var totalHgt = 0;
            var hgt = 0;
            setVisible("idSiteTopRow", sitevis);
            var currentTopRowHeight = 0;
            if(alreadyCalculated == false){
                topRowHeight = getElemHeight("idSiteTopRow");
                alreadyCalculated = true;
            }
            var tpr = document.getElementById("idSiteTopRow");
            topRowHeight = tpr.scrollHeight; //getElemHeight("idSiteTopRow");
            currentTopRowHeight = sitevis == 'flex' ? topRowHeight : 0;
            hgtComponents.idMasterSite = getDocHeight(); // - 30;
            hgtComponents.idMasterSiteExpander =  hgt = getElemHeight("idMasterSiteControlRow"); totalHgt += hgt;
            hgtComponents.idMasterSiteSummary =  hgt = getElemHeight("idMasterSiteSummary"); totalHgt += hgt;
            hgtComponents.idSiteTopRow =  hgt = currentTopRowHeight; totalHgt += hgt;
            hgtComponents.idFooter =  hgt = getElemHeight("idFooter") + 10;  totalHgt += hgt;
            hgtComponents.totalHgt = totalHgt;
            console.log("calculateComponentHeights : sitevis, " + sitevis);
            console.log("calculateComponentHeights : master site height, " + hgtComponents.idMasterSite);
            console.log("calculateComponentHeights : top row height, " + hgtComponents.idSiteTopRow)
            // displayHeights("####calculateComponentHeights###");
        }

      function getAvailableSiteColumnHeights( sumVis, siteVis){
        var colHgt = 0;
        if( sumVis == "inline"){
          if(siteVis == 'none'){
            var colHgtBB = hgtComponents.idMasterSite -  hgtComponents.idMasterSiteExpander
              - hgtComponents.idMasterSiteSummary;
            colHgt = colHgtBB;
            }
            else{
              var colHgtB = hgtComponents.idMasterSite - hgtComponents.totalHgt;
              colHgt = colHgtB;
          }
        }
        else{ // sumVis == "none"
          if(siteVis == 'none'){
            var colHgtAA = hgtComponents.idMasterSite - hgtComponents.idMasterSiteExpander
               - hgtComponents.idFooter;
            colHgt = colHgtAA;
          }
          else{ // siteVis == "flex, etc."
            var colHgtA = hgtComponents.idMasterSite - hgtComponents.idMasterSiteExpander
               - hgtComponents.idSiteTopRow - hgtComponents.idFooter;
            colHgt = colHgtA
          }
        }
        showRelativeHeights(colHgt, hgtComponents.idMasterSite, hgtComponents.idMasterSiteSummary);
        // displayHeights("####getAvailableSiteColumnHeights###");
        return colHgt;
      }

        function toFixedTwo (x, y, precision)
        {
            var fixed = {
                lon : toFixedOne(x, precision),
                lat : toFixedOne(y, precision)
            }
            return fixed;
        };

        function toFixedOne(value, precision)
        {
            var precision = precision || 0,
                neg = value < 0,
                power = Math.pow(10, precision),
                value = Math.round(value * power),
                integral = String((neg ? Math.ceil : Math.floor)(value / power)),
                fraction = String((neg ? -value : value) % power),
                padding = new Array(Math.max(precision - fraction.length, 0) + 1).join('0');
            var sign = neg ? "-" : "";
            if(integral[0] == '-')
                sign = "";

            return sign + (precision ? integral + '.' +  padding + fraction : integral);
        };
        function showLoading ()
        {
            console.log("show loading");
            esri.show(loading);

        };

        function hideLoading(error)
        {
            console.log("hide loading");
            esri.hide(loading);
        };

        function getRandomInt(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }
        return {
            showHeights : showHeights,
            getDocHeight : getDocHeight,
            getButtonHeight : getButtonHeight,
            displayHeights : displayHeights,
            calculateComponentHeights : calculateComponentHeights,
//            getComponentHeights : getComponentHeights,
            getAvailableSiteColumnHeights : getAvailableSiteColumnHeights,
            getTopRowHeight : getTopRowHeight,
            getFooterHeight : getFooterHeight,
            getMasterSiteHeight : getMasterSiteHeight,
            getElemHeight : getElemHeight,
            setElementHeight : setElementHeight,
            toFixed : toFixedTwo,
            toFixedOne: toFixedOne,
            showLoading : showLoading,
            hideLoading : hideLoading,
            getRandomInt : getRandomInt,
            recalculateTopRow : recalculateTopRow
        }
    });
}).call(this);
<|endoftext|>