<commit_before>/*
 * Copyright (c) $year, Den Norske Turistforening (DNT)
 *
 * https://github.com/Turistforeningen/turadmin
 */

module.exports = function (app, options) {
    "use strict";

    var ntbApiUri = options.ntbApiUri;
    var ntbApiKey = options.ntbApiKey;
    var pictureFileManager = options.pictureFileManager;
    var restler = require('restler');
    var underscore = require('underscore');
    var util = require('util');

    /*
        Move picture to permanent storage using jquery-file-upload-middleware'filehandler
     */
    var movePicture = function (req, picture) {
        var status = {ok: true, error: ""};
        var userId = req.session.userId;
        pictureFileManager.movePictureToPermanentStorage(picture.url, userId, function (error, result) {

            if (!error && !!result) {
                picture.url = result.url;
                picture.thumbnailUrl = result.thumbnailUrl;

                underscore.each(picture.img, function (image) {
                    //is thumbnail if width and height is set
                    if (!!image.width && !!image.height) {
                        image.url = result.thumbnailUrl;
                    } else {
                        image.url = result.url;
                    }
                });

                console.log("moved picture: ", picture);

            } else {
                status.error = 'Error moving file to permanent storage';
                status.ok = false;
                console.error(status.error);
            }
        });
        return status;
    };

    /*
        Move id from document object to _id on result object, to update client side model with id.
     */
    var moveId = function (data) {
        if (data.document && data.document._id) {
            data._id = data.document._id;
        } else {
            console.error('id is missing in result after post!');
        }
        data.document = undefined;
    };

    var makeRequest = function (path, req, res, onCompleteOverride) {
        var apiKey = (path.match(/\?/) ? '&' : '?') + 'api_key=' + ntbApiKey;
        var url = ntbApiUri + path + apiKey;
        var method = req.method;
        var json, options;

        // console.log("Request URL:", url);

        var onCompleteDefault = function (data) {
            // console.log(data);
            if (data.document !== undefined) {
                data.document = undefined;
            }
            res.json(data);
        };

        var onComplete = onCompleteOverride || onCompleteDefault;

        var onCompletePost = function (data, response) {
            console.log("Response:", data);
            moveId(data);
            res.json(data);
        };

        var onCompletePostPicture = function (data, picture) {
            data = underscore.extend(data, picture);
            onCompletePost(data);
        };

        var onCompletePostGpx = function (data, picture) {
            data = underscore.extend(data, picture);
            onCompletePost(data);
        };

        if (method === "GET") {
            // console.log("getUrl = " + url);
            restler.get(url, {})
                .on('complete', onComplete);

        } else if (method === "POST") {
            console.log("Posting:", util.inspect(req.body));

            //Move pictures to permanent storage when saving to rest api. Updates results object with new urls.
            if (path.indexOf("bilder") > -1) {
                var result = movePicture(req, req.body);
                var resultOk = result.ok;
                var error = result.error;
                if (resultOk) {
                    restler.postJson(url, req.body)
                        .on('complete', function (data) {
                            onCompletePostPicture(data, req.body);
                        });
                } else {
                    restler.abort(error);
                }

            } else {
                restler.postJson(url, req.body)
                    .on('complete', onCompletePost);
            }

        } else if (method === "PUT") {
            json = JSON.stringify(req.body);
            options = {data: json, headers: {}};
            options.headers['content-type'] = 'application/json';
            // console.log("PUT url:", url);
            // console.log("PUT options:", options);
            restler.put(url, options).on('complete', onComplete);

        } else if (method === "PATCH") {
            json = JSON.stringify(req.body);
            options = {data: json, headers: {}};
            options.headers['content-type'] = 'application/json';
            // console.log("PATCH url:", url);
            // console.log("PATCH options:", options);
            restler.patch(url, options).on('complete', onComplete);

        } else if (method === "DELETE") {
            // console.log("DELETE url:", url);
            restler.del(url, {})
                .on('complete', onComplete);
        }
    };

    // var makeRequest = function (path, method, req, res, onCompleteOverride) {

    app.all('/restProxy/*', function (req, res) {
        // console.log(req);
        var path = req.url;
        path = path.replace("restProxy/", "");
        makeRequest(path, req, res);
    });

    return { makeApiRequest : makeRequest };
};
<commit_msg>Set correct status code on response in restProxy<commit_after>/*
 * Copyright (c) $year, Den Norske Turistforening (DNT)
 *
 * https://github.com/Turistforeningen/turadmin
 */

module.exports = function (app, options) {
    "use strict";

    var ntbApiUri = options.ntbApiUri;
    var ntbApiKey = options.ntbApiKey;
    var pictureFileManager = options.pictureFileManager;
    var restler = require('restler');
    var underscore = require('underscore');
    var util = require('util');

    /*
        Move picture to permanent storage using jquery-file-upload-middleware'filehandler
     */
    var movePicture = function (req, picture) {
        var status = {ok: true, error: ""};
        var userId = req.session.userId;
        pictureFileManager.movePictureToPermanentStorage(picture.url, userId, function (error, result) {

            if (!error && !!result) {
                picture.url = result.url;
                picture.thumbnailUrl = result.thumbnailUrl;

                underscore.each(picture.img, function (image) {
                    //is thumbnail if width and height is set
                    if (!!image.width && !!image.height) {
                        image.url = result.thumbnailUrl;
                    } else {
                        image.url = result.url;
                    }
                });

                console.log("moved picture: ", picture);

            } else {
                status.error = 'Error moving file to permanent storage';
                status.ok = false;
                console.error(status.error);
            }
        });
        return status;
    };

    /*
        Move id from document object to _id on result object, to update client side model with id.
     */
    var moveId = function (data) {
        if (data.document && data.document._id) {
            data._id = data.document._id;
        } else {
            console.error('id is missing in result after post!');
        }
        data.document = undefined;
    };

    var makeRequest = function (path, req, res, onCompleteOverride) {
        var apiKey = (path.match(/\?/) ? '&' : '?') + 'api_key=' + ntbApiKey;
        var url = ntbApiUri + path + apiKey;
        var method = req.method;
        var json, options;

        // console.log("Request URL:", url);

        var onCompleteDefault = function (data, response) {
            res.statusCode = response.statusCode;
            if (data.document !== undefined) {
                data.document = undefined;
            }
            res.json(data);
        };

        var onComplete = onCompleteOverride || onCompleteDefault;

        var onCompletePost = function (data, response) {
            res.statusCode = response.statusCode;
            console.log("Response:", data);
            moveId(data);
            res.json(data);
        };

        var onCompletePostPicture = function (data, picture) {
            data = underscore.extend(data, picture);
            onCompletePost(data);
        };

        var onCompletePostGpx = function (data, picture) {
            data = underscore.extend(data, picture);
            onCompletePost(data);
        };

        if (method === "GET") {
            // console.log("getUrl = " + url);
            restler.get(url, {})
                .on('complete', onComplete);

        } else if (method === "POST") {
            console.log("Posting:", util.inspect(req.body));

            //Move pictures to permanent storage when saving to rest api. Updates results object with new urls.
            if (path.indexOf("bilder") > -1) {
                var result = movePicture(req, req.body);
                var resultOk = result.ok;
                var error = result.error;
                if (resultOk) {
                    restler.postJson(url, req.body)
                        .on('complete', function (data) {
                            onCompletePostPicture(data, req.body);
                        });
                } else {
                    restler.abort(error);
                }

            } else {
                restler.postJson(url, req.body)
                    .on('complete', onCompletePost);
            }

        } else if (method === "PUT") {
            json = JSON.stringify(req.body);
            options = {data: json, headers: {}};
            options.headers['content-type'] = 'application/json';
            // console.log("PUT url:", url);
            // console.log("PUT options:", options);
            restler.put(url, options).on('complete', onComplete);

        } else if (method === "PATCH") {
            json = JSON.stringify(req.body);
            options = {data: json, headers: {}};
            options.headers['content-type'] = 'application/json';
            // console.log("PATCH url:", url);
            // console.log("PATCH options:", options);
            restler.patch(url, options).on('complete', onComplete);

        } else if (method === "DELETE") {
            // console.log("DELETE url:", url);
            restler.del(url, {})
                .on('complete', onComplete);
        }
    };

    // var makeRequest = function (path, method, req, res, onCompleteOverride) {

    app.all('/restProxy/*', function (req, res) {
        // console.log(req);
        var path = req.url;
        path = path.replace("restProxy/", "");
        makeRequest(path, req, res);
    });

    return { makeApiRequest : makeRequest };
};
<|endoftext|>


