<commit_before>/*global console, confirm, alert*/
import Ember from 'ember';
import layout from '../templates/components/data-table';

export default Ember.Component.extend({
  layout,
  isLoadingData: true,
  store: Ember.inject.service(),
  columns: [],
  columnNames: [],
  showRows: 5,
  page: 1,
  showActions: true,
  showDeleteButton: true,

  didInsertElement() {
    if(typeof this.get('columnNames') === 'string' ) {
      this.set('columnNames', this.get('columnNames').split(','));
    }
    if(typeof this.get('columns') === 'string' ) {
      this.set('columns', this.get('columns').split(','));
    }
    if(this.get('columns.length') !== this.get('columnNames.length')) {
      console.warn('DATA-TABLE: A quantidade de parâmetros de "column" e "columnNames" é diferente e pode gerar erros de visualisação');
    }
    this.resetQueryParams();
    this.loadData();
  },

  loadData() {
    this.set('isLoadingData', true);
    this.get('store')
      .query(this.get('modelName'), this.get('filters'))
      .then((model) => {
        this.set('model', model);
        this.set('isLoadingData', false);
      });
  },

  resetQueryParams() {
    this.set('page', 1);
    this.set('filters', {
      limit: this.get('showRows'),
      skip: 0
    });
  },

  fakeRowsCounter: Ember.computed('showRows', function() {
    let counter = [];

    for (let i = 1; i <= this.get('showRows'); i++) {
      counter.push(i);
    }

    return counter;
  }),

  buildQuery(search) {
    var query = { or: [] };
    this.get('columns').map(function (column) {
      var obj = {};
      obj[column] = {contains: search};
      query.or.push(obj);
    });
    return query;
  },

	actions: {
		changePage(page) {
      this.set('page', page);
			this.set('filters.skip', (page-1) * this.get("showRows"));
			this.loadData();
		},
    searchOnKeyUp: function(searchTerms) {
      this.resetQueryParams();

			if (searchTerms === '') {
				this.loadData();
			} else {
				clearTimeout(this.get('searchDelay'));
				this.set('searchDelay', setTimeout(() => {
					this.set('filters.where', JSON.stringify(this.buildQuery(searchTerms)));
					this.loadData();
				}, 300));
			}
		},
    delete(model) {
      if(swal) {
        swal({
            title: "Tem certeza que deseja remover este registro?",
            text: "Este registro será permanentemente removido e não será possível recupera-lo!",
            type: "warning",
            showCancelButton: true,
            confirmButtonColor: "#DD6B55",
            confirmButtonText: "Sim, remover!",
            cancelButtonText: "Cancelar!",
            closeOnConfirm: false,
            closeOnCancel: true
          },
          function(isConfirm) {
            if (isConfirm) {
              model.destroyRecord().then(() => {
                  swal("Removido com sucesso!", "", "success");
                })
                .catch((/*error*/) => {
                  swal("Ops", "Não foi possível remover este registro", "error");
                });
            }
          });
      } else {
        if(confirm("Tem certeza que deseja excluir o registro?")) {
          model.destroyRecord().then(() => {
              alert("Removido com sucesso!");
            })
            .catch((/*error*/) => {
              alert("Ops", "Não foi possível remover este registro");
            });
        }
      }
    }
	}
});
<commit_msg>Permite especificar as verdadeiras propriedades de um atributo computado<commit_after>/*global console, confirm, alert, _*/
import Ember from 'ember';
import _ from 'lodash';
import layout from '../templates/components/data-table';

export default Ember.Component.extend({
  layout,
  isLoadingData: true,
  store: Ember.inject.service(),
  columns: [],
  columnNames: [],
  showRows: 5,
  page: 1,
  showActions: true,
  showDeleteButton: true,

  didInsertElement() {
    if(typeof this.get('columnNames') === 'string' ) {
      this.set('columnNames', this.get('columnNames').split(','));
    }
    if(typeof this.get('columns') === 'string' ) {
      this.set('columns', this.get('columns').split(','));
    }
    if(typeof this.get('computedProperties') === 'string' ) {
      this.buildComputedProperties();
    }
    if(this.get('columns.length') !== this.get('columnNames.length')) {
      console.warn('DATA-TABLE: A quantidade de parâmetros de "column" e "columnNames" é diferente e pode gerar erros de visualisação');
    }
    this.resetQueryParams();
    this.loadData();
  },

  buildComputedProperties() {
    let computedProperties = [];
    let splited = this.get('computedProperties').split(',');

    splited.forEach((row)=> {
      let objectRow = {};
      let rowSplited = row.split('=');
      let computedProps = _.last(rowSplited).split('|');
      let relationshipProperty = _.first(rowSplited).split('.');

      if (relationshipProperty.length > 1) {
        computedProps = _.map(computedProps, (o)=> {
          return _.first(relationshipProperty) + '.' + o;
        });
      }

      objectRow.key = _.first(rowSplited);
      objectRow.properties = computedProps;
      computedProperties.push(objectRow);
    });

    this.set('computedProperties', computedProperties);
  },

  loadData() {
    this.set('isLoadingData', true);
    this.get('store')
      .query(this.get('modelName'), this.get('filters'))
      .then((model) => {
        this.set('model', model);
        this.set('isLoadingData', false);
      });
  },

  resetQueryParams() {
    this.set('page', 1);
    this.set('filters', {
      limit: this.get('showRows'),
      skip: 0
    });
  },

  fakeRowsCounter: Ember.computed('showRows', function() {
    let counter = [];

    for (let i = 1; i <= this.get('showRows'); i++) {
      counter.push(i);
    }

    return counter;
  }),

  buildQuery(search) {
    let computedProperties = this.get('computedProperties');
    let query = { or: [] };

    let computedProperty;
    this.get('columns').map(function (column) {
      computedProperty = _.find(computedProperties, { key: column });
      var obj;

      if (computedProperty) {
        computedProperty.properties.forEach((property)=> {
          obj = {};
          obj[property] = {contains: search};
          query.or.push(obj);
        });
      } else {
        obj = {};
        obj[column] = {contains: search};
        query.or.push(obj);
      }
    });

    return query;
  },

	actions: {
		changePage(page) {
      this.set('page', page);
			this.set('filters.skip', (page-1) * this.get("showRows"));
			this.loadData();
		},
    searchOnKeyUp: function(searchTerms) {
      this.resetQueryParams();

			if (searchTerms === '') {
				this.loadData();
			} else {
				clearTimeout(this.get('searchDelay'));
				this.set('searchDelay', setTimeout(() => {
					this.set('filters.where', JSON.stringify(this.buildQuery(searchTerms)));
					this.loadData();
				}, 300));
			}
		},
    delete(model) {
      if(swal) {
        swal({
            title: "Tem certeza que deseja remover este registro?",
            text: "Este registro será permanentemente removido e não será possível recupera-lo!",
            type: "warning",
            showCancelButton: true,
            confirmButtonColor: "#DD6B55",
            confirmButtonText: "Sim, remover!",
            cancelButtonText: "Cancelar!",
            closeOnConfirm: false,
            closeOnCancel: true
          },
          function(isConfirm) {
            if (isConfirm) {
              model.destroyRecord().then(() => {
                  swal("Removido com sucesso!", "", "success");
                })
                .catch((/*error*/) => {
                  swal("Ops", "Não foi possível remover este registro", "error");
                });
            }
          });
      } else {
        if(confirm("Tem certeza que deseja excluir o registro?")) {
          model.destroyRecord().then(() => {
              alert("Removido com sucesso!");
            })
            .catch((/*error*/) => {
              alert("Ops", "Não foi possível remover este registro");
            });
        }
      }
    }
	}
});
<|endoftext|>


<commit_before>import Component from '@glimmer/component';
import { action } from '@ember/object';
import { cancel, debounce } from '@ember/runloop';
import { getPosition, getCoords } from '@zestia/position-utils';
import { guidFor } from '@ember/object/internals';
import { isPresent } from '@ember/utils';
import { htmlSafe, dasherize } from '@ember/string';
import { inject } from '@ember/service';
import { resolve } from 'rsvp';
import { tracked } from '@glimmer/tracking';
import autoPosition from '../utils/auto-position';

export default class TooltipperComponent extends Component {
  @inject('tooltip') tooltipService;

  @tracked coords = { top: 0, left: 0, position: '' };
  @tracked isLoaded = false;
  @tracked isLoading = false;
  @tracked isOverReferenceElement = false;
  @tracked isOverTooltipElement = false;
  @tracked isShowingTooltip = false;
  @tracked loadedData = null;
  @tracked loadEndTime = 0;
  @tracked loadError = null;
  @tracked loadStartTime = 0;
  @tracked previousReferenceElement = null;
  @tracked referenceElement = null;
  @tracked shouldRenderTooltip = false;
  @tracked tooltipElement = null;
  @tracked tooltipperElement = null;

  // Computed state

  get id() {
    return guidFor(this).replace('ember', '');
  }

  get columns() {
    return isPresent(this.args.columns) ? this.args.columns : 3;
  }

  get rows() {
    return isPresent(this.args.rows) ? this.args.rows : 3;
  }

  get shouldAdjust() {
    return isPresent(this.args.adjust) ? this.args.adjust : false;
  }

  get hideDelay() {
    return isPresent(this.args.hideDelay) ? this.args.hideDelay : 0;
  }

  get showDelay() {
    return isPresent(this.args.showDelay) ? this.args.showDelay : 0;
  }

  get tooltipComponent() {
    return isPresent(this.args.tooltip) ? this.args.tooltip : 'tooltip';
  }

  get tooltipStyle() {
    return htmlSafe(`top: ${this.coords.top}px; left: ${this.coords.left}px`);
  }

  get tooltipPosition() {
    return dasherize(this.coords.position);
  }

  get loadDelay() {
    return this.loadEndTime - this.loadStartTime;
  }

  get showDelayRemainder() {
    const maxDelay = isPresent(this.args.showDelay) ? this.args.showDelay : 0;
    return this.loadDelay > maxDelay ? 0 : maxDelay - this.loadDelay;
  }

  get shouldUseMouseEvents() {
    return this.args.mouseEvents !== false;
  }

  // Internal actions

  @action
  handleInsertTooltipper(element) {
    this.tooltipperElement = element;
    this._autoSetupReferenceElement();
    this._toggleViaArgument();
  }

  @action
  handleUpdatedArguments() {
    this._autoSetupReferenceElement();
    this._toggleViaArgument();
    this._positionTooltip();
  }

  @action
  handleDestroyTooltipper() {
    this._cancelShowTooltip();
    this._cancelHideTooltip();
    this._autoTearDownReferenceElement();
  }

  @action
  handleInsertTooltip(element) {
    this.tooltipElement = element;
    this._positionTooltip();
  }

  @action
  handleDestroyTooltip() {
    this.tooltipElement = null;
    this.isOverTooltipElement = false;
  }

  @action
  handleMouseEnterTooltip() {
    this.isOverTooltipElement = true;
  }

  @action
  handleMouseLeaveTooltip() {
    this.isOverTooltipElement = false;

    if (this.shouldUseMouseEvents) {
      this._scheduleHideTooltipFromHover();
    }
  }

  // Public API Actions

  @action
  hideTooltip() {
    return this._hideTooltip();
  }

  @action
  showTooltip() {
    this._showTooltip();
  }

  @action
  toggleTooltip() {
    if (this.shouldRenderTooltip) {
      this._hideTooltip();
    } else {
      this._showTooltip();
    }
  }

  _toggleViaArgument() {
    if (this.args.showTooltip === true) {
      this._showTooltip();
    } else if (this.args.showTooltip === false) {
      this._hideTooltip();
    }
  }

  _startListening(element) {
    this._enterHandler = this._mouseEnterReferenceElement.bind(this);
    this._leaveHandler = this._mouseLeaveReferenceElement.bind(this);

    element.addEventListener('mouseenter', this._enterHandler);
    element.addEventListener('mouseleave', this._leaveHandler);
  }

  _stopListening(element) {
    element.removeEventListener('mouseenter', this._enterHandler);
    element.removeEventListener('mouseleave', this._leaveHandler);
  }

  _mouseEnterReferenceElement() {
    this.isOverReferenceElement = true;

    this._scheduleShowTooltipFromHover();
  }

