<commit_before>'use strict';

var aFrom          = require('es5-ext/array/from')
  , compact        = require('es5-ext/array/#/compact')
  , isCopy         = require('es5-ext/array/#/is-copy')
  , copy           = require('es5-ext/object/copy')
  , assign         = require('es5-ext/object/assign')
  , isObject       = require('es5-ext/object/is-object')
  , callable       = require('es5-ext/object/valid-callable')
  , toArray        = require('es5-ext/array/to-array')
  , d              = require('d')
  , memoize        = require('memoizee/plain')
  , memoizeMethods = require('memoizee/methods-plain')
  , getNormalizer  = require('memoizee/normalizers/get-1')
  , makeEl         = require('dom-ext/document/#/make-element')
  , append         = require('dom-ext/element/#/append')
  , clear          = require('dom-ext/element/#/clear')
  , remove         = require('dom-ext/element/#/remove')
  , replaceCont    = require('dom-ext/element/#/replace-content')
  , dispatchEvnt   = require('dom-ext/html-element/#/dispatch-event-2')
  , DOMInput       = require('../_controls/input')
  , eventOpts      = require('../_event-options')
  , setup          = require('../')

  , isArray = Array.isArray, map = Array.prototype.map
  , defineProperty = Object.defineProperty
  , defineProperties = Object.defineProperties
  , getName = Object.getOwnPropertyDescriptor(DOMInput.prototype, 'name').get
  , Input, render, renderItem, getTempForm, getForceReset;

getForceReset = memoize(function (document) {
	var form = document.createElement('form');
	return function (input) {
		var parent = input.parentNode, nextSibling = input.nextSibling;
		form.appendChild(input);
		form.reset();
		parent.insertBefore(input, nextSibling);
	};
}, { normalizer: getNormalizer() });

getTempForm = memoize(function (document) {
	var form = document.createElement('form');
	form.setAttribute('method', 'post');
	form.setAttribute('enctype', 'multipart/form-data');
	form.setAttribute('style', 'display: none');
	return form;
}, { normalizer: getNormalizer() });

render = function (options) {
	var el = this.make;
	return el('div', { class: 'dbjs-file' },
		this.valueDOM = this.multiple ? el('ul') : el('span'),
		el('label', { class: 'dbjs-file-input' }, options.label,
			this.control = el('input', { type: 'file' })));
};

renderItem = function (file) {
	var el = this.make, data = {};
	data.dom = el(this.multiple ? 'li' : 'span', { 'data-id': file.__id__ });
	append.call(data.dom,
		el('a', { href: file._url, target: '_blank' }, file._name), " ",
		data.control = el('input', { type: 'hidden', name: this.name,
			value: file.__id__ }),
		el('a', { class: 'clear', onclick: this.removeItem.bind(this, data.dom) },
			"x"));
	return data;
};

Input = function (document, type/*, options*/) {
	var options = arguments[2], action;
	this.make = makeEl.bind(document);
	this.controls = [];
	this.type = type;
	options = this._resolveOptions(options);
	if (options.multiple) this.multiple = true;
	((options.render == null) || callable(options.render));
	defineProperty(this, 'renderItem', d((options.renderItem == null)
		? renderItem : callable(options.renderItem)));
	DOMInput.call(this, document, type, options);
	if (this.multiple) this.control.setAttribute('multiple', 'multiple');
	this.control.setAttribute('accept', toArray(type.accept).join(','));

	if (options.autoSubmit != null) {
		action = options.autoSubmit;
		this.on('change', function () {
			var form, parent, sibling;
			if (!this.changed) return;
			form = getTempForm(document);
			parent = this.dom.parentNode;
			sibling = this.dom.nextSibling;
			form.setAttribute('action', action);
			document.body.appendChild(form);
			form.appendChild(this.dom);
			dispatchEvnt.call(form, 'submit');
			parent.insertBefore(this.dom, sibling);
			if (form.parentNode) form.parentNode.removeChild(form);
		});
	}
};

Input.prototype = Object.create(DOMInput.prototype, assign({
	constructor: d(Input),
	multiple: d(false),
	_value: d(null),
	controlAttributes: d(assign(copy(DOMInput.prototype.controlAttributes),
		{ required: true })),
	dbAttributes: d(assign(copy(DOMInput.prototype.dbAttributes),
		{ required: true })),
	_render: d(function (options) {
		this.dom = (options.render || render).call(this, options);
		this.controls.push(this.control);
	}),
	name: d.gs(getName, function (name) {
		this._name = name;
		name = this.name;
		this.controls.forEach(function (input) { input.name = name; });
	}),
	inputValue: d.gs(function () {
		var value;
		if (!this.multiple) {
			if (this.control.files[0]) return this.control.files[0];
			if (!this.valueDOM.firstElementChild) return null;
			return this.valueDOM.firstElementChild.getAttribute('data-id');
		}
		value = map.call(this.valueDOM.childNodes, function (node) {
			var id = node.getAttribute('data-id');
			if (!id) {
				throw new TypeError("Missing id (data-id attribute) on file item");
			}
			return id;
		}).concat(aFrom(this.control.files));
		return value.length ? value : null;
	}, function (nu) {
		var old = this.inputValue, changed;
		this._value = nu;
		if (this.multiple) {
			if (nu) {
				if (!old || !isCopy.call(nu, old)) {
					this.control.value = null;
					if (this.control.files && this.control.files.length) {
						// In Opera control is not reset properly, force it with hack
						getForceReset(this.document)(this.control);
					}
					replaceCont.call(this.valueDOM, nu.map(this._renderItem));
					if (this._required) this.castControlAttribute('required', false);
					changed = true;
				}
			} else {
				clear.call(this.valueDOM);
				if (this._required) this.castControlAttribute('required', true);
			}
		} else if (nu !== old) {
			this.control.value = null;
			if (nu) {
				replaceCont.call(this.valueDOM, this._renderItem(nu));
				if (this._required) this.castControlAttribute('required', false);
				this.dom.classList.add('filled');
			} else {
				clear.call(this.valueDOM);
				if (this._required) this.castControlAttribute('required', true);
				this.dom.classList.remove('filled');
			}
			changed = true;
		}
		if (changed) {
			try {
				dispatchEvnt.call(this.control, 'change', eventOpts);
			} catch (ignore) {}
		} else {
			this.onChange();
		}
	}),
	value: d.gs(function () {
		var value = this.inputValue;
		if (value == null) return null;
		if (this.multiple) return value.map(this.type.toInputValue, this.type);
		return this.type.toInputValue(value);
	}, function (value) {
		if (value == null) {
			value = null;
		} else if (this.multiple) {
			value = toArray(value);
			if (value.length) {
				value = compact.call(value.map(this.type.toInputValue, this.type));
			}
			if (!value.length) value = null;
		} else {
			value = this.type.toInputValue(value);
		}

		this.inputValue = value;
	}),
	onChange: d(function () {
		var value, changed, valid, emitChanged, emitValid;
		value = this.inputValue;
		changed = (this.multiple && (this._value != null) && (value != null))
			? isCopy.call(value, this._value) : (value !== this._value);
		valid = this.required ? (value != null) : true;

		if (this.changed !== changed) {
			this.changed = changed;
			emitChanged = true;
		}
		if (this.valid !== valid) {
			this.valid = valid;
			emitValid = true;
		}

		this.emit('change', value);
		if (emitChanged) this.emit('change:changed', this.changed);
		if (emitValid) this.emit('change:valid', this.valid);
	}),
	removeItem: d(function (dom) {
		remove.call(dom);
		if (!this.multiple) this.dom.classList.remove('filled');
		dispatchEvnt.call(this.control, 'change', eventOpts);
	})
}, memoizeMethods({
	_renderItem: d(function (file) {
		var data;
		file = this.type.getById(file);
		data = this.renderItem(file);
		this.controls.push(data.control);
		return data.dom;
	})
})));

module.exports = memoize(function (db) {
	defineProperties(setup(db).File, {
		fromInputValue: d(function (value) {
			if (value == null) return null;
			if (isArray(value) && (value.length === 2)) {
				if (typeof value[0] === 'string') {
					if (isObject(value[1])) return value[1];
				} else if (typeof value[1] === 'string') {
					if (isObject(value[0])) return value[0];
				}
				return value;
			}
			if (isObject(value)) return value;
			value = value.trim();
			if (!value) return null;
			return this.getById(value);
		}),
		DOMInput: d(Input),
		toDOMInput: d(function (document/*, options*/) {
			var options = Object(arguments[1]);
			if (options.multiple || (options.type !== 'checkbox')) {
				return new this.DOMInput(document, this, options);
			}
			return db.Object.toDOMInput(document, options);
		})
	});
}, { normalizers: getNormalizer() });

exports.Input = Input;
<commit_msg>Fix typo<commit_after>'use strict';

var aFrom          = require('es5-ext/array/from')
  , compact        = require('es5-ext/array/#/compact')
  , isCopy         = require('es5-ext/array/#/is-copy')
  , copy           = require('es5-ext/object/copy')
  , assign         = require('es5-ext/object/assign')
  , isObject       = require('es5-ext/object/is-object')
  , callable       = require('es5-ext/object/valid-callable')
  , toArray        = require('es5-ext/array/to-array')
  , d              = require('d')
  , memoize        = require('memoizee/plain')
  , memoizeMethods = require('memoizee/methods-plain')
  , getNormalizer  = require('memoizee/normalizers/get-1')
  , makeEl         = require('dom-ext/document/#/make-element')
  , append         = require('dom-ext/element/#/append')
  , clear          = require('dom-ext/element/#/clear')
  , remove         = require('dom-ext/element/#/remove')
  , replaceCont    = require('dom-ext/element/#/replace-content')
  , dispatchEvnt   = require('dom-ext/html-element/#/dispatch-event-2')
  , DOMInput       = require('../_controls/input')
  , eventOpts      = require('../_event-options')
  , setup          = require('../')

  , isArray = Array.isArray, map = Array.prototype.map
  , defineProperty = Object.defineProperty
  , defineProperties = Object.defineProperties
  , getName = Object.getOwnPropertyDescriptor(DOMInput.prototype, 'name').get
  , Input, render, renderItem, getTempForm, getForceReset;

getForceReset = memoize(function (document) {
	var form = document.createElement('form');
	return function (input) {
		var parent = input.parentNode, nextSibling = input.nextSibling;
		form.appendChild(input);
		form.reset();
		parent.insertBefore(input, nextSibling);
	};
}, { normalizer: getNormalizer() });

getTempForm = memoize(function (document) {
	var form = document.createElement('form');
	form.setAttribute('method', 'post');
	form.setAttribute('enctype', 'multipart/form-data');
	form.setAttribute('style', 'display: none');
	return form;
}, { normalizer: getNormalizer() });

render = function (options) {
	var el = this.make;
	return el('div', { class: 'dbjs-file' },
		this.valueDOM = this.multiple ? el('ul') : el('span'),
		el('label', { class: 'dbjs-file-input' }, options.label,
			this.control = el('input', { type: 'file' })));
};

renderItem = function (file) {
	var el = this.make, data = {};
	data.dom = el(this.multiple ? 'li' : 'span', { 'data-id': file.__id__ });
	append.call(data.dom,
		el('a', { href: file._url, target: '_blank' }, file._name), " ",
		data.control = el('input', { type: 'hidden', name: this.name,
			value: file.__id__ }),
		el('a', { class: 'clear', onclick: this.removeItem.bind(this, data.dom) },
			"x"));
	return data;
};

