<commit_before>/**
 * ngAuth 0.0.1
 * (c) 2014 Sahat Yalkabov <sahat@me.com>
 * License: MIT
 */

/**
 * $facebook.config(property) - Return the config property.
 $facebook.getAuthResponse() - Return the AuthResponse(assuming you already connected)
 $facebook.getLoginStatus() - Return promise of the result.
 $facebook.login() - Logged in to your app by facebook. Return promise of the result.
 $facebook.logout() - Logged out from facebook. Return promise of the result.
 $facebook.ui(params) - Do UI action(see facebook sdk docs). Return promise of the result.
 $facebook.api(args...) - Do API action(see facebook sdk docs). Return promise of the result.
 $facebook.cachedApi(args...) - Do API action(see above), but the result will cached. Return promise of the result.
 */

/*
 The service will broadcast the facebook sdk events with the prefix fb..

 In return you will get the next arguments to your $on handler: event,response,FB (FB is the facebook native js sdk).

 fb.auth.login
 fb.auth.logout
 fb.auth.prompt
 fb.auth.sessionChange
 fb.auth.statusChange
 fb.auth.authResponseChange
 fb.xfbml.render
 fb.edge.create
 fb.edge.remove
 fb.comment.create
 fb.comment.remove
 fb.message.send
 */