  _mouseLeaveReferenceElement() {
    this.isOverReferenceElement = false;

    this._scheduleHideTooltipFromHover();
  }

  _load() {
    const action =
      this.isLoaded || typeof this.args.onLoad !== 'function'
        ? this._onLoad.bind(this)
        : this.args.onLoad;

    this._loadStarted();

    return resolve(action())
      .then(this._loadedData.bind(this))
      .catch(this._loadError.bind(this))
      .finally(this._loadFinished.bind(this));
  }

  _onLoad() {
    return this.loadedData;
  }

  _loadStarted() {
    this.loadStartTime = Date.now();
    this.isLoading = true;
  }

  _loadFinished() {
    this.isLoading = false;
    this.loadEndTime = Date.now();
  }

  _loadedData(data) {
    this.loadedData = data;
    this.isLoaded = true;
  }

  _loadError(error) {
    this.loadError = error;
  }

  _scheduleShowTooltipFromHover() {
    if (this.isLoading) {
      return;
    }

    this._load().then(this._attemptShowTooltipFromHover.bind(this));
  }

  _attemptShowTooltipFromHover() {
    if (!this.isOverReferenceElement) {
      return;
    }

    this._scheduleShowTooltip();
  }

  _scheduleShowTooltip() {
    this._cancelHideTooltip();

    this.showTimer = debounce(this, '_showTooltip', this.showDelayRemainder);
  }

  _cancelShowTooltip() {
    cancel(this.showTimer);
  }

  _showTooltip() {
    if (this.shouldRenderTooltip) {
      return;
    }

    this._load().then(this._renderTooltip.bind(this));
  }

  _renderTooltip() {
    this.isShowingTooltip = true;
    this.shouldRenderTooltip = true;

    this.tooltipService.add(this);
  }

  _scheduleHideTooltipFromHover() {
    this._cancelShowTooltip();

    this.hideTimer = debounce(
      this,
      '_attemptHideTooltipFromHover',
      this.hideDelay
    );
  }

  _cancelHideTooltip() {
    cancel(this.hideTimer);
  }

  _attemptHideTooltipFromHover() {
    if (this.isOverReferenceElement || this.isOverTooltipElement) {
      return;
    }

    this._hideTooltip();
  }

  _hideTooltip() {
    if (!this.tooltipElement) {
      return;
    }

    return this._waitForTooltipToHide().then(this._destroyTooltip.bind(this));
  }

  _waitForTooltipToHide() {
    return new Promise(resolve => {
      this.tooltipElement.addEventListener('animationend', resolve, {
        once: true
      });

      this.isShowingTooltip = false;
    });
  }

  _destroyTooltip() {
    this.tooltipService.remove(this);

    this.shouldRenderTooltip = false;
  }

  _autoSetupReferenceElement() {
    this.referenceElement =
      this.args.referenceElement || this.tooltipperElement;

    if (
      !this.referenceElement ||
      this.referenceElement === this.previousReferenceElement
    ) {
      return;
    }

    if (this.previousReferenceElement) {
      this._teardownReferenceElement(this.previousReferenceElement);
    }

    this.previousReferenceElement = this.referenceElement;

    this._setupReferenceElement(this.referenceElement);
  }

  _autoTearDownReferenceElement() {
    this._teardownReferenceElement(this.referenceElement);
  }

  _setupReferenceElement(element) {
    if (!this.shouldUseMouseEvents) {
      return;
    }

    this._startListening(element);
  }

  _teardownReferenceElement(element) {
    if (!this.shouldUseMouseEvents) {
      return;
    }

    this._stopListening(element);
  }

  _determinePosition(referencePosition) {
    return isPresent(this.args.position)
      ? this.args.position
      : autoPosition(referencePosition);
  }

  _positionTooltip() {
    const element = this.tooltipElement;
    const reference = this.referenceElement;

    if (!element || !reference) {
      return;
    }

    const container = this.shouldAdjust ? window : null;

    // Get the rough position of the reference element in the window by
    // splitting it in to a grid of rows and columns and choosing a square.
    const refPosition = getPosition(reference, window, this.columns, this.rows);

    // The position of the tooltip should be the one provided, or one based
    // upon the position of the reference element, that the tooltip is for.
    const position = this._determinePosition(refPosition);

    try {
      // Compute the coordinates required to place the tooltip near the reference
      // element. And, if a container is provided, attempt to adjust the position
      // further to make sure it is always visible.
      this.coords = getCoords(position, element, reference, container);
    } catch (error) {
      // The reference element was probably hidden, therefore it's not possible
      // to compute coordinates.
    }
  }
}
<commit_msg>only track what is necessary to track<commit_after>import Component from '@glimmer/component';
import { action } from '@ember/object';
import { cancel, debounce } from '@ember/runloop';
import { getPosition, getCoords } from '@zestia/position-utils';
import { guidFor } from '@ember/object/internals';
import { isPresent } from '@ember/utils';
import { htmlSafe, dasherize } from '@ember/string';
import { inject } from '@ember/service';
import { resolve } from 'rsvp';
import { tracked } from '@glimmer/tracking';
import autoPosition from '../utils/auto-position';

export default class TooltipperComponent extends Component {
  @inject('tooltip') tooltipService;

  @tracked coords = { top: 0, left: 0, position: '' };
  @tracked isLoading = false;
  @tracked isShowingTooltip = false;
  @tracked shouldRenderTooltip = false;

  isLoaded = false;
  isOverReferenceElement = false;
  isOverTooltipElement = false;
  loadedData = null;
  loadEndTime = 0;
  loadError = null;
  loadStartTime = 0;
  previousReferenceElement = null;
  referenceElement = null;
  tooltipElement = null;
  tooltipperElement = null;

  // Computed state

  get id() {
    return guidFor(this).replace('ember', '');
  }

  get columns() {
    return isPresent(this.args.columns) ? this.args.columns : 3;
  }

  get rows() {
    return isPresent(this.args.rows) ? this.args.rows : 3;
  }

  get shouldAdjust() {
    return isPresent(this.args.adjust) ? this.args.adjust : false;
  }

  get hideDelay() {
    return isPresent(this.args.hideDelay) ? this.args.hideDelay : 0;
  }

  get showDelay() {
    return isPresent(this.args.showDelay) ? this.args.showDelay : 0;
  }

  get tooltipComponent() {
    return isPresent(this.args.tooltip) ? this.args.tooltip : 'tooltip';
  }

  get tooltipStyle() {
    return htmlSafe(`top: ${this.coords.top}px; left: ${this.coords.left}px`);
  }

  get tooltipPosition() {
    return dasherize(this.coords.position);
  }

  get loadDelay() {
    return this.loadEndTime - this.loadStartTime;
  }

  get showDelayRemainder() {
    const maxDelay = isPresent(this.args.showDelay) ? this.args.showDelay : 0;
    return this.loadDelay > maxDelay ? 0 : maxDelay - this.loadDelay;
  }

  get shouldUseMouseEvents() {
    return this.args.mouseEvents !== false;
  }

  // Internal actions

  @action
  handleInsertTooltipper(element) {
    this.tooltipperElement = element;
    this._autoSetupReferenceElement();
    this._toggleViaArgument();
  }

  @action
  handleUpdatedArguments() {
    this._autoSetupReferenceElement();
    this._toggleViaArgument();
    this._positionTooltip();
  }

  @action
  handleDestroyTooltipper() {
    this._cancelShowTooltip();
    this._cancelHideTooltip();
    this._autoTearDownReferenceElement();
  }

  @action
  handleInsertTooltip(element) {
    this.tooltipElement = element;
    this._positionTooltip();
  }

  @action
  handleDestroyTooltip() {
    this.tooltipElement = null;
    this.isOverTooltipElement = false;
  }

  @action
  handleMouseEnterTooltip() {
    this.isOverTooltipElement = true;
  }

  @action
  handleMouseLeaveTooltip() {
    this.isOverTooltipElement = false;

    if (this.shouldUseMouseEvents) {
      this._scheduleHideTooltipFromHover();
    }
  }

  // Public API Actions

  @action
  hideTooltip() {
    return this._hideTooltip();
  }

  @action
  showTooltip() {
    this._showTooltip();
  }

  @action
  toggleTooltip() {
    if (this.shouldRenderTooltip) {
      this._hideTooltip();
    } else {
      this._showTooltip();
    }
  }

  _toggleViaArgument() {
    if (this.args.showTooltip === true) {
      this._showTooltip();
    } else if (this.args.showTooltip === false) {
      this._hideTooltip();
    }
  }

  _startListening(element) {
    this._enterHandler = this._mouseEnterReferenceElement.bind(this);
    this._leaveHandler = this._mouseLeaveReferenceElement.bind(this);

    element.addEventListener('mouseenter', this._enterHandler);
    element.addEventListener('mouseleave', this._leaveHandler);
  }

  _stopListening(element) {
    element.removeEventListener('mouseenter', this._enterHandler);
    element.removeEventListener('mouseleave', this._leaveHandler);
  }

  _mouseEnterReferenceElement() {
    this.isOverReferenceElement = true;

    this._scheduleShowTooltipFromHover();
  }

  _mouseLeaveReferenceElement() {
    this.isOverReferenceElement = false;

    this._scheduleHideTooltipFromHover();
  }

  _load() {
    const action =
      this.isLoaded || typeof this.args.onLoad !== 'function'
        ? this._onLoad.bind(this)
        : this.args.onLoad;

    this._loadStarted();

    return resolve(action())
      .then(this._loadedData.bind(this))
      .catch(this._loadError.bind(this))
      .finally(this._loadFinished.bind(this));
  }

  _onLoad() {
    return this.loadedData;
  }

  _loadStarted() {
    this.loadStartTime = Date.now();
    this.isLoading = true;
  }

  _loadFinished() {
    this.isLoading = false;
    this.loadEndTime = Date.now();
  }

  _loadedData(data) {
    this.loadedData = data;
    this.isLoaded = true;
  }

  _loadError(error) {
    this.loadError = error;
  }

  _scheduleShowTooltipFromHover() {
    if (this.isLoading) {
      return;
    }

    this._load().then(this._attemptShowTooltipFromHover.bind(this));
  }

  _attemptShowTooltipFromHover() {
    if (!this.isOverReferenceElement) {
      return;
    }

    this._scheduleShowTooltip();
  }

  _scheduleShowTooltip() {
    this._cancelHideTooltip();

    this.showTimer = debounce(this, '_showTooltip', this.showDelayRemainder);
  }

  _cancelShowTooltip() {
    cancel(this.showTimer);
  }

  _showTooltip() {
    if (this.shouldRenderTooltip) {
      return;
    }

    this._load().then(this._renderTooltip.bind(this));
  }

  _renderTooltip() {
    this.isShowingTooltip = true;
    this.shouldRenderTooltip = true;

    this.tooltipService.add(this);
  }

  _scheduleHideTooltipFromHover() {
    this._cancelShowTooltip();

    this.hideTimer = debounce(
      this,
      '_attemptHideTooltipFromHover',
      this.hideDelay
    );
  }

  _cancelHideTooltip() {
    cancel(this.hideTimer);
  }

  _attemptHideTooltipFromHover() {
    if (this.isOverReferenceElement || this.isOverTooltipElement) {
      return;
    }

    this._hideTooltip();
  }

  _hideTooltip() {
    if (!this.tooltipElement) {
      return;
    }

    return this._waitForTooltipToHide().then(this._destroyTooltip.bind(this));
  }

  _waitForTooltipToHide() {
    return new Promise(resolve => {
      this.tooltipElement.addEventListener('animationend', resolve, {
        once: true
      });

      this.isShowingTooltip = false;
    });
  }

  _destroyTooltip() {
    this.tooltipService.remove(this);

    this.shouldRenderTooltip = false;
  }

  _autoSetupReferenceElement() {
    this.referenceElement =
      this.args.referenceElement || this.tooltipperElement;

    if (
      !this.referenceElement ||
      this.referenceElement === this.previousReferenceElement
    ) {
      return;
    }

    if (this.previousReferenceElement) {
      this._teardownReferenceElement(this.previousReferenceElement);
    }

    this.previousReferenceElement = this.referenceElement;

    this._setupReferenceElement(this.referenceElement);
  }