Input = function (document, type/*, options*/) {
	var options = arguments[2], action;
	this.make = makeEl.bind(document);
	this.controls = [];
	this.type = type;
	options = this._resolveOptions(options);
	if (options.multiple) this.multiple = true;
	((options.render == null) || callable(options.render));
	defineProperty(this, 'renderItem', d((options.renderItem == null)
		? renderItem : callable(options.renderItem)));
	DOMInput.call(this, document, type, options);
	if (this.multiple) this.control.setAttribute('multiple', 'multiple');
	this.control.setAttribute('accept', toArray(type.accept).join(','));

	if (options.autoSubmit != null) {
		action = options.autoSubmit;
		this.on('change', function () {
			var form, parent, sibling;
			if (!this.changed) return;
			form = getTempForm(document);
			parent = this.dom.parentNode;
			sibling = this.dom.nextSibling;
			form.setAttribute('action', action);
			document.body.appendChild(form);
			form.appendChild(this.dom);
			dispatchEvnt.call(form, 'submit');
			parent.insertBefore(this.dom, sibling);
			if (form.parentNode) form.parentNode.removeChild(form);
		});
	}
};

Input.prototype = Object.create(DOMInput.prototype, assign({
	constructor: d(Input),
	multiple: d(false),
	_value: d(null),
	controlAttributes: d(assign(copy(DOMInput.prototype.controlAttributes),
		{ required: true })),
	dbAttributes: d(assign(copy(DOMInput.prototype.dbAttributes),
		{ required: true })),
	_render: d(function (options) {
		this.dom = (options.render || render).call(this, options);
		this.controls.push(this.control);
	}),
	name: d.gs(getName, function (name) {
		this._name = name;
		name = this.name;
		this.controls.forEach(function (input) { input.name = name; });
	}),
	inputValue: d.gs(function () {
		var value;
		if (!this.multiple) {
			if (this.control.files[0]) return this.control.files[0];
			if (!this.valueDOM.firstElementChild) return null;
			return this.valueDOM.firstElementChild.getAttribute('data-id');
		}
		value = map.call(this.valueDOM.childNodes, function (node) {
			var id = node.getAttribute('data-id');
			if (!id) {
				throw new TypeError("Missing id (data-id attribute) on file item");
			}
			return id;
		}).concat(aFrom(this.control.files));
		return value.length ? value : null;
	}, function (nu) {
		var old = this.inputValue, changed;
		this._value = nu;
		if (this.multiple) {
			if (nu) {
				if (!old || !isCopy.call(nu, old)) {
					this.control.value = null;
					if (this.control.files && this.control.files.length) {
						// In Opera control is not reset properly, force it with hack
						getForceReset(this.document)(this.control);
					}
					replaceCont.call(this.valueDOM, nu.map(this._renderItem));
					if (this._required) this.castControlAttribute('required', false);
					changed = true;
				}
			} else {
				clear.call(this.valueDOM);
				if (this._required) this.castControlAttribute('required', true);
			}
		} else if (nu !== old) {
			this.control.value = null;
			if (nu) {
				replaceCont.call(this.valueDOM, this._renderItem(nu));
				if (this._required) this.castControlAttribute('required', false);
				this.dom.classList.add('filled');
			} else {
				clear.call(this.valueDOM);
				if (this._required) this.castControlAttribute('required', true);
				this.dom.classList.remove('filled');
			}
			changed = true;
		}
		if (changed) {
			try {
				dispatchEvnt.call(this.control, 'change', eventOpts);
			} catch (ignore) {}
		} else {
			this.onChange();
		}
	}),
	value: d.gs(function () {
		var value = this.inputValue;
		if (value == null) return null;
		if (this.multiple) return value.map(this.type.toInputValue, this.type);
		return this.type.toInputValue(value);
	}, function (value) {
		if (value == null) {
			value = null;
		} else if (this.multiple) {
			value = toArray(value);
			if (value.length) {
				value = compact.call(value.map(this.type.toInputValue, this.type));
			}
			if (!value.length) value = null;
		} else {
			value = this.type.toInputValue(value);
		}

		this.inputValue = value;
	}),
	onChange: d(function () {
		var value, changed, valid, emitChanged, emitValid;
		value = this.inputValue;
		changed = (this.multiple && (this._value != null) && (value != null))
			? isCopy.call(value, this._value) : (value !== this._value);
		valid = this.required ? (value != null) : true;

		if (this.changed !== changed) {
			this.changed = changed;
			emitChanged = true;
		}
		if (this.valid !== valid) {
			this.valid = valid;
			emitValid = true;
		}

		this.emit('change', value);
		if (emitChanged) this.emit('change:changed', this.changed);
		if (emitValid) this.emit('change:valid', this.valid);
	}),
	removeItem: d(function (dom) {
		remove.call(dom);
		if (!this.multiple) this.dom.classList.remove('filled');
		dispatchEvnt.call(this.control, 'change', eventOpts);
	})
}, memoizeMethods({
	_renderItem: d(function (file) {
		var data;
		file = this.type.getById(file);
		data = this.renderItem(file);
		this.controls.push(data.control);
		return data.dom;
	})
})));

module.exports = memoize(function (db) {
	defineProperties(setup(db).File, {
		fromInputValue: d(function (value) {
			if (value == null) return null;
			if (isArray(value) && (value.length === 2)) {
				if (typeof value[0] === 'string') {
					if (isObject(value[1])) return value[1];
				} else if (typeof value[1] === 'string') {
					if (isObject(value[0])) return value[0];
				}
				return value;
			}
			if (isObject(value)) return value;
			value = value.trim();
			if (!value) return null;
			return this.getById(value);
		}),
		DOMInput: d(Input),
		toDOMInput: d(function (document/*, options*/) {
			var options = Object(arguments[1]);
			if (options.multiple || (options.type !== 'checkbox')) {
				return new this.DOMInput(document, this, options);
			}
			return db.Object.toDOMInput(document, options);
		})
	});
}, { normalizer: getNormalizer() });

exports.Input = Input;
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import deepEqual from 'deep-equal';
import {FormUnit} from './form-unit';
import {find} from '../helpers';
import {Input} from '../inputs';
import crypto from 'crypto';

const deepClone = o => JSON.parse(JSON.stringify(o));
const isOptional = ({optional}, current) => typeof optional === 'function' ? optional({current}) : optional;
const isPromise = promise => promise && typeof promise.then === 'function';
const newId = () => crypto.randomBytes(16).toString('base64');
const noop = () => undefined;

const newFormState = (fields, ids, cb) => {
  const state = {initial: {}, current: {}, ids, submitting: false, errors: {}};

  for (const name in fields) {
    const props = fields[name];
    if (!props) continue;

    const {initialValue, currentValue} = cb({...props, name});
    state.initial[name] = initialValue;
    state.current[name] = currentValue;
    state.ids[name] = ids[name] || newId();
  }

  return state;
};

const newInitialValue = initialValue =>
  initialValue === null || initialValue === undefined ? '' : initialValue;

export class Form extends React.Component {
  static propTypes = {
    afterSubmit: PropTypes.func,
    fields: PropTypes.object,
    onModified: PropTypes.func,
    onSubmit: PropTypes.func,
    onSubmitError: PropTypes.func,
    resetOnSubmit: PropTypes.bool
  };

  static defaultProps = {
    children: noop,
    fields: {},
    onModified: noop,
    onSubmit: noop,
    onSubmitError: () => ({}),
    afterSubmit: noop
  };

  constructor(props) {
    super(props);
    this.state = newFormState(props.fields, {}, ({initialValue}) => {
      initialValue = newInitialValue(initialValue);
      return {initialValue, currentValue: deepClone(initialValue)};
    });
  }

  componentDidMount() {
    require('../../css/forms');
  }

  shouldComponentUpdate({fields}, nextState) {
    const isStateChange = nextState !== this.state;
    const {current, initial} = nextState;
    const {initial: newInitial, ids, current: newCurrent} = newFormState(fields, nextState.ids,
      ({name, initialValue}) => {
        initialValue = newInitialValue(initialValue);
        return {
          initialValue: initialValue,
          currentValue: current.hasOwnProperty(name)
            ? current[name] === this.state.initial[name] ? deepClone(initialValue) : current[name]
            : deepClone(initialValue)
        };
      });
    nextState.initial = isStateChange ? initial : newInitial;
    nextState.current = newCurrent;
    nextState.ids = ids;
    return true;
  }

  componentWillUnmount() {
    this.props.onModified(false);
  }

  onChangeCheckbox = (name, cb = noop) => val => {
    if (typeof val.persist === 'function') val.persist();
    this.setValues({[name]: !this.state.current[name]}, () => cb(val));
  };

  onChange = (name, validator, cb = noop) => val => {
    const {initial} = this.state;
    const {onModified} = this.props;
    const value = val.target && 'value' in val.target ? val.target.value : val;
    const nextState = {current: {...this.state.current, [name]: value}};
    const error = validator && validator(value);
    if (!error) {
      nextState.errors = {...this.state.errors};
      delete nextState.errors[name];
    }
    if (typeof val.persist === 'function') val.persist();
    this.setState(nextState, () => cb(val));
    onModified(!deepEqual(initial, nextState.current));
  };

  onBlur = ({name, validator}) => ({target: {value}}) => {
    const error = validator(value);
    this.setState({errors: {...this.state.errors, [name]: error}});
  };

  canReset = () => !this.state.submitting && !deepEqual(this.state.initial, this.state.current);

  reset = () => {
    const {onModified} = this.props;
    const {initial} = this.state;
    onModified(false);
    this.setState({current: deepClone(initial), errors: {}});
  };

  canSubmit = ({checkRequiredFields} = {}) => {
    const {fields} = this.props;
    const {initial, current, submitting} = this.state;

    const isDiffFromInitial = find(Object.keys(initial), key => !deepEqual(initial[key], current[key]));
    const requiredFields = Object.keys(fields).filter(name => fields[name] && !isOptional(fields[name], current));
    const requiredFieldsHaveValue = requiredFields.every(name => current[name] || current[name] === 0);

    let passesValidators = true;
    for (const name in fields) {
      const props = fields[name];
      if (!props) continue;

      if (props.validator && props.validator(current[name])) {
        passesValidators = false;
        break;
      }
    }

    return !submitting
      && isDiffFromInitial
      && (checkRequiredFields
        ? checkRequiredFields(current)
        : requiredFieldsHaveValue)
      && passesValidators;
  };

  onSubmit = e => {
    e && e.preventDefault();
    const {onSubmit, onSubmitError, afterSubmit, onModified, resetOnSubmit} = this.props;
    const {initial, current} = this.state;
    this.setState({submitting: true});
    const nextState = {submitting: false};

    const onSuccess = response => {
      this.setState({
        ...nextState,
        current: resetOnSubmit ? deepClone(initial) : current,
        initial: resetOnSubmit ? initial : deepClone(current),
        errors: {}
      });
      const after = () => afterSubmit({state: this.state, response, reset: this.reset});
      const onModifiedPromise = onModified(false);
      return isPromise(onModifiedPromise) ? onModifiedPromise.then(after) : after();
    };

    const onError = e => {
      this.setState({...nextState, errors: (onSubmitError && onSubmitError(e)) || {}});
    };

    try {
      const afterSubmitPromise = onSubmit({initial, current});
      if (isPromise(afterSubmitPromise)) {
        return afterSubmitPromise.then(onSuccess).catch(onError);
      } else {
        return onSuccess(afterSubmitPromise);
      }
    } catch (e) {
      onError(e);
      throw e;
    }
  };

  setValues = (values, cb) => this.setState({current: {...this.state.current, ...values}}, cb);

  controlField = ({children = <Input type="text"/>, validator, name, ids}) => {
    const {canSubmit, canReset, reset, onSubmit, setValues, state, onChange, onBlur, onChangeCheckbox} = this;
    const {submitting} = state;

    const element = typeof children !== 'function'
      ? children
      : children({
        onChange: onChange(name, validator), canSubmit, canReset, reset, onSubmit, submitting, setValues, state
      });

    if (!element || React.Children.count(element) !== 1 || !name) return element;

    const props = {name: element.props.name || name};
    props.id = element.props.id || ids[props.name];

    const hasCurrentValue = state.current.hasOwnProperty(name);

    if (element.props.type === 'checkbox') {
      props.checked = !!(hasCurrentValue
        ? (state.current && state.current[name])
        : element.props.checked);
      props.onChange = onChangeCheckbox(name, element.props.onChange);
    } else {
      props.value = hasCurrentValue
        ? (state.current && state.current[name])
        : element.props.value;
      props.onChange = onChange(name, validator, element.props.onChange);
      if (validator) props.onBlur = onBlur({name, validator});
    }

    return React.cloneElement(element, props);
  };

