<commit_before>var _ = require('lodash');
var React = require('react');
var createReactClass = require('create-react-class');
var request = require('browser-request');
var cx = require('classnames');

var { transform, formatError } = require('../lib/util');

var examples = require('./examples.json');
var exampleGrammar = examples[0].source;
examples = examples.slice(1);

var App = createReactClass({

  formats: {
    pegjs: 'PEG.js',
    ebnf: 'EBNF',
    ohm: 'Ohm',
  },

  handleChange(e) {
    const {name, value} = e.currentTarget;
    this.setState({[name]: value});
  },

  UNSAFE_componentWillMount() {
    this.updateGrammarDebounced = _.debounce(() => this.updateGrammar, 150);
    if (location.hash) {
      var hash = location.hash.replace(/^#/, '');
      if (hash.match(/^https?:\/\/|\.\//)) {
        this.loadGrammar(hash);
      } else {
        this.updateGrammar(decodeURIComponent(hash));
      }
    } else {
      this.updateGrammar(exampleGrammar);
    }
  },

  getInitialState() {
    return {
      examples: examples,
      procesedGrammars: [],
      format: 'auto',
      detectedFormat: null
    };
  },

  render() {
    var { format, detectedFormat, syntaxError } = this.state;

    return (

            <form onSubmit={this.onLoadGrammar}>

                <input className="form-control" type="text" name="link" value={this.state.link} onChange={this.handleChange} placeholder="e.g. http://server.com/grammar.pegjs" />

              <button className="btn btn-primary col-md-3 col-sm-3 col-xs-4" type="submit" disabled={this.state.loading}>
                {this.state.loading ? 'Loading...' : 'Load Grammar'}
              </button>
            </form>

            Format:{" "}
            <select value={format} onChange={this.onChangeFormat}>
              <option value="auto">Auto-detect</option>
              {Object.keys(this.formats).map(k =>
                <option key={k} value={k}>{this.formats[k]}</option>
              )}
            </select>
            {format === 'auto' && !!detectedFormat &&
             Detected: {this.formats[detectedFormat]}}

            Try some examples:

            {this.state.examples.map((example, key) =>
               this.onSwitchGrammar(example.link, example.format)}>{example.name}
            )}

          {this.state.loadError &&

            {this.state.loadError}

}

            <textarea className="form-control grammar-edit" value={this.state.grammar} onChange={this.onChangeGrammar} />
            {syntaxError &&

              {formatError(syntaxError)}

}

          {this.state.procesedGrammars.map(({ rules, references, name }, key) =>

              {!!name &&
{name}
}
              {rules.map((rule, key) =>

{rule.name}

                  {references[rule.name] && references[rule.name].usedBy.length > 0 &&

                    Used By: {references[rule.name].usedBy.map((rule, key) =>
                       {rule}
                    )}

}
                  {references[rule.name] && references[rule.name].references.length > 0 &&

                    References: {references[rule.name].references.map((rule, key) =>
                       {rule}
                    )}

}

              )}

          )}

    );
  },

  onChangeGrammar(ev) {
    this.setState({grammar: ev.target.value});
    this.updateGrammarDebounced(ev.target.value);
  },

  onSwitchGrammar(link, format /* , ev */) {
    this.loadGrammar(link, format);
  },

  onLoadGrammar(ev) {
    ev.preventDefault();
    this.loadGrammar(this.state.link);
  },

  onClickDiagram(ev) {
    // if the node was clicked then go to rule definition
    if (ev.target.tagName === 'text') {
      location.hash = ev.target.textContent;
    }
  },

  onChangeFormat(ev) {
    this.updateGrammar(this.state.grammar, ev.target.value);
  },

  updateGrammar(grammar, format) {
    format = format || this.state.format;
    var state = {
      grammar: grammar,
      syntaxError: null,
      format,
      detectedFormat: null
    };

    try {
      state = Object.assign(state, transform(grammar, format));
    } catch (e) {
      state.syntaxError = e;
      state.procesedGrammars = [];
    }

    this.setState(state);
  },

  loadGrammar(link, format) {
    format = format || 'auto';
    link = link.trim().replace(/^https?:\/\/github.com\/([^\/]+)\/([^\/]+)\/blob\//, 'https://raw.githubusercontent.com/$1/$2/');
    location.hash = link;
    this.setState({
      link: link,
      grammar: '',
      procesedGrammars: [],
      loading: true,
      loadError: null,
      format,
      detectedFormat: null
    });
    request(link, (er, response, body) => {
      this.setState({loading: false})
      if (er || response.status !== 200) {
        this.setState({loadError: '' + (er || body)});
      } else {
        this.updateGrammar(body, format);
      }
    })
  }
});

module.exports = App;
<commit_msg>Fix linter error<commit_after>var _ = require('lodash');
var React = require('react');
var createReactClass = require('create-react-class');
var request = require('browser-request');
var cx = require('classnames');

var { transform, formatError } = require('../lib/util');

var examples = require('./examples.json');
var exampleGrammar = examples[0].source;
examples = examples.slice(1);

var App = createReactClass({

  formats: {
    pegjs: 'PEG.js',
    ebnf: 'EBNF',
    ohm: 'Ohm',
  },

  handleChange(e) {
    const {name, value} = e.currentTarget;
    this.setState({[name]: value});
  },

  UNSAFE_componentWillMount() {
    this.updateGrammarDebounced = _.debounce(() => this.updateGrammar, 150);
    if (location.hash) {
      var hash = location.hash.replace(/^#/, '');
      if (hash.match(/^https?:\/\/|\.\//)) {
        this.loadGrammar(hash);
      } else {
        this.updateGrammar(decodeURIComponent(hash));
      }
    } else {
      this.updateGrammar(exampleGrammar);
    }
  },

  getInitialState() {
    return {
      examples: examples,
      procesedGrammars: [],
      format: 'auto',
      detectedFormat: null
    };
  },

  render() {
    var { format, detectedFormat, syntaxError } = this.state;

    return (

            <form onSubmit={this.onLoadGrammar}>

                <input className="form-control" type="text" name="link" value={this.state.link} onChange={this.handleChange} placeholder="e.g. http://server.com/grammar.pegjs" />

              <button className="btn btn-primary col-md-3 col-sm-3 col-xs-4" type="submit" disabled={this.state.loading}>
                {this.state.loading ? 'Loading...' : 'Load Grammar'}
              </button>
            </form>

            Format:{" "}
            <select value={format} onChange={this.onChangeFormat}>
              <option value="auto">Auto-detect</option>
              {Object.keys(this.formats).map(k =>
                <option key={k} value={k}>{this.formats[k]}</option>
              )}
            </select>
            {format === 'auto' && !!detectedFormat &&
             Detected: {this.formats[detectedFormat]}}

            Try some examples:

            {this.state.examples.map((example, key) =>
               this.onSwitchGrammar(example.link, example.format)}>{example.name}
            )}

          {this.state.loadError &&

            {this.state.loadError}

}

            <textarea className="form-control grammar-edit" value={this.state.grammar} onChange={this.onChangeGrammar} />
            {syntaxError &&

              {formatError(syntaxError)}

}

          {this.state.procesedGrammars.map(({ rules, references, name }, key) =>

              {!!name &&
{name}
}
              {rules.map((rule, key) =>

{rule.name}

                  {references[rule.name] && references[rule.name].usedBy.length > 0 &&

                    Used By: {references[rule.name].usedBy.map((rule, key) =>
                       {rule}
                    )}

}
                  {references[rule.name] && references[rule.name].references.length > 0 &&

                    References: {references[rule.name].references.map((rule, key) =>
                       {rule}
                    )}

}

              )}

          )}

    );
  },

  onChangeGrammar(ev) {
    this.setState({grammar: ev.target.value});
    this.updateGrammarDebounced(ev.target.value);
  },

  onSwitchGrammar(link, format /* , ev */) {
    this.loadGrammar(link, format);
  },

  onLoadGrammar(ev) {
    ev.preventDefault();
    this.loadGrammar(this.state.link);
  },

  onClickDiagram(ev) {
    // if the node was clicked then go to rule definition
    if (ev.target.tagName === 'text') {
      location.hash = ev.target.textContent;
    }
  },

  onChangeFormat(ev) {
    this.updateGrammar(this.state.grammar, ev.target.value);
  },

  updateGrammar(grammar, format) {
    format = format || this.state.format;
    var state = {
      grammar: grammar,
      syntaxError: null,
      format,
      detectedFormat: null
    };

    try {
      state = Object.assign(state, transform(grammar, format));
    } catch (e) {
      state.syntaxError = e;
      state.procesedGrammars = [];
    }

    this.setState(state);
  },

  loadGrammar(link, format) {
    format = format || 'auto';
    link = link.trim().replace(/^https?:\/\/github.com\/([^/]+)\/([^/]+)\/blob\//, 'https://raw.githubusercontent.com/$1/$2/');
    location.hash = link;
    this.setState({
      link: link,
      grammar: '',
      procesedGrammars: [],
      loading: true,
      loadError: null,
      format,
      detectedFormat: null
    });
    request(link, (er, response, body) => {
      this.setState({loading: false})
      if (er || response.status !== 200) {
        this.setState({loadError: '' + (er || body)});
      } else {
        this.updateGrammar(body, format);
      }
    })
  }
});

module.exports = App;
<|endoftext|>


<commit_before>// Load in dependencies
var tokenUtils = require('rocambole-token');

// DEV: We use `tokenBefore` to update tokens (e.g. break down
//   vars) before they are fully parsed (e.g. `VariableDeclaration`)
// https://github.com/millermedeiros/esformatter/tree/v0.4.3#tokenbeforetoken

// Keyword : var
// WhiteSpace :
// Identifier : a
// WhiteSpace :
// Punctuator : =
// WhiteSpace :
// String : 'hello'
// LineBreak :

// WhiteSpace :
// Punctuator : ,
// WhiteSpace :
// Identifier : b
// WhiteSpace :
// Punctuator : =
// WhiteSpace :
// String : 'world'
// Punctuator : ;
// LineBreak :

// TODO: How do we deal with `range`?

exports.nodeBefore = function (node) {
  // If the token is a variable declaration (e.g. `var`, `let`)
  // https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API
  // interface VariableDeclaration <: Declaration {
  //     type: "VariableDeclaration";
  //     declarations: [ VariableDeclarator ];
  //     kind: "var" | "let" | "const";
  // }
  if (node.type === 'VariableDeclaration') {
    // TODO: If we are inside of a loop, do nothing
    // Generate a `var` for each of the declarators
    var varDeclaration = node;
    var declarators = varDeclaration.declarations;
    var declarations = declarators.map(function generateDeclaration (declarator, index) {
      // Generate a new delcaration similar to the original
      // Example: `var`` ` ... `;` (i.e. `var` <-> ` ` <-> ... <-> `;`)
      var declaration = {
        type: varDeclaration.type, // should always be `VariableDeclaration`
        declarations: [declarator],
          // link to declaration's tokens
        kind: varDeclaration.kind, // (e.g. `var`, `let`)
        // prev: connect to `declarations[i - 1]` or if first, original var's `prev`
        // next: connect to `declarations[i + 1]` or if last, original var's `next`
        startToken: {
          type: varDeclaration.startToken.type, // should always be `Keyword`
          value: varDeclaration.startToken.value, // (e.g. `var`, `let`)
          // prev: connect to `declarations[i - 1].endToken` or if first, original var's `startToken.prev`
          next: {
            type: varDeclaration.startToken.next.type, // should be `WhiteSpace`
            value: varDeclaration.startToken.next.value, // (e.g. ` `)
            // prev: set later to `declaration.startToken`
            next: declarator.startToken
              // update `next.prev` later
          }
        },
        endToken: {
          type: varDeclaration.endToken.type, // (e.g. `Punctuation`, `LineBreak`)
          value: varDeclaration.endToken.value, // (e.g. `;`, '\n')
          prev: declarator.endToken
            // update `prev.next` later
          // next: connect to `declarator[i + 1].startToken` or if last, original var's `endToken.next`
        }
      };
      declaration.startToken.next.prev = declaration.startToken;

      // Handle link backs
      if (declaration.startToken.next.next) {
        declaration.startToken.next.next.prev = declaration.startToken.next;
      }
      if (declarator.endToken.prev) {
        declarator.endToken.prev.next = declarator.endToken;
      }

      // Return the declaration
      return declaration;
    });

    // Connect all of our declarations
    // Example: `Leading code` <-> `var ... ;` <-> `var ... ;` <-> `Trailing code`
    var varDeclarationStartToken = varDeclaration.startToken;
    var varDeclarationEndToken = varDeclaration.endToken;
    var lenMinusOne = declarations.length - 1;
    declarations.forEach(function connectDeclaration (declaration, index) {
      // If we are the first item, connect to `varDeclaration's` predecessor
      if (index === 0) {
        declaration.prev = varDeclaration.prev;
        declaration.startToken.prev = varDeclarationStartToken.prev;
      // Otherwise, connect to the previous declaration
      } else {
        declaration.prev = declarations[index - 1];
        declaration.startToken.prev = declarations[index - 1].endToken;
      }

      // Handle link backs
      if (declaration.prev) {
        declaration.prev.next = declaration;
      }
      if (declaration.startToken.prev) {
        declaration.startToken.prev.next = declaration.startToken;
      }

      // If we are the last item, connect to `varDeclaration's` successor
      if (index === lenMinusOne) {
      // Otherwise, connect to the next declaration
        declaration.next = varDeclaration.next;
        declaration.endToken.next = varDeclarationEndToken.next;
      } else {
        // TODO: We might need whitespace... (e.g. `var hai;\nvar bai;`)
        declaration.next = declarations[index + 1];
        declaration.endToken.next = declarations[index + 1].startToken;
      }

      // Handle link backs
      if (declaration.next) {
        declaration.next.prev = declaration;
      }
      if (declaration.endToken.next) {
        declaration.endToken.next.prev = declaration.endToken;
      }
    });

    // Connect all of our declarator's tokens
    declarators.forEach(function connectDeclarator (declarator, index) {
      // DEV: This is the whitespace character
      declarator.startToken.prev = declarations[index].startToken.next;
      declarator.endToken.next = declarations[index].endToken;
    });

    // Overwrite `node` with our first declaration
    node = declarations[0];
    console.log(node);
  }

  // Return the updated node
  return node;
};
<commit_msg>Cleaning up code but not sure what to do about whitespace<commit_after>// Load in dependencies
var tokenUtils = require('rocambole-token');

// TODO: This comment is *wrong*
// DEV: We use `tokenBefore` to update tokens (e.g. break down
//   vars) before they are fully parsed (e.g. `VariableDeclaration`)
// https://github.com/millermedeiros/esformatter/tree/v0.4.3#tokenbeforetoken

// TODO: How do we deal with `range`?

exports.nodeBefore = function (node) {
  // If the token is a variable declaration (e.g. `var`, `let`)
  // https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API
  // interface VariableDeclaration <: Declaration {
  //     type: "VariableDeclaration";
  //     declarations: [ VariableDeclarator ];
  //     kind: "var" | "let" | "const";
  // }
  if (node.type === 'VariableDeclaration') {
    // TODO: If we are inside of a loop, do nothing
    // Generate a `var` for each of the declarators
    var varDeclaration = node;
    var declarators = varDeclaration.declarations;
    var declarations = declarators.map(function generateDeclaration (declarator, index) {
      // Generate a new delcaration similar to the original
      // Example: `var`` ` ... `;` (i.e. `var` <-> ` ` <-> ... <-> `;`)
      var declaration = {
        type: varDeclaration.type, // should always be `VariableDeclaration`
        declarations: [declarator],
          // link to declaration's tokens
        kind: varDeclaration.kind, // (e.g. `var`, `let`)
        // prev: connect to `declarations[i - 1]` or if first, original var's `prev`
        // next: connect to `declarations[i + 1]` or if last, original var's `next`
        startToken: {
          type: varDeclaration.startToken.type, // should always be `Keyword`
          value: varDeclaration.startToken.value, // (e.g. `var`, `let`)
          // prev: connect to `declarations[i - 1].endToken` or if first, original var's `startToken.prev`
          next: {
            type: varDeclaration.startToken.next.type, // should be `WhiteSpace`
            value: varDeclaration.startToken.next.value, // (e.g. ` `)
            // prev: set later to `declaration.startToken`
            next: declarator.startToken
              // update `next.prev` later
          }
        },
        endToken: {
          type: varDeclaration.endToken.type, // (e.g. `Punctuation`, `LineBreak`)
          value: varDeclaration.endToken.value, // (e.g. `;`, '\n')
          prev: declarator.endToken
            // update `prev.next` later
          // next: connect to `declarator[i + 1].startToken` or if last, original var's `endToken.next`
        }
      };
      declaration.startToken.next.prev = declaration.startToken;

      // Handle link backs
      if (declaration.startToken.next.next) {
        declaration.startToken.next.next.prev = declaration.startToken.next;
      }
      if (declarator.endToken.prev) {
        declarator.endToken.prev.next = declarator.endToken;
      }

      // Return the declaration
      return declaration;
    });

    // Connect all of our declarations
    // Example: `Leading code` <-> `var ... ;` <-> `var ... ;` <-> `Trailing code`
    var varDeclarationStartToken = varDeclaration.startToken;
    var varDeclarationEndToken = varDeclaration.endToken;
    var lenMinusOne = declarations.length - 1;
    declarations.forEach(function connectDeclaration (declaration, index) {
      // If we are the first item, connect to `varDeclaration's` predecessor
      if (index === 0) {
        declaration.prev = varDeclaration.prev;
        declaration.startToken.prev = varDeclarationStartToken.prev;
      // Otherwise, connect to the previous declaration
      } else {
        declaration.prev = declarations[index - 1];
        declaration.startToken.prev = declarations[index - 1].endToken;
      }

      // Handle link backs
      if (declaration.prev) {
        declaration.prev.next = declaration;
      }
      if (declaration.startToken.prev) {
        declaration.startToken.prev.next = declaration.startToken;
      }

      // If we are the last item, connect to `varDeclaration's` successor
      if (index === lenMinusOne) {
      // Otherwise, connect to the next declaration
        declaration.next = varDeclaration.next;
        declaration.endToken.next = varDeclarationEndToken.next;
      } else {
        // TODO: We might need whitespace... (e.g. `var hai;\nvar bai;`)
        declaration.next = declarations[index + 1];
        declaration.endToken.next = declarations[index + 1].startToken;
      }

      // Handle link backs
      if (declaration.next) {
        declaration.next.prev = declaration;
      }
      if (declaration.endToken.next) {
        declaration.endToken.next.prev = declaration.endToken;
      }
    });

    // Connect all of our declarator's tokens
    declarators.forEach(function connectDeclarator (declarator, index) {
      // DEV: This is the whitespace character
      declarator.startToken.prev = declarations[index].startToken.next;
      declarator.endToken.next = declarations[index].endToken;
    });

    // Overwrite `node` with our first declaration
    node = declarations[0];
    console.log(node);
  }

  // Return the updated node
  return node;
};
<|endoftext|>


<commit_before>/*
* maskMoney plugin for jQuery
* http://plentz.github.com/jquery-maskmoney/
* version: 2.0.0 beta
* Licensed under the MIT license
*/
;(function($) {
	if(!$.browser){
		$.browser = {};
		$.browser.mozilla = /mozilla/.test(navigator.userAgent.toLowerCase()) && !/webkit/.test(navigator.userAgent.toLowerCase());
		$.browser.webkit = /webkit/.test(navigator.userAgent.toLowerCase());
		$.browser.opera = /opera/.test(navigator.userAgent.toLowerCase());
		$.browser.msie = /msie/.test(navigator.userAgent.toLowerCase());
	}

	var methods = {
		destroy : function(){
			var input = $(this);
			input.unbind('.maskMoney');

			if ($.browser.msie) {
				this.onpaste = null;
			} else if ($.browser.mozilla) {
				this.removeEventListener('input', blurEvent, false);
			}
			return this;
		},

		mask : function(){
			return this.trigger('mask');
		},

		init : function(settings) {
			settings = $.extend({
				symbol: 'US$',
				showSymbol: false,
				symbolStay: false,
				thousands: ',',
				decimal: '.',
				precision: 2,
				defaultZero: true,
				allowZero: false,
				allowNegative: false
			}, settings);

			return this.each(function() {
				var input = $(this);
				var dirty = false;

				function markAsDirty() {
					dirty = true;
				}

				function clearDirt(){
					dirty = false;
				}

				function keypressEvent(e) {
					e = e || window.event;
					var k = e.charCode || e.keyCode || e.which;
					if (k == undefined) return false; //needed to handle an IE "special" event
					if (input.attr('readonly') && (k != 13 && k != 9)) return false; // don't allow editing of readonly fields but allow tab/enter

					if (k < 48 || k > 57) { // any key except the numbers 0-9
						if (k == 45) { // -(minus) key
							markAsDirty();
							input.val(changeSign(input));
							return false;
						} else if (k == 43) { // +(plus) key
							markAsDirty();
							input.val(input.val().replace('-',''));
							return false;
						} else if (k == 13 || k == 9) { // enter key or tab key
							if(dirty){
								clearDirt();
								$(this).change();
							}
							return true;
						} else if (k == 37 || k == 39) { // left arrow key or right arrow key
							return true;
						} else { // any other key with keycode less than 48 and greater than 57
							preventDefault(e);
							return true;
						}
					} else if (input.val().length>=input.attr('maxlength')) {
						return false;
					} else {
						preventDefault(e);

						var key = String.fromCharCode(k);
						var x = input.get(0);
						var selection = getInputSelection(x);
						var startPos = selection.start;
						var endPos = selection.end;
						x.value = x.value.substring(0, startPos) + key + x.value.substring(endPos, x.value.length);
						maskAndPosition(x, startPos + 1);
						markAsDirty();
						return false;
					}
				}

				function keydownEvent(e) {
					e = e||window.event;
					var k = e.charCode||e.keyCode||e.which;
					if (k == undefined) return false; //needed to handle an IE "special" event
					if (input.attr('readonly') && (k!=13&&k!=9)) return false; // don't allow editing of readonly fields but allow tab/enter

					var x = input.get(0);
					var selection = getInputSelection(x);
					var startPos = selection.start;
					var endPos = selection.end;

					if (k==8) { // backspace key
						preventDefault(e);

						if(startPos == endPos){
							// Remove single character
							x.value = x.value.substring(0, startPos - 1) + x.value.substring(endPos, x.value.length);
							startPos = startPos - 1;
						} else {
							// Remove multiple characters
							x.value = x.value.substring(0, startPos) + x.value.substring(endPos, x.value.length);
						}
						maskAndPosition(x, startPos);
						markAsDirty();
						return false;
					} else if (k==9) { // tab key
						if(dirty) {
							$(this).change();
							clearDirt();
						}
						return true;
					} else if ( k==46 || k==63272 ) { // delete key (with special case for safari)
						preventDefault(e);
						if(x.selectionStart == x.selectionEnd){
							// Remove single character
							x.value = x.value.substring(0, startPos) + x.value.substring(endPos + 1, x.value.length);
						} else {
							//Remove multiple characters
							x.value = x.value.substring(0, startPos) + x.value.substring(endPos, x.value.length);
						}
						maskAndPosition(x, startPos);
						markAsDirty();
						return false;
					} else { // any other key
						return true;
					}
				}

				function focusEvent(e) {
					var mask = getDefaultMask();
					if (input.val() == mask) {
						input.val('');
					} else if (input.val()=='' && settings.defaultZero) {
						input.val(setSymbol(mask));
					} else {
						input.val(setSymbol(input.val()));
					}
					if (this.createTextRange) {
						var textRange = this.createTextRange();
						textRange.collapse(false); // set the cursor at the end of the input
						textRange.select();
					}
				}

				function blurEvent(e) {
					if ($.browser.msie) {
						keypressEvent(e);
					}

					if (input.val() == '' || input.val() == setSymbol(getDefaultMask()) || input.val() == settings.symbol) {
						if(!settings.allowZero) input.val('');
						else if (!settings.symbolStay) input.val(getDefaultMask());
						else input.val(setSymbol(getDefaultMask()));
					} else {
						if (!settings.symbolStay) input.val(input.val().replace(settings.symbol,''));
						else if (settings.symbolStay&&input.val()==settings.symbol) input.val(setSymbol(getDefaultMask()));
					}
				}

				function preventDefault(e) {
					if (e.preventDefault) { //standard browsers
						e.preventDefault();
					} else { // internet explorer
						e.returnValue = false
					}
				}

				function maskAndPosition(x, startPos) {
					var originalLen = input.val().length;
					input.val(maskValue(x.value));
					var newLen = input.val().length;
					startPos = startPos - (originalLen - newLen);
					setCursorPosition(input, startPos);
				}

				function mask(){
					var value = input.val();
					input.val(maskValue(value));
				}

				function maskValue(v) {
					v = v.replace(settings.symbol, '');

					var strCheck = '0123456789';
					var len = v.length;
					var a = '', t = '', neg='';

					if(len != 0 && v.charAt(0)=='-'){
						v = v.replace('-','');
						if(settings.allowNegative){
							neg = '-';
						}
					}

					if (len==0) {
						if (!settings.defaultZero) return t;
						t = '0.00';
					}

					for (var i = 0; i<len; i++) {
						if ((v.charAt(i)!='0') && (v.charAt(i)!=settings.decimal)) break;
					}

					for (; i < len; i++) {
						if (strCheck.indexOf(v.charAt(i))!=-1) a+= v.charAt(i);
					}
					var n = parseFloat(a);

					n = isNaN(n) ? 0 : n/Math.pow(10,settings.precision);
					t = n.toFixed(settings.precision);

					i = settings.precision == 0 ? 0 : 1;
					var p, d = (t=t.split('.'))[i].substr(0,settings.precision);
					for (p = (t=t[0]).length; (p-=3)>=1;) {
						t = t.substr(0,p)+settings.thousands+t.substr(p);
					}

					return (settings.precision>0)
					? setSymbol(neg+t+settings.decimal+d+Array((settings.precision+1)-d.length).join(0))
					: setSymbol(neg+t);
				}

				function getDefaultMask() {
					var n = parseFloat('0')/Math.pow(10,settings.precision);
					return (n.toFixed(settings.precision)).replace(new RegExp('\\.','g'),settings.decimal);
				}

				function setSymbol(v) {
					if (settings.showSymbol) {
						if (v.substr(0, settings.symbol.length) != settings.symbol) return settings.symbol+v;
					}
					return v;
				}

				function changeSign(i){
					if (settings.allowNegative) {
						var vic = i.val();
						if (i.val()!='' && i.val().charAt(0)=='-'){
							return i.val().replace('-','');
						} else{
							return '-'+i.val();
						}
					} else {
						return i.val();
					}
				}

				function setCursorPosition(input, pos) {
					// I'm not sure if we need to jqueryfy input
					$(input).each(function(index, elem) {
						if (elem.setSelectionRange) {
							elem.focus();
							elem.setSelectionRange(pos, pos);
						} else if (elem.createTextRange) {
							var range = elem.createTextRange();
							range.collapse(true);
							range.moveEnd('character', pos);
							range.moveStart('character', pos);
							range.select();
						}
					});
					return this;
				};

				function getInputSelection(el) {
					var start = 0, end = 0, normalizedValue, range, textInputRange, len, endRange;

					if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
						start = el.selectionStart;
						end = el.selectionEnd;
					} else {
						range = document.selection.createRange();

						if (range && range.parentElement() == el) {
							len = el.value.length;
							normalizedValue = el.value.replace(/\r\n/g, "\n");

							// Create a working TextRange that lives only in the input
							textInputRange = el.createTextRange();
							textInputRange.moveToBookmark(range.getBookmark());

							// Check if the start and end of the selection are at the very end
							// of the input, since moveStart/moveEnd doesn't return what we want
							// in those cases
							endRange = el.createTextRange();
							endRange.collapse(false);

							if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
								start = end = len;
							} else {
								start = -textInputRange.moveStart("character", -len);
								start += normalizedValue.slice(0, start).split("\n").length - 1;

								if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
									end = len;
								} else {
									end = -textInputRange.moveEnd("character", -len);
									end += normalizedValue.slice(0, end).split("\n").length - 1;
								}
							}
						}
					}

					return {
						start: start,
						end: end
					};
				} // getInputSelection

				if (!input.attr("readonly")){
					input.unbind('.maskMoney');
					input.bind('keypress.maskMoney', keypressEvent);
					input.bind('keydown.maskMoney', keydownEvent);
					input.bind('blur.maskMoney', blurEvent);
					input.bind('focus.maskMoney', focusEvent);
					input.bind('mask.maskMoney', mask);
				}
			})
		}
	}

	$.fn.maskMoney = function(method) {
		if ( methods[method] ) {
			return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
		} else if ( typeof method === 'object' || ! method ) {
			return methods.init.apply( this, arguments );
		} else {
			$.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
		}
	};
})(jQuery);
<commit_msg>removing code that handle readonly fields since we don't bind to them anymore. fixes #51 related #58<commit_after>/*
* maskMoney plugin for jQuery
* http://plentz.github.com/jquery-maskmoney/
* version: 2.0.0 beta
* Licensed under the MIT license
*/
;(function($) {
	if(!$.browser){
		$.browser = {};
		$.browser.mozilla = /mozilla/.test(navigator.userAgent.toLowerCase()) && !/webkit/.test(navigator.userAgent.toLowerCase());
		$.browser.webkit = /webkit/.test(navigator.userAgent.toLowerCase());
		$.browser.opera = /opera/.test(navigator.userAgent.toLowerCase());
		$.browser.msie = /msie/.test(navigator.userAgent.toLowerCase());
	}

	var methods = {
		destroy : function(){
			var input = $(this);
			input.unbind('.maskMoney');

			if ($.browser.msie) {
				this.onpaste = null;
			} else if ($.browser.mozilla) {
				this.removeEventListener('input', blurEvent, false);
			}
			return this;
		},

		mask : function(){
			return this.trigger('mask');
		},

		init : function(settings) {
			settings = $.extend({
				symbol: 'US$',
				showSymbol: false,
				symbolStay: false,
				thousands: ',',
				decimal: '.',
				precision: 2,
				defaultZero: true,
				allowZero: false,
				allowNegative: false
			}, settings);

			return this.each(function() {
				var input = $(this);
				var dirty = false;

				function markAsDirty() {
					dirty = true;
				}

				function clearDirt(){
					dirty = false;
				}

				function keypressEvent(e) {
					e = e || window.event;
					var k = e.charCode || e.keyCode || e.which;
					if (k == undefined) return false; //needed to handle an IE "special" event

					if (k < 48 || k > 57) { // any key except the numbers 0-9
						if (k == 45) { // -(minus) key
							markAsDirty();
							input.val(changeSign(input));
							return false;
						} else if (k == 43) { // +(plus) key
							markAsDirty();
							input.val(input.val().replace('-',''));
							return false;
						} else if (k == 13 || k == 9) { // enter key or tab key
							if(dirty){
								clearDirt();
								$(this).change();
							}
							return true;
						} else if (k == 37 || k == 39) { // left arrow key or right arrow key
							return true;
						} else { // any other key with keycode less than 48 and greater than 57
							preventDefault(e);
							return true;
						}
					} else if (input.val().length>=input.attr('maxlength')) {
						return false;
					} else {
						preventDefault(e);

						var key = String.fromCharCode(k);
						var x = input.get(0);
						var selection = getInputSelection(x);
						var startPos = selection.start;
						var endPos = selection.end;
						x.value = x.value.substring(0, startPos) + key + x.value.substring(endPos, x.value.length);
						maskAndPosition(x, startPos + 1);
						markAsDirty();
						return false;
					}
				}

				function keydownEvent(e) {
					e = e||window.event;
					var k = e.charCode||e.keyCode||e.which;
					if (k == undefined) return false; //needed to handle an IE "special" event

					var x = input.get(0);
					var selection = getInputSelection(x);
					var startPos = selection.start;
					var endPos = selection.end;

					if (k==8) { // backspace key
						preventDefault(e);

						if(startPos == endPos){
							// Remove single character
							x.value = x.value.substring(0, startPos - 1) + x.value.substring(endPos, x.value.length);
							startPos = startPos - 1;
						} else {
							// Remove multiple characters
							x.value = x.value.substring(0, startPos) + x.value.substring(endPos, x.value.length);
						}
						maskAndPosition(x, startPos);
						markAsDirty();
						return false;
					} else if (k==9) { // tab key
						if(dirty) {
							$(this).change();
							clearDirt();
						}
						return true;
					} else if ( k==46 || k==63272 ) { // delete key (with special case for safari)
						preventDefault(e);
						if(x.selectionStart == x.selectionEnd){
							// Remove single character
							x.value = x.value.substring(0, startPos) + x.value.substring(endPos + 1, x.value.length);
						} else {
							//Remove multiple characters
							x.value = x.value.substring(0, startPos) + x.value.substring(endPos, x.value.length);
						}
						maskAndPosition(x, startPos);
						markAsDirty();
						return false;
					} else { // any other key
						return true;
					}
				}

				function focusEvent(e) {
					var mask = getDefaultMask();
					if (input.val() == mask) {
						input.val('');
					} else if (input.val()=='' && settings.defaultZero) {
						input.val(setSymbol(mask));
					} else {
						input.val(setSymbol(input.val()));
					}
					if (this.createTextRange) {
						var textRange = this.createTextRange();
						textRange.collapse(false); // set the cursor at the end of the input
						textRange.select();
					}
				}

				function blurEvent(e) {
					if ($.browser.msie) {
						keypressEvent(e);
					}

					if (input.val() == '' || input.val() == setSymbol(getDefaultMask()) || input.val() == settings.symbol) {
						if(!settings.allowZero) input.val('');
						else if (!settings.symbolStay) input.val(getDefaultMask());
						else input.val(setSymbol(getDefaultMask()));
					} else {
						if (!settings.symbolStay) input.val(input.val().replace(settings.symbol,''));
						else if (settings.symbolStay&&input.val()==settings.symbol) input.val(setSymbol(getDefaultMask()));
					}
				}

				function preventDefault(e) {
					if (e.preventDefault) { //standard browsers
						e.preventDefault();
					} else { // internet explorer
						e.returnValue = false
					}
				}

				function maskAndPosition(x, startPos) {
					var originalLen = input.val().length;
					input.val(maskValue(x.value));
					var newLen = input.val().length;
					startPos = startPos - (originalLen - newLen);
					setCursorPosition(input, startPos);
				}

				function mask(){
					var value = input.val();
					input.val(maskValue(value));
				}

				function maskValue(v) {
					v = v.replace(settings.symbol, '');

					var strCheck = '0123456789';
					var len = v.length;
					var a = '', t = '', neg='';

					if(len != 0 && v.charAt(0)=='-'){
						v = v.replace('-','');
						if(settings.allowNegative){
							neg = '-';
						}
					}

					if (len==0) {
						if (!settings.defaultZero) return t;
						t = '0.00';
					}

					for (var i = 0; i<len; i++) {
						if ((v.charAt(i)!='0') && (v.charAt(i)!=settings.decimal)) break;
					}

					for (; i < len; i++) {
						if (strCheck.indexOf(v.charAt(i))!=-1) a+= v.charAt(i);
					}
					var n = parseFloat(a);

					n = isNaN(n) ? 0 : n/Math.pow(10,settings.precision);
					t = n.toFixed(settings.precision);

					i = settings.precision == 0 ? 0 : 1;
					var p, d = (t=t.split('.'))[i].substr(0,settings.precision);
					for (p = (t=t[0]).length; (p-=3)>=1;) {
						t = t.substr(0,p)+settings.thousands+t.substr(p);
					}

					return (settings.precision>0)
					? setSymbol(neg+t+settings.decimal+d+Array((settings.precision+1)-d.length).join(0))
					: setSymbol(neg+t);
				}

				function getDefaultMask() {
					var n = parseFloat('0')/Math.pow(10,settings.precision);
					return (n.toFixed(settings.precision)).replace(new RegExp('\\.','g'),settings.decimal);
				}

				function setSymbol(v) {
					if (settings.showSymbol) {
						if (v.substr(0, settings.symbol.length) != settings.symbol) return settings.symbol+v;
					}
					return v;
				}

				function changeSign(i){
					if (settings.allowNegative) {
						var vic = i.val();
						if (i.val()!='' && i.val().charAt(0)=='-'){
							return i.val().replace('-','');
						} else{
							return '-'+i.val();
						}
					} else {
						return i.val();
					}
				}

				function setCursorPosition(input, pos) {
					// I'm not sure if we need to jqueryfy input
					$(input).each(function(index, elem) {
						if (elem.setSelectionRange) {
							elem.focus();
							elem.setSelectionRange(pos, pos);
						} else if (elem.createTextRange) {
							var range = elem.createTextRange();
							range.collapse(true);
							range.moveEnd('character', pos);
							range.moveStart('character', pos);
							range.select();
						}
					});
					return this;
				};

				function getInputSelection(el) {
					var start = 0, end = 0, normalizedValue, range, textInputRange, len, endRange;

					if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
						start = el.selectionStart;
						end = el.selectionEnd;
					} else {
						range = document.selection.createRange();

						if (range && range.parentElement() == el) {
							len = el.value.length;
							normalizedValue = el.value.replace(/\r\n/g, "\n");

							// Create a working TextRange that lives only in the input
							textInputRange = el.createTextRange();
							textInputRange.moveToBookmark(range.getBookmark());

							// Check if the start and end of the selection are at the very end
							// of the input, since moveStart/moveEnd doesn't return what we want
							// in those cases
							endRange = el.createTextRange();
							endRange.collapse(false);

							if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
								start = end = len;
							} else {
								start = -textInputRange.moveStart("character", -len);
								start += normalizedValue.slice(0, start).split("\n").length - 1;

								if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
									end = len;
								} else {
									end = -textInputRange.moveEnd("character", -len);
									end += normalizedValue.slice(0, end).split("\n").length - 1;
								}
							}
						}
					}

					return {
						start: start,
						end: end
					};
				} // getInputSelection

				if (!input.attr("readonly")){
					input.unbind('.maskMoney');
					input.bind('keypress.maskMoney', keypressEvent);
					input.bind('keydown.maskMoney', keydownEvent);
					input.bind('blur.maskMoney', blurEvent);
					input.bind('focus.maskMoney', focusEvent);
					input.bind('mask.maskMoney', mask);
				}
			})
		}
	}

	$.fn.maskMoney = function(method) {
		if ( methods[method] ) {
			return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
		} else if ( typeof method === 'object' || ! method ) {
			return methods.init.apply( this, arguments );
		} else {
			$.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
		}
	};
})(jQuery);
<|endoftext|>