  _autoTearDownReferenceElement() {
    this._teardownReferenceElement(this.referenceElement);
  }

  _setupReferenceElement(element) {
    if (!this.shouldUseMouseEvents) {
      return;
    }

    this._startListening(element);
  }

  _teardownReferenceElement(element) {
    if (!this.shouldUseMouseEvents) {
      return;
    }

    this._stopListening(element);
  }

  _determinePosition(referencePosition) {
    return isPresent(this.args.position)
      ? this.args.position
      : autoPosition(referencePosition);
  }

  _positionTooltip() {
    const element = this.tooltipElement;
    const reference = this.referenceElement;

    if (!element || !reference) {
      return;
    }

    const container = this.shouldAdjust ? window : null;

    // Get the rough position of the reference element in the window by
    // splitting it in to a grid of rows and columns and choosing a square.
    const refPosition = getPosition(reference, window, this.columns, this.rows);

    // The position of the tooltip should be the one provided, or one based
    // upon the position of the reference element, that the tooltip is for.
    const position = this._determinePosition(refPosition);

    try {
      // Compute the coordinates required to place the tooltip near the reference
      // element. And, if a container is provided, attempt to adjust the position
      // further to make sure it is always visible.
      this.coords = getCoords(position, element, reference, container);
    } catch (error) {
      // The reference element was probably hidden, therefore it's not possible
      // to compute coordinates.
    }
  }
}
<|endoftext|>


<commit_before>/* globals Readability, watchFunction */
/* exported FILENAME */
/** extractor-worker is a content worker that is attached to a page when
    making a shot

    extractData() does the main work
    */

// Set for use in error messages:
var FILENAME = "extractor-worker.js";

/** Extracts data:
    - Gets the Readability version of the page (`.readable`)
    - Finds images in roughly the preferred order (`.images`)
    */
function extractData() {
  let start = Date.now();
  // FIXME: need to include found images too
  let startImage = Date.now();
  let readableDiv;
  let readable;
  if (typeof Readable != "undefined") {
    let result = extractReadable();
    readable = result.readable;
    readableDiv = result.readableDiv;
  }
  var images = findImages([
    {element: document.head, isReadable: false},
    {element: readableDiv, isReadable: true},
    {element: document.body, isReadable: false}]);
  console.info("Image time:", Date.now() - startImage, "ms");
  var siteName = findSiteName();
  console.info("extractData time:", Date.now() - start, "ms");
  let passwordFields = [];
  for (let el of document.querySelectorAll('input[type=password]')) {
    passwordFields.push(el.name || null);
  }
  return {
    readable: readable,
    images: images,
    siteName: siteName,
    passwordFields: passwordFields
  };
}

function extractReadable() {
  // Readability is destructive, so we have to run it on a copy
  var readableDiv = document.createElement("div");
  readableDiv.innerHTML = document.body.innerHTML;
  // FIXME: location.href isn't what Readability expects (but I am
  // working around the parts of the code that seem to expect
  // something different)
  let startReader = Date.now();
  let uri = {
    spec: location.href,
    host: location.host,
    prePath: location.scheme + "://" + location.host,
    scheme: location.scheme,
    pathBase: location.href.replace(/\/[^\/]*$/, "/")
  };
  var reader = new Readability(uri, readableDiv);
  let readable;
  try {
    readable = reader.parse();
  } catch (e) {
    console.warn("Exception getting readable version:", e);
    console.warn("Traceback:", e.stack);
  }
  if (readable) {
    delete readable.uri;
  }
  console.info("Readability time:", Date.now() - startReader, "ms", "success:", !! readable);
  return {readable, readableDiv};
}

// Images smaller than either of these sizes are skipped:
var MIN_IMAGE_WIDTH = 250;
var MIN_IMAGE_HEIGHT = 200;

/** Finds images in any of the given elements, avoiding duplicates
    Looks for Open Graph og:image, then img elements, sorting img
    elements by width (largest preferred) */
function findImages(elements) {
  var images = [];
  var found = {};
  function addImage(imgData) {
    if (! (imgData && imgData.url)) {
      return;
    }
    // FIXME: handle relative links
    if (found[imgData.url]) {
      return;
    }
    images.push(imgData);
    found[imgData.url] = true;
  }
  for (var i=0; i<elements.length; i++) {
    var el = elements[i].element;
    if (! el) {
      continue;
    }
    var isReadable = elements[i].isReadable;
    var ogs = el.querySelectorAll("meta[property='og:image'], meta[name='twitter:image']");
    var j;
    for (j=0; j<ogs.length; j++) {
      var src = ogs[j].getAttribute("content");
      if (src.startsWith("/")) {
        src = location.origin + src;
      }
      addImage({
        url: src
      });
    }
    var imgs = el.querySelectorAll("img");
    imgs = Array.prototype.slice.call(imgs);
    // Widest images first:
    imgs.sort(function (a, b) {
      if (a.width > b.width) {
        return -1;
      }
      return 1;
    });
    for (j=0; j<imgs.length; j++) {
      var img = imgs[j];
      if (img.width >= MIN_IMAGE_WIDTH && img.height >= MIN_IMAGE_HEIGHT) {
        addImage({
          url: img.src,
          dimensions: {x: img.width, y: img.height},
          title: img.getAttribute("title") || null,
          alt: img.getAttribute("alt") || null,
          isReadable: isReadable
        });
      }
    }
  }
  return images;
}

function findSiteName() {
  let el = document.querySelector("meta[property='og:site_name']");
  if (el) {
    return el.getAttribute("content");
  }
  // nytimes.com uses this property:
  el = document.querySelector("meta[name='cre']");
  if (el) {
    return el.getAttribute("content");
  }
  return null;
}

self.port.emit("data", watchFunction(extractData)());
<commit_msg>Remove unneeded timing variable<commit_after>/* globals Readability, watchFunction */
/* exported FILENAME */
/** extractor-worker is a content worker that is attached to a page when
    making a shot

    extractData() does the main work
    */

// Set for use in error messages:
var FILENAME = "extractor-worker.js";

/** Extracts data:
    - Gets the Readability version of the page (`.readable`)
    - Finds images in roughly the preferred order (`.images`)
    */
function extractData() {
  let start = Date.now();
  let readableDiv;
  let readable;
  if (typeof Readable != "undefined") {
    let result = extractReadable();
    readable = result.readable;
    readableDiv = result.readableDiv;
  }
  var images = findImages([
    {element: document.head, isReadable: false},
    {element: readableDiv, isReadable: true},
    {element: document.body, isReadable: false}]);
  console.info("Image time:", Date.now() - start, "ms");
  var siteName = findSiteName();
  console.info("extractData time:", Date.now() - start, "ms");
  let passwordFields = [];
  for (let el of document.querySelectorAll('input[type=password]')) {
    passwordFields.push(el.name || null);
  }
  return {
    readable: readable,
    images: images,
    siteName: siteName,
    passwordFields: passwordFields
  };
}

function extractReadable() {
  // Readability is destructive, so we have to run it on a copy
  var readableDiv = document.createElement("div");
  readableDiv.innerHTML = document.body.innerHTML;
  // FIXME: location.href isn't what Readability expects (but I am
  // working around the parts of the code that seem to expect
  // something different)
  let startReader = Date.now();
  let uri = {
    spec: location.href,
    host: location.host,
    prePath: location.scheme + "://" + location.host,
    scheme: location.scheme,
    pathBase: location.href.replace(/\/[^\/]*$/, "/")
  };
  var reader = new Readability(uri, readableDiv);
  let readable;
  try {
    readable = reader.parse();
  } catch (e) {
    console.warn("Exception getting readable version:", e);
    console.warn("Traceback:", e.stack);
  }
  if (readable) {
    delete readable.uri;
  }
  console.info("Readability time:", Date.now() - startReader, "ms", "success:", !! readable);
  return {readable, readableDiv};
}

// Images smaller than either of these sizes are skipped:
var MIN_IMAGE_WIDTH = 250;
var MIN_IMAGE_HEIGHT = 200;

/** Finds images in any of the given elements, avoiding duplicates
    Looks for Open Graph og:image, then img elements, sorting img
    elements by width (largest preferred) */
function findImages(elements) {
  var images = [];
  var found = {};
  function addImage(imgData) {
    if (! (imgData && imgData.url)) {
      return;
    }
    // FIXME: handle relative links
    if (found[imgData.url]) {
      return;
    }
    images.push(imgData);
    found[imgData.url] = true;
  }
  for (var i=0; i<elements.length; i++) {
    var el = elements[i].element;
    if (! el) {
      continue;
    }
    var isReadable = elements[i].isReadable;
    var ogs = el.querySelectorAll("meta[property='og:image'], meta[name='twitter:image']");
    var j;
    for (j=0; j<ogs.length; j++) {
      var src = ogs[j].getAttribute("content");
      if (src.startsWith("/")) {
        src = location.origin + src;
      }
      addImage({
        url: src
      });
    }
    var imgs = el.querySelectorAll("img");
    imgs = Array.prototype.slice.call(imgs);
    // Widest images first:
    imgs.sort(function (a, b) {
      if (a.width > b.width) {
        return -1;
      }
      return 1;
    });
    for (j=0; j<imgs.length; j++) {
      var img = imgs[j];
      if (img.width >= MIN_IMAGE_WIDTH && img.height >= MIN_IMAGE_HEIGHT) {
        addImage({
          url: img.src,
          dimensions: {x: img.width, y: img.height},
          title: img.getAttribute("title") || null,
          alt: img.getAttribute("alt") || null,
          isReadable: isReadable
        });
      }
    }
  }
  return images;
}

function findSiteName() {
  let el = document.querySelector("meta[property='og:site_name']");
  if (el) {
    return el.getAttribute("content");
  }
  // nytimes.com uses this property:
  el = document.querySelector("meta[name='cre']");
  if (el) {
    return el.getAttribute("content");
  }
  return null;
}

self.port.emit("data", watchFunction(extractData)());
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { findDOMNode } from 'react-dom';
import classNames from 'classnames';

const propTypes = {
    className: PropTypes.string,
    onCancel: PropTypes.func,
    open: PropTypes.bool
};

const defaultProps = {
    onCancel: e => e.preventDefault()
};

class Dialog extends React.Component {
    componentDidMount() {
        this.dialogRef.addEventListener('cancel', this.props.onCancel);
        if (this.props.open) {
            findDOMNode(this).showModal();
        }
    }

    componentDidUpdate(prevProps) {
        if (this.props.open !== prevProps.open) {
            if (this.props.open) {
                findDOMNode(this).showModal();

                // display the dialog at the right location
                // needed for the polyfill, otherwise it's not at the right position
                const windowHeight = window.innerHeight;
                if (this.dialogRef) {
                    const dialogHeight = this.dialogRef.clientHeight;
                    this.dialogRef.style.position = 'fixed';
                    this.dialogRef.style.top = `${(windowHeight - dialogHeight) / 2}px`;
                }
            } else {
                findDOMNode(this).close();
            }
        }
    }

    componentWillUnmount() {
        this.dialogRef.removeEventListener('cancel', this.props.onCancel);
    }

    render() {
        // We cannot set the `open` prop on the Dialog if we manage its state manually with `showModal`,
        // thus the disabled eslint rule
        // eslint-disable-next-line no-unused-vars
        const { className, open, onCancel, children, ...otherProps } = this.props;

        const classes = classNames('mdl-dialog', className);

        return (
            <dialog ref={(c) => (this.dialogRef = c)} className={classes} {...otherProps}>
                {children}
            </dialog>
        );
    }
}

Dialog.propTypes = propTypes;
Dialog.defaultProps = defaultProps;