  render() {
    // eslint-disable-next-line no-unused-vars
    const {className, children, fields, onModified, onSubmitError, afterSubmit, resetOnSubmit, ...others} = this.props;
    const {canSubmit, canReset, reset, onSubmit, setValues, state, onBlur} = this;
    const {current, submitting, ids} = state;

    const formUnits = {};
    for (const name in fields) {
      const props = fields[name];
      if (!props) continue;

      const error = state.errors[name];
      const children = this.controlField({...props, name, ids});
      const help = error || props.help;
      const labelFor = props.labelFor || children.props.id;
      // eslint-disable-next-line no-unused-vars
      const {className: _, ...rest} = props;

      formUnits[name] = (
        <FormUnit {...{
          ...rest, key: name, optional: isOptional(rest, current), setValues, state, name, hasError: !!error,
          help, labelFor, children
        }}/>
      );
    }

    return (
      <form {...{...others, className: classnames('form', className), onSubmit: this.onSubmit}}>
        <fieldset {...{disabled: submitting}}>
          {children({
            fields: formUnits, canSubmit, canReset, reset, onSubmit, setValues, state, onBlur, submitting
          })}
        </fieldset>
      </form>
    );
  }
}<commit_msg>Form: defer deepEqual comparison until we know onModified prop is set [#162335682]<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import deepEqual from 'deep-equal';
import {FormUnit} from './form-unit';
import {find} from '../helpers';
import {Input} from '../inputs';
import crypto from 'crypto';

const deepClone = o => JSON.parse(JSON.stringify(o));
const isOptional = ({optional}, current) => typeof optional === 'function' ? optional({current}) : optional;
const isPromise = promise => promise && typeof promise.then === 'function';
const newId = () => crypto.randomBytes(16).toString('base64');
const noop = () => undefined;

const newFormState = (fields, ids, cb) => {
  const state = {initial: {}, current: {}, ids, submitting: false, errors: {}};

  for (const name in fields) {
    const props = fields[name];
    if (!props) continue;

    const {initialValue, currentValue} = cb({...props, name});
    state.initial[name] = initialValue;
    state.current[name] = currentValue;
    state.ids[name] = ids[name] || newId();
  }

  return state;
};

const newInitialValue = initialValue =>
  initialValue === null || initialValue === undefined ? '' : initialValue;

export class Form extends React.Component {
  static propTypes = {
    afterSubmit: PropTypes.func,
    fields: PropTypes.object,
    onModified: PropTypes.func,
    onSubmit: PropTypes.func,
    onSubmitError: PropTypes.func,
    resetOnSubmit: PropTypes.bool
  };

  static defaultProps = {
    children: noop,
    fields: {},
    onSubmit: noop,
    onSubmitError: () => ({}),
    afterSubmit: noop
  };

  constructor(props) {
    super(props);
    this.state = newFormState(props.fields, {}, ({initialValue}) => {
      initialValue = newInitialValue(initialValue);
      return {initialValue, currentValue: deepClone(initialValue)};
    });
  }

  componentDidMount() {
    require('../../css/forms');
  }

  shouldComponentUpdate({fields}, nextState) {
    const isStateChange = nextState !== this.state;
    const {current, initial} = nextState;
    const {initial: newInitial, ids, current: newCurrent} = newFormState(fields, nextState.ids,
      ({name, initialValue}) => {
        initialValue = newInitialValue(initialValue);
        return {
          initialValue: initialValue,
          currentValue: current.hasOwnProperty(name)
            ? current[name] === this.state.initial[name] ? deepClone(initialValue) : current[name]
            : deepClone(initialValue)
        };
      });
    nextState.initial = isStateChange ? initial : newInitial;
    nextState.current = newCurrent;
    nextState.ids = ids;
    return true;
  }

  componentWillUnmount() {
    if (this.props.onModified) this.props.onModified(false);
  }

  onChangeCheckbox = (name, cb = noop) => val => {
    if (typeof val.persist === 'function') val.persist();
    this.setValues({[name]: !this.state.current[name]}, () => cb(val));
  };

  onChange = (name, validator, cb = noop) => val => {
    const {initial} = this.state;
    const value = val.target && 'value' in val.target ? val.target.value : val;
    const nextState = {current: {...this.state.current, [name]: value}};
    const error = validator && validator(value);
    if (!error) {
      nextState.errors = {...this.state.errors};
      delete nextState.errors[name];
    }
    if (typeof val.persist === 'function') val.persist();
    this.setState(nextState, () => cb(val));

    if (this.props.onModified) this.props.onModified(!deepEqual(initial, nextState.current));
  };

  onBlur = ({name, validator}) => ({target: {value}}) => {
    const error = validator(value);
    this.setState({errors: {...this.state.errors, [name]: error}});
  };

  canReset = () => !this.state.submitting && !deepEqual(this.state.initial, this.state.current);

  reset = () => {
    const {initial} = this.state;
    if (this.props.onModified) this.props.onModified(false);
    this.setState({current: deepClone(initial), errors: {}});
  };

  canSubmit = ({checkRequiredFields} = {}) => {
    const {fields} = this.props;
    const {initial, current, submitting} = this.state;

    const isDiffFromInitial = find(Object.keys(initial), key => !deepEqual(initial[key], current[key]));
    const requiredFields = Object.keys(fields).filter(name => fields[name] && !isOptional(fields[name], current));
    const requiredFieldsHaveValue = requiredFields.every(name => current[name] || current[name] === 0);

    let passesValidators = true;
    for (const name in fields) {
      const props = fields[name];
      if (!props) continue;

      if (props.validator && props.validator(current[name])) {
        passesValidators = false;
        break;
      }
    }

    return !submitting
      && isDiffFromInitial
      && (checkRequiredFields
        ? checkRequiredFields(current)
        : requiredFieldsHaveValue)
      && passesValidators;
  };

  onSubmit = e => {
    e && e.preventDefault();
    const {onSubmit, onSubmitError, afterSubmit, onModified, resetOnSubmit} = this.props;
    const {initial, current} = this.state;
    this.setState({submitting: true});
    const nextState = {submitting: false};

    const onSuccess = response => {
      this.setState({
        ...nextState,
        current: resetOnSubmit ? deepClone(initial) : current,
        initial: resetOnSubmit ? initial : deepClone(current),
        errors: {}
      });
      const after = () => afterSubmit({state: this.state, response, reset: this.reset});
      const onModifiedPromise = onModified && onModified(false);
      return isPromise(onModifiedPromise) ? onModifiedPromise.then(after) : after();
    };

    const onError = e => {
      this.setState({...nextState, errors: (onSubmitError && onSubmitError(e)) || {}});
    };

    try {
      const afterSubmitPromise = onSubmit({initial, current});
      if (isPromise(afterSubmitPromise)) {
        return afterSubmitPromise.then(onSuccess).catch(onError);
      } else {
        return onSuccess(afterSubmitPromise);
      }
    } catch (e) {
      onError(e);
      throw e;
    }
  };

  setValues = (values, cb) => this.setState({current: {...this.state.current, ...values}}, cb);

  controlField = ({children = <Input type="text"/>, validator, name, ids}) => {
    const {canSubmit, canReset, reset, onSubmit, setValues, state, onChange, onBlur, onChangeCheckbox} = this;
    const {submitting} = state;

    const element = typeof children !== 'function'
      ? children
      : children({
        onChange: onChange(name, validator), canSubmit, canReset, reset, onSubmit, submitting, setValues, state
      });

    if (!element || React.Children.count(element) !== 1 || !name) return element;

    const props = {name: element.props.name || name};
    props.id = element.props.id || ids[props.name];

    const hasCurrentValue = state.current.hasOwnProperty(name);

    if (element.props.type === 'checkbox') {
      props.checked = !!(hasCurrentValue
        ? (state.current && state.current[name])
        : element.props.checked);
      props.onChange = onChangeCheckbox(name, element.props.onChange);
    } else {
      props.value = hasCurrentValue
        ? (state.current && state.current[name])
        : element.props.value;
      props.onChange = onChange(name, validator, element.props.onChange);
      if (validator) props.onBlur = onBlur({name, validator});
    }

    return React.cloneElement(element, props);
  };

  render() {
    // eslint-disable-next-line no-unused-vars
    const {className, children, fields, onModified, onSubmitError, afterSubmit, resetOnSubmit, ...others} = this.props;
    const {canSubmit, canReset, reset, onSubmit, setValues, state, onBlur} = this;
    const {current, submitting, ids} = state;

    const formUnits = {};
    for (const name in fields) {
      const props = fields[name];
      if (!props) continue;

      const error = state.errors[name];
      const children = this.controlField({...props, name, ids});
      const help = error || props.help;
      const labelFor = props.labelFor || children.props.id;
      // eslint-disable-next-line no-unused-vars
      const {className: _, ...rest} = props;

      formUnits[name] = (
        <FormUnit {...{
          ...rest, key: name, optional: isOptional(rest, current), setValues, state, name, hasError: !!error,
          help, labelFor, children
        }}/>
      );
    }

    return (
      <form {...{...others, className: classnames('form', className), onSubmit: this.onSubmit}}>
        <fieldset {...{disabled: submitting}}>
          {children({
            fields: formUnits, canSubmit, canReset, reset, onSubmit, setValues, state, onBlur, submitting
          })}
        </fieldset>
      </form>
    );
  }
}<|endoftext|>


<commit_before>// ==UserScript==
// @name          I am over 18
// @namespace     http://tsai.it/project/gmscripts/i-am-over-18/
// @homepageURL   http://tsai.it/project/gmscripts/i-am-over-18/
// @version       0.2.20160802
// @description   Automatically agrees the "I'm over 18" declaration. The current supported sites are primarily in Taiwan.
// @icon          https://github.com/tsaiid/gm-i-am-over-18/raw/master/icon48.png
// @icon64        https://github.com/tsaiid/gm-i-am-over-18/raw/master/icon64.png
// @license       MIT License (Expat)
// @copyright     2016, I-Ta Tsai (http://tsai.it/)
// @include       https://www.ptt.cc/*
// @include       http://www.ettoday.net/*
// @include       http://star.ettoday.net/*
// @include       http://*.playno1.com/*
// @include       http://*.eyny.com/*
// @include       http://ck101.com/*
// @include       http://www.mycould.com/*
// @include       http://kickass.socialtorrent.net/*
// @include       http://katproxy.com/*
// @include       http://www.xvideos.com/*
// @include       http://video.jav101.com/*
// @include       http://*.blogspot.tw/*
// @include       http://www.appledaily.com.tw/*
// @include       http://www.kocpc.com.tw/*
// @include       http://www.myfreecams.com/*
// @include       http://www.ibeauty.tw/*
// @require       https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
// @require       https://gist.githubusercontent.com/BrockA/2625891/raw/waitForKeyElements.js
// @grant         none
// ==/UserScript==

window.addEventListener('load', function() { // wait until page loaded

  this.$ = this.jQuery = jQuery.noConflict(true);

  var url = window.location.href;

  function clickToContinue (jNodes) {
      console.log(jNodes);
      console.log(jNodes.context);
      console.log(jNodes.selector);
      jNodes[0].click();
  }

  // for ptt
  if (url.match(/www\.ptt\.cc/) && $('button:contains("我同意，我已年滿十八歲")').length) {
    $('button:contains("我同意，我已年滿十八歲")').click();
  }

  // for ettoday
  if (url.match(/www|star\.ettoday\.net/) && $('.adult-box').length && $('.adult-box').is(':visible')) {
    $('.adult-box').hide();
  }

  // for playno1
  if (url.match(/\.playno1\.com/)) {
    console.log("play01");
    waitForKeyElements (
      'button:contains("我已滿18歲 進入")',
          clickToContinue
    );
  }

  // for eyny, mycould
  if (url.match(/\.eyny\.com|www\.mycould\.com/) && $('input[value*="是，我已年滿18歲。"]').length) {
    $('input[value*="是，我已年滿18歲。"]').click();
  }

  // for ck101
  if (url.match(/ck101\.com/)) {
      console.log("ck101");
      waitForKeyElements (
      "#fwin_dialog_submit",
          clickToContinue
      );
  }

  // for kickass
  if (url.match(/kickass\.socialtorrent\.net|katproxy\.com/) && $('button:contains("Yes, let me see it")').length) {
    $('button:contains("Yes, let me see it")').click();
  }

  // for xvideos
  if ($('#disclamer_message').length) {
    $('#disclamer_message span:contains("ENTER")').parent().click();
  }

  // for jav101
  if (url.match(/video\.jav101\.com/) && $('a.agreeBtn').length) {
    $('a.agreeBtn').click();
  }

  // blogspot
  // from https://gist.github.com/obeattie/362589
  if (url.match(/\.blogspot\.tw/)) {
    var overlay = document.getElementById('injected-iframe');
    if (overlay) {
      var nextSibling = overlay.nextElementSibling;
      if (nextSibling.tagName == 'STYLE') nextSibling.parentElement.removeChild(nextSibling);
      overlay.parentElement.removeChild(overlay);
    }
  }

  // appledaily
  if (url.match(/www\.appledaily\.com\.tw/)) {
      console.log("appledaily");
      waitForKeyElements (
      "#popup_18 a.yes",
          clickToContinue
      );
  }

  // www.kocpc.com.tw
  if (url.match(/www\.kocpc\.com\.tw/)) {
      console.log("kocpc");
      waitForKeyElements (
      "button.ox18B",
          clickToContinue
      );
  }

  // myfreecams
  if (url.match(/www\.myfreecams\.com/)) {
      console.log("myfreecams");
      waitForKeyElements (
      "#enter_desktop",
          clickToContinue
      );
  }

  // ibeauty
  if (url.match(/www\.ibeauty\.tw/)) {
      console.log("ibeauty");
      waitForKeyElements (
        ".warningWp .warningBtn .btnYes",
        clickToContinue
      );
  }

}, false);
<commit_msg>change homepageURL.<commit_after>// ==UserScript==
// @name          I am over 18
// @namespace     http://tsai.it/project/gmscripts/i-am-over-18/
// @homepageURL   https://github.com/tsaiid/gm-i-am-over-18
// @version       0.2.20160802
// @description   Automatically agrees the "I'm over 18" declaration. The current supported sites are primarily in Taiwan.
// @icon          https://github.com/tsaiid/gm-i-am-over-18/raw/master/icon48.png
// @icon64        https://github.com/tsaiid/gm-i-am-over-18/raw/master/icon64.png
// @license       MIT License (Expat)
// @copyright     2016, I-Ta Tsai (http://tsai.it/)
// @include       https://www.ptt.cc/*
// @include       http://www.ettoday.net/*
// @include       http://star.ettoday.net/*
// @include       http://*.playno1.com/*
// @include       http://*.eyny.com/*
// @include       http://ck101.com/*
// @include       http://www.mycould.com/*
// @include       http://kickass.socialtorrent.net/*
// @include       http://katproxy.com/*
// @include       http://www.xvideos.com/*
// @include       http://video.jav101.com/*
// @include       http://*.blogspot.tw/*
// @include       http://www.appledaily.com.tw/*
// @include       http://www.kocpc.com.tw/*
// @include       http://www.myfreecams.com/*
// @include       http://www.ibeauty.tw/*
// @require       https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
// @require       https://gist.githubusercontent.com/BrockA/2625891/raw/waitForKeyElements.js
// @grant         none
// ==/UserScript==

window.addEventListener('load', function() { // wait until page loaded

  this.$ = this.jQuery = jQuery.noConflict(true);

  var url = window.location.href;

  function clickToContinue (jNodes) {
      console.log(jNodes);
      console.log(jNodes.context);
      console.log(jNodes.selector);
      jNodes[0].click();
  }

  // for ptt
  if (url.match(/www\.ptt\.cc/) && $('button:contains("我同意，我已年滿十八歲")').length) {
    $('button:contains("我同意，我已年滿十八歲")').click();
  }

  // for ettoday
  if (url.match(/www|star\.ettoday\.net/) && $('.adult-box').length && $('.adult-box').is(':visible')) {
    $('.adult-box').hide();
  }

  // for playno1
  if (url.match(/\.playno1\.com/)) {
    console.log("play01");
    waitForKeyElements (
      'button:contains("我已滿18歲 進入")',
          clickToContinue
    );
  }

  // for eyny, mycould
  if (url.match(/\.eyny\.com|www\.mycould\.com/) && $('input[value*="是，我已年滿18歲。"]').length) {
    $('input[value*="是，我已年滿18歲。"]').click();
  }

  // for ck101
  if (url.match(/ck101\.com/)) {
      console.log("ck101");
      waitForKeyElements (
      "#fwin_dialog_submit",
          clickToContinue
      );
  }

  // for kickass
  if (url.match(/kickass\.socialtorrent\.net|katproxy\.com/) && $('button:contains("Yes, let me see it")').length) {
    $('button:contains("Yes, let me see it")').click();
  }

  // for xvideos
  if ($('#disclamer_message').length) {
    $('#disclamer_message span:contains("ENTER")').parent().click();
  }

  // for jav101
  if (url.match(/video\.jav101\.com/) && $('a.agreeBtn').length) {
    $('a.agreeBtn').click();
  }

  // blogspot
  // from https://gist.github.com/obeattie/362589
  if (url.match(/\.blogspot\.tw/)) {
    var overlay = document.getElementById('injected-iframe');
    if (overlay) {
      var nextSibling = overlay.nextElementSibling;
      if (nextSibling.tagName == 'STYLE') nextSibling.parentElement.removeChild(nextSibling);
      overlay.parentElement.removeChild(overlay);
    }
  }

  // appledaily
  if (url.match(/www\.appledaily\.com\.tw/)) {
      console.log("appledaily");
      waitForKeyElements (
      "#popup_18 a.yes",
          clickToContinue
      );
  }

  // www.kocpc.com.tw
  if (url.match(/www\.kocpc\.com\.tw/)) {
      console.log("kocpc");
      waitForKeyElements (
      "button.ox18B",
          clickToContinue
      );
  }

  // myfreecams
  if (url.match(/www\.myfreecams\.com/)) {
      console.log("myfreecams");
      waitForKeyElements (
      "#enter_desktop",
          clickToContinue
      );
  }

  // ibeauty
  if (url.match(/www\.ibeauty\.tw/)) {
      console.log("ibeauty");
      waitForKeyElements (
        ".warningWp .warningBtn .btnYes",
        clickToContinue
      );
  }

}, false);
<|endoftext|>


<commit_before>import {
    ADD_VOTE_COMMENT,
    CREATE_COMMENT,
    REMOVE_COMMENT,
    REMOVE_VOTE_COMMENT,
    SET_COMMENTS,
    UPDATE_COMMENT
} from "../actions/Comment";
import {REMOVE_POST} from "../actions/Post";

const initialStateComments = {
    comments:[]
};

export default function comment(state = initialStateComments, action) {

    switch (action.type) {
        case REMOVE_COMMENT :
            state.comments.find(comment => comment.id === action.id).deleted = true;
            return state;

        case REMOVE_POST :
            state.comments.filter(comment => comment.parentId === action.id).map(comment => {
                comment.parentDeleted = true;
            });
            return state;

        case CREATE_COMMENT:
            state.comments.push(action.comment);
            return state;

        case ADD_VOTE_COMMENT:
            state.comments.find(comment => comment.id === action.id).voteScore += 1;
            return state;

        case REMOVE_VOTE_COMMENT:
            state.comments.find(comment => comment.id === action.id).voteScore -= 1;
            return state;

        case UPDATE_COMMENT:
            state.comments.find(comment => comment.id === action.comment.id).body = action.comment.body;
            return state;

        case SET_COMMENTS:
            return {
                comments: action.comments
            };

        default :
            return state
    }
}<commit_msg>fix: Change reducers to return a new state<commit_after>import {
    ADD_VOTE_COMMENT,
    CREATE_COMMENT,
    REMOVE_COMMENT,
    REMOVE_VOTE_COMMENT,
    SET_COMMENTS,
    UPDATE_COMMENT
} from "../actions/Comment";
import {REMOVE_POST} from "../actions/Post";

const initialStateComments = {
    comments:[]
};

export default function comment(state = initialStateComments, action) {

    switch (action.type) {
        case REMOVE_COMMENT :
            let newState = {...state};
            newState.comments.find(comment => comment.id === action.id).deleted = true;
            return newState;

        case REMOVE_POST :
            let newState = {...state};
            newState.comments.filter(comment => comment.parentId === action.id).map(comment => {
                comment.parentDeleted = true;
            });
            return newState;

        case CREATE_COMMENT:
            let newState = {...state};
            newState.comments.push(action.comment);
            return newState;

        case ADD_VOTE_COMMENT:
            let newState = {...state};
            newState.comments.find(comment => comment.id === action.id).voteScore += 1;
            return newState;

        case REMOVE_VOTE_COMMENT:
            let newState = {...state};
            newState.comments.find(comment => comment.id === action.id).voteScore -= 1;
            return newState;

        case UPDATE_COMMENT:
            let newState = {...state};
            newState.comments.find(comment => comment.id === action.comment.id).body = action.comment.body;
            return newState;

        case SET_COMMENTS:
            return {
                comments: action.comments
            };

        default :
            return state
    }
}<|endoftext|>


<commit_before>import _filter from "lodash/filter";
import * as types from "../actions/types";
import { genotypeColors } from "../util/globals";

export const intersectGenes = function intersectGenes(geneMap, pos) {
  for (const gene of Object.keys(geneMap)) {
    if (pos >= geneMap[gene].start && pos <= geneMap[gene].end) {
      return gene;
    }
  }
  return false;
};

const getAnnotations = (jsonData) => {
  const annotations = [];
  let aaCount = 0;
  for (const prot of Object.keys(jsonData)) {
    if (prot !== "nuc") {
      const tmpProt = jsonData[prot];
      aaCount += 1;
      annotations.push({
        prot: prot,
        start: tmpProt["pos"][0],
        end: tmpProt["pos"][tmpProt["pos"].length - 1],
        readingFrame: 1, // +tmpProt['pos'][0]%3,
        fill: genotypeColors[aaCount % 10]
      });
    }
  }
  return annotations;
};

const processAnnotations = (annotations) => {
  const m = {}; /* m === geneMap */
  annotations.forEach((d) => {
    m[d.prot] = d;
  });
  const sorted = Object.keys(m).sort((a, b) =>
    m[a].start < m[b].start ? -1 : m[a].start > m[b].start ? 1 : 0
  );
  for (const gene of Object.keys(m)) {
    m[gene].idx = sorted.indexOf(gene);
  }
  return m;
};

const Entropy = (state = {loaded: false}, action) => {
  switch (action.type) {
    case types.DATA_INVALID:
      return {loaded: false};
    case types.RECEIVE_ENTROPY:
      const annotations = getAnnotations(action.data);
      const geneMap = processAnnotations(annotations);
      return Object.assign({}, state, {
        loaded: false,
        jsonData: action.data,
        maxNt: Math.max(...action.data.nuc.pos),
        annotations,
        geneMap
      });
    case types.ENTROPY_DATA:
      return Object.assign({}, state, {
        loaded: true,
        bars: action.data,
        maxYVal: action.maxYVal
      });
    default:
      return state;
  }
};

export default Entropy;
<commit_msg>remove json entropy data from reducer<commit_after>import _filter from "lodash/filter";
import * as types from "../actions/types";
import { genotypeColors } from "../util/globals";

export const intersectGenes = function intersectGenes(geneMap, pos) {
  for (const gene of Object.keys(geneMap)) {
    if (pos >= geneMap[gene].start && pos <= geneMap[gene].end) {
      return gene;
    }
  }
  return false;
};

const getAnnotations = (jsonData) => {
  const annotations = [];
  let aaCount = 0;
  for (const prot of Object.keys(jsonData)) {
    if (prot !== "nuc") {
      const tmpProt = jsonData[prot];
      aaCount += 1;
      annotations.push({
        prot: prot,
        start: tmpProt["pos"][0],
        end: tmpProt["pos"][tmpProt["pos"].length - 1],
        readingFrame: 1, // +tmpProt['pos'][0]%3,
        fill: genotypeColors[aaCount % 10]
      });
    }
  }
  return annotations;
};

const processAnnotations = (annotations) => {
  const m = {}; /* m === geneMap */
  annotations.forEach((d) => {
    m[d.prot] = d;
  });
  const sorted = Object.keys(m).sort((a, b) =>
    m[a].start < m[b].start ? -1 : m[a].start > m[b].start ? 1 : 0
  );
  for (const gene of Object.keys(m)) {
    m[gene].idx = sorted.indexOf(gene);
  }
  return m;
};

const Entropy = (state = {loaded: false}, action) => {
  switch (action.type) {
    case types.DATA_INVALID:
      return {loaded: false};
    case types.RECEIVE_ENTROPY:
      const annotations = getAnnotations(action.data);
      const geneMap = processAnnotations(annotations);
      return Object.assign({}, state, {
        loaded: false,
        // jsonData: action.data,
        maxNt: Math.max(...action.data.nuc.pos),
        annotations,
        geneMap
      });
    case types.ENTROPY_DATA:
      return Object.assign({}, state, {
        loaded: true,
        bars: action.data,
        maxYVal: action.maxYVal
      });
    default:
      return state;
  }
};

export default Entropy;
<|endoftext|>


<commit_before>//Processamento de parâmentros via URL

//Foi solicitada mudança de mapa por URL?

if (URLSetBaseLayer!=null){
	switch(URLSetBaseLayer) {
		case 'satelite' : URLSetBaseLayer = 'lMBT'; break;
	}

	if(BaselayersValidas.match(URLSetBaseLayer)){
		$('#map-select-layer').val(URLSetBaseLayer);
		$('#map-select-layer').change();
	}
}

    //Se foi solicitado marcador no mapa
    if (MarkerLatLonByURL !=null){
	if (!MapPreventNewUserMakers){
		MapPreventNewUserMakers = true;
		UserTempMarker.setLatLng(MarkerLatLonByURL);
		map.setView(MarkerLatLonByURL, 18);
		var Msg = TempMarkerMsg(MarkerLatLonByURL[0],MarkerLatLonByURL[1]);
 		UserTempMarker.bindPopup(Msg).addTo(map);
		UserTempMarker.openPopup();
	}else{
		MapPreventNewUserMakers = false;
		map.removeLayer(UserTempMarker);
	}
    }

if (CamadaDeDados !=null){
   switch( CamadaDeDados  ) {
	case 'hospedagem' : AddDataOverlay('hospedagem','Hospedagem',HotelIcon,'lodging'); break;
	case 'taxi'       : AddDataOverlay('taxi','Táxi',TaxiIcon,'car'); break;
   }
}

//test - Add geoJSON
/*
var olHosp = L.mapbox.featureLayer()
  .loadURL('dados/hospedagem.geojson')
  .on('layeradd', function(e) {
    var marker = e.layer;
    marker.setIcon(HotelIcon);
        e.layer.bindPopup(FormatNameDesc(e.layer.feature.properties.Name,e.layer.feature.properties.Description));

  })
  .on('ready', function() {
       var ClusterLayerHosp = new L.MarkerClusterGroup();
       ClusterLayerHosp.addLayer(olHosp);
       ControlLayers.addOverlay(ClusterLayerHosp, ' Meios de Hospedagem');
       map.addLayer(ClusterLayerHosp);
});
*/
<commit_msg>Update proc-param.js<commit_after>//Processamento de parâmentros via URL

//Foi solicitada mudança de mapa por URL?

if (URLSetBaseLayer!=null){
	switch(URLSetBaseLayer) {
		case 'satelite' : URLSetBaseLayer = 'lMBT'; break;
	}

	if(BaselayersValidas.match(URLSetBaseLayer)){
		$('#map-select-layer').val(URLSetBaseLayer);
		$('#map-select-layer').change();
	}
}

    //Se foi solicitado marcador no mapa
    if (MarkerLatLonByURL !=null){
	if (!MapPreventNewUserMakers){
		MapPreventNewUserMakers = true;
		UserTempMarker.setLatLng(MarkerLatLonByURL);
		map.setView(MarkerLatLonByURL, 18);
		var Msg = TempMarkerMsg(MarkerLatLonByURL[0],MarkerLatLonByURL[1]);
 		UserTempMarker.bindPopup(Msg).addTo(map);
		UserTempMarker.openPopup();
	}else{
		MapPreventNewUserMakers = false;
		map.removeLayer(UserTempMarker);
	}
    }

if (CamadaDeDados !=null){
   switch( CamadaDeDados  ) {
	case 'hospedagem' : AddDataOverlay('hospedagem','Hospedagem',HotelIcon,'lodging'); break;
	case 'barrest'    : AddDataOverlay('bares-restaurantes','Bares e Restaurantes',AlimentIcon,'bar'); break;
	case 'taxi'       : AddDataOverlay('taxi','Táxi',TaxiIcon,'car'); break;
   }
}

//test - Add geoJSON
/*
var olHosp = L.mapbox.featureLayer()
  .loadURL('dados/hospedagem.geojson')
  .on('layeradd', function(e) {
    var marker = e.layer;
    marker.setIcon(HotelIcon);
        e.layer.bindPopup(FormatNameDesc(e.layer.feature.properties.Name,e.layer.feature.properties.Description));

  })
  .on('ready', function() {
       var ClusterLayerHosp = new L.MarkerClusterGroup();
       ClusterLayerHosp.addLayer(olHosp);
       ControlLayers.addOverlay(ClusterLayerHosp, ' Meios de Hospedagem');
       map.addLayer(ClusterLayerHosp);
});
*/
<|endoftext|>


<commit_before>!function (context) {

  var remark = context.remark = context.remark || {}
    , slideshow = remark.slideshow = {}
    , scaleFactor = 227
    , heightFactor = 3
    , widthFactor = 4
    ;

  slideshow.create = function (source, element) {
    var slides = createSlides(source, element);

    styleElement(element);

    return {
      showSlide: function (slideIndex) {
        var slide = element.children[slideIndex];
        prepareSlideIfNeeded(slide, slides, slideIndex);
        slide.style.display = 'table';
      }
    , hideSlide: function (slideIndex) {
        element.children[slideIndex].style.display = 'none';
      }
    , getSlideCount: function () {
        return slides.length;
      }
    };
  };

  var createSlides = function (source, element) {
    var slides
      , slide
      , content
      , i
      ;

    slides = source.split(/\n\n---\n/)

    for (i = 0; i < slides.length; ++i) {
      slide = document.createElement('div');
      slide.className = 'slide';
      content = document.createElement('div');
      content.className = 'content';
      slide.appendChild(content);
      element.appendChild(slide);
    }

    return slides;
  };

  var styleElement = function (element) {
    var containerHeight = window.innerHeight
      , containerWidth = window.innerWidth
      , elementWidth = scaleFactor * widthFactor
      , elementHeight = scaleFactor * heightFactor
      ;

    var resize = function () {
      var scale;

      if (containerWidth / widthFactor > containerHeight / heightFactor) {
        scale = containerHeight / (scaleFactor * heightFactor);
      }
      else {
        scale = containerWidth / (scaleFactor * widthFactor);
      }

      element.style['-webkit-transform'] = 'scale(' + scale + ')';
      element.style.MozTransform = 'scale(' + scale + ')';
      element.style.left = (containerWidth - elementWidth * scale) / 2 + 'px';
      element.style.top = (containerHeight - elementHeight * scale) / 2 + 'px';
    };

    element.style.width = scaleFactor * widthFactor + 'px';
    element.style.height = scaleFactor * heightFactor + 'px';

    window.onresize = resize;
    window.onresize();
  };

  var prepareSlideIfNeeded = function (slide, slides, slideIndex) {
    var content = slide.children[0];

    if (content.innerHTML === '') {
      content.innerHTML = slides[slideIndex];
      formatContent(content);
    }
  };

  var formatContent = function (content) {
    remark.converter.convertContentClasses(content);
    remark.converter.convertSlideClasses(content);
    remark.converter.convertMarkdown(content);
    remark.converter.convertCodeBlocks(content);
  };

}(this);
<commit_msg>Fixed non-working resize<commit_after>!function (context) {

  var remark = context.remark = context.remark || {}
    , slideshow = remark.slideshow = {}
    , scaleFactor = 227
    , heightFactor = 3
    , widthFactor = 4
    ;

  slideshow.create = function (source, element) {
    var slides = createSlides(source, element);

    styleElement(element);

    return {
      showSlide: function (slideIndex) {
        var slide = element.children[slideIndex];
        prepareSlideIfNeeded(slide, slides, slideIndex);
        slide.style.display = 'table';
      }
    , hideSlide: function (slideIndex) {
        element.children[slideIndex].style.display = 'none';
      }
    , getSlideCount: function () {
        return slides.length;
      }
    };
  };

  var createSlides = function (source, element) {
    var slides
      , slide
      , content
      , i
      ;

    slides = source.split(/\n\n---\n/)

    for (i = 0; i < slides.length; ++i) {
      slide = document.createElement('div');
      slide.className = 'slide';
      content = document.createElement('div');
      content.className = 'content';
      slide.appendChild(content);
      element.appendChild(slide);
    }

    return slides;
  };

  var styleElement = function (element) {
    var elementWidth = scaleFactor * widthFactor
      , elementHeight = scaleFactor * heightFactor
      ;

    var resize = function () {
      var containerHeight = window.innerHeight
        , containerWidth = window.innerWidth
        , scale
        ;

      if (containerWidth / widthFactor > containerHeight / heightFactor) {
        scale = containerHeight / (scaleFactor * heightFactor);
      }
      else {
        scale = containerWidth / (scaleFactor * widthFactor);
      }

      element.style['-webkit-transform'] = 'scale(' + scale + ')';
      element.style.MozTransform = 'scale(' + scale + ')';
      element.style.left = (containerWidth - elementWidth * scale) / 2 + 'px';
      element.style.top = (containerHeight - elementHeight * scale) / 2 + 'px';
    };

    element.style.width = scaleFactor * widthFactor + 'px';
    element.style.height = scaleFactor * heightFactor + 'px';

    window.onresize = resize;
    window.onresize();
  };

  var prepareSlideIfNeeded = function (slide, slides, slideIndex) {
    var content = slide.children[0];

    if (content.innerHTML === '') {
      content.innerHTML = slides[slideIndex];
      formatContent(content);
    }
  };

  var formatContent = function (content) {
    remark.converter.convertContentClasses(content);
    remark.converter.convertSlideClasses(content);
    remark.converter.convertMarkdown(content);
    remark.converter.convertCodeBlocks(content);
  };

}(this);
<|endoftext|>


<commit_before>describe('Charts', function () {

  var
    width = 480,
    height = 320,
    a, b, options, defaults;

  defaults = {
    width : 480,
    height : 320,
    offsetLeft : 0,
    offsetRight : 0,
    color : "rgb(192,216,0)",
    context : null,
    data : null,
    fill : false,
    fillColor : null,
    fillOpacity : 0.4,
    fillStyle : "rgba(192,216,0,0.4)",
    fontColor : "#545454",
    fontSize : 7.5,
    htmlText : true,
    lineWidth : 2,
    shadowSize : 4,
    show : false,
    stacked : false,
    textEnabled : true,
    xScale : function (x) { return x; },
    yScale : function (y) { return height - y; }
  };

  describe('Lines', function () {

    describe('Draw', function () {

      beforeEach(function () {
        this.addMatchers(imagediff.jasmine);
        a = imagediff.createCanvas(width, height);
        b = imagediff.createCanvas(width, height);
        options = _.clone(defaults);
        options.context = a.getContext('2d');
      });

      it('draws a line chart', function () {

        options.data = [
          [0, 0],
          [240, 300],
          [480, 0]
        ];

        TestFlotr.graphTypes.lines.draw(options);
        options.context = b.getContext('2d');
        StableFlotr.graphTypes.lines.draw(options);

        expect(b).toImageDiffEqual(a);
      });

      it('skips null values', function () {
        options.data = [
          [0, 0],
          [100, 50],
          [200, null],
          [300, 150],
          [400, 200],
          [480, 240]
        ];

        TestFlotr.graphTypes.lines.draw(options);
        options.context = b.getContext('2d');
        StableFlotr.graphTypes.lines.draw(options);
        expect(b).toImageDiffEqual(a);
      });

      it('draws two lines', function () {

        // First line
        options.data = [[0, 0], [240, 160], [480, 320]];
        TestFlotr.graphTypes.lines.draw(options);
        options.context = b.getContext('2d');
        StableFlotr.graphTypes.lines.draw(options);

        // Second Line
        options.context = a.getContext('2d');
        options.data = [[0, 320], [240, 160], [480, 0]];
        TestFlotr.graphTypes.lines.draw(options);
        options.context = b.getContext('2d');
        StableFlotr.graphTypes.lines.draw(options);

        expect(b).toImageDiffEqual(a);
      });
    });
  });
});
<commit_msg>Add drawTest helper method.<commit_after>describe('Charts', function () {

  var
    width = 480,
    height = 320,
    a, b, options, defaults;

  defaults = {
    width : 480,
    height : 320,
    offsetLeft : 0,
    offsetRight : 0,
    color : "rgb(192,216,0)",
    context : null,
    data : null,
    fill : false,
    fillColor : null,
    fillOpacity : 0.4,
    fillStyle : "rgba(192,216,0,0.4)",
    fontColor : "#545454",
    fontSize : 7.5,
    htmlText : true,
    lineWidth : 2,
    shadowSize : 4,
    show : false,
    stacked : false,
    textEnabled : true,
    xScale : function (x) { return x; },
    yScale : function (y) { return height - y; }
  };

  function drawTest (data) {
    options.data = data;

    TestFlotr.graphTypes.lines.draw(options);
    options.context = b.getContext('2d');
    StableFlotr.graphTypes.lines.draw(options);

    expect(b).toImageDiffEqual(a);
  }

  describe('Lines', function () {

    describe('Draw', function () {

      beforeEach(function () {
        this.addMatchers(imagediff.jasmine);
        a = imagediff.createCanvas(width, height);
        b = imagediff.createCanvas(width, height);
        options = _.clone(defaults);
        options.context = a.getContext('2d');
      });

      it('draws a line chart', function () {
        drawTest([
          [0, 0],
          [240, 300],
          [480, 0]
        ]);
      });

      it('skips null values', function () {
        drawTest([
          [0, 0],
          [100, 50],
          [200, null],
          [300, 150],
          [400, 200],
          [480, 240]
        ]);
      });

      it('draws two lines', function () {
        // First line
        drawTest([[0, 0], [240, 160], [480, 320]]);

        // Second Line
        options.context = a.getContext('2d');
        drawTest([[0, 320], [240, 160], [480, 0]]);
      });
    });
  });
});
<|endoftext|>


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

/**
 * A router method of this plugin
 * @param {String} method
 * @param {Json} params
 * @returns {Json}
 */
$.fn.view = function(method,params, callbackDebug){
    switch(method){
        case 'assign':
            return $(this).assign(params, callbackDebug);
            break;
        case 'unreplace':
            return $(this).viewDataUnreplace();
            break;
        case 'extract':
            return $(this).extract(params, callbackDebug);
        case 'iterate':
            var options = $.extend({
                'template':$(),
                'collection':[],
                'callbackItem':false,
                'cleanBeforeInit':false
            },params);
            return $(this).iterate(options.template, options.collection, options.callbackItem, options.cleanBeforeInit);
            break;
        case 'extractCollection':
            var options = $.extend({
                'valueObject':{},
                'selector':''
            },params);
            return $(this).extractCollection(options.valueObject, options.selector, callbackDebug);
    }
};

/**
 * Default find and add $(this) too if selector found
 * @param {type} selector
 * @returns {jQuery}
 */
$.fn.findMeToo = function(selector){
    if($(this).is(selector)){
        return $(this).add($(this).find(selector));
    }else{
        return $(this).find(selector);
    }
};
/**
 * Method used to set css
 * @param {String} property
 * @param {String} value
 * @returns {jQuery}
 */
$.fn.viewDataCss = function(property, value) {
    var $this = $(this);
    if (!$(this)[0])
        return $(this);
    $.each($this, function() {
        var attr = $this.attr('data-css-' + property);
        if(!attr){
            console.log($this, 'value of ' + 'data-css-' + property + ' is not found.');
            return true;
        }
        var attrs = attr.split('|');
        $.each(attrs,function(j,v){
            $this.css(attrs[j], value);
        });
    });
    return $(this);
};

/**
 * Method used to set property
 * @param string property
 * @param string value
 * @returns void
 */
$.fn.viewDataProp = function(property, valor) {
    var $this = $(this);
    if (!$this[0])
        return;
    $.each($this, function() {
        var attr = $this.attr('data-prop-' + property);
        if(!attr){
            console.log($this, 'not found value of: ' + 'data-prop-' + property);
            return true;
        }
        var attrs = attr.split('|');
        if(attrs.length < 2){
            console.log($this, 'not found value of: ' + 'data-prop-' + property + ' expected something like "checked|functionValidateCheck"');
            return true;
        };
        try{
            var fn = eval(attrs[1]);
            $this.prop(attrs[0],fn(valor, $this));
        }catch (e){
            console.log($this, 'it was not possible to apply in ' + 'data-prop-' + property + ' property ' + attrs[0] + ' or function ' + attrs[1] + ' not exists.');
        }
    });
};
/**
 * method to create property
 * @param string property
 * @param string value
 * @returns void
 */
$.fn.viewDataAttr = function(property, valor) {
    var $this = $(this);
    if (!$this[0])
        return;
    $.each($this, function() {
        var attr = $this.attr('data-attr-' + property);
        if(!attr){
            console.log($this, 'value of ' + 'data-attr-' + property + ' is not found.');
            return true;
        }
        var attrs = attr.split('|');
        $.each(attrs,function(j,v){
            $this.attr(attrs[j], valor);
        });
    });
};
$.fn.viewDataUnreplace = function(){
    $.each($(this),function(){
        var $this = $(this);
        $.each($this.findMeToo('[data-view-replaced="true"]'),function(){
            $el = $(this);
            $.each($el.data('data-view-attrs-replaced'),function(attribute, value){
                $el.attr(attribute, value);
            });
        });
    });
    return $(this);
};
$.fn.viewStoreBeforeReplace = function () {
    $.each($(this),function(){
        var $this = $(this);
        if(!$this.attr('data-view-replaced')){
            var replace = {};
            var reg = /^data-replace/;
            $.each($this,function(){
                $.each(this.attributes,function(){
                    var attribute = this;
                    if(reg.test(attribute.name)){
                        $.each($this.attr(attribute.name).split('|'), function(i,configured){
                            replace[configured] = $this.attr(configured);
                        });
                    }
                });
            });
            $this.data('data-view-attrs-replaced',replace);
            $this.attr('data-view-replaced','true');
        }

    });
};
/**
 * method to replace of property
 * @param string property
 * @param string value
 * @returns void
 */
$.fn.viewDataReplace = function(property, valor) {
    var $this = $(this);
    if (!$this[0])
        return;
    $.each($this, function() {
        var $el = $(this);
        var attr = $el.attr('data-replace-' + property);
        if(!attr){
            console.log($el, 'value of ' + 'data-attr-' + property + ' is not found.');
            return true;
        }
        var attrs = attr.split('|');
        $.each(attrs,function(j,attr){
            $el.attr(attr, $el.attr(attr).replaceAll('{' + property + '}', valor));
        });
    });
};
/**
 * Assign values of json object in to jquery object
 * <element  data-val-{index} to execute jquery "val" method in element
 * <element data-html-{index} to execute jquery "html" method in element
 * <element data-attr-{index}="{new-attribute-name}" adds the element of the index value in the attribute-related
 * <element data-attr-{index}="{new-attribute-name|[callback-for-value-in]}" adds the element of the index value in the attribute related, with callback for value
 * <element data-prop-{index}="{property-name}" set element property
 * <element data-prop-{index}="{property-name|callback-for-value-in}" set element property, with callback for value
 *      Samples:
 *
 *

 *
 *          <input type="text" data-val-ID_PESSOA />
 *

 *      will be executed on  tag:
 *          $(this).find('[data-attr-ST_LINK_PAGINA="href"]').attr('href',ST_LINK_PAGINA);
 *          $(this).find('[data-html-DS_TEXTO]').html(DS_TEXTO);
 *      will be executed on <input> tag:
 *          $(this).find('[data-val-ID_PESSOA]').val(ID_PESSOA);
 * @param Object json
 * @param function to debug
 * @returns jQuery
 */
$.fn.assign = function(obj, fnDebug) {
    var $this = $(this);
    fnDebug = fnDebug || function() {
    };
    if (!$this.length)
        return;
    if (fnDebug) {
        for (var i in obj) {
            var $html = $this.findMeToo('[data-html-' + i + ']');
            $html.html(obj[i]);
            fnDebug($html, obj[i], 'html', i);
            var $val = $this.findMeToo('[data-val-' + i + ']');
            $val.val(obj[i]);
            fnDebug($val, obj[i], 'val', i);
            var $attr = $this.findMeToo('[data-attr-' + i + ']');
            $attr.viewDataAttr(i, obj[i]);
            fnDebug($attr, obj[i], 'attr', i);
            var $prop = $this.findMeToo('[data-prop-' + i + ']');
            $prop.viewDataProp(i, obj[i]);
            fnDebug($prop, obj[i], 'prop', i);
            var $css = $this.findMeToo('[data-css-' + i + ']');
            $css.viewDataCss(i, obj[i]);
            fnDebug($css, obj[i], 'css', i);
            var $replace = $this.findMeToo('[data-replace-' + i + ']');
            $replace.viewStoreBeforeReplace();
            $replace.viewDataReplace(i, obj[i]);
            fnDebug($replace, obj[i], 'replace', i);
        }
    } else {
        for (var i in obj) {
            $this.findMeToo('[data-html-' + i + ']').html(obj[i]);
            $this.findMeToo('[data-val-' + i + ']').val(obj[i]);
            $this.findMeToo('[data-attr-' + i + ']').viewDataAttr(i, obj[i]);
            $this.findMeToo('[data-prop-' + i + ']').viewDataProp(i, obj[i]);
            $this.findMeToo('[data-css-' + i + ']').viewDataCss(i, obj[i]);
            $this.findMeToo('[data-replace-' + i + ']').viewStoreBeforeReplace();
            $this.findMeToo('[data-replace-' + i + ']').viewDataReplace(i, obj[i]);
        }
    }
    return $this;
};
/**
 * returns a result set for each item found
 * @param json attributes for search
 * @param string selector for item
 * @param function to debug
 * @returns Array with json objects
 */
$.fn.extractCollection = function(obj, seletor, fn) {
    var res = [];
    $.each($(this).find(seletor), function() {
        res.push($(this).extract($.extend(true, {}, obj), fn));
    });
    return res;
};
/**
 * returns a json completed for element
 * @param Object json
 * @param function to debug
 * @returns Object json
 */
$.fn.extract = function(objeto, fn) {
    fn = fn || function() {
    };
    var $this = $(this);
    if (!$this[0])
        return objeto;
    if (fn) {
        for (var i in objeto) {
            var attr = $this.findMeToo('[data-' + i + ']').attr('data-' + i);
            var val = $this.findMeToo('[data-val-' + i + ']').val();
            var html = $this.findMeToo('[data-html-' + i + ']').html();
            objeto[i] = attr ? attr : (val ? val : (html ? html : null));
            fn(i, objeto[i], attr, val, html);
        }
    } else {
        for (var i in objeto) {
            var attr = $this.findMeToo('[data-' + i + ']').attr('data-' + i);
            var val = $this.findMeToo('[data-val-' + i + ']').val();
            var html = $this.findMeToo('[data-html-' + i + ']').html();
            objeto[i] = attr ? attr : (val ? val : (html ? html : null));
        }
    }
    return objeto;
};
/**
 * Fills the element with several templates filled with the collection object
 * @param jQuery template for to cloning in loop
 * @param Array collection of json for assign in template
 * @param function for callback in item loop
 * @param boolean to clean before init operation
 * @returns jQuery
 */
$.fn.iterate = function($tpl, collection, callbackItem, cleanBeforeInit, callbackDebug) {
    var $this = this;
    cleanBeforeInit = cleanBeforeInit || false;
    if (cleanBeforeInit) {
        $this.html('');
    }
    if (callbackItem) {
        $.each(collection,function(i,v){
            var $clone = $tpl.clone(true);
            $this.append($clone.assign(collection[i]), callbackDebug)
            callbackItem($clone, collection[i]);
        });
    } else {
        $.each(collection,function(i,v){
            $this.append($tpl.clone(true).assign(collection[i]))
        });
    }
    return $this;
};

/**
 * Replace all occurrences of a string
 * @param string search
 * @param string replacement
 * @returns {String}
 */
String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};
<commit_msg>Compatibilização<commit_after>/*
 *	Copyright 2015 Calixto Jorge calixto.jorge@gmail.com
 *
 *	Licensed under the Apache License, Version 2.0 (the "License");
 *	you may not use this file except in compliance with the License.
 *	You may obtain a copy of the License at
 *
 *	    http://www.apache.org/licenses/LICENSE-2.0
 *
 *	Unless required by applicable law or agreed to in writing, software
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License.
 */

