<commit_before>angular
    .module('material.components.keyboard')
    .directive('mdKeyboard', MdKeyboardDirective)
    .directive('useKeyboard', useKeyboardDirective);

function MdKeyboardDirective($mdKeyboard, $mdTheming) {
    return {
        restrict: 'E',
        link: function postLink(scope, element) {
            $mdTheming(element);
            // When navigation force destroys an interimElement, then
            // listen and $destroy() that interim instance...
            scope.$on('$destroy', function () {
                $mdKeyboard.destroy();
            });
        }
    };
}

function useKeyboardDirective($mdKeyboard, $timeout, $animate, $rootScope) {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function (scope, element, attrs, ngModelCtrl) {
            // requires ngModel silently
            if (!ngModelCtrl) {
                return;
            }

            // bind instance to that var
            var keyboard;

            // Don't show virtual keyboard in mobile devices (default)
            var isMobile = false;
            (function (a) {
                if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) {
                    isMobile = true;
                }
            })(navigator.userAgent || navigator.vendor || window.opera);
            if (isMobile && attrs.showInMobile !== true) {
                return;
            }

            // open keyboard on focus
            element
                .bind('focus', showKeyboard)
                .bind('blur', hideKeyboard);

            function showKeyboard() {
                if ($rootScope.keyboardTimeout) {
                    $timeout.cancel($rootScope.keyboardTimeout);
                }
                if ($rootScope.keyboardAnimation) {
                    $animate.cancel($rootScope.keyboardAnimation);
                }

                // no keyboard active, so add new
                if (!$mdKeyboard.isVisible()) {
                    $mdKeyboard.currentModel = ngModelCtrl;
                    $rootScope.keyboardAnimation = $mdKeyboard.show({
                        templateUrl: '../view/mdKeyboard.view.html',
                        controller: mdKeyboardController,
                        bindToController: true
                    });
                }

                // use existing keyboard
                else {
                    $mdKeyboard.currentModel = ngModelCtrl;
                    $mdKeyboard.useLayout(attrs.useKeyboard);
                }
            }

            function mdKeyboardController($scope) {
                $mdKeyboard.useLayout(attrs.useKeyboard);

                var getKeyClass = function (key) {
                    var k = (key[0] || ' ').toLowerCase();
                    var keys = ['bksp', 'tab', 'caps', 'enter', 'shift', 'alt', 'altgr', 'altlk'];

                    // space bar
                    if (k == ' ') {
                        k = 'space';
                    }
                    // special key
                    else if (keys.indexOf(k) < 0) {
                        k = 'char';
                    }
                    // spacer helper element
                    else if (k == 'spacer') {
                        return k;
                    }

                    return 'key-' + k;
                };

                var triggerKey = function($event, key) {
                    $event.preventDefault();

                    switch (key) {
                        case "Caps":
                            $scope.capsLocked = !$scope.capsLocked;
                            $scope.caps = false;
                            break;

                        case "Shift":
                            $scope.caps = !$scope.caps;
                            break;

                        case "Alt":
                        case "AltGr":
                        case "AltLk":
                            // modify input, visualize
                            //self.VKI_modify(type);
                            break;

                        case "Tab":
                            // TODO: handle text selection

                            // cycle through elements
                            // or insert \t tab
                            //if (self.VKI_activeTab) {
                            //    if (self.VKI_target.form) {
                            //        var target = self.VKI_target, elems = target.form.elements;
                            //        self.VKI_close(false);
                            //        for (var z = 0, me = false, j = -1; z < elems.length; z++) {
                            //            if (j == -1 && elems[z].getAttribute("VKI_attached")) j = z;
                            //            if (me) {
                            //                if (self.VKI_activeTab == 1 && elems[z]) break;
                            //                if (elems[z].getAttribute("VKI_attached")) break;
                            //            } else if (elems[z] == target) me = true;
                            //        }
                            //        if (z == elems.length) z = Math.max(j, 0);
                            //        if (elems[z].getAttribute("VKI_attached")) {
                            //            self.VKI_show(elems[z]);
                            //        } else elems[z].focus();
                            //    } else self.VKI_target.focus();
                            //} else self.VKI_insert("\t");
                            //return false;

                            $mdKeyboard.currentModel.$setViewValue(($mdKeyboard.currentModel.$viewValue || '') + "\t");
                            $mdKeyboard.currentModel.$validate();
                            $mdKeyboard.currentModel.$render();

                            break;

                        case "Bksp":
                            // TODO: handle text selection

                            // backspace
                            //self.VKI_target.focus();
                            //if (self.VKI_target.setSelectionRange && hasSelectionStartEnd(self.VKI_target) && !self.VKI_target.readOnly) {
                            //    var rng = [self.VKI_target.selectionStart, self.VKI_target.selectionEnd];
                            //    if (rng[0] < rng[1]) rng[0]++;
                            //    self.VKI_target.value = self.VKI_target.value.substr(0, rng[0] - 1) + self.VKI_target.value.substr(rng[1]);
                            //    self.VKI_target.setSelectionRange(rng[0] - 1, rng[0] - 1);
                            //} else if (self.VKI_target.createTextRange && !self.VKI_target.readOnly) {
                            //    try {
                            //        self.VKI_target.range.select();
                            //    } catch (e) {
                            //        self.VKI_target.range = document.selection.createRange();
                            //    }
                            //    if (!self.VKI_target.range.text.length) self.VKI_target.range.moveStart('character', -1);
                            //    self.VKI_target.range.text = "";
                            //} else self.VKI_target.value = self.VKI_target.value.substr(0, self.VKI_target.value.length - 1);
                            //if (self.VKI_shift) self.VKI_modify("Shift");
                            //if (self.VKI_altgr) self.VKI_modify("AltGr");
                            //self.VKI_target.focus();
                            //self.keyInputCallback();
                            //return true;

                            $mdKeyboard.currentModel.$setViewValue(($mdKeyboard.currentModel.$viewValue || '').slice(0, -1));
                            $mdKeyboard.currentModel.$validate();
                            $mdKeyboard.currentModel.$render();

                            break;

                        case "Enter":
                            if (element[0].nodeName.toUpperCase() != 'TEXTAREA') {
                                $timeout(function () {
                                    angular.element(element[0].form).triggerHandler('submit');
                                });
                            } else {
                                $mdKeyboard.currentModel.$setViewValue(($mdKeyboard.currentModel.$viewValue || '') + "\n");
                                $mdKeyboard.currentModel.$validate();
                                $mdKeyboard.currentModel.$render();
                            }

                            break;

                        default:
                            $mdKeyboard.currentModel.$setViewValue(($mdKeyboard.currentModel.$viewValue || '') + key[0]);
                            $mdKeyboard.currentModel.$validate();
                            $mdKeyboard.currentModel.$render();

                            $scope.caps = false;
                    }
                };

                var _init = function () {
                    $scope.resolve = function () {
                        $mdKeyboard.hide('ok');
                    };
                    $scope.getKeyClass = getKeyClass;
                    $scope.keyboard = $mdKeyboard.getCurrentLayout();
                    $scope.pressed = triggerKey;

                    $scope.$on('$mdKeyboardLayoutChanged', function () {
                        $scope.keyboard = $mdKeyboard.getCurrentLayout();
                        $scope.$apply();
                    });
                };

                _init();
            }

            function _getCaretPosition() {
                if ('selectionStart' in element) {
                    return element.selectionStart;
                } else if (document.selection) {
                    element.focus();
                    var sel = document.selection.createRange();
                    var selLen = document.selection.createRange().text.length;
                    sel.moveStart('character', -element.value.length);
                    return sel.text.length - selLen;
                }
            }

            function hideKeyboard() {
                if ($rootScope.keyboardTimeout) {
                    $timeout.cancel($rootScope.keyboardTimeout);
                }
                $rootScope.keyboardTimeout = $timeout(function () {
                    $rootScope.keyboardAnimation = $mdKeyboard.hide();
                }, 500);
            }
        }
    }
}
<commit_msg>decreased timeout for hiding keyboard<commit_after>angular
    .module('material.components.keyboard')
    .directive('mdKeyboard', MdKeyboardDirective)
    .directive('useKeyboard', useKeyboardDirective);

function MdKeyboardDirective($mdKeyboard, $mdTheming) {
    return {
        restrict: 'E',
        link: function postLink(scope, element) {
            $mdTheming(element);
            // When navigation force destroys an interimElement, then
            // listen and $destroy() that interim instance...
            scope.$on('$destroy', function () {
                $mdKeyboard.destroy();
            });
        }
    };
}