(function(window, angular, undefined) {
  'use strict';

  var config = {
    logoutRedirect: '/',
    loginRedirect: '/',
    loginUrl: '/auth/login',
    signupUrl: '/auth/signup',
    signupRedirect: '/login',
    userObject: 'currentUser',
    loginRoute: '/login',
    signupRoute: '/signup'
  };

  var providers = {
    google: {
      url: '/auth/google',
      authorizationEndpoint: 'https://accounts.google.com/o/oauth2/auth',
      redirectUri: window.location.origin,
      scope: 'openid profile email',
      requiredUrlParams: ['scope'],
      optionalUrlParams: ['display'],
      display: 'popup',
      type: 'OAuth2',
      popupOptions: {
        width: 452,
        height: 633
      }
    },
    facebook: {
      url: '/auth/facebook',
      authorizationEndpoint: 'https://www.facebook.com/dialog/oauth',
      redirectUri: window.location.origin,
      scope: 'email',
      requiredUrlParams: ['display'],
      display: 'popup',
      type: 'OAuth2',
      popupOptions: {
        width: 481,
        height: 269
      }
    },
    linkedin: {
      url: '/auth/linkedin',
      authorizationEndpoint: 'https://www.linkedin.com/uas/oauth2/authorization',
      redirectUri: window.location.origin,
      requiredUrlParams: ['state'],
      state: 'STATE',
      type: 'OAuth2'
    },
    twitter: {
      url: '/auth/twitter',
      authorizationEndpoint: 'https://api.twitter.com/oauth/authenticate',
      type: 'OAuth1'
    }
  };

  angular.module('ngAuth', []).provider('$auth', function() {

    this.config = config;

    // Configure an existing provider by supplying additional information
    // such as scope, clientId, redirectUri.
    this.setProvider = function(params) {
      if (!params.name) {
        throw new Error('You did not set a provider\'s name.');
      }

      if (!providers[params.name]) {
        throw new Error('Provider ' + params.name + ' is not found. Are you trying to add a custom provider? Use addProvider() instead.');
      }

      angular.extend(providers[params.name], params);
    };

    // Add a custom provider by supplying everything that setProvider
    // requires plus additional information like authorizationEndpoint
    // and requiredParameters.
    this.addProvider = function(params) {
      if (!params.name) {
        throw new Error('You did not set a provider\'s name.');
      }

      if (providers[params.name]) {
        throw new Error('Provider ' + params.name + ' already exists. Use setProvider() instead.');
      }

      providers[params.name] = {};
      angular.extend(providers[params.name], params);
    };

    this.$get = function($interval, $http, $location, $rootScope, $q, $window) {

      // **Popup** class. The *popup* property refers to the `window` object
      // of the browser popup and the *polling* property is an interval object
      // assigned by the `Popup.prototype.pollPopup` method.
      var Popup = function() {
        this.popup = null;
        this.polling = null;
      };

      // Opens the popup with the optional `options` object to specify width and
      // height of a popup. An event listener is then added to the parent window
      // to wait for the `message` event from the popup. Meanwhile popup is
      // polled to detect when popup is abruptly closed by the user. Returns
      // promise that is either **rejected** in the `pollPopup` or **resolved**
      // in the `postMessageHandler`.
      Popup.prototype.open = function(url, options) {
        var deferred = $q.defer();
        var optionsString = stringifyOptions(prepareOptions(options || { }));

        this.popup = $window.open(url, 'ngAuth', optionsString);
        this.popup.focus();

        this.postMessageHandler(deferred);
        this.pollPopup(deferred);

        return deferred.promise;
      };

      // Polls the popup every 35 milliseconds. If popup is closed by the user
      // intervall polling is cancelled and promise is rejected.
      Popup.prototype.pollPopup = function(deferred) {
        this.polling = $interval(function() {
          if (this.popup.closed) {
            $interval.cancel(this.polling);
            deferred.reject('Popup was closed by the user.');
          }
        }.bind(this), 35);
      };

      Popup.prototype.postMessageHandler = function(deferred) {
        $window.addEventListener('message', function(event) {
          if (event.origin === $window.location.origin) {
            deferred.resolve(event.data);
          }
        }.bind(this), false);
      };

      Popup.prototype.close = function() {
        if (this.popup) {
          this.popup.close();
          this.popup = null;
        }
      };

      function prepareOptions(options) {
        var width = options.width || 500;
        var height = options.height || 500;
        return angular.extend({
          left: ((window.screen.width / 2) - (width / 2)),
          top: ((window.screen.height / 2) - (height / 2)),
          width: width,
          height: height
        }, options);
      }

      function stringifyOptions(options) {
        var optionsStrings = [];
        for (var key in options) {
          if (options.hasOwnProperty(key)) {
            var value;
            switch (options[key]) {
              case true:
                value = '1';
                break;
              case false:
                value = '0';
                break;
              default:
                value = options[key];
            }
            optionsStrings.push(
                key + '=' + value
            );
          }
        }
        return optionsStrings.join(',');
      }

      /**
       * OAuth 1.0
       */
      var OAuth1 = function(config) {
        angular.extend(this, config);
        this.name = config.name;
        this.url = config.url;
        this.authorizationEndpoint = config.authorizationEndpoint;
        this.popupOptions = config.popupOptions;
      };

      OAuth1.prototype.tokenRequest = function() {
        return $http.post(this.url)
      };

      OAuth1.prototype.open = function() {
        var deferred = $q.defer();

        var popup = new Popup();
        popup.open(this.url).then(function(oauthData) {
          this.exchangeForToken(oauthData).then(function(response) {
            deferred.resolve(response.data);
          });
        }.bind(this));

        return deferred.promise;
      };

      OAuth1.prototype.exchangeForToken = function(oauthData) {
        return $http.get(this.url, { params: oauthData });
      };

      /**
       * OAuth 2.0
       */
      var OAuth2 = function(config) {
        angular.extend(this, config); // TODO: define all possible properties, then no need to extend
        this.name = config.name;
        this.clientId = config.clientId;
        this.scope = config.scope;
        this.authorizationEndpoint = config.authorizationEndpoint;
        this.redirectUri = config.redirectUri;
        this.responseType = 'code';
        this.defaultUrlParams = ['response_type', 'client_id', 'redirect_uri'];
        this.requiredUrlParams = config.requiredUrlParams;
        this.optionalUrlParams = config.optionalUrlParams;
        this.popupOptions = config.popupOptions;
      };

      OAuth2.prototype.open = function() {
        var deferred = $q.defer();
        var url = this.buildUrl();
        var popup = new Popup();

        popup.open(url, this.popupOptions).then(function(oauthData) {
          this.exchangeForToken(oauthData).then(function(response) {
            deferred.resolve(response.data);
          });
        }.bind(this));

        return deferred.promise;
      };

      OAuth2.prototype.exchangeForToken = function(oauthData) {
        return $http.post(this.url, {
          code: oauthData.code,
          clientId: this.clientId,
          redirectUri: this.redirectUri
        });
      };

      OAuth2.prototype.buildUrl = function() {
        var baseUrl = this.authorizationEndpoint;
        var qs = this.buildQueryString();
        return [baseUrl, qs].join('?');
      };

      OAuth2.prototype.buildQueryString = function() {
        var obj = this;
        var keyValuePairs = [];

        angular.forEach(this.defaultUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        angular.forEach(this.requiredUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        angular.forEach(this.optionalUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        return keyValuePairs.map(function(pair) {
          return pair.join('=');
        }).join('&');
      };

      // loginWithUsername
      // loginWithOauth withThirdParty
      return {
        authenticate: function(providerName, options) {
          if (!providerName) {
            return $q.reject('Expected a provider named \'' + providerName + '\', did you forget to add it?');
          }

          if (providers[providerName].type === 'OAuth1') {
            var provider;
            provider = new OAuth1(providers[providerName]);
          } else {

            provider = new OAuth2(providers[providerName]);
          }

          var deferred = $q.defer();

          provider.open(options).then(function(token) {
            var payload = JSON.parse($window.atob(token.split('.')[1]));
            $window.localStorage.token = token;
            $rootScope.currentUser = payload.user;
            $location.path(config.loginRedirect);
            deferred.resolve();
          });

          return deferred.promise;
        },

        login: function(user) {
          if (!user) throw new Error('Must take a user object.')
          var deferred = $q.defer();
          $http.post(config.loginUrl, user)
            .success(function(data) {
              $window.localStorage.token = data.token;
              var payload = JSON.parse($window.atob(data.token.split('.')[1]));
              $rootScope.currentUser = payload.user;
              $location.path(config.loginRedirect);
              deferred.resolve(payload.user);
            })
            .error(function(error) {
              deferred.reject(error);
            });
          return deferred.promise;
        },
        signup: function(user) {
          return $http.post(config.signupUrl, user).success(function() {
            $location.path(config.signupRedirect);
          });
        },
        logout: function() {
          delete $window.localStorage.token;
          $rootScope.currentUser = null;
          $location.path(config.logoutRedirect);
        },
        isAuthenticated: function() {
          return Boolean($rootScope.currentUser);
        }
      };
    };

  })
    .factory('authInterceptor', function($q, $window, $location) {
      return {
        request: function(config) {
          if ($window.localStorage.token) {
            config.headers.Authorization = 'Bearer ' + $window.localStorage.token;
          }
          return config;
        },
        responseError: function(response) {
          if (response.status === 401 || response.status === 403) {
            $location.path('/login');
          }
          return $q.reject(response);
        }
      }
    })
    .config(function($httpProvider) {
      $httpProvider.interceptors.push('authInterceptor');
    })
    .run(function($rootScope, $window, $location) {
      var token = $window.localStorage.token;
      if (token) {
        var payload = JSON.parse($window.atob(token.split('.')[1]));
        $rootScope.currentUser = payload.user;
      }

      var params = $window.location.search.substring(1);
      var qs = parseQueryString(params);
      if ($window.opener && $window.opener.location.origin === $window.location.origin) {
        if (qs.oauth_token && qs.oauth_verifier) {
          $window.opener.postMessage({ oauth_token: qs.oauth_token, oauth_verifier: qs.oauth_verifier }, '*');
        } else if (qs.code) {
          $window.opener.postMessage({ code: qs.code }, '*');
        }
        $window.close();
      }

      $rootScope.$on('$routeChangeStart', function(event, current, previous) {
        if ($rootScope.currentUser &&
          (current.originalPath === '/login' || current.originalPath === '/signup')) {
          $location.path('/');
        }
        if (current.authenticated && !$rootScope.currentUser) {
          $location.path('/login');
        }
      });
    });

  function parseQueryString(keyValue) {
    var obj = { }, key, value;
    angular.forEach((keyValue || '').split('&'), function(keyValue) {
      if (keyValue) {
        value = keyValue.split('=');
        key = decodeURIComponent(value[0]);
        obj[key] = angular.isDefined(value[1]) ? decodeURIComponent(value[1]) : true;
      }
    });
    return obj;
  }

  function camelCase(name) {
    return name.replace(/([\:\-\_]+(.))/g, function(_, separator, letter, offset) {
      return offset ? letter.toUpperCase() : letter;
    });
  }
})(window, window.angular);

<commit_msg>removed popup.prototype.close() added comments<commit_after>/**
 * ngAuth 0.0.1
 * (c) 2014 Sahat Yalkabov <sahat@me.com>
 * License: MIT
 */

/**
 * $facebook.config(property) - Return the config property.
 $facebook.getAuthResponse() - Return the AuthResponse(assuming you already connected)
 $facebook.getLoginStatus() - Return promise of the result.
 $facebook.login() - Logged in to your app by facebook. Return promise of the result.
 $facebook.logout() - Logged out from facebook. Return promise of the result.
 $facebook.ui(params) - Do UI action(see facebook sdk docs). Return promise of the result.
 $facebook.api(args...) - Do API action(see facebook sdk docs). Return promise of the result.
 $facebook.cachedApi(args...) - Do API action(see above), but the result will cached. Return promise of the result.
 */

/*
 The service will broadcast the facebook sdk events with the prefix fb..

 In return you will get the next arguments to your $on handler: event,response,FB (FB is the facebook native js sdk).

 fb.auth.login
 fb.auth.logout
 fb.auth.prompt
 fb.auth.sessionChange
 fb.auth.statusChange
 fb.auth.authResponseChange
 fb.xfbml.render
 fb.edge.create
 fb.edge.remove
 fb.comment.create
 fb.comment.remove
 fb.message.send
 */

(function(window, angular, undefined) {
  'use strict';

  var config = {
    logoutRedirect: '/',
    loginRedirect: '/',
    loginUrl: '/auth/login',
    signupUrl: '/auth/signup',
    signupRedirect: '/login',
    userObject: 'currentUser',
    loginRoute: '/login',
    signupRoute: '/signup'
  };

  var providers = {
    google: {
      url: '/auth/google',
      authorizationEndpoint: 'https://accounts.google.com/o/oauth2/auth',
      redirectUri: window.location.origin,
      scope: 'openid profile email',
      requiredUrlParams: ['scope'],
      optionalUrlParams: ['display'],
      display: 'popup',
      type: 'OAuth2',
      popupOptions: {
        width: 452,
        height: 633
      }
    },
    facebook: {
      url: '/auth/facebook',
      authorizationEndpoint: 'https://www.facebook.com/dialog/oauth',
      redirectUri: window.location.origin,
      scope: 'email',
      requiredUrlParams: ['display'],
      display: 'popup',
      type: 'OAuth2',
      popupOptions: {
        width: 481,
        height: 269
      }
    },
    linkedin: {
      url: '/auth/linkedin',
      authorizationEndpoint: 'https://www.linkedin.com/uas/oauth2/authorization',
      redirectUri: window.location.origin,
      requiredUrlParams: ['state'],
      state: 'STATE',
      type: 'OAuth2'
    },
    twitter: {
      url: '/auth/twitter',
      authorizationEndpoint: 'https://api.twitter.com/oauth/authenticate',
      type: 'OAuth1'
    }
  };

  angular.module('ngAuth', []).provider('$auth', function() {

    this.config = config;

    // Configure an existing provider by supplying additional information
    // such as scope, clientId, redirectUri.
    this.setProvider = function(params) {
      if (!params.name) {
        throw new Error('You did not set a provider\'s name.');
      }

      if (!providers[params.name]) {
        throw new Error('Provider ' + params.name + ' is not found. Are you trying to add a custom provider? Use addProvider() instead.');
      }

      angular.extend(providers[params.name], params);
    };

    // Add a custom provider by supplying everything that setProvider
    // requires plus additional information like authorizationEndpoint
    // and requiredParameters.
    this.addProvider = function(params) {
      if (!params.name) {
        throw new Error('You did not set a provider\'s name.');
      }

      if (providers[params.name]) {
        throw new Error('Provider ' + params.name + ' already exists. Use setProvider() instead.');
      }

      providers[params.name] = {};
      angular.extend(providers[params.name], params);
    };

    this.$get = function($interval, $http, $location, $rootScope, $q, $window) {

      // **Popup** constructor. The *popup* property refers to the `window`
      // object of the browser popup and the *polling* property is an interval
      // object assigned by the `Popup.prototype.pollPopup` method.
      var Popup = function() {
        this.popup = null;
        this.polling = null;
      };

      // Opens the popup with the optional `options` object to specify width and
      // height of a popup. An event listener is then added to the parent window
      // to wait for the `message` event from the popup. Meanwhile popup is
      // polled to detect when popup is abruptly closed by the user. Returns
      // promise that is either **rejected** in the `pollPopup` or **resolved**
      // in the `postMessageHandler`.
      Popup.prototype.open = function(url, options) {
        var deferred = $q.defer();
        var optionsString = stringifyOptions(prepareOptions(options || { }));

        this.popup = $window.open(url, 'ngAuth', optionsString);
        this.popup.focus();

        this.postMessageHandler(deferred);
        this.pollPopup(deferred);

        return deferred.promise;
      };

      // Polls the popup every 35 milliseconds. If popup is closed by the user
      // intervall polling is cancelled and promise is rejected.
      Popup.prototype.pollPopup = function(deferred) {
        this.polling = $interval(function() {
          if (this.popup.closed) {
            $interval.cancel(this.polling);
            deferred.reject('Popup was closed by the user.');
          }
        }.bind(this), 35);
      };

      // Listens for the *message* event that contains an `authorization_code`
      // string.
      Popup.prototype.postMessageHandler = function(deferred) {
        $window.addEventListener('message', function(event) {
          if (event.origin === $window.location.origin) {
            deferred.resolve(event.data);
          }
        }, false);
      };

      function prepareOptions(options) {
        var width = options.width || 500;
        var height = options.height || 500;
        return angular.extend({
          left: ((window.screen.width / 2) - (width / 2)),
          top: ((window.screen.height / 2) - (height / 2)),
          width: width,
          height: height
        }, options);
      }

      function stringifyOptions(options) {
        var optionsStrings = [];
        for (var key in options) {
          if (options.hasOwnProperty(key)) {
            var value;
            switch (options[key]) {
              case true:
                value = '1';
                break;
              case false:
                value = '0';
                break;
              default:
                value = options[key];
            }
            optionsStrings.push(
                key + '=' + value
            );
          }
        }
        return optionsStrings.join(',');
      }

      /**
       * OAuth 1.0
       */
      var OAuth1 = function(config) {
        angular.extend(this, config);
        this.name = config.name;
        this.url = config.url;
        this.authorizationEndpoint = config.authorizationEndpoint;
        this.popupOptions = config.popupOptions;
      };

      OAuth1.prototype.tokenRequest = function() {
        return $http.post(this.url)
      };

      OAuth1.prototype.open = function() {
        var deferred = $q.defer();

        var popup = new Popup();
        popup.open(this.url).then(function(oauthData) {
          this.exchangeForToken(oauthData).then(function(response) {
            deferred.resolve(response.data);
          });
        }.bind(this));

        return deferred.promise;
      };

      OAuth1.prototype.exchangeForToken = function(oauthData) {
        return $http.get(this.url, { params: oauthData });
      };

      /**
       * OAuth 2.0
       */
      var OAuth2 = function(config) {
        angular.extend(this, config); // TODO: define all possible properties, then no need to extend
        this.name = config.name;
        this.clientId = config.clientId;
        this.scope = config.scope;
        this.authorizationEndpoint = config.authorizationEndpoint;
        this.redirectUri = config.redirectUri;
        this.responseType = 'code';
        this.defaultUrlParams = ['response_type', 'client_id', 'redirect_uri'];
        this.requiredUrlParams = config.requiredUrlParams;
        this.optionalUrlParams = config.optionalUrlParams;
        this.popupOptions = config.popupOptions;
      };

      OAuth2.prototype.open = function() {
        var deferred = $q.defer();
        var url = this.buildUrl();
        var popup = new Popup();

        popup.open(url, this.popupOptions).then(function(oauthData) {
          this.exchangeForToken(oauthData).then(function(response) {
            deferred.resolve(response.data);
          });
        }.bind(this));

        return deferred.promise;
      };

      OAuth2.prototype.exchangeForToken = function(oauthData) {
        return $http.post(this.url, {
          code: oauthData.code,
          clientId: this.clientId,
          redirectUri: this.redirectUri
        });
      };

      OAuth2.prototype.buildUrl = function() {
        var baseUrl = this.authorizationEndpoint;
        var qs = this.buildQueryString();
        return [baseUrl, qs].join('?');
      };

      OAuth2.prototype.buildQueryString = function() {
        var obj = this;
        var keyValuePairs = [];

        angular.forEach(this.defaultUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        angular.forEach(this.requiredUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        angular.forEach(this.optionalUrlParams, function(paramName) {
          var camelizedName = camelCase(paramName);
          var paramValue = obj[camelizedName];
          keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
        });

        return keyValuePairs.map(function(pair) {
          return pair.join('=');
        }).join('&');
      };

      // loginWithUsername
      // loginWithOauth withThirdParty
      return {
        authenticate: function(providerName, options) {
          if (!providerName) {
            return $q.reject('Expected a provider named \'' + providerName + '\', did you forget to add it?');
          }

          if (providers[providerName].type === 'OAuth1') {
            var provider;
            provider = new OAuth1(providers[providerName]);
          } else {

            provider = new OAuth2(providers[providerName]);
          }

          var deferred = $q.defer();

          provider.open(options).then(function(token) {
            var payload = JSON.parse($window.atob(token.split('.')[1]));
            $window.localStorage.token = token;
            $rootScope.currentUser = payload.user;
            $location.path(config.loginRedirect);
            deferred.resolve();
          });

          return deferred.promise;
        },

        login: function(user) {
          if (!user) throw new Error('Must take a user object.')
          var deferred = $q.defer();
          $http.post(config.loginUrl, user)
            .success(function(data) {
              $window.localStorage.token = data.token;
              var payload = JSON.parse($window.atob(data.token.split('.')[1]));
              $rootScope.currentUser = payload.user;
              $location.path(config.loginRedirect);
              deferred.resolve(payload.user);
            })
            .error(function(error) {
              deferred.reject(error);
            });
          return deferred.promise;
        },
        signup: function(user) {
          return $http.post(config.signupUrl, user).success(function() {
            $location.path(config.signupRedirect);
          });
        },
        logout: function() {
          delete $window.localStorage.token;
          $rootScope.currentUser = null;
          $location.path(config.logoutRedirect);
        },
        isAuthenticated: function() {
          return Boolean($rootScope.currentUser);
        }
      };
    };

  })
    .factory('authInterceptor', function($q, $window, $location) {
      return {
        request: function(config) {
          if ($window.localStorage.token) {
            config.headers.Authorization = 'Bearer ' + $window.localStorage.token;
          }
          return config;
        },
        responseError: function(response) {
          if (response.status === 401 || response.status === 403) {
            $location.path('/login');
          }
          return $q.reject(response);
        }
      }
    })
    .config(function($httpProvider) {
      $httpProvider.interceptors.push('authInterceptor');
    })
    .run(function($rootScope, $window, $location) {
      var token = $window.localStorage.token;
      if (token) {
        var payload = JSON.parse($window.atob(token.split('.')[1]));
        $rootScope.currentUser = payload.user;
      }

      var params = $window.location.search.substring(1);
      var qs = parseQueryString(params);
      if ($window.opener && $window.opener.location.origin === $window.location.origin) {
        if (qs.oauth_token && qs.oauth_verifier) {
          $window.opener.postMessage({ oauth_token: qs.oauth_token, oauth_verifier: qs.oauth_verifier }, '*');
        } else if (qs.code) {
          $window.opener.postMessage({ code: qs.code }, '*');
        }
        $window.close();
      }

      $rootScope.$on('$routeChangeStart', function(event, current, previous) {
        if ($rootScope.currentUser &&
          (current.originalPath === '/login' || current.originalPath === '/signup')) {
          $location.path('/');
        }
        if (current.authenticated && !$rootScope.currentUser) {
          $location.path('/login');
        }
      });
    });

  function parseQueryString(keyValue) {
    var obj = { }, key, value;
    angular.forEach((keyValue || '').split('&'), function(keyValue) {
      if (keyValue) {
        value = keyValue.split('=');
        key = decodeURIComponent(value[0]);
        obj[key] = angular.isDefined(value[1]) ? decodeURIComponent(value[1]) : true;
      }
    });
    return obj;
  }

  function camelCase(name) {
    return name.replace(/([\:\-\_]+(.))/g, function(_, separator, letter, offset) {
      return offset ? letter.toUpperCase() : letter;
    });
  }
})(window, window.angular);

<|endoftext|>


<commit_before>var tileRadius = 20;
var boardSize = 10;

var tileData = [
  // letter, value, frequency
  ['A', 0, 7],
  ['B', 2, 3],
  ['C', 2, 3],
  ['D', 1, 3],
  ['E', 0, 10],
  ['F', 2, 3],
  ['G', 2, 4],
  ['H', 3, 2],
  ['I', 0, 7],
  ['J', 4, 1],
  ['K', 3, 2],
  ['L', 0, 4],
  ['M', 2, 3],
  ['N', 1, 4],
  ['O', 0, 7],
  ['P', 2, 3],
  ['Q', 4, 1],
  ['R', 1, 5],
  ['S', 1, 5],
  ['T', 1, 5],
  ['U', 1, 4],
  ['V', 4, 1],
  ['W', 3, 3],
  ['X', 4, 1],
  ['Y', 3, 2],
  ['Z', 4, 1],
  [' ', 0, 2]
];

var Game = Backbone.Model.extend({
  initialize: function () {
    this.board = new Board({ game: this });
    this.makeAllTiles(tileData);

    this.board.placeTiles(this.tiles);

    this.selected = [];
    this.total = 0;
  },

  makeAllTiles: function (tileData) {
    this.tiles = [];
    var game = this;
    $.each(tileData, function (_, args) {
      game.makeTiles.apply(game, args);
    });
    $.shuffle(this.tiles);
  },

  makeTiles: function (letter, value, freq) {
    for (var i = 0; i < freq; i++) {
      this.tiles.push(new Tile({ game: this, letter: letter, value: value }));
    }
  },

  select: function (tile) {
    this.selected.push(tile);
  },

  unselect: function (tile) {
    this.selected.splice(this.selected.indexOf(tile), 1);
  },

  reset: function () {
    while (this.selected.length > 0) {
      var tile = this.selected[0];
      tile.origin.placeTile(tile);
      tile.view.position({ my: 'left top', at: 'left top', of: tile.origin.view,
                           collision: 'none' });
    }
  },

  updateWord: function () {
    this.set('word', this.getWord());
  },

  getWord: function () {
    tiles = this.selected;
    if (tiles.length > 1) {
      tiles.sort(function (a, b) {
        if (a == b) return 0;
        var as = a.space, bs = b.space;
        return (as.r < bs.r || as.r == bs.r && as.c < bs.c) ? -1 : 1;
      });
      var origin = tiles[0].space;
      var space = tiles[1].space
      var Δr = space.r - origin.r, Δc = space.c - origin.c;
      if (Δr >= -1 && Δr <= 1 && Δc >= -1 && Δc <= 1) {
        for (var i = 2; i < tiles.length; i++) {
          var next = tiles[i].space;
          if (next.r - space.r != Δr || next.c - space.c != Δc) return;
          space = next;
        }
        var letters = $.map(tiles, function (tile) { return tile.letter; });
        return letters.join('');
      }
    }
  },

  score: function () {
    if (this.get('word')) {
      var sum = 0;
      $.each(this.selected, function (_, tile) { sum += tile.value; });
      return sum * this.selected.length;
    }
  },

  scoreWord: function () {
    var score = this.score();
    $.each(this.selected, function (_, tile) { tile.remove(); });
    this.selected = [];
    this.total += score;
    this.updateWord();
  }
});

var Board = Backbone.Model.extend({
  initialize: function (attrs) {
    this.game = attrs.game;
    this.makeSpaces();
  },

  makeSpaces: function () {
    this.spaces = [];
    for (var r = 0; r < boardSize; r++) {
      this.spaces.push([]);
      for (var c = 0; c < boardSize; c++) {
        this.makeSpace(r, c);
      }
    }
  },

  makeSpace: function (r, c) {
    var space = new Space({ board: this, r: r, c: c });
    this.spaces[r][c] = space;
  },

  spaceAt: function (r, c) {
    return this.spaces[r][c];
  },

  placeTiles: function (tiles) {
    for (var r = 0; r < boardSize; r++) {
      for (var c = 0; c < boardSize; c++) {
        if (r < boardSize/2 - 1 || r > boardSize/2 ||
            c < boardSize/2 - 1 || c > boardSize/2) {
          this.placeTile(tiles.pop(), r, c);
        }
      }
    }
  },

  placeTile: function (tile, r, c) {
    var space = this.spaceAt(r, c);
    tile.origin = space;
    space.placeTile(tile, true);
    tile.board = this;
  }
});

var Space = Backbone.Model.extend({
  initialize: function (attrs) {
    this.board = attrs.board;
    this.r = attrs.r;
    this.c = attrs.c;
  },

  placeTile: function (tile, noUpdate) {
    var oldSpace = tile.space;
    if (oldSpace) oldSpace.tile = null;
    this.tile = tile;
    tile.space = this;

    if (!noUpdate) tile.updateHighlight();
  },

  isBetween: function (s1, s2) {
    // TO DO: I suspect there is a simpler/quicker way to compute this.
    return (s1.r - s2.r)*(s1.c - this.c) == (s1.c - s2.c)*(s1.r - this.r) &&
      (s1.r <= this.r && this.r <= s2.r || s2.r <= this.r && this.r <= s1.r) &&
      (s1.c <= this.c && this.c <= s2.c || s2.c <= this.c && this.c <= s1.c);
  }
});

function drawCircle(canvas, p) {
  p.radius = p.radius || tileRadius;
  p.width = p.height = 2*p.radius;
  p.strokeStyle = p.strokeStyle || 'black';
  canvas.drawEllipse(p);
}

var Tile = Backbone.Model.extend({
  initialize: function (attrs) {
    this.game = attrs.game;
    this.letter = attrs.letter;
    this.value = attrs.value;
  },

  legalSpaces: function () {
    var tile = this;
    var board = this.board;
    var r0 = this.origin.r;
    var c0 = this.origin.c;
    var spaces = [];
    if (!this.origin.tile) {
      // A tile can't move back to its origin if it would be in the
      // way of another tile that's already moved.
      if ($.grep(this.game.selected, function (movedTile) {
        return tile != movedTile &&
          tile.origin.isBetween(movedTile.origin, movedTile.space);
      }).length == 0) {
        spaces.push(this.origin);
      }
    }
    $.each([-1, 0, 1], function (_, Δr) {
      $.each([-1, 0, 1], function (_, Δc) {
        if (Δr || Δc) {
          for (var i = 1; i < boardSize; i++) {
            var r = r0 + i*Δr;
            var c = c0 + i*Δc;
            if (r < 0 || r >= boardSize || c < 0 || c >= boardSize) break;
            var space = board.spaceAt(r, c);
            if (space == tile.origin) break;
            var tileInSpace = space.tile;
            if (tileInSpace && tileInSpace != tile) break;
            spaces.push(space);
          }
        }
      });
    });
    return spaces;
  },

  updateHighlight: function () {
    if (this.space == this.origin) {
      this.unhighlight();
    } else {
      this.highlight();
    }
  },

  highlight: function () {
    if (!this.highlit) {
      this.highlit = true;
      this.game.select(this);
      var canvas = this.view.find('canvas');
      canvas.addLayer({
        method: 'drawEllipse',
        strokeStyle: 'red',
        strokeWidth: 5,
        x: tileRadius*1.5,
        y: tileRadius*1.5,
        width: (tileRadius+3)*2,
        height: (tileRadius+3)*2
      });
      canvas.drawLayers();
    }
    this.game.updateWord();
  },

  unhighlight: function () {
    if (this.highlit) {
      this.highlit = false;
      this.game.unselect(this);
      var canvas = this.view.find('canvas');
      canvas.removeLayer(1);
      canvas.drawLayers();
    }
    this.game.updateWord();
  },

  remove: function () {
    this.view.css('visibility', 'hidden');
    this.space.tile = null;
  }
});

var GameView = Backbone.View.extend({
  initialize: function (attrs) {
    var game = this.model;
    var view = this.$el;
    game.view = view;

    view.width(tileRadius*boardSize*3);
    view.height(tileRadius*boardSize*3);

    new BoardView({ model: game.board, parent: view });

    game.on('change', this.render, this);
  },

  render: function () {
    var word = this.model.get('word');
    $('#word').text(word || '');
    $('#score').text(word ? '= ' + this.model.score() : '');
    $('#scoreButton').attr('disabled', !word);
    $('#total').text(this.model.total);
    return this;
  }
});

var BoardView = Backbone.View.extend({
  id: 'board',

  initialize: function (opts) {
    var board = this.model;
    var view = this.$el;
    board.view = view;

    view.appendTo(opts.parent);
    view.width(tileRadius*boardSize*3);
    view.height(tileRadius*boardSize*3);

    for (var r = 0; r < boardSize; r++) {
      for (var c = 0; c < boardSize; c++) {
        new SpaceView({ model: board.spaces[r][c], parent: view });
      }
    }
  }
});

var SpaceView = Backbone.View.extend({
  tagName: 'canvas',
  className: 'space',

  initialize: function (opts) {
    var space = this.model;
    var view = this.$el;
    view.data('model', space);
    space.view = view;

    view.appendTo(opts.parent);
    view.attr('width', tileRadius*3);
    view.attr('height', tileRadius*3);
    drawCircle(view, { x: tileRadius*1.5, y: tileRadius*1.5 });

    view.position({ my: 'left top', at: 'left top', of: opts.parent,
                    collision: 'none',
                    offset: space.c*tileRadius*3 + ' ' + space.r*tileRadius*3 });

    if (space.tile) {
      new TileView({ model: space.tile, parent: space.board.game.view});
    }
  }
});

var TileView = Backbone.View.extend({
  className: 'tile',

  initialize: function (opts) {
    var tile = this.model;
    var view = this.$el;
    view.data('model', tile);
    tile.view = view;

    view.appendTo(opts.parent);
    view.width(tileRadius*3);
    view.height(tileRadius*3);

    var canvas = $('<canvas />').appendTo(view);
    canvas.attr('width', tileRadius*3);
    canvas.attr('height', tileRadius*3);
    canvas.addLayer({
      method: 'drawEllipse',
      x: tileRadius*1.5,
      y: tileRadius*1.5,
      width: tileRadius*2,
      height: tileRadius*2,
      strokeStyle: 'black',
      fillStyle: 'tan'
    });
    canvas.drawLayers();

    var label = $('
').appendTo(view);
    $('
' + tile.letter + '
').appendTo(label);
    if (tile.value) {
      $('' + tile.value + '').appendTo(label);
    }
    label.position({ my: 'center', at: 'center', of: canvas });

    view.position({ my: 'left top', at: 'left top', of: tile.space.view,
                    collision: 'none' });

    view.mouseup(function (e) {
      if (!tile.highlit) {
        tile.highlight();
      } else {
        tile.updateHighlight();
      }
    });

    view.draggable({
      distance: 5,
      stack: '.tile',
      revert: function (space) {
        if (!space) {
          tile.updateHighlight();
          return true;
        } else {
          space.data('model').placeTile(tile);
          view.position({ my: 'left top', at: 'left top', of: space,
                          collision: 'none' });
          return false;
        }
      },
      revertDuration: 200,
      start: function (e) {
        $.each(tile.legalSpaces(), function (_, space) {
          space.view.droppable();
        });
      },
      stop: function (e) {
        // This bypasses the mouseup handler, because highlighting is
        // updated in the revert function.
        e.stopImmediatePropagation();
        $('.space').droppable('destroy');
      }
    });
  }
});

var game;
var gameView;

function main() {
  game = new Game();
  gameView = new GameView({ model: game, el: $('#wordsearch') });
}

$(main);
<commit_msg>Use an event handler to move a tile view.<commit_after>var tileRadius = 20;
var boardSize = 10;

var tileData = [
  // letter, value, frequency
  ['A', 0, 7],
  ['B', 2, 3],
  ['C', 2, 3],
  ['D', 1, 3],
  ['E', 0, 10],
  ['F', 2, 3],
  ['G', 2, 4],
  ['H', 3, 2],
  ['I', 0, 7],
  ['J', 4, 1],
  ['K', 3, 2],
  ['L', 0, 4],
  ['M', 2, 3],
  ['N', 1, 4],
  ['O', 0, 7],
  ['P', 2, 3],
  ['Q', 4, 1],
  ['R', 1, 5],
  ['S', 1, 5],
  ['T', 1, 5],
  ['U', 1, 4],
  ['V', 4, 1],
  ['W', 3, 3],
  ['X', 4, 1],
  ['Y', 3, 2],
  ['Z', 4, 1],
  [' ', 0, 2]
];

var Game = Backbone.Model.extend({
  initialize: function () {
    this.board = new Board({ game: this });
    this.makeAllTiles(tileData);

    this.board.placeTiles(this.tiles);

    this.selected = [];
    this.total = 0;
  },

  makeAllTiles: function (tileData) {
    this.tiles = [];
    var game = this;
    $.each(tileData, function (_, args) {
      game.makeTiles.apply(game, args);
    });
    $.shuffle(this.tiles);
  },

  makeTiles: function (letter, value, freq) {
    for (var i = 0; i < freq; i++) {
      this.tiles.push(new Tile({ game: this, letter: letter, value: value }));
    }
  },

  select: function (tile) {
    this.selected.push(tile);
  },

  unselect: function (tile) {
    this.selected.splice(this.selected.indexOf(tile), 1);
  },

  reset: function () {
    while (this.selected.length > 0) {
      var tile = this.selected[0];
      tile.origin.placeTile(tile);
    }
  },

  updateWord: function () {
    this.set('word', this.getWord());
  },

  getWord: function () {
    tiles = this.selected;
    if (tiles.length > 1) {
      tiles.sort(function (a, b) {
        if (a == b) return 0;
        var as = a.space, bs = b.space;
        return (as.r < bs.r || as.r == bs.r && as.c < bs.c) ? -1 : 1;
      });
      var origin = tiles[0].space;
      var space = tiles[1].space
      var Δr = space.r - origin.r, Δc = space.c - origin.c;
      if (Δr >= -1 && Δr <= 1 && Δc >= -1 && Δc <= 1) {
        for (var i = 2; i < tiles.length; i++) {
          var next = tiles[i].space;
          if (next.r - space.r != Δr || next.c - space.c != Δc) return;
          space = next;
        }
        var letters = $.map(tiles, function (tile) { return tile.letter; });
        return letters.join('');
      }
    }
  },

  score: function () {
    if (this.get('word')) {
      var sum = 0;
      $.each(this.selected, function (_, tile) { sum += tile.value; });
      return sum * this.selected.length;
    }
  },

  scoreWord: function () {
    var score = this.score();
    $.each(this.selected, function (_, tile) { tile.remove(); });
    this.selected = [];
    this.total += score;
    this.updateWord();
  }
});

var Board = Backbone.Model.extend({
  initialize: function (attrs) {
    this.game = attrs.game;
    this.makeSpaces();
  },

  makeSpaces: function () {
    this.spaces = [];
    for (var r = 0; r < boardSize; r++) {
      this.spaces.push([]);
      for (var c = 0; c < boardSize; c++) {
        this.makeSpace(r, c);
      }
    }
  },

  makeSpace: function (r, c) {
    var space = new Space({ board: this, r: r, c: c });
    this.spaces[r][c] = space;
  },

  spaceAt: function (r, c) {
    return this.spaces[r][c];
  },

  placeTiles: function (tiles) {
    for (var r = 0; r < boardSize; r++) {
      for (var c = 0; c < boardSize; c++) {
        if (r < boardSize/2 - 1 || r > boardSize/2 ||
            c < boardSize/2 - 1 || c > boardSize/2) {
          this.placeTile(tiles.pop(), r, c);
        }
      }
    }
  },

  placeTile: function (tile, r, c) {
    var space = this.spaceAt(r, c);
    tile.origin = space;
    space.placeTile(tile, true);
    tile.board = this;
  }
});

var Space = Backbone.Model.extend({
  initialize: function (attrs) {
    this.board = attrs.board;
    this.r = attrs.r;
    this.c = attrs.c;
  },

  placeTile: function (tile, noUpdate) {
    var oldSpace = tile.space;
    if (oldSpace) oldSpace.tile = null;
    this.tile = tile;
    tile.setSpace(this);

    if (!noUpdate) tile.updateHighlight();
  },

  isBetween: function (s1, s2) {
    // TO DO: I suspect there is a simpler/quicker way to compute this.
    return (s1.r - s2.r)*(s1.c - this.c) == (s1.c - s2.c)*(s1.r - this.r) &&
      (s1.r <= this.r && this.r <= s2.r || s2.r <= this.r && this.r <= s1.r) &&
      (s1.c <= this.c && this.c <= s2.c || s2.c <= this.c && this.c <= s1.c);
  }
});

function drawCircle(canvas, p) {
  p.radius = p.radius || tileRadius;
  p.width = p.height = 2*p.radius;
  p.strokeStyle = p.strokeStyle || 'black';
  canvas.drawEllipse(p);
}

var Tile = Backbone.Model.extend({
  initialize: function (attrs) {
    this.game = attrs.game;
    this.letter = attrs.letter;
    this.value = attrs.value;
  },

  legalSpaces: function () {
    var tile = this;
    var board = this.board;
    var r0 = this.origin.r;
    var c0 = this.origin.c;
    var spaces = [];
    if (!this.origin.tile) {
      // A tile can't move back to its origin if it would be in the
      // way of another tile that's already moved.
      if ($.grep(this.game.selected, function (movedTile) {
        return tile != movedTile &&
          tile.origin.isBetween(movedTile.origin, movedTile.space);
      }).length == 0) {
        spaces.push(this.origin);
      }
    }
    $.each([-1, 0, 1], function (_, Δr) {
      $.each([-1, 0, 1], function (_, Δc) {
        if (Δr || Δc) {
          for (var i = 1; i < boardSize; i++) {
            var r = r0 + i*Δr;
            var c = c0 + i*Δc;
            if (r < 0 || r >= boardSize || c < 0 || c >= boardSize) break;
            var space = board.spaceAt(r, c);
            if (space == tile.origin) break;
            var tileInSpace = space.tile;
            if (tileInSpace && tileInSpace != tile) break;
            spaces.push(space);
          }
        }
      });
    });
    return spaces;
  },

  setSpace: function (space) {
    this.space = space;
    this.set('space', space);
  },

  updateHighlight: function () {
    if (this.space == this.origin) {
      this.unhighlight();
    } else {
      this.highlight();
    }
  },

  highlight: function () {
    if (!this.highlit) {
      this.highlit = true;
      this.game.select(this);
      var canvas = this.view.find('canvas');
      canvas.addLayer({
        method: 'drawEllipse',
        strokeStyle: 'red',
        strokeWidth: 5,
        x: tileRadius*1.5,
        y: tileRadius*1.5,
        width: (tileRadius+3)*2,
        height: (tileRadius+3)*2
      });
      canvas.drawLayers();
    }
    this.game.updateWord();
  },

  unhighlight: function () {
    if (this.highlit) {
      this.highlit = false;
      this.game.unselect(this);
      var canvas = this.view.find('canvas');
      canvas.removeLayer(1);
      canvas.drawLayers();
    }
    this.game.updateWord();
  },

  remove: function () {
    this.view.css('visibility', 'hidden');
    this.space.tile = null;
  }
});

var GameView = Backbone.View.extend({
  initialize: function (attrs) {
    var game = this.model;
    var view = this.$el;
    game.view = view;

    view.width(tileRadius*boardSize*3);
    view.height(tileRadius*boardSize*3);

    new BoardView({ model: game.board, parent: view });

    game.on('change', this.render, this);
  },

  render: function () {
    var word = this.model.get('word');
    $('#word').text(word || '');
    $('#score').text(word ? '= ' + this.model.score() : '');
    $('#scoreButton').attr('disabled', !word);
    $('#total').text(this.model.total);
    return this;
  }
});

var BoardView = Backbone.View.extend({
  id: 'board',

  initialize: function (opts) {
    var board = this.model;
    var view = this.$el;
    board.view = view;

    view.appendTo(opts.parent);
    view.width(tileRadius*boardSize*3);
    view.height(tileRadius*boardSize*3);

    for (var r = 0; r < boardSize; r++) {
      for (var c = 0; c < boardSize; c++) {
        new SpaceView({ model: board.spaces[r][c], parent: view });
      }
    }
  }
});

var SpaceView = Backbone.View.extend({
  tagName: 'canvas',
  className: 'space',

  initialize: function (opts) {
    var space = this.model;
    var view = this.$el;
    view.data('model', space);
    space.view = view;

    view.appendTo(opts.parent);
    view.attr('width', tileRadius*3);
    view.attr('height', tileRadius*3);
    drawCircle(view, { x: tileRadius*1.5, y: tileRadius*1.5 });

    view.position({ my: 'left top', at: 'left top', of: opts.parent,
                    collision: 'none',
                    offset: space.c*tileRadius*3 + ' ' + space.r*tileRadius*3 });

    if (space.tile) {
      new TileView({ model: space.tile, parent: space.board.game.view});
    }
  }
});

var TileView = Backbone.View.extend({
  className: 'tile',

  initialize: function (opts) {
    var tile = this.model;
    var view = this.$el;
    view.data('model', tile);
    tile.view = view;

    view.appendTo(opts.parent);
    view.width(tileRadius*3);
    view.height(tileRadius*3);

    var canvas = $('<canvas />').appendTo(view);
    canvas.attr('width', tileRadius*3);
    canvas.attr('height', tileRadius*3);
    canvas.addLayer({
      method: 'drawEllipse',
      x: tileRadius*1.5,
      y: tileRadius*1.5,
      width: tileRadius*2,
      height: tileRadius*2,
      strokeStyle: 'black',
      fillStyle: 'tan'
    });
    canvas.drawLayers();

    var label = $('
').appendTo(view);
    $('
' + tile.letter + '
').appendTo(label);
    if (tile.value) {
      $('' + tile.value + '').appendTo(label);
    }
    label.position({ my: 'center', at: 'center', of: canvas });

    this.render();

    this.model.on('change:space', this.render, this);

    view.mouseup(function (e) {
      if (!tile.highlit) {
        tile.highlight();
      } else {
        tile.updateHighlight();
      }
    });

    view.draggable({
      distance: 5,
      stack: '.tile',
      revert: function (space) {
        if (!space) {
          tile.updateHighlight();
          return true;
        } else {
          space.data('model').placeTile(tile);
          return false;
        }
      },
      revertDuration: 200,
      start: function (e) {
        $.each(tile.legalSpaces(), function (_, space) {
          space.view.droppable();
        });
      },
      stop: function (e) {
        // This bypasses the mouseup handler, because highlighting is
        // updated in the revert function.
        e.stopImmediatePropagation();
        $('.space').droppable('destroy');
      }
    });
  },

  render: function () {
    this.$el.position({ my: 'left top', at: 'left top',
                        of: this.model.space.view,
                        collision: 'none' });
    return this;
  }
});

var game;
var gameView;

function main() {
  game = new Game();
  gameView = new GameView({ model: game, el: $('#wordsearch') });
}

$(main);
<|endoftext|>


<commit_before>/**
* Created by Mauriel on 3/9/2017.
*/

// Resource type constraint definitions
constraints = {
    GeographicFeatureResource: {
        requiredFiles: ['.DBF', '.SHP', '.SHX'],    // File extensions in uppercase
        canBeEmpty: true,                           // Optional. Defaults to true
        singleFileFormat: '.ZIP',                   // File format when uploading a single file
        sameFileNames: true,                        // The files must share the same file name
        sameFileNamesExcep: ['SHP.XML']                 // Additional file extensions to check for
    }
};

$(document).ready(function () {
    var json_response_file_types = {};
    var json_response_multiple_file = {};
    var selected_file = undefined;
    var myDropzone;
    var fileIcons = getFileIcons();

    if (sessionStorage.signininfo) {
        $("#sign-in-info").text(sessionStorage.signininfo);
        $("#btn-select-irods-file").show();
        $("#irods-sel-file").text("No file selected.");
    }
    $alert_error = '
 \
        <button type="button" class="close" data-dismiss="alert">x</button> \
        Error!  \
        Resource failed to create.\

';
    Dropzone.options.hsDropzone = {
        previewTemplate: document.getElementById('preview-template').innerHTML,
        clickable: "#dz-container",
        previewsContainer: "#dz-container:not(.dz-details)",
        paramName: "files", // The name that will be used to transfer the file
        maxFilesize: 1024, // MB
        autoProcessQueue: false,
        uploadMultiple: true,
        parallelUploads: 99, // arbitrary large number for parallel uploads

        success: function (file, response) {
            if (response.status == "success") {
                window.location = response['resource_url'];
            }
            else {
                console.log(response);
                $alert_error = $alert_error.replace("Resource failed to create.", response.message);
                $('.btn-create-resource').before($alert_error);
                $("#alert-error").fadeTo(2000, 500).slideUp(1000, function(){
                    $("#alert-error").alert('close');
                });
                $("html, #dz-container").css("cursor", "initial");
                Dropzone.forElement("#hsDropzone").removeAllFiles(true);
                $(".hs-upload-indicator").show();
            }
        },
        error: function (file, response) {
            console.log(response);
        },

        init: function () {
            myDropzone = this;
            $(".btn-create-resource").click(function () {
                $("html, #dz-container").css("cursor", "progress");

                // Delete invalid files from queue before uploading
                $(".dz-error .btn-remove").trigger("click");

                var title = $("#txtTitle").val().trim();
                if (!title) {
                    title = $("#txtTitle").attr("placeholder");
                }

                $("#form-title").val(title);

                if (myDropzone.files.length > 0) {
                    myDropzone.processQueue();
                }
                else {
                    var url = $("#hsDropzone").attr("action");
                    var datastring = $("#hsDropzone").serialize();
                    $.ajax({
                        type: "POST",
                        data: datastring,
                        url: url,
                        success: function (response) {
                            if (response.status == "success") {
                                window.location = response['resource_url'];
                            }
                        },
                        error: function (response) {
                            console.log(response);
                        }
                    });
                }
            });

            // The user dragged a file onto the Dropzone
            this.on("dragenter", function (file) {
                $("#hsDropzone").toggleClass("hs-dropzone-highlight", true);
            });

            // The user dragged a file out of the Dropzone
            this.on("dragleave", function (event) {
                $("#hsDropzone").toggleClass("hs-dropzone-highlight", false);
            });

            this.on("addedfile", function (file) {
                // Initialize tooltips
                var template = $(file.previewElement);
                template.find(".dz-filename").attr("title", template.find("span[data-dz-name]").text());

                // Set file type icon
                var fileName = template.find(".dz-filename").text();
                var fileTypeExt = fileName.substr(fileName.lastIndexOf(".") + 1, fileName.length).toUpperCase();
                var iconTemplate
                if (fileIcons[fileTypeExt]) {
                    icontemplate = fileIcons[fileTypeExt];
                    if (icontemplate === fileIcons.JSON){
                        // json is really for refts.json icon
                        if (!fileName.toUpperCase().endsWith(".REFTS.JSON")){
                            iconTemplate = fileIcons.DEFAULT;
                        }
                    }
                }
                else {
                    iconTemplate = fileIcons.DEFAULT;
                }
                template.find(".file-type-icon").append(iconTemplate);

                template.find("[data-toggle='tooltip']").tooltip();

                if (!myDropzone.options.uploadMultiple && myDropzone.files[1] != null) {
                    this.removeFile(this.files[0]);
                }
                $("#hsDropzone").toggleClass("hs-dropzone-highlight", false);

                $(".hs-upload-indicator").hide();

                setConstraintsHelp();
                checkConstraints();
            });

            this.on("removedfile", function (file) {
                $('#hsDropzone .tooltip').remove();
                if (myDropzone.files.length == 0) {
                    $(".hs-upload-indicator").show();
                }
                setConstraintsHelp();
                checkConstraints();
            });

            this.on("error", function (file, error) {
                var template = $(file.previewElement);
                $(template).addClass("dz-error");
                $(template).attr("data-toggle", "tooltip");
                $(template).attr("data-placement", "top");
                $(template).attr("title", error);
                template.tooltip();
            });

            this.on('sendingmultiple', function (data, xhr, formData) {
                $("#upload-content").find("input[name]").each(function () {
                    formData.append($(this).attr("name"), $(this).val());
                });
            });

            checkConstraints();
            setConstraintsHelp();
        }
    };

    $('input:radio[name="copy-move"]').change(function () {
        if ($(this).val() == 'move') {
            $("#copy-or-move").val('move');
            $("#file-move-warning").show();
        }
        else {
            $("#copy-or-move").val('copy');
            $("#file-move-warning").hide();
        }
    });

    // Prevents event from being defined twice
    $('#dropdown-resource-type li a').unbind("click");

    $('#dropdown-resource-type li a').on("click", function () {
        // Remove all previously queued files when the resource type changes.
        Dropzone.forElement("#hsDropzone").removeAllFiles(true);
        $('#irods-sel-file').text("No file selected.");
        $('#irods_file_names').val("");

        if (selected_file != undefined) {
            selected_file.value = '';
        }

        $("#form-resource-type").val($(this).attr("data-value"));

        var template = this.innerHTML;
        $("#select-resource-type")[0].innerHTML = template;
        $("#select-resource-type").find(".resource-type-name").append(" ")

        // Get supported file types
        $.ajax({
            type: "GET",
            url: "/hsapi/_internal/" + $(this).attr("data-value") + "/supported-file-types/",
            success: function (result) {
                json_response_file_types = JSON.parse(result);

                if (JSON.parse(json_response_file_types.file_types).length == 0) {
                    $("#upload-content").hide();    // No files needed
                }
                else {
                    $("#upload-content").show();

                    var supported_file_types = JSON.parse(json_response_file_types.file_types);

                    $("#file-types").empty();

                    if (supported_file_types != ".*") {
                        // Append message
                        $("#file-types").append("" +
                                "Only the following file types can be uploaded:
");

                        // Render badge for each file type
                        for (var i = 0; i < supported_file_types.length; i++) {
                            $("#file-types").append('' + supported_file_types[i] + '');
                        }

                        // Set controls
                        if (myDropzone) {
                            myDropzone.options.acceptedFiles = supported_file_types.toString();
                            $(myDropzone.hiddenFileInput).attr("accept", supported_file_types.toString());
                        }

                    }
                    else {
                        // Append message
                        $("#file-types").append("" +
                                "Any file type can be uploaded.");

                        // Set controls
                        if (myDropzone) {
                            myDropzone.options.acceptedFiles = "";
                            $(myDropzone.hiddenFileInput).removeAttr("accept");
                        }

                    }
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                $("#file-types").empty();

                // Append message
                $("#file-types").append("" +
                                "Error in determining supported file types
");

                // Set controls
                if (myDropzone) {
                    myDropzone.options.acceptedFiles = "";
                    $(myDropzone.hiddenFileInput).removeAttr("accept");
                }
            }
        });

        // Get multiple files flag value
        $.ajax({
            type: "GET",
            url: "/hsapi/_internal/" + $(this).attr("data-value") + "/allow-multiple-file/",
            success: function (result) {
                json_response_multiple_file = JSON.parse(result);

                $("#file-multiple").empty();
                if (json_response_multiple_file.allow_multiple_file == true) {
                    // Append message
                    $("#file-multiple").append("");
                    $("#file-multiple").append("Multiple file upload is allowed.");

                    // Set controls
                    if (myDropzone) {
                        myDropzone.options.uploadMultiple = true;
                        $(myDropzone.hiddenFileInput).attr("multiple", 'multiple');
                    }
                }
                else {
                    // Append message
                    $("#file-multiple").append("");
                    $("#file-multiple").append("Only one file can be uploaded.");

                    // Set controls
                    if (myDropzone) {
                        myDropzone.options.uploadMultiple = false;
                        $(myDropzone.hiddenFileInput).removeAttr('multiple');
                    }
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                $("#file-multiple").empty();

                // Append message
                $("#file-multiple").append("");
                $("#file-multiple").append("Error in determining if multiple file upload is allowed for this resource type.");

                // Set controls
                if (myDropzone) {
                    myDropzone.options.uploadMultiple = true;
                    $(myDropzone.hiddenFileInput).attr("multiple", 'multiple');
                }
            }
        });

        setConstraintsHelp();
        checkConstraints();
    });

    $("#btn-remove-all-files").click(function () {
        Dropzone.forElement("#hsDropzone").removeAllFiles(true);
        $(".hs-upload-indicator").show();
    });
});

// Shows help messages and their status for each relevant constraint
function setConstraintsHelp() {
    var type = $("#form-resource-type").val();
    var rules = constraints[type];
    var myDropzone = Dropzone.forElement("#hsDropzone");
    var someDisplayed = false;

    $("#constraints > li").css("display", "none");

    if (type in constraints) {
        if (!rules.canBeEmpty && myDropzone.files.length == 0) {
            $("#res-empty").css("display", "block");
            someDisplayed = true;
        }

        if (rules.requiredFiles && myDropzone.files.length > 0 && !(rules.singleFileFormat && myDropzone.files.length == 1)) {
            $("#required-types").css("display", "block");
            $("#required-types > span").empty();
            rules.requiredFiles.forEach(function(ext) {
                $("#required-types > span").append("" + ext.toLowerCase() + "")
            });
            someDisplayed = true;
        }

        if (rules.singleFileFormat && myDropzone.files.length == 1) {
            $("#single-file").css("display", "block");
            $("#single-file-type").empty();
            $("#single-file-type").append("" + rules.singleFileFormat.toLowerCase() + "")
            someDisplayed = true;
        }

        if (rules.sameFileNames && myDropzone.files.length > 1) {
            $("#same-file-names").css("display", "block");
            someDisplayed = true;
        }

        if (someDisplayed) {
            $("#constraints").css("display", "block");
        }
    }
    else {
        $("#constraints").css("display", "none");
    }
}

// Enables/disables Create Resource button based on resource type constraints
function checkConstraints() {
    var invalid = false;
    $("#constraints > li").toggleClass("invalid", false);
    var myDropzone = Dropzone.forElement("#hsDropzone");

    var type = $("#form-resource-type").val();

    if (type in constraints) {
        var rules = constraints[type];

        // Check canBeEmpty
        if (!rules.canBeEmpty && myDropzone.files.length == 0) {
            invalid = true;
            $("#res-empty").toggleClass("invalid", true);
        }

        // Check required files. Ignore when single file and single file format flag
        if (rules.requiredFiles && myDropzone.files.length > 0 && !(rules.singleFileFormat && myDropzone.files.length == 1)) {
            var extensions = [];
            myDropzone.files.forEach(function(element) {
                var fileTypeExt = element.name.substr(element.name.lastIndexOf("."), element.name.length).toUpperCase();
                extensions.push(fileTypeExt)
            });

            rules.requiredFiles.forEach(function(element) {
                if (!extensions.includes(element)) {
                    invalid = true;
                    $("#required-types").toggleClass("invalid", true)
                }
            });
        }

        // Check single file format
        if (rules.singleFileFormat && myDropzone.files.length == 1) {
            var fileName = myDropzone.files[0].name;
            var fileTypeExt = fileName.substr(fileName.lastIndexOf("."), fileName.length).toUpperCase();

            if (fileTypeExt.toUpperCase() != rules.singleFileFormat) {
                invalid = true;
                $("#single-file").toggleClass("invalid", true)
            }
        }

        // Check for same file names
        if (rules.sameFileNames && myDropzone.files.length > 1) {
            var fNames = [];
            myDropzone.files.forEach(function(element) {
                // Check the exceptions first
                var found = false;
                if (rules.sameFileNamesExcep && rules.sameFileNamesExcep.length > 0) {
                    rules.sameFileNamesExcep.forEach(function (excep) {
                        if (element.name.toUpperCase().endsWith(excep)) {
                            var fileName = element.name.substr(0, element.name.toUpperCase().lastIndexOf(excep) - 1);
                            fNames.push(fileName);
                            found = true;
                        }
                    });
                }

                // Check for file names
                if (!found) {
                    var fileName = element.name.substr(0, element.name.lastIndexOf("."));
                    fNames.push(fileName)
                }
            });

            var uniqueNames = fNames.filter(function (value, index, self) {
                return self.indexOf(value) === index
            });

            if (uniqueNames.length > 1) {
                invalid = true;
                $("#same-file-names").toggleClass("invalid", true)
            }
        }
    }

    $(".btn-create-resource").toggleClass("disabled", invalid);
}<commit_msg>[#2567] put full path in hover over text<commit_after>/**
* Created by Mauriel on 3/9/2017.
*/

// Resource type constraint definitions
constraints = {
    GeographicFeatureResource: {
        requiredFiles: ['.DBF', '.SHP', '.SHX'],    // File extensions in uppercase
        canBeEmpty: true,                           // Optional. Defaults to true
        singleFileFormat: '.ZIP',                   // File format when uploading a single file
        sameFileNames: true,                        // The files must share the same file name
        sameFileNamesExcep: ['SHP.XML']                 // Additional file extensions to check for
    }
};

$(document).ready(function () {
    var json_response_file_types = {};
    var json_response_multiple_file = {};
    var selected_file = undefined;
    var myDropzone;
    var fileIcons = getFileIcons();

    if (sessionStorage.signininfo) {
        $("#sign-in-info").text(sessionStorage.signininfo);
        $("#btn-select-irods-file").show();
        $("#irods-sel-file").text("No file selected.");
    }
    $alert_error = '
 \
        <button type="button" class="close" data-dismiss="alert">x</button> \
        Error!  \
        Resource failed to create.\

';
    Dropzone.options.hsDropzone = {
        previewTemplate: document.getElementById('preview-template').innerHTML,
        clickable: "#dz-container",
        previewsContainer: "#dz-container:not(.dz-details)",
        paramName: "files", // The name that will be used to transfer the file
        maxFilesize: 1024, // MB
        autoProcessQueue: false,
        uploadMultiple: true,
        parallelUploads: 99, // arbitrary large number for parallel uploads

        success: function (file, response) {
            if (response.status == "success") {
                window.location = response['resource_url'];
            }
            else {
                console.log(response);
                $alert_error = $alert_error.replace("Resource failed to create.", response.message);
                $('.btn-create-resource').before($alert_error);
                $("#alert-error").fadeTo(2000, 500).slideUp(1000, function(){
                    $("#alert-error").alert('close');
                });
                $("html, #dz-container").css("cursor", "initial");
                Dropzone.forElement("#hsDropzone").removeAllFiles(true);
                $(".hs-upload-indicator").show();
            }
        },
        error: function (file, response) {
            console.log(response);
        },

        init: function () {
            myDropzone = this;
            $(".btn-create-resource").click(function () {
                $("html, #dz-container").css("cursor", "progress");

                // Delete invalid files from queue before uploading
                $(".dz-error .btn-remove").trigger("click");

                var title = $("#txtTitle").val().trim();
                if (!title) {
                    title = $("#txtTitle").attr("placeholder");
                }

                $("#form-title").val(title);

                if (myDropzone.files.length > 0) {
                    myDropzone.processQueue();
                }
                else {
                    var url = $("#hsDropzone").attr("action");
                    var datastring = $("#hsDropzone").serialize();
                    $.ajax({
                        type: "POST",
                        data: datastring,
                        url: url,
                        success: function (response) {
                            if (response.status == "success") {
                                window.location = response['resource_url'];
                            }
                        },
                        error: function (response) {
                            console.log(response);
                        }
                    });
                }
            });

            // The user dragged a file onto the Dropzone
            this.on("dragenter", function (file) {
                $("#hsDropzone").toggleClass("hs-dropzone-highlight", true);
            });

            // The user dragged a file out of the Dropzone
            this.on("dragleave", function (event) {
                $("#hsDropzone").toggleClass("hs-dropzone-highlight", false);
            });

            this.on("addedfile", function (file) {
                // Initialize tooltips
                var template = $(file.previewElement);
                template.find(".dz-filename").attr("title", file.fullPath);

                // Set file type icon
                var fileName = template.find(".dz-filename").text();
                var fileTypeExt = fileName.substr(fileName.lastIndexOf(".") + 1, fileName.length).toUpperCase();
                var iconTemplate;
                if (fileIcons[fileTypeExt]) {
                    icontemplate = fileIcons[fileTypeExt];
                    if (icontemplate === fileIcons.JSON){
                        // json is really for refts.json icon
                        if (!fileName.toUpperCase().endsWith(".REFTS.JSON")){
                            iconTemplate = fileIcons.DEFAULT;
                        }
                    }
                }
                else {
                    iconTemplate = fileIcons.DEFAULT;
                }
                template.find(".file-type-icon").append(iconTemplate);

                template.find("[data-toggle='tooltip']").tooltip();

                if (!myDropzone.options.uploadMultiple && myDropzone.files[1] != null) {
                    this.removeFile(this.files[0]);
                }
                $("#hsDropzone").toggleClass("hs-dropzone-highlight", false);

                $(".hs-upload-indicator").hide();

                setConstraintsHelp();
                checkConstraints();
            });

            this.on("removedfile", function (file) {
                $('#hsDropzone .tooltip').remove();
                if (myDropzone.files.length == 0) {
                    $(".hs-upload-indicator").show();
                }
                setConstraintsHelp();
                checkConstraints();
            });

            this.on("error", function (file, error) {
                var template = $(file.previewElement);
                $(template).addClass("dz-error");
                $(template).attr("data-toggle", "tooltip");
                $(template).attr("data-placement", "top");
                $(template).attr("title", error);
                template.tooltip();
            });

            this.on('sendingmultiple', function (data, xhr, formData) {
                $("#upload-content").find("input[name]").each(function () {
                    formData.append($(this).attr("name"), $(this).val());
                });
            });

            checkConstraints();
            setConstraintsHelp();
        }
    };

    $('input:radio[name="copy-move"]').change(function () {
        if ($(this).val() == 'move') {
            $("#copy-or-move").val('move');
            $("#file-move-warning").show();
        }
        else {
            $("#copy-or-move").val('copy');
            $("#file-move-warning").hide();
        }
    });

    // Prevents event from being defined twice
    $('#dropdown-resource-type li a').unbind("click");

    $('#dropdown-resource-type li a').on("click", function () {
        // Remove all previously queued files when the resource type changes.
        Dropzone.forElement("#hsDropzone").removeAllFiles(true);
        $('#irods-sel-file').text("No file selected.");
        $('#irods_file_names').val("");

        if (selected_file != undefined) {
            selected_file.value = '';
        }

        $("#form-resource-type").val($(this).attr("data-value"));

        var template = this.innerHTML;
        $("#select-resource-type")[0].innerHTML = template;
        $("#select-resource-type").find(".resource-type-name").append(" ")

        // Get supported file types
        $.ajax({
            type: "GET",
            url: "/hsapi/_internal/" + $(this).attr("data-value") + "/supported-file-types/",
            success: function (result) {
                json_response_file_types = JSON.parse(result);

                if (JSON.parse(json_response_file_types.file_types).length == 0) {
                    $("#upload-content").hide();    // No files needed
                }
                else {
                    $("#upload-content").show();

                    var supported_file_types = JSON.parse(json_response_file_types.file_types);

                    $("#file-types").empty();

                    if (supported_file_types != ".*") {
                        // Append message
                        $("#file-types").append("" +
                                "Only the following file types can be uploaded:
");

                        // Render badge for each file type
                        for (var i = 0; i < supported_file_types.length; i++) {
                            $("#file-types").append('' + supported_file_types[i] + '');
                        }

                        // Set controls
                        if (myDropzone) {
                            myDropzone.options.acceptedFiles = supported_file_types.toString();
                            $(myDropzone.hiddenFileInput).attr("accept", supported_file_types.toString());
                        }

                    }
                    else {
                        // Append message
                        $("#file-types").append("" +
                                "Any file type can be uploaded.");

                        // Set controls
                        if (myDropzone) {
                            myDropzone.options.acceptedFiles = "";
                            $(myDropzone.hiddenFileInput).removeAttr("accept");
                        }

                    }
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                $("#file-types").empty();

                // Append message
                $("#file-types").append("" +
                                "Error in determining supported file types
");

                // Set controls
                if (myDropzone) {
                    myDropzone.options.acceptedFiles = "";
                    $(myDropzone.hiddenFileInput).removeAttr("accept");
                }
            }
        });

        // Get multiple files flag value
        $.ajax({
            type: "GET",
            url: "/hsapi/_internal/" + $(this).attr("data-value") + "/allow-multiple-file/",
            success: function (result) {
                json_response_multiple_file = JSON.parse(result);

                $("#file-multiple").empty();
                if (json_response_multiple_file.allow_multiple_file == true) {
                    // Append message
                    $("#file-multiple").append("");
                    $("#file-multiple").append("Multiple file upload is allowed.");

                    // Set controls
                    if (myDropzone) {
                        myDropzone.options.uploadMultiple = true;
                        $(myDropzone.hiddenFileInput).attr("multiple", 'multiple');
                    }
                }
                else {
                    // Append message
                    $("#file-multiple").append("");
                    $("#file-multiple").append("Only one file can be uploaded.");

                    // Set controls
                    if (myDropzone) {
                        myDropzone.options.uploadMultiple = false;
                        $(myDropzone.hiddenFileInput).removeAttr('multiple');
                    }
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                $("#file-multiple").empty();

                // Append message
                $("#file-multiple").append("");
                $("#file-multiple").append("Error in determining if multiple file upload is allowed for this resource type.");

                // Set controls
                if (myDropzone) {
                    myDropzone.options.uploadMultiple = true;
                    $(myDropzone.hiddenFileInput).attr("multiple", 'multiple');
                }
            }
        });

        setConstraintsHelp();
        checkConstraints();
    });

    $("#btn-remove-all-files").click(function () {
        Dropzone.forElement("#hsDropzone").removeAllFiles(true);
        $(".hs-upload-indicator").show();
    });
});

// Shows help messages and their status for each relevant constraint
function setConstraintsHelp() {
    var type = $("#form-resource-type").val();
    var rules = constraints[type];
    var myDropzone = Dropzone.forElement("#hsDropzone");
    var someDisplayed = false;

    $("#constraints > li").css("display", "none");

    if (type in constraints) {
        if (!rules.canBeEmpty && myDropzone.files.length == 0) {
            $("#res-empty").css("display", "block");
            someDisplayed = true;
        }

        if (rules.requiredFiles && myDropzone.files.length > 0 && !(rules.singleFileFormat && myDropzone.files.length == 1)) {
            $("#required-types").css("display", "block");
            $("#required-types > span").empty();
            rules.requiredFiles.forEach(function(ext) {
                $("#required-types > span").append("" + ext.toLowerCase() + "")
            });
            someDisplayed = true;
        }

        if (rules.singleFileFormat && myDropzone.files.length == 1) {
            $("#single-file").css("display", "block");
            $("#single-file-type").empty();
            $("#single-file-type").append("" + rules.singleFileFormat.toLowerCase() + "")
            someDisplayed = true;
        }

        if (rules.sameFileNames && myDropzone.files.length > 1) {
            $("#same-file-names").css("display", "block");
            someDisplayed = true;
        }

        if (someDisplayed) {
            $("#constraints").css("display", "block");
        }
    }
    else {
        $("#constraints").css("display", "none");
    }
}

// Enables/disables Create Resource button based on resource type constraints
function checkConstraints() {
    var invalid = false;
    $("#constraints > li").toggleClass("invalid", false);
    var myDropzone = Dropzone.forElement("#hsDropzone");

    var type = $("#form-resource-type").val();

    if (type in constraints) {
        var rules = constraints[type];

        // Check canBeEmpty
        if (!rules.canBeEmpty && myDropzone.files.length == 0) {
            invalid = true;
            $("#res-empty").toggleClass("invalid", true);
        }

        // Check required files. Ignore when single file and single file format flag
        if (rules.requiredFiles && myDropzone.files.length > 0 && !(rules.singleFileFormat && myDropzone.files.length == 1)) {
            var extensions = [];
            myDropzone.files.forEach(function(element) {
                var fileTypeExt = element.name.substr(element.name.lastIndexOf("."), element.name.length).toUpperCase();
                extensions.push(fileTypeExt)
            });

            rules.requiredFiles.forEach(function(element) {
                if (!extensions.includes(element)) {
                    invalid = true;
                    $("#required-types").toggleClass("invalid", true)
                }
            });
        }

        // Check single file format
        if (rules.singleFileFormat && myDropzone.files.length == 1) {
            var fileName = myDropzone.files[0].name;
            var fileTypeExt = fileName.substr(fileName.lastIndexOf("."), fileName.length).toUpperCase();

            if (fileTypeExt.toUpperCase() != rules.singleFileFormat) {
                invalid = true;
                $("#single-file").toggleClass("invalid", true)
            }
        }

        // Check for same file names
        if (rules.sameFileNames && myDropzone.files.length > 1) {
            var fNames = [];
            myDropzone.files.forEach(function(element) {
                // Check the exceptions first
                var found = false;
                if (rules.sameFileNamesExcep && rules.sameFileNamesExcep.length > 0) {
                    rules.sameFileNamesExcep.forEach(function (excep) {
                        if (element.name.toUpperCase().endsWith(excep)) {
                            var fileName = element.name.substr(0, element.name.toUpperCase().lastIndexOf(excep) - 1);
                            fNames.push(fileName);
                            found = true;
                        }
                    });
                }

                // Check for file names
                if (!found) {
                    var fileName = element.name.substr(0, element.name.lastIndexOf("."));
                    fNames.push(fileName)
                }
            });

            var uniqueNames = fNames.filter(function (value, index, self) {
                return self.indexOf(value) === index
            });

            if (uniqueNames.length > 1) {
                invalid = true;
                $("#same-file-names").toggleClass("invalid", true)
            }
        }
    }

    $(".btn-create-resource").toggleClass("disabled", invalid);
}<|endoftext|>


<commit_before>module.exports = [

  // ESLint
  // http://eslint.org/docs/rules/#deprecated
  'no-native-reassign',
  'no-negated-in-lhs',
  'no-spaced-func',

  // Import Plugin
  // https://github.com/benmosher/eslint-plugin-import/blob/dc3609f895f5ad390d88fd9925dce40960117930/src/index.js#L35
  'import/imports-first',

  // Flowtype Plugin
  // https://github.com/gajus/eslint-plugin-flowtype#eslint-plugin-flowtype-rules-valid-syntax
  'flowtype/valid-syntax',

  // React Plugin
  // https://github.com/yannickcr/eslint-plugin-react/blob/e1697996ff494bf584057418e2974ece7f3d99d8/index.js#L3
  'react/no-comment-textnodes',
  'react/require-extension',
  'react/wrap-multilines'
]
<commit_msg>Nested deprecated rules<commit_after>module.exports = {

  // Deprecated Rules
  rules: [

    // ESLint
    // http://eslint.org/docs/rules/#deprecated
    'no-native-reassign',
    'no-negated-in-lhs',
    'no-spaced-func',

    // Import Plugin
    // https://github.com/benmosher/eslint-plugin-import/blob/dc3609f895f5ad390d88fd9925dce40960117930/src/index.js#L35
    'import/imports-first',

    // Flowtype Plugin
    // https://github.com/gajus/eslint-plugin-flowtype#eslint-plugin-flowtype-rules-valid-syntax
    'flowtype/valid-syntax',

    // React Plugin
    // https://github.com/yannickcr/eslint-plugin-react/blob/e1697996ff494bf584057418e2974ece7f3d99d8/index.js#L3
    'react/no-comment-textnodes',
    'react/require-extension',
    'react/wrap-multilines'
  ]
}
<|endoftext|>