<commit_before>/**
 * Copyright (C) 2011 Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

define([
  'i18n!alerts',
  'jquery', // $
  'jquery.ajaxJSON', // ajaxJSON
  'jquery.instructure_forms', // validateForm, formErrors, errorBox
  'jquery.instructure_misc_helpers', // replaceTags
  'vendor/jquery.ba-tinypubsub', // /\.publish/
  'jqueryui/button' // /\.button/
], function(I18n, $) {

  $(function () {
    var $list = $('.alerts_list');

    var getAlertData = function($alert) {
      var criteria = [];
      $alert.find('ul.criteria li').each(function() {
        criteria.push({
          id: $(this).find('input[name="alert[criteria][][id]"]').attr('value'),
          criterion_type: $(this).data('value'),
          threshold: $(this).find('span').text()
        });
      });
      var recipients = [];
      $alert.find('ul.recipients li').each(function() {
        recipients.push($(this).data('value'));
      });
      var repetition = $alert.find('input[name="repetition"]:checked').attr('value');
      if(repetition == "value") {
        repetition = $alert.find('input[name="alert[repetition]"]').attr('value');
      } else {
        repetition = null;
      }
      return {criteria: criteria, recipients: recipients, repetition: repetition};
    }

    var addRecipientInOrder = function($node, $item) {
      $node.append($item);
      return $item;
    }

    var createElement = function(key, element, value, lookup) {
      var $element = $("<" + element + " />");
      $element.data('value', key);
      $element.html(lookup[key][value]);
      if(element == 'li') {
        $element.append(' ');
        $element.append($list.find('>.delete_item_link').clone().toggle());
      } else {
        $element.attr('value', key);
      }
      return $element;
    }

    var createRecipient = function(recipient, element) {
      $element = createElement(recipient, element, 'label', ENV.ALERTS.POSSIBLE_RECIPIENTS);
      if(element == 'li') {
        $element.prepend($("<input type='hidden' name='alert[recipients][]' />").attr('value', recipient));
      }
      return $element;
    }

    var createCriterion = function(criterion, element) {
      var criterion_type = criterion, threshold, id;
      if(typeof criterion == "object") {
        criterion_type = criterion.criterion_type;
        threshold = criterion.threshold;
        id = criterion.id;
      }
      $element = createElement(criterion_type, element, element == 'li' ? 'label' : 'option', ENV.ALERTS.POSSIBLE_CRITERIA)
      if (element == 'li') {
        if (!threshold) {
          threshold = ENV.ALERTS.POSSIBLE_CRITERIA[criterion_type].default_threshold;
        }
        $element.find('span').text(threshold);
        $element.find('input').attr('value', threshold).attr('title', ENV.ALERTS.POSSIBLE_CRITERIA[criterion_type].title);
        $element.prepend($("<input type='hidden' name='alert[criteria][][criterion_type]' />").attr('value', criterion_type));
        if(id) {
          $element.prepend($("<input type='hidden' name='alert[criteria][][id]' />").attr('value', id));
        }
      }
      return $element;
    }

    var restoreAlert = function($alert, data) {
      var $criteria = $alert.find('.criteria');
      $criteria.empty();
      for(var idx in data.criteria) {
        $criteria.append(createCriterion(data.criteria[idx], 'li'));
      }
      var $recipients = $alert.find('.recipients');
      $recipients.empty();
      for(var idx in data.recipients) {
        if (ENV.ALERTS.POSSIBLE_RECIPIENTS[data.recipients[idx]]) {
          $recipients.append(createRecipient(data.recipients[idx], 'li'));
        }
      }
      if(data.repetition) {
        $alert.find('input[name="repetition"][value="value"]').attr('checked', true);
        $alert.find('input[name="alert[repetition]"]').attr('value', data.repetition);
        $alert.find('.repetition_group .no_repetition').toggle(false);
        $alert.find('.repetition_group .repetition').toggle(true).find('span').text(data.repetition);
      } else {
        $alert.find('input[name="repetition"][value="none"]').attr('checked', true);
        $alert.find('.repetition_group .no_repetition').toggle(true);
        $alert.find('.repetition_group .repetition').toggle(false);
      }
    }

    for(var idx in ENV.ALERTS.DATA) {
      var alert = ENV.ALERTS.DATA[idx];
      restoreAlert($('#edit_alert_' + alert.id), alert);
    }

    $('.add_alert_link').click(function(event) {
      event.preventDefault();
      var $blank = $('.alert.blank');
      var $alert = $blank.clone();
      $alert.removeClass('blank');
      $alert.addClass('new');
      if($list.find('.alert:visible').length != 0) {
        $('

').insertBefore($blank);
      }
      var rand = Math.floor(Math.random() * 100000000);
      $alert.find('input').each(function() {
        $(this).attr('id', $.replaceTags($(this).attr('id'), 'id', rand));
      });
      $alert.find('label').each(function() {
        $(this).attr('for', $.replaceTags($(this).attr('for'), 'id', rand));
      });
      $alert.insertBefore($blank);
      $alert.find('.edit_link').trigger('click');
      $alert.toggle(false);
      $alert.slideDown();
    });

    $list.delegate('.edit_link', 'click', function() {
      var $alert = $(this).parents('.alert');
      var data = getAlertData($alert);
      $alert.data('data', data);

      var $criteria_select = $alert.find('.add_criterion_link').prev();
      $criteria_select.empty();
      var count = 0;
      for(var idx in ENV.ALERTS.POSSIBLE_CRITERIA_ORDER) {
        var criterion = ENV.ALERTS.POSSIBLE_CRITERIA_ORDER[idx];
        var found = -1;
        for(var jdx in data.criteria) {
          if(data.criteria[jdx].criterion_type == criterion) {
            found = jdx;
            break;
          }
        }
        if(found == -1) {
          $criteria_select.append(createCriterion(criterion, 'option'));
          count = count + 1;
        }
      }
      if(count == 0) {
        $alert.find('.add_criteria_line').toggle(false);
      }

      var $recipients_select = $alert.find('.add_recipient_link').prev();
      $recipients_select.empty();
      count = 0;
      for(var idx in ENV.ALERTS.POSSIBLE_RECIPIENTS_ORDER) {
        var recipient = ENV.ALERTS.POSSIBLE_RECIPIENTS_ORDER[idx];
        if($.inArray(recipient, data.recipients) == -1) {
          $recipients_select.append(createRecipient(recipient, 'option'));
          count = count + 1;
        }
      }
      if(count == 0) {
        $alert.find('.add_recipients_line').toggle(false);
      }

      $alert.find('.repetition_group label').toggle(true);
      $alert.toggleClass('editing');
      $alert.toggleClass('displaying');
      return false;
    }).delegate('.delete_link', 'click', function() {
      var $alert = $(this).parents('.alert');
      if(!$alert.hasClass('new')) {
        $alert.find('input[name="_method"]').attr('value', 'DELETE');
        $.ajaxJSON($alert.attr('action'), 'POST', $alert.serialize(), function(data) {
          $alert.slideUp(function() {
            $alert.remove();
            $list.find('.alert:first').prev('.alert_separator').remove();
            $list.find('.alert_separator + .alert_separator').remove();
            $list.find('.alert:visible:last').next('.alert_separator').remove();
          });
        });
      } else {
        $alert.slideUp(function() {
          $alert.remove();
          $list.find('.alert:first').prev('.alert_separator').remove();
          $list.find('.alert_separator + .alert_separator').remove();
          $list.find('.alert:visible:last').next('.alert_separator').remove();
        });
      }
      return false;
    }).delegate('.cancel_button', 'click', function() {
      $(this).parent().hideErrors();
      var $alert = $(this).parents('.alert');
      if($alert.hasClass('new')) {
        $alert.slideUp(function() {
          $alert.remove();
          $list.find('.alert:first').prev('.alert_separator').remove();
          $list.find('.alert_separator + .alert_separator').remove();
          $list.find('.alert:visible:last').next('.alert_separator').remove();
        });
      } else {
        var data = $alert.data('data');
        restoreAlert($alert, data);

        $alert.toggleClass('editing', false);
        $alert.toggleClass('displaying', true);
      }
      return false;
    }).delegate('.alert', 'submit', function() {
      var $alert = $(this);

      // Validation (validateForm doesn't support arrays, and formErrors
      // wouldn't be able to locate the correct elements)
      var errors = [];
      if($alert.find('.criteria li').length == 0) {
        errors.push([$alert.find('.add_criterion_link').prev(), I18n.t('errors.criteria_required', "At least one trigger is required")]);
      }
      $alert.find('.criteria input.editing').each(function() {
        var val = $(this).attr('value');
        if(!val || isNaN(val) || parseFloat(val) < 0) {
          errors.push([$(this), I18n.t('errors.threshold_should_be_numeric', "This should be a positive number")]);
        }
      });
      if($alert.find('.recipients li').length == 0) {
        errors.push([$alert.find('.add_recipient_link').prev(), I18n.t('errors.recipients_required', "At least one recipient is required")]);
      }
      if($alert.find('input[name="repetition"]:checked').attr('value') == 'none') {
        $alert.find('input[name="alert[repetition]"]').attr('value', '');
      } else {
        var $repetition = $alert.find('input[name="alert[repetition]"]');
        var val = $repetition.attr('value');
        if(!val || isNaN(val) || parseFloat(val) < 0) {
          errors.push([$repetition, I18n.t('errors.threshold_should_be_numeric', "This should be a positive number")]);
        }
      }
      if(errors.length != 0) {
        $alert.formErrors(errors);
        return false;
      }

      $.ajaxJSON($alert.attr('action'), 'POST', $alert.serialize(), function(data, xhr) {
        $alert.removeClass('new');
        $alert.attr('action', xhr.getResponseHeader('Location'));
        var $method = $alert.find('input[name="_method"]');
        if($method.length == 0) {
          $alert.append($('<input type="hidden" name="_method" value="put" />'));
        }
        $alert.toggleClass('editing', false);
        $alert.toggleClass('displaying', true);
        restoreAlert($alert, data);
      }, function(data) {
        $alert.formErrors(data);
      });
      return false;
    }).delegate('.recipients .delete_item_link', 'click', function() {
      var $li = $(this).parents('li');
      var $add_link = $(this).parents('.alert').find('.add_recipient_link');
      addRecipientInOrder($add_link.prev(), createRecipient($li.data('value'), 'option'));

      $li.slideUp(function() {
        $li.remove();
      });
      $add_link.parent().slideDown(function() {
        $add_link.parent().css('display', '');
      });
      return false;
    }).delegate('.add_recipient_link', 'click', function() {
      var $recipients = $(this).parents('.alert').find('.recipients');
      var $select = $(this).prev();
      var recipient = $select.attr('value');
      addRecipientInOrder($recipients, createRecipient(recipient, 'li')).toggle().slideDown();
      var $errorBox = $select.data('associated_error_box');
      if($errorBox) {
        $errorBox.fadeOut('slow', function() {
          $errorBox.remove();
        });
      }

      $select.find('option[value="' + recipient + '"]').remove();

      if($select.find('*').length == 0) {
        $(this).parent().slideUp();
      }
      return false;
    }).delegate('.criteria .delete_item_link', 'click', function() {
      var $li = $(this).parents('li');
      var $add_link = $(this).parents('.alert').find('.add_criterion_link');
      addRecipientInOrder($add_link.prev(), createCriterion($li.data('value'), 'option'));

      $li.slideUp(function(){
        $li.remove();
      });
      $add_link.parent().slideDown(function() {
        $add_link.parent().css('display', '');
      });
      return false;
    }).delegate('.add_criterion_link', 'click', function() {
      var $criteria = $(this).parents('.alert').find('.criteria');
      var $select = $(this).prev();
      var criterion = $select.attr('value');
      addRecipientInOrder($criteria, createCriterion(criterion, 'li')).toggle().slideDown();
      var $errorBox = $select.data('associated_error_box');
      if($errorBox) {
        $errorBox.fadeOut('slow', function() {
          $errorBox.remove();
        });
      }

      $select.find('option[value="' + criterion + '"]').remove();

      if($select.find('*').length == 0) {
        $(this).parent().slideUp();
      }
      return false;
    }).delegate('input[name="repetition"]', 'click', function() {
      var $error_box = $(this).parents('.alert').find('input[name="alert[repetition]"]').data('associated_error_box');
      if($error_box) {
        $error_box.fadeOut('slow', function() {
          $error_box.remove();
        });
      }
    });
  });
});

<commit_msg>Fix alerts label/radio button Firefox bug<commit_after>/**
 * Copyright (C) 2011 Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

define([
  'i18n!alerts',
  'jquery', // $
  'jquery.ajaxJSON', // ajaxJSON
  'jquery.instructure_forms', // validateForm, formErrors, errorBox
  'jquery.instructure_misc_helpers', // replaceTags
  'vendor/jquery.ba-tinypubsub', // /\.publish/
  'jqueryui/button' // /\.button/
], function(I18n, $) {

  $(function () {
    var $list = $('.alerts_list');

    var getAlertData = function($alert) {
      var criteria = [];
      $alert.find('ul.criteria li').each(function() {
        criteria.push({
          id: $(this).find('input[name="alert[criteria][][id]"]').attr('value'),
          criterion_type: $(this).data('value'),
          threshold: $(this).find('span').text()
        });
      });
      var recipients = [];
      $alert.find('ul.recipients li').each(function() {
        recipients.push($(this).data('value'));
      });
      var repetition = $alert.find('input[name="repetition"]:checked').attr('value');
      if(repetition == "value") {
        repetition = $alert.find('input[name="alert[repetition]"]').attr('value');
      } else {
        repetition = null;
      }
      return {criteria: criteria, recipients: recipients, repetition: repetition};
    }

    var addRecipientInOrder = function($node, $item) {
      $node.append($item);
      return $item;
    }

    var createElement = function(key, element, value, lookup) {
      var $element = $("<" + element + " />");
      $element.data('value', key);
      $element.html(lookup[key][value]);
      if(element == 'li') {
        $element.append(' ');
        $element.append($list.find('>.delete_item_link').clone().toggle());
      } else {
        $element.attr('value', key);
      }
      return $element;
    }

    var createRecipient = function(recipient, element) {
      $element = createElement(recipient, element, 'label', ENV.ALERTS.POSSIBLE_RECIPIENTS);
      if(element == 'li') {
        $element.prepend($("<input type='hidden' name='alert[recipients][]' />").attr('value', recipient));
      }
      return $element;
    }

    var createCriterion = function(criterion, element) {
      var criterion_type = criterion, threshold, id;
      if(typeof criterion == "object") {
        criterion_type = criterion.criterion_type;
        threshold = criterion.threshold;
        id = criterion.id;
      }
      $element = createElement(criterion_type, element, element == 'li' ? 'label' : 'option', ENV.ALERTS.POSSIBLE_CRITERIA)
      if (element == 'li') {
        if (!threshold) {
          threshold = ENV.ALERTS.POSSIBLE_CRITERIA[criterion_type].default_threshold;
        }
        $element.find('span').text(threshold);
        $element.find('input').attr('value', threshold).attr('title', ENV.ALERTS.POSSIBLE_CRITERIA[criterion_type].title);
        $element.prepend($("<input type='hidden' name='alert[criteria][][criterion_type]' />").attr('value', criterion_type));
        if(id) {
          $element.prepend($("<input type='hidden' name='alert[criteria][][id]' />").attr('value', id));
        }
      }
      return $element;
    }

    var restoreAlert = function($alert, data) {
      var $criteria = $alert.find('.criteria');
      $criteria.empty();
      for(var idx in data.criteria) {
        $criteria.append(createCriterion(data.criteria[idx], 'li'));
      }
      var $recipients = $alert.find('.recipients');
      $recipients.empty();
      for(var idx in data.recipients) {
        if (ENV.ALERTS.POSSIBLE_RECIPIENTS[data.recipients[idx]]) {
          $recipients.append(createRecipient(data.recipients[idx], 'li'));
        }
      }
      if(data.repetition) {
        $alert.find('input[name="repetition"][value="value"]').attr('checked', true);
        $alert.find('input[name="alert[repetition]"]').attr('value', data.repetition);
        $alert.find('.repetition_group .no_repetition').toggle(false);
        $alert.find('.repetition_group .repetition').toggle(true).find('span').text(data.repetition);
      } else {
        $alert.find('input[name="repetition"][value="none"]').attr('checked', true);
        $alert.find('.repetition_group .no_repetition').toggle(true);
        $alert.find('.repetition_group .repetition').toggle(false);
      }
    }

    for(var idx in ENV.ALERTS.DATA) {
      var alert = ENV.ALERTS.DATA[idx];
      restoreAlert($('#edit_alert_' + alert.id), alert);
    }

    $('.add_alert_link').click(function(event) {
      event.preventDefault();
      var $blank = $('.alert.blank');
      var $alert = $blank.clone();
      $alert.removeClass('blank');
      $alert.addClass('new');
      if($list.find('.alert:visible').length != 0) {
        $('

').insertBefore($blank);
      }
      var rand = Math.floor(Math.random() * 100000000);
      $alert.find('input').each(function() {
        $(this).attr('id', $.replaceTags($(this).attr('id'), 'id', rand));
      });
      $alert.find('label').each(function() {
        $(this).attr('for', $.replaceTags($(this).attr('for'), 'id', rand));
      });
      $alert.insertBefore($blank);
      $alert.find('.edit_link').trigger('click');
      $alert.toggle(false);
      $alert.slideDown();
    });

    $list.delegate('.edit_link', 'click', function() {
      var $alert = $(this).parents('.alert');
      var data = getAlertData($alert);
      $alert.data('data', data);

      var $criteria_select = $alert.find('.add_criterion_link').prev();
      $criteria_select.empty();
      var count = 0;
      for(var idx in ENV.ALERTS.POSSIBLE_CRITERIA_ORDER) {
        var criterion = ENV.ALERTS.POSSIBLE_CRITERIA_ORDER[idx];
        var found = -1;
        for(var jdx in data.criteria) {
          if(data.criteria[jdx].criterion_type == criterion) {
            found = jdx;
            break;
          }
        }
        if(found == -1) {
          $criteria_select.append(createCriterion(criterion, 'option'));
          count = count + 1;
        }
      }
      if(count == 0) {
        $alert.find('.add_criteria_line').toggle(false);
      }

      var $recipients_select = $alert.find('.add_recipient_link').prev();
      $recipients_select.empty();
      count = 0;
      for(var idx in ENV.ALERTS.POSSIBLE_RECIPIENTS_ORDER) {
        var recipient = ENV.ALERTS.POSSIBLE_RECIPIENTS_ORDER[idx];
        if($.inArray(recipient, data.recipients) == -1) {
          $recipients_select.append(createRecipient(recipient, 'option'));
          count = count + 1;
        }
      }
      if(count == 0) {
        $alert.find('.add_recipients_line').toggle(false);
      }

      $alert.find('.repetition_group label').toggle(true);
      $alert.toggleClass('editing');
      $alert.toggleClass('displaying');
      return false;
    }).delegate('.delete_link', 'click', function() {
      var $alert = $(this).parents('.alert');
      if(!$alert.hasClass('new')) {
        $alert.find('input[name="_method"]').attr('value', 'DELETE');
        $.ajaxJSON($alert.attr('action'), 'POST', $alert.serialize(), function(data) {
          $alert.slideUp(function() {
            $alert.remove();
            $list.find('.alert:first').prev('.alert_separator').remove();
            $list.find('.alert_separator + .alert_separator').remove();
            $list.find('.alert:visible:last').next('.alert_separator').remove();
          });
        });
      } else {
        $alert.slideUp(function() {
          $alert.remove();
          $list.find('.alert:first').prev('.alert_separator').remove();
          $list.find('.alert_separator + .alert_separator').remove();
          $list.find('.alert:visible:last').next('.alert_separator').remove();
        });
      }
      return false;
    }).delegate('.cancel_button', 'click', function() {
      $(this).parent().hideErrors();
      var $alert = $(this).parents('.alert');
      if($alert.hasClass('new')) {
        $alert.slideUp(function() {
          $alert.remove();
          $list.find('.alert:first').prev('.alert_separator').remove();
          $list.find('.alert_separator + .alert_separator').remove();
          $list.find('.alert:visible:last').next('.alert_separator').remove();
        });
      } else {
        var data = $alert.data('data');
        restoreAlert($alert, data);

        $alert.toggleClass('editing', false);
        $alert.toggleClass('displaying', true);
      }
      return false;
    }).delegate('.alert', 'submit', function() {
      var $alert = $(this);

      // Validation (validateForm doesn't support arrays, and formErrors
      // wouldn't be able to locate the correct elements)
      var errors = [];
      if($alert.find('.criteria li').length == 0) {
        errors.push([$alert.find('.add_criterion_link').prev(), I18n.t('errors.criteria_required', "At least one trigger is required")]);
      }
      $alert.find('.criteria input.editing').each(function() {
        var val = $(this).attr('value');
        if(!val || isNaN(val) || parseFloat(val) < 0) {
          errors.push([$(this), I18n.t('errors.threshold_should_be_numeric', "This should be a positive number")]);
        }
      });
      if($alert.find('.recipients li').length == 0) {
        errors.push([$alert.find('.add_recipient_link').prev(), I18n.t('errors.recipients_required', "At least one recipient is required")]);
      }
      if($alert.find('input[name="repetition"]:checked').attr('value') == 'none') {
        $alert.find('input[name="alert[repetition]"]').attr('value', '');
      } else {
        var $repetition = $alert.find('input[name="alert[repetition]"]');
        var val = $repetition.attr('value');
        if(!val || isNaN(val) || parseFloat(val) < 0) {
          errors.push([$repetition, I18n.t('errors.threshold_should_be_numeric', "This should be a positive number")]);
        }
      }
      if(errors.length != 0) {
        $alert.formErrors(errors);
        return false;
      }

      $.ajaxJSON($alert.attr('action'), 'POST', $alert.serialize(), function(data, xhr) {
        $alert.removeClass('new');
        $alert.attr('action', xhr.getResponseHeader('Location'));
        var $method = $alert.find('input[name="_method"]');
        if($method.length == 0) {
          $alert.append($('<input type="hidden" name="_method" value="put" />'));
        }
        $alert.toggleClass('editing', false);
        $alert.toggleClass('displaying', true);
        restoreAlert($alert, data);
      }, function(data) {
        $alert.formErrors(data);
      });
      return false;
    }).delegate('.recipients .delete_item_link', 'click', function() {
      var $li = $(this).parents('li');
      var $add_link = $(this).parents('.alert').find('.add_recipient_link');
      addRecipientInOrder($add_link.prev(), createRecipient($li.data('value'), 'option'));

      $li.slideUp(function() {
        $li.remove();
      });
      $add_link.parent().slideDown(function() {
        $add_link.parent().css('display', '');
      });
      return false;
    }).delegate('.add_recipient_link', 'click', function() {
      var $recipients = $(this).parents('.alert').find('.recipients');
      var $select = $(this).prev();
      var recipient = $select.attr('value');
      addRecipientInOrder($recipients, createRecipient(recipient, 'li')).toggle().slideDown();
      var $errorBox = $select.data('associated_error_box');
      if($errorBox) {
        $errorBox.fadeOut('slow', function() {
          $errorBox.remove();
        });
      }

      $select.find('option[value="' + recipient + '"]').remove();

      if($select.find('*').length == 0) {
        $(this).parent().slideUp();
      }
      return false;
    }).delegate('.criteria .delete_item_link', 'click', function() {
      var $li = $(this).parents('li');
      var $add_link = $(this).parents('.alert').find('.add_criterion_link');
      addRecipientInOrder($add_link.prev(), createCriterion($li.data('value'), 'option'));

      $li.slideUp(function(){
        $li.remove();
      });
      $add_link.parent().slideDown(function() {
        $add_link.parent().css('display', '');
      });
      return false;
    }).delegate('.add_criterion_link', 'click', function() {
      var $criteria = $(this).parents('.alert').find('.criteria');
      var $select = $(this).prev();
      var criterion = $select.attr('value');
      addRecipientInOrder($criteria, createCriterion(criterion, 'li')).toggle().slideDown();
      var $errorBox = $select.data('associated_error_box');
      if($errorBox) {
        $errorBox.fadeOut('slow', function() {
          $errorBox.remove();
        });
      }

      $select.find('option[value="' + criterion + '"]').remove();

      if($select.find('*').length == 0) {
        $(this).parent().slideUp();
      }
      return false;
    }).delegate('input[name="repetition"]', 'click', function() {
      var $error_box = $(this).parents('.alert').find('input[name="alert[repetition]"]').data('associated_error_box');
      if($error_box) {
        $error_box.fadeOut('slow', function() {
          $error_box.remove();
        });
      }
    }).delegate('label.repetition', 'click', function(event){
      event.preventDefault();
      $(this).parents('.alert').find('input[name="repetition"]').prop('checked', true);
    });
  });
});

<|endoftext|>


<commit_before>!function(){var a=function(){this.hash=function(a){return String(a).split("").reduce(function(a,b){return a=(a<<5)-a+b.charCodeAt(0),a&a},0)},this.isDOMElement=function(a){return"object"==typeof HTMLElement?a instanceof HTMLElement:a&&"object"==typeof a&&null!==a&&1===a.nodeType&&"string"==typeof a.nodeName}};IdentiHeart=function(e,f,g,h){if("undefined"==typeof e)throw new Error("Cannot instantiate an IdentiHeart without a target canvas.");var i=new a;if(!i.isDOMElement(e))throw new Error("The target canvas must be a DOM Element.");if("CANVAS"!==e.tagName)throw new Error("The target canvas must be a <canvas> element.");"undefined"==typeof f&&(console.info("No canvas 2D context was provided. Extracting from the target canvas..."),f=e.getContext("2d"));var j=["#F44336","#E91E63","#9C27B0","#673AB7","#3F51B5","#2196F3","#03A9F4","#00BCD4","#009688","#4CAF50","#8BC34A","#CDDC39","#FFEB3B","#FFC107","#FF9800","#FF5722","#795548","#607D8B"];return this.canvas=e,this.context=f,this.primary,this.accent,this.margin=g||5,this.scale=h||20,this.cellSize=this.canvas.width/2-this.margin*this.scale,this.hash,this.blocks,this.shape,this.hasStroke=!0,this.strokeWeight=500,this.strokeColor="#000000",this.compositeOperation="multiply",this.setUsername=function(b){var c=new a;return this.hash=c.hash(b),this},this.setPalette=function(a){return typeof a!=typeof[]||void 0===a.length?(console.warn("The palette must be an array of color values."),!1):a.length<2?(console.warn("The palette must contain at least two values."),!1):(j=a,this)},this.setHasStroke=function(a){return"boolean"!=typeof a?(console.warn("The parameter for the function IdentiHeart.setHasStroke() must be a boolean."),!1):(this.hasStroke=a,this)},this.setStrokeWeight=function(a){return"number"!=typeof a?(console.warn("The parameter for the function IdentiHeart.setStrokeWeight() must be a number."),!1):(this.strokeWeight=a,this)},this.setStrokeColor=function(a){return"string"!=typeof a?(console.warn("The stroke color must be a string."),!1):(this.strokeColor=a,this)},this.setCompositeOperation=function(a){var b=["source-over","source-in","source-out","source-atop","destination-over","destination-in","destination-out","destination-atop","lighter","copy","xor","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"];return a=a.toLowerCase(),-1===b.indexOf(a)?(console.warn('The provided composite operation "'+a+'" does not exist.'),!1):(this.compositeOperation=a,this)},this.setCanvas=function(b){var c=new a;return c.isDOMElement(e)?"CANVAS"!==e.tagName?(console.warn("The parameter for the function IdentiHeart.setCanvas() must be a <canvas> element."),!1):(this.canvas=b,this.context=b.getContext("2d"),this):(console.warn("The parameter for the function IdentiHeart.setCanvas() must be a DOM Element."),!1)},this.draw=function(){return this.init(),this.context.save(),this.context.translate(e.width/2,e.height/2),this.context.rotate(-Math.PI/4),this.context.translate(-e.width/2,-e.height/2),this.generateBlocks(),this.drawBlocks(),this.hasStroke&&this.drawOutline(),this.shape=new d(this.canvas,this.context,this.hash,this.primary,this.accent,{x:this.margin*this.scale+1.5*this.cellSize,y:this.margin*this.scale+.5*this.cellSize},this.scale,this.cellSize,this.strokeColor),this.shape.draw(this.hasStroke,this.strokeWeight),this.context.restore(),this},this.init=function(){this.blocks=new Array,this.shape=null,this.primary=j[Math.abs(this.hash%j.length)];var b=new a,c=b.hash(this.hash);return this.accent=j[Math.abs(c%j.length)],this.context.globalCompositeOperation="source-over",this.context.clearRect(0,0,this.canvas.width,this.canvas.height),this.context.globalCompositeOperation=this.compositeOperation,this},this.offset=function(){this.context.save(),this.context.translate(.6*this.scale,-.6*this.scale)},this.resetOffset=function(){this.context.restore()},this.drawOutline=function(){this.offset(),this.context.globalCompositeOperation="source-over",this.context.beginPath(),this.context.moveTo(this.margin*this.scale,this.margin*this.scale),this.context.lineTo(this.margin*this.scale,this.canvas.height-this.margin*this.scale),this.context.lineTo(this.canvas.width-this.margin*this.scale,this.canvas.height-this.margin*this.scale),this.context.lineTo(this.canvas.width-this.margin*this.scale,this.canvas.height/2),this.context.lineTo(this.canvas.width/2,this.canvas.height/2),this.context.lineTo(this.canvas.width/2,this.margin*this.scale),this.context.closePath(),this.context.strokeStyle=this.strokeColor,this.context.lineWidth=this.scale*(this.strokeWeight/this.canvas.width),this.context.lineJoin="round",this.context.lineCap="round",this.context.stroke(),this.context.beginPath(),this.context.moveTo(this.canvas.width/2,this.canvas.height/2),this.context.lineTo(this.margin*this.scale,this.canvas.height/2),this.context.moveTo(this.canvas.width/2,this.canvas.height/2),this.context.lineTo(this.canvas.width/2,this.canvas.height-this.margin*this.scale),this.context.stroke(),this.resetOffset(),this.context.globalCompositeOperation=this.compositeOperation},this.generateBlocks=function(){var a=new c(this.canvas,this.context,b.ONE,this.primary,this.accent);a.setHash(this.hash),a.setPos({x:this.margin*this.scale,y:this.margin*this.scale}),a.setSizing(this.cellSize,this.margin,this.scale),this.blocks.push(a);var d=new c(this.canvas,this.context,b.TWO,this.primary,this.accent);d.setHash(this.hash),d.setPos({x:this.margin*this.scale,y:this.canvas.height/2}),d.setSizing(this.cellSize,this.margin,this.scale),this.blocks.push(d);var e=new c(this.canvas,this.context,b.THREE,this.primary,this.accent);e.setHash(this.hash),e.setPos({x:this.canvas.width/2,y:this.canvas.height/2}),e.setSizing(this.cellSize,this.margin,this.scale),this.blocks.push(e)},this.drawBlocks=function(){if(0==this.blocks.length)return!1;for(var a=0;a<this.blocks.length;a++)this.blocks[a].draw()},this};var b=new function(){this.ONE=1,this.TWO=2,this.THREE=3},c=function(a,c,d,e,f){this.type=d,this.primary=e,this.accent=f,this.cellSize,this.margin,this.scale,this.pos,this.hash,this.setHash=function(a){return"number"!=typeof a?(console.warn("The provided hash must be a number."),!1):void(this.hash=a)},this.setPos=function(a){return"object"!=typeof a?(console.warn("The position must be an object."),!1):void(this.pos=a)},this.setSizing=function(a,b,c){return"number"!=typeof a||"number"!=typeof b||"number"!=typeof c?(console.warn("Sizing parameters must be numbers."),!1):(this.cellSize=a,this.margin=b,void(this.scale=c))},this.offset=function(){c.save(),c.translate(.6*this.scale,-.6*this.scale)},this.resetOffset=function(){c.restore()},this.makePath=function(a,b){var d=Math.abs(a+b)%4;switch(d){case 0:c.beginPath(),c.moveTo(this.pos.x,this.pos.y),c.lineTo(this.pos.x+this.cellSize,this.pos.y),c.lineTo(this.pos.x+this.cellSize,this.pos.y+this.cellSize),c.closePath();break;case 1:c.beginPath(),c.moveTo(this.pos.x+this.cellSize,this.pos.y),c.lineTo(this.pos.x+this.cellSize,this.pos.y+this.cellSize),c.lineTo(this.pos.x,this.pos.y+this.cellSize),c.closePath();break;case 2:c.beginPath(),c.moveTo(this.pos.x,this.pos.y),c.lineTo(this.pos.x,this.pos.y+this.cellSize),c.lineTo(this.pos.x+this.cellSize,this.pos.y+this.cellSize),c.closePath();break;case 3:c.beginPath(),c.moveTo(this.pos.x,this.pos.y),c.lineTo(this.pos.x+this.cellSize,this.pos.y),c.lineTo(this.pos.x,this.pos.y+this.cellSize),c.closePath();break;default:c.beginPath(),c.moveTo(this.pos.x,this.pos.y),c.lineTo(this.pos.x+this.cellSize,this.pos.y),c.lineTo(this.pos.x,this.pos.y+this.cellSize),c.closePath()}},this.draw=function(){this.offset(),this.type===b.ONE?(this.makePath(this.hash,this.hash%3),c.fillStyle=this.primary,c.fill(),this.makePath(this.hash,this.hash%5),c.fillStyle=this.accent,c.fill()):this.type===b.TWO?(this.makePath(this.hash,this.hash%4),c.fillStyle=this.accent,c.fill(),this.makePath(this.hash,this.hash%3),c.fillStyle=this.primary,c.fill()):(this.makePath(this.hash,this.hash%7),c.fillStyle=this.accent,c.fill(),this.makePath(this.hash,this.hash%8),c.fillStyle=this.primary,c.fill()),this.resetOffset()}},d=function(a,b,c,d,e,f,g,h,i){this.hash=c,this.primary=d,this.accent=e,this.pos=f,this.scale=g,this.cellSize=h,this.strokeColor=i,this.getColor=function(){return[this.primary,this.accent][Math.abs(this.hash%2)]},this.makePath=function(){var a=Math.abs(this.hash+1)%4;switch(a){case 0:b.beginPath(),b.moveTo(this.pos.x,this.pos.y),b.lineTo(this.pos.x+this.cellSize/2,this.pos.y),b.lineTo(this.pos.x+this.cellSize/2,this.pos.y-this.cellSize/2),b.lineTo(this.pos.x,this.pos.y-this.cellSize/2),b.closePath();break;case 1:b.beginPath(),b.arc(this.pos.x+this.cellSize/Math.PI-5,this.pos.y-this.cellSize/Math.PI+5,this.cellSize/3,0,2*Math.PI,!0);break;case 2:b.beginPath(),b.moveTo(this.pos.x,this.pos.y),b.lineTo(this.pos.x+.65*this.cellSize,this.pos.y),b.lineTo(this.pos.x,this.pos.y-.65*this.cellSize),b.closePath();break;case 3:b.beginPath(),b.moveTo(this.pos.x-.2*this.cellSize,this.pos.y+.2*this.cellSize),b.quadraticCurveTo(this.pos.x+.4*this.cellSize,this.pos.y,this.pos.x+.5*this.cellSize,this.pos.y-.5*this.cellSize),b.moveTo(this.pos.x+.5*this.cellSize,this.pos.y-.5*this.cellSize),b.quadraticCurveTo(this.pos.x,this.pos.y-.4*this.cellSize,this.pos.x-.2*this.cellSize,this.pos.y+.2*this.cellSize);break;default:b.beginPath(),b.moveTo(this.pos.x,this.pos.y),b.lineTo(this.pos.x+this.cellSize/2,this.pos.y),b.lineTo(this.pos.x+this.cellSize/2,this.pos.y-this.cellSize/2),b.lineTo(this.pos.x,this.pos.y-this.cellSize/2),b.closePath()}},this.draw=function(c,d){var e=this.getColor();b.globalCompositeOperation="source-over",this.makePath(),b.fillStyle=e,b.strokeStyle=i,b.lineWidth=this.scale*(.8*d/a.width),b.lineJoin="round",b.lineCap="round",b.fill(),c&&b.stroke()}}}();<commit_msg>Updated min lib<commit_after>!function(){var a=function(){this.hash=function(a){return String(a).split("").reduce(function(a,b){return a=(a<<5)-a+b.charCodeAt(0),a&a},0)},this.isDOMElement=function(a){return"object"==typeof HTMLElement?a instanceof HTMLElement:a&&"object"==typeof a&&null!==a&&1===a.nodeType&&"string"==typeof a.nodeName}};IdentiHeart=function(e,f,g,h){if("undefined"==typeof e)throw new Error("Cannot instantiate an IdentiHeart without a target canvas.");var i=new a;if(!i.isDOMElement(e))throw new Error("The target canvas must be a DOM Element.");if("CANVAS"!==e.tagName)throw new Error("The target canvas must be a <canvas> element.");"undefined"==typeof f&&(console.info("No canvas 2D context was provided. Extracting from the target canvas..."),f=e.getContext("2d"));var j=["#F44336","#E91E63","#9C27B0","#673AB7","#3F51B5","#2196F3","#03A9F4","#00BCD4","#009688","#4CAF50","#8BC34A","#CDDC39","#FFEB3B","#FFC107","#FF9800","#FF5722","#795548","#607D8B"];return this.canvas=e,this.context=f,this.primary,this.accent,this.margin=g||5,this.scale=h||20,this.cellSize=this.canvas.width/2-this.margin*this.scale,this.hash,this.blocks,this.shape,this.hasStroke=!0,this.strokeWeight=500,this.strokeColor="#000000",this.compositeOperation="multiply",this.setUsername=function(b){var c=new a;return this.hash=c.hash(b),this},this.setPalette=function(a){return typeof a!=typeof[]||void 0===a.length?(console.warn("The palette must be an array of color values."),!1):a.length<2?(console.warn("The palette must contain at least two values."),!1):(j=a,this)},this.setHasStroke=function(a){return"boolean"!=typeof a?(console.warn("The parameter for the function IdentiHeart.setHasStroke() must be a boolean."),!1):(this.hasStroke=a,this)},this.setStrokeWeight=function(a){return"number"!=typeof a?(console.warn("The parameter for the function IdentiHeart.setStrokeWeight() must be a number."),!1):(this.strokeWeight=a,this)},this.setStrokeColor=function(a){return"string"!=typeof a?(console.warn("The stroke color must be a string."),!1):(this.strokeColor=a,this)},this.setCompositeOperation=function(a){var b=["source-over","source-in","source-out","source-atop","destination-over","destination-in","destination-out","destination-atop","lighter","copy","xor","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"];return a=a.toLowerCase(),-1===b.indexOf(a)?(console.warn('The provided composite operation "'+a+'" does not exist.'),!1):(this.compositeOperation=a,this)},this.setCanvas=function(b){var c=new a;return c.isDOMElement(e)?"CANVAS"!==e.tagName?(console.warn("The parameter for the function IdentiHeart.setCanvas() must be a <canvas> element."),!1):(this.canvas=b,this.context=b.getContext("2d"),this):(console.warn("The parameter for the function IdentiHeart.setCanvas() must be a DOM Element."),!1)},this.draw=function(){return this.init(),this.context.save(),this.context.translate(e.width/2,e.height/2),this.context.rotate(-Math.PI/4),this.context.translate(-e.width/2,-e.height/2),this.generateBlocks(),this.drawBlocks(),this.hasStroke&&this.drawOutline(),this.shape=new d(this.canvas,this.context,this.hash,this.primary,this.accent,{x:this.margin*this.scale+1.5*this.cellSize,y:this.margin*this.scale+.5*this.cellSize},this.scale,this.cellSize,this.strokeColor),this.shape.draw(this.hasStroke,this.strokeWeight),this.context.restore(),this},this.init=function(){this.blocks=new Array,this.shape=null,this.primary=j[Math.abs(this.hash%j.length)];var b=new a,c=b.hash(this.hash);return this.accent=j[Math.abs(c%j.length)],this.context.globalCompositeOperation="source-over",this.context.clearRect(0,0,this.canvas.width,this.canvas.height),this.context.globalCompositeOperation=this.compositeOperation,this},this.offset=function(){this.context.save(),this.context.translate(.6*this.scale,-.6*this.scale)},this.resetOffset=function(){this.context.restore()},this.drawOutline=function(){this.offset(),this.context.globalCompositeOperation="source-over",this.context.beginPath(),this.context.moveTo(this.margin*this.scale,this.margin*this.scale),this.context.lineTo(this.margin*this.scale,this.canvas.height-this.margin*this.scale),this.context.lineTo(this.canvas.width-this.margin*this.scale,this.canvas.height-this.margin*this.scale),this.context.lineTo(this.canvas.width-this.margin*this.scale,this.canvas.height/2),this.context.lineTo(this.canvas.width/2,this.canvas.height/2),this.context.lineTo(this.canvas.width/2,this.margin*this.scale),this.context.closePath(),this.context.strokeStyle=this.strokeColor,this.context.lineWidth=this.scale*(this.strokeWeight/this.canvas.width),this.context.lineJoin="round",this.context.lineCap="round",this.context.stroke(),this.context.beginPath(),this.context.moveTo(this.canvas.width/2,this.canvas.height/2),this.context.lineTo(this.margin*this.scale,this.canvas.height/2),this.context.moveTo(this.canvas.width/2,this.canvas.height/2),this.context.lineTo(this.canvas.width/2,this.canvas.height-this.margin*this.scale),this.context.stroke(),this.resetOffset(),this.context.globalCompositeOperation=this.compositeOperation},this.generateBlocks=function(){var a=new c(this.canvas,this.context,b.ONE,this.primary,this.accent);a.setHash(this.hash),a.setPos({x:this.margin*this.scale,y:this.margin*this.scale}),a.setSizing(this.cellSize,this.margin,this.scale),this.blocks.push(a);var d=new c(this.canvas,this.context,b.TWO,this.primary,this.accent);d.setHash(this.hash),d.setPos({x:this.margin*this.scale,y:this.canvas.height/2}),d.setSizing(this.cellSize,this.margin,this.scale),this.blocks.push(d);var e=new c(this.canvas,this.context,b.THREE,this.primary,this.accent);e.setHash(this.hash),e.setPos({x:this.canvas.width/2,y:this.canvas.height/2}),e.setSizing(this.cellSize,this.margin,this.scale),this.blocks.push(e)},this.drawBlocks=function(){if(0==this.blocks.length)return!1;for(var a=0;a<this.blocks.length;a++)this.blocks[a].draw()},this};var b=new function(){this.ONE=1,this.TWO=2,this.THREE=3},c=function(a,c,d,e,f){this.type=d,this.primary=e,this.accent=f,this.cellSize,this.margin,this.scale,this.pos,this.hash,this.setHash=function(a){return"number"!=typeof a?(console.warn("The provided hash must be a number."),!1):void(this.hash=a)},this.setPos=function(a){return"object"!=typeof a?(console.warn("The position must be an object."),!1):void(this.pos=a)},this.setSizing=function(a,b,c){return"number"!=typeof a||"number"!=typeof b||"number"!=typeof c?(console.warn("Sizing parameters must be numbers."),!1):(this.cellSize=a,this.margin=b,void(this.scale=c))},this.offset=function(){c.save(),c.translate(.6*this.scale,-.6*this.scale)},this.resetOffset=function(){c.restore()},this.makePath=function(a,b){var d=Math.abs(a+b)%4;switch(d){case 0:c.beginPath(),c.moveTo(this.pos.x,this.pos.y),c.lineTo(this.pos.x+this.cellSize,this.pos.y),c.lineTo(this.pos.x+this.cellSize,this.pos.y+this.cellSize),c.closePath();break;case 1:c.beginPath(),c.moveTo(this.pos.x+this.cellSize,this.pos.y),c.lineTo(this.pos.x+this.cellSize,this.pos.y+this.cellSize),c.lineTo(this.pos.x,this.pos.y+this.cellSize),c.closePath();break;case 2:c.beginPath(),c.moveTo(this.pos.x,this.pos.y),c.lineTo(this.pos.x,this.pos.y+this.cellSize),c.lineTo(this.pos.x+this.cellSize,this.pos.y+this.cellSize),c.closePath();break;case 3:c.beginPath(),c.moveTo(this.pos.x,this.pos.y),c.lineTo(this.pos.x+this.cellSize,this.pos.y),c.lineTo(this.pos.x,this.pos.y+this.cellSize),c.closePath();break;default:c.beginPath(),c.moveTo(this.pos.x,this.pos.y),c.lineTo(this.pos.x+this.cellSize,this.pos.y),c.lineTo(this.pos.x,this.pos.y+this.cellSize),c.closePath()}},this.draw=function(){this.offset(),this.type===b.ONE?(this.makePath(this.hash,this.hash%3),c.fillStyle=this.primary,c.fill(),this.makePath(this.hash,this.hash%5),c.fillStyle=this.accent,c.fill()):this.type===b.TWO?(this.makePath(this.hash,this.hash%4),c.fillStyle=this.accent,c.fill(),this.makePath(this.hash,this.hash%3),c.fillStyle=this.primary,c.fill()):(this.makePath(this.hash,this.hash%7),c.fillStyle=this.accent,c.fill(),this.makePath(this.hash,this.hash%8),c.fillStyle=this.primary,c.fill()),this.resetOffset()}},d=function(a,b,c,d,e,f,g,h,i){this.hash=c,this.primary=d,this.accent=e,this.pos=f,this.scale=g,this.cellSize=h,this.strokeColor=i,this.getColor=function(){return[this.primary,this.accent][Math.abs(this.hash%2)]},this.makePath=function(){var a=Math.abs(this.hash+1)%4;switch(a){case 0:b.beginPath(),b.moveTo(this.pos.x,this.pos.y),b.lineTo(this.pos.x+this.cellSize/2,this.pos.y),b.lineTo(this.pos.x+this.cellSize/2,this.pos.y-this.cellSize/2),b.lineTo(this.pos.x,this.pos.y-this.cellSize/2),b.closePath();break;case 1:b.beginPath(),b.arc(this.pos.x+this.cellSize/Math.PI-5,this.pos.y-this.cellSize/Math.PI+5,this.cellSize/3,0,2*Math.PI,!0);break;case 2:b.beginPath(),b.moveTo(this.pos.x,this.pos.y),b.lineTo(this.pos.x+.65*this.cellSize,this.pos.y),b.lineTo(this.pos.x,this.pos.y-.65*this.cellSize),b.closePath();break;case 3:b.beginPath(),b.moveTo(this.pos.x-.2*this.cellSize,this.pos.y+.2*this.cellSize),b.quadraticCurveTo(this.pos.x+.4*this.cellSize,this.pos.y,this.pos.x+.5*this.cellSize,this.pos.y-.5*this.cellSize),b.moveTo(this.pos.x+.5*this.cellSize,this.pos.y-.5*this.cellSize),b.quadraticCurveTo(this.pos.x,this.pos.y-.4*this.cellSize,this.pos.x-.2*this.cellSize,this.pos.y+.2*this.cellSize);break;default:b.beginPath(),b.moveTo(this.pos.x,this.pos.y),b.lineTo(this.pos.x+this.cellSize/2,this.pos.y),b.lineTo(this.pos.x+this.cellSize/2,this.pos.y-this.cellSize/2),b.lineTo(this.pos.x,this.pos.y-this.cellSize/2),b.closePath()}},this.draw=function(c,d){var e=this.getColor();b.globalCompositeOperation="source-over",this.makePath(),b.fillStyle=e,b.strokeStyle=this.strokeColor,b.lineWidth=this.scale*(.8*d/a.width),b.lineJoin="round",b.lineCap="round",b.fill(),c&&b.stroke()}}}();<|endoftext|>


<commit_before>munit.queue( 'Integration.delay', 7, function( queue, assert ) {
	MUNIT( 'single', function( module ) {
		module.delay( 50, function( m ) {
			assert.equal( 'current module passed to callback', m, module );
			module.pass( 'first test' );
		});
	});

	MUNIT( 'nested', function( module ) {
		module.delay( 50, function(){
			module.pass( 'first level' );
			module.delay( 50, function(){
				module.pass( 'second level' );
				module.delay( 50, function(){
					module.pass( 'third and last level' );
					assert.pass( 'third nested level reached' );
				});
			});
		});
	});

	MUNIT( 'extend', { timeout: 50 }, function( module ) {
		module.delay( 100, function(){
			module.pass( 'extension' );
			assert.pass( 'extension met' );
		});
	});

	MUNIT.render(function( e, m ) {
		assert.log( MUNIT.tests, e );
		assert.empty( 'no error', e );
		assert.equal( 'correct munit passed back', m, MUNIT );
		assert.equal( 'all tests met', MUNIT.passed, 5 );
		assert.equal( 'no failed tests', MUNIT.failed, 0 );
	});
});
<commit_msg>Removing debug code<commit_after>munit.queue( 'Integration.delay', 7, function( queue, assert ) {
	MUNIT( 'single', function( module ) {
		module.delay( 50, function( m ) {
			assert.equal( 'current module passed to callback', m, module );
			module.pass( 'first test' );
		});
	});

	MUNIT( 'nested', function( module ) {
		module.delay( 50, function(){
			module.pass( 'first level' );
			module.delay( 50, function(){
				module.pass( 'second level' );
				module.delay( 50, function(){
					module.pass( 'third and last level' );
					assert.pass( 'third nested level reached' );
				});
			});
		});
	});

	MUNIT( 'extend', { timeout: 50 }, function( module ) {
		module.delay( 100, function(){
			module.pass( 'extension' );
			assert.pass( 'extension met' );
		});
	});

	MUNIT.render(function( e, m ) {
		assert.empty( 'no error', e );
		assert.equal( 'correct munit passed back', m, MUNIT );
		assert.equal( 'all tests met', MUNIT.passed, 5 );
		assert.equal( 'no failed tests', MUNIT.failed, 0 );
	});
});
<|endoftext|>


<commit_before>/*global window:true */