function useKeyboardDirective($mdKeyboard, $timeout, $animate, $rootScope) {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function (scope, element, attrs, ngModelCtrl) {
            // requires ngModel silently
            if (!ngModelCtrl) {
                return;
            }

            // bind instance to that var
            var keyboard;

            // Don't show virtual keyboard in mobile devices (default)
            var isMobile = false;
            (function (a) {
                if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) {
                    isMobile = true;
                }
            })(navigator.userAgent || navigator.vendor || window.opera);
            if (isMobile && attrs.showInMobile !== true) {
                return;
            }

            // open keyboard on focus
            element
                .bind('focus', showKeyboard)
                .bind('blur', hideKeyboard);

            function showKeyboard() {
                if ($rootScope.keyboardTimeout) {
                    $timeout.cancel($rootScope.keyboardTimeout);
                }
                if ($rootScope.keyboardAnimation) {
                    $animate.cancel($rootScope.keyboardAnimation);
                }

                // no keyboard active, so add new
                if (!$mdKeyboard.isVisible()) {
                    $mdKeyboard.currentModel = ngModelCtrl;
                    $rootScope.keyboardAnimation = $mdKeyboard.show({
                        templateUrl: '../view/mdKeyboard.view.html',
                        controller: mdKeyboardController,
                        bindToController: true
                    });
                }

                // use existing keyboard
                else {
                    $mdKeyboard.currentModel = ngModelCtrl;
                    $mdKeyboard.useLayout(attrs.useKeyboard);
                }
            }

            function mdKeyboardController($scope) {
                $mdKeyboard.useLayout(attrs.useKeyboard);

                var getKeyClass = function (key) {
                    var k = (key[0] || ' ').toLowerCase();
                    var keys = ['bksp', 'tab', 'caps', 'enter', 'shift', 'alt', 'altgr', 'altlk'];

                    // space bar
                    if (k == ' ') {
                        k = 'space';
                    }
                    // special key
                    else if (keys.indexOf(k) < 0) {
                        k = 'char';
                    }
                    // spacer helper element
                    else if (k == 'spacer') {
                        return k;
                    }

                    return 'key-' + k;
                };

                var triggerKey = function($event, key) {
                    $event.preventDefault();

                    switch (key) {
                        case "Caps":
                            $scope.capsLocked = !$scope.capsLocked;
                            $scope.caps = false;
                            break;

                        case "Shift":
                            $scope.caps = !$scope.caps;
                            break;

                        case "Alt":
                        case "AltGr":
                        case "AltLk":
                            // modify input, visualize
                            //self.VKI_modify(type);
                            break;

                        case "Tab":
                            // TODO: handle text selection

                            // cycle through elements
                            // or insert \t tab
                            //if (self.VKI_activeTab) {
                            //    if (self.VKI_target.form) {
                            //        var target = self.VKI_target, elems = target.form.elements;
                            //        self.VKI_close(false);
                            //        for (var z = 0, me = false, j = -1; z < elems.length; z++) {
                            //            if (j == -1 && elems[z].getAttribute("VKI_attached")) j = z;
                            //            if (me) {
                            //                if (self.VKI_activeTab == 1 && elems[z]) break;
                            //                if (elems[z].getAttribute("VKI_attached")) break;
                            //            } else if (elems[z] == target) me = true;
                            //        }
                            //        if (z == elems.length) z = Math.max(j, 0);
                            //        if (elems[z].getAttribute("VKI_attached")) {
                            //            self.VKI_show(elems[z]);
                            //        } else elems[z].focus();
                            //    } else self.VKI_target.focus();
                            //} else self.VKI_insert("\t");
                            //return false;

                            $mdKeyboard.currentModel.$setViewValue(($mdKeyboard.currentModel.$viewValue || '') + "\t");
                            $mdKeyboard.currentModel.$validate();
                            $mdKeyboard.currentModel.$render();

                            break;

                        case "Bksp":
                            // TODO: handle text selection

                            // backspace
                            //self.VKI_target.focus();
                            //if (self.VKI_target.setSelectionRange && hasSelectionStartEnd(self.VKI_target) && !self.VKI_target.readOnly) {
                            //    var rng = [self.VKI_target.selectionStart, self.VKI_target.selectionEnd];
                            //    if (rng[0] < rng[1]) rng[0]++;
                            //    self.VKI_target.value = self.VKI_target.value.substr(0, rng[0] - 1) + self.VKI_target.value.substr(rng[1]);
                            //    self.VKI_target.setSelectionRange(rng[0] - 1, rng[0] - 1);
                            //} else if (self.VKI_target.createTextRange && !self.VKI_target.readOnly) {
                            //    try {
                            //        self.VKI_target.range.select();
                            //    } catch (e) {
                            //        self.VKI_target.range = document.selection.createRange();
                            //    }
                            //    if (!self.VKI_target.range.text.length) self.VKI_target.range.moveStart('character', -1);
                            //    self.VKI_target.range.text = "";
                            //} else self.VKI_target.value = self.VKI_target.value.substr(0, self.VKI_target.value.length - 1);
                            //if (self.VKI_shift) self.VKI_modify("Shift");
                            //if (self.VKI_altgr) self.VKI_modify("AltGr");
                            //self.VKI_target.focus();
                            //self.keyInputCallback();
                            //return true;

                            $mdKeyboard.currentModel.$setViewValue(($mdKeyboard.currentModel.$viewValue || '').slice(0, -1));
                            $mdKeyboard.currentModel.$validate();
                            $mdKeyboard.currentModel.$render();

                            break;

                        case "Enter":
                            if (element[0].nodeName.toUpperCase() != 'TEXTAREA') {
                                $timeout(function () {
                                    angular.element(element[0].form).triggerHandler('submit');
                                });
                            } else {
                                $mdKeyboard.currentModel.$setViewValue(($mdKeyboard.currentModel.$viewValue || '') + "\n");
                                $mdKeyboard.currentModel.$validate();
                                $mdKeyboard.currentModel.$render();
                            }

                            break;

                        default:
                            $mdKeyboard.currentModel.$setViewValue(($mdKeyboard.currentModel.$viewValue || '') + key[0]);
                            $mdKeyboard.currentModel.$validate();
                            $mdKeyboard.currentModel.$render();

                            $scope.caps = false;
                    }
                };

                var _init = function () {
                    $scope.resolve = function () {
                        $mdKeyboard.hide('ok');
                    };
                    $scope.getKeyClass = getKeyClass;
                    $scope.keyboard = $mdKeyboard.getCurrentLayout();
                    $scope.pressed = triggerKey;

                    $scope.$on('$mdKeyboardLayoutChanged', function () {
                        $scope.keyboard = $mdKeyboard.getCurrentLayout();
                        $scope.$apply();
                    });
                };

                _init();
            }

            function _getCaretPosition() {
                if ('selectionStart' in element) {
                    return element.selectionStart;
                } else if (document.selection) {
                    element.focus();
                    var sel = document.selection.createRange();
                    var selLen = document.selection.createRange().text.length;
                    sel.moveStart('character', -element.value.length);
                    return sel.text.length - selLen;
                }
            }

            function hideKeyboard() {
                if ($rootScope.keyboardTimeout) {
                    $timeout.cancel($rootScope.keyboardTimeout);
                }
                $rootScope.keyboardTimeout = $timeout(function () {
                    $rootScope.keyboardAnimation = $mdKeyboard.hide();
                }, 200);
            }
        }
    }
}
<|endoftext|>


<commit_before>import {dedupingMixin} from '@polymer/polymer/lib/utils/mixin.js';
import {addCurrencyAmountDelimiter, displayCurrencyAmount} from './etools-currency-module';

/**
 * Currency amount input. US format only.
 * @polymer
 * @mixinFunction
 */
export const EtoolsCurrency = dedupingMixin(
  (superClass) =>
    class extends superClass {
      /**
       * Format value as currency amount. Delimited used ', '
       */
      addCurrencyAmountDelimiter(value) {
        return addCurrencyAmountDelimiter(value);
      }

      /**
       * Format value as currency amount and return it to be displayed
       * Use this to display readonly currency amounts on interface
       */
      displayCurrencyAmount(value, placeholder, noOfDecimals) {
        return displayCurrencyAmount(value, placeholder, noOfDecimals);
      }
    }
);
<commit_msg>Update etools-currency-mixin.js<commit_after>import {dedupingMixin} from '@polymer/polymer/lib/utils/mixin.js';
import {addCurrencyAmountDelimiter, displayCurrencyAmount} from './etools-currency-module';

