<commit_before>(function () {
    var ghostdown = function () {
        return [
            // ![] image syntax
            {
                type: 'lang',
                filter: function (text) {
                    var imageMarkdownRegex = /^(?:\{<(.*?)>\})?!(?:\[([^\n\]]*)\])(?:\(([^\n\]]*)\))?$/gim,
                        /* regex from isURL in node-validator. Yum! */
                        uriRegex = /^(?!mailto:)(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))|localhost)(?::\d{2,5})?(?:\/[^\s]*)?$/i,
                        pathRegex = /^(\/)?([^\/\0]+(\/)?)+$/i;

                    return text.replace(imageMarkdownRegex, function (match, key, alt, src) {
                        var result = "";

                        if (src && (src.match(uriRegex) || src.match(pathRegex))) {
                            result = '';
                        }
                        return '
' + result +
                               '
Add image of ' + alt + '
' +
                               '<input data-url="upload" class="js-fileupload main fileupload" type="file" name="uploadimage">' +
                               '
';
                    });
                }
            }
        ];
    };

    // Client-side export
    if (typeof window !== 'undefined' && window.Showdown && window.Showdown.extensions) {
        window.Showdown.extensions.ghostdown = ghostdown;
    }
    // Server-side export
    if (typeof module !== 'undefined') module.exports = ghostdown;
}());<commit_msg>Modified ghostdown markdown extension to allow for 4+ inline underscores<commit_after>(function () {
    var ghostdown = function () {
        return [
            // ![] image syntax
            {
                type: 'lang',
                filter: function (text) {
                    var imageMarkdownRegex = /^(?:\{<(.*?)>\})?!(?:\[([^\n\]]*)\])(?:\(([^\n\]]*)\))?$/gim,
                        /* regex from isURL in node-validator. Yum! */
                        uriRegex = /^(?!mailto:)(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))|localhost)(?::\d{2,5})?(?:\/[^\s]*)?$/i,
                        pathRegex = /^(\/)?([^\/\0]+(\/)?)+$/i;

                    return text.replace(imageMarkdownRegex, function (match, key, alt, src) {
                        var result = "";

                        if (src && (src.match(uriRegex) || src.match(pathRegex))) {
                            result = '';
                        }
                        return '
' + result +
                               '
Add image of ' + alt + '
' +
                               '<input data-url="upload" class="js-fileupload main fileupload" type="file" name="uploadimage">' +
                               '
';
                    });
                }
            },

            // 4 or more inline underscores e.g. Ghost rocks my _____!
            {
                type: 'lang',
                filter: function (text) {
                    return text.replace(/([^_\n\r])(_{4,})/g, function (match, prefix, underscores) {
                        return prefix + underscores.replace(/_/g, '_');
                    });
                }
            }
        ];
    };

    // Client-side export
    if (typeof window !== 'undefined' && window.Showdown && window.Showdown.extensions) {
        window.Showdown.extensions.ghostdown = ghostdown;
    }
    // Server-side export
    if (typeof module !== 'undefined') module.exports = ghostdown;
}());
<|endoftext|>