(function ($) {
    /**
     * A router method of this plugin
     * @param {String} method
     * @param {Json} params
     * @returns {Json}
     */
    $.fn.view = function (method, params, callbackDebug) {
        switch (method) {
            case 'assign':
                return $(this).assign(params, callbackDebug);
                break;
            case 'unreplace':
                return $(this).viewDataUnreplace();
                break;
            case 'extract':
                return $(this).extract(params, callbackDebug);
            case 'iterate':
                var options = $.extend({
                    'template': $(),
                    'collection': [],
                    'callbackItem': false,
                    'cleanBeforeInit': false
                }, params);
                return $(this).iterate(options.template, options.collection, options.callbackItem, options.cleanBeforeInit);
                break;
            case 'extractCollection':
                var options = $.extend({
                    'valueObject': {},
                    'selector': ''
                }, params);
                return $(this).extractCollection(options.valueObject, options.selector, callbackDebug);
        }
    };

    /**
     * Default find and add $(this) too if selector found
     * @param {type} selector
     * @returns {jQuery}
     */
    $.fn.findMeToo = function (selector) {
        if ($(this).is(selector)) {
            return $(this).add($(this).find(selector));
        } else {
            return $(this).find(selector);
        }
    };
    /**
     * Method used to set css
     * @param {String} property
     * @param {String} value
     * @returns {jQuery}
     */
    $.fn.viewDataCss = function (property, value) {
        var $this = $(this);
        if (!$(this)[0])
            return $(this);
        $.each($this, function () {
            var attr = $this.attr('data-css-' + property);
            if (!attr) {
                console.log($this, 'value of ' + 'data-css-' + property + ' is not found.');
                return true;
            }
            var attrs = attr.split('|');
            $.each(attrs, function (j, v) {
                $this.css(attrs[j], value);
            });
        });
        return $(this);
    };

    /**
     * Method used to set property
     * @param string property
     * @param string value
     * @returns void
     */
    $.fn.viewDataProp = function (property, valor) {
        var $this = $(this);
        if (!$this[0])
            return;
        $.each($this, function () {
            var attr = $this.attr('data-prop-' + property);
            if (!attr) {
                console.log($this, 'not found value of: ' + 'data-prop-' + property);
                return true;
            }
            var attrs = attr.split('|');
            if (attrs.length < 2) {
                console.log($this, 'not found value of: ' + 'data-prop-' + property + ' expected something like "checked|functionValidateCheck"');
                return true;
            }
            ;
            try {
                var fn = eval(attrs[1]);
                $this.prop(attrs[0], fn(valor, $this));
            } catch (e) {
                console.log($this, 'it was not possible to apply in ' + 'data-prop-' + property + ' property ' + attrs[0] + ' or function ' + attrs[1] + ' not exists.');
            }
        });
    };
    /**
     * method to create property
     * @param string property
     * @param string value
     * @returns void
     */
    $.fn.viewDataAttr = function (property, valor) {
        var $this = $(this);
        if (!$this[0])
            return;
        $.each($this, function () {
            var attr = $this.attr('data-attr-' + property);
            if (!attr) {
                console.log($this, 'value of ' + 'data-attr-' + property + ' is not found.');
                return true;
            }
            var attrs = attr.split('|');
            $.each(attrs, function (j, v) {
                $this.attr(attrs[j], valor);
            });
        });
    };
    $.fn.viewDataUnreplace = function () {
        $.each($(this), function () {
            var $this = $(this);
            $.each($this.findMeToo('[data-view-replaced="true"]'), function () {
                $el = $(this);
                $.each($el.data('data-view-attrs-replaced'), function (attribute, value) {
                    $el.attr(attribute, value);
                });
            });
        });
        return $(this);
    };
    $.fn.viewStoreBeforeReplace = function () {
        $.each($(this), function () {
            var $this = $(this);
            if (!$this.attr('data-view-replaced')) {
                var replace = {};
                var reg = /^data-replace/;
                $.each($this, function () {
                    $.each(this.attributes, function () {
                        var attribute = this;
                        if (reg.test(attribute.name)) {
                            $.each($this.attr(attribute.name).split('|'), function (i, configured) {
                                replace[configured] = $this.attr(configured);
                            });
                        }
                    });
                });
                $this.data('data-view-attrs-replaced', replace);
                $this.attr('data-view-replaced', 'true');
            }

        });
    };
    /**
     * method to replace of property
     * @param string property
     * @param string value
     * @returns void
     */
    $.fn.viewDataReplace = function (property, valor) {
        var $this = $(this);
        if (!$this[0])
            return;
        $.each($this, function () {
            var $el = $(this);
            var attr = $el.attr('data-replace-' + property);
            if (!attr) {
                console.log($el, 'value of ' + 'data-attr-' + property + ' is not found.');
                return true;
            }
            var attrs = attr.split('|');
            $.each(attrs, function (j, attr) {
                $el.attr(attr, $el.attr(attr).replaceAll('{' + property + '}', valor));
            });
        });
    };
    /**
     * Assign values of json object in to jquery object
     * <element  data-val-{index} to execute jquery "val" method in element
     * <element data-html-{index} to execute jquery "html" method in element
     * <element data-attr-{index}="{new-attribute-name}" adds the element of the index value in the attribute-related
     * <element data-attr-{index}="{new-attribute-name|[callback-for-value-in]}" adds the element of the index value in the attribute related, with callback for value
     * <element data-prop-{index}="{property-name}" set element property
     * <element data-prop-{index}="{property-name|callback-for-value-in}" set element property, with callback for value
     *      Samples:
     *
     *

     *
     *          <input type="text" data-val-ID_PESSOA />
     *

     *      will be executed on  tag:
     *          $(this).find('[data-attr-ST_LINK_PAGINA="href"]').attr('href',ST_LINK_PAGINA);
     *          $(this).find('[data-html-DS_TEXTO]').html(DS_TEXTO);
     *      will be executed on <input> tag:
     *          $(this).find('[data-val-ID_PESSOA]').val(ID_PESSOA);
     * @param Object json
     * @param function to debug
     * @returns jQuery
     */
    $.fn.assign = function (obj, fnDebug) {
        var $this = $(this);
        fnDebug = fnDebug || function () {
        };
        if (!$this.length)
            return;
        if (fnDebug) {
            for (var i in obj) {
                var $html = $this.findMeToo('[data-html-' + i + ']');
                $html.html(obj[i]);
                fnDebug($html, obj[i], 'html', i);
                var $val = $this.findMeToo('[data-val-' + i + ']');
                $val.val(obj[i]);
                fnDebug($val, obj[i], 'val', i);
                var $attr = $this.findMeToo('[data-attr-' + i + ']');
                $attr.viewDataAttr(i, obj[i]);
                fnDebug($attr, obj[i], 'attr', i);
                var $prop = $this.findMeToo('[data-prop-' + i + ']');
                $prop.viewDataProp(i, obj[i]);
                fnDebug($prop, obj[i], 'prop', i);
                var $css = $this.findMeToo('[data-css-' + i + ']');
                $css.viewDataCss(i, obj[i]);
                fnDebug($css, obj[i], 'css', i);
                var $replace = $this.findMeToo('[data-replace-' + i + ']');
                $replace.viewStoreBeforeReplace();
                $replace.viewDataReplace(i, obj[i]);
                fnDebug($replace, obj[i], 'replace', i);
            }
        } else {
            for (var i in obj) {
                $this.findMeToo('[data-html-' + i + ']').html(obj[i]);
                $this.findMeToo('[data-val-' + i + ']').val(obj[i]);
                $this.findMeToo('[data-attr-' + i + ']').viewDataAttr(i, obj[i]);
                $this.findMeToo('[data-prop-' + i + ']').viewDataProp(i, obj[i]);
                $this.findMeToo('[data-css-' + i + ']').viewDataCss(i, obj[i]);
                $this.findMeToo('[data-replace-' + i + ']').viewStoreBeforeReplace();
                $this.findMeToo('[data-replace-' + i + ']').viewDataReplace(i, obj[i]);
            }
        }
        return $this;
    };
    /**
     * returns a result set for each item found
     * @param json attributes for search
     * @param string selector for item
     * @param function to debug
     * @returns Array with json objects
     */
    $.fn.extractCollection = function (obj, seletor, fn) {
        var res = [];
        $.each($(this).find(seletor), function () {
            res.push($(this).extract($.extend(true, {}, obj), fn));
        });
        return res;
    };
    /**
     * returns a json completed for element
     * @param Object json
     * @param function to debug
     * @returns Object json
     */
    $.fn.extract = function (objeto, fn) {
        fn = fn || function () {
        };
        var $this = $(this);
        if (!$this[0])
            return objeto;
        if (fn) {
            for (var i in objeto) {
                var attr = $this.findMeToo('[data-' + i + ']').attr('data-' + i);
                var val = $this.findMeToo('[data-val-' + i + ']').val();
                var html = $this.findMeToo('[data-html-' + i + ']').html();
                objeto[i] = attr ? attr : (val ? val : (html ? html : null));
                fn(i, objeto[i], attr, val, html);
            }
        } else {
            for (var i in objeto) {
                var attr = $this.findMeToo('[data-' + i + ']').attr('data-' + i);
                var val = $this.findMeToo('[data-val-' + i + ']').val();
                var html = $this.findMeToo('[data-html-' + i + ']').html();
                objeto[i] = attr ? attr : (val ? val : (html ? html : null));
            }
        }
        return objeto;
    };
    /**
     * Fills the element with several templates filled with the collection object
     * @param jQuery template for to cloning in loop
     * @param Array collection of json for assign in template
     * @param function for callback in item loop
     * @param boolean to clean before init operation
     * @returns jQuery
     */
    $.fn.iterate = function ($tpl, collection, callbackItem, cleanBeforeInit, callbackDebug) {
        var $this = this;
        cleanBeforeInit = cleanBeforeInit || false;
        if (cleanBeforeInit) {
            $this.html('');
        }
        if (callbackItem) {
            $.each(collection, function (i, v) {
                var $clone = $tpl.clone(true);
                $this.append($clone.assign(collection[i]), callbackDebug)
                callbackItem($clone, collection[i]);
            });
        } else {
            $.each(collection, function (i, v) {
                $this.append($tpl.clone(true).assign(collection[i]))
            });
        }
        return $this;
    };
})(jQuery);