/**
 * Currency amount input. US format only.
 * @polymer
 * @mixinFunction
 */
export const EtoolsCurrency = dedupingMixin(
  superClass =>
    class extends superClass {
      /**
       * Format value as currency amount. Delimited used ', '
       */
      addCurrencyAmountDelimiter(value) {
        return addCurrencyAmountDelimiter(value);
      }

      /**
       * Format value as currency amount and return it to be displayed
       * Use this to display readonly currency amounts on interface
       */
      displayCurrencyAmount(value, placeholder, noOfDecimals) {
        return displayCurrencyAmount(value, placeholder, noOfDecimals);
      }
    }
);
<|endoftext|>


<commit_before>( function( mdash )
{

        var KeyboardManager = mdash.KeyboardManager = function() {},
                proto       = KeyboardManager.prototype;

        proto.init = function()
        {
            this.searchTerm       = "";
            this.modifierPressed  = false;
            this.modifierKeyCodes = [
                93, // ⌘
                16  // Shift
            ];

            this.bindKeyboard();
        }

        proto.bindKeyboard = function()
        {
            var _this = this;

            $(document).on('keydown', function(e) {

                if (_this.isModifierKey(e.which))
                {
                    _this.modifierPressed = true;
                }
                else if (e.which == 8)
                {
                    // Backspace
                    if (_this.modifierPressed) {
                        _this.searchTerm = '';
                    } else {
                        _this.searchTerm = _this.searchTerm.slice(0, -1);
                    }
                }
                else
                {
                    if (e.which >= 65 && e.which <= 90)
                    {
                        _this.searchTerm += String.fromCharCode(e.which);
                    }
                }

                $('#filter p').text(_this.searchTerm);

                _this.filterTiles();
            });

            $(document).on('keyup', function(e) {
                if (_this.isModifierKey(e.which)) {
                    _this.modifierPressed = false;
                }
            });
    }

    proto.isModifierKey = function(keyCode)
    {
        return (this.modifierKeyCodes.indexOf(keyCode) !== -1);
    }

    proto.filterTiles = function()
    {
        var _this = this;
        var filterable = $('#bookmarks a').not('.add');

        $.each(filterable, function(i, item) {
            var $item = $(item);
            var title = $item.data('title');

            if (title.match(new RegExp('' + _this.searchTerm, 'i'))) {
                $item.show();
            } else {
                $item.hide();
            }
        });
    }

} )( window.mdash || ( window.mdash = {} ) );<commit_msg>Prevents the address bar from getting focus when pressing backspace while filtering bookmarks.<commit_after>( function( mdash )
{

        var KeyboardManager = mdash.KeyboardManager = function() {},
                proto       = KeyboardManager.prototype;

        proto.init = function()
        {
            this.searchTerm       = "";
            this.modifierPressed  = false;
            this.modifierKeyCodes = [
                93, // ⌘
                16  // Shift
            ];

            this.bindKeyboard();
        }

        proto.bindKeyboard = function()
        {
            var _this = this;

            $(document).on('keydown', function(e) {

                if (_this.isModifierKey(e.which))
                {
                    _this.modifierPressed = true;
                }
                else if (e.which == 8)
                {
                    // Backspace
                    if (_this.modifierPressed) {
                        _this.searchTerm = '';
                    } else {
                        _this.searchTerm = _this.searchTerm.slice(0, -1);
                    }

                    // Prevents the address bar from getting focus
                    e.preventDefault();
                }
                else
                {
                    if (e.which >= 65 && e.which <= 90)
                    {
                        _this.searchTerm += String.fromCharCode(e.which);
                    }
                }

                $('#filter p').text(_this.searchTerm);

                _this.filterTiles();
            });

            $(document).on('keyup', function(e) {
                if (_this.isModifierKey(e.which)) {
                    _this.modifierPressed = false;
                }
            });
    }

    proto.isModifierKey = function(keyCode)
    {
        return (this.modifierKeyCodes.indexOf(keyCode) !== -1);
    }

    proto.filterTiles = function()
    {
        var _this = this;
        var filterable = $('#bookmarks a').not('.add');

        $.each(filterable, function(i, item) {
            var $item = $(item);
            var title = $item.data('title');

            if (title.match(new RegExp('' + _this.searchTerm, 'i'))) {
                $item.show();
            } else {
                $item.hide();
            }
        });
    }

} )( window.mdash || ( window.mdash = {} ) );
<|endoftext|>


<commit_before>export default {
    methods: {
        getToken: function(TokenName) {
            //Use regex to extract out the require token
            const regEx = new RegExp(TokenName + "=([^;]+)");
            const value = regEx.exec(document.cookie);
            return (value !== null) ? encodeURIComponent(value[1]) : null;
        }
    }
}<commit_msg>Require template literals instead of string concatenation.<commit_after>export default {
    methods: {
        getToken: function(TokenName) {
            //Use regex to extract out the require token
            const regEx = new RegExp(`${TokenName}\=([^;]+)`);
            const value = regEx.exec(document.cookie);
            return (value !== null) ? encodeURIComponent(value[1]) : null;
        }
    }
}<|endoftext|>


<commit_before>import React, { PropTypes, Component } from 'react';
const ReactLink = require('react/lib/ReactLink');
const ReactStateSetters = require('react/lib/ReactStateSetters');
import * as ThreadActionCreators from '../actions/ThreadActionCreators';
import AuthenticatedComponent from '../components/AuthenticatedComponent';
import translate from '../i18n/Translate';
import connectToStores from '../utils/connectToStores';
import FilterStore from '../stores/FilterStore';
import TagSuggestionsStore from '../stores/TagSuggestionsStore';
import ThreadStore from '../stores/ThreadStore';
import TextInput from '../components/ui/TextInput';
import TextRadios from '../components/ui/TextRadios';
import CreateContentThread from '../components/threads/CreateContentThread';
import CreateUsersThread from '../components/threads/CreateUsersThread';
import TopNavBar from '../components/ui/TopNavBar';

function parseThreadId(params) {
    return params.threadId;
}

/**
 * Requests data from server for current props.
 */
function requestData(props) {
    const userId = props.user.id;
    ThreadActionCreators.requestFilters(userId);
    ThreadActionCreators.requestThreads(userId);
}

/**
 * Retrieves state from stores for current props.
 */
function getState(props) {
    const filters = FilterStore.filters;
    const tags = TagSuggestionsStore.tags;
    const threadId = parseThreadId(props.params);
    const thread = ThreadStore.get(threadId);
    const errors = ThreadStore.getErrors();

    return {
        tags,
        filters,
        thread,
        errors
    };
}

@AuthenticatedComponent
@translate('EditThreadPage')
@connectToStores([ThreadStore, FilterStore, TagSuggestionsStore], getState)
export default class EditThreadPage extends Component {

    static propTypes = {
        // Injected by @connectToStores:
        filters: PropTypes.object,
        tags   : PropTypes.array,
        thread : PropTypes.object.isRequired,
        errors : PropTypes.string,
        // Injected by @AuthenticatedComponent
        user   : PropTypes.object.isRequired,
        // Injected by @translate:
        strings: PropTypes.object
    };

    constructor(props) {
        super(props);

        this.handleClickCategory = this.handleClickCategory.bind(this);

        this.state = {
            threadName: '',
            category  : null
        };
    }

    componentWillMount() {
        requestData(this.props);
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.thread) {
            this.setState({
                threadName: this.state.threadName ? this.state.threadName : nextProps.thread.name,
                category  : nextProps.thread.category == 'ThreadUsers' ? 'persons' : 'contents'
            });
        }
        if (nextProps.errors) {
            nekunoApp.alert(nextProps.errors);
            ThreadStore.deleteErrors();
        }
    }

    handleClickCategory(category) {
        this.setState({
            category: category
        });
    }

    linkState(key) {
        return new ReactLink(this.state[key], ReactStateSetters.createStateKeySetter(this, key));
    }

    render() {
        const {user, filters, tags, thread, strings} = this.props;
        const {category, threadName} = this.state;
        return (

                <TopNavBar centerText={strings.edit} leftText={strings.cancel}/>

                        {thread && filters ?

                                        <TextInput placeholder={strings.placeholder} valueLink={this.linkState('threadName')}/>

                                        <TextRadios labels={[{key: 'persons', text: strings.people}, {key: 'contents', text: strings.contents}]} onClickHandler={this.handleClickCategory} value={category}/>

                                {category === 'contents' ? <CreateContentThread userId={user.id} defaultFilters={filters['contentFilters']} threadName={threadName} tags={tags} thread={thread}/> : ''}
                                {category === 'persons' ? <CreateUsersThread userId={user.id} defaultFilters={filters['userFilters']} threadName={threadName} tags={tags} thread={thread}/> : ''}

                            : ''}

        );
    }
};