var _tics = _tics || {};

_tics.gaProvider = (function () {
	'use strict';

	var isInitialized = false;

	var ga = null;
	var helper = null;
	var functions = null;
	var account = null;
	var domain = null;

	var runCustomFunction = function (elm) {
		var funcName = elm.getAttribute('data-val-analyze-custom');
		var func;

		if (!funcName) {
			return null;
		}

		func = functions.get(funcName);

		if (typeof func !== 'function') {
			return null;
		}

		return func.apply(null, [elm, ga]);
	};

	var sendTrackingFor = function (elm, ev) {
		if (!isInitialized) {
			return;
		}

		var url = helper.createUrlBy(elm);
		var category = elm.tagName;
		var action = ev.type;
		var label = helper.getValueFrom(elm);

		var result = runCustomFunction(elm, ga);

		if (result) {
			if(result.isProvisioned) {
				return;
			}

			if (result.isPartialData) {
				url = helper.appendToUrl(url, result.data);
			} else {
				url = result.data;
			}
		}

		ga('send', 'pageview', url);
		ga('send', 'event', category, action, label);
	};

	var setDefaults = function () {
		if (!isInitialized) {
			return;
		}

		ga('create', account, domain);
		ga('send', 'pageview');
	};

	var initialize = function (gaAccount) {
		if (!gaAccount || !gaAccount.account || !gaAccount.domain) {
			return;
		}

		ga = window.ga;
		helper = _tics.helper;
		functions = _tics.functions;

		account = gaAccount.account;
		domain = gaAccount.domain;

		isInitialized = true;
	};

	return {
		init: initialize,
		trackPage: setDefaults,
		track: sendTrackingFor
	};
}());<commit_msg>gaProvider bug fixes<commit_after>/*global window:true */