/**
 * Replace all occurrences of a string
 * @param string search
 * @param string replacement
 * @returns {String}
 */
String.prototype.replaceAll = function (search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};
<|endoftext|>


<commit_before>const mongoose = require('mongoose')
const { composeWithMongoose } = require('graphql-compose-mongoose')
// const { ErrorTC } = require('./ErrorSchema')

const AuthenSchema = new mongoose.Schema(
  {
    // Common
    installationId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Installation'
    },
    userId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User'
    },
    isLoggedIn: { type: Boolean, default: false },
    loggedInAt: Date,
    loggedInWith: String,
    loggedOutAt: Date,
    sessionToken: String,
    accessToken: String,
  },
  {
    timestamps: true,
  }
)

// - - - - - - Plugins - - - - - -

const Authen = mongoose.model('Authen', AuthenSchema)
const AuthenTC = composeWithMongoose(Authen)

// - - - - - - Relation - - - - - -

const { InstallationTC } = require('./InstallationSchema')
const { UserTC } = require('./UserSchema')

AuthenTC.addRelation(
  'user',
  () => ({
    resolver: UserTC.getResolver('findOne'),
    args: {
      filter: (source) => ({ userId: source.userId }),
      skip: null,
      sort: null,
    },
    projection: { userId: true },
  })
)