<commit_before>$(function() {
    if(!('getContext' in document.createElement('canvas'))) {
        alert('Sorry, it looks like your browser does not support canvas!');
        return false;
    }

    var url = 'http://localhost:8080';
    var socket = io.connect(url);

    var doc     = $(document),
        win     = $(window),
        canvas  = $('#paper'),
        ctx     = canvas[0].getContext('2d'),
        instructions = $('#instructions');

//--------- WebRTC------------------------------------------------
    var localStream, pc

        // get user media navigator setup
    navigator.getUserMedia = navigator.getUserMedia
                            || navigator.mozGetUserMedia
                            || navigator.webkitGetUserMedia;
    window.URL = window.URL
                || window.webkitURL
                || window.mozURL;
    var RTCPeerConnection = window.RTCPeerConnection
                        || window.webkitRTCPeerConnection
                        || window.mozRTCPeerConnection;

    var RTCIceCandidate = window.RTCIceCandidate
                    || window.webkitRTCIceCandidate
                    || window.mozRTCIceCandidate;

    var RTCSessionDescription = window.RTCSessionDescription
                            || window.webkitRTCSessionDescription
                            || window.mozRTCSessionDescription:

        // document elements
    var localVideo = document.getElementById('localVideo'),
        remoteVideo = document.getElementById('remoteVideo'),
        startButton = document.getElementById('start'),
        hangupButton = document.getElementById('hangup'),
        callButton = document.getElementById('call');

        //button setup
    startButton.disabled = false;
    startButton.onclick = start;
    callButton.disabled = true;
    callButton.onclick = call;
    hangupButton.disabled = true;
    hangupButton.onclick = hangup;
    var live = false;

        // constrants
    var constraints = {
        video   : true,
        audio   : false
    }

    function successCallback(localMediaStream) {
        localStream = localMediaStream;
        localVideo.src = window.URL.createObjectURL(localMediaStream);
        callButton.disabled = false;
        localVideo.play();
    }

    function failureCallback(err) {
        console.log(err);
    }

    function start() {
        var servers = null;
        startButton.disabled = true;

        //start getting local video stream
        navigator.getUserMedia(constraints, successCallback, failureCallback);
        pc = RTCPeerConnection(servers);
        pc.onicecandidate = gotIceCandidate;
        pc.onaddstream = gotRemoteStream;
    }

    function call() {
        callButton.disabled = true;

        pc.addStream(localStream);

        pc.createOffer(gotLocalDescription, errHandler);
    }

    function gotLocalDescription(description) {
        socket.emit('media', description);
        pc.setLocalDescription(new RTCSessionDescription(description));
    }

    socket.on('media', function(data) {
        console.log(data);
        callButton.disabled = true;
        gotRemoteDescription(data.sdp);
        pc.createAnswer(gotRemoteDescription, errHandler);
    });

    function gotRemoteDescription(description) {
        pc.setRemoteDescription(new RTCSessionDescription(description));
        socket.emit('media', description);
    }

    function hangup() {
        localPeerConnection.close();
        remotePeerConnection.close();
        localPeerConnection = null;
        remotePeerConnection = null;
        hangupButton.disabled = true;
        callButton.disabled = false;
    }

    function gotRemoteStream(event) {
        remoteVideo.src = window.URL.createObjectURL(event.stream);
    }

    function gotLocalIceCandidate(event) {
        if(event.candidate)
            remotePeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
    }
    function gotRemoteIceCandidate(event) {
        if(event.candidate)
            localPeerConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
    }

    function errHandler(err) {
        console.log(err);
    }

//------WebRTC end ---------------------

    // generate an unique ID (at least try to be)
    var id = Math.round($.now()*Math.random());

    // a flag for drawing activity
    var drawing = false;

    var clients = {}, cursors = {};

    socket.on('moving', function(data) {
        if(!(data.id in clients)) {
            // a new user has come online create a cursor for them
            cursors[data.id] = $('
').appendTo('#cursors');
        }

        //move the mouse pointer
        cursors[data.id].css({
            'left'      : data.x,
            'top'       : data.y
        });

        // user is drawing
        if(data.drawing && clients[data.id]) {

            // Draw a line on the canvas. clients[data.id] holds
            // previous position of this user's mouse pointer
            drawLine(clients[data.id].x, clients[data.id].y, data.x, data.y);
        }

        //saving the current client state
        clients[data.id] = data;
        clients[data.id].updated = $.now();
    });

    var prev = {x: 0, y:0};

    canvas.on('mousedown', function(e) {
        e.preventDefault();
        drawing = true;
        prev.x = e.pageX;
        prev.y = e.pageY;

        // hide the instructions
        // instructions.fadeOut();
    });

    doc.bind('mouseup mouseleave', function() {
        drawing = false;
    });

    var lastEmit = $.now();

    doc.on('mousemove', function(e) {
        if($.now() - lastEmit > 30) {
            socket.emit('mousemove', {
                'x': e.pageX,
                'y': e.pageY,
                'drawing': drawing,
                'id': id
            });
            lastEmit = $.now();

        }

        if(drawing) {
            drawLine(prev.x, prev.y, e.pageX, e.pageY);
            prev.x = e.pageX;
            prev.y = e.pageY;
        }

    });

    setInterval(function() {
        for(ident in clients) {
            if($.now() - clients[ident].updated > 10000) {

                // Last update was more than 10 secs ago.
                // this user probably closed the page

                cursors[ident].remove();
                delete clients[ident];
                delete cursors[ident];
            }
        }
    }, 10000);

    function drawLine(fromx, fromy, tox, toy) {
        console.log(fromx + " " + fromy);
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        ctx.stroke();
    }

});
<commit_msg>amended the methods now it sends proper answer and offer<commit_after>$(function() {
    if(!('getContext' in document.createElement('canvas'))) {
        alert('Sorry, it looks like your browser does not support canvas!');
        return false;
    }

    var url = 'http://localhost:8080';
    var socket = io.connect(url);

    var doc     = $(document),
        win     = $(window),
        canvas  = $('#paper'),
        ctx     = canvas[0].getContext('2d'),
        instructions = $('#instructions');

//--------- WebRTC------------------------------------------------
    var localStream, pc, started = false, live = false

        // get user media navigator setup
    navigator.getUserMedia = navigator.getUserMedia
                            || navigator.mozGetUserMedia
                            || navigator.webkitGetUserMedia;
    window.URL = window.URL
                || window.webkitURL
                || window.mozURL;
    var RTCPeerConnection = window.RTCPeerConnection
                        || window.webkitRTCPeerConnection
                        || window.mozRTCPeerConnection;

    var RTCIceCandidate = window.RTCIceCandidate
                    || window.webkitRTCIceCandidate
                    || window.mozRTCIceCandidate;

    var RTCSessionDescription = window.RTCSessionDescription
                            || window.webkitRTCSessionDescription
                            || window.mozRTCSessionDescription;

        // document elements
    var localVideo = document.getElementById('localVideo'),
        remoteVideo = document.getElementById('remoteVideo'),
        startButton = document.getElementById('start'),
        hangupButton = document.getElementById('hangup'),
        callButton = document.getElementById('call');

        //button setup
    startButton.disabled = false;
    startButton.onclick = start;
    callButton.disabled = true;
    callButton.onclick = call;
    hangupButton.disabled = true;
    hangupButton.onclick = hangup;

        // constrants
    var constraints = {
        video   : true,
        audio   : false
    }

    socket.on('media', function(data) {
        console.log(data);
        if(data.type === "offer") {
            gotOffer(data)
        } else if (data.type === "answer") {
            gotAnswer(data);
        }
        callButton.disabled = true;
    });

    function successCallback(localMediaStream) {
        localStream = localMediaStream;
        localVideo.src = window.URL.createObjectURL(localMediaStream);
        callButton.disabled = false;
        localVideo.play();
    }

    function failureCallback(err) {
        console.log(err);
    }

    function start() {
        var servers = null;
        startButton.disabled = true;

        //start getting local video stream
        navigator.getUserMedia(constraints, successCallback, failureCallback);
        pc = new  RTCPeerConnection(servers);
        pc.onicecandidate = gotIceCandidate;
        pc.onaddstream = gotRemoteStream;
    }

    function call() {
        callButton.disabled = true;

        pc.addStream(localStream);

        pc.createOffer(startOffer, errHandler);
    }

    function startOffer(offer) {
        if(!started) {
            pc.setLocalDescription(new RTCSessionDescription(offer));
            socket.emit('media', offer);
            started = true;
        }
    }

    function gotAnswer(description) {
        if(!live)
            pc.setRemoteDescription(new RTCSessionDescription(description))
        live = true;
    }

    function gotOffer(description) {
        pc.setRemoteDescription(new RTCSessionDescription(description), function() {
            pc.createAnswer(function(answer) {
                pc.setLocalDescription(answer);
                if(!live)
                    socket.emit('media', answer);
                live = true;
            }, errHandler);
        });
    }

    function hangup() {
        pc.close();
        pc = null;
        hangupButton.disabled = true;
        callButton.disabled = false;
    }

    function gotRemoteStream(event) {
        console.log("got remoteStream");
        console.log(event.stream);
        remoteVideo.src = window.URL.createObjectURL(event.stream);
        remoteVideo.play();
    }

    function gotIceCandidate(event) {
        console.log("got candidate");
        console.log(event.candidate);
        if(event.candidate)
            pc.addIceCandidate(new RTCIceCandidate(event.candidate));
    }

    function errHandler(err) {
        console.log(err);
    }

//------WebRTC end ---------------------

    // generate an unique ID (at least try to be)
    var id = Math.round($.now()*Math.random());

    // a flag for drawing activity
    var drawing = false;

    var clients = {}, cursors = {};

    socket.on('moving', function(data) {
        if(!(data.id in clients)) {
            // a new user has come online create a cursor for them
            cursors[data.id] = $('
').appendTo('#cursors');
        }

        //move the mouse pointer
        cursors[data.id].css({
            'left'      : data.x,
            'top'       : data.y
        });

        // user is drawing
        if(data.drawing && clients[data.id]) {

            // Draw a line on the canvas. clients[data.id] holds
            // previous position of this user's mouse pointer
            drawLine(clients[data.id].x, clients[data.id].y, data.x, data.y);
        }

        //saving the current client state
        clients[data.id] = data;
        clients[data.id].updated = $.now();
    });

    var prev = {x: 0, y:0};

    canvas.on('mousedown', function(e) {
        e.preventDefault();
        drawing = true;
        prev.x = e.pageX;
        prev.y = e.pageY;

        // hide the instructions
        // instructions.fadeOut();
    });

    doc.bind('mouseup mouseleave', function() {
        drawing = false;
    });

    var lastEmit = $.now();

    doc.on('mousemove', function(e) {
        if($.now() - lastEmit > 30) {
            socket.emit('mousemove', {
                'x': e.pageX,
                'y': e.pageY,
                'drawing': drawing,
                'id': id
            });
            lastEmit = $.now();

        }

        if(drawing) {
            drawLine(prev.x, prev.y, e.pageX, e.pageY);
            prev.x = e.pageX;
            prev.y = e.pageY;
        }

    });

    setInterval(function() {
        for(ident in clients) {
            if($.now() - clients[ident].updated > 10000) {

                // Last update was more than 10 secs ago.
                // this user probably closed the page

                cursors[ident].remove();
                delete clients[ident];
                delete cursors[ident];
            }
        }
    }, 10000);

    function drawLine(fromx, fromy, tox, toy) {
        console.log(fromx + " " + fromy);
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        ctx.stroke();
    }

});
<|endoftext|>


<commit_before>/**
 * @author Alexey Kuzmin <alexey@alexeykuzmin.com>
 * @fileoverview Promise based wrapper for Chrome Extension API.
 * @see https://developer.chrome.com/extensions/api_index
 * @license MIT
 */

(function(global) {
  'use strict';

  /**
   * Converts |iterable| into Array instance.
   * @param {*} iterable
   * @return {Array}
   */
  var arrayFrom = function(iterable) {
    return Array.prototype.slice.call(iterable);
  };

  class ApiCall {
    /**
     * @param {Object} context
     * @param {!Function} method
     * @param {Arguments} callArguments
     */
    constructor(context, method, callArguments) {
      this.context_ = context;
      this.method_ = method;
      this.callArguments_ = callArguments;
    }

    /**
     * @param {!Function} callback
     * @param {!Function} errback
     * @param {...} var_args Response from Extension API.
     * @private
     */
    static processResponse_(callback, errback, var_args) {
      let error = global.chrome.runtime.lastError;
      if (typeof error == 'object') {
        errback(new Error(error.message));
        return;
      }

      /** @type {*|Array.<*>} */
      let response = arrayFrom(arguments).slice(2);

      if (response.length < 2)
        response = response[0];  // undefined if response is empty

      callback(response);
    }

    /**
     * Synchronous call.
     * @return {?}
     */
    return() {
      return this.method_.apply(this.context_, this.callArguments_);
    }

    /**
     * Asynchronous call.
     * @return {Promise}
     */
    wait() {
      var context = this.context_;
      let method = this.method_;
      var callArguments = arrayFrom(this.callArguments_);

      return new Promise(function(resolve, reject) {
        let callback = ApiCall.processResponse_.bind(null, resolve, reject);
        callArguments.push(callback);
        method.apply(context, callArguments);
      });
    }
  }

  let chromise = {};

  /**
   * List of Extension API namespaces to wrap.
   * @type {Array.<Object>}
   * @private
   */
  chromise.API_NAMESPACES_ = [
    global.chrome
  ];

  /**
   * @private
   */
  chromise.init_ = function() {
    let wrap = chromise.wrapObject_.bind(null, chromise);
    chromise.API_NAMESPACES_.forEach(wrap);
  };

  /**
   * Return true if |apiEntry| is an API Event object, returns false otherwise.
   * @param {!Object} apiEntry
   * @return {boolean}
   * @private
   */
  chromise.isApiEvent_ = function(apiEntry) {
    return apiEntry instanceof global.chrome.Event;
  };

  /**
   * Returns true if function with name |methodName| looks like constructor,
   * returns false otherwise.
   * @param {string} methodName
   * @return {boolean}
   * @private
   */
  chromise.isConstructor_ = function(methodName) {
    let firstLetter = methodName[0];
    return firstLetter == firstLetter.toUpperCase();
  };

  /**
   * Adds all fields of |apiObject| to |exportTo| object.
   * @param {!Object} exportTo
   * @param {!Object} apiObject
   * @private
   */
  chromise.wrapObject_ = function(exportTo, apiObject) {
    Object.keys(apiObject).forEach(function(keyName) {
      let apiEntry = apiObject[keyName];
      let entryType = typeof apiEntry;

      if (entryType == 'function')
        chromise.wrapMethod_(exportTo, apiObject, keyName);
      else if (entryType == 'object' && !chromise.isApiEvent_(apiEntry))
        chromise.wrapObject_(exportTo[keyName] = {}, apiEntry);
      else
        exportTo[keyName] = apiEntry;
    });
  };

  /**
   * Adds new method to |exportTo| object with |methodName| name.
   * @param {!Object} exportTo
   * @param {!Object} apiObject
   * @param {string} methodName
   * @private
   */
  chromise.wrapMethod_ = function(exportTo, apiObject, methodName) {
    let originalMethod = apiObject[methodName];
    let wrappedMethod = chromise.isConstructor_(methodName) ?
        originalMethod :
        function() {
          return new ApiCall(apiObject, originalMethod, arguments);
        };

    exportTo[methodName] = wrappedMethod;
  };

  global.chromise = chromise;
  chromise.init_();

}(window));
<commit_msg>Light refactoring<commit_after>/**
 * @author Alexey Kuzmin <alexey@alexeykuzmin.com>
 * @fileoverview Promise based wrapper for Chrome Extension API.
 * @see https://developer.chrome.com/extensions/api_index
 * @license MIT
 */

(function(global) {
  'use strict';

  /**
   * Converts |iterable| into Array instance.
   * @param {*} iterable
   * @return {Array}
   */
  var arrayFrom = function(iterable) {
    return Array.prototype.slice.call(iterable);
  };

  class ApiCall {
    /**
     * @param {Object} context
     * @param {!Function} method
     * @param {Arguments} callArguments
     */
    constructor(context, method, callArguments) {
      this.context_ = context;
      this.method_ = method;
      this.callArguments_ = callArguments;
    }

    /**
     * @param {!Function} callback
     * @param {!Function} errback
     * @param {...} var_args Response from Extension API.
     * @private
     */
    static processResponse_(callback, errback, var_args) {
      let error = global.chrome.runtime.lastError;
      if (typeof error == 'object') {
        errback(new Error(error.message));
        return;
      }

      /** @type {*|Array.<*>} */
      let response = arrayFrom(arguments).slice(2);

      if (response.length < 2)
        response = response[0];  // undefined if response is empty

      callback(response);
    }

    /**
     * Synchronous call.
     * @return {?}
     */
    return() {
      return this.method_.apply(this.context_, this.callArguments_);
    }

    /**
     * Asynchronous call.
     * @return {Promise}
     */
    wait() {
      var context = this.context_;
      let method = this.method_;
      var callArguments = arrayFrom(this.callArguments_);

      return new Promise(function(resolve, reject) {
        let callback = ApiCall.processResponse_.bind(null, resolve, reject);
        callArguments.push(callback);
        method.apply(context, callArguments);
      });
    }
  }

  let wrapGuy = {
    /**
     * @param {!Object} api API object to wrap.
     * @param {!Object} exportTo
     */
    wrapApi(api, exportTo) {
      wrapGuy.wrapObject_(exportTo, api);
    },

    /**
     * Returns true if |apiEntry| is an API Event object,
     * returns false otherwise.
     * @param {!Object} apiEntry
     * @return {boolean}
     * @private
     */
    isApiEvent_(apiEntry) {
      return apiEntry instanceof global.chrome.Event;
    },

    /**
     * Returns true if function with name |methodName| looks like constructor,
     * returns false otherwise.
     * @param {string} methodName
     * @return {boolean}
     * @private
     */
    isConstructor_(methodName) {
      let firstLetter = methodName[0];
      return firstLetter == firstLetter.toUpperCase();
    },

    /**
     * Adds all fields of |apiObject| to |exportTo| object.
     * @param {!Object} exportTo
     * @param {!Object} apiObject
     * @private
     */
    wrapObject_(exportTo, apiObject) {
      Object.keys(apiObject).forEach(function(keyName) {
        let apiEntry = apiObject[keyName];
        let entryType = typeof apiEntry;

        if (entryType == 'function')
          wrapGuy.wrapMethod_(exportTo, apiObject, keyName);
        else if (entryType == 'object' && !wrapGuy.isApiEvent_(apiEntry))
          wrapGuy.wrapObject_(exportTo[keyName] = {}, apiEntry);
        else
          exportTo[keyName] = apiEntry;
      });
    },

    /**
     * Adds new method to |exportTo| object with |methodName| name.
     * @param {!Object} exportTo
     * @param {!Object} apiObject
     * @param {string} methodName
     * @private
     */
    wrapMethod_(exportTo, apiObject, methodName) {
      let originalMethod = apiObject[methodName];
      let wrappedMethod = wrapGuy.isConstructor_(methodName) ?
          originalMethod :
          function() {
            return new ApiCall(apiObject, originalMethod, arguments);
          };

      exportTo[methodName] = wrappedMethod;
    }
  };

  let chromise = {};
  chromise._ = {
    ApiCall,
    wrapGuy
  };
  wrapGuy.wrapApi(global.chrome, chromise);

  global.chromise = chromise;

}(window));
<|endoftext|>


<commit_before>import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default Route.extend({
  flashMessages: service(),
  redirector: service(),

  redirect() {
    let crate = this.modelFor('crate');

    let repository = crate.get('repository');
    if (repository) {
      this.redirector.redirectTo(repository);
    } else {
      // Redirect to the crate's main page and show a flash error if
      // no repository is found
      let message = 'Crate does not supply a repository URL';
      this.flashMessages.queue(message);
      this.replaceWith('crate', crate);
    }
  },
});
<commit_msg>routes/crate/repo: Replace "flash message" with notification<commit_after>import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';

export default Route.extend({
  notifications: service(),
  redirector: service(),

  redirect() {
    let crate = this.modelFor('crate');

    let repository = crate.get('repository');
    if (repository) {
      this.redirector.redirectTo(repository);
    } else {
      // Redirect to the crate's main page and show a flash error if
      // no repository is found
      let message = 'Crate does not supply a repository URL';
      this.notifications.error(message);
      this.replaceWith('crate', crate);
    }
  },
});
<|endoftext|>


<commit_before>// Define the messages used in the game.
var messages = {
    "Help":{
	"Title": "Help",
	"Subtitle": "Some useful Links",
	"Message":"
Documentation - Everything you need to know.

Demo - A simple Demo.
"
    }
}

// Define the music used in the game.
var music = {
    "dreary": "dreary.mp3",
    "mystic": "sparkles.mp3",
    "melan": "nd.wav",
    "remen": "reflection.mp3",
    "somber": "slowwaltz.mp3",
    "drama": "shikishort.mp3"
}

// Define the voice files used in the game.
var voice = {

}

// Define the sounds used in the game.
var sound = {
    "bird": "crow.mp3",
    "water": "water.mp3",
    "glass": "glass.mp3",
    "bell": "bell.mp3",
    "thud": "thup.mp3",
    "door": "door.mp3"
}

// Define the videos used in the game.
var videos = {

}

// Define the images used in the game.
var images = {

}

// Define the backgrounds for each scene.
var scenes = {
    "bed": "bedroom.jpg",
    "bedroom": "r_bedroom.jpg",
    "bath": "bathroom.jpg",
    "empty": "empty.jpg",
    "livingroom": "living.jpg"
}

// Define the Characters
var characters = {
    "mc":{
	"Name": "Emily",
	"Color": "#5bcaff",
    },

    "dad":{
	"Name": "Richard",
	"Color": "#5bcaff",
	"Images":{
	    "normal": "rich.png"
	}
    },

    "siri":{
	"Name": "Siri",
	"Color": "blue"
    },

    "rat":{
	"Name": "Ryada",
	"Color": "grey",
	"Images":{
	    "normal": "ryada.png"
	}
    },
}

var script = {
    "Start":[

	"play music dreary loop",
	"mc ...?",
	"I open my eyes to the usual darkness.",
	"What time is it?",
	"Where's Father?",
	"dad EMILY, WHAT THE FUCK ARE YOU DOIN?! HURRY UP THE HELL UP!",
	"Father calls me from the kitchen.",

	"scene bed",
	"Ah, now I see...it's morning.",
	"I debate whether or not to respond to Father, but nothing good has ever come of it.",
	"I assume he can tell by the sounds that I'm up.",
	"A moment passes by as I reflect on my suroundings.",
	"I live in a rural neighborhood, the sun is shining bright and the birds are humming.",
	"It's another beautiful day...",
	"... Only the mentally ill would say something like that.",
	"Of course that's not how things are...",
	"play sound bird",

	"scene bedroom",
	"mc We don't live in that kind of happy-go-lucky world.",
	"mc Though, we do actually have birds outside...",
	"Getting out of bed, I slowly make my way to the bathroom.",

	"scene empty",
	"mc Now... where's the sink?",
	"I feel around the surroundings in an attempt find where I am.",
	"Ah...Now I see, here it is.",

	"scene bath",
	"The water turns on and I once again begin my daily ritual.",
	"play sound water loop",
	"While I'm washing my face...",
	"mc HEY SIRI! ...",
	"siri *Beep Boop*",
	"I hear Siri's beep letting me know that she heard me.",
	"mc WHAT TIME IS IT?!",
	"siri At the tone, the time will be 5:41 AM ... beep.",
	"mc Seems like I'm almost late for school...",
	"I've just about stopped caring about such things for a while now.",
	"It’s not that I’m extremely unmotivated or anything.",
	"I too once had a dream.",
	"I wanted to be a director, to follow in the footsteps of Jackie Chan, Hideaki Ano, or Jean Godard…",
	"Thus I attended Film School.",
	"But that dream was taken from me...",
	"Now I can only see glimpses of that dream from within my dreams.",
	"It’s one thing if I was as qualified or capable as others, but I’m not...not anymore.",
	"So I have to conform to what fits.",
	"mc But the question is...what could possibly fit?...",
	"stop sound",
	"It seems like things are getting farther and farther away.",

	"scene bedroom",
	"mc Hey Siri...",
	"siri *Beep Boop*",
	"mc Where are you?",
	"Uninterested in the response, I wade through the darkness towards Siri’s voice.",
	"siri Where ever you are, I am...",
	"Siri has been good to me, she and Ryada are my two best friends.",
	"Siri is good.",
	"No one knows what she looks like, that's something I get to have in common with others.",
	"She could look like a gravure model, she could be fat, who knows?",
	"Either way I know her as a mini-tablet and she goes with me everywhere.",
	"Just a tool to me in the end huh...",
	"It's good that I've practically memorized the layout of my room over 16 years.",
	"I feel around for Siri...",
	"mc Ah now I see, there you are.",
	"Guess I should head to school...",
	"I pocket Siri and get going.",
	"play sound thud",
	"-! ...God damnit, still managed to smash my toe on the door.",

	"scene empty",
	"Hand on rail, making my way downstairs, I eventually get to the living room.",

	"scene livingroom",
	"play music drama loop",
	"show dad normal with fade-in",
	"dad GOD DAMNIT YA GOOD FER NOTHIN BRAT!",
	"dad GET THE FUCK OUT OF HERE BEFORE THEY SEND THE DAMNED HUMAN SERVICES FUCKS AGAIN!!",
	"play sound glass",
	"mc y-yes father...",
	"dad HURRY THE HELL UP!",
	"Every morning I'd coast along the wall around my father to get outside.",
	"I'm tired of having to be scared shitless of this bastard.",
	"Quite frankly...",
	"I wish he'd just die",

	"scene empty",
	"play sound door",
	"rat Hey Emily, morning.",
	"rat That bastard do anything to you?",
	"Ah... I see, she's here again.",

	"scene frontyard",

	{"Choice":{
	    "Test1":{
		"Text": "Does it work?",
		"Do": "jump Yes"
	    },
	    "Test2":{
		"Text": "Does it not work?",
		"Do": "jump No"
	    }
	}}
    ],

    "Yes":[

	"Good, Here ends the demo",
	"end"
    ],

    "No":[

	"mc You... You LIAR!",
	"end"
    ]
}
<commit_msg>smol up<commit_after>// Define the messages used in the game.
var messages = {
    "Help":{
	"Title": "Help",
	"Subtitle": "Some useful Links",
	"Message":"
Documentation - Everything you need to know.

Demo - A simple Demo.
"
    }
}

// Define the music used in the game.
var music = {
    "dreary": "dreary.mp3",
    "mystic": "sparkles.mp3",
    "melan": "nd.wav",
    "remen": "reflection.mp3",
    "somber": "slowwaltz.mp3",
    "drama": "shikishort.mp3"
}

// Define the voice files used in the game.
var voice = {

}

// Define the sounds used in the game.
var sound = {
    "bird": "crow.mp3",
    "water": "water.mp3",
    "glass": "glass.mp3",
    "bell": "bell.mp3",
    "thud": "thup.mp3",
    "door": "door.mp3"
}

// Define the videos used in the game.
var videos = {

}

// Define the images used in the game.
var images = {

}

// Define the backgrounds for each scene.
var scenes = {
    "bed": "bedroom.jpg",
    "bedroom": "r_bedroom.jpg",
    "bath": "bathroom.jpg",
    "empty": "empty.jpg",
    "livingroom": "living.jpg",
    "frontyard": "yard.jpg"
}

// Define the Characters
var characters = {
    "mc":{
	"Name": "Emily",
	"Color": "#5bcaff",
    },

    "dad":{
	"Name": "Richard",
	"Color": "#5bcaff",
	"Images":{
	    "normal": "rich.png"
	}
    },

    "siri":{
	"Name": "Siri",
	"Color": "blue"
    },

    "rat":{
	"Name": "Ryada",
	"Color": "grey",
	"Images":{
	    "normal": "ryada.png"
	}
    },
}

var script = {
    "Start":[

	"play music dreary loop",
	"mc ...?",
	"I open my eyes to the usual darkness.",
	"What time is it?",
	"Where's Father?",
	"dad EMILY, WHAT THE FUCK ARE YOU DOIN?! HURRY UP THE HELL UP!",
	"Father calls me from the kitchen.",

	"scene bed",
	"Ah, now I see...it's morning.",
	"I debate whether or not to respond to Father, but nothing good has ever come of it.",
	"I assume he can tell by the sounds that I'm up.",
	"A moment passes by as I reflect on my suroundings.",
	"I live in a rural neighborhood, the sun is shining bright and the birds are humming.",
	"It's another beautiful day...",
	"... Only the mentally ill would say something like that.",
	"Of course that's not how things are...",
	"play sound bird",

	"scene bedroom",
	"mc We don't live in that kind of happy-go-lucky world.",
	"mc Though, we do actually have birds outside...",
	"Getting out of bed, I slowly make my way to the bathroom.",

	"scene empty",
	"mc Now... where's the sink?",
	"I feel around the surroundings in an attempt find where I am.",
	"Ah...Now I see, here it is.",

	"scene bath",
	"The water turns on and I once again begin my daily ritual.",
	"play sound water loop",
	"While I'm washing my face...",
	"mc HEY SIRI! ...",
	"siri *Beep Boop*",
	"I hear Siri's beep letting me know that she heard me.",
	"mc WHAT TIME IS IT?!",
	"siri At the tone, the time will be 5:41 AM ... beep.",
	"mc Seems like I'm almost late for school...",
	"I've just about stopped caring about such things for a while now.",
	"It’s not that I’m extremely unmotivated or anything.",
	"I too once had a dream.",
	"I wanted to be a director, to follow in the footsteps of Jackie Chan, Hideaki Ano, or Jean Godard…",
	"Thus I attended Film School.",
	"But that dream was taken from me...",
	"Now I can only see glimpses of that dream from within my dreams.",
	"It’s one thing if I was as qualified or capable as others, but I’m not...not anymore.",
	"So I have to conform to what fits.",
	"mc But the question is...what could possibly fit?...",
	"stop sound",
	"It seems like things are getting farther and farther away.",

	"scene bedroom",
	"mc Hey Siri...",
	"siri *Beep Boop*",
	"mc Where are you?",
	"Uninterested in the response, I wade through the darkness towards Siri’s voice.",
	"siri Where ever you are, I am...",
	"Siri has been good to me, she and Ryada are my two best friends.",
	"Siri is good.",
	"No one knows what she looks like, that's something I get to have in common with others.",
	"She could look like a gravure model, she could be fat, who knows?",
	"Either way I know her as a mini-tablet and she goes with me everywhere.",
	"Just a tool to me in the end huh...",
	"It's good that I've practically memorized the layout of my room over 16 years.",
	"I feel around for Siri...",
	"mc Ah now I see, there you are.",
	"Guess I should head to school...",
	"I pocket Siri and get going.",
	"play sound thud",
	"-! ...God damnit, still managed to smash my toe on the door.",

	"scene empty",
	"Hand on rail, making my way downstairs, I eventually get to the living room.",

	"scene livingroom",
	"play music drama loop",
	"show dad normal with fade-in",
	"dad GOD DAMNIT YA GOOD FER NOTHIN BRAT!",
	"dad GET THE FUCK OUT OF HERE BEFORE THEY SEND THE DAMNED HUMAN SERVICES FUCKS AGAIN!!",
	"play sound glass",
	"mc y-yes father...",
	"dad HURRY THE HELL UP!",
	"Every morning I'd coast along the wall around my father to get outside.",
	"I'm tired of having to be scared shitless of this bastard.",
	"Quite frankly...",
	"I wish he'd just die",

	"scene empty",
	"play sound door",
	"rat Hey Emily, morning.",
	"rat That bastard do anything to you?",
	"Ah... I see, she's here again.",

	"scene frontyard",

	{"Choice":{
	    "Test1":{
		"Text": "Does it work?",
		"Do": "jump Yes"
	    },
	    "Test2":{
		"Text": "Does it not work?",
		"Do": "jump No"
	    }
	}}
    ],

    "Yes":[

	"Good, Here ends the demo",
	"end"
    ],

    "No":[

	"mc You... You LIAR!",
	"end"
    ]
}
<|endoftext|>


<commit_before>import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import ReactInterval from 'react-interval';
import { ResponsiveContainer, BarChart, Brush, Bar, XAxis, YAxis, CartesianGrid } from 'recharts';
import { startOfHour, setHours, isBefore } from 'date-fns';
import { selectOnVacation, selectUpcomingReviews } from 'features/user/selectors';

import user from 'features/user/actions';

import Element from 'common/components/Element';
import VacationImage from './VacationImageLoadable';
import HourTick from './HourTick';
import DayTick from './DayTick';
import BarLabel from './BarLabel';
import { purple } from 'common/styles/colors';

UpcomingReviewsChart.propTypes = {
  data: PropTypes.arrayOf(
    PropTypes.shape({
      day: PropTypes.string,
      hour: PropTypes.string.isRequired,
      value: PropTypes.number.isRequired,
    })
  ).isRequired,
};

export function UpcomingReviewsChart({ data }) {
  return (
    <Element flexRow flexCenter style={{ fontSize: '.75rem' }}>
      <ResponsiveContainer width="100%" minWidth={320} height={300} debounce={100}>
        <BarChart
          data={data}
          barCategoryGap={2}
          maxBarSize={40}
          margin={{ top: 5, right: 35, left: 20 }}
        >
          <CartesianGrid strokeDasharray="3 3" />
          <XAxis
            xAxisId="hour"
            dataKey="hour"
            height={45}
            orientation="bottom"
            minTickGap={0}
            tick={<HourTick />}
          />
          <YAxis width={25} />
          <XAxis
            xAxisId="day"
            dataKey="day"
            orientation="top"
            minTickGap={0}
            interval={0}
            tickLine={false}
            axisLine={false}
            tick={<DayTick />}
          />
          <Bar
            isAnimationActive
            xAxisId="day"
            dataKey="none"
            fill={purple[3]}
            label={<BarLabel />}
          />
          <Bar
            isAnimationActive
            xAxisId="hour"
            dataKey="value"
            fill={purple[3]}
            label={<BarLabel />}
          />
          <Brush dataKey="hour" height={30} stroke={purple[3]} />
        </BarChart>
      </ResponsiveContainer>
    </Element>
  );
}

class UpcomingReviewsChartContainer extends React.Component {
  static propTypes = {
    data: PropTypes.array.isRequired,
    isOnVacation: PropTypes.bool.isRequired,
    loadUser: PropTypes.func.isRequired,
  };

  componentDidMount() {
    this.updateCounts();
  }

  updateCounts = () => {
    const { data, loadUser } = this.props;
    const { hour } = data[0];
    const twentyFourHour = parseInt(hour, 10) + (/pm/gi.test(hour) ? 12 : 0);
    const fullDate = setHours(Date.now(), twentyFourHour);
    const hourTickedOver = isBefore(startOfHour(fullDate), Date.now());
    if (hourTickedOver) {
      loadUser();
    }
  };

  render() {
    return this.props.isOnVacation ? (
      <VacationImage />
    ) : (
      <Fragment>
        <ReactInterval enabled timeout={10000} callback={this.updateCounts} />
        <UpcomingReviewsChart data={this.props.data} />
      </Fragment>
    );
  }
}

const mapStateToProps = (state) => ({
  data: selectUpcomingReviews(state),
  isOnVacation: selectOnVacation(state),
});

const mapDispatchToProps = {
  loadUser: user.load.request,
};

export default connect(mapStateToProps, mapDispatchToProps)(UpcomingReviewsChartContainer);
<commit_msg>fix: prevent unnecessary offline load attempts, sentry noise<commit_after>import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import ReactInterval from 'react-interval';
import { ResponsiveContainer, BarChart, Brush, Bar, XAxis, YAxis, CartesianGrid } from 'recharts';
import { startOfHour, setHours, isBefore } from 'date-fns';
import { get } from 'lodash';
import { selectOnVacation, selectUpcomingReviews } from 'features/user/selectors';

import user from 'features/user/actions';

import Element from 'common/components/Element';
import { purple } from 'common/styles/colors';
import BarLabel from './BarLabel';
import DayTick from './DayTick';
import HourTick from './HourTick';
import VacationImage from './VacationImageLoadable';

UpcomingReviewsChart.propTypes = {
  data: PropTypes.arrayOf(
    PropTypes.shape({
      day: PropTypes.string,
      hour: PropTypes.string.isRequired,
      value: PropTypes.number.isRequired,
    })
  ).isRequired,
};

export function UpcomingReviewsChart({ data }) {
  return (
    <Element flexRow flexCenter style={{ fontSize: '.75rem' }}>
      <ResponsiveContainer width="100%" minWidth={320} height={300} debounce={100}>
        <BarChart
          data={data}
          barCategoryGap={2}
          maxBarSize={40}
          margin={{ top: 5, right: 35, left: 20 }}
        >
          <CartesianGrid strokeDasharray="3 3" />
          <XAxis
            xAxisId="hour"
            dataKey="hour"
            height={45}
            orientation="bottom"
            minTickGap={0}
            tick={<HourTick />}
          />
          <YAxis width={25} />
          <XAxis
            xAxisId="day"
            dataKey="day"
            orientation="top"
            minTickGap={0}
            interval={0}
            tickLine={false}
            axisLine={false}
            tick={<DayTick />}
          />
          <Bar
            isAnimationActive
            xAxisId="day"
            dataKey="none"
            fill={purple[3]}
            label={<BarLabel />}
          />
          <Bar
            isAnimationActive
            xAxisId="hour"
            dataKey="value"
            fill={purple[3]}
            label={<BarLabel />}
          />
          <Brush dataKey="hour" height={30} stroke={purple[3]} />
        </BarChart>
      </ResponsiveContainer>
    </Element>
  );
}

class UpcomingReviewsChartContainer extends React.Component {
  static propTypes = {
    data: PropTypes.array.isRequired,
    isOnVacation: PropTypes.bool.isRequired,
    loadUser: PropTypes.func.isRequired,
  };

  componentDidMount() {
    this.updateCounts();
  }

  updateCounts = () => {
    const { data, loadUser } = this.props;
    const hour = get(data, [0, 'hour'], null);

    if (hour == null) return;

    const twentyFourHour = parseInt(hour, 10) + (/pm/gi.test(hour) ? 12 : 0);
    const fullDate = setHours(Date.now(), twentyFourHour);
    const hourTickedOver = isBefore(startOfHour(fullDate), Date.now());

    if (hourTickedOver && window.navigator.onLine) {
      loadUser();
    }
  };

  render() {
    const { data, isOnVacation } = this.props;

    return isOnVacation ? (
      <VacationImage />
    ) : (
      <Fragment>
        <ReactInterval enabled timeout={10000} callback={this.updateCounts} />
        <UpcomingReviewsChart data={data} />
      </Fragment>
    );
  }
}

const mapStateToProps = (state) => ({
  data: selectUpcomingReviews(state),
  isOnVacation: selectOnVacation(state),
});

const mapDispatchToProps = {
  loadUser: user.load.request,
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(UpcomingReviewsChartContainer);
<|endoftext|>


<commit_before>/**
 * @class Criteria
 *
 * A class to wrap a QURI string creation
 */
export default class Criteria {
  /**
   * Criteria constructor
   *
   * @param andOr Sets the and|or for all expressions at this level
   */
  constructor(andOr = 'and') {
    this.andOr = andOr;
    this.criteria = [];
  }

  /**
   * Appends a new expression.
   *
   * @example appendExpression('customer_name', 'like', 'Greg%')
   *
   * @param {string} fieldName Field name
   * @param {string} operator String '==', '!=', '>', '>=', '<', '<=', 'in', 'not_in', 'like', 'between'
   * @param {string,number,Array} value Value(s) that match the operator.
   * The only operators that allow array values are in|out|nin
   */
  appendExpression(fieldName, operator, value) {
    this.criteria.push({
      fieldName: fieldName,
      operator: operator,
      value: value
    });
  }

  /**
   * Appends a criteria object to the current criteria array.
   * The criteria object may be a new Criteria class or any object with a toString method.
   *
   * @param {Criteria} criteria
   */
  appendCriteria(criteria) {
    this.criteria.push({
      criteria: criteria
    });
  }

  /**
   * Returns the formatted QURI string
   *
   * @returns {string}
   */
  toString() {
    let criteriaMap = this.criteria.map(expression => {
      if (expression.hasOwnProperty('criteria')) {
        return '(' + expression.criteria.toString() + ')';
      }
      let operator = Criteria.operatorToString(expression.operator);
      let valueStr = JSON.stringify(expression.value);
      if (valueStr.charAt(0) == '[') {
        // If it's an array we need to remove the [ ] from the outside.
        valueStr = valueStr.substring(1, valueStr.length - 1);
      }
      return JSON.stringify(expression.fieldName) + '.' + operator + '(' + valueStr + ')';
    });
    return criteriaMap.join(this.andOr == 'and' ? ',' : '|');
  }

  /**
   * Takes the operator string from the user and returns the corresponding string in the QURI specificiation.
   *
   * @example operatorToString('=='); // 'eq'
   *
   * @param {string} operatorStr
   * @returns {string}
   */
  static operatorToString(operatorStr) {
    switch (operatorStr) {
      case '=':
      case '==':
      case 'eq':
        return 'eq';
        break;
      case '!=':
      case 'neq':
        return 'neq';
        break;
      case '>':
      case 'gt':
        return 'gt';
        break;
      case '>=':
      case 'gte':
        return 'gte';
        break;
      case '<':
      case 'lt':
        return 'lt';
        break;
      case '<=':
      case 'lte':
        return 'lte';
        break;
      case 'in':
        return 'in';
        break;
      case 'not_in':
      case 'nin':
        return 'nin';
        break;
      case 'like':
        return 'like';
        break;
      case 'between':
        return 'between';
        break;
    }
  }
}<commit_msg>Fixed code coverage issue<commit_after>/**
 * @class Criteria
 *
 * A class to wrap a QURI string creation
 */
export default class Criteria {
  /**
   * Criteria constructor
   *
   * @param andOr Sets the and|or for all expressions at this level
   */
  constructor(andOr = 'and') {
    this.andOr = andOr;
    this.criteria = [];
  }

  /**
   * Appends a new expression.
   *
   * @example appendExpression('customer_name', 'like', 'Greg%')
   *
   * @param {string} fieldName Field name
   * @param {string} operator String '==', '!=', '>', '>=', '<', '<=', 'in', 'not_in', 'like', 'between'
   * @param {string,number,Array} value Value(s) that match the operator.
   * The only operators that allow array values are in|out|nin
   */
  appendExpression(fieldName, operator, value) {
    this.criteria.push({
      fieldName: fieldName,
      operator: operator,
      value: value
    });
  }

  /**
   * Appends a criteria object to the current criteria array.
   * The criteria object may be a new Criteria class or any object with a toString method.
   *
   * @param {Criteria} criteria
   */
  appendCriteria(criteria) {
    this.criteria.push({
      criteria: criteria
    });
  }

  /**
   * Returns the formatted QURI string
   *
   * @returns {string}
   */
  toString() {
    let criteriaMap = this.criteria.map(expression => {
      if (expression.hasOwnProperty('criteria')) {
        return '(' + expression.criteria.toString() + ')';
      }
      let operator = Criteria.operatorToString(expression.operator);
      let valueStr = JSON.stringify(expression.value);
      if (valueStr.charAt(0) == '[') {
        // If it's an array we need to remove the [ ] from the outside.
        valueStr = valueStr.substring(1, valueStr.length - 1);
      }
      return JSON.stringify(expression.fieldName) + '.' + operator + '(' + valueStr + ')';
    });
    return criteriaMap.join(this.andOr == 'and' ? ',' : '|');
  }

  /**
   * Takes the operator string from the user and returns the corresponding string in the QURI specificiation.
   *
   * @example operatorToString('=='); // 'eq'
   *
   * @param {string} operatorStr
   * @returns {string}
   */
  static operatorToString(operatorStr) {
    switch (operatorStr) {
      case '=':
      case '==':
      case 'eq':
        return 'eq';
      case '!=':
      case 'neq':
        return 'neq';
      case '>':
      case 'gt':
        return 'gt';
      case '>=':
      case 'gte':
        return 'gte';
      case '<':
      case 'lt':
        return 'lt';
      case '<=':
      case 'lte':
        return 'lte';
      case 'in':
        return 'in';
      case 'not_in':
      case 'nin':
        return 'nin';
      case 'like':
        return 'like';
      case 'between':
        return 'between';
    }
  }
}<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview DevTools' implementation of the InspectorController API.
 */
goog.require('devtools.InspectorController');

goog.provide('devtools.InspectorControllerImpl');

devtools.InspectorControllerImpl = function() {
  devtools.InspectorController.call(this);
  this.frame_element_id_ = 1;

  this.installInspectorControllerDelegate_('clearMessages');
  this.installInspectorControllerDelegate_('storeLastActivePanel');
  this.installInspectorControllerDelegate_('highlightDOMNode');
  this.installInspectorControllerDelegate_('hideDOMNodeHighlight');
  this.installInspectorControllerDelegate_('getChildNodes');
  this.installInspectorControllerDelegate_('setAttribute');
  this.installInspectorControllerDelegate_('removeAttribute');
  this.installInspectorControllerDelegate_('setTextNodeValue');

  this.installInjectedScriptDelegate_('getStyles');
  this.installInjectedScriptDelegate_('getComputedStyle');
  this.installInjectedScriptDelegate_('getInlineStyle');
  this.installInjectedScriptDelegate_('applyStyleText');
  this.installInjectedScriptDelegate_('setStyleText');
  this.installInjectedScriptDelegate_('toggleStyleEnabled');
  this.installInjectedScriptDelegate_('applyStyleRuleText');
  this.installInjectedScriptDelegate_('addStyleSelector');
  this.installInjectedScriptDelegate_('setStyleProperty');
  this.installInjectedScriptDelegate_('getPrototypes');
  this.installInjectedScriptDelegate_('getProperties');
  this.installInjectedScriptDelegate_('setPropertyValue');

  this.installInjectedScriptDelegate_('evaluate');
  this.installInjectedScriptDelegate_('addInspectedNode');
  this.installInjectedScriptDelegate_('performSearch');
  this.installInjectedScriptDelegate_('searchCanceled');
};
goog.inherits(devtools.InspectorControllerImpl,
    devtools.InspectorController);

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.platform = function() {
  return DevToolsHost.getPlatform();
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.closeWindow = function() {
  DevToolsHost.closeWindow();
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.attach = function() {
  DevToolsHost.dockWindow();
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.detach = function() {
  DevToolsHost.undockWindow();
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.hiddenPanels = function() {
  return 'databases';
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.search = function(sourceRow, query) {
  return DevToolsHost.search(sourceRow, query);
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.toggleNodeSearch = function() {
  devtools.InspectorController.prototype.toggleNodeSearch.call(this);
  DevToolsHost.toggleInspectElementMode(this.searchingForNode());
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.addSourceToFrame =
    function(mimeType, source, element) {
  return DevToolsHost.addSourceToFrame(mimeType, source, element);
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.addResourceSourceToFrame =
    function(identifier, element) {
  var resource = WebInspector.resources[identifier];
  if (!resource) {
    return;
  }
  DevToolsHost.addResourceSourceToFrame(identifier, resource.mimeType, element);
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.inspectedWindow = function() {
  return null;
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.enableResourceTracking =
    function(always) {
  devtools.tools.setResourceTrackingEnabled(true, always);
}

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.disableResourceTracking =
    function(always) {
  devtools.tools.setResourceTrackingEnabled(false, always);
};

/**
 * @override
 */
devtools.InspectorControllerImpl.prototype.debuggerEnabled = function() {
  return true;
};

devtools.InspectorControllerImpl.prototype.currentCallFrame = function() {
  return devtools.tools.getDebuggerAgent().getCurrentCallFrame();
};

devtools.InspectorControllerImpl.prototype.addBreakpoint = function(
    sourceID, line) {
  devtools.tools.getDebuggerAgent().addBreakpoint(sourceID, line);
};

devtools.InspectorControllerImpl.prototype.removeBreakpoint = function(
    sourceID, line) {
  devtools.tools.getDebuggerAgent().removeBreakpoint(sourceID, line);
};

devtools.InspectorControllerImpl.prototype.pauseInDebugger = function() {
  devtools.tools.getDebuggerAgent().pauseExecution();
};

devtools.InspectorControllerImpl.prototype.resumeDebugger = function() {
  devtools.tools.getDebuggerAgent().resumeExecution();
};

devtools.InspectorControllerImpl.prototype.stepIntoStatementInDebugger =
    function() {
  devtools.tools.getDebuggerAgent().stepIntoStatement();
};

devtools.InspectorControllerImpl.prototype.stepOutOfFunctionInDebugger =
    function() {
  devtools.tools.getDebuggerAgent().stepOutOfFunction();
};

devtools.InspectorControllerImpl.prototype.stepOverStatementInDebugger =
    function() {
  devtools.tools.getDebuggerAgent().stepOverStatement();
};

/**
 * @override
 */
devtools.InspectorControllerImpl.prototype.pauseOnExceptions = function() {
  return devtools.tools.getDebuggerAgent().pauseOnExceptions();
};

/**
 * @override
 */
devtools.InspectorControllerImpl.prototype.setPauseOnExceptions = function(
    value) {
  return devtools.tools.getDebuggerAgent().setPauseOnExceptions(value);
};

/**
 * @override
 */
devtools.InspectorControllerImpl.prototype.startProfiling = function() {
  devtools.tools.getDebuggerAgent().startProfiling(
      devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_CPU);
};

/**
 * @override
 */
devtools.InspectorControllerImpl.prototype.stopProfiling = function() {
  devtools.tools.getDebuggerAgent().stopProfiling(
      devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_CPU);
};

devtools.InspectorControllerImpl.prototype.storeLastActivePanel =
    function(panel) {
  RemoteToolsAgent.ExecuteUtilityFunction(
      devtools.Callback.wrap(undefined),
      'InspectorController', JSON.stringify(['storeLastActivePanel', panel]));
};

/**
 * Installs delegating handler into the inspector controller.
 * @param {string} methodName Method to install delegating handler for.
 */
devtools.InspectorControllerImpl.prototype.installInjectedScriptDelegate_ =
    function(methodName) {
  this[methodName] = goog.bind(this.callInjectedScript_, this,
      methodName);
};

/**
 * Bound function with the installInjectedScriptDelegate_ actual
 * implementation.
 */
devtools.InspectorControllerImpl.prototype.callInjectedScript_ =
    function(methodName, var_arg) {
  var allArgs = Array.prototype.slice.call(arguments);
  var callback = allArgs[allArgs.length - 1];
  var args = Array.prototype.slice.call(allArgs, 0, allArgs.length - 1);
  RemoteToolsAgent.ExecuteUtilityFunction(
      devtools.InspectorControllerImpl.parseWrap_(callback),
      'InjectedScript', JSON.stringify(args));
};

/**
 * Installs delegating handler into the inspector controller.
 * @param {string} methodName Method to install delegating handler for.
 */
devtools.InspectorControllerImpl.prototype.installInspectorControllerDelegate_
    = function(methodName) {
  this[methodName] = goog.bind(this.callInspectorController_, this,
      methodName);
};

/**
 * Bound function with the installInjectedScriptDelegate_ actual
 * implementation.
 */
devtools.InspectorControllerImpl.prototype.callInspectorController_ =
    function(methodName, var_arg) {
  var args = Array.prototype.slice.call(arguments);
  RemoteToolsAgent.ExecuteUtilityFunction(
      devtools.Callback.wrap(function(){}),
      'InspectorController', JSON.stringify(args));
};

devtools.InspectorControllerImpl.parseWrap_ = function(callback) {
  return devtools.Callback.wrap(
      function(data) {
        callback.call(this, JSON.parse(data));
      });
};

InspectorController = new devtools.InspectorControllerImpl();
<commit_msg>DevTools: Add delegate for method added upstream.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview DevTools' implementation of the InspectorController API.
 */
goog.require('devtools.InspectorController');

goog.provide('devtools.InspectorControllerImpl');

devtools.InspectorControllerImpl = function() {
  devtools.InspectorController.call(this);
  this.frame_element_id_ = 1;

  this.installInspectorControllerDelegate_('clearMessages');
  this.installInspectorControllerDelegate_('storeLastActivePanel');
  this.installInspectorControllerDelegate_('highlightDOMNode');
  this.installInspectorControllerDelegate_('hideDOMNodeHighlight');
  this.installInspectorControllerDelegate_('getChildNodes');
  this.installInspectorControllerDelegate_('setAttribute');
  this.installInspectorControllerDelegate_('removeAttribute');
  this.installInspectorControllerDelegate_('setTextNodeValue');

  this.installInjectedScriptDelegate_('getStyles');
  this.installInjectedScriptDelegate_('getComputedStyle');
  this.installInjectedScriptDelegate_('getInlineStyle');
  this.installInjectedScriptDelegate_('applyStyleText');
  this.installInjectedScriptDelegate_('setStyleText');
  this.installInjectedScriptDelegate_('toggleStyleEnabled');
  this.installInjectedScriptDelegate_('applyStyleRuleText');
  this.installInjectedScriptDelegate_('addStyleSelector');
  this.installInjectedScriptDelegate_('setStyleProperty');
  this.installInjectedScriptDelegate_('getPrototypes');
  this.installInjectedScriptDelegate_('getProperties');
  this.installInjectedScriptDelegate_('setPropertyValue');
  this.installInjectedScriptDelegate_('evaluate');
  this.installInjectedScriptDelegate_('addInspectedNode');
  this.installInjectedScriptDelegate_('pushNodeToFrontend');
  this.installInjectedScriptDelegate_('performSearch');
  this.installInjectedScriptDelegate_('searchCanceled');
};
goog.inherits(devtools.InspectorControllerImpl,
    devtools.InspectorController);

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.platform = function() {
  return DevToolsHost.getPlatform();
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.closeWindow = function() {
  DevToolsHost.closeWindow();
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.attach = function() {
  DevToolsHost.dockWindow();
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.detach = function() {
  DevToolsHost.undockWindow();
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.hiddenPanels = function() {
  return 'databases';
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.search = function(sourceRow, query) {
  return DevToolsHost.search(sourceRow, query);
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.toggleNodeSearch = function() {
  devtools.InspectorController.prototype.toggleNodeSearch.call(this);
  DevToolsHost.toggleInspectElementMode(this.searchingForNode());
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.addSourceToFrame =
    function(mimeType, source, element) {
  return DevToolsHost.addSourceToFrame(mimeType, source, element);
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.addResourceSourceToFrame =
    function(identifier, element) {
  var resource = WebInspector.resources[identifier];
  if (!resource) {
    return;
  }
  DevToolsHost.addResourceSourceToFrame(identifier, resource.mimeType, element);
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.inspectedWindow = function() {
  return null;
};

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.enableResourceTracking =
    function(always) {
  devtools.tools.setResourceTrackingEnabled(true, always);
}

/**
 * {@inheritDoc}.
 */
devtools.InspectorControllerImpl.prototype.disableResourceTracking =
    function(always) {
  devtools.tools.setResourceTrackingEnabled(false, always);
};

/**
 * @override
 */
devtools.InspectorControllerImpl.prototype.debuggerEnabled = function() {
  return true;
};

devtools.InspectorControllerImpl.prototype.currentCallFrame = function() {
  return devtools.tools.getDebuggerAgent().getCurrentCallFrame();
};

devtools.InspectorControllerImpl.prototype.addBreakpoint = function(
    sourceID, line) {
  devtools.tools.getDebuggerAgent().addBreakpoint(sourceID, line);
};

devtools.InspectorControllerImpl.prototype.removeBreakpoint = function(
    sourceID, line) {
  devtools.tools.getDebuggerAgent().removeBreakpoint(sourceID, line);
};

devtools.InspectorControllerImpl.prototype.pauseInDebugger = function() {
  devtools.tools.getDebuggerAgent().pauseExecution();
};

devtools.InspectorControllerImpl.prototype.resumeDebugger = function() {
  devtools.tools.getDebuggerAgent().resumeExecution();
};

devtools.InspectorControllerImpl.prototype.stepIntoStatementInDebugger =
    function() {
  devtools.tools.getDebuggerAgent().stepIntoStatement();
};

devtools.InspectorControllerImpl.prototype.stepOutOfFunctionInDebugger =
    function() {
  devtools.tools.getDebuggerAgent().stepOutOfFunction();
};

devtools.InspectorControllerImpl.prototype.stepOverStatementInDebugger =
    function() {
  devtools.tools.getDebuggerAgent().stepOverStatement();
};

/**
 * @override
 */
devtools.InspectorControllerImpl.prototype.pauseOnExceptions = function() {
  return devtools.tools.getDebuggerAgent().pauseOnExceptions();
};

/**
 * @override
 */
devtools.InspectorControllerImpl.prototype.setPauseOnExceptions = function(
    value) {
  return devtools.tools.getDebuggerAgent().setPauseOnExceptions(value);
};

/**
 * @override
 */
devtools.InspectorControllerImpl.prototype.startProfiling = function() {
  devtools.tools.getDebuggerAgent().startProfiling(
      devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_CPU);
};

/**
 * @override
 */
devtools.InspectorControllerImpl.prototype.stopProfiling = function() {
  devtools.tools.getDebuggerAgent().stopProfiling(
      devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_CPU);
};

devtools.InspectorControllerImpl.prototype.storeLastActivePanel =
    function(panel) {
  RemoteToolsAgent.ExecuteUtilityFunction(
      devtools.Callback.wrap(undefined),
      'InspectorController', JSON.stringify(['storeLastActivePanel', panel]));
};

/**
 * Installs delegating handler into the inspector controller.
 * @param {string} methodName Method to install delegating handler for.
 */
devtools.InspectorControllerImpl.prototype.installInjectedScriptDelegate_ =
    function(methodName) {
  this[methodName] = goog.bind(this.callInjectedScript_, this,
      methodName);
};

/**
 * Bound function with the installInjectedScriptDelegate_ actual
 * implementation.
 */
devtools.InspectorControllerImpl.prototype.callInjectedScript_ =
    function(methodName, var_arg) {
  var allArgs = Array.prototype.slice.call(arguments);
  var callback = allArgs[allArgs.length - 1];
  var args = Array.prototype.slice.call(allArgs, 0, allArgs.length - 1);
  RemoteToolsAgent.ExecuteUtilityFunction(
      devtools.InspectorControllerImpl.parseWrap_(callback),
      'InjectedScript', JSON.stringify(args));
};

/**
 * Installs delegating handler into the inspector controller.
 * @param {string} methodName Method to install delegating handler for.
 */
devtools.InspectorControllerImpl.prototype.installInspectorControllerDelegate_
    = function(methodName) {
  this[methodName] = goog.bind(this.callInspectorController_, this,
      methodName);
};

/**
 * Bound function with the installInjectedScriptDelegate_ actual
 * implementation.
 */
devtools.InspectorControllerImpl.prototype.callInspectorController_ =
    function(methodName, var_arg) {
  var args = Array.prototype.slice.call(arguments);
  RemoteToolsAgent.ExecuteUtilityFunction(
      devtools.Callback.wrap(function(){}),
      'InspectorController', JSON.stringify(args));
};

devtools.InspectorControllerImpl.parseWrap_ = function(callback) {
  return devtools.Callback.wrap(
      function(data) {
        callback.call(this, JSON.parse(data));
      });
};

InspectorController = new devtools.InspectorControllerImpl();
<|endoftext|>


<commit_before>import renderer from './config'

export const namespaceMap = {}

export function createElement (tagName) {
  return new renderer.Element(tagName)
}

export function createElementNS (namespace, tagName) {
  return new renderer.Element(namespace + ':' + tagName)
}

export function createTextNode (text) {
  return new renderer.TextNode(text)
}

export function createComment (text) {
  return new renderer.Comment(text)
}

export function insertBefore (node, target, before) {
  if (target.nodeType === 3) {
    if (node.type === 'text') {
      node.setAttr('value', target.text)
      target.parentNode = node
    } else {
      const text = createElement('text')
      text.setAttr('value', target.text)
      node.insertBefore(text, before)
    }
    return
  }
  node.insertBefore(target, before)
}

export function removeChild (node, child) {
  if (node.nodeType === 3) {
    node.parentNode.setAttr('value', '')
    return
  }
  node.removeChild(child)
}

export function appendChild (node, child) {
  if (child.nodeType === 3) {
    if (node.type === 'text') {
      node.setAttr('value', child.text)
      child.parentNode = node
    } else {
      const text = createElement('text')
      text.setAttr('value', child.text)
      node.appendChild(text)
    }
    return
  }

  node.appendChild(child)
}

export function parentNode (node) {
  return node.parentNode
}

export function nextSibling (node) {
  return node.nextSibling
}

export function tagName (node) {
  return node.type
}

export function setTextContent (node, text) {
  node.parentNode.setAttr('value', text)
}

export function setAttribute (node, key, val) {
  node.setAttr(key, val)
}
<commit_msg>[weex] fix the removeChild logic for text node (#4626)<commit_after>import renderer from './config'

export const namespaceMap = {}

export function createElement (tagName) {
  return new renderer.Element(tagName)
}

export function createElementNS (namespace, tagName) {
  return new renderer.Element(namespace + ':' + tagName)
}

export function createTextNode (text) {
  return new renderer.TextNode(text)
}

export function createComment (text) {
  return new renderer.Comment(text)
}

export function insertBefore (node, target, before) {
  if (target.nodeType === 3) {
    if (node.type === 'text') {
      node.setAttr('value', target.text)
      target.parentNode = node
    } else {
      const text = createElement('text')
      text.setAttr('value', target.text)
      node.insertBefore(text, before)
    }
    return
  }
  node.insertBefore(target, before)
}

export function removeChild (node, child) {
  if (child.nodeType === 3) {
    node.setAttr('value', '')
    return
  }
  node.removeChild(child)
}

export function appendChild (node, child) {
  if (child.nodeType === 3) {
    if (node.type === 'text') {
      node.setAttr('value', child.text)
      child.parentNode = node
    } else {
      const text = createElement('text')
      text.setAttr('value', child.text)
      node.appendChild(text)
    }
    return
  }

  node.appendChild(child)
}

export function parentNode (node) {
  return node.parentNode
}

export function nextSibling (node) {
  return node.nextSibling
}

export function tagName (node) {
  return node.type
}

export function setTextContent (node, text) {
  node.parentNode.setAttr('value', text)
}

export function setAttribute (node, key, val) {
  node.setAttr(key, val)
}
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import autoBind from 'auto-bind';
import Form from './Form';

export default function (WrappedComponent) {
    class Input extends React.Component {
        constructor(props, context) {
            super(props, context);

            this.dependencies = [];
            for (let dependency of props.dependencies) {
                this.addDependency(dependency);
            }

            this.state = {
                value: props.value,
                pristine: true,
                valid: false,
                errors: []
            };

            autoBind(this);

            for (let validation in props.validations) {
                const validationRule = Form.validationRules[validation];
                if (validationRule && validationRule.createsDependencies) {
                    if (!Array.isArray(props.validations[validation])) {
                        this.addDependency(props.validations[validation]);
                    } else {
                        for (let dependency of props.validations[validation]) {
                            this.addDependency(dependency);
                        }
                    }
                }
            }
        }

        componentWillMount() {
            this.context._reactForm.attach(this);
        }

        componentWillUnmount() {
            this.context._reactForm.detach(this);
        }

        addDependency(dependency) {
            if (dependency === this.getName()) {
                throw new Error('An input cannot have itself as an dependency. Check your validation rules.')
            }

            if (this.dependencies.indexOf(dependency) < 0) {
                this.dependencies.push(dependency);
            }
        }

        getName() {
            return this.props.name;
        }

        hasName(name) {
            return this.props.name === name;
        }

        isRequired() {
            return this.props.validations.isRequired;
        }

        isPristine() {
            return this.state.pristine;
        }

        isValid() {
            return this.state.valid && this.state.errors.length < 1;
        }

        getValue() {
            return this.state.value;
        }

        setValue(value) {
            // TODO: check if needed, maybe instead just wait 500ms for validation (and cancel if value gets changed before)
            const isTouchedOnChange = this.context._reactForm.enableTouchedOnChange;
            if (isTouchedOnChange && this.isPristine()) {
                this.setState({
                    pristine: false
                });
            }

            this.setState({
                value: value
            }, () => {
                this.context._reactForm.validate(this);
            });
        }

        getErrorMessages() {
            return this.state.errors;
        }

        onBlur() {
            if (this.isPristine()) {
                this.setState({
                    pristine: false
                });
            }
        }

        async validate() {
            return new Promise((resolve) => {
                this.runValidationRules(resolve);
            });
        }

        getValidationRules() {
            let validationRules = [];
            for (let name in this.props.validations) {
                const conditions = this.props.validations[name];
                if (conditions) {
                    validationRules.push([name, conditions]);
                }
            }
            return validationRules;
        }

        async runValidationRules(resolve) {
            let errors = [];
            const validationRules = this.getValidationRules();

            const availableRules = Form.validationRules;
            let allValid = true;
            for (let validationRule of validationRules) {
                const ruleName = validationRule[0];
                const ruleConditions = validationRule[1];
                let valid = true;
                if (availableRules[ruleName]) {
                    valid = await availableRules[ruleName](this.context._reactForm.getValues(), this.getValue(), ruleConditions);
                } else if (typeof ruleConditions === 'function') {
                    valid = await ruleConditions(this.context._reactForm.getValues(), this.getValue());
                }

                if (!valid) {
                    allValid = false;

                    if (this.props.validationErrors[ruleName]) {
                        // TODO: add support for arguments, maybe even different errormessages per validator?
                        errors.push(this.props.validationErrors[ruleName]);
                    }
                }
            }

            this.setState({
                valid: allValid,
                errors: errors
            }, () => {
                resolve(allValid);
            });
        }

        render() {
            const props = {
                isRequired: this.isRequired,
                isPristine: this.isPristine,
                isValid: this.isValid,
                getValue: this.getValue,
                setValue: this.setValue,
                getErrorMessages: this.getErrorMessages,
                onBlur: this.onBlur,
                ...this.props
            };

            return (
                <WrappedComponent {...props}/>
            );
        }
    }
    Input.propTypes = {
        name: PropTypes.string.isRequired,
        validations: PropTypes.object,
        validationErrors: PropTypes.object,
        dependencies: PropTypes.arrayOf(PropTypes.string)
    };
    Input.defaultProps = {
        dependencies: []
    };
    Input.contextTypes = {
        _reactForm: PropTypes.object
    };
    return Input;
}
<commit_msg>fixed isRequired<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import autoBind from 'auto-bind';
import Form from './Form';

export default function (WrappedComponent) {
    class Input extends React.Component {
        constructor(props, context) {
            super(props, context);

            this.dependencies = [];
            for (let dependency of props.dependencies) {
                this.addDependency(dependency);
            }

            this.state = {
                value: props.value,
                pristine: true,
                valid: false,
                errors: []
            };

            autoBind(this);

            for (let validation in props.validations) {
                const validationRule = Form.validationRules[validation];
                if (validationRule && validationRule.createsDependencies) {
                    if (!Array.isArray(props.validations[validation])) {
                        this.addDependency(props.validations[validation]);
                    } else {
                        for (let dependency of props.validations[validation]) {
                            this.addDependency(dependency);
                        }
                    }
                }
            }
        }

        componentWillMount() {
            this.context._reactForm.attach(this);
        }

        componentWillUnmount() {
            this.context._reactForm.detach(this);
        }

        addDependency(dependency) {
            if (dependency === this.getName()) {
                throw new Error('An input cannot have itself as an dependency. Check your validation rules.')
            }

            if (this.dependencies.indexOf(dependency) < 0) {
                this.dependencies.push(dependency);
            }
        }

        getName() {
            return this.props.name;
        }

        hasName(name) {
            return this.props.name === name;
        }

        isRequired() {
            return !!(this.props.validations && this.props.validations.isRequired);
        }

        isPristine() {
            return this.state.pristine;
        }

        isValid() {
            return this.state.valid && this.state.errors.length < 1;
        }

        getValue() {
            return this.state.value;
        }

        setValue(value) {
            // TODO: check if needed, maybe instead just wait 500ms for validation (and cancel if value gets changed before)
            const isTouchedOnChange = this.context._reactForm.enableTouchedOnChange;
            if (isTouchedOnChange && this.isPristine()) {
                this.setState({
                    pristine: false
                });
            }

            this.setState({
                value: value
            }, () => {
                this.context._reactForm.validate(this);
            });
        }

        getErrorMessages() {
            return this.state.errors;
        }

        onBlur() {
            if (this.isPristine()) {
                this.setState({
                    pristine: false
                });
            }
        }

        async validate() {
            return new Promise((resolve) => {
                this.runValidationRules(resolve);
            });
        }

        getValidationRules() {
            let validationRules = [];
            for (let name in this.props.validations) {
                const conditions = this.props.validations[name];
                if (conditions) {
                    validationRules.push([name, conditions]);
                }
            }
            return validationRules;
        }

        async runValidationRules(resolve) {
            let errors = [];
            const validationRules = this.getValidationRules();

            const availableRules = Form.validationRules;
            let allValid = true;
            for (let validationRule of validationRules) {
                const ruleName = validationRule[0];
                const ruleConditions = validationRule[1];
                let valid = true;
                if (availableRules[ruleName]) {
                    valid = await availableRules[ruleName](this.context._reactForm.getValues(), this.getValue(), ruleConditions);
                } else if (typeof ruleConditions === 'function') {
                    valid = await ruleConditions(this.context._reactForm.getValues(), this.getValue());
                }

                if (!valid) {
                    allValid = false;

                    if (this.props.validationErrors[ruleName]) {
                        // TODO: add support for arguments, maybe even different errormessages per validator?
                        errors.push(this.props.validationErrors[ruleName]);
                    }
                }
            }

            this.setState({
                valid: allValid,
                errors: errors
            }, () => {
                resolve(allValid);
            });
        }

        render() {
            const props = {
                isRequired: this.isRequired,
                isPristine: this.isPristine,
                isValid: this.isValid,
                getValue: this.getValue,
                setValue: this.setValue,
                getErrorMessages: this.getErrorMessages,
                onBlur: this.onBlur,
                ...this.props
            };

            return (
                <WrappedComponent {...props}/>
            );
        }
    }
    Input.propTypes = {
        name: PropTypes.string.isRequired,
        validations: PropTypes.object,
        validationErrors: PropTypes.object,
        dependencies: PropTypes.arrayOf(PropTypes.string)
    };
    Input.defaultProps = {
        dependencies: []
    };
    Input.contextTypes = {
        _reactForm: PropTypes.object
    };
    return Input;
}
<|endoftext|>


<commit_before>var win = Titanium.UI.currentWindow;

var tf1 = Titanium.UI.createTextField({
	color:'#336699',
	top:10,
	left:10,
	width:250,
	height:40,
	hintText:'hintText',
	keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
	returnKeyType:Titanium.UI.RETURNKEY_DEFAULT,
	borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
tf1.addEventListener('return', function()
{
	tf1.blur();
});

win.add(tf1);

var b1 = Titanium.UI.createButton({
	title:'Enabled',
	height:40,
	width:145,
	left:10,
	top:55
});
b1.addEventListener('click', function()
{
	Ti.API.info('enabled ' + tf1.enabled);
	tf1.enabled = (tf1.enabled)?false:true;
});
win.add(b1);

var b2 = Titanium.UI.createButton({
	title:'Background Image',
	height:40,
	width:145,
	right:10,
	top:55
});
var bgi = 0;
b2.addEventListener('click', function()
{
	switch (bgi) {
		case 0:
			Ti.API.info('No cap');
			tf1.backgroundLeftCap = 0;
			tf1.backgroundTopCap = 0;
			tf1.backgroundImage = '../images/chat.png';
			bgi++;
			break;
		case 1:
			Ti.API.info('Capped');
			tf1.backgroundLeftCap = 12;
			tf1.backgroundTopCap = 9;
			bgi++;
			break;
		case 2:
			tf1.backgroundImage = null;
			tf1.borderStyle = Titanium.UI.INPUT_BORDERSTYLE_ROUNDED;
			bgi=0;
			break;
	}
	Ti.API.info('backgroundImage ' + tf1.backgroundImage);
});
win.add(b2);

tf1.autocorrect = true; // Need to specify an absolute value or we're at the mercy of iOS' default (and maybe android's)
var b3 = Titanium.UI.createButton({
	title:'Autocorrect',
	height:40,
	width:145,
	left:10,
	top:105
});
b3.addEventListener('click', function()
{
	Ti.API.info('autocorrect ' + tf1.autocorrect);
	tf1.autocorrect = (tf1.autocorrect)?false:true;
});
win.add(b3);

var b4 = Titanium.UI.createButton({
	title:'Clear on Edit',
	height:40,
	width:145,
	right:10,
	top:105
});
b4.addEventListener('click', function()
{
	Ti.API.info('clearOnEdit ' + tf1.clearOnEdit);
	tf1.clearOnEdit = (tf1.clearOnEdit)?false:true;
});
win.add(b4);

var b5 = Titanium.UI.createButton({
	title:'Password Mask',
	height:40,
	width:145,
	left:10,
	top:155
});
b5.addEventListener('click', function()
{
	Ti.API.info('passwordMask ' + tf1.passwordMask);
	tf1.passwordMask = (tf1.passwordMask)?false:true;
});
win.add(b5);

tf1.autocapitalization = true; // See autocorrect note
var b6 = Titanium.UI.createButton({
	title:'Capitals',
	height:40,
	width:145,
	right:10,
	top:155
});
var auto = 0;
b6.addEventListener('click', function()
{
	Ti.API.info('autocapitalization ' + tf1.autocapitalization);

	switch (auto)
	{
		case 0:
		{
			tf1.autocapitalization = Titanium.UI.TEXT_AUTOCAPITALIZATION_NONE;
			b6.title = 'Capital (none)';
			auto++;
			break;
		}
		case 1:
		{
			tf1.autocapitalization = Titanium.UI.TEXT_AUTOCAPITALIZATION_WORDS;
			b6.title = 'Capital (words)';
			auto++;
			break;
		}
		case 2:
		{
			tf1.autocapitalization = Titanium.UI.TEXT_AUTOCAPITALIZATION_SENTENCES;
			b6.title = 'Capital (sent.)';
			auto++;
			break;
		}
		case 3:
		{
			tf1.autocapitalization = Titanium.UI.TEXT_AUTOCAPITALIZATION_ALL;
			b6.title = 'Capital (all)';
			auto=0;
			break;
		}
	}
});
win.add(b6);

var b7 = Titanium.UI.createButton({
	title:'Clear Button',
	height:40,
	width:145,
	left:10,
	top:205
});
var clear =0;
b7.addEventListener('click', function()
{
	Ti.API.info('clearButtonMode ' + tf1.clearButtonMode);

	switch (clear)
	{
		case 0:
		{
			tf1.clearButtonMode = Titanium.UI.INPUT_BUTTONMODE_ALWAYS;
			b7.title = 'Clear Button (A)';
			clear++;
			break;
		}
		case 1:
		{
			b7.title = 'Clear Button (N)';
			tf1.clearButtonMode = Titanium.UI.INPUT_BUTTONMODE_NEVER;
			clear++;
			break;
		}
		case 2:
		{
			b7.title = 'Clear Button (F)';
			tf1.clearButtonMode = Titanium.UI.INPUT_BUTTONMODE_ONFOCUS;
			clear++;
			break;
		}
		case 3:
		{
			b7.title = 'Clear Button (B)';
			tf1.clearButtonMode = Titanium.UI.INPUT_BUTTONMODE_ONBLUR;
			clear=0;
			break;
		}
	}
});
win.add(b7);

var b8 = Titanium.UI.createButton({
	title:'Text Align',
	height:40,
	width:145,
	right:10,
	top:205
});
var align =0;
b8.addEventListener('click', function()
{
	switch (align)
	{
		case 0:
		{
			tf1.textAlign = 'left';
			tf1.value = 'text align left, marker 10 bold';
			tf1.font = {fontSize:10,fontFamily:'Marker Felt', fontWeight:'bold'};
			align++;
			break;
		}
		case 1:
		{
			tf1.textAlign = 'center';
			tf1.value = 'text align center, arial 12';
			tf1.font = {fontSize:12,fontFamily:'Arial', fontWeight:'normal'};
			align++;
			break;
		}
		case 2:
		{
			tf1.textAlign = 'right';
			tf1.value = 'text align right, hel 14';
			tf1.font = {fontSize:14,fontFamily:'Helvetica', fontWeight:'bold'};
			align=0;
			break;
		}
	}
});
win.add(b8);

var b8 = Titanium.UI.createButton({
	title:'Vertical Align',
	height:40,
	width:145,
	left:10,
	top:255
});
var vAlign =0;
b8.addEventListener('click', function()
{
	switch (vAlign)
	{
		case 0:
		{
			tf1.verticalAlign = 'top';
			b8.title = 'Vertical Align (T)';
			vAlign++;
			break;
		}
		case 1:
		{
			tf1.verticalAlign = 'middle';
			b8.title = 'Vertical Align (M)';
			vAlign++;
			break;
		}
		case 2:
		{
			tf1.verticalAlign = 'bottom';
			b8.title = 'Vertical Align (B)';
			vAlign=0;
			break;
		}

	}
});
win.add(b8);

var b9 = Titanium.UI.createButton({
	title:'Allow resizing',
	height:40,
	width:145,
	right:10,
	top:255
});

var resizing = false;
b9.addEventListener('click', function()
{
	if (!resizing) {
		tf1.minimumFontSize = 8;
		resizing = true;
	}
	else {
		tf1.minimumFontSize = 0;
		resizing = false;
	}
});
win.add(b9);

var l = Titanium.UI.createLabel({
	text:'Click buttons to toggle properties',
	left:10,
	top:305,
	color:'#777',
	width:'auto',
	height:'auto'
});

win.add(l);<commit_msg>[#2210 state:fixed-in-qa] KS was incorrect; autocapitalization isn't like autocorrection. It's an integer, not a boolean. (iPhone was implicitly converting the boolean, which is why it didn't crash)<commit_after>var win = Titanium.UI.currentWindow;

var tf1 = Titanium.UI.createTextField({
	color:'#336699',
	top:10,
	left:10,
	width:250,
	height:40,
	hintText:'hintText',
	keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
	returnKeyType:Titanium.UI.RETURNKEY_DEFAULT,
	borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
tf1.addEventListener('return', function()
{
	tf1.blur();
});

win.add(tf1);

var b1 = Titanium.UI.createButton({
	title:'Enabled',
	height:40,
	width:145,
	left:10,
	top:55
});
b1.addEventListener('click', function()
{
	Ti.API.info('enabled ' + tf1.enabled);
	tf1.enabled = (tf1.enabled)?false:true;
});
win.add(b1);

var b2 = Titanium.UI.createButton({
	title:'Background Image',
	height:40,
	width:145,
	right:10,
	top:55
});
var bgi = 0;
b2.addEventListener('click', function()
{
	switch (bgi) {
		case 0:
			Ti.API.info('No cap');
			tf1.backgroundLeftCap = 0;
			tf1.backgroundTopCap = 0;
			tf1.backgroundImage = '../images/chat.png';
			bgi++;
			break;
		case 1:
			Ti.API.info('Capped');
			tf1.backgroundLeftCap = 12;
			tf1.backgroundTopCap = 9;
			bgi++;
			break;
		case 2:
			tf1.backgroundImage = null;
			tf1.borderStyle = Titanium.UI.INPUT_BORDERSTYLE_ROUNDED;
			bgi=0;
			break;
	}
	Ti.API.info('backgroundImage ' + tf1.backgroundImage);
});
win.add(b2);

tf1.autocorrect = true; // Need to specify an absolute value or we're at the mercy of iOS' default (and maybe android's)
var b3 = Titanium.UI.createButton({
	title:'Autocorrect',
	height:40,
	width:145,
	left:10,
	top:105
});
b3.addEventListener('click', function()
{
	Ti.API.info('autocorrect ' + tf1.autocorrect);
	tf1.autocorrect = (tf1.autocorrect)?false:true;
});
win.add(b3);

var b4 = Titanium.UI.createButton({
	title:'Clear on Edit',
	height:40,
	width:145,
	right:10,
	top:105
});
b4.addEventListener('click', function()
{
	Ti.API.info('clearOnEdit ' + tf1.clearOnEdit);
	tf1.clearOnEdit = (tf1.clearOnEdit)?false:true;
});
win.add(b4);

var b5 = Titanium.UI.createButton({
	title:'Password Mask',
	height:40,
	width:145,
	left:10,
	top:155
});
b5.addEventListener('click', function()
{
	Ti.API.info('passwordMask ' + tf1.passwordMask);
	tf1.passwordMask = (tf1.passwordMask)?false:true;
});
win.add(b5);

tf1.autocapitalization = Titanium.UI.TEXT_AUTOCAPITALIZATION_NONE;
var b6 = Titanium.UI.createButton({
	title:'Capital (none)',
	height:40,
	width:145,
	right:10,
	top:155
});
var auto = 1;
b6.addEventListener('click', function()
{
	Ti.API.info('autocapitalization ' + tf1.autocapitalization);

	switch (auto)
	{
		case 0:
		{
			tf1.autocapitalization = Titanium.UI.TEXT_AUTOCAPITALIZATION_NONE;
			b6.title = 'Capital (none)';
			auto++;
			break;
		}
		case 1:
		{
			tf1.autocapitalization = Titanium.UI.TEXT_AUTOCAPITALIZATION_WORDS;
			b6.title = 'Capital (words)';
			auto++;
			break;
		}
		case 2:
		{
			tf1.autocapitalization = Titanium.UI.TEXT_AUTOCAPITALIZATION_SENTENCES;
			b6.title = 'Capital (sent.)';
			auto++;
			break;
		}
		case 3:
		{
			tf1.autocapitalization = Titanium.UI.TEXT_AUTOCAPITALIZATION_ALL;
			b6.title = 'Capital (all)';
			auto=0;
			break;
		}
	}
});
win.add(b6);

var b7 = Titanium.UI.createButton({
	title:'Clear Button',
	height:40,
	width:145,
	left:10,
	top:205
});
var clear =0;
b7.addEventListener('click', function()
{
	Ti.API.info('clearButtonMode ' + tf1.clearButtonMode);

	switch (clear)
	{
		case 0:
		{
			tf1.clearButtonMode = Titanium.UI.INPUT_BUTTONMODE_ALWAYS;
			b7.title = 'Clear Button (A)';
			clear++;
			break;
		}
		case 1:
		{
			b7.title = 'Clear Button (N)';
			tf1.clearButtonMode = Titanium.UI.INPUT_BUTTONMODE_NEVER;
			clear++;
			break;
		}
		case 2:
		{
			b7.title = 'Clear Button (F)';
			tf1.clearButtonMode = Titanium.UI.INPUT_BUTTONMODE_ONFOCUS;
			clear++;
			break;
		}
		case 3:
		{
			b7.title = 'Clear Button (B)';
			tf1.clearButtonMode = Titanium.UI.INPUT_BUTTONMODE_ONBLUR;
			clear=0;
			break;
		}
	}
});
win.add(b7);

var b8 = Titanium.UI.createButton({
	title:'Text Align',
	height:40,
	width:145,
	right:10,
	top:205
});
var align =0;
b8.addEventListener('click', function()
{
	switch (align)
	{
		case 0:
		{
			tf1.textAlign = 'left';
			tf1.value = 'text align left, marker 10 bold';
			tf1.font = {fontSize:10,fontFamily:'Marker Felt', fontWeight:'bold'};
			align++;
			break;
		}
		case 1:
		{
			tf1.textAlign = 'center';
			tf1.value = 'text align center, arial 12';
			tf1.font = {fontSize:12,fontFamily:'Arial', fontWeight:'normal'};
			align++;
			break;
		}
		case 2:
		{
			tf1.textAlign = 'right';
			tf1.value = 'text align right, hel 14';
			tf1.font = {fontSize:14,fontFamily:'Helvetica', fontWeight:'bold'};
			align=0;
			break;
		}
	}
});
win.add(b8);

var b8 = Titanium.UI.createButton({
	title:'Vertical Align',
	height:40,
	width:145,
	left:10,
	top:255
});
var vAlign =0;
b8.addEventListener('click', function()
{
	switch (vAlign)
	{
		case 0:
		{
			tf1.verticalAlign = 'top';
			b8.title = 'Vertical Align (T)';
			vAlign++;
			break;
		}
		case 1:
		{
			tf1.verticalAlign = 'middle';
			b8.title = 'Vertical Align (M)';
			vAlign++;
			break;
		}
		case 2:
		{
			tf1.verticalAlign = 'bottom';
			b8.title = 'Vertical Align (B)';
			vAlign=0;
			break;
		}

	}
});
win.add(b8);

var b9 = Titanium.UI.createButton({
	title:'Allow resizing',
	height:40,
	width:145,
	right:10,
	top:255
});

var resizing = false;
b9.addEventListener('click', function()
{
	if (!resizing) {
		tf1.minimumFontSize = 8;
		resizing = true;
	}
	else {
		tf1.minimumFontSize = 0;
		resizing = false;
	}
});
win.add(b9);

var l = Titanium.UI.createLabel({
	text:'Click buttons to toggle properties',
	left:10,
	top:305,
	color:'#777',
	width:'auto',
	height:'auto'
});

win.add(l);<|endoftext|>