var _tics = _tics || {};

_tics.gaProvider = (function () {
	'use strict';

	var isInitialized = false;

	var helper = null;
	var functions = null;
	var account = null;
	var domain = null;

	var runCustomFunction = function (elm) {
		var funcName = elm.getAttribute('data-val-analyze-custom');
		var func;

		if (!funcName) {
			return null;
		}

		func = functions.get(funcName);

		if (typeof func !== 'function') {
			return null;
		}

		return func.apply(null, [elm, window.ga]);
	};

	var sendTrackingFor = function (elm, ev) {
		if (!isInitialized) {
			return;
		}

		var url = helper.createUrlBy(elm);
		var category = elm.tagName;
		var action = ev.type;
		var label = helper.getValueFrom(elm);

		var result = runCustomFunction(elm);

		if (result) {
			if(result.isProvisioned) {
				return;
			}

			if (result.isPartialData) {
				url = helper.appendToUrl(url, result.data);
			} else {
				url = result.data;
			}
		}

		window.ga('send', 'pageview', url);
		window.ga('send', 'event', category, action, label);
	};

	var setDefaults = function () {
		if (!isInitialized) {
			return;
		}

		window.ga('create', account, domain);
		window.ga('send', 'pageview');
	};

	var initialize = function (gaAccount) {
		if (!gaAccount || !gaAccount.account || !gaAccount.domain) {
			return;
		}

		helper = _tics.helper;
		functions = _tics.functions;

		account = gaAccount.account;
		domain = gaAccount.domain;

		isInitialized = true;
	};

	return {
		init: initialize,
		trackPage: setDefaults,
		track: sendTrackingFor
	};
}());<|endoftext|>