AuthenTC.addRelation(
  'installation',
  () => ({
    resolver: InstallationTC.getResolver('findOne'),
    args: {
      filter: (source) => ({ userId: source.installationId }),
      skip: null,
      sort: null,
    },
    projection: { installationId: true },
  })
)

// - - - - - - Extras - - - - - -

const { willInstall } = require('./InstallationSchema')
const { createUser } = require('./UserSchema')

AuthenTC.addResolver({
  name: 'loginWithFacebook',
  kind: 'mutation',
  args: {
    // Devices
    deviceInfo: 'String',
    locale: 'String',
    country: 'String',
    timezone: 'String',
    deviceName: 'String',
    isEmulater: 'Boolean',
    isTablet: 'Boolean',

    // Facebook
    accessToken: 'String'
  },
  type: AuthenTC,
  resolve: ({ context, args }) => new Promise(async (resolve) => {
    // Error
    const onError = err => {
      context.nap.errors.push({ code: 403, message: err.message })
      resolve(null)
    }

    // Installation
    const installation = await willInstall(args).catch(onError)
    const user = await context.nap.willLoginWithFacebook(context, args.accessToken).then(createUser).catch(onError)
    const authen = await context.nap.willAuthen(installation.id, user.id, 'facebook').catch(onError)

    // Fail
    if (!authen) {
      onError(new Error( 'Authen error'))
      return
    }

    // Succeed
    debug.info(' * authen :', authen)
    resolve(authen)
  })
})