<commit_before>import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { bindActions, mapStateToProps } from '../stores';
import * as actions from '../actions/main';
import Page from './Page';
import SideMenu from './SideMenu';
import PageContent from './PageContent';

// eslint-disable-next-line
class Main extends React.PureComponent {
  render() {
    const menu = [{
      to: { pathname: '/about' },
      label: 'About this repo',
    }, {
      to: '/libraries',
      label: 'Libraries',
    }, {
      to: '/extend',
      label: 'How to extend from this repo',
    }, {
      to: '/contact',
      label: 'Contact',
    }];

    return (
      <Page>
        <SideMenu menu={menu} />
        <PageContent>{this.props.children}</PageContent>
      </Page>
    );
  }
}

Main.defaultProps = {
  children: null,
};

Main.propTypes = {
  // eslint-disable-next-line
  actions: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
  // eslint-disable-next-line
  store: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
  children: PropTypes.oneOfType([
    PropTypes.object,
    PropTypes.array,
  ]), // eslint-disable-line react/forbid-prop-types
};

export default connect(mapStateToProps('main'), bindActions(actions))(Main);
<commit_msg>add link to home<commit_after>import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { bindActions, mapStateToProps } from '../stores';
import * as actions from '../actions/main';
import Page from './Page';
import SideMenu from './SideMenu';
import PageContent from './PageContent';

