summaryrefslogtreecommitdiff
path: root/app/assets/javascripts
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/application.js2
-rw-r--r--app/assets/javascripts/buttons.js39
-rw-r--r--app/assets/javascripts/leap.js7
-rw-r--r--app/assets/javascripts/platform.js93
m---------app/assets/javascripts/srp0
-rw-r--r--app/assets/javascripts/users.js181
6 files changed, 321 insertions, 1 deletions
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 03a40da..9af373d 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -20,4 +20,4 @@
//= require platform
//= require tickets
//= require users
-//= require_tree .
+//= require buttons
diff --git a/app/assets/javascripts/buttons.js b/app/assets/javascripts/buttons.js
new file mode 100644
index 0000000..7142957
--- /dev/null
+++ b/app/assets/javascripts/buttons.js
@@ -0,0 +1,39 @@
+/*
+ * Buttons.js
+ *
+ * Use bootstrap loading state after submitting a form.
+ *
+ * Some form inputs are validaded before the submission
+ * so triggering loading state on click events is not a
+ * good idea. If the validation fails the errors will
+ * be displayed but the button would be in loading state.
+ *
+ * We used to trigger it based on form submission but
+ * we have a few forms that contain multiple buttons.
+ * So now we mark the buttons as clicked on click and
+ * put the clicked button into loading state on submit.
+ *
+ */
+
+(function() {
+ markAsClicked = function () {
+ var btn = $(this)
+ btn.addClass('clicked')
+ setTimeout(function () {
+ btn.removeClass('clicked')
+ }, 1000)
+ };
+
+ markAsLoading = function(submitEvent) {
+ var form = submitEvent.target;
+ $(form).addClass('submitted')
+ // bootstrap loading state:
+ $(form).find('.btn.clicked[type="submit"]').button('loading');
+ };
+
+ $(document).ready(function() {
+ $('form').submit(markAsLoading);
+ $('.btn[type="submit"]').click(markAsClicked);
+ });
+
+}).call(this);
diff --git a/app/assets/javascripts/leap.js b/app/assets/javascripts/leap.js
new file mode 100644
index 0000000..94e602d
--- /dev/null
+++ b/app/assets/javascripts/leap.js
@@ -0,0 +1,7 @@
+
+//
+// add a bootstrap alert to the page via javascript.
+//
+function alert_message(msg) {
+ $('#messages').append('<div class="alert alert-error"><a class="close" data-dismiss="alert">×</a><span>'+msg+'</span></div>');
+}
diff --git a/app/assets/javascripts/platform.js b/app/assets/javascripts/platform.js
new file mode 100644
index 0000000..108c162
--- /dev/null
+++ b/app/assets/javascripts/platform.js
@@ -0,0 +1,93 @@
+/* Inspired by mozillas platform detection:
+ https://github.com/mozilla/bedrock/tree/master/media/js/base
+*/
+ (function () {
+ 'use strict';
+ function getPlatform() {
+ var ua = navigator.userAgent,
+ pf = navigator.platform;
+ if (/Win(16|9[x58]|NT( [1234]| 5\.0| [^0-9]|[^ -]|$))/.test(ua) ||
+ /Windows ([MC]E|9[x58]|3\.1|4\.10|NT( [1234]| 5\.0| [^0-9]|[^ ]|$))/.test(ua) ||
+ /Windows_95/.test(ua)) {
+ /**
+ * Officially unsupported platforms are Windows 95, 98, ME, NT 4.x, 2000
+ * These regular expressions match:
+ * - Win16
+ * - Win9x
+ * - Win95
+ * - Win98
+ * - WinNT (not followed by version or followed by version <= 5)
+ * - Windows ME
+ * - Windows CE
+ * - Windows 9x
+ * - Windows 95
+ * - Windows 98
+ * - Windows 3.1
+ * - Windows 4.10
+ * - Windows NT (not followed by version or followed by version <= 5)
+ * - Windows_95
+ */
+ return 'oldwin';
+ }
+ if (ua.indexOf("MSIE 6.0") !== -1 &&
+ ua.indexOf("Windows NT 5.1") !== -1 &&
+ ua.indexOf("SV1") === -1) {
+ // Windows XP SP1
+ return 'oldwin';
+ }
+ if (pf.indexOf("Win32") !== -1 ||
+ pf.indexOf("Win64") !== -1) {
+ return 'windows';
+ }
+ if (/android/i.test(ua)) {
+ return 'android';
+ }
+ if (/armv[6-7]l/.test(pf)) {
+ return 'android';
+ }
+ if (pf.indexOf("Linux") !== -1) {
+ return 'linux';
+ //if (pf.indexOf("64") !== -1) {
+ // return 'linux64';
+ //} else {
+ // return 'linux32';
+ //}
+ }
+ if (pf.indexOf("MacPPC") !== -1) {
+ return 'oldmac';
+ }
+ if (/Mac OS X 10.[0-5]/.test(ua)) {
+ return 'oldmac';
+ }
+ if (pf.indexOf('iPhone') !== -1 ||
+ pf.indexOf('iPad') !== -1 ||
+ pf.indexOf('iPod') !== -1 ) {
+ return 'ios';
+ }
+ if (ua.indexOf("Mac OS X") !== -1) {
+ return 'osx';
+ }
+ if (ua.indexOf("MSIE 5.2") !== -1) {
+ return 'oldmac';
+ }
+ if (pf.indexOf("Mac") !== -1) {
+ return 'oldmac';
+ }
+ if (navigator.platform === '' &&
+ navigator.userAgent.indexOf("Firefox") !== -1 &&
+ navigator.userAgent.indexOf("Mobile") !== -1) {
+ return 'fxos';
+ }
+
+ return 'other';
+ }
+ (function () {
+ // Immediately set the platform classname on the html-element
+ // to avoid lots of flickering
+ var h = document.documentElement;
+ window.site = {
+ platform : getPlatform()
+ };
+ h.className = window.site.platform;
+ })();
+ })();
diff --git a/app/assets/javascripts/srp b/app/assets/javascripts/srp
new file mode 160000
+Subproject 8f33d32d40b1e21ae7fb9a92c78a275422af421
diff --git a/app/assets/javascripts/users.js b/app/assets/javascripts/users.js
new file mode 100644
index 0000000..e6c2fcc
--- /dev/null
+++ b/app/assets/javascripts/users.js
@@ -0,0 +1,181 @@
+(function() {
+
+
+ var settings = {
+ "error_class":"help-inline",
+ "error_tag":"span",
+ "wrapper_error_class":"error",
+ "wrapper_tag":"div",
+ "wrapper_class":"control-group"
+ }
+
+ //
+ // LOCAL FUNCTIONS
+ //
+
+ var poll_users,
+ prevent_default,
+ clear_errors,
+ clear_field_errors,
+ validate_password_confirmation,
+ validate_password_length,
+ update_user;
+
+ prevent_default = function(event) {
+ return event.preventDefault();
+ };
+
+ poll_users = function(query, process) {
+ return $.get("/1/users.json", {
+ query: query
+ }).done(process);
+ };
+
+ clear_errors = function() {
+ return $('#messages').empty();
+ };
+
+ clear_field_errors = function() {
+ return $(settings.error_tag + '.' + settings.error_class).remove();
+ };
+
+ update_user = function(submitEvent) {
+ var form = submitEvent.target;
+ var token = form.dataset.token;
+ var url = form.action;
+ var req = $.ajax({
+ url: url,
+ type: 'PUT',
+ headers: { Authorization: 'Token token="' + token + '"' },
+ data: $(form).serialize()
+ });
+ req.done( function() {
+ $(form).find('.btn[type="submit"]').button('reset');
+ });
+ };
+
+ validate_password_confirmation = function(submitEvent) {
+ var form = submitEvent.target;
+ var password = $(form).find('input#srp_password').val();
+ var confirmation = $(form).find('input#srp_password_confirmation').val();
+ if (password === confirmation) {
+ return true;
+ }
+ else {
+ displayFieldError("password_confirmation", "does not match.");
+ submitEvent.stopImmediatePropagation()
+ return false;
+ }
+ };
+
+ validate_password_length = function(submitEvent) {
+ var form = submitEvent.target;
+ var password = $(form).find('input#srp_password').val();
+ if (password.length > 7) {
+ return true;
+ }
+ else {
+ displayFieldError("password", "needs to be at least 8 characters long.");
+ submitEvent.stopImmediatePropagation()
+ return false;
+ }
+ };
+
+ //
+ // PUBLIC FUNCTIONS
+ //
+
+ srp.session = new srp.Session();
+
+ srp.signedUp = function() {
+ return srp.login();
+ };
+
+ srp.loggedIn = function() {
+ return window.location = '/';
+ };
+
+ srp.updated = function() {
+ return window.location = '/users/' + srp.session.id();
+ };
+
+ //
+ // if a json request returns an error, this function gets called and
+ // decorates the appropriate fields with the error messages.
+ //
+ srp.error = function(message) {
+ clear_errors();
+ var errors = extractErrors(message);
+ displayErrors(errors);
+ $('.btn[type="submit"]').button('reset');
+ }
+
+ function extractErrors(message) {
+ if ($.isPlainObject(message) && message.errors) {
+ return message.errors;
+ } else {
+ return {
+ base: (message.error || JSON.stringify(message))
+ };
+ }
+ }
+
+ function displayErrors(errors) {
+ for (var field in errors) {
+ var error = errors[field];
+ if (field === 'base') {
+ alert_message(error);
+ } else {
+ displayFieldError(field, error);
+ }
+ }
+ }
+
+ function displayFieldError(field, error) {
+ var message = $.isArray(error) ? error[0] : error;
+ var element = $('form input[name$="[' + field + ']"]');
+ if (element) {
+ addError(element, settings, message);
+ }
+ };
+
+ function addError(element, settings, message) {
+ var errorElement, wrapper;
+
+ errorElement = element.parent().find("" + settings.error_tag + "." + settings.error_class);
+ wrapper = element.closest(settings.wrapper_tag + '.' + settings.wrapper_class);
+ if (errorElement[0] == null) {
+ errorElement = $("<" + settings.error_tag + "/>", {
+ "class": settings.error_class,
+ text: message
+ });
+ element.after(errorElement);
+ }
+ wrapper.addClass(settings.wrapper_error_class);
+ return errorElement.text(message);
+ }
+
+//
+// INIT
+//
+
+ $(document).ready(function() {
+ $('.hidden.js-show').removeClass('hidden');
+ $('.js-show').show();
+ $('#new_user').submit(prevent_default);
+ $('#new_user').submit(clear_field_errors);
+ $('#new_user').submit(validate_password_length);
+ $('#new_user').submit(validate_password_confirmation);
+ $('#new_user').submit(srp.signup);
+ $('#new_session').submit(prevent_default);
+ $('#new_session').submit(srp.login);
+ $('#update_login_and_password').submit(prevent_default);
+ $('#update_login_and_password').submit(srp.update);
+ $('#update_pgp_key').submit(prevent_default);
+ $('#update_pgp_key').submit(update_user);
+ return $('#user-typeahead').typeahead({
+ source: poll_users
+ });
+ });
+
+}).call(this);