const willLogout = (installationId, userId, sessionToken) => new Promise((resolve, reject) => {
  debug.log(' * logout :', installationId, userId, sessionToken)

  Authen.findOneAndUpdate({ installationId, userId, sessionToken, isLoggedIn: true }, {
    loggedOutAt: new Date().toISOString(),
    isLoggedIn: false
  }, { new: true, upsert: false }, (error, result) => {
    // Error?
    error && debug.error(error) && reject(error)
    // Succeed
    resolve(result)
  })
})

AuthenTC.addResolver({
  name: 'logout',
  kind: 'mutation',
  type: AuthenTC,
  resolve: ({ context }) => new Promise(async (resolve, reject) => {
    // Guard
    if(!context.nap.currentUser) {
      reject(new Error('No session found'))
      return
    }

    // Logout
    const authen = await willLogout(context.nap.currentUser.installationId, context.nap.currentUser.userId, context.token)

    // Fail
    if (!authen) {
      reject(new Error('No session found'))
      return
    }

    // Succeed
    debug.info(' * authen :', authen)
    resolve(authen)
  })
})

// - - - - - - Exports - - - - - -

module.exports = { Authen, AuthenTC }
<commit_msg>Will signout from cookie too<commit_after>const mongoose = require('mongoose')
const { composeWithMongoose } = require('graphql-compose-mongoose')
// const { ErrorTC } = require('./ErrorSchema')