EditThreadPage.defaultProps = {
    strings: {
        edit       : 'Edit yarn',
        cancel     : 'Cancel',
        placeholder: 'Write a descriptive title of the yarn',
        people     : 'People',
        contents   : 'Contents'
    }
};
<commit_msg>QS-1036: Do not overwrite thread name if already editing it (reverted from commit 0380817c24ca8977ef27086f5907185caaa3e399)<commit_after>import React, { PropTypes, Component } from 'react';
const ReactLink = require('react/lib/ReactLink');
const ReactStateSetters = require('react/lib/ReactStateSetters');
import * as ThreadActionCreators from '../actions/ThreadActionCreators';
import AuthenticatedComponent from '../components/AuthenticatedComponent';
import translate from '../i18n/Translate';
import connectToStores from '../utils/connectToStores';
import FilterStore from '../stores/FilterStore';
import TagSuggestionsStore from '../stores/TagSuggestionsStore';
import ThreadStore from '../stores/ThreadStore';
import TextInput from '../components/ui/TextInput';
import TextRadios from '../components/ui/TextRadios';
import CreateContentThread from '../components/threads/CreateContentThread';
import CreateUsersThread from '../components/threads/CreateUsersThread';
import TopNavBar from '../components/ui/TopNavBar';

function parseThreadId(params) {
    return params.threadId;
}

/**
 * Requests data from server for current props.
 */
function requestData(props) {
    const userId = props.user.id;
    ThreadActionCreators.requestFilters(userId);
    ThreadActionCreators.requestThreads(userId);
}

/**
 * Retrieves state from stores for current props.
 */
function getState(props) {
    const filters = FilterStore.filters;
    const tags = TagSuggestionsStore.tags;
    const threadId = parseThreadId(props.params);
    const thread = ThreadStore.get(threadId);
    const errors = ThreadStore.getErrors();

    return {
        tags,
        filters,
        thread,
        errors
    };
}

@AuthenticatedComponent
@translate('EditThreadPage')
@connectToStores([ThreadStore, FilterStore, TagSuggestionsStore], getState)
export default class EditThreadPage extends Component {

    static propTypes = {
        // Injected by @connectToStores:
        filters: PropTypes.object,
        tags   : PropTypes.array,
        thread : PropTypes.object.isRequired,
        errors : PropTypes.string,
        // Injected by @AuthenticatedComponent
        user   : PropTypes.object.isRequired,
        // Injected by @translate:
        strings: PropTypes.object
    };

    constructor(props) {
        super(props);

        this.handleClickCategory = this.handleClickCategory.bind(this);

        this.state = {
            threadName: '',
            category  : null
        };
    }

    componentWillMount() {
        requestData(this.props);
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.thread) {
            this.setState({
                threadName: nextProps.thread.name,
                category  : nextProps.thread.category == 'ThreadUsers' ? 'persons' : 'contents'
            });
        }
        if (nextProps.errors) {
            nekunoApp.alert(nextProps.errors);
            ThreadStore.deleteErrors();
        }
    }

    handleClickCategory(category) {
        this.setState({
            category: category
        });
    }

    linkState(key) {
        return new ReactLink(this.state[key], ReactStateSetters.createStateKeySetter(this, key));
    }

    render() {
        const {user, filters, tags, thread, strings} = this.props;
        const {category, threadName} = this.state;
        return (

                <TopNavBar centerText={strings.edit} leftText={strings.cancel}/>

                        {thread && filters ?

                                        <TextInput placeholder={strings.placeholder} valueLink={this.linkState('threadName')}/>

                                        <TextRadios labels={[{key: 'persons', text: strings.people}, {key: 'contents', text: strings.contents}]} onClickHandler={this.handleClickCategory} value={category}/>

                                {category === 'contents' ? <CreateContentThread userId={user.id} defaultFilters={filters['contentFilters']} threadName={threadName} tags={tags} thread={thread}/> : ''}
                                {category === 'persons' ? <CreateUsersThread userId={user.id} defaultFilters={filters['userFilters']} threadName={threadName} tags={tags} thread={thread}/> : ''}

                            : ''}

        );
    }
};

EditThreadPage.defaultProps = {
    strings: {
        edit       : 'Edit yarn',
        cancel     : 'Cancel',
        placeholder: 'Write a descriptive title of the yarn',
        people     : 'People',
        contents   : 'Contents'
    }
};
<|endoftext|>


<commit_before>/*
 * JavaScript Load Image Scaling
 * https://github.com/blueimp/JavaScript-Load-Image
 *
 * Copyright 2011, Sebastian Tschan
 * https://blueimp.net
 *
 * Licensed under the MIT license:
 * https://opensource.org/licenses/MIT
 */

/* global define, module, require */