<commit_before>(function(exports) {
    "use strict";

    var PANEL_BACKGROUND_COLOR = "#eeeeec";

    var Panel = new Class({
        Extends: Window,
        connect: function(server) {
            this.parent(server);
            this._leftButtons = [];
            this._rightButtons = [];
            this._display.changeAttributes({ windowId: this.windowId,
                                             backgroundColor: PANEL_BACKGROUND_COLOR });
            this._display.selectInput({ windowId: this._display.rootWindowId,
                                        events: ["ConfigureNotify"] });
            this._display.changeProperty({ windowId: this.windowId,
                                           name: "_NET_WM_WINDOW_TYPE",
                                           value: "_NET_WM_WINDOW_TYPE_DOCK" });
            this._syncSize();
            this._display.mapWindow({ windowId: this.windowId });
        },
        _syncSize: function() {
            var rootWindowGeometry = this._display.getGeometry({ drawableId: this._display.rootWindowId });
            this._display.configureWindow({ windowId: this.windowId,
                                            width: rootWindowGeometry.width,
                                            height: 30 });
        },
        _relayout: function() {
            var padding = 4;
            var x;
            x = padding;

            var buttonHeight = this.height - 1;
            this._leftButtons.forEach(function(button) {
                var geom = this._display.getGeometry({ drawableId: button.windowId });
                this._display.configureWindow({ windowId: button.windowId,
                                                x: x, y: 0, height: buttonHeight });
                x += geom.width + padding;
            }.bind(this));

            x = this.width - padding;
            this._rightButtons.forEach(function(button) {
                var geom = this._display.getGeometry({ drawableId: button.windowId });
                x -= geom.width;
                this._display.configureWindow({ windowId: button.windowId,
                                               x: x, y: 0, height: buttonHeight });
                x -= padding;
            }.bind(this));
        },
        configureNotify: function(event) {
            this.parent(event);

            // Try and resize if the root window changes size
            if (event.windowId === this._display.rootWindowId)
                this._syncSize();

            // If we've changed width, relayout.
            else if (event.windowId === this.windowId && event.width !== undefined)
                this._relayout();

            // And if a button changes width, relayout as well.
            else if (event.windowId !== this.windowId && event.width !== undefined)
                this._relayout();
        },
        _addButton: function(box, button) {
            box.push(button);
            this._display.selectInput({ windowId: button.windowId,
                                        events: ["ConfigureNotify"] });
            this._display.reparentWindow({ windowId: button.windowId,
                                           newParentId: this.windowId });
            this._display.mapWindow({ windowId: button.windowId });
            this._relayout();
        },
        _removeButton: function(box, button) {
            var idx = box.indexOf(button);
            // XXX -- way to unselect for input
            this._display.reparentWindow({ windowId: button.windowId,
                                           newParentId: this._display.rootWindowId });
            box.splice(idx, 1);
        },
        addLauncher: function(launcher) {
            this._addButton(this._leftButtons, launcher);
        },
        removeLauncher: function(launcher) {
            this._removeButton(this._leftButtons, launcher);
        },
        addAction: function(action) {
            this._addButton(this._rightButtons, action);
        },
        removeAction: function(action) {
            this._removeButton(this._rightButtons, action);
        },
        _draw: function() {
            this._display.drawTo(this.windowId, function(ctx) {
                this._exposeHandler.clip(ctx);

                ctx.strokeStyle = '#bec0c0';
                ctx.lineWidth = 1;
                ctx.beginPath();
                ctx.moveTo(0, this.height - 0.5);
                ctx.lineTo(this.width, this.height - 0.5);
                ctx.stroke();
            }.bind(this));
        },
    });

    // Used for operations like measureText which require
    // a 2D context but we don't really draw anything to.
    var tmpCanvas = document.createElement("canvas");
    var tmpCtx = tmpCanvas.getContext("2d");

    var Menu = new Class({
        Extends: Window,
        connect: function(server) {
            this.parent(server);
            this._display.changeAttributes({ windowId: this.windowId,
                                             backgroundColor: "#ffffff",
                                             overrideRedirect: true });
            this._display.selectInput({ windowId: this.windowId,
                                       events: ["ButtonPress", "ButtonRelease"] });
        },
        _syncGeometry: function(openerWindowId) {
            var tree = this._display.queryTree({ windowId: openerWindowId });
            var geometry = this._display.getGeometry({ drawableId: openerWindowId });
            var rootCoords = this._display.translateCoordinates({ srcWindowId: tree.parent,
                                                                 destWindowId: this._display.rootWindowId,
                                                                 x: geometry.x, y: geometry.y });

            var width = 200;
            var height = 200;

            // XXX: hardcoded anchor to the bottom right
            var openerRight = rootCoords.x + geometry.width;
            var openerBottom = rootCoords.y + geometry.height;

            var x = openerRight - width;
            var y = openerBottom;

            this._display.configureWindow({ windowId: this.windowId,
                                           x: x, y: y, width: width, height: height });
        },
        _grab: function() {
            this._display.grabPointer({ windowId: this.windowId,
                                        ownerEvents: true,
                                        events: [],
                                        pointerMode: "Async",
                                        cursor: "" });
        },
        _ungrab: function() {
            this._display.ungrabPointer({ windowId: this.windowId });
        },
        open: function(openerWindowId, closedCallback) {
            this._syncGeometry(openerWindowId);
            this._display.configureWindow({ windowId: this.windowId, stackMode: "Above" });
            this._display.mapWindow({ windowId: this.windowId });
            this._grab();
            this._closedCallback = closedCallback;
        },
        close: function() {
            this._display.unmapWindow({ windowId: this.windowId });
            this._closedCallback();
        },
        _draw: function() {
        },
        handleEvent: function(event) {
            switch (event.type) {
            case "ButtonRelease":
                return this.close();
            default:
                return this.parent(event);
            }
        },
    });

    var MenuButton = new Class({
        Extends: Window,
        initialize: function(label) {
            this.parent();
            this._label = label;
            this._font = '11pt sans-serif';

            this.menu = new Menu();
        },
        connect: function(server) {
            this.parent(server);
            this._syncSize();
            this._display.changeAttributes({ windowId: this.windowId,
                                             backgroundColor: PANEL_BACKGROUND_COLOR });
            this._display.selectInput({ windowId: this.windowId,
                                        events: ["ButtonPress"] });

            this.menu.connect(server);
        },
        _syncSize: function() {
            var padding = 4;
            tmpCtx.save();
            tmpCtx.font = this._font;
            var metrics = tmpCtx.measureText(this._label);
            tmpCtx.restore();
            var width = metrics.width + padding * 2;
            this._display.configureWindow({ windowId: this.windowId,
                                            width: width });
        },
        _draw: function() {
            var padding = 4;
            this._display.drawTo(this.windowId, function(ctx) {
                this._exposeHandler.clip(ctx);

                ctx.font = this._font;
                ctx.fillStyle = '#000000';
                // XXX: Browsers can't measure alphabetic baseline yet,
                // so just hardcode it for now.
                // var metrics = ctx.measureText(this._label);
                // var baseline = metrics.alphabeticBaseline;
                var baseline = 11;
                var y = (this.height - baseline) / 2 + baseline;
                ctx.fillText(this._label, padding, y);
            }.bind(this));
        },
        _onMenuClosed: function() {
            this._display.changeAttributes({ windowId: this.windowId,
                                             backgroundColor: PANEL_BACKGROUND_COLOR });
        },
        _clicked: function() {
            this.menu.open(this.windowId, this._onMenuClosed.bind(this));
            this._display.changeAttributes({ windowId: this.windowId,
                                             backgroundColor: "#ffffff" });
        },
        handleEvent: function(event) {
            switch (event.type) {
            case "ButtonPress":
                return this._clicked(event);
            default:
                return this.parent(event);
            }
        },
    });

    var Button = new Class({
        Extends: Window,
        initialize: function(imageSrc) {
            this.parent();
            this._imageSrc = imageSrc;
        },
        connect: function(server) {
            this.parent(server);

            this._pixmapId = 0;
            Util.loadImageAsPixmap(this._display, this._imageSrc, function(pixmapId) {
                this._pixmapId = pixmapId;
                var geom = this._display.getGeometry({ drawableId: this._pixmapId });
                this._display.configureWindow({ windowId: this.windowId,
                                                width: geom.width,
                                                height: geom.height });
                this._display.invalidateWindow({ windowId: this.windowId });
            }.bind(this));

            this._display.changeAttributes({ windowId: this.windowId,
                                             backgroundColor: PANEL_BACKGROUND_COLOR,
                                             cursor: "pointer" });
            this._display.selectInput({ windowId: this.windowId,
                                        events: ["ButtonPress"] });
        },
        configureNotify: function(event) {
            this.parent(event);
            this._display.invalidateWindow({ windowId: this.windowId });
        },
        _draw: function() {
            if (!this._pixmapId)
                return;

            var image = this._display.getPixmapImage({ pixmapId: this._pixmapId });
            var x = ((this.width - image.width) / 2) | 0;
            var y = ((this.height - image.height) / 2) | 0;
            this._display.drawTo(this.windowId, function(ctx) {
                this._exposeHandler.clip(ctx);
                ctx.drawImage(image, x, y, image.width, image.height);
            }.bind(this));
        },
        handleEvent: function(event) {
            switch (event.type) {
            case "ButtonPress":
                return this._clicked(event);
            default:
                return this.parent(event);
            }
        },
    });

    var Refresh = new Class({
        Extends: Button,
        initialize: function() {
            this.parent("demo/data/refresh.png");
        },
        _clicked: function() {
            this._display.invalidateWindow({ windowId: this._display.rootWindowId,
                                             includeChildren: true });
        },
    });

    var Launcher = new Class({
        Extends: Button,
        initialize: function(imageSrc, constructor) {
            this.parent(imageSrc);
            this._constructor = constructor;
        },
        _clicked: function() {
            var client = new this._constructor();
            client.connect(this._privateServer);
        },
    });

    exports.Panel = Panel;
    exports.MenuButton = MenuButton;
    exports.Launcher = Launcher;
    exports.Refresh = Refresh;

})(window);
<commit_msg>Only relayout if the root window changes width<commit_after>(function(exports) {
    "use strict";

    var PANEL_BACKGROUND_COLOR = "#eeeeec";

    var Panel = new Class({
        Extends: Window,
        connect: function(server) {
            this.parent(server);
            this._leftButtons = [];
            this._rightButtons = [];
            this._display.changeAttributes({ windowId: this.windowId,
                                             backgroundColor: PANEL_BACKGROUND_COLOR });
            this._display.selectInput({ windowId: this._display.rootWindowId,
                                        events: ["ConfigureNotify"] });
            this._display.changeProperty({ windowId: this.windowId,
                                           name: "_NET_WM_WINDOW_TYPE",
                                           value: "_NET_WM_WINDOW_TYPE_DOCK" });
            this._syncSize();
            this._display.mapWindow({ windowId: this.windowId });
        },
        _syncSize: function() {
            var rootWindowGeometry = this._display.getGeometry({ drawableId: this._display.rootWindowId });
            this._display.configureWindow({ windowId: this.windowId,
                                            width: rootWindowGeometry.width,
                                            height: 30 });
        },
        _relayout: function() {
            var padding = 4;
            var x;
            x = padding;

            var buttonHeight = this.height - 1;
            this._leftButtons.forEach(function(button) {
                var geom = this._display.getGeometry({ drawableId: button.windowId });
                this._display.configureWindow({ windowId: button.windowId,
                                                x: x, y: 0, height: buttonHeight });
                x += geom.width + padding;
            }.bind(this));

            x = this.width - padding;
            this._rightButtons.forEach(function(button) {
                var geom = this._display.getGeometry({ drawableId: button.windowId });
                x -= geom.width;
                this._display.configureWindow({ windowId: button.windowId,
                                               x: x, y: 0, height: buttonHeight });
                x -= padding;
            }.bind(this));
        },
        configureNotify: function(event) {
            this.parent(event);

            // Try and resize if the root window changes width
            if (event.windowId === this._display.rootWindowId && event.width !== undefined)
                this._syncSize();

            // If we've changed width, relayout.
            else if (event.windowId === this.windowId && event.width !== undefined)
                this._relayout();

            // And if a button changes width, relayout as well.
            else if (event.windowId !== this.windowId && event.width !== undefined)
                this._relayout();
        },
        _addButton: function(box, button) {
            box.push(button);
            this._display.selectInput({ windowId: button.windowId,
                                        events: ["ConfigureNotify"] });
            this._display.reparentWindow({ windowId: button.windowId,
                                           newParentId: this.windowId });
            this._display.mapWindow({ windowId: button.windowId });
            this._relayout();
        },
        _removeButton: function(box, button) {
            var idx = box.indexOf(button);
            // XXX -- way to unselect for input
            this._display.reparentWindow({ windowId: button.windowId,
                                           newParentId: this._display.rootWindowId });
            box.splice(idx, 1);
        },
        addLauncher: function(launcher) {
            this._addButton(this._leftButtons, launcher);
        },
        removeLauncher: function(launcher) {
            this._removeButton(this._leftButtons, launcher);
        },
        addAction: function(action) {
            this._addButton(this._rightButtons, action);
        },
        removeAction: function(action) {
            this._removeButton(this._rightButtons, action);
        },
        _draw: function() {
            this._display.drawTo(this.windowId, function(ctx) {
                this._exposeHandler.clip(ctx);

                ctx.strokeStyle = '#bec0c0';
                ctx.lineWidth = 1;
                ctx.beginPath();
                ctx.moveTo(0, this.height - 0.5);
                ctx.lineTo(this.width, this.height - 0.5);
                ctx.stroke();
            }.bind(this));
        },
    });

    // Used for operations like measureText which require
    // a 2D context but we don't really draw anything to.
    var tmpCanvas = document.createElement("canvas");
    var tmpCtx = tmpCanvas.getContext("2d");

    var Menu = new Class({
        Extends: Window,
        connect: function(server) {
            this.parent(server);
            this._display.changeAttributes({ windowId: this.windowId,
                                             backgroundColor: "#ffffff",
                                             overrideRedirect: true });
            this._display.selectInput({ windowId: this.windowId,
                                       events: ["ButtonPress", "ButtonRelease"] });
        },
        _syncGeometry: function(openerWindowId) {
            var tree = this._display.queryTree({ windowId: openerWindowId });
            var geometry = this._display.getGeometry({ drawableId: openerWindowId });
            var rootCoords = this._display.translateCoordinates({ srcWindowId: tree.parent,
                                                                 destWindowId: this._display.rootWindowId,
                                                                 x: geometry.x, y: geometry.y });

            var width = 200;
            var height = 200;

            // XXX: hardcoded anchor to the bottom right
            var openerRight = rootCoords.x + geometry.width;
            var openerBottom = rootCoords.y + geometry.height;

            var x = openerRight - width;
            var y = openerBottom;

            this._display.configureWindow({ windowId: this.windowId,
                                           x: x, y: y, width: width, height: height });
        },
        _grab: function() {
            this._display.grabPointer({ windowId: this.windowId,
                                        ownerEvents: true,
                                        events: [],
                                        pointerMode: "Async",
                                        cursor: "" });
        },
        _ungrab: function() {
            this._display.ungrabPointer({ windowId: this.windowId });
        },
        open: function(openerWindowId, closedCallback) {
            this._syncGeometry(openerWindowId);
            this._display.configureWindow({ windowId: this.windowId, stackMode: "Above" });
            this._display.mapWindow({ windowId: this.windowId });
            this._grab();
            this._closedCallback = closedCallback;
        },
        close: function() {
            this._display.unmapWindow({ windowId: this.windowId });
            this._closedCallback();
        },
        _draw: function() {
        },
        handleEvent: function(event) {
            switch (event.type) {
            case "ButtonRelease":
                return this.close();
            default:
                return this.parent(event);
            }
        },
    });

    var MenuButton = new Class({
        Extends: Window,
        initialize: function(label) {
            this.parent();
            this._label = label;
            this._font = '11pt sans-serif';

            this.menu = new Menu();
        },
        connect: function(server) {
            this.parent(server);
            this._syncSize();
            this._display.changeAttributes({ windowId: this.windowId,
                                             backgroundColor: PANEL_BACKGROUND_COLOR });
            this._display.selectInput({ windowId: this.windowId,
                                        events: ["ButtonPress"] });

            this.menu.connect(server);
        },
        _syncSize: function() {
            var padding = 4;
            tmpCtx.save();
            tmpCtx.font = this._font;
            var metrics = tmpCtx.measureText(this._label);
            tmpCtx.restore();
            var width = metrics.width + padding * 2;
            this._display.configureWindow({ windowId: this.windowId,
                                            width: width });
        },
        _draw: function() {
            var padding = 4;
            this._display.drawTo(this.windowId, function(ctx) {
                this._exposeHandler.clip(ctx);

                ctx.font = this._font;
                ctx.fillStyle = '#000000';
                // XXX: Browsers can't measure alphabetic baseline yet,
                // so just hardcode it for now.
                // var metrics = ctx.measureText(this._label);
                // var baseline = metrics.alphabeticBaseline;
                var baseline = 11;
                var y = (this.height - baseline) / 2 + baseline;
                ctx.fillText(this._label, padding, y);
            }.bind(this));
        },
        _onMenuClosed: function() {
            this._display.changeAttributes({ windowId: this.windowId,
                                             backgroundColor: PANEL_BACKGROUND_COLOR });
        },
        _clicked: function() {
            this.menu.open(this.windowId, this._onMenuClosed.bind(this));
            this._display.changeAttributes({ windowId: this.windowId,
                                             backgroundColor: "#ffffff" });
        },
        handleEvent: function(event) {
            switch (event.type) {
            case "ButtonPress":
                return this._clicked(event);
            default:
                return this.parent(event);
            }
        },
    });

    var Button = new Class({
        Extends: Window,
        initialize: function(imageSrc) {
            this.parent();
            this._imageSrc = imageSrc;
        },
        connect: function(server) {
            this.parent(server);

            this._pixmapId = 0;
            Util.loadImageAsPixmap(this._display, this._imageSrc, function(pixmapId) {
                this._pixmapId = pixmapId;
                var geom = this._display.getGeometry({ drawableId: this._pixmapId });
                this._display.configureWindow({ windowId: this.windowId,
                                                width: geom.width,
                                                height: geom.height });
                this._display.invalidateWindow({ windowId: this.windowId });
            }.bind(this));

            this._display.changeAttributes({ windowId: this.windowId,
                                             backgroundColor: PANEL_BACKGROUND_COLOR,
                                             cursor: "pointer" });
            this._display.selectInput({ windowId: this.windowId,
                                        events: ["ButtonPress"] });
        },
        configureNotify: function(event) {
            this.parent(event);
            this._display.invalidateWindow({ windowId: this.windowId });
        },
        _draw: function() {
            if (!this._pixmapId)
                return;

            var image = this._display.getPixmapImage({ pixmapId: this._pixmapId });
            var x = ((this.width - image.width) / 2) | 0;
            var y = ((this.height - image.height) / 2) | 0;
            this._display.drawTo(this.windowId, function(ctx) {
                this._exposeHandler.clip(ctx);
                ctx.drawImage(image, x, y, image.width, image.height);
            }.bind(this));
        },
        handleEvent: function(event) {
            switch (event.type) {
            case "ButtonPress":
                return this._clicked(event);
            default:
                return this.parent(event);
            }
        },
    });

    var Refresh = new Class({
        Extends: Button,
        initialize: function() {
            this.parent("demo/data/refresh.png");
        },
        _clicked: function() {
            this._display.invalidateWindow({ windowId: this._display.rootWindowId,
                                             includeChildren: true });
        },
    });

    var Launcher = new Class({
        Extends: Button,
        initialize: function(imageSrc, constructor) {
            this.parent(imageSrc);
            this._constructor = constructor;
        },
        _clicked: function() {
            var client = new this._constructor();
            client.connect(this._privateServer);
        },
    });

    exports.Panel = Panel;
    exports.MenuButton = MenuButton;
    exports.Launcher = Launcher;
    exports.Refresh = Refresh;

})(window);
<|endoftext|>