const AuthenSchema = new mongoose.Schema(
  {
    // Common
    installationId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Installation'
    },
    userId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User'
    },
    isLoggedIn: { type: Boolean, default: false },
    loggedInAt: Date,
    loggedInWith: String,
    loggedOutAt: Date,
    sessionToken: String,
    accessToken: String,
  },
  {
    timestamps: true,
  }
)

// - - - - - - Plugins - - - - - -

const Authen = mongoose.model('Authen', AuthenSchema)
const AuthenTC = composeWithMongoose(Authen)

// - - - - - - Relation - - - - - -

const { InstallationTC } = require('./InstallationSchema')
const { UserTC } = require('./UserSchema')

AuthenTC.addRelation(
  'user',
  () => ({
    resolver: UserTC.getResolver('findOne'),
    args: {
      filter: (source) => ({ userId: source.userId }),
      skip: null,
      sort: null,
    },
    projection: { userId: true },
  })
)

AuthenTC.addRelation(
  'installation',
  () => ({
    resolver: InstallationTC.getResolver('findOne'),
    args: {
      filter: (source) => ({ userId: source.installationId }),
      skip: null,
      sort: null,
    },
    projection: { installationId: true },
  })
)

// - - - - - - Extras - - - - - -

const { willInstall } = require('./InstallationSchema')
const { createUser } = require('./UserSchema')

AuthenTC.addResolver({
  name: 'loginWithFacebook',
  kind: 'mutation',
  args: {
    // Devices
    deviceInfo: 'String',
    locale: 'String',
    country: 'String',
    timezone: 'String',
    deviceName: 'String',
    isEmulater: 'Boolean',
    isTablet: 'Boolean',

    // Facebook
    accessToken: 'String'
  },
  type: AuthenTC,
  resolve: ({ context, args }) => new Promise(async (resolve) => {
    // Error
    const onError = err => {
      context.nap.errors.push({ code: 403, message: err.message })
      resolve(null)
    }

    // Installation
    const installation = await willInstall(args).catch(onError)
    const user = await context.nap.willLoginWithFacebook(context, args.accessToken).then(createUser).catch(onError)
    const authen = await context.nap.willAuthen(installation.id, user.id, 'facebook').catch(onError)

    // Fail
    if (!authen) {
      onError(new Error( 'Authen error'))
      return
    }

    // Succeed
    debug.info(' * authen :', authen)
    resolve(authen)
  })
})

const willLogout = (installationId, userId, sessionToken) => new Promise((resolve, reject) => {
  debug.log(' * logout :', installationId, userId, sessionToken)

  Authen.findOneAndUpdate({ installationId, userId, sessionToken, isLoggedIn: true }, {
    loggedOutAt: new Date().toISOString(),
    isLoggedIn: false
  }, { new: true, upsert: false }, (error, result) => {
    // Error?
    error && debug.error(error) && reject(error)
    // Succeed
    resolve(result)
  })
})

AuthenTC.addResolver({
  name: 'logout',
  kind: 'mutation',
  type: AuthenTC,
  resolve: ({ context }) => new Promise(async (resolve, reject) => {
    // Logout from cookie
    context.logout()

    // Guard
    if(!context.nap.currentUser) {
      reject(new Error('No session found'))
      return
    }

    // Logout
    const authen = await willLogout(context.nap.currentUser.installationId, context.nap.currentUser.userId, context.token)

    // Fail
    if (!authen) {
      reject(new Error('No session found'))
      return
    }

    // Succeed
    debug.info(' * authen :', authen)
    resolve(authen)
  })
})

// - - - - - - Exports - - - - - -

module.exports = { Authen, AuthenTC }
<|endoftext|>


<commit_before>
// vim:sw=2:

var whop = whop || (function () {

var node = document.createElement.bind(document);
var elem = document.getElementById.bind(document);
var stage;
var sprites = [];

function movenode(n, x, y) {
  n.style.left = x + 'px';
  n.style.top = y + 'px';
}

function img(src, x, y) {
  var n = node('img');
  n.src = src;
  n.style.position = 'absolute';
  movenode(n, x, y);
  stage.appendChild(n);
  return n;
}

function makeSprite(src, x, y) {
  var xd = 0, yd = 0;
  var node = img(src, x, y);

  function move(nx, ny) {
    x = nx;
    y = ny;
    movenode(node, x, y);
  }

  function update() { move(x + xd, y + yd); }
  function setSpeed(nxd, nyd) { xd = nxd; yd = nyd; }
  function accel(xdd, ydd) { setSpeed(xd + xdd, yd + ydd); }

  var inst = { move: move, update: update, setSpeed: setSpeed, accel: accel };
  sprites.push(inst);

  return inst;
}

function nextFrame() {
  sprites.forEach(function(sprite) { sprite.update(); });
  requestAnimationFrame(nextFrame);
}

function init(stagename) {
  stage = elem(stagename);
  stage.removeChild(elem('jswarning'));
  requestAnimationFrame(nextFrame);
}

return { initialise: init, makeSprite: makeSprite };

})();

<commit_msg>sprite queries, whenMoved<commit_after>
// vim:sw=2:

var whop = whop || (function () {

var node = document.createElement.bind(document);
var elem = document.getElementById.bind(document);
var stage;
var sprites = [];

function movenode(n, x, y) {
  n.style.left = x + 'px';
  n.style.top = y + 'px';
}

function img(src, x, y) {
  var n = node('img');
  n.src = src;
  n.style.position = 'absolute';
  movenode(n, x, y);
  stage.appendChild(n);
  return n;
}

function makeSprite(src, x, y) {
  var xd = 0, yd = 0;
  var node = img(src, x, y);
  var hooks = [];

  function move(nx, ny) {
    x = nx;
    y = ny;
    movenode(node, x, y);
  }

  var inst = {
    x: function getX() { return x; },
    y: function getY() { return y; },
    xSpeed: function getXSpeed() { return xd; },
    ySpeed: function getYSpeed() { return yd; },

    move: move,
    update: function update() {
      hooks.forEach(function(hook) { hook(); });
      move(x + xd, y + yd);
    },

    setSpeed: function setSpeed(nxd, nyd) { xd = nxd; yd = nyd; },
    accel: function accel(xdd, ydd) { inst.setSpeed(xd + xdd, yd + ydd); },
    whenMoved: function whenMoved(cb) { hooks.push(cb); },

    clear: function clear() {
      hooks = [];
      inst.setSpeed(0, 0);
    }
  }

  sprites.push(inst);

  return inst;
}

function nextFrame() {
  sprites.forEach(function(sprite) { sprite.update(); });
  requestAnimationFrame(nextFrame);
}

function init(stagename) {
  stage = elem(stagename);
  stage.removeChild(elem('jswarning'));
  requestAnimationFrame(nextFrame);
}

return { initialise: init, makeSprite: makeSprite };

})();

<|endoftext|>