export default Dialog;
<commit_msg>feat: Add `onBackdropClick` on `Dialog` (#475)<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { findDOMNode } from 'react-dom';
import classNames from 'classnames';

const propTypes = {
    className: PropTypes.string,
    onCancel: PropTypes.func,
    onBackdropClick: PropTypes.func,
    open: PropTypes.bool
};

const defaultProps = {
    onCancel: e => e.preventDefault()
};

class Dialog extends React.Component {
    componentDidMount() {
        this.backdropClickCallback = this.onDialogClick.bind(this);
        this.dialogRef.addEventListener('click', this.backdropClickCallback);
        this.dialogRef.addEventListener('cancel', this.props.onCancel);
        if (this.props.open) {
            findDOMNode(this).showModal();
        }
    }

    componentDidUpdate(prevProps) {
        if (this.props.open !== prevProps.open) {
            if (this.props.open) {
                findDOMNode(this).showModal();

                // display the dialog at the right location
                // needed for the polyfill, otherwise it's not at the right position
                const windowHeight = window.innerHeight;
                if (this.dialogRef) {
                    const dialogHeight = this.dialogRef.clientHeight;
                    this.dialogRef.style.position = 'fixed';
                    this.dialogRef.style.top = `${(windowHeight - dialogHeight) / 2}px`;
                }
            } else {
                findDOMNode(this).close();
            }
        }
    }

    componentWillUnmount() {
        this.dialogRef.removeEventListener('cancel', this.props.onCancel);
        this.dialogRef.removeEventListener('click', this.backdropClickCallback);
    }

    onDialogClick(event) {
        // http://stackoverflow.com/a/26984690
        if (this.props.onBackdropClick && event.target === this.dialogRef) {
            const rect = this.dialogRef.getBoundingClientRect();
            const insideDialog = (
                rect.top <= event.clientY &&
                event.clientY <= rect.top + rect.height &&
                rect.left <= event.clientX &&
                event.clientX <= rect.left + rect.width
            );

            if (!insideDialog) {
                this.props.onBackdropClick();
            }
        }
    }

    render() {
        // We cannot set the `open` prop on the Dialog if we manage its state manually with `showModal`,
        // thus the disabled eslint rule
        // eslint-disable-next-line no-unused-vars
        const { className, open, onCancel, children, onBackdropClick, ...otherProps } = this.props;

        const classes = classNames('mdl-dialog', className);

        return (
            <dialog ref={(c) => (this.dialogRef = c)} className={classes} {...otherProps}>
                {children}
            </dialog>
        );
    }
}

Dialog.propTypes = propTypes;
Dialog.defaultProps = defaultProps;

export default Dialog;
<|endoftext|>


<commit_before>/* Add http:// to URL fields on blur or when enter is pressed.
 * From https://aaronparecki.com/2018/06/03/4/url-form-field
 * Thanks Aaron!
 */
document.addEventListener('DOMContentLoaded', function() {
  function addDefaultScheme(target) {
    val = target.value.trim()
    if(val.match(/^(?!https?:)[^@]+\.[^@]+$/)) {
      scheme = target.attributes.scheme;
      target.value = (scheme ? scheme.value : "http") + "://" + val;
    }
  }
  var elements = document.querySelectorAll("input[type=url]");
  Array.prototype.forEach.call(elements, function(el, i){
    el.addEventListener("blur", function(e){
      addDefaultScheme(e.target);
    });
    el.addEventListener("keydown", function(e){
      if(e.keyCode == 13) {
        addDefaultScheme(e.target);
      }
    });
  });
});
<commit_msg>util.js: add comment that it shouldn't be loaded async<commit_after>/* Add http:// to URL fields on blur or when enter is pressed.
 * From https://aaronparecki.com/2018/06/03/4/url-form-field
 * Thanks Aaron!
 *
 * Warning: this script must be loaded synchronously, ie *not* with <script
 * async>. It adds an event listener on DOMContentLoaded, which some browsers
 * (eg Chrome) may fire before async scripts are loaded.
 */
document.addEventListener('DOMContentLoaded', function() {
  function addDefaultScheme(target) {
    val = target.value.trim()
    if(val.match(/^(?!https?:)[^@]+\.[^@]+$/)) {
      scheme = target.attributes.scheme;
      target.value = (scheme ? scheme.value : "http") + "://" + val;
    }
  }
  var elements = document.querySelectorAll("input[type=url]");
  Array.prototype.forEach.call(elements, function(el, i){
    el.addEventListener("blur", function(e){
      addDefaultScheme(e.target);
    });
    el.addEventListener("keydown", function(e){
      if(e.keyCode == 13) {
        addDefaultScheme(e.target);
      }
    });
  });
});
<|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/. */

"use strict";

var crypto = require("crypto");
var uuid = require('node-uuid');
var jwcrypto = require('jwcrypto');

/**
 * Build a digits code
 */
function digitsCode(size) {
  var nbBytes = Math.ceil(size / 2);
  var code = parseInt(crypto.randomBytes(nbBytes)
             .toString("hex"), 16).toString().substr(0, size);
  // If the code starts with zeros, parseInt removed them so we have
  // to put them back.
  while (code.length < size) {
    code = "0" + code;
  }
  return code;
}

function checkProperties(obj, keys) {
  keys.forEach(function(key) {
    if (!obj.hasOwnProperty(key)) {
      throw new Error("missing " + key + " parameter");
    }
  });
}

/**
 * Validate JWCrypto Keys
 */
function validateJWCryptoKey(keyObj) {
  if (keyObj === "") {
    throw new Error("Please generate a new JWCrypto keypair using: " +
                    "node bin/generate-keypair");
  }
  var keys;
  if (keyObj.algorithm === 'RS') {
    keys = ['n', 'e'];
  }
  else { // DS
    keys = ['y', 'p', 'q', 'g'];
  }
  checkProperties(keyObj, keys);
  return keyObj;
}

/**
 * Generate a BID certificate
 */
function generateCertificate(msisdn, host, publicKey, privateKey, duration,
                             callback) {
  var now = Date.now();
  var md5sum = crypto.createHash("md5");
  md5sum.update(msisdn);
  var msisdn_uuid = uuid.unparse(md5sum.digest());

  jwcrypto.cert.sign({
    publicKey: jwcrypto.loadPublicKeyFromObject(publicKey),
    principal: { email: msisdn_uuid + "@" + host}
  }, {
    issuer: host,
    // Set issuedAt to 10 seconds ago. Pads for verifier clock skew
    issuedAt: new Date(now - (10 * 1000)),
    expiresAt: new Date(now + duration)
  }, {
    "lastAuthAt": now,
    "verifiedMSISDN": msisdn
  }, privateKey, function(err, cert) {
    if (err) {
      callback(err);
      return;
    }
    callback(null, cert, now);
  });
}

module.exports = {
  crypto: crypto,
  digitsCode: digitsCode,
  validateJWCryptoKey: validateJWCryptoKey,
  generateCertificate: generateCertificate
};
<commit_msg>Bug — Duration is defined as being in seconds.<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/. */

"use strict";

var crypto = require("crypto");
var uuid = require('node-uuid');
var jwcrypto = require('jwcrypto');

/**
 * Build a digits code
 */
function digitsCode(size) {
  var nbBytes = Math.ceil(size / 2);
  var code = parseInt(crypto.randomBytes(nbBytes)
             .toString("hex"), 16).toString().substr(0, size);
  // If the code starts with zeros, parseInt removed them so we have
  // to put them back.
  while (code.length < size) {
    code = "0" + code;
  }
  return code;
}

function checkProperties(obj, keys) {
  keys.forEach(function(key) {
    if (!obj.hasOwnProperty(key)) {
      throw new Error("missing " + key + " parameter");
    }
  });
}

/**
 * Validate JWCrypto Keys
 */
function validateJWCryptoKey(keyObj) {
  if (keyObj === "") {
    throw new Error("Please generate a new JWCrypto keypair using: " +
                    "node bin/generate-keypair");
  }
  var keys;
  if (keyObj.algorithm === 'RS') {
    keys = ['n', 'e'];
  }
  else { // DS
    keys = ['y', 'p', 'q', 'g'];
  }
  checkProperties(keyObj, keys);
  return keyObj;
}

/**
 * Generate a BID certificate
 */
function generateCertificate(msisdn, host, publicKey, privateKey, duration,
                             callback) {
  var now = Date.now();
  var md5sum = crypto.createHash("md5");
  md5sum.update(msisdn);
  var msisdn_uuid = uuid.unparse(md5sum.digest());

  jwcrypto.cert.sign({
    publicKey: jwcrypto.loadPublicKeyFromObject(publicKey),
    principal: { email: msisdn_uuid + "@" + host}
  }, {
    issuer: host,
    // Set issuedAt to 10 seconds ago. Pads for verifier clock skew
    issuedAt: new Date(now - (10 * 1000)),
    expiresAt: new Date(now + duration * 1000)
  }, {
    "lastAuthAt": now,
    "verifiedMSISDN": msisdn
  }, privateKey, function(err, cert) {
    if (err) {
      callback(err);
      return;
    }
    callback(null, cert, now);
  });
}

module.exports = {
  crypto: crypto,
  digitsCode: digitsCode,
  validateJWCryptoKey: validateJWCryptoKey,
  generateCertificate: generateCertificate
};
<|endoftext|>


<commit_before>var clock = cabrito.Class.extends(function (time) {
    var status = 0;
    this.timeElapsed = time;
    this.date = function () {
        var d = new Date();
        return d;
    };

    var getMinutes = function (seconds_left) {
        return parseInt(seconds_left / 60);
    };

    var getSeconds = function (seconds_left) {
        var seconds = parseInt(seconds_left % 60);
        if (seconds <= 9) {
            seconds = '0' + seconds;
        }
        return seconds;
    };

    this.getTimer = function (seconds_left) {
        return getMinutes(seconds_left) + ':' + getSeconds(seconds_left);
    };

    this.pomodoro = function (time, div) {
        var d1 = this.date();
        var d2 = this.date();
        d2.setMinutes(d2.getMinutes() + time);
        var seconds_left = (d2 - d1) / 1000;
        div = document.getElementById(div);
        if (div) {
            div.innerHTML = this.getTimer(seconds_left);
        }
        var getTimer = this.getTimer;
        var int = setInterval(function () {
            status += 1;
            seconds_left = seconds_left - 1;
            if (div) {
                div.innerHTML = getTimer(seconds_left);
            }
            if (d1 >= d2) {
                status = 0;
                clearInterval(int);
                alert('POMODORO!');
            }
        }, 1000);
    };
    this.status = function () {
        return status;
    };
});
<commit_msg>BUGFIX - Corrigindo Bug que permitia que o relógio ficasse negativo<commit_after>var clock = cabrito.Class.extends(function (time) {
    var status = 0;
    this.timeElapsed = time;
    this.date = function () {
        var d = new Date();
        return d;
    };

    var getMinutes = function (seconds_left) {
        return parseInt(seconds_left / 60);
    };

    var getSeconds = function (seconds_left) {
        var seconds = parseInt(seconds_left % 60);
        if (seconds <= 9) {
            seconds = '0' + seconds;
        }
        return seconds;
    };

    this.getTimer = function (seconds_left) {
        return getMinutes(seconds_left) + ':' + getSeconds(seconds_left);
    };

    this.pomodoro = function (time, div) {
        var d1 = this.date();
        var d2 = this.date();
        d2.setMinutes(d2.getMinutes() + time);
        var seconds_left = (d2 - d1) / 1000;
        div = document.getElementById(div);
        if (div) {
            div.innerHTML = this.getTimer(seconds_left);
        }
        var getTimer = this.getTimer;
        var int = setInterval(function () {
            status += 1;
            seconds_left = seconds_left - 1;
            if (seconds_left <= 0) {
                status = 0;
                clearInterval(int);
                alert('POMODORO!');
                return;
            }
            if (div) {
                div.innerHTML = getTimer(seconds_left);
            }
        }, 1000);
    };
    this.status = function () {
        return status;
    };
});
<|endoftext|>


<commit_before>(function () {

    var customersController = function ($rootScope, $scope, $location, $routeParams, $timeout, config, dataService, modalService) {

        var customerID = ($routeParams.customerID) ? parseInt($routeParams.customerID) : 0,
            timer,
            onRouteChangeOff;

        $scope.customer;
        $scope.states = [];
        $scope.title = (customerID > 0) ? 'Edit' : 'Add';
        $scope.buttonText = (customerID > 0) ? 'Update' : 'Add';
        $scope.updateStatus = false;
        $scope.errorMessage = '';

        init();

        $scope.isStateSelected = function (customerStateId, stateId) {
            return customerStateId === stateId;
        };

        $scope.saveCustomer = function () {
            if ($scope.editForm.$valid) {
                if (!$scope.customer.id) {
                    dataService.insertCustomer($scope.customer).then(processSuccess, processError);
                }
                else {
                    dataService.updateCustomer($scope.customer).then(processSuccess, processError);
                }
            }
        };

        $scope.deleteCustomer = function () {
            var custName = $scope.customer.firstName + ' ' + $scope.customer.lastName;
            var modalOptions = {
                closeButtonText: 'Cancel',
                actionButtonText: 'Delete Customer',
                headerText: 'Delete ' + custName + '?',
                bodyText: 'Are you sure you want to delete this customer?'
            };

            modalService.showModal({}, modalOptions).then(function (result) {
                if (result === 'ok') {
                    dataService.deleteCustomer($scope.customer.id).then(function () {
                        onRouteChangeOff(); //Stop listening for location changes
                        $location.path('/customers');
                    }, processError);
                }
            });
        };

        function init() {
            if (customerID > 0) {
                dataService.getCustomer(customerID).then(function (customer) {
                    $scope.customer = customer;
                }, processError);
            } else {
                dataService.newCustomer().then(function (customer) {
                    $scope.customer = customer;
                });

            }
            getStates();

            //Make sure they're warned if they made a change but didn't save it
            //Call to $on returns a "deregistration" function that can be called to
            //remove the listener (see routeChange() for an example of using it)
            onRouteChangeOff = $rootScope.$on('$locationChangeStart', routeChange);
        }

        function routeChange(event, newUrl) {
            //Navigate to newView if the form isn't dirty
            if (!$scope.editForm.$dirty) return;

            var modalOptions = {
                closeButtonText: 'Cancel',
                actionButtonText: 'Ignore Changes',
                headerText: 'Unsaved Changes',
                bodyText: 'You have unsaved changes. Leave the page?'
            };

            modalService.showModal({}, modalOptions).then(function (result) {
                if (result === 'ok') {
                    onRouteChangeOff(); //Stop listening for location changes
                    $location.path(newUrl); //Go to page they're interested in
                }
            });

            //prevent navigation by default since we'll handle it
            //once the user selects a dialog option
            event.preventDefault();
            return;
        }

        function getStates() {
            dataService.getStates().then(function (states) {
                $scope.states = states;
            }, processError);
        }

        function processSuccess() {
            $scope.editForm.$dirty = false;
            $scope.updateStatus = true;
            $scope.title = 'Edit';
            $scope.buttonText = 'Update';
            startTimer();
        }

        function processError(error) {
            $scope.errorMessage = error.message;
            startTimer();
        }

        function startTimer() {
            timer = $timeout(function () {
                $timeout.cancel(timer);
                $scope.errorMessage = '';
                $scope.updateStatus = false;
            }, 3000);
        }
    };

    customersManager.customersApp.controller('CustomerEditController',
       ['$rootScope', '$scope', '$location', '$routeParams', '$timeout', 'config', 'dataService', 'modalService', customersController]);

}());<commit_msg>Fixed up comment<commit_after>(function () {

    var customersController = function ($rootScope, $scope, $location, $routeParams, $timeout, config, dataService, modalService) {

        var customerID = ($routeParams.customerID) ? parseInt($routeParams.customerID) : 0,
            timer,
            onRouteChangeOff;

        $scope.customer;
        $scope.states = [];
        $scope.title = (customerID > 0) ? 'Edit' : 'Add';
        $scope.buttonText = (customerID > 0) ? 'Update' : 'Add';
        $scope.updateStatus = false;
        $scope.errorMessage = '';

        init();

        $scope.isStateSelected = function (customerStateId, stateId) {
            return customerStateId === stateId;
        };

        $scope.saveCustomer = function () {
            if ($scope.editForm.$valid) {
                if (!$scope.customer.id) {
                    dataService.insertCustomer($scope.customer).then(processSuccess, processError);
                }
                else {
                    dataService.updateCustomer($scope.customer).then(processSuccess, processError);
                }
            }
        };

        $scope.deleteCustomer = function () {
            var custName = $scope.customer.firstName + ' ' + $scope.customer.lastName;
            var modalOptions = {
                closeButtonText: 'Cancel',
                actionButtonText: 'Delete Customer',
                headerText: 'Delete ' + custName + '?',
                bodyText: 'Are you sure you want to delete this customer?'
            };

            modalService.showModal({}, modalOptions).then(function (result) {
                if (result === 'ok') {
                    dataService.deleteCustomer($scope.customer.id).then(function () {
                        onRouteChangeOff(); //Stop listening for location changes
                        $location.path('/customers');
                    }, processError);
                }
            });
        };

        function init() {
            if (customerID > 0) {
                dataService.getCustomer(customerID).then(function (customer) {
                    $scope.customer = customer;
                }, processError);
            } else {
                dataService.newCustomer().then(function (customer) {
                    $scope.customer = customer;
                });

            }
            getStates();

            //Make sure they're warned if they made a change but didn't save it
            //Call to $on returns a "deregistration" function that can be called to
            //remove the listener (see routeChange() for an example of using it)
            onRouteChangeOff = $rootScope.$on('$locationChangeStart', routeChange);
        }

        function routeChange(event, newUrl) {
            //Navigate to newUrl if the form isn't dirty
            if (!$scope.editForm.$dirty) return;

            var modalOptions = {
                closeButtonText: 'Cancel',
                actionButtonText: 'Ignore Changes',
                headerText: 'Unsaved Changes',
                bodyText: 'You have unsaved changes. Leave the page?'
            };

            modalService.showModal({}, modalOptions).then(function (result) {
                if (result === 'ok') {
                    onRouteChangeOff(); //Stop listening for location changes
                    $location.path(newUrl); //Go to page they're interested in
                }
            });

            //prevent navigation by default since we'll handle it
            //once the user selects a dialog option
            event.preventDefault();
            return;
        }

        function getStates() {
            dataService.getStates().then(function (states) {
                $scope.states = states;
            }, processError);
        }

        function processSuccess() {
            $scope.editForm.$dirty = false;
            $scope.updateStatus = true;
            $scope.title = 'Edit';
            $scope.buttonText = 'Update';
            startTimer();
        }

        function processError(error) {
            $scope.errorMessage = error.message;
            startTimer();
        }

        function startTimer() {
            timer = $timeout(function () {
                $timeout.cancel(timer);
                $scope.errorMessage = '';
                $scope.updateStatus = false;
            }, 3000);
        }
    };

    customersManager.customersApp.controller('CustomerEditController',
       ['$rootScope', '$scope', '$location', '$routeParams', '$timeout', 'config', 'dataService', 'modalService', customersController]);

}());<|endoftext|>


<commit_before>if (!Spaz.dock) Spaz.dock = {};

/***********
Spaz.dock takes care of the docking
***********/

Spaz.dock.init = function() {

   // Only on OSX
   Spaz.dock.active = air.NativeApplication.supportsDockIcon;

   //
   if (!Spaz.dock.active)
   {
      return;
   }

   // Create the text format
   var format = new window.runtime.flash.text.TextFormat();
   format.size = 30;
   format.color = 0xFFFFFF;
   format.bold = true;
   format.font = 'Arial';
   air.trace("Dock text format created");

   // Load the image async
   var imageURL = 'images/spaz-icon-alpha.png';
   air.trace("Want to load image " + imageURL);
   var loader = new air.Loader();
   loader.contentLoaderInfo.addEventListener(air.Event.COMPLETE, function(event)
   {
      air.trace("Loaded image " + imageURL);
      Spaz.dock.bitmapData = event.target.content.bitmapData;
   }, false, 0, true);
   loader.load(new air.URLRequest(imageURL));

   // Save for later use
   Spaz.dock.icon = air.NativeApplication.nativeApplication.icon;
   Spaz.dock.textFormat = format;
   Spaz.dock.padding = 4;
   Spaz.dock.border = 5;

   // Install the refresh timer to 1/2 second which seems a reasonable value
   window.setInterval(Spaz.dock.refresh, 500);
}

Spaz.dock.refresh = function(unreadCount)
{
   if (!Spaz.dock.active)
   {
      return;
   }

   //
   if (typeof unreadCount == 'undefined')
   {
      unreadCount = $("#timeline-friends div.timeline-entry").size() - $("#timeline-friends div.timeline-entry.read").size();
   }

   //
   if (unreadCount == Spaz.dock.lastUnreadCount)
   {
      return;
   }

   // Use the original icon if count is zero
   if (unreadCount == 0)
   {
      // Update state
      Spaz.dock.icon.bitmaps = [Spaz.dock.bitmapData];
      Spaz.dock.lastUnreadCount = 0;
      return;
   }

   //
   var tf = new window.runtime.flash.text.TextField();
   tf.defaultTextFormat = Spaz.dock.textFormat;
   tf.text = "" + unreadCount;
   tf.wordWrap = true;

   // Clone the bitmap
   var clone = Spaz.dock.bitmapData.clone();

   // Draw the text in a buffer
   var buffer = new window.runtime.flash.display.BitmapData(
      256,
      256,
      true,
      0);
   buffer.draw(tf);

   // Compute the bounding box, we cannot use TextField.textWidth and TextField.textHeight as
   // they return approximation which results into incorrect display
   var xmin = 0;
   var ymin = 0;
   var xmax = tf.textWidth;
   var ymax = tf.textHeight;
   var width = xmax - xmin;
   var height = ymax - ymin;

   // Compute the ellipse dimensions
   var eH = (width / (Math.sqrt(2)));
   var eY = (height / (Math.sqrt(2)));

   // Correct the dimension if the ellipse width is lesser than the ellipse height
   if (eH < eY)
   {
      eH = eY;
   }

   // Compute the inner and outter ellipses
   var innerW = eH + Spaz.dock.padding;
   var innerH = eY + Spaz.dock.padding;
   var outterW = eH + Spaz.dock.padding + Spaz.dock.border;
   var outterH = eY + Spaz.dock.padding + Spaz.dock.border;

   // Draw the shape
   var shape = new window.runtime.flash.display.Shape();
   Spaz.dock.drawPolygon(
      shape.graphics,
      outterW,
      outterH,
      innerW,
      innerH,
      outterW,
      outterH,
      30);
   clone.draw(shape);

   // Copy the text on top of the shape
   clone.copyPixels(
      buffer,
      new window.runtime.flash.geom.Rectangle(xmin, ymin, width, height),
      new window.runtime.flash.geom.Point(outterW - width / 2, outterH - height / 2),
      null,
      null,
      true);

   // Update state
   Spaz.dock.icon.bitmaps = [clone];
   Spaz.dock.lastUnreadCount = unreadCount;
}

Spaz.dock.drawPolygon = function(graphics, centerX, centerY, innerW, innerH, outterW, outterH, size)
{
   var delta = (Math.PI * 2) / size;
   var angle = 0;
   var xs = [];
   var ys = [];
   for (var i = 0;i < size;i++)
   {
      angle = delta * i + (Math.PI / 2);
      var x1 = centerX + outterW * Math.cos(angle) + 0.5;
      var y1 = centerY - outterH * Math.sin(angle) + 0.5;
      angle += delta / 2;
      var x2 = centerX + innerW * Math.cos(angle) + 0.5;
      var y2 = centerY - innerH * Math.sin(angle) + 0.5;

      //
      xs.push(x1);
      ys.push(y1);
      xs.push(x2);
      ys.push(y2);
   }

   // Draw the inner
   var fillType = window.runtime.flash.display.GradientType.LINEAR;
   var colors = [0xFF0000, 0xAA0000];
   var alphas = [1, 1];
   var ratios = [0x00, 0xFF];
   var matr = new window.runtime.flash.geom.Matrix();
   matr.createGradientBox(outterW * 2, 0, 0, 0, 0);
   var spreadMethod = window.runtime.flash.display.SpreadMethod.PAD;
   graphics.beginGradientFill(fillType, colors, alphas, ratios, matr, spreadMethod);

   //
   graphics.lineStyle(
      2,
      0x660000,
      1,
      false,
      window.runtime.flash.display.LineScaleMode.NORMAL,
      window.runtime.flash.display.CapsStyle.NONE,
      window.runtime.flash.display.JointStyle.MITER,
      3);

   //
   for (var j in xs)
   {
      if (j == 0)
      {
         graphics.moveTo(xs[j], ys[j]);
      }
      else
      {
         graphics.lineTo(xs[j], ys[j]);
      }
   }

   //
   graphics.endFill();

   // Draw the perimeter
//   graphics.lineStyle(
//      3,
//      0xFF,
//      1,
//      false,
//      window.runtime.flash.display.LineScaleMode.NORMAL,
//      window.runtime.flash.display.CapsStyle.NONE,
//      window.runtime.flash.display.JointStyle.MITER,
//      3);
//   for (var j in xs)
//   {
//      if (j == 0)
//      {
//         graphics.moveTo(xs[j], ys[j]);
//      }
//      else
//      {
//         graphics.lineTo(xs[j], ys[j]);
//      }
//   }
//   graphics.lineTo(xs[0], ys[0]);
}
<commit_msg>remove obsolete code<commit_after>if (!Spaz.dock) Spaz.dock = {};

/***********
Spaz.dock takes care of the docking
***********/

Spaz.dock.init = function() {

   // Only on OSX
   Spaz.dock.active = air.NativeApplication.supportsDockIcon;

   //
   if (!Spaz.dock.active)
   {
      return;
   }

   // Create the text format
   var format = new window.runtime.flash.text.TextFormat();
   format.size = 30;
   format.color = 0xFFFFFF;
   format.bold = true;
   format.font = 'Arial';
   air.trace("Dock text format created");

   // Load the image async
   var imageURL = 'images/spaz-icon-alpha.png';
   air.trace("Want to load image " + imageURL);
   var loader = new air.Loader();
   loader.contentLoaderInfo.addEventListener(air.Event.COMPLETE, function(event)
   {
      air.trace("Loaded image " + imageURL);
      Spaz.dock.bitmapData = event.target.content.bitmapData;
   }, false, 0, true);
   loader.load(new air.URLRequest(imageURL));

   // Save for later use
   Spaz.dock.icon = air.NativeApplication.nativeApplication.icon;
   Spaz.dock.textFormat = format;
   Spaz.dock.padding = 4;
   Spaz.dock.border = 5;

   // Install the refresh timer to 1/2 second which seems a reasonable value
   window.setInterval(Spaz.dock.refresh, 500);
}

Spaz.dock.refresh = function(unreadCount)
{
   if (!Spaz.dock.active)
   {
      return;
   }

   //
   if (typeof unreadCount == 'undefined')
   {
      unreadCount = $("#timeline-friends div.timeline-entry").size() - $("#timeline-friends div.timeline-entry.read").size();
   }

   //
   if (unreadCount == Spaz.dock.lastUnreadCount)
   {
      return;
   }

   // Use the original icon if count is zero
   if (unreadCount == 0)
   {
      // Update state
      Spaz.dock.icon.bitmaps = [Spaz.dock.bitmapData];
      Spaz.dock.lastUnreadCount = 0;
      return;
   }

   //
   var tf = new window.runtime.flash.text.TextField();
   tf.defaultTextFormat = Spaz.dock.textFormat;
   tf.text = "" + unreadCount;
   tf.wordWrap = true;

   // Clone the bitmap
   var clone = Spaz.dock.bitmapData.clone();

   // Draw the text in a buffer
   var buffer = new window.runtime.flash.display.BitmapData(
      256,
      256,
      true,
      0);
   buffer.draw(tf);

   // Compute the bounding box, we cannot use TextField.textWidth and TextField.textHeight as
   // they return approximation which results into incorrect display
   var xmin = 0;
   var ymin = 0;
   var xmax = tf.textWidth;
   var ymax = tf.textHeight;
   var width = xmax - xmin;
   var height = ymax - ymin;

   // Compute the ellipse dimensions
   var eH = (width / (Math.sqrt(2)));
   var eY = (height / (Math.sqrt(2)));

   // Correct the dimension if the ellipse width is lesser than the ellipse height
   if (eH < eY)
   {
      eH = eY;
   }

   // Compute the inner and outter ellipses
   var innerW = eH + Spaz.dock.padding;
   var innerH = eY + Spaz.dock.padding;
   var outterW = eH + Spaz.dock.padding + Spaz.dock.border;
   var outterH = eY + Spaz.dock.padding + Spaz.dock.border;

   // Draw the shape
   var shape = new window.runtime.flash.display.Shape();
   Spaz.dock.drawPolygon(
      shape.graphics,
      outterW,
      outterH,
      innerW,
      innerH,
      outterW,
      outterH,
      30);
   clone.draw(shape);

   // Copy the text on top of the shape
   clone.copyPixels(
      buffer,
      new window.runtime.flash.geom.Rectangle(xmin, ymin, width, height),
      new window.runtime.flash.geom.Point(outterW - width / 2, outterH - height / 2),
      null,
      null,
      true);

   // Update state
   Spaz.dock.icon.bitmaps = [clone];
   Spaz.dock.lastUnreadCount = unreadCount;
}

Spaz.dock.drawPolygon = function(graphics, centerX, centerY, innerW, innerH, outterW, outterH, size)
{
   var delta = (Math.PI * 2) / size;
   var angle = 0;
   var xs = [];
   var ys = [];
   for (var i = 0;i < size;i++)
   {
      angle = delta * i + (Math.PI / 2);
      var x1 = centerX + outterW * Math.cos(angle) + 0.5;
      var y1 = centerY - outterH * Math.sin(angle) + 0.5;
      angle += delta / 2;
      var x2 = centerX + innerW * Math.cos(angle) + 0.5;
      var y2 = centerY - innerH * Math.sin(angle) + 0.5;

      //
      xs.push(x1);
      ys.push(y1);
      xs.push(x2);
      ys.push(y2);
   }

   // Draw the inner
   var fillType = window.runtime.flash.display.GradientType.LINEAR;
   var colors = [0xFF0000, 0xAA0000];
   var alphas = [1, 1];
   var ratios = [0x00, 0xFF];
   var matr = new window.runtime.flash.geom.Matrix();
   matr.createGradientBox(outterW * 2, 0, 0, 0, 0);
   var spreadMethod = window.runtime.flash.display.SpreadMethod.PAD;
   graphics.beginGradientFill(fillType, colors, alphas, ratios, matr, spreadMethod);

   //
   graphics.lineStyle(
      2,
      0x660000,
      1,
      false,
      window.runtime.flash.display.LineScaleMode.NORMAL,
      window.runtime.flash.display.CapsStyle.NONE,
      window.runtime.flash.display.JointStyle.MITER,
      3);

   //
   for (var j in xs)
   {
      if (j == 0)
      {
         graphics.moveTo(xs[j], ys[j]);
      }
      else
      {
         graphics.lineTo(xs[j], ys[j]);
      }
   }

   //
   graphics.endFill();
}
<|endoftext|>


<commit_before><commit_msg>Added medium size<commit_after><|endoftext|>


<commit_before>var _class = (function() {

  var CLASS_RELATIONSHIP = [[Object, null]];

  var get_parent = function(_class) {
    for (var i=0,l=CLASS_RELATIONSHIP.length;i<l;i++) {
      var rel = CLASS_RELATIONSHIP[i];
      if (rel[0] === _class) return rel[1];
    }
    return null;
  };

  var __super__ = function() {
    var pro = this.__proto__;
    return ((pro !== void(0)) ?
            ((this.constructor.prototype === this) ? pro : pro.__proto__ ) :
            get_parent(this.constructor).prototype);
  };

  var inherits = function(_class, parent) {

    CLASS_RELATIONSHIP.push([_class, parent]);

    var f = function(){}
    f.prototype = parent.prototype;
    _class.prototype = new f();
    _class.prototype.constructor = _class;
    _class.prototype.__super__ = __super__;

    var iiop = _class['%%INIT_INSTANCE_ORIGN_PROPS'];

    _class['%%INIT_INSTANCE_ORIGN_PROPS'] = function(inst) {
      var parent_iiop = parent['%%INIT_INSTANCE_ORIGN_PROPS'];
      if (parent_iiop) parent_iiop(inst);
      iiop(inst);
    };

    return _class;

  };

  var method = function(_class, name, func) {
    _class.prototype[name] = func;
  };

  var genclassid = (function() {
    var id = 0;
    return function() {
      var ret = "%%ANONYMOUS_CLASS_"+id+"%%"; ++id;
      return ret;
    };
  })();

  var mixin = function(_class, include) {
    var incproto = include.prototype;
    for(i in incproto) {
      if (incproto.hasOwnProperty(i)) {
        if (i !== "__super__" && i !== "constructor" && i !=="init") {
          _class.prototype[i] = incproto[i];
        }
      }
    }

    var iiop = _class['%%INIT_INSTANCE_ORIGN_PROPS'];
    _class['%%INIT_INSTANCE_ORIGN_PROPS'] = function(inst) {
      var include_iiop = include['%%INIT_INSTANCE_ORIGN_PROPS'];
      if (include_iiop) include_iiop(inst);
      iiop(inst);
    };
  };

  var check_interface = function(_class, impl) {
    for (var i in impl.prototype) {
      if (impl.prototype.hasOwnProperty(i)) {
        if (!_class.prototype.hasOwnProperty(i)) {
          throw new DeclarationError(
              'The class \'' + _class['%%CLASSNAME%%'] +
              '\' must provide property or method \'' + i +
              '\' imposed by \'' + impl['%%CLASSNAME%%'] +'".');
        }
      }
    }
  };

  return function _class(name, definition) {
    var __class__, i, j, l, c, def, type;

    var props = {};
    var class_props = {};
    var methods = {};
    var class_methods = {};
    var parent = Object;
    var mixins = [];
    var interfaces = [];

    for(i in definition) {
      if (definition.hasOwnProperty(i)) {
        if (i === "props") {
          def = definition[i];
          for (j in def) {
            if (def.hasOwnProperty(j))
              props[j] = def[j];
          }

        } else if (i === "class_props") {
          class_props = definition[i];

        } else if (i === "methods") {
          methods = definition[i];

        } else if (i === "class_methods") {
          class_methods = definition[i];

        } else if (i === "parent") {
          parent = definition[i];

        } else if (i === "interfaces") {
          interfaces = definition[i];

        } else if (i === "mixins") {
          mixins = definition[i];

        } else {
          throw new ArgumentError(
              'You gave \'' + i + '\' as definition, but the _class() excepts' +
              ' only \'props\',\'class_props\',\'methods\',\'class_methods\',\'parent\',\'interfaces\',\'mixins\'.');

        }
      }
    }

    var init = methods["init"];

    if (init) {
      __class__ = function() {
        __class__['%%INIT_INSTANCE_ORIGN_PROPS'](this);
        init.apply(this, arguments);
      };

    } else {
      __class__ = function(arg){
        __class__['%%INIT_INSTANCE_ORIGN_PROPS'](this);
        if (arg) {
          _clone(arg, this);
        }
      };

    }

    l = 0;
    for (p in props) {
      if (props.hasOwnProperty(p)) l++;
    }

    __class__['%%INIT_INSTANCE_ORIGN_PROPS'] = (
      ( l > 0 ) ? function(inst) {
        for (var p in props) {
          if (props.hasOwnProperty(p)) {
            inst[p] = _clone(props[p]);
          }
        }
      } : function(){});

    inherits(__class__, parent);

    for(j=0, l=mixins.length; j<l; j++) {
      mixin(__class__, mixins[j]);
    }

    for (i in methods) {
      if (methods.hasOwnProperty(i)) {
        method(__class__, i, methods[i]);
      }
    }

    __class__['%%CLASSNAME%%'] = name || genclassid();
    for(i in class_methods) {
      if (class_methods.hasOwnProperty(i)) {
        __class__[i] = class_methods[i];
      }
    }

    for(i in class_props) {
      if (class_props.hasOwnProperty(i)) {
        __class__[i] = class_props[i];
      }
    }

    for (j=0, l=interfaces.length; j<l; j++) {
      check_interface(__class__, interfaces[j]);
    }

    return __class__;

  };

})();
<commit_msg>No need to use hasOwnProperty() here.<commit_after>var _class = (function() {

  var CLASS_RELATIONSHIP = [[Object, null]];

  var get_parent = function(_class) {
    for (var i=0,l=CLASS_RELATIONSHIP.length;i<l;i++) {
      var rel = CLASS_RELATIONSHIP[i];
      if (rel[0] === _class) return rel[1];
    }
    return null;
  };

  var __super__ = function() {
    var pro = this.__proto__;
    return ((pro !== void(0)) ?
            ((this.constructor.prototype === this) ? pro : pro.__proto__ ) :
            get_parent(this.constructor).prototype);
  };

  var inherits = function(_class, parent) {

    CLASS_RELATIONSHIP.push([_class, parent]);

    var f = function(){}
    f.prototype = parent.prototype;
    _class.prototype = new f();
    _class.prototype.constructor = _class;
    _class.prototype.__super__ = __super__;

    var iiop = _class['%%INIT_INSTANCE_ORIGN_PROPS'];

    _class['%%INIT_INSTANCE_ORIGN_PROPS'] = function(inst) {
      var parent_iiop = parent['%%INIT_INSTANCE_ORIGN_PROPS'];
      if (parent_iiop) parent_iiop(inst);
      iiop(inst);
    };

    return _class;

  };

  var method = function(_class, name, func) {
    _class.prototype[name] = func;
  };

  var genclassid = (function() {
    var id = 0;
    return function() {
      var ret = "%%ANONYMOUS_CLASS_"+id+"%%"; ++id;
      return ret;
    };
  })();

  var mixin = function(_class, include) {
    var incproto = include.prototype;
    for(i in incproto) {
      if (i !== "__super__" && i !== "constructor" && i !=="init") {
        _class.prototype[i] = incproto[i];
      }
    }

    var iiop = _class['%%INIT_INSTANCE_ORIGN_PROPS'];
    _class['%%INIT_INSTANCE_ORIGN_PROPS'] = function(inst) {
      var include_iiop = include['%%INIT_INSTANCE_ORIGN_PROPS'];
      if (include_iiop) include_iiop(inst);
      iiop(inst);
    };
  };

  var check_interface = function(_class, impl) {
    for (var i in impl.prototype) {
      if (impl.prototype.hasOwnProperty(i)) {
        if (!_class.prototype.hasOwnProperty(i)) {
          throw new DeclarationError(
              'The class \'' + _class['%%CLASSNAME%%'] +
              '\' must provide property or method \'' + i +
              '\' imposed by \'' + impl['%%CLASSNAME%%'] +'".');
        }
      }
    }
  };

  return function _class(name, definition) {
    var __class__, i, j, l, c, def, type;

    var props = {};
    var class_props = {};
    var methods = {};
    var class_methods = {};
    var parent = Object;
    var mixins = [];
    var interfaces = [];

    for(i in definition) {
      if (i === "props") {
        def = definition[i];
        for (j in def) {
          if (def.hasOwnProperty(j))
            props[j] = def[j];
        }
      } else if (i === "class_props") {
        class_props = definition[i];

      } else if (i === "methods") {
        methods = definition[i];

      } else if (i === "class_methods") {
        class_methods = definition[i];

      } else if (i === "parent") {
        parent = definition[i];

      } else if (i === "interfaces") {
        interfaces = definition[i];

      } else if (i === "mixins") {
        mixins = definition[i];

      } else {
        throw new ArgumentError(
            'You gave \'' + i + '\' as definition, but the _class() excepts' +
            ' only \'props\',\'class_props\',\'methods\',\'class_methods\',\'parent\',\'interfaces\',\'mixins\'.');

      }
    }

    var init = methods["init"];

    if (init) {
      __class__ = function() {
        __class__['%%INIT_INSTANCE_ORIGN_PROPS'](this);
        init.apply(this, arguments);
      };

    } else {
      __class__ = function(arg){
        __class__['%%INIT_INSTANCE_ORIGN_PROPS'](this);
        if (arg) {
          _clone(arg, this);
        }
      };

    }

    l = 0;
    for (p in props) {
      if (props.hasOwnProperty(p)) l++;
    }

    __class__['%%INIT_INSTANCE_ORIGN_PROPS'] = (
      ( l > 0 ) ? function(inst) {
        for (var p in props) {
          if (props.hasOwnProperty(p)) {
            inst[p] = _clone(props[p]);
          }
        }
      } : function(){});

    inherits(__class__, parent);

    for(j=0, l=mixins.length; j<l; j++) {
      mixin(__class__, mixins[j]);
    }

    for (i in methods) {
      if (methods.hasOwnProperty(i)) {
        method(__class__, i, methods[i]);
      }
    }

    __class__['%%CLASSNAME%%'] = name || genclassid();
    for(i in class_methods) {
      if (class_methods.hasOwnProperty(i)) {
        __class__[i] = class_methods[i];
      }
    }

    for(i in class_props) {
      if (class_props.hasOwnProperty(i)) {
        __class__[i] = class_props[i];
      }
    }

    for (j=0, l=interfaces.length; j<l; j++) {
      check_interface(__class__, interfaces[j]);
    }

    return __class__;

  };

})();
<|endoftext|>


<commit_before>bt = bt || {};

bt.Widget = (function() {
  var widgets = {}, eventHandlers = {}, dispatchEvent, currentHandler;

  // Workaround for Firefox Bug 574941 -- should work in all UAs:
  var NativeError = Error;
  Error = function(settings) {
    arguments.callee.check('Error', arguments, 'Os', 0);
    var e = (this instanceof Error) ? this : new Error(arguments);
    if ('string' === typeof settings[0]) e.message = settings[0];
    if ('string' === typeof settings)    e.message = settings;
    else if ('object' === typeof settings) _.extend(e, settings);
    e.toString = e.toString || function() {
      return settings.name + ': ' + settings.message;
    };
    throw e;
    return;
  }
  Error.prototype = new NativeError();

  // Set up event-based callbacks.
  var createEventDispatcher = function(name) {
    var eventName = name + '_Events';
    if (document.addEventListener) {
      document.addEventListener(eventName, function() {
        currentHandler.apply(
          currentHandler.persona || currentHandler,
          currentHandler.args);
      }, false);
      dispatchEvent = function() {
        var widgetEvent = document.createEvent("UIEvents");
        widgetEvent.initEvent(eventName, false, false);
        document.dispatchEvent(widgetEvent);
      };
    }
    else { // MSIE
      document.documentElement[eventName] = 0;
      document.documentElement.attachEvent("onpropertychange", function(event) {
        if (eventName === event.propertyName) {
          currentHandler.apply(
            currentHandler.persona || currentHandler,
            currentHandler.args || []);
        }
      });
      dispatchEvent = function(handler) {
        document.documentElement[eventName]++;
      };
    }
    return dispatchEvent;
  };

  var createError = function(settings) {
    var e = _.clone(settings);
    e.prototype = new Error;
    return e;
  };

  return function(widgetName) {
    arguments.callee.check('Widget', arguments, 'S');

    widgetName = widgetName.replace(/\W/g, '_');

    // Check for error conditions.
    if(!(this instanceof bt.Widget)) {
      throw new createError({
        name: 'InvocationError',
        message: 'Widget constructor must create a new instance.'
      });
    }
    if (undefined !== widgets[widgetName]) {
      throw new createError({
        name: 'IdentityTheftError',
        message: sprintf('A Widget named "%s" already exists.', widgetName)
      });
    }

    widgets[widgetName] = this;

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // this.addCallback()
    this.addCallback = function(category, handler) {
      arguments.callee.check('addCallback', arguments, 'SF');
      var name = widgetName + ':' + category;
      eventHandlers[name] = eventHandlers[name] || [];
      eventHandlers[name].push(handler);
    };

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // this.dispatchCallbacks()
    this.dispatchCallbacks = function(category) {
      arguments.callee.check('dispatchCallbacks', arguments, 'S');
      var name = widgetName + ':' + category;
      for (var i = 0; i < eventHandlers[name].length; i++) {
        currentHandler = eventHandlers[name][i];
        dispatchEvent();
      }
    };
    var dispatchEvent = createEventDispatcher(widgetName);

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // this.removeCallbacks()
    this.removeCallbacks = function(category) {
      arguments.callee.check('removeCallbacks', arguments, 'S');
      eventHandlers[widgetName + ':' + category] = [];
    };

    return this;
  }
})();
<commit_msg>Stop expecting properties of a potentially undefined argument.<commit_after>bt = bt || {};

bt.Widget = (function() {
  var widgets = {}, eventHandlers = {}, dispatchEvent, currentHandler;

  // Workaround for Firefox Bug 574941 -- should work in all UAs:
  var NativeError = Error;
  Error = function(settings) {
    arguments.callee.check('Error', arguments, 'Os', 0);
    var e = (this instanceof Error) ? this : new Error(arguments);
    if ('object' === typeof settings && 'string' === typeof settings[0]) {
      e.message = settings[0];
    }
    if ('string' === typeof settings) { e.message = settings; }
    else if ('object' === typeof settings) _.extend(e, settings);
    e.toString = e.toString || function() {
      return settings.name + ': ' + settings.message;
    };
    throw e;
    return;
  }
  Error.prototype = new NativeError();

  // Set up event-based callbacks.
  var createEventDispatcher = function(name) {
    var eventName = name + '_Events';
    if (document.addEventListener) {
      document.addEventListener(eventName, function() {
        currentHandler.apply(
          currentHandler.persona || currentHandler,
          currentHandler.args);
      }, false);
      dispatchEvent = function() {
        var widgetEvent = document.createEvent("UIEvents");
        widgetEvent.initEvent(eventName, false, false);
        document.dispatchEvent(widgetEvent);
      };
    }
    else { // MSIE
      document.documentElement[eventName] = 0;
      document.documentElement.attachEvent("onpropertychange", function(event) {
        if (eventName === event.propertyName) {
          currentHandler.apply(
            currentHandler.persona || currentHandler,
            currentHandler.args || []);
        }
      });
      dispatchEvent = function(handler) {
        document.documentElement[eventName]++;
      };
    }
    return dispatchEvent;
  };

  var createError = function(settings) {
    var e = _.clone(settings);
    e.prototype = new Error;
    return e;
  };

  return function(widgetName) {
    arguments.callee.check('Widget', arguments, 'S');

    widgetName = widgetName.replace(/\W/g, '_');

    // Check for error conditions.
    if(!(this instanceof bt.Widget)) {
      throw new createError({
        name: 'InvocationError',
        message: 'Widget constructor must create a new instance.'
      });
    }
    if (undefined !== widgets[widgetName]) {
      throw new createError({
        name: 'IdentityTheftError',
        message: sprintf('A Widget named "%s" already exists.', widgetName)
      });
    }

    widgets[widgetName] = this;

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // this.addCallback()
    this.addCallback = function(category, handler) {
      arguments.callee.check('addCallback', arguments, 'SF');
      var name = widgetName + ':' + category;
      eventHandlers[name] = eventHandlers[name] || [];
      eventHandlers[name].push(handler);
    };

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // this.dispatchCallbacks()
    this.dispatchCallbacks = function(category) {
      arguments.callee.check('dispatchCallbacks', arguments, 'S');
      var name = widgetName + ':' + category;
      for (var i = 0; i < eventHandlers[name].length; i++) {
        currentHandler = eventHandlers[name][i];
        dispatchEvent();
      }
    };
    var dispatchEvent = createEventDispatcher(widgetName);

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // this.removeCallbacks()
    this.removeCallbacks = function(category) {
      arguments.callee.check('removeCallbacks', arguments, 'S');
      eventHandlers[widgetName + ':' + category] = [];
    };

    return this;
  }
})();
<|endoftext|>


<commit_before>Vex.Flow.StemmableNote = (function(){
  var StemmableNote = function(note_struct) {
    if (arguments.length > 0) this.init(note_struct);
  };

  // Stem directions
  var Stem = Vex.Flow.Stem;

  Vex.Inherit(StemmableNote, Vex.Flow.Note, {
    init: function(note_struct){
      StemmableNote.superclass.init.call(this, note_struct);

      this.beam = null;
      this.stem_extension = 0;
      this.stem_direction = 1;
    },

    getStemLength: function() {
      return Stem.HEIGHT + this.stem_extension;
    },

    // Determine minimum length of stem
    getStemMinumumLength: function() {
      var length = this.duration == "w" ? 0 : 20;
      // if note is flagged, cannot shorten beam
      switch (this.duration) {
       case "8":
         if (this.beam == null) length = 35;
         break;
       case "16":
         if (this.beam == null)
           length = 35;
         else
           length = 25;
         break;
       case "32":
         if (this.beam == null)
           length = 45;
         else
           length = 35;
         break;
       case "64":
         if (this.beam == null)
           length = 50;
         else
           length = 40;
         break;
       case "128":
         if (this.beam == null)
           length = 55;
         else
           length = 45;
      }
      return length;
    },

    getStemDirection: function() {
      return this.stem_direction;
    },

    setStemDirection: function(direction) {
      if (!direction) direction = Stem.UP;
      if (direction != Stem.UP &&
          direction != Stem.DOWN) {
        throw new Vex.RERR("BadArgument", "Invalid stem direction: " + direction);
      }

      this.stem_direction = direction;
      this.beam = null;
      if (this.preFormatted) {
        this.preFormat();
      }
      return this;
    },

    getStemX: function() {
      var x_begin = this.getAbsoluteX() + this.x_shift;
      var x_end = this.getAbsoluteX() + this.x_shift + this.glyph.head_width;

      var stem_x = this.stem_direction == Stem.DOWN ?
        x_begin : x_end;

      stem_x -= ((Stem.WIDTH / 2) * this.stem_direction);

      return stem_x;
    },

    // Manuallly set note stem length
    setStemLength: function(height) {
      this.stem_extension = (height - Stem.HEIGHT);
      return this;
    },

    getStemExtents: function() {
      if (!this.ys || this.ys.length === 0) throw new Vex.RERR("NoYValues",
          "Can't get top stem Y when note has no Y values.");

      var top_pixel = this.ys[0];
      var base_pixel = this.ys[0];
      var stem_height = Stem.HEIGHT + this.stem_extension;

      for (var i = 0; i < this.ys.length; ++i) {
        var stem_top = this.ys[i] + (stem_height * -this.stem_direction);

        if (this.stem_direction == Stem.DOWN) {
          top_pixel = (top_pixel > stem_top) ? top_pixel : stem_top;
          base_pixel = (base_pixel < this.ys[i]) ? base_pixel : this.ys[i];
        } else {
          top_pixel = (top_pixel < stem_top) ? top_pixel : stem_top;
          base_pixel = (base_pixel > this.ys[i]) ? base_pixel : this.ys[i];
        }

        if(this.noteType == "s" || this.noteType == 'x') {
          top_pixel -= this.stem_direction * 7;
          base_pixel -= this.stem_direction * 7;
        }
      }

      return { topY: top_pixel, baseY: base_pixel };
    },

    setBeam: function(beam) {
      this.beam = beam;
      return this;
    },

    drawStem: function(stem_struct){
      if (!this.context) throw new Vex.RERR("NoCanvasContext",
          "Can't draw without a canvas context.");

      this.stem = new Stem(stem_struct);
      this.stem.setContext(this.context).draw();
    }

  });

  return StemmableNote;
}());<commit_msg>Set StemmableNote stem_direction on init<commit_after>Vex.Flow.StemmableNote = (function(){
  var StemmableNote = function(note_struct) {
    if (arguments.length > 0) this.init(note_struct);
  };

  // Stem directions
  var Stem = Vex.Flow.Stem;

  Vex.Inherit(StemmableNote, Vex.Flow.Note, {
    init: function(note_struct){
      StemmableNote.superclass.init.call(this, note_struct);

      this.beam = null;
      this.stem_extension = 0;
      this.setStemDirection(note_struct.stem_direction);
    },

    getStemLength: function() {
      return Stem.HEIGHT + this.stem_extension;
    },

    // Determine minimum length of stem
    getStemMinumumLength: function() {
      var length = this.duration == "w" ? 0 : 20;
      // if note is flagged, cannot shorten beam
      switch (this.duration) {
       case "8":
         if (this.beam == null) length = 35;
         break;
       case "16":
         if (this.beam == null)
           length = 35;
         else
           length = 25;
         break;
       case "32":
         if (this.beam == null)
           length = 45;
         else
           length = 35;
         break;
       case "64":
         if (this.beam == null)
           length = 50;
         else
           length = 40;
         break;
       case "128":
         if (this.beam == null)
           length = 55;
         else
           length = 45;
      }
      return length;
    },

    getStemDirection: function() {
      return this.stem_direction;
    },

    setStemDirection: function(direction) {
      if (!direction) direction = Stem.UP;
      if (direction != Stem.UP &&
          direction != Stem.DOWN) {
        throw new Vex.RERR("BadArgument", "Invalid stem direction: " + direction);
      }

      this.stem_direction = direction;
      this.beam = null;
      if (this.preFormatted) {
        this.preFormat();
      }
      return this;
    },

    getStemX: function() {
      var x_begin = this.getAbsoluteX() + this.x_shift;
      var x_end = this.getAbsoluteX() + this.x_shift + this.glyph.head_width;

      var stem_x = this.stem_direction == Stem.DOWN ?
        x_begin : x_end;

      stem_x -= ((Stem.WIDTH / 2) * this.stem_direction);

      return stem_x;
    },

    // Manuallly set note stem length
    setStemLength: function(height) {
      this.stem_extension = (height - Stem.HEIGHT);
      return this;
    },

    getStemExtents: function() {
      if (!this.ys || this.ys.length === 0) throw new Vex.RERR("NoYValues",
          "Can't get top stem Y when note has no Y values.");

      var top_pixel = this.ys[0];
      var base_pixel = this.ys[0];
      var stem_height = Stem.HEIGHT + this.stem_extension;

      for (var i = 0; i < this.ys.length; ++i) {
        var stem_top = this.ys[i] + (stem_height * -this.stem_direction);

        if (this.stem_direction == Stem.DOWN) {
          top_pixel = (top_pixel > stem_top) ? top_pixel : stem_top;
          base_pixel = (base_pixel < this.ys[i]) ? base_pixel : this.ys[i];
        } else {
          top_pixel = (top_pixel < stem_top) ? top_pixel : stem_top;
          base_pixel = (base_pixel > this.ys[i]) ? base_pixel : this.ys[i];
        }

        if(this.noteType == "s" || this.noteType == 'x') {
          top_pixel -= this.stem_direction * 7;
          base_pixel -= this.stem_direction * 7;
        }
      }

      return { topY: top_pixel, baseY: base_pixel };
    },

    setBeam: function(beam) {
      this.beam = beam;
      return this;
    },

    drawStem: function(stem_struct){
      if (!this.context) throw new Vex.RERR("NoCanvasContext",
          "Can't draw without a canvas context.");

      this.stem = new Stem(stem_struct);
      this.stem.setContext(this.context).draw();
    }

  });

  return StemmableNote;
}());<|endoftext|>


<commit_before>/**
 * @file String related streams
 * @since 0.1.9
 */
/*#ifndef(UMD)*/
"use strict";
/*global _gpfDefine*/ // Shortcut for gpf.define
/*global _gpfStreamSecureInstallProgressFlag*/ // Install the progress flag used by _gpfStreamSecureRead and Write
/*global _gpfStreamSecureRead*/ // Generate a wrapper to secure multiple calls to stream#read
/*global _gpfStreamSecureWrite*/ // Generates a wrapper to secure multiple calls to stream#write
/*#endif*/

var
    _gpfStreamReadableString = _gpfDefine(/** @lends gpf.node.ReadableString */ {
        $class: "gpf.stream.ReadableString",

        /**
         * Wraps a string inside a readable stream
         *
         * @constructor gpf.node.ReadableString
         * @implements {gpf.interfaces.IReadableStream}
         * @param {String} buffer String buffer
         * @since 0.1.9
         */
        constructor: function (buffer) {
            this._buffer = buffer;
        },

        //region gpf.interfaces.IReadableStream

        /**
         * @gpf:sameas gpf.interfaces.IReadableStream#read
         * @since 0.1.9
         */
        read: _gpfStreamSecureRead(function (output) {
            return output.write(this._buffer); //eslint-disable-line no-invalid-this
        }),

        //endregion

        /**
         * Buffer
         * @since 0.1.9
         */
        _buffer: ""

    }),

    /**
     * @since 0.1.9
     */
    _gpfStreamWritableString = _gpfDefine(/** @lends gpf.node.WritableString */ {
        $class: "gpf.stream.WritableString",

        /**
         * Creates a writable stream that can be converted to string
         *
         * @constructor gpf.node.WritableString
         * @implements {gpf.interfaces.IWritableStream}
         * @since 0.1.9
         */
        constructor: function () {
            this._buffer = [];
        },

        //region gpf.interfaces.IReadableStream

        /**
         * @gpf:sameas gpf.interfaces.IWritableStream#write
         * @since 0.1.9
         */
        write: _gpfStreamSecureWrite(function (buffer) {
            this._buffer.push(buffer.toString()); //eslint-disable-line no-invalid-this
            return Promise.resolve();
        }),

        //endregion

        toString: function () {
            return this._buffer.join("");
        },

        /**
         * Buffer
         *
         * @type {String[]}
         * @since 0.1.9
         */
        _buffer: []

    });

_gpfStreamSecureInstallProgressFlag(_gpfStreamReadableString);
_gpfStreamSecureInstallProgressFlag(_gpfStreamWritableString);
<commit_msg>Simplify class access<commit_after>/**
 * @file String related streams
 * @since 0.1.9
 */
/*#ifndef(UMD)*/
"use strict";
/*global _gpfDefine*/ // Shortcut for gpf.define
/*global _gpfStreamSecureInstallProgressFlag*/ // Install the progress flag used by _gpfStreamSecureRead and Write
/*global _gpfStreamSecureRead*/ // Generate a wrapper to secure multiple calls to stream#read
/*global _gpfStreamSecureWrite*/ // Generates a wrapper to secure multiple calls to stream#write
/*exported _GpfStreamReadableString*/ // gpf.stream.ReadableString
/*exported _GpfStreamWritableString*/ // gpf.stream.WritableString
/*#endif*/

var
    _GpfStreamReadableString = _gpfDefine(/** @lends gpf.node.ReadableString */ {
        $class: "gpf.stream.ReadableString",

        /**
         * Wraps a string inside a readable stream
         *
         * @constructor gpf.node.ReadableString
         * @implements {gpf.interfaces.IReadableStream}
         * @param {String} buffer String buffer
         * @since 0.1.9
         */
        constructor: function (buffer) {
            this._buffer = buffer;
        },

        //region gpf.interfaces.IReadableStream

        /**
         * @gpf:sameas gpf.interfaces.IReadableStream#read
         * @since 0.1.9
         */
        read: _gpfStreamSecureRead(function (output) {
            return output.write(this._buffer); //eslint-disable-line no-invalid-this
        }),

        //endregion

        /**
         * Buffer
         * @since 0.1.9
         */
        _buffer: ""

    }),

    /**
     * @since 0.1.9
     */
    _GpfStreamWritableString = _gpfDefine(/** @lends gpf.node.WritableString */ {
        $class: "gpf.stream.WritableString",

        /**
         * Creates a writable stream that can be converted to string
         *
         * @constructor gpf.node.WritableString
         * @implements {gpf.interfaces.IWritableStream}
         * @since 0.1.9
         */
        constructor: function () {
            this._buffer = [];
        },

        //region gpf.interfaces.IReadableStream

        /**
         * @gpf:sameas gpf.interfaces.IWritableStream#write
         * @since 0.1.9
         */
        write: _gpfStreamSecureWrite(function (buffer) {
            this._buffer.push(buffer.toString()); //eslint-disable-line no-invalid-this
            return Promise.resolve();
        }),

        //endregion

        toString: function () {
            return this._buffer.join("");
        },

        /**
         * Buffer
         *
         * @type {String[]}
         * @since 0.1.9
         */
        _buffer: []

    });

_gpfStreamSecureInstallProgressFlag(_GpfStreamReadableString);
_gpfStreamSecureInstallProgressFlag(_GpfStreamWritableString);
<|endoftext|>