<commit_before>
var isAndroid = Framework7.prototype.device.android === true;
var isIos = Framework7.prototype.device.ios === true;

// Set Template7 global devices flags
Template7.global = {
    android: isAndroid,
    ios: isIos
};

// Export selectors engine
var $$ = Dom7;
/*
if (isAndroid) {
    // Change class
    $$('.view .navbar-through').removeClass('navbar-through').addClass('navbar-fixed');
    // And move Navbar into Page
    $$('.view .navbar').prependTo('.view .page');
}*/

// Initialize your app
var myApp = new Framework7({
    //Enable Material theme for Android device only
    material: isAndroid ? true : false,
    //Enable Template7 pages
    template7pages: true,
    precompileTemplates: true,
    animateNavBackIcon: true,
    pushState: true,
    sortable: false, // disable sortable lists, improves performance
    swipeout: false, // not using this
    scrollTopOnNavbarClick : true
});

// Add view
var mainView = myApp.addView('.view-main', {
    // Material doesn't support it but don't worry about it
    // Because we use fixed-through navbar we can enable dynamic navbar
    dynamicNavbar: true
});

/*
// Callbacks to run specific code for specific pages, for example for About page:
myApp.onPageInit('asia', function (page) {
    // run createContentPage func after link was clicked
    $$('.create-page').on('click', function () {
        createContentPage();
    });
});
*/
myApp.onPageInit('fim', function (page) {

    var fimDomainCount = $$('.fimCalculator li').length;
    var fimScores = [];         // creates an array of scores
    resetFIMarr();              // sets all elements to 0

    $$('.fimCalculator li input[type="range"]').each(function(index,value){
        $$(this).on('input change', function(){
            fimScores[index] = parseInt(this.value);
            $$(this).parents().eq(2).find('span.score').text('('+this.value+')');

            // calculate the total FIM score
            $$('#totalScore').html('Total: ' + getSum(fimScores));
        });
    });

    $$('#resetFIMscoresButton').click(function(){
        resetFIMarr();
        $$('#totalScore').html('Total: ' + getSum(fimScores));
        $$('.fimCalculator li input[type="range"]').val(0);
    });

    function resetFIMarr(){
        for(i=0; i<fimDomainCount; i++){ fimScores[i] = 0; }
    }

});