;(function (factory) {
  'use strict'
  if (typeof define === 'function' && define.amd) {
    // Register as an anonymous AMD module:
    define(['./load-image'], factory)
  } else if (typeof module === 'object' && module.exports) {
    factory(require('./load-image'))
  } else {
    // Browser globals:
    factory(window.loadImage)
  }
})(function (loadImage) {
  'use strict'

  var originalTransform = loadImage.transform

  loadImage.transform = function (img, options, callback, file, data) {
    originalTransform.call(
      loadImage,
      loadImage.scale(img, options, data),
      options,
      callback,
      file,
      data
    )
  }

  // Transform image coordinates, allows to override e.g.
  // the canvas orientation based on the orientation option,
  // gets canvas, options passed as arguments:
  loadImage.transformCoordinates = function () {}

  // Returns transformed options, allows to override e.g.
  // maxWidth, maxHeight and crop options based on the aspectRatio.
  // gets img, options passed as arguments:
  loadImage.getTransformedOptions = function (img, options) {
    var aspectRatio = options.aspectRatio
    var newOptions
    var i
    var width
    var height
    if (!aspectRatio) {
      return options
    }
    newOptions = {}
    for (i in options) {
      if (Object.prototype.hasOwnProperty.call(options, i)) {
        newOptions[i] = options[i]
      }
    }
    newOptions.crop = true
    width = img.naturalWidth || img.width
    height = img.naturalHeight || img.height
    if (width / height > aspectRatio) {
      newOptions.maxWidth = height * aspectRatio
      newOptions.maxHeight = height
    } else {
      newOptions.maxWidth = width
      newOptions.maxHeight = width / aspectRatio
    }
    return newOptions
  }

  // Canvas render method, allows to implement a different rendering algorithm:
  loadImage.renderImageToCanvas = function (
    canvas,
    img,
    sourceX,
    sourceY,
    sourceWidth,
    sourceHeight,
    destX,
    destY,
    destWidth,
    destHeight,
    options
  ) {
    var ctx = canvas.getContext('2d')
    if (options.imageSmoothingEnabled === false) {
      ctx.imageSmoothingEnabled = false
    } else if (options.imageSmoothingQuality) {
      ctx.imageSmoothingQuality = options.imageSmoothingQuality
    }
    ctx.drawImage(
      img,
      sourceX,
      sourceY,
      sourceWidth,
      sourceHeight,
      destX,
      destY,
      destWidth,
      destHeight
    )
    return canvas
  }

  // Determines if the target image should be a canvas element:
  loadImage.hasCanvasOption = function (options) {
    return options.canvas || options.crop || !!options.aspectRatio
  }

  // Scales and/or crops the given image (img or canvas HTML element)
  // using the given options.
  // Returns a canvas object if the browser supports canvas
  // and the hasCanvasOption method returns true or a canvas
  // object is passed as image, else the scaled image:
  loadImage.scale = function (img, options, data) {
    // eslint-disable-next-line no-param-reassign
    options = options || {}
    var canvas = document.createElement('canvas')
    var useCanvas =
      img.getContext ||
      (loadImage.hasCanvasOption(options) && canvas.getContext)
    var width = img.naturalWidth || img.width
    var height = img.naturalHeight || img.height
    var destWidth = width
    var destHeight = height
    var maxWidth
    var maxHeight
    var minWidth
    var minHeight
    var sourceWidth
    var sourceHeight
    var sourceX
    var sourceY
    var pixelRatio
    var downsamplingRatio
    var tmp
    /**
     * Scales up image dimensions
     */
    function scaleUp() {
      var scale = Math.max(
        (minWidth || destWidth) / destWidth,
        (minHeight || destHeight) / destHeight
      )
      if (scale > 1) {
        destWidth *= scale
        destHeight *= scale
      }
    }
    /**
     * Scales down image dimensions
     */
    function scaleDown() {
      var scale = Math.min(
        (maxWidth || destWidth) / destWidth,
        (maxHeight || destHeight) / destHeight
      )
      if (scale < 1) {
        destWidth *= scale
        destHeight *= scale
      }
    }
    if (useCanvas) {
      // eslint-disable-next-line no-param-reassign
      options = loadImage.getTransformedOptions(img, options, data)
      sourceX = options.left || 0
      sourceY = options.top || 0
      if (options.sourceWidth) {
        sourceWidth = options.sourceWidth
        if (options.right !== undefined && options.left === undefined) {
          sourceX = width - sourceWidth - options.right
        }
      } else {
        sourceWidth = width - sourceX - (options.right || 0)
      }
      if (options.sourceHeight) {
        sourceHeight = options.sourceHeight
        if (options.bottom !== undefined && options.top === undefined) {
          sourceY = height - sourceHeight - options.bottom
        }
      } else {
        sourceHeight = height - sourceY - (options.bottom || 0)
      }
      destWidth = sourceWidth
      destHeight = sourceHeight
    }
    maxWidth = options.maxWidth
    maxHeight = options.maxHeight
    minWidth = options.minWidth
    minHeight = options.minHeight
    if (useCanvas && maxWidth && maxHeight && options.crop) {
      destWidth = maxWidth
      destHeight = maxHeight
      tmp = sourceWidth / sourceHeight - maxWidth / maxHeight
      if (tmp < 0) {
        sourceHeight = (maxHeight * sourceWidth) / maxWidth
        if (options.top === undefined && options.bottom === undefined) {
          sourceY = (height - sourceHeight) / 2
        }
      } else if (tmp > 0) {
        sourceWidth = (maxWidth * sourceHeight) / maxHeight
        if (options.left === undefined && options.right === undefined) {
          sourceX = (width - sourceWidth) / 2
        }
      }
    } else {
      if (options.contain || options.cover) {
        minWidth = maxWidth = maxWidth || minWidth
        minHeight = maxHeight = maxHeight || minHeight
      }
      if (options.cover) {
        scaleDown()
        scaleUp()
      } else {
        scaleUp()
        scaleDown()
      }
    }
    if (useCanvas) {
      pixelRatio = options.pixelRatio
      if (pixelRatio > 1) {
        canvas.style.width = destWidth + 'px'
        canvas.style.height = destHeight + 'px'
        destWidth *= pixelRatio
        destHeight *= pixelRatio
        canvas.getContext('2d').scale(pixelRatio, pixelRatio)
      }
      downsamplingRatio = options.downsamplingRatio
      if (
        downsamplingRatio > 0 &&
        downsamplingRatio < 1 &&
        destWidth < sourceWidth &&
        destHeight < sourceHeight
      ) {
        while (sourceWidth * downsamplingRatio > destWidth) {
          canvas.width = sourceWidth * downsamplingRatio
          canvas.height = sourceHeight * downsamplingRatio
          loadImage.renderImageToCanvas(
            canvas,
            img,
            sourceX,
            sourceY,
            sourceWidth,
            sourceHeight,
            0,
            0,
            canvas.width,
            canvas.height,
            options
          )
          sourceX = 0
          sourceY = 0
          sourceWidth = canvas.width
          sourceHeight = canvas.height
          // eslint-disable-next-line no-param-reassign
          img = document.createElement('canvas')
          img.width = sourceWidth
          img.height = sourceHeight
          loadImage.renderImageToCanvas(
            img,
            canvas,
            0,
            0,
            sourceWidth,
            sourceHeight,
            0,
            0,
            sourceWidth,
            sourceHeight,
            options
          )
        }
      }
      canvas.width = destWidth
      canvas.height = destHeight
      loadImage.transformCoordinates(canvas, options)
      return loadImage.renderImageToCanvas(
        canvas,
        img,
        sourceX,
        sourceY,
        sourceWidth,
        sourceHeight,
        0,
        0,
        destWidth,
        destHeight,
        options
      )
    }
    img.width = destWidth
    img.height = destHeight
    return img
  }
})
<commit_msg>Always pass a data arg to getTransformedOptions.<commit_after>/*
 * JavaScript Load Image Scaling
 * https://github.com/blueimp/JavaScript-Load-Image
 *
 * Copyright 2011, Sebastian Tschan
 * https://blueimp.net
 *
 * Licensed under the MIT license:
 * https://opensource.org/licenses/MIT
 */

/* global define, module, require */