// eslint-disable-next-line
class Main extends React.PureComponent {
  render() {
    const menu = [{
      to: { pathname: '/' },
      label: 'Home',
    }, {
      to: { pathname: '/about' },
      label: 'About this repo',
    }, {
      to: '/libraries',
      label: 'Libraries',
    }, {
      to: '/extend',
      label: 'How to extend from this repo',
    }, {
      to: '/contact',
      label: 'Contact',
    }];

    return (
      <Page>
        <SideMenu menu={menu} />
        <PageContent>{this.props.children}</PageContent>
      </Page>
    );
  }
}

Main.defaultProps = {
  children: null,
};

Main.propTypes = {
  // eslint-disable-next-line
  actions: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
  // eslint-disable-next-line
  store: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
  children: PropTypes.oneOfType([
    PropTypes.object,
    PropTypes.array,
  ]), // eslint-disable-line react/forbid-prop-types
};

export default connect(mapStateToProps('main'), bindActions(actions))(Main);
<|endoftext|>


<commit_before>/* -*- mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */

(function(){
  var $ = jQuery;

  $.microdata = {};

  // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-time-string
  function validTimeStringLength(s) {
    var m = /^(\d\d):(\d\d)(:(\d\d)(\.\d+)?)?/.exec(s);
    if (m && m[1]<=23 && m[2]<=59 && (!m[4] || m[4]<=59))
      return m[0].length;
    return 0;
  }

  function isValidTimeString(s) {
    return s && validTimeStringLength(s) == s.length;
  }

  // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#number-of-days-in-month-month-of-year-year
  function daysInMonth(year, month) {
    if (month==1 || month==3 || month==5 || month==7 ||
        month==8 || month==10 || month==12) {
      return 31;
    } else if (month==4 || month==6 || month==9 || month==11) {
      return 30;
    } else if (month == 2 && (year%400==0 || (year%4==0 && year%100!=0))) {
      return 29;
    } else {
      return 28;
    }
  }

  // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-date-string
  function validDateStringLength(s) {
    var m = /^(\d{4,})-(\d\d)-(\d\d)/.exec(s);
    if (m && m[1]>=1 && m[2]>=1 && m[2]<=12 && m[3]>=1 && m[3]<=daysInMonth(m[1],m[2]))
      return m[0].length;
    return 0;
  }

  function isValidDateString(s) {
    return s && validDateStringLength(s) == s.length;
  }

  // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-global-date-and-time-string
  function isValidGlobalDateAndTimeString(s) {
    var skip = validDateStringLength(s);
    if (skip && s[skip] == 'T') {
      s = s.substr(skip+1);
      skip = validTimeStringLength(s);
      if (skip) {
        s = s.substr(skip);
        if (s == 'Z')
          return true;
        var m = /^[+-](\d\d):(\d\d)$/.exec(s);
        if (m && m[1]<=23 && m[2]<=59)
          return true;
      }
    }
    return false;
  }

  $.microdata.isValidGlobalDateAndTimeString = isValidGlobalDateAndTimeString;
  $.microdata.isValidDateString = isValidDateString;

  function splitTokens(s) {
    if (s && /\S/.test(s))
      return s.replace(/^\s+|\s+$/g,'').split(/\s+/);
    return [];
  }

  function getItems(types) {
    var doc = this[0];
    if (doc.getItems)
      return $(types ? doc.getItems(types) : doc.getItems());
    var selector = $.map(splitTokens(types), function(t) {
      return '[itemtype~="'+t.replace(/"/g, '\\"')+'"]';
    }).join(',') || '*';
    // filter results to only match top-level items
    // because [attr] selector doesn't work in IE we have to
    // filter the elements. http://dev.jquery.com/ticket/5637
    return $(selector, this).filter(function() {
      return (this.getAttribute('itemscope') != null &&
              this.getAttribute('itemprop') == null);
    });
  }

  function resolve(url) {
    if (!url)
      return '';
    var img = document.createElement('img');
    img.setAttribute('src', url);
    return img.src;
  }

  function tokenList(attr) {
    return function() {
      return $(splitTokens(this.attr(attr)));
    };
  }

  function itemValue() {
    var elm = this[0];
    if (this.attr('itemprop') === undefined)
      return null;
    if (this.itemScope()) {
      return elm; // or a new jQuery object?
    }
    switch (elm.tagName.toUpperCase()) {
    case 'META':
      return this.attr('content') || '';
    case 'AUDIO':
    case 'EMBED':
    case 'IFRAME':
    case 'IMG':
    case 'SOURCE':
    case 'TRACK':
    case 'VIDEO':
      return resolve(this.attr('src'));
    case 'A':
    case 'AREA':
    case 'LINK':
      return resolve(this.attr('href'));
    case 'OBJECT':
      return resolve(this.attr('data'));
    case 'TIME':
      var datetime = this.attr('datetime');
      if (!(datetime === undefined))
        return datetime;
    default:
      return this.text();
    }
  }

  function properties(name) {
    // Find all elements that add properties to the item, optionally
    // filtered by a property name. Look in the subtrees rooted at the
    // item itself and any itemref'd elements. An item can never have
    // itself as a property, but circular reference is possible.

    var props = [];

    function crawl(root) {
      var toTraverse = [root];

      function traverse(node) {
        for (var i = 0; i < toTraverse.length; i++) {
          if (toTraverse[i] == node)
            toTraverse.splice(i--, 1);
        }
        var $node = $(node);
        if (node != root) {
          var $names = $node.itemProp();
          if ($names.length) {
            if (!name || $.inArray(name, $names.toArray()) != -1)
              props.push(node);
          }
          if ($node.itemScope())
            return;
        }
        $node.children().each(function() {
          traverse(this);
        });
      }

      var context = root;
      while (context.parentNode)
        context = context.parentNode;
      $(root).itemRef().each(function(i, id) {
        var $ref = $('#'+id, context);
        if ($ref.length)
          toTraverse.push($ref[0]);
      });
      $.unique(toTraverse);

      while (toTraverse.length) {
        traverse(toTraverse[0]);
      }
    }

    if (this.itemScope())
      crawl(this[0]);

    // properties are already sorted in tree order
    return $(props);
  }

  // feature detection to use native support where available
  var t = $('<div itemscope itemtype="type" itemid="id" itemprop="prop" itemref="ref">')[0];

  $.fn.extend({
    items: getItems,
    itemScope: t.itemScope ? function() {
      return this[0].itemScope;
    } : function () {
      return this.attr('itemscope') != undefined;
    },
    itemType: t.itemType ? function() {
      return this[0].itemType;
    } : function () {
      return this.attr('itemtype') || '';
    },
    itemId: t.itemId ? function() {
      return this[0].itemId;
    } : function () {
      return resolve(this.attr('itemid'));
    },
    itemProp: t.itemProp && t.itemProp.length ? function() {
      return $(this[0].itemProp);
    } : tokenList('itemprop'),
    itemRef: t.itemRef && t.itemRef.length ? function() {
      return $(this[0].itemRef);
    } : tokenList('itemref'),
    itemValue: t.itemValue ? function() {
      return this[0].itemValue;
    } : itemValue,
    properties: t.properties && t.properties.namedItem ? function(name) {
      return $(name ? this[0].properties.namedItem(name) : this[0].properties);
    } : properties
  });
})();
<commit_msg>punctuation<commit_after>/* -*- mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */

(function(){
  var $ = jQuery;

  $.microdata = {};

  // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-time-string
  function validTimeStringLength(s) {
    var m = /^(\d\d):(\d\d)(:(\d\d)(\.\d+)?)?/.exec(s);
    if (m && m[1]<=23 && m[2]<=59 && (!m[4] || m[4]<=59))
      return m[0].length;
    return 0;
  }

  function isValidTimeString(s) {
    return s && validTimeStringLength(s) == s.length;
  }

  // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#number-of-days-in-month-month-of-year-year
  function daysInMonth(year, month) {
    if (month==1 || month==3 || month==5 || month==7 ||
        month==8 || month==10 || month==12) {
      return 31;
    } else if (month==4 || month==6 || month==9 || month==11) {
      return 30;
    } else if (month == 2 && (year%400==0 || (year%4==0 && year%100!=0))) {
      return 29;
    } else {
      return 28;
    }
  }

  // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-date-string
  function validDateStringLength(s) {
    var m = /^(\d{4,})-(\d\d)-(\d\d)/.exec(s);
    if (m && m[1]>=1 && m[2]>=1 && m[2]<=12 && m[3]>=1 && m[3]<=daysInMonth(m[1],m[2]))
      return m[0].length;
    return 0;
  }

  function isValidDateString(s) {
    return s && validDateStringLength(s) == s.length;
  }

  // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-global-date-and-time-string
  function isValidGlobalDateAndTimeString(s) {
    var skip = validDateStringLength(s);
    if (skip && s[skip] == 'T') {
      s = s.substr(skip+1);
      skip = validTimeStringLength(s);
      if (skip) {
        s = s.substr(skip);
        if (s == 'Z')
          return true;
        var m = /^[+-](\d\d):(\d\d)$/.exec(s);
        if (m && m[1]<=23 && m[2]<=59)
          return true;
      }
    }
    return false;
  }

  $.microdata.isValidGlobalDateAndTimeString = isValidGlobalDateAndTimeString;
  $.microdata.isValidDateString = isValidDateString;

  function splitTokens(s) {
    if (s && /\S/.test(s))
      return s.replace(/^\s+|\s+$/g,'').split(/\s+/);
    return [];
  }

  function getItems(types) {
    var doc = this[0];
    if (doc.getItems)
      return $(types ? doc.getItems(types) : doc.getItems());
    var selector = $.map(splitTokens(types), function(t) {
      return '[itemtype~="'+t.replace(/"/g, '\\"')+'"]';
    }).join(',') || '*';
    // filter results to only match top-level items.
    // because [attr] selector doesn't work in IE we have to
    // filter the elements. http://dev.jquery.com/ticket/5637
    return $(selector, this).filter(function() {
      return (this.getAttribute('itemscope') != null &&
              this.getAttribute('itemprop') == null);
    });
  }

  function resolve(url) {
    if (!url)
      return '';
    var img = document.createElement('img');
    img.setAttribute('src', url);
    return img.src;
  }

  function tokenList(attr) {
    return function() {
      return $(splitTokens(this.attr(attr)));
    };
  }

  function itemValue() {
    var elm = this[0];
    if (this.attr('itemprop') === undefined)
      return null;
    if (this.itemScope()) {
      return elm; // or a new jQuery object?
    }
    switch (elm.tagName.toUpperCase()) {
    case 'META':
      return this.attr('content') || '';
    case 'AUDIO':
    case 'EMBED':
    case 'IFRAME':
    case 'IMG':
    case 'SOURCE':
    case 'TRACK':
    case 'VIDEO':
      return resolve(this.attr('src'));
    case 'A':
    case 'AREA':
    case 'LINK':
      return resolve(this.attr('href'));
    case 'OBJECT':
      return resolve(this.attr('data'));
    case 'TIME':
      var datetime = this.attr('datetime');
      if (!(datetime === undefined))
        return datetime;
    default:
      return this.text();
    }
  }

  function properties(name) {
    // Find all elements that add properties to the item, optionally
    // filtered by a property name. Look in the subtrees rooted at the
    // item itself and any itemref'd elements. An item can never have
    // itself as a property, but circular reference is possible.

    var props = [];

    function crawl(root) {
      var toTraverse = [root];

      function traverse(node) {
        for (var i = 0; i < toTraverse.length; i++) {
          if (toTraverse[i] == node)
            toTraverse.splice(i--, 1);
        }
        var $node = $(node);
        if (node != root) {
          var $names = $node.itemProp();
          if ($names.length) {
            if (!name || $.inArray(name, $names.toArray()) != -1)
              props.push(node);
          }
          if ($node.itemScope())
            return;
        }
        $node.children().each(function() {
          traverse(this);
        });
      }

      var context = root;
      while (context.parentNode)
        context = context.parentNode;
      $(root).itemRef().each(function(i, id) {
        var $ref = $('#'+id, context);
        if ($ref.length)
          toTraverse.push($ref[0]);
      });
      $.unique(toTraverse);

      while (toTraverse.length) {
        traverse(toTraverse[0]);
      }
    }

    if (this.itemScope())
      crawl(this[0]);

    // properties are already sorted in tree order
    return $(props);
  }

  // feature detection to use native support where available
  var t = $('<div itemscope itemtype="type" itemid="id" itemprop="prop" itemref="ref">')[0];

  $.fn.extend({
    items: getItems,
    itemScope: t.itemScope ? function() {
      return this[0].itemScope;
    } : function () {
      return this.attr('itemscope') != undefined;
    },
    itemType: t.itemType ? function() {
      return this[0].itemType;
    } : function () {
      return this.attr('itemtype') || '';
    },
    itemId: t.itemId ? function() {
      return this[0].itemId;
    } : function () {
      return resolve(this.attr('itemid'));
    },
    itemProp: t.itemProp && t.itemProp.length ? function() {
      return $(this[0].itemProp);
    } : tokenList('itemprop'),
    itemRef: t.itemRef && t.itemRef.length ? function() {
      return $(this[0].itemRef);
    } : tokenList('itemref'),
    itemValue: t.itemValue ? function() {
      return this[0].itemValue;
    } : itemValue,
    properties: t.properties && t.properties.namedItem ? function(name) {
      return $(name ? this[0].properties.namedItem(name) : this[0].properties);
    } : properties
  });
})();
<|endoftext|>


<commit_before>/*global define */
/*jslint
 white: true, browser: true
 */
define([
    'kb/common/pluginManager',
    'kb/common/dom',
    'kb/common/messenger',
    'kb/widget/widgetMount',
    'kb/common/props',
    'kb/common/asyncQueue',
    'kb/common/appServiceManager'
], function (
    pluginManagerFactory,
    dom,
    messengerFactory,
    widgetMountFactory,
    props,
    asyncQueue,
    AppServiceManager
    )
{
    'use strict';

    var moduleVersion = '0.0.1';

    function factory(config) {
        var pluginManager,
            serviceConfig = config.serviceConfig,
            clientConfig = config.clientConfig,
            clientConfigProps = props.make({data: clientConfig}),
            rootNode;

        // quick hack:
        clientConfig.services = serviceConfig.services;

        function getConfig(prop, defaultValue) {
            return clientConfigProps.getItem(prop, defaultValue);
        }
        function hasConfig(prop) {
            return clientConfigProps.hasItem(prop);
        }

        // Events

        // Our own events
        var messenger = messengerFactory.make();
        function receive(channel, message, fun) {
            return rcv({
                channel: channel,
                message: message,
                handler: fun
            });
        }
        // The "short" versions of the message functions just use the raw
        // messenger api, which expects an object argument.
        function rcv(spec) {
            return messenger.receive(spec);
        }
        function urcv(spec) {
            return messenger.unreceive(spec);
        }
        function snd(spec) {
            return messenger.send(spec);
        }

        // The friendlier more verbose functions take explicit arguments and
        // packge them up into the messenger api format.
        function send(channel, message, data) {
            return snd({
                channel: channel,
                message: message,
                data: data
            });
        }
        function drop(spec) {
            urcv(spec);
        }
        function sendp(channel, message, data) {
            return messenger.sendPromise({
                channel: channel,
                message: message,
                data: data
            });
        }

        // Plugins
        function installPlugins(plugins) {
            return pluginManager.installPlugins(plugins);
        }

        // Services for plugins

        function setRootNode(selector) {
            rootNode = dom.qs(selector);
            if (!rootNode) {
                throw new Error('Cannot set root node for selector ' + selector);
            }

        }
        setRootNode(config.nodes.root.selector);

        var rootMount;
        function mountRootWidget(widgetId, runtime) {
            if (!rootNode) {
                throw new Error('Cannot set root widget without a root node');
            }
            if (!rootMount) {
                // create the root mount.
                rootMount = widgetMountFactory.make({
                    node: rootNode,
                    runtime: runtime
                });

            }
            // ask it to load a widget.
            return rootMount.mountWidget(widgetId);
        }

        var renderQueue = asyncQueue.make();

        var appServiceManager = AppServiceManager.make();

        function proxyMethod(obj, method, args) {
            if (!obj[method]) {
                throw {
                    name: 'UndefinedMethod',
                    message: 'The requested method "' + method + '" does not exist on this object',
                    suggestion: 'This is a developer problem, not your fault'
                };
            }
            return obj[method].apply(obj, args);
        }

        function navigate(path) {
            send('app', 'navigate', path);
        }

        var api = {
            getConfig: getConfig,
            config: getConfig,
            hasConfig: hasConfig,
            // Session
            installPlugins: installPlugins,
            send: send,
            sendp: sendp,
            recv: receive,
            drop: drop,
            snd: snd,
            rcv: rcv,
            urcv: urcv,
            // navigation
            navigate: navigate,
            // Services
            addService: function () {
                return proxyMethod(appServiceManager, 'addService', arguments);
            },
            loadService: function () {
                return proxyMethod(appServiceManager, 'loadService', arguments);
            },
            getService: function () {
                return proxyMethod(appServiceManager, 'getService', arguments);
            },
            service: function () {
                return proxyMethod(appServiceManager, 'getService', arguments);
            },
            hasService: function () {
                return proxyMethod(appServiceManager, 'hasService', arguments);
            },
            dumpServices: function () {
                return proxyMethod(appServiceManager, 'dumpServices', arguments);
            }
        };

        function begin() {
            // Register service handlers.
            appServiceManager.addService('session', {
                runtime: api,
                cookieName: 'kbase_session',
                extraCookieNames: ['kbase_narr_session'],
                loginUrl: serviceConfig.services.login.url,
                cookieMaxAge: clientConfig.ui.constants.session_max_age

            });
            appServiceManager.addService('heartbeat', {
                runtime: api,
                interval: 500
            });
            appServiceManager.addService('route', {
                runtime: api,
                // notFoundRoute: {redirect: {path: 'message/notfound'}},
                defaultRoute: {redirect: {path: 'dashboard'}}
            });
            appServiceManager.addService('menu', {
                runtime: api,
                menus: config.menus
            });
            appServiceManager.addService('widget', {
                runtime: api
            });
            appServiceManager.addService('service', {
                runtime: api
            });
            appServiceManager.addService('data', {
                runtime: api
            });
            appServiceManager.addService('type', {
                runtime: api
            });
            appServiceManager.addService('userprofile', {
                runtime: api
            });

            pluginManager = pluginManagerFactory.make({
                runtime: api
            });

            // Behavior
            // There are not too many global behaviors, and perhaps there should
            // even fewer or none. Most behavior is within services or
            // active widgets themselves.
            receive('session', 'loggedout', function () {
                send('app', 'navigate', 'goodbye');
            });

            receive('app', 'route-not-found', function (info) {
                // alert('help, the route was not found!: ' + route.path);
                send('app', 'navigate', {
                    path: 'message/error/notfound',
                    params: {
                        info: JSON.stringify(info)
                    }
                });
            });

            // UI should be a service...
            // NB this was never developed beyond this stage, and should
            // probably be hunted down and removed.
            receive('ui', 'render', function (arg) {
                renderQueue.addItem({
                    onRun: function () {
                        if (arg.node) {
                            arg.node.innerHTML = arg.content;
                        } else {
                            console.error('ERROR');
                            console.error('Invalid node for ui/render');
                        }
                    }
                });
            });

            // ROUTING

            return appServiceManager.loadServices()
                .then(function () {
                    return installPlugins(config.plugins);
                })
                .then(function () {
                    return appServiceManager.startServices();
                })
                .then(function () {
                    return mountRootWidget('root', api);
                })
                .then(function () {
                    // kick off handling of the current route.
                    send('app', 'do-route');
                    return api;
                });
        }
        return {
            begin: begin
        };
    }
    return {
        run: function (config) {
            var runtime = factory(config);
            return runtime.begin();
        },
        version: function () {
            return moduleVersion;
        }
    };
});<commit_msg>incorporate entire services config into runtime config (was just "services")<commit_after>/*global define */
/*jslint
 white: true, browser: true
 */
define([
    'kb/common/pluginManager',
    'kb/common/dom',
    'kb/common/messenger',
    'kb/widget/widgetMount',
    'kb/common/props',
    'kb/common/asyncQueue',
    'kb/common/appServiceManager'
], function (
    pluginManagerFactory,
    dom,
    messengerFactory,
    widgetMountFactory,
    props,
    asyncQueue,
    AppServiceManager
    )
{
    'use strict';

    var moduleVersion = '0.0.1';

    function factory(config) {
        var pluginManager,
            serviceConfig = config.serviceConfig,
            clientConfig = config.clientConfig,
            clientConfigProps = props.make({data: clientConfig}),
            rootNode;

        // quick hack:
        Object.keys(serviceConfig).forEach(function (key) {
            clientConfig[key] = serviceConfig[key];
        });

        function getConfig(prop, defaultValue) {
            return clientConfigProps.getItem(prop, defaultValue);
        }
        function hasConfig(prop) {
            return clientConfigProps.hasItem(prop);
        }

        // Events

        // Our own events
        var messenger = messengerFactory.make();
        function receive(channel, message, fun) {
            return rcv({
                channel: channel,
                message: message,
                handler: fun
            });
        }
        // The "short" versions of the message functions just use the raw
        // messenger api, which expects an object argument.
        function rcv(spec) {
            return messenger.receive(spec);
        }
        function urcv(spec) {
            return messenger.unreceive(spec);
        }
        function snd(spec) {
            return messenger.send(spec);
        }

        // The friendlier more verbose functions take explicit arguments and
        // packge them up into the messenger api format.
        function send(channel, message, data) {
            return snd({
                channel: channel,
                message: message,
                data: data
            });
        }
        function drop(spec) {
            urcv(spec);
        }
        function sendp(channel, message, data) {
            return messenger.sendPromise({
                channel: channel,
                message: message,
                data: data
            });
        }

        // Plugins
        function installPlugins(plugins) {
            return pluginManager.installPlugins(plugins);
        }

        // Services for plugins

        function setRootNode(selector) {
            rootNode = dom.qs(selector);
            if (!rootNode) {
                throw new Error('Cannot set root node for selector ' + selector);
            }

        }
        setRootNode(config.nodes.root.selector);

        var rootMount;
        function mountRootWidget(widgetId, runtime) {
            if (!rootNode) {
                throw new Error('Cannot set root widget without a root node');
            }
            if (!rootMount) {
                // create the root mount.
                rootMount = widgetMountFactory.make({
                    node: rootNode,
                    runtime: runtime
                });

            }
            // ask it to load a widget.
            return rootMount.mountWidget(widgetId);
        }

        var renderQueue = asyncQueue.make();

        var appServiceManager = AppServiceManager.make();

        function proxyMethod(obj, method, args) {
            if (!obj[method]) {
                throw {
                    name: 'UndefinedMethod',
                    message: 'The requested method "' + method + '" does not exist on this object',
                    suggestion: 'This is a developer problem, not your fault'
                };
            }
            return obj[method].apply(obj, args);
        }

        function navigate(path) {
            send('app', 'navigate', path);
        }

        var api = {
            getConfig: getConfig,
            config: getConfig,
            hasConfig: hasConfig,
            // Session
            installPlugins: installPlugins,
            send: send,
            sendp: sendp,
            recv: receive,
            drop: drop,
            snd: snd,
            rcv: rcv,
            urcv: urcv,
            // navigation
            navigate: navigate,
            // Services
            addService: function () {
                return proxyMethod(appServiceManager, 'addService', arguments);
            },
            loadService: function () {
                return proxyMethod(appServiceManager, 'loadService', arguments);
            },
            getService: function () {
                return proxyMethod(appServiceManager, 'getService', arguments);
            },
            service: function () {
                return proxyMethod(appServiceManager, 'getService', arguments);
            },
            hasService: function () {
                return proxyMethod(appServiceManager, 'hasService', arguments);
            },
            dumpServices: function () {
                return proxyMethod(appServiceManager, 'dumpServices', arguments);
            }
        };

        function begin() {
            // Register service handlers.
            appServiceManager.addService('session', {
                runtime: api,
                cookieName: 'kbase_session',
                extraCookieNames: ['kbase_narr_session'],
                loginUrl: serviceConfig.services.login.url,
                cookieMaxAge: clientConfig.ui.constants.session_max_age

            });
            appServiceManager.addService('heartbeat', {
                runtime: api,
                interval: 500
            });
            appServiceManager.addService('route', {
                runtime: api,
                // notFoundRoute: {redirect: {path: 'message/notfound'}},
                defaultRoute: {redirect: {path: 'dashboard'}}
            });
            appServiceManager.addService('menu', {
                runtime: api,
                menus: config.menus
            });
            appServiceManager.addService('widget', {
                runtime: api
            });
            appServiceManager.addService('service', {
                runtime: api
            });
            appServiceManager.addService('data', {
                runtime: api
            });
            appServiceManager.addService('type', {
                runtime: api
            });
            appServiceManager.addService('userprofile', {
                runtime: api
            });

            pluginManager = pluginManagerFactory.make({
                runtime: api
            });

            // Behavior
            // There are not too many global behaviors, and perhaps there should
            // even fewer or none. Most behavior is within services or
            // active widgets themselves.
            receive('session', 'loggedout', function () {
                send('app', 'navigate', 'goodbye');
            });

            receive('app', 'route-not-found', function (info) {
                // alert('help, the route was not found!: ' + route.path);
                send('app', 'navigate', {
                    path: 'message/error/notfound',
                    params: {
                        info: JSON.stringify(info)
                    }
                });
            });

            // UI should be a service...
            // NB this was never developed beyond this stage, and should
            // probably be hunted down and removed.
            receive('ui', 'render', function (arg) {
                renderQueue.addItem({
                    onRun: function () {
                        if (arg.node) {
                            arg.node.innerHTML = arg.content;
                        } else {
                            console.error('ERROR');
                            console.error('Invalid node for ui/render');
                        }
                    }
                });
            });

            // ROUTING

            return appServiceManager.loadServices()
                .then(function () {
                    return installPlugins(config.plugins);
                })
                .then(function () {
                    return appServiceManager.startServices();
                })
                .then(function () {
                    return mountRootWidget('root', api);
                })
                .then(function () {
                    // kick off handling of the current route.
                    send('app', 'do-route');
                    return api;
                });
        }
        return {
            begin: begin
        };
    }
    return {
        run: function (config) {
            var runtime = factory(config);
            return runtime.begin();
        },
        version: function () {
            return moduleVersion;
        }
    };
});<|endoftext|>


<commit_before>import React, { Component, createElement } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { IconChevronUpSmallOutline, IconChevronDownSmallOutline, IconWarningBadgedSmallFilled } from '@teamleader/ui-icons';
import InputMetaPropTypes from './InputMetaPropTypes';
import Counter from '../counter';
import theme from './theme.css';

export default class Input extends Component {
  static propTypes = {
    bold: PropTypes.bool,
    className: PropTypes.string,
    counter: PropTypes.number,
    disabled: PropTypes.bool,
    icon: PropTypes.oneOfType([PropTypes.func, PropTypes.element]),
    iconPlacement: PropTypes.oneOf(['left', 'right']),
    id: PropTypes.string,
    meta: InputMetaPropTypes,
    onBlur: PropTypes.func,
    onChange: PropTypes.func,
    onFocus: PropTypes.func,
    placeholder: PropTypes.string,
    readOnly: PropTypes.bool,
    size: PropTypes.oneOf(['small', 'medium', 'large']),
    step: PropTypes.number,
    type: PropTypes.string,
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  };

  static defaultProps = {
    iconPlacement: 'left',
    disabled: false,
    placeholder: '',
    readOnly: false,
    size: 'medium',
    step: 1,
  };

  constructor(props) {
    super(props);

    this.isNumberInput = Boolean(props.type === 'number');
    this.handleChange = ::this.onChange;
    this.handleIncreaseValue = ::this.increaseValue;
    this.handleDecreaseValue = ::this.decreaseValue;

    this.state = {
      value: this.isNumberInput ? Number(props.value) || '' : props.value || '',
    };
  }

  componentWillUpdate(props, state) {
    if (state.value) {
      this.props.onChange(state.value);
    }
  }

  onChange(event) {
    const value = event.target.value;

    this.setState(() => ({
      value: this.isNumberInput ? Number(value) : value,
    }));
  }

  increaseValue() {
    this.setState((previousState, props) => ({
      value: previousState.value ? previousState.value + props.step : props.step,
    }));
  }

  decreaseValue() {
    this.setState((previousState, props) => ({
      value: previousState.value ? previousState.value - props.step : -props.step,
    }));
  }

  renderInput() {
    const { bold, disabled, id, onBlur, onFocus, placeholder, readOnly, step, type } = this.props;
    const classNames = cx(theme['input'], {
      [theme['is-disabled']]: disabled,
      [theme['is-read-only']]: readOnly,
      [theme['is-bold']]: bold,
    });
    const props = {
      className: classNames,
      disabled: disabled,
      id,
      onBlur: onBlur,
      onChange: this.handleChange,
      onFocus: onFocus,
      placeholder,
      readOnly,
      step,
      type,
      value: this.state.value,
    };

    return <input {...props} />;
  }

  renderCounter() {
    if (this.props.counter) {
      return <Counter className={theme.counter} count={this.props.counter} color="ruby" size="small" />;
    }
  }

  renderSpinnerControls() {
    if (this.isNumberInput) {
      return (

          <button className={theme['spinner-up']} onClick={this.handleIncreaseValue}>
            <IconChevronUpSmallOutline />
          </button>
          <button className={theme['spinner-down']} onClick={this.handleDecreaseValue}>
            <IconChevronDownSmallOutline />
          </button>

      );
    }
  }

  renderError() {
    if (this.props.meta && this.props.meta.error) {
      return (

          <IconWarningBadgedSmallFilled /> {this.props.meta.error}

      );
    }
  }

  render() {
    const { className, counter, icon, iconPlacement, size, meta } = this.props;
    const classNames = cx(theme.wrapper, theme[`is-${size}`], className, {
      [theme[`has-icon-${iconPlacement}`]]: icon,
      [theme['has-counter']]: counter,
      [theme['has-errors']]: Boolean(meta && meta.error),
    });

    return (

          {icon &&
            createElement(icon, {
              className: theme.icon,
            })}

          {this.renderInput()}
          {this.renderCounter()}
          {this.renderSpinnerControls()}

        {this.renderError()}

    );
  }
}
<commit_msg>Prettier Linting™<commit_after>import React, { Component, createElement } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import {
  IconChevronUpSmallOutline,
  IconChevronDownSmallOutline,
  IconWarningBadgedSmallFilled,
} from '@teamleader/ui-icons';
import InputMetaPropTypes from './InputMetaPropTypes';
import Counter from '../counter';
import theme from './theme.css';

export default class Input extends Component {
  static propTypes = {
    bold: PropTypes.bool,
    className: PropTypes.string,
    counter: PropTypes.number,
    disabled: PropTypes.bool,
    icon: PropTypes.oneOfType([PropTypes.func, PropTypes.element]),
    iconPlacement: PropTypes.oneOf(['left', 'right']),
    id: PropTypes.string,
    meta: InputMetaPropTypes,
    onBlur: PropTypes.func,
    onChange: PropTypes.func,
    onFocus: PropTypes.func,
    placeholder: PropTypes.string,
    readOnly: PropTypes.bool,
    size: PropTypes.oneOf(['small', 'medium', 'large']),
    step: PropTypes.number,
    type: PropTypes.string,
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  };

  static defaultProps = {
    iconPlacement: 'left',
    disabled: false,
    placeholder: '',
    readOnly: false,
    size: 'medium',
    step: 1,
  };

  constructor(props) {
    super(props);

    this.isNumberInput = Boolean(props.type === 'number');
    this.handleChange = ::this.onChange;
    this.handleIncreaseValue = ::this.increaseValue;
    this.handleDecreaseValue = ::this.decreaseValue;

    this.state = {
      value: this.isNumberInput ? Number(props.value) || '' : props.value || '',
    };
  }

  componentWillUpdate(props, state) {
    if (state.value) {
      this.props.onChange(state.value);
    }
  }

  onChange(event) {
    const value = event.target.value;

    this.setState(() => ({
      value: this.isNumberInput ? Number(value) : value,
    }));
  }

  increaseValue() {
    this.setState((previousState, props) => ({
      value: previousState.value ? previousState.value + props.step : props.step,
    }));
  }

  decreaseValue() {
    this.setState((previousState, props) => ({
      value: previousState.value ? previousState.value - props.step : -props.step,
    }));
  }

  renderInput() {
    const { bold, disabled, id, onBlur, onFocus, placeholder, readOnly, step, type } = this.props;
    const classNames = cx(theme['input'], {
      [theme['is-disabled']]: disabled,
      [theme['is-read-only']]: readOnly,
      [theme['is-bold']]: bold,
    });
    const props = {
      className: classNames,
      disabled: disabled,
      id,
      onBlur: onBlur,
      onChange: this.handleChange,
      onFocus: onFocus,
      placeholder,
      readOnly,
      step,
      type,
      value: this.state.value,
    };

    return <input {...props} />;
  }

  renderCounter() {
    if (this.props.counter) {
      return <Counter className={theme.counter} count={this.props.counter} color="ruby" size="small" />;
    }
  }

  renderSpinnerControls() {
    if (this.isNumberInput) {
      return (

          <button className={theme['spinner-up']} onClick={this.handleIncreaseValue}>
            <IconChevronUpSmallOutline />
          </button>
          <button className={theme['spinner-down']} onClick={this.handleDecreaseValue}>
            <IconChevronDownSmallOutline />
          </button>

      );
    }
  }

  renderError() {
    if (this.props.meta && this.props.meta.error) {
      return (

          <IconWarningBadgedSmallFilled /> {this.props.meta.error}

      );
    }
  }

  render() {
    const { className, counter, icon, iconPlacement, size, meta } = this.props;
    const classNames = cx(theme.wrapper, theme[`is-${size}`], className, {
      [theme[`has-icon-${iconPlacement}`]]: icon,
      [theme['has-counter']]: counter,
      [theme['has-errors']]: Boolean(meta && meta.error),
    });

    return (

          {icon &&
            createElement(icon, {
              className: theme.icon,
            })}

          {this.renderInput()}
          {this.renderCounter()}
          {this.renderSpinnerControls()}

        {this.renderError()}

    );
  }
}
<|endoftext|>


<commit_before>/**
 * XMLHttpRequest.js
 *
 * Copyright 2013, Moxiecode Systems AB
 * Released under GPL License.
 *
 * License: http://www.plupload.com/license
 * Contributing: http://www.plupload.com/contributing
 */

/*jshint smarttabs:true, undef:true, unused:true, latedef:true, curly:true, bitwise:true, scripturl:true, browser:true, laxcomma:true */
/*global define:true */

/**
@class moxie/runtime/html4/xhr/XMLHttpRequest
@private
*/
define("moxie/runtime/html4/xhr/XMLHttpRequest", [
	"moxie/runtime/html4/Runtime",
	"moxie/core/utils/Basic",
	"moxie/core/utils/Dom",
	"moxie/core/Exceptions",
	"moxie/core/utils/Events",
	"moxie/file/Blob",
	"moxie/xhr/FormData",
	"moxie/core/JSON"
], function(extensions, Basic, Dom, x, Events, Blob, FormData, parseJSON) {

	function XMLHttpRequest() {
		var _status, _response, _iframe;

		function cleanup(cb) {
			var target = this, uid, form, inputs, i, hasFile = false;

			if (!_iframe) {
				return;
			}

			uid = _iframe.id.replace(/_iframe$/, '');

			form = Dom.get(uid + '_form');
			if (form) {
				inputs = form.getElementsByTagName('input');
				i = inputs.length;

				while (i--) {
					switch (inputs[i].getAttribute('type')) {
						case 'hidden':
							inputs[i].parentNode.removeChild(inputs[i]);
							break;
						case 'file':
							hasFile = true; // flag the case for later
							break;
					}
				}
				inputs = [];

				if (!hasFile) { // we need to keep the form for sake of possible retries
					form.parentNode.removeChild(form);
				}
				form = null;
			}

			// without timeout, request is marked as canceled (in console)
			setTimeout(function() {
				Events.removeEvent(_iframe, 'load', target.uid);
				if (_iframe.parentNode) { // #382
					_iframe.parentNode.removeChild(_iframe);
				}

				// check if shim container has any other children, if - not, remove it as well
				var shimContainer = target.getRuntime().getShimContainer();
				if (!shimContainer.children.length) {
					shimContainer.parentNode.removeChild(shimContainer);
				}

				shimContainer = _iframe = null;
				cb();
			}, 1);
		}

		Basic.extend(this, {
			send: function(meta, data) {
				var target = this, I = target.getRuntime(), uid, form, input, blob;

				_status = _response = null;

				function createIframe() {
					var container = I.getShimContainer() || document.body
					, temp = document.createElement('div')
					;

					// IE 6 won't be able to set the name using setAttribute or iframe.name
					temp.innerHTML = '';
					_iframe = temp.firstChild;
					container.appendChild(_iframe);

					/* _iframe.onreadystatechange = function() {
						console.info(_iframe.readyState);
					};*/

					Events.addEvent(_iframe, 'load', function() { // _iframe.onload doesn't work in IE lte 8
						var el;

						try {
							el = _iframe.contentWindow.document || _iframe.contentDocument || window.frames[_iframe.id].document;

							// try to detect some standard error pages
							if (/^4\d{2}\s/.test(el.title) && el.getElementsByTagName('address').length) { // standard Apache style
								_status = el.title.replace(/^(\d+).*$/, '$1');
							} else {
								_status = 200;
								// get result
								_response = Basic.trim(el.body.innerHTML);

								target.trigger({
									type: 'uploadprogress',
									loaded: blob && blob.size || 1025,
									total: blob && blob.size || 1025
								});
							}
						} catch (ex) {
							// if response is sent with error code, iframe in IE gets redirected to res://ieframe.dll/http_x.htm
							// which obviously results to cross domain error (wtf?)
							_status = 404;
						}

						cleanup.call(target, function() {
							target.trigger('load');
						});
					}, target.uid);
				} // end createIframe

				// prepare data to be sent and convert if required
				if (data instanceof FormData && data.hasBlob()) {
					blob = data.getBlob();
					uid = blob.uid;
					input = Dom.get(uid);
					form = Dom.get(uid + '_form');
					if (!form) {
						throw new x.DOMException(x.DOMException.NOT_FOUND_ERR);
					}
				} else {
					uid = Basic.guid('uid_');

					form = document.createElement('form');
					form.setAttribute('id', uid + '_form');
					form.setAttribute('method', meta.method);
					form.setAttribute('enctype', 'multipart/form-data');
					form.setAttribute('encoding', 'multipart/form-data');
					form.setAttribute('target', uid + '_iframe');

					I.getShimContainer().appendChild(form);
				}

				if (data instanceof FormData) {
					data.each(function(value, name) {
						if (value instanceof Blob) {
							if (input) {
								input.setAttribute('name', name);
							}
						} else {
							var hidden = document.createElement('input');

							Basic.extend(hidden, {
								type : 'hidden',
								name : name,
								value : value
							});

							form.appendChild(hidden);
						}
					});
				}

				// set destination url
				form.setAttribute("action", meta.url);

				createIframe();
				form.submit();
				target.trigger('loadstart');
			},

			getStatus: function() {
				return _status;
			},

			getResponse: function(responseType) {
				if ('json' === responseType) {
					// strip off
..
 tags that might be enclosing the response
					if (Basic.typeOf(_response) === 'string') {
						return parseJSON(_response.replace(/^\s*
]*>/, '').replace(/<\/pre>\s*$/, ''));
					}
				} else if ('document' === responseType) {

				}
				return _response;
			},

			abort: function() {
				var target = this;

				if (_iframe && _iframe.contentWindow) {
					if (_iframe.contentWindow.stop) { // FireFox/Safari/Chrome
						_iframe.contentWindow.stop();
					} else if (_iframe.contentWindow.document.execCommand) { // IE
						_iframe.contentWindow.document.execCommand('Stop');
					} else {
						_iframe.src = "about:blank";
					}
				}

				cleanup.call(this, function() {
					// target.dispatchEvent('readystatechange');
					target.dispatchEvent('abort');
				});
			}
		});
	}

	return (extensions.XMLHttpRequest = XMLHttpRequest);
});<commit_msg>XHR, HTML4: Make sure we survive invalid json response.<commit_after>/**
 * XMLHttpRequest.js
 *
 * Copyright 2013, Moxiecode Systems AB
 * Released under GPL License.
 *
 * License: http://www.plupload.com/license
 * Contributing: http://www.plupload.com/contributing
 */

/*jshint smarttabs:true, undef:true, unused:true, latedef:true, curly:true, bitwise:true, scripturl:true, browser:true, laxcomma:true */
/*global define:true */

/**
@class moxie/runtime/html4/xhr/XMLHttpRequest
@private
*/
define("moxie/runtime/html4/xhr/XMLHttpRequest", [
	"moxie/runtime/html4/Runtime",
	"moxie/core/utils/Basic",
	"moxie/core/utils/Dom",
	"moxie/core/Exceptions",
	"moxie/core/utils/Events",
	"moxie/file/Blob",
	"moxie/xhr/FormData",
	"moxie/core/JSON"
], function(extensions, Basic, Dom, x, Events, Blob, FormData, parseJSON) {

	function XMLHttpRequest() {
		var _status, _response, _iframe;

		function cleanup(cb) {
			var target = this, uid, form, inputs, i, hasFile = false;

			if (!_iframe) {
				return;
			}

			uid = _iframe.id.replace(/_iframe$/, '');

			form = Dom.get(uid + '_form');
			if (form) {
				inputs = form.getElementsByTagName('input');
				i = inputs.length;

				while (i--) {
					switch (inputs[i].getAttribute('type')) {
						case 'hidden':
							inputs[i].parentNode.removeChild(inputs[i]);
							break;
						case 'file':
							hasFile = true; // flag the case for later
							break;
					}
				}
				inputs = [];

				if (!hasFile) { // we need to keep the form for sake of possible retries
					form.parentNode.removeChild(form);
				}
				form = null;
			}

			// without timeout, request is marked as canceled (in console)
			setTimeout(function() {
				Events.removeEvent(_iframe, 'load', target.uid);
				if (_iframe.parentNode) { // #382
					_iframe.parentNode.removeChild(_iframe);
				}

				// check if shim container has any other children, if - not, remove it as well
				var shimContainer = target.getRuntime().getShimContainer();
				if (!shimContainer.children.length) {
					shimContainer.parentNode.removeChild(shimContainer);
				}

				shimContainer = _iframe = null;
				cb();
			}, 1);
		}

		Basic.extend(this, {
			send: function(meta, data) {
				var target = this, I = target.getRuntime(), uid, form, input, blob;

				_status = _response = null;

				function createIframe() {
					var container = I.getShimContainer() || document.body
					, temp = document.createElement('div')
					;

					// IE 6 won't be able to set the name using setAttribute or iframe.name
					temp.innerHTML = '';
					_iframe = temp.firstChild;
					container.appendChild(_iframe);

					/* _iframe.onreadystatechange = function() {
						console.info(_iframe.readyState);
					};*/

					Events.addEvent(_iframe, 'load', function() { // _iframe.onload doesn't work in IE lte 8
						var el;

						try {
							el = _iframe.contentWindow.document || _iframe.contentDocument || window.frames[_iframe.id].document;

							// try to detect some standard error pages
							if (/^4\d{2}\s/.test(el.title) && el.getElementsByTagName('address').length) { // standard Apache style
								_status = el.title.replace(/^(\d+).*$/, '$1');
							} else {
								_status = 200;
								// get result
								_response = Basic.trim(el.body.innerHTML);

								target.trigger({
									type: 'uploadprogress',
									loaded: blob && blob.size || 1025,
									total: blob && blob.size || 1025
								});
							}
						} catch (ex) {
							// if response is sent with error code, iframe in IE gets redirected to res://ieframe.dll/http_x.htm
							// which obviously results to cross domain error (wtf?)
							_status = 404;
						}

						cleanup.call(target, function() {
							target.trigger('load');
						});
					}, target.uid);
				} // end createIframe

				// prepare data to be sent and convert if required
				if (data instanceof FormData && data.hasBlob()) {
					blob = data.getBlob();
					uid = blob.uid;
					input = Dom.get(uid);
					form = Dom.get(uid + '_form');
					if (!form) {
						throw new x.DOMException(x.DOMException.NOT_FOUND_ERR);
					}
				} else {
					uid = Basic.guid('uid_');

					form = document.createElement('form');
					form.setAttribute('id', uid + '_form');
					form.setAttribute('method', meta.method);
					form.setAttribute('enctype', 'multipart/form-data');
					form.setAttribute('encoding', 'multipart/form-data');
					form.setAttribute('target', uid + '_iframe');

					I.getShimContainer().appendChild(form);
				}

				if (data instanceof FormData) {
					data.each(function(value, name) {
						if (value instanceof Blob) {
							if (input) {
								input.setAttribute('name', name);
							}
						} else {
							var hidden = document.createElement('input');

							Basic.extend(hidden, {
								type : 'hidden',
								name : name,
								value : value
							});

							form.appendChild(hidden);
						}
					});
				}

				// set destination url
				form.setAttribute("action", meta.url);

				createIframe();
				form.submit();
				target.trigger('loadstart');
			},

			getStatus: function() {
				return _status;
			},

			getResponse: function(responseType) {
				if ('json' === responseType) {
					// strip off
..
 tags that might be enclosing the response
					if (Basic.typeOf(_response) === 'string') {
						try {
							return parseJSON(_response.replace(/^\s*
]*>/, '').replace(/<\/pre>\s*$/, ''));
						} catch (ex) {
							return null;
						}
					}
				} else if ('document' === responseType) {

				}
				return _response;
			},

			abort: function() {
				var target = this;

				if (_iframe && _iframe.contentWindow) {
					if (_iframe.contentWindow.stop) { // FireFox/Safari/Chrome
						_iframe.contentWindow.stop();
					} else if (_iframe.contentWindow.document.execCommand) { // IE
						_iframe.contentWindow.document.execCommand('Stop');
					} else {
						_iframe.src = "about:blank";
					}
				}

				cleanup.call(this, function() {
					// target.dispatchEvent('readystatechange');
					target.dispatchEvent('abort');
				});
			}
		});
	}

	return (extensions.XMLHttpRequest = XMLHttpRequest);
});<|endoftext|>