var scimsliders = [];

myApp.onPageInit('scim', function (page) {

    var scim = new SCIM_Scale();    // load the questions from the scales.js model
    var scimHTML = "";

    for(i=0;i<scim.questions.length;i++){
        var q = scim.questions[i];
        var subSectionHTML = "
" + q.title + "
\n\t\t" +
                             "
\n\t\t\t" +
                            "

\n" +
                            "
\n\t";

        for (j=0; j < q.choices.length; j++){
            subSectionHTML += "
("+ q.choices[j].value +
            ") " + q.choices[j].description + "
\n";
        }
        subSectionHTML += "
\n
\n";
        scimHTML = scimHTML + subSectionHTML;
    }

    $$('#scim-page-content').append(scimHTML);

    for(i=0;i<scim.questions.length;i++){
        // Activate the slider functionality
        var targetSwiperDiv = '.swiper-'+i;

        scimsliders[i] = myApp.swiper(targetSwiperDiv, {
            pagination:'.swiper-pagination',
            grabCursor: true,
            spaceBetween: 50,
            onSlideChangeEnd: function(swiper){
                // callback function triggered when slide finishes moving
                var newScore = swiper.slides[swiper.activeIndex].getAttribute("score");
                scim.userScores[swiper.container[0].getAttribute("index")] = parseInt(newScore);
                $$('#scimScore span').html(getSum(scim.userScores) + "/100");
            }
        });
    }

    $$('#emailButton').on('click', function () {
        scim.sendReportByEmail();
    });
});

var myswiper99;
myApp.onPageInit('care', function (page) {

    myswiper99 = myApp.swiper('.swiper-care-test', {
        spaceBetween: 50,
        pagination: '.swiper-pagination',
        grabCursor:true,
        onSlideChangeEnd: function(swiper){
            var newScore = $$('.swiper-care-test .swiper-slide-active').attr("score");
            console.log("new slide score: " + newScore);
        }
    });
});

// Gets sum of array items
function getSum(scores){
    var sum =0;
    for (i=0; i<scores.length;i++){
        sum+= scores[i];
    }
    return sum;
}

/*
// Generate dynamic page
var dynamicPageIndex = 0;
function createContentPage() {
	mainView.router.loadContent(    ''   );
	return;
}*/<commit_msg>reset SCIM sliders and score button with functionality<commit_after>
var isAndroid = Framework7.prototype.device.android === true;
var isIos = Framework7.prototype.device.ios === true;

// Set Template7 global devices flags
Template7.global = {
    android: isAndroid,
    ios: isIos
};

// Export selectors engine
var $$ = Dom7;
/*
if (isAndroid) {
    // Change class
    $$('.view .navbar-through').removeClass('navbar-through').addClass('navbar-fixed');
    // And move Navbar into Page
    $$('.view .navbar').prependTo('.view .page');
}*/

// Initialize your app
var myApp = new Framework7({
    //Enable Material theme for Android device only
    material: isAndroid ? true : false,
    //Enable Template7 pages
    template7pages: true,
    precompileTemplates: true,
    animateNavBackIcon: true,
    pushState: true,
    sortable: false, // disable sortable lists, improves performance
    swipeout: false, // not using this
    scrollTopOnNavbarClick : true
});

// Add view
var mainView = myApp.addView('.view-main', {
    // Material doesn't support it but don't worry about it
    // Because we use fixed-through navbar we can enable dynamic navbar
    dynamicNavbar: true
});

/*
// Callbacks to run specific code for specific pages, for example for About page:
myApp.onPageInit('asia', function (page) {
    // run createContentPage func after link was clicked
    $$('.create-page').on('click', function () {
        createContentPage();
    });
});
*/
myApp.onPageInit('fim', function (page) {

    var fimDomainCount = $$('.fimCalculator li').length;
    var fimScores = [];         // creates an array of scores
    resetFIMarr();              // sets all elements to 0

    $$('.fimCalculator li input[type="range"]').each(function(index,value){
        $$(this).on('input change', function(){
            fimScores[index] = parseInt(this.value);
            $$(this).parents().eq(2).find('span.score').text('('+this.value+')');

            // calculate the total FIM score
            $$('#totalScore').html('Total: ' + getSum(fimScores));
        });
    });

    $$('#resetFIMscoresButton').click(function(){
        resetFIMarr();
        $$('#totalScore').html('Total: ' + getSum(fimScores));
        $$('.fimCalculator li input[type="range"]').val(0);
    });

    function resetFIMarr(){
        for(i=0; i<fimDomainCount; i++){ fimScores[i] = 0; }
    }

});

var scimsliders = [];

myApp.onPageInit('scim', function (page) {

    var scim = new SCIM_Scale();    // load the questions from the scales.js model
    var scimHTML = "";

    for(i=0;i<scim.questions.length;i++){
        var q = scim.questions[i];
        var subSectionHTML = "
" + q.title + "
\n\t\t" +
                             "
\n\t\t\t" +
                            "

\n" +
                            "
\n\t";

        for (j=0; j < q.choices.length; j++){
            subSectionHTML += "
("+ q.choices[j].value +
            ") " + q.choices[j].description + "
\n";
        }
        subSectionHTML += "
\n
\n";
        scimHTML = scimHTML + subSectionHTML;
    }
    scimHTML = scimHTML + "\n\n
Reset Scores
";

    $$('#scim-page-content').append(scimHTML);

    for(i=0;i<scim.questions.length;i++){
        // Activate the slider functionality
        var targetSwiperDiv = '.swiper-'+i;

        scimsliders[i] = myApp.swiper(targetSwiperDiv, {
            pagination:'.swiper-pagination',
            grabCursor: true,
            spaceBetween: 50,
            onSlideChangeEnd: function(swiper){
                // callback function triggered when slide finishes moving
                var newScore = swiper.slides[swiper.activeIndex].getAttribute("score");
                scim.userScores[swiper.container[0].getAttribute("index")] = parseInt(newScore);
                $$('#scimScore span').html(getSum(scim.userScores) + "/100");
            }
        });
    }

    $$('#emailButton').on('click', function () {
        scim.sendReportByEmail();
    });

    $$('#resetSCIMscoresButton').click(function(){
        for(i=0; i< scim.userScores.length; i++){
            scim.userScores[i] = 0;                       // reset all user scores to 0
            scimsliders[i].slideTo(0, 500, false);   // move all sliders back to 0 & skip callbacks
        }
        $$('#scimScore span').html('0/100');
    });
});

var myswiper99;
myApp.onPageInit('care', function (page) {

    myswiper99 = myApp.swiper('.swiper-care-test', {
        spaceBetween: 50,
        pagination: '.swiper-pagination',
        grabCursor:true,
        onSlideChangeEnd: function(swiper){
            var newScore = $$('.swiper-care-test .swiper-slide-active').attr("score");
            console.log("new slide score: " + newScore);
        }
    });
});

// Gets sum of array items
function getSum(scores){
    var sum =0;
    for (i=0; i<scores.length;i++){
        sum+= scores[i];
    }
    return sum;
}

/*
// Generate dynamic page
var dynamicPageIndex = 0;
function createContentPage() {
	mainView.router.loadContent(    ''   );
	return;
}*/<|endoftext|>