;(function (factory) {
  'use strict'
  if (typeof define === 'function' && define.amd) {
    // Register as an anonymous AMD module:
    define(['./load-image'], factory)
  } else if (typeof module === 'object' && module.exports) {
    factory(require('./load-image'))
  } else {
    // Browser globals:
    factory(window.loadImage)
  }
})(function (loadImage) {
  'use strict'

  var originalTransform = loadImage.transform

  loadImage.transform = function (img, options, callback, file, data) {
    originalTransform.call(
      loadImage,
      loadImage.scale(img, options, data),
      options,
      callback,
      file,
      data
    )
  }

  // Transform image coordinates, allows to override e.g.
  // the canvas orientation based on the orientation option,
  // gets canvas, options passed as arguments:
  loadImage.transformCoordinates = function () {}

  // Returns transformed options, allows to override e.g.
  // maxWidth, maxHeight and crop options based on the aspectRatio.
  // gets img, options, data passed as arguments:
  loadImage.getTransformedOptions = function (img, options) {
    var aspectRatio = options.aspectRatio
    var newOptions
    var i
    var width
    var height
    if (!aspectRatio) {
      return options
    }
    newOptions = {}
    for (i in options) {
      if (Object.prototype.hasOwnProperty.call(options, i)) {
        newOptions[i] = options[i]
      }
    }
    newOptions.crop = true
    width = img.naturalWidth || img.width
    height = img.naturalHeight || img.height
    if (width / height > aspectRatio) {
      newOptions.maxWidth = height * aspectRatio
      newOptions.maxHeight = height
    } else {
      newOptions.maxWidth = width
      newOptions.maxHeight = width / aspectRatio
    }
    return newOptions
  }

  // Canvas render method, allows to implement a different rendering algorithm:
  loadImage.renderImageToCanvas = function (
    canvas,
    img,
    sourceX,
    sourceY,
    sourceWidth,
    sourceHeight,
    destX,
    destY,
    destWidth,
    destHeight,
    options
  ) {
    var ctx = canvas.getContext('2d')
    if (options.imageSmoothingEnabled === false) {
      ctx.imageSmoothingEnabled = false
    } else if (options.imageSmoothingQuality) {
      ctx.imageSmoothingQuality = options.imageSmoothingQuality
    }
    ctx.drawImage(
      img,
      sourceX,
      sourceY,
      sourceWidth,
      sourceHeight,
      destX,
      destY,
      destWidth,
      destHeight
    )
    return canvas
  }

  // Determines if the target image should be a canvas element:
  loadImage.hasCanvasOption = function (options) {
    return options.canvas || options.crop || !!options.aspectRatio
  }

  // Scales and/or crops the given image (img or canvas HTML element)
  // using the given options.
  // Returns a canvas object if the browser supports canvas
  // and the hasCanvasOption method returns true or a canvas
  // object is passed as image, else the scaled image:
  loadImage.scale = function (img, options, data) {
    // eslint-disable-next-line no-param-reassign
    options = options || {}
    var canvas = document.createElement('canvas')
    var useCanvas =
      img.getContext ||
      (loadImage.hasCanvasOption(options) && canvas.getContext)
    var width = img.naturalWidth || img.width
    var height = img.naturalHeight || img.height
    var destWidth = width
    var destHeight = height
    var maxWidth
    var maxHeight
    var minWidth
    var minHeight
    var sourceWidth
    var sourceHeight
    var sourceX
    var sourceY
    var pixelRatio
    var downsamplingRatio
    var tmp
    /**
     * Scales up image dimensions
     */
    function scaleUp() {
      var scale = Math.max(
        (minWidth || destWidth) / destWidth,
        (minHeight || destHeight) / destHeight
      )
      if (scale > 1) {
        destWidth *= scale
        destHeight *= scale
      }
    }
    /**
     * Scales down image dimensions
     */
    function scaleDown() {
      var scale = Math.min(
        (maxWidth || destWidth) / destWidth,
        (maxHeight || destHeight) / destHeight
      )
      if (scale < 1) {
        destWidth *= scale
        destHeight *= scale
      }
    }
    if (useCanvas) {
      // eslint-disable-next-line no-param-reassign
      options = loadImage.getTransformedOptions(img, options, data || {})
      sourceX = options.left || 0
      sourceY = options.top || 0
      if (options.sourceWidth) {
        sourceWidth = options.sourceWidth
        if (options.right !== undefined && options.left === undefined) {
          sourceX = width - sourceWidth - options.right
        }
      } else {
        sourceWidth = width - sourceX - (options.right || 0)
      }
      if (options.sourceHeight) {
        sourceHeight = options.sourceHeight
        if (options.bottom !== undefined && options.top === undefined) {
          sourceY = height - sourceHeight - options.bottom
        }
      } else {
        sourceHeight = height - sourceY - (options.bottom || 0)
      }
      destWidth = sourceWidth
      destHeight = sourceHeight
    }
    maxWidth = options.maxWidth
    maxHeight = options.maxHeight
    minWidth = options.minWidth
    minHeight = options.minHeight
    if (useCanvas && maxWidth && maxHeight && options.crop) {
      destWidth = maxWidth
      destHeight = maxHeight
      tmp = sourceWidth / sourceHeight - maxWidth / maxHeight
      if (tmp < 0) {
        sourceHeight = (maxHeight * sourceWidth) / maxWidth
        if (options.top === undefined && options.bottom === undefined) {
          sourceY = (height - sourceHeight) / 2
        }
      } else if (tmp > 0) {
        sourceWidth = (maxWidth * sourceHeight) / maxHeight
        if (options.left === undefined && options.right === undefined) {
          sourceX = (width - sourceWidth) / 2
        }
      }
    } else {
      if (options.contain || options.cover) {
        minWidth = maxWidth = maxWidth || minWidth
        minHeight = maxHeight = maxHeight || minHeight
      }
      if (options.cover) {
        scaleDown()
        scaleUp()
      } else {
        scaleUp()
        scaleDown()
      }
    }
    if (useCanvas) {
      pixelRatio = options.pixelRatio
      if (pixelRatio > 1) {
        canvas.style.width = destWidth + 'px'
        canvas.style.height = destHeight + 'px'
        destWidth *= pixelRatio
        destHeight *= pixelRatio
        canvas.getContext('2d').scale(pixelRatio, pixelRatio)
      }
      downsamplingRatio = options.downsamplingRatio
      if (
        downsamplingRatio > 0 &&
        downsamplingRatio < 1 &&
        destWidth < sourceWidth &&
        destHeight < sourceHeight
      ) {
        while (sourceWidth * downsamplingRatio > destWidth) {
          canvas.width = sourceWidth * downsamplingRatio
          canvas.height = sourceHeight * downsamplingRatio
          loadImage.renderImageToCanvas(
            canvas,
            img,
            sourceX,
            sourceY,
            sourceWidth,
            sourceHeight,
            0,
            0,
            canvas.width,
            canvas.height,
            options
          )
          sourceX = 0
          sourceY = 0
          sourceWidth = canvas.width
          sourceHeight = canvas.height
          // eslint-disable-next-line no-param-reassign
          img = document.createElement('canvas')
          img.width = sourceWidth
          img.height = sourceHeight
          loadImage.renderImageToCanvas(
            img,
            canvas,
            0,
            0,
            sourceWidth,
            sourceHeight,
            0,
            0,
            sourceWidth,
            sourceHeight,
            options
          )
        }
      }
      canvas.width = destWidth
      canvas.height = destHeight
      loadImage.transformCoordinates(canvas, options)
      return loadImage.renderImageToCanvas(
        canvas,
        img,
        sourceX,
        sourceY,
        sourceWidth,
        sourceHeight,
        0,
        0,
        destWidth,
        destHeight,
        options
      )
    }
    img.width = destWidth
    img.height = destHeight
    return img
  }
})
<|endoftext|>


<commit_before>// FIXME htmlparser

var depdir = __dirname + "/../deps",
    _require = require('./canvas-svg/require')(depdir);

var jsdom = _require('jsdom', 'jsdom/lib/jsdom'),
    vargs = _require('vargs', 'vargs/lib/vargs'),
    overload = _require('node-overload', 'overload', 'lib/overload',
                        'node-overload/lib/overload'),
    Canvas = _require('node-canvas', 'canvas', 'node-canvas/lib/canvas',
                      'canvas/lib/canvas'),

    patch = require('./canvas-svg/patch')(overload),
    Vargs = vargs.Constructor;

var svg = exports.svg = {};

var check_canvg = function () {
    if (svg.canvg) return true;
    throw new Error("You have to load Canvg first."+
        "\nIt should be already in the repo. If not get it from:"+
        " http://code.google.com/p/canvg/");
};

var parse_data = function (data, type) {
    if (type)
        type = {contentType:type};

    var elem = jsdom.jsdom(""+data+"",null,type).body;

    for(var i=0,l=elem.childNodes.length;i<l;i++) {
        if (elem.childNodes[i].nodeName[0] !== "#")// i hope this isn't dumb
            return [null, elem.childNodes[i]];
    }
    return [new Error("cannot find a proper element in data"), elem];
};

exports.svg.render = function (svgdata/*, width, height, options, callback*/) {
    check_canvg();
    var args = new Vargs(arguments);
    if (!svgdata)
        return args.callback(new Error("no svg given"), new Canvas(42, 42));

    var doc = jsdom.jsdom(),
        win = doc.createWindow(),
        DOMParser = function () {
            this.parseFromString = function (data, type) {
                var res = parse_data(data, type);
                //if (/*err*/res[0]) ### /*ignored*/ ###
                //    throw res[0];
                return { documentElement : patch.nodeName(res[1]) };
            };
        };
    win.DOMParser = true;

    var width, height;
    if (args.length > 2) {
        width = args.all[1];
        height = args.all[2];

    } else {
        var res = parse_data(svgdata);
        if (/*err*/res[0])
            return args.callback(res[0], new Canvas(42, 42));
        var elem = res[1];
        svgdata = elem.outerHTML; // maybe cleaner

        width = elem.hasAttribute('width') ?
            parseInt(elem.getAttribute('width')) : 42;
        height = elem.hasAttribute('height') ?
            parseInt(elem.getAttribute('height')) : 42;
    }

    var canvas = new Canvas(width, height);

    var options = {};
    if (args.length  == 2 || args.length > 3)
        options = args.last;

    var defaults = {
        renderCallback : function () { args.callback(null, canvas) },
        ignoreMouse: true,
        ignoreAnimation: true,
        ignoreDimensions: true,
        ignoreClear: true,
        offsetX: 0,
        offsetY: 0
    };

    var keys = Object.keys(defaults);
    for(var key,i=0,l=keys.length;i<l&&((key=keys[i])||true);i++) {
        if(!(key in options))
            options[key] = defaults[key];
    }

    try {
        svg.canvg(win, doc, DOMParser)(canvas, svgdata, options);
    } catch(e) {
        args.callback(e, canvas);
    }
};

exports.load = require('./canvas-svg/loader')(depdir, vargs, svg);

<commit_msg>rewrite render function<commit_after>// FIXME htmlparser

var depdir = __dirname + "/../deps",
    _require = require('./canvas-svg/require')(depdir);

var jsdom = _require('jsdom', 'jsdom/lib/jsdom'),
    vargs = _require('vargs', 'vargs/lib/vargs'),
    overload = _require('node-overload', 'overload', 'lib/overload',
                        'node-overload/lib/overload'),
    Canvas = _require('node-canvas', 'canvas', 'node-canvas/lib/canvas',
                      'canvas/lib/canvas'),

    patch = require('./canvas-svg/patch')(overload),
    Vargs = vargs.Constructor;

var svg = exports.svg = {};

var check_canvg = function () {
    if (svg.canvg) return true;
    throw new Error("You have to load Canvg first."+
        "\nIt should be already in the repo. If not get it from:"+
        " http://code.google.com/p/canvg/");
};

var parse_data = function (data, type) {
    if (type)
        type = {contentType:type};

    var elem = jsdom.jsdom(""+data+"",null,type).body;

    for(var i=0,l=elem.childNodes.length;i<l;i++) {
        if (elem.childNodes[i].nodeName[0] !== "#")// i hope this isn't dumb
            return [null, elem.childNodes[i]];
    }
    return [new Error("cannot find a proper element in data"), elem];
};

exports.svg.render = function (/*canvas, svgdata, width, height, options, callback*/) {
    check_canvg();
    var args = new Vargs(arguments),
        arglist = args.all.slice(0);

    var svgdata = "", canvas = null;
    if (typeof args.first === 'string') {
        svgdata = args.shift();
    } else {
        canvas = args.shift();
        svgdata = args.shift();
    }

    if (!svgdata)
        return args.callback(new Error("no svg given"), new Canvas(42, 42));

    if (!canvas) {
        var doc = jsdom.jsdom(),
            win = doc.createWindow(),
            DOMParser = function () {
                this.parseFromString = function (data, type) {
                    var res = parse_data(data, type);
                    //if (/*err*/res[0]) ### /*ignored*/ ###
                    //    throw res[0];
                    return { documentElement : patch.nodeName(res[1]) };
                };
            };
        win.DOMParser = true;

        var width, height;
        if (arglist.length > 1) {
            width = arglist.shift();
            height = arglist.shift();

        } else {
            var res = parse_data(svgdata);
            if (/*err*/res[0])
                return args.callback(res[0], new Canvas(42, 42));
            var elem = res[1];
            svgdata = elem.outerHTML; // maybe cleaner

            width = elem.hasAttribute('width') ?
                parseInt(elem.getAttribute('width')) : 42;
            height = elem.hasAttribute('height') ?
                parseInt(elem.getAttribute('height')) : 42;
        }
        canvas = new Canvas(width, height);
    }

    var options = arglist ? args.last : {},
        defaults = {
        renderCallback : function () { args.callback(null, canvas) },
        ignoreMouse: true,
        ignoreAnimation: true,
        ignoreDimensions: true,
        ignoreClear: true,
        offsetX: 0,
        offsetY: 0
    };

    var keys = Object.keys(defaults);
    for(var key,i=0,l=keys.length;i<l&&((key=keys[i])||true);i++) {
        if(!(key in options))
            options[key] = defaults[key];
    }

    try {
        svg.canvg(win, doc, DOMParser)(canvas, svgdata, options);
    } catch(e) {
        args.callback(e, canvas);
    }
};

exports.Canvas = Canvas;

exports.load = require('./canvas-svg/loader')(depdir, vargs, svg);

<|endoftext|>


<commit_before>/*jslint nomen: true */
/*globals define: true */

define([
  'jquery',
  'lib/lodash',
  'backbone',
  'lib/tinypubsub',

  // LocalData
  'settings',
  'util',
  'api',

  // Models
  'models/responses',

  // Templates
  'text!templates/responses/item.html'
],

function($, _, Backbone, events, settings, util, api, Responses, template) {
  'use strict';

  var ResponseView = Backbone.View.extend({
    className: 'response',

    template: _.template(template),

    responseEdits: {}, // changes to make to the responses object.

    events: {
      // Deleting
      'click .action-show-confirm': 'confirm',
      'click .action-delete': 'destroy',
      'click .cancel': 'cancel',

      // Editing
      'click .action-show-edit': 'edit',
      'click .action-save-edit': 'save',
      'click .action-cancel-edit': 'cancelEdit',
      'change .edit': 'questionEdited',

      // Flagging
      'click .action-flag': 'flag',
      'click .action-accept': 'accept'
    },

    initialize: function(options) {
      this.listenTo(this.model, "sync", this.render);
      this.listenTo(this.model, "destroy", this.remove);

      this.surveyOptions = options.surveyOptions || {};
      this.exploration = options.exploration;
      this.labels = options.labels;
      this.forms = options.forms;
    },

    makeAnswerLabels: function() {
      var form = this.forms.getFlattenedForm();
      var questions = {};
      _.each(form, function(question, key) {
        questions[key] = {};
        _.each(question.answers, function(answer) {
          questions[key][answer.value] = answer.text;
        });
      });
      return questions;
    },

    render: function() {
      var $el = $(this.el);

      // If this is meant for anonymous consumption, then ignore the fact
      // that the user might be logged in through the primary dashboard.
      // TODO: If the entire interface is meant for anonymous consumption,
      // then we should not even be asking the API for the user's info.
      if (this.surveyOptions.anonymous) {
        this.surveyOptions.loggedIn = false;
      } else {
        this.surveyOptions.loggedIn = settings.user && settings.user.isLoggedIn();
      }

      var responses = this.model.get('responses');
      var form = this.forms.getMostRecentForm().getFormV2();
      var fields = [];
      var processed = {};
      // Go through the questions in the latest form and map the question-answer slug pairs to text pairs.
      _.forEach(form.questions, function (question) {
        var valueSlug = responses[question.slug];
        var value;
        var key;
        // If there was a match, then we can use the text for this question.
        // Questions might be duplicated in a form becase of conditional
        // structures. Don't display a question/answer pair twice.
        if (valueSlug && !processed[question.slug]) {
          key = question.text;
          // If the value slug matches an answer, then we can also use the text for that answer.
          value = _.pluck(_.where(question.answers, { value: valueSlug}), 'text')[0];
          if (!value) {
            value = valueSlug;
          }
          fields.push({
            question: key,
            questionSlug: question.slug,
            answer: value,
            answerSlug: valueSlug,
            answerOptions: question.answers
          });
          processed[question.slug] = true;
        }
      });
      // Go through the full set of question-answer slug pairs in this entry and
      // add any that didn't map to the form.
      _.forEach(_.keys(responses).reverse(), function (key) {
        if (!processed[key]) {
          fields.push({
            question: key,
            questionSlug: key,
            answer: responses[key]
          });
        }
      });

      var options = {
        r: this.model.toJSON(),
        fields: fields,
        surveyOptions: this.surveyOptions,
        exploration: this.exploration
      };

      $el.html(this.template(options));
      return this;
    },

    // Deleting
    confirm: function(event) {
      event.preventDefault();
      this.$('.action-show-confirm').hide();
      this.$('.confirm-delete').show();
    },

    cancel: function(event) {
      event.preventDefault();
      this.$('.confirm-delete').hide();
      this.$('.action-show-confirm').show();
    },

    destroy: function(event) {
      event.preventDefault();

      function success(model, repsonse) {
      }

      function error(model, xhr, options) {
        console.log("Error destroying", xhr, options);
        console.log($('.error'));
        $('.error').show();
      }

      this.model.destroy({
        success: success,
        error: error
      });

      util.track('survey.response.delete');
    },

    // Editing
    edit: function(event) {
      event.preventDefault();
      util.track('survey.response.edit');

      this.$('.value').hide();
      this.$('.action-show-edit').hide();

      this.$('.edit').show();
      this.$('.action-save-edit').show();
      this.$('.action-cancel-edit').show();
    },

    questionEdited: function(event) {
      var question = $(event.target).attr('data-question');
      var answer = $(event.target).val();

      this.responseEdits[question] = answer;
    },

    cancelEdit: function(event) {
      event.preventDefault();
      util.track('survey.response.edit.cancel');

      // Show the values and edit button
      this.$('.value').show();
      this.$('.action-show-edit').show();

      // Hide the form and save / cancel buttons
      this.$('.edit').hide();
      this.$('.action-save-edit').hide();
      this.$('.action-cancel-edit').hide();

      // Fetch the attributes to make sure we have the latest version.
      this.model.fetch();
    },

    save: function(event) {
      event.preventDefault();
      util.track('survey.response.edit.save');

      this.model.save({
        responses: this.responseEdits
      }, {
        patch: true,
        wait: true, // wait until sync to update attributes
        success: function (event) {
          // We need to fetch the model because patch resets the local
          // attributes.
          this.model.fetch({ reset: true });
        }.bind(this)
      });
    },

    // Flagging
    flag: function(event) {
      event.preventDefault();
      util.track('survey.response.flag');

      this.model.save({
        responses: {
          reviewed: 'flagged'
        }
      }, {
        patch: true,
        wait: true, // wait until sync to update attributes
        success: function (event) {
          // We need to fetch the model because patch resets the local
          // attributes.
          this.model.fetch({ reset: true });
        }.bind(this)
      });
    },

    accept: function(event) {
      event.preventDefault();
      util.track('survey.response.accept');

      this.model.save({
        responses: {
          reviewed: 'accepted'
        }
      }, {
        patch: true,
        wait: true,
        success: function (event) {
          this.model.fetch({ reset: true });
        }.bind(this)
      });
    }
  });

  return ResponseView;
});
<commit_msg>Defend against null responses objects<commit_after>/*jslint nomen: true */
/*globals define: true */

define([
  'jquery',
  'lib/lodash',
  'backbone',
  'lib/tinypubsub',

  // LocalData
  'settings',
  'util',
  'api',

  // Models
  'models/responses',

  // Templates
  'text!templates/responses/item.html'
],

function($, _, Backbone, events, settings, util, api, Responses, template) {
  'use strict';

  var ResponseView = Backbone.View.extend({
    className: 'response',

    template: _.template(template),

    responseEdits: {}, // changes to make to the responses object.

    events: {
      // Deleting
      'click .action-show-confirm': 'confirm',
      'click .action-delete': 'destroy',
      'click .cancel': 'cancel',

      // Editing
      'click .action-show-edit': 'edit',
      'click .action-save-edit': 'save',
      'click .action-cancel-edit': 'cancelEdit',
      'change .edit': 'questionEdited',

      // Flagging
      'click .action-flag': 'flag',
      'click .action-accept': 'accept'
    },

    initialize: function(options) {
      this.listenTo(this.model, "sync", this.render);
      this.listenTo(this.model, "destroy", this.remove);

      this.surveyOptions = options.surveyOptions || {};
      this.exploration = options.exploration;
      this.labels = options.labels;
      this.forms = options.forms;
    },

    makeAnswerLabels: function() {
      var form = this.forms.getFlattenedForm();
      var questions = {};
      _.each(form, function(question, key) {
        questions[key] = {};
        _.each(question.answers, function(answer) {
          questions[key][answer.value] = answer.text;
        });
      });
      return questions;
    },

    render: function() {
      var $el = $(this.el);

      // If this is meant for anonymous consumption, then ignore the fact
      // that the user might be logged in through the primary dashboard.
      // TODO: If the entire interface is meant for anonymous consumption,
      // then we should not even be asking the API for the user's info.
      if (this.surveyOptions.anonymous) {
        this.surveyOptions.loggedIn = false;
      } else {
        this.surveyOptions.loggedIn = settings.user && settings.user.isLoggedIn();
      }

      var responses = this.model.get('responses') || {};
      var form = this.forms.getMostRecentForm().getFormV2();
      var fields = [];
      var processed = {};
      // Go through the questions in the latest form and map the question-answer slug pairs to text pairs.
      _.forEach(form.questions, function (question) {
        var valueSlug = responses[question.slug];
        var value;
        var key;
        // If there was a match, then we can use the text for this question.
        // Questions might be duplicated in a form becase of conditional
        // structures. Don't display a question/answer pair twice.
        if (valueSlug && !processed[question.slug]) {
          key = question.text;
          // If the value slug matches an answer, then we can also use the text for that answer.
          value = _.pluck(_.where(question.answers, { value: valueSlug}), 'text')[0];
          if (!value) {
            value = valueSlug;
          }
          fields.push({
            question: key,
            questionSlug: question.slug,
            answer: value,
            answerSlug: valueSlug,
            answerOptions: question.answers
          });
          processed[question.slug] = true;
        }
      });
      // Go through the full set of question-answer slug pairs in this entry and
      // add any that didn't map to the form.
      _.forEach(_.keys(responses).reverse(), function (key) {
        if (!processed[key]) {
          fields.push({
            question: key,
            questionSlug: key,
            answer: responses[key]
          });
        }
      });

      var r = this.model.toJSON();
      if (!r.responses) {
        r.responses = {};
      }

      var options = {
        r: r,
        fields: fields,
        surveyOptions: this.surveyOptions,
        exploration: this.exploration
      };

      $el.html(this.template(options));
      return this;
    },

    // Deleting
    confirm: function(event) {
      event.preventDefault();
      this.$('.action-show-confirm').hide();
      this.$('.confirm-delete').show();
    },

    cancel: function(event) {
      event.preventDefault();
      this.$('.confirm-delete').hide();
      this.$('.action-show-confirm').show();
    },

    destroy: function(event) {
      event.preventDefault();

      function success(model, repsonse) {
      }

      function error(model, xhr, options) {
        console.log("Error destroying", xhr, options);
        console.log($('.error'));
        $('.error').show();
      }

      this.model.destroy({
        success: success,
        error: error
      });

      util.track('survey.response.delete');
    },

    // Editing
    edit: function(event) {
      event.preventDefault();
      util.track('survey.response.edit');

      this.$('.value').hide();
      this.$('.action-show-edit').hide();

      this.$('.edit').show();
      this.$('.action-save-edit').show();
      this.$('.action-cancel-edit').show();
    },

    questionEdited: function(event) {
      var question = $(event.target).attr('data-question');
      var answer = $(event.target).val();

      this.responseEdits[question] = answer;
    },

    cancelEdit: function(event) {
      event.preventDefault();
      util.track('survey.response.edit.cancel');

      // Show the values and edit button
      this.$('.value').show();
      this.$('.action-show-edit').show();

      // Hide the form and save / cancel buttons
      this.$('.edit').hide();
      this.$('.action-save-edit').hide();
      this.$('.action-cancel-edit').hide();

      // Fetch the attributes to make sure we have the latest version.
      this.model.fetch();
    },

    save: function(event) {
      event.preventDefault();
      util.track('survey.response.edit.save');

      this.model.save({
        responses: this.responseEdits
      }, {
        patch: true,
        wait: true, // wait until sync to update attributes
        success: function (event) {
          // We need to fetch the model because patch resets the local
          // attributes.
          this.model.fetch({ reset: true });
        }.bind(this)
      });
    },

    // Flagging
    flag: function(event) {
      event.preventDefault();
      util.track('survey.response.flag');

      this.model.save({
        responses: {
          reviewed: 'flagged'
        }
      }, {
        patch: true,
        wait: true, // wait until sync to update attributes
        success: function (event) {
          // We need to fetch the model because patch resets the local
          // attributes.
          this.model.fetch({ reset: true });
        }.bind(this)
      });
    },

    accept: function(event) {
      event.preventDefault();
      util.track('survey.response.accept');

      this.model.save({
        responses: {
          reviewed: 'accepted'
        }
      }, {
        patch: true,
        wait: true,
        success: function (event) {
          this.model.fetch({ reset: true });
        }.bind(this)
      });
    }
  });

  return ResponseView;
});
<|endoftext|>


<commit_before>script =
    act: 0
    line: 0
    acts: [
        [
            "Hello world",
            "This is another line"
        ],
        [
            "We're starting a new story",
            "What do you want to talk about?"
        ]
    ]
txt = $ 'textarea'
running = false
showScriptStep = () ->
    return if script.act >= script.acts.length

    txt.val '' if script.line == 0

    act = script.acts[script.act]
    line = act[script.line].split ''
    line.reverse()
    running = true
    setTimeout go = () ->
        l = line.pop()
        if !l
            running = false
            l = '\r\n'

        txt.val txt.val() + l

        if running
            setTimeout ->
                go()
            , 50
    , 50

    script.line++
    if script.line >= act.length
        script.act++
        script.line = 0

$ ->
    txt.keypress (e) ->
        e.preventDefault

        switch e.keyCode
            when 13
                showScriptStep() if !running
            else
        return false
    $(window).resize ->
        w = $ this
        txt.height w.height() - 35
        txt.width w.width() - 15

    $(window).resize()<commit_msg>fixing the compliance with notepud<commit_after>script =
    [
        [
            "Hello world",
            "This is another line"
        ],
        [
            "We're starting a new story",
            "What do you want to talk about?"
        ]
    ].reverse()
txt = $ 'textarea'
act = script.pop()
line = act.reverse().pop().split ''
char = 0;
type = () ->
    if char >= line.length
        return

    txt.val txt.val() + line[char] if char < line.length

    char++
showNext = () ->
    txt.val txt.val() + '\r\n' if act && act.length
    if act.length == 0
        act = script.pop()
        if !act
            showNext = () ->
                return
            return
        txt.val ''
    line = act.reverse().pop().split ''
    char = 0

$ ->
    txt.keypress (e) ->
        e.preventDefault

        switch e.keyCode
            when 13
                showNext()
            else
                type()
        return false

    $(window).resize ->
        w = $ this
        txt.height w.height() - 35
        txt.width w.width() - 15

    $(window).resize()<|endoftext|>