<commit_before>// Copyright (C) 2016 Goom Inc. All rights reserved.

import React, { PropTypes } from 'react';
import _ from 'lodash';

import ProductDetailModelView from './ProductDetailModelView';

import i18n from 'commons/utils/i18n';
import { constants } from 'commons/utils/constants';
import { productDetailAttributes } from 'commons/data';

export default React.createClass({
  propTypes: {
    images: PropTypes.array,
    product: PropTypes.object,
    sizes: PropTypes.array,
  },
  render() {
    const { product, sizes, images } = this.props;
    const renderSizesTable = () => {
      if (!sizes.length) {
        return null;
      }
      const kind = _.get(product, 'data.detail.kind');
      if (!productDetailAttributes[kind]) {
        return null;
      }
      const baseIndex = Math.floor(sizes.length / 2);
      const renderSize = (size, index) => {
        const res = [<td key={`${size}-${index}`}>{size}	];
        for (let i = 0; i < productDetailAttributes[kind].length; i++) {
          res.push(
            <td key={`${size}-size-${i}`}>{(+_.get(product, `data.detail.size${i + 1}`) + (index - baseIndex) * 2) || 0}cm
          );
        }
        return
{res}
;
      };
      return (

            {i18n.get('pcItemDetail.detailSize')}
            {productDetailAttributes[kind].map((attr) => {i18n.get(attr)}	)}

          {sizes.map(renderSize)}

      );
    };
    const renderDetailInfo = () => {
      const enumFiels = [
        { title: '촉감', enums: ['까슬함', '적당함', '부드러움'], key: 'data.detail.touch' },
        { title: '신축성', enums: ['좋음', '약간', '없음'], key: 'data.detail.flexibility' },
        { title: '비침', enums: ['많이비침', '약간비침', '비침없음'], key: 'data.detail.transparency' },
        { title: '광택감', enums: ['광택있음', '약간있음', '광택없음'], key: 'data.detail.gloss' },
        { title: '두께감', enums: ['두꺼움', '적당함', '얇음'], key: 'data.detail.thickness' },
        { title: '안감', enums: ['전체안감', '부분안감', '안감없음'], key: 'data.detail.lining' },
        // { title: '모델착용사이즈', key: 'data.detail.modelSize' },
        // { title: '원산지', key: 'data.detail.origin' },
      ];
      const convert = (key) => {
        const k = key.split('.').slice(-1)[0];
        return `${k[0].toUpperCase()}${k.substring(1)}`;
      };
      const activeIndexes = new Array(enumFiels.length).fill(-1);
      enumFiels.forEach((field, index) => {
        field.i18nPrefix = `pcItemDetail.info${convert(field.key)}`;
        const productValue = _.get(product, field.key);
        for (let i = 0; i < field.enums.length; i++) {
          if (productValue === field.enums[i]) {
            activeIndexes[index] = i;
            break;
          }
        }
      });

      const renderEnumField = (field, fieldIndex) => (

            {i18n.get(`${field.i18nPrefix}`)}

          {field.enums.map((e, enumIndex) =>
            <div
              key={e} className={`enum-value ${enumIndex === activeIndexes[fieldIndex] ? 'active' : ''}`}
            >
              {i18n.get(`${field.i18nPrefix}${enumIndex}`)}

          )}

      );
      return (

          {enumFiels.map(renderEnumField)}

{i18n.get('pcItemDetail.infoModelSize')}

{_.get(product, 'data.detail.modelSize') || ''}

{i18n.get('pcItemDetail.infoOrigin')}

{_.get(product, 'data.detail.origin') || ''}

      );
    };
    const renderImages = () => {
      const res = [];
      let row = 0;
      let imageIndex = 0;
      while (imageIndex < images.length) {
        if (row === 1 || imageIndex === images.length - 1) {
          res.push(
            <div key={`detail-image-row-${row}`} className="image-row">

          );
        } else {
          res.push(
            <div key={`detail-image-row-${row}`} className="image-row">

          );
        }
        row++;
      }
      return res;
    };
    const renderModel = () => {
      const models = [
        {
          imgUrl: `${constants.resourceRoot}/banner/models/model_eun.png`,
          name: '이은지',
          height: '168 cm',
          weight: '48 kg',
          shoulderWidth: '40 cm',
          topsLength: '47 cm',
          bottomslength: '96 cm',
          waist: '26.7 inch',
          armLength: '65 cm',
          topBustSize: '80 cm',
          bottomBustSize: '68.5 cm',
          hipSize: '89 cm',
          ShoesSize: '235 cm',
        },
        {
          imgUrl: `${constants.resourceRoot}/banner/models/model_sori.png`,
          name: '임소리',
          height: '167 cm',
          weight: '47 kg',
          shoulderWidth: '40 cm',
          topsLength: '48 cm',
          bottomslength: '97 cm',
          waist: '23 inch',
          armLength: '63 cm',
          topBustSize: '79 cm',
          bottomBustSize: '69 cm',
          hipSize: '88 cm',
          ShoesSize: '235 cm',
        },
        {
          imgUrl: `${constants.resourceRoot}/banner/models/model_ys.png`,
          name: '유영석',
          height: '182 cm',
          weight: '64 kg',
          shoulderWidth: '53 cm',
          topsLength: '57 cm',
          bottomslength: '105 cm',
          waist: '29 inch',
          armLength: '63 cm',
          topBustSize: '94 cm',
          bottomBustSize: '94 cm',
          hipSize: '96 cm',
          ShoesSize: '260 cm',
        },
      ];
      for (let i = 0; i < models.length; i++) {
        const model = models[i];
        if (_.get(product, 'data.detail.modelName') === model.name) {
          return <ProductDetailModelView model={model} />;
        }
      }
      return null;
    };

    return (

{i18n.get('pcItemDetail.bottomTitle')}

        {renderSizesTable()}
        {renderDetailInfo()}
        {renderImages()}
        {renderModel()}

{i18n.get('pcItemDetail.descRefundTitle')}

            - {i18n.get('pcItemDetail.descRefund1')}

            - {i18n.get('pcItemDetail.descRefund2')}

            - {i18n.get('pcItemDetail.descRefund3')}

            - {i18n.get('pcItemDetail.descRefund4')}

            - {i18n.get('pcItemDetail.descRefund5')}

            - {i18n.get('pcItemDetail.descRefund6')}

{i18n.get('pcItemDetail.descDelayTitle')}

            - {i18n.get('pcItemDetail.descDelay1')}

            - {i18n.get('pcItemDetail.descDelay2')}

            - {i18n.get('pcItemDetail.descDelay3')}

    );
  },
});
<commit_msg>product detail image - do not use 1-item row when product image is even<commit_after>// Copyright (C) 2016 Goom Inc. All rights reserved.

import React, { PropTypes } from 'react';
import _ from 'lodash';

import ProductDetailModelView from './ProductDetailModelView';

import i18n from 'commons/utils/i18n';
import { constants } from 'commons/utils/constants';
import { productDetailAttributes } from 'commons/data';

export default React.createClass({
  propTypes: {
    images: PropTypes.array,
    product: PropTypes.object,
    sizes: PropTypes.array,
  },
  render() {
    const { product, sizes, images } = this.props;
    const renderSizesTable = () => {
      if (!sizes.length) {
        return null;
      }
      const kind = _.get(product, 'data.detail.kind');
      if (!productDetailAttributes[kind]) {
        return null;
      }
      const baseIndex = Math.floor(sizes.length / 2);
      const renderSize = (size, index) => {
        const res = [<td key={`${size}-${index}`}>{size}	];
        for (let i = 0; i < productDetailAttributes[kind].length; i++) {
          res.push(
            <td key={`${size}-size-${i}`}>{(+_.get(product, `data.detail.size${i + 1}`) + (index - baseIndex) * 2) || 0}cm
          );
        }
        return
{res}
;
      };
      return (

            {i18n.get('pcItemDetail.detailSize')}
            {productDetailAttributes[kind].map((attr) => {i18n.get(attr)}	)}

          {sizes.map(renderSize)}

      );
    };
    const renderDetailInfo = () => {
      const enumFiels = [
        { title: '촉감', enums: ['까슬함', '적당함', '부드러움'], key: 'data.detail.touch' },
        { title: '신축성', enums: ['좋음', '약간', '없음'], key: 'data.detail.flexibility' },
        { title: '비침', enums: ['많이비침', '약간비침', '비침없음'], key: 'data.detail.transparency' },
        { title: '광택감', enums: ['광택있음', '약간있음', '광택없음'], key: 'data.detail.gloss' },
        { title: '두께감', enums: ['두꺼움', '적당함', '얇음'], key: 'data.detail.thickness' },
        { title: '안감', enums: ['전체안감', '부분안감', '안감없음'], key: 'data.detail.lining' },
        // { title: '모델착용사이즈', key: 'data.detail.modelSize' },
        // { title: '원산지', key: 'data.detail.origin' },
      ];
      const convert = (key) => {
        const k = key.split('.').slice(-1)[0];
        return `${k[0].toUpperCase()}${k.substring(1)}`;
      };
      const activeIndexes = new Array(enumFiels.length).fill(-1);
      enumFiels.forEach((field, index) => {
        field.i18nPrefix = `pcItemDetail.info${convert(field.key)}`;
        const productValue = _.get(product, field.key);
        for (let i = 0; i < field.enums.length; i++) {
          if (productValue === field.enums[i]) {
            activeIndexes[index] = i;
            break;
          }
        }
      });

      const renderEnumField = (field, fieldIndex) => (

            {i18n.get(`${field.i18nPrefix}`)}

          {field.enums.map((e, enumIndex) =>
            <div
              key={e} className={`enum-value ${enumIndex === activeIndexes[fieldIndex] ? 'active' : ''}`}
            >
              {i18n.get(`${field.i18nPrefix}${enumIndex}`)}

          )}

      );
      return (

          {enumFiels.map(renderEnumField)}

{i18n.get('pcItemDetail.infoModelSize')}

{_.get(product, 'data.detail.modelSize') || ''}

{i18n.get('pcItemDetail.infoOrigin')}

{_.get(product, 'data.detail.origin') || ''}

      );
    };
    const renderImages = () => {
      const res = [];
      let row = 0;
      let imageIndex = 0;
      const productImageCount = _.get(product, 'appImages.default').length;
      const isOddCount = productImageCount && productImageCount % 2 === 1;
      while (imageIndex < images.length) {
        if ((isOddCount && row === 1) || imageIndex === images.length - 1) {
          res.push(
            <div key={`detail-image-row-${row}`} className="image-row">

          );
        } else {
          res.push(
            <div key={`detail-image-row-${row}`} className="image-row">

          );
        }
        row++;
      }
      return res;
    };
    const renderModel = () => {
      const models = [
        {
          imgUrl: `${constants.resourceRoot}/banner/models/model_eun.png`,
          name: '이은지',
          height: '168 cm',
          weight: '48 kg',
          shoulderWidth: '40 cm',
          topsLength: '47 cm',
          bottomslength: '96 cm',
          waist: '26.7 inch',
          armLength: '65 cm',
          topBustSize: '80 cm',
          bottomBustSize: '68.5 cm',
          hipSize: '89 cm',
          ShoesSize: '235 cm',
        },
        {
          imgUrl: `${constants.resourceRoot}/banner/models/model_sori.png`,
          name: '임소리',
          height: '167 cm',
          weight: '47 kg',
          shoulderWidth: '40 cm',
          topsLength: '48 cm',
          bottomslength: '97 cm',
          waist: '23 inch',
          armLength: '63 cm',
          topBustSize: '79 cm',
          bottomBustSize: '69 cm',
          hipSize: '88 cm',
          ShoesSize: '235 cm',
        },
        {
          imgUrl: `${constants.resourceRoot}/banner/models/model_ys.png`,
          name: '유영석',
          height: '182 cm',
          weight: '64 kg',
          shoulderWidth: '53 cm',
          topsLength: '57 cm',
          bottomslength: '105 cm',
          waist: '29 inch',
          armLength: '63 cm',
          topBustSize: '94 cm',
          bottomBustSize: '94 cm',
          hipSize: '96 cm',
          ShoesSize: '260 cm',
        },
      ];
      for (let i = 0; i < models.length; i++) {
        const model = models[i];
        if (_.get(product, 'data.detail.modelName') === model.name) {
          return <ProductDetailModelView model={model} />;
        }
      }
      return null;
    };

    return (

{i18n.get('pcItemDetail.bottomTitle')}

        {renderSizesTable()}
        {renderDetailInfo()}
        {renderImages()}
        {renderModel()}

{i18n.get('pcItemDetail.descRefundTitle')}

            - {i18n.get('pcItemDetail.descRefund1')}

            - {i18n.get('pcItemDetail.descRefund2')}

            - {i18n.get('pcItemDetail.descRefund3')}

            - {i18n.get('pcItemDetail.descRefund4')}

            - {i18n.get('pcItemDetail.descRefund5')}

            - {i18n.get('pcItemDetail.descRefund6')}

{i18n.get('pcItemDetail.descDelayTitle')}

            - {i18n.get('pcItemDetail.descDelay1')}

            - {i18n.get('pcItemDetail.descDelay2')}

            - {i18n.get('pcItemDetail.descDelay3')}

    );
  },
});
<|endoftext|>


<commit_before>function hijackConnection(original, type) {
  return function () {
    var self = this;
    var args = Array.prototype.slice.call(arguments);

    // if this comes from a Method.call we don't need to track it
    var isFromCall = Zone.fromCall.get();

    if(!isFromCall && args.length) {
      var callback = args[args.length - 1];
      if(typeof callback === 'function') {
        var methodName = args[0];
        var methodArgs = args.slice(1, args.length - 1);
        var ownerInfo = {type: type, name: methodName, args: methodArgs};
        var zoneInfo = {type: type, name: methodName, args: methodArgs};
        zone.setInfo(type, zoneInfo);
        args[args.length - 1] = function (argument) {
          var args = Array.prototype.slice.call(arguments);
          return callback.apply(this, args);
        }
        args[args.length - 1] = zone.bind(args[args.length - 1], false, ownerInfo, pickAllArgs);
      }
    }

    if(type == "Meteor.call") {
      // make sure this won't get tracked another time
      return Zone.fromCall.withValue(true, function() {
        return original.apply(self, args);
      });
    } else {
      return original.apply(this, args);
    }
  }
}

function hijackSubscribe(originalFunction, type) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    if(args.length) {
      var callback = args[args.length - 1];
      var subName = args[0];
      var subArgs = args.slice(1, args.length - 1);
      if(typeof callback === 'function') {
        var ownerInfo = {type: type, name: subName, args: subArgs};
        var zoneInfo = {type: type, name: subName, args: subArgs};
        zone.setInfo(type, zoneInfo);
        args[args.length - 1] = function (argument) {
          var args = Array.prototype.slice.call(arguments);
          return callback.apply(this, args);
        }
        args[args.length - 1] = zone.bind(args[args.length - 1], false, ownerInfo, pickAllArgs);
      } else if(callback) {
        ['onReady', 'onError'].forEach(function (funName) {
          var ownerInfo = {type: type, name: subName, args: subArgs, callbackType: funName};
          if(typeof callback[funName] === "function") {
            var zoneInfo = {type: type, name: subName, args: subArgs, callbackType: funName};
            zone.setInfo(type, zoneInfo);
            callback[funName] = function (argument) {
              var args = Array.prototype.slice.call(arguments);
              return callback.apply(this, args);
            }
            callback[funName] = zone.bind(callback[funName], false, ownerInfo, pickAllArgs);
          }
        })
      }
    }
    return originalFunction.apply(this, args);
  }
}

function hijackCursor(Cursor) {

  hijackFunction('observe', [
    'added', 'addedAt', 'changed', 'changedAt',
    'removed', 'removedAt', 'movedTo'
  ]);

  hijackFunction('observeChanges', [
    'added', 'addedBefore', 'changed',
    'removed', 'movedBefore'
  ]);

  // hijack Cursor.fetch
  var originalCursorFetch = Cursor.fetch;
  Cursor.fetch = function () {
    var self = this;
    var args = Array.prototype.slice.call(arguments);
    var type = 'MongoCursor.fetch';
    if(zone && !this._avoidZones) {
      var collection = this.collection && this.collection.name;
      var query = this.matcher && this.matcher._selector;
      var zoneInfo = {type: type, collection: collection, query: query};
      zone.setInfo(type, zoneInfo)
    };
    return Zone.notFromForEach.withValue(true, function() {
      return originalCursorFetch.apply(self, args);
    });
  };

  ['forEach', 'map'].forEach(function (name) {
    var original = Cursor[name];
    Cursor[name] = function (callback, thisArg) {
      var self = thisArg || this;
      var args = Array.prototype.slice.call(arguments);
      var type = 'MongoCursor.' + name;
      var notFromForEach = Zone.notFromForEach.get();
      if(!this._avoidZones
        && !notFromForEach
        && typeof callback === 'function') {
        args[0] = function (doc, index) {
          var args = Array.prototype.slice.call(arguments);
          var collection = self.collection && self.collection.name;
          var query = self.matcher && self.matcher._selector;
          var ownerInfo = {type: type, collection: collection, query: query};
          var zoneInfo = {type: type, collection: collection, query: query, document: doc, index: index};
          zone.setInfo(type, zoneInfo);
          callback = zone.bind(callback, false, ownerInfo, pickAllArgs);
          return callback.apply(this, args);
        };
      }

      if(name !== 'forEach') {
        return Zone.notFromForEach.withValue(true, function() {
          return original.apply(self, args);
        });
      } else {
        return original.apply(self, args);
      }
    }
  });

  function hijackFunction(type, callbacks) {
    var original = Cursor[type];
    Cursor[type] = function (options) {
      var self = this;
      // check this request comes from an observer call
      // if so, we don't need to track this request
      var isFromObserve = Zone.fromObserve.get();

      if(!this._avoidZones && !isFromObserve && options) {
        callbacks.forEach(function (funName) {
          var callback = options[funName];
          if(typeof callback === 'function') {
            var ownerInfo = {
              type: 'MongoCursor.' + type,
              callbackType: funName,
              collection: self.collection.name
            };
            zone.setInfo(type, {
              type: 'MongoCursor.' + type,
              collection: self.collection.name
            });
            options[funName] = zone.bind(callback, false, ownerInfo, pickAllArgs);
          }
        });
      }

      if(type == 'observe') {
        // notify observeChanges to not to track again
        return Zone.fromObserve.withValue(true, function() {
          return original.call(self, options);
        });
      } else {
        return original.call(this, options);
      }
    };
  }
}

function hijackComponentEvents(original) {
  var type = 'Template.event';
  return function (dict) {
    var self = this;
    var name = this.__templateName || this.kind.split('_')[1];
    for (var target in dict) {
      var handler = dict[target];
      if (typeof handler === 'function') {
        dict[target] = prepareHandler(handler, target);
      }
    }

    return original.call(this, dict);

    function prepareHandler(handler, target) {
      return function () {
        var args = Array.prototype.slice.call(arguments);
        var ownerInfo = {type: type, event: target, template: name};
        zone.owner = ownerInfo;
        handler.apply(this, args);
      };
    }

  }
}

function hijackDepsFlush(original, type) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    if(zone.owner && window.zone.owner.type == 'setTimeout') {
      zone.owner = {type: type};
    }
    return original.apply(this, args);
  }
}

function hijackSessionSet(original, type) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    zone.addEvent({type: type, key: args[0], value: args[1]});
    return original.apply(this, args);
  }
}

var TemplateCoreFunctions = ['prototype', '__makeView', '__render'];

function hijackTemplateHelpers(template, templateName) {
  _.each(template, function (hookFn, name) {
    template[name] = hijackHelper(hookFn, name, templateName);
  });
}

function hijackNewTemplateHelpers(original, templateName) {
  return function (dict) {
    dict && _.each(dict, function (hookFn, name) {
      dict[name] = hijackHelper(hookFn, name, templateName);
    });

    var args = Array.prototype.slice.call(arguments);
    return original.apply(this, args);
  }
}

function hijackHelper(hookFn, name, templateName) {
  if(hookFn
    && typeof hookFn === 'function'
    && _.indexOf(TemplateCoreFunctions, name) === -1) {
    // Assuming the value is a template helper
    return function () {
      var args = Array.prototype.slice.call(arguments);
      zone.setInfo('Template.helper', {name: name, template: templateName});
      var result = hookFn.apply(this, args);
      if(result && typeof result.observe === 'function') {
        result._avoidZones = true;
      }
      return result;
    }
  } else {
    return hookFn;
  }
}

function hijackGlobalHelpers(helpers) {
  var _ = Package.underscore._;
  _(helpers || {}).each(function (helperFn, name) {
    helpers[name] = hijackGlobalHelper(helperFn, name)
  });
}

function hijackNewGlobalHelpers (original) {
  return function (name, helperFn) {
    var args = Array.prototype.slice.call(arguments);
    args[1] = hijackGlobalHelper(helperFn, name);
    return original.apply(this, args);
  };
}

function hijackGlobalHelper(helperFn, name) {
  var _ = Package.underscore._;
  if(helperFn
    && typeof helperFn === 'function'
    && _.indexOf(TemplateCoreFunctions, name) === -1) {
    return function () {
      var args = Array.prototype.slice.call(arguments);
      var result = helperFn.apply(this, args);
      if(result && typeof result.observe === 'function') {
        result._avoidZones = true;
        zone.setInfo('Global.helper', {name: name, args: args});
      } else {
        var zoneInfo = {name: name, args: args, result: result};
        zone.setInfo('Global.helper', zoneInfo);
      }
      return result;
    }
  } else {
    return helperFn;
  }
}

//--------------------------------------------------------------------------\\

var routerEvents = [
  'onRun', 'onData', 'onBeforeAction', 'onAfterAction', 'onStop', 'waitOn',
  'load', 'before', 'after', 'unload',
  'data', 'waitOn'
];

function hijackRouterConfigure(original, type) {
  return function (options) {
    var args = Array.prototype.slice.call(arguments);
    options && routerEvents.forEach(function (hookName) {
      var hookFn = options[hookName];
      if(typeof hookFn === 'function') {
        options[hookName] = function () {
          var args = Array.prototype.slice.call(arguments);
          zone.setInfo(type, {
            name: this.route && this.route.name,
            hook: hookName,
            path: this.path
          });
          return hookFn.apply(this, args);
        }
      }
    });
    return original.apply(this, args);
  }
}

function hijackRouterGlobalHooks(Router, type) {
  routerEvents.forEach(function (hookName) {
    var hookFn = Router[hookName];
    /**
     * Example
     * Router.onBeforeAction( handler-function, options )
     */
    Router[hookName] = function (hook, options) {
      var args = Array.prototype.slice.call(arguments);
      var hook = args[0];
      if(hook && typeof hook === 'function') {
        // override hook function before sending to iron-router
        args[0] = function () {
          var args = Array.prototype.slice.call(arguments);
          zone.setInfo(type, {
            name: this.route && this.route.name,
            hook: hookName,
            path: this.path
          });
          return hook.apply(this, args);
        }
      }
      return hookFn.apply(this, args);
    }
  });

  return Router;
}

function hijackRouterOptions(original, type) {
  return function (name, options) {
    var args = Array.prototype.slice.call(arguments);

    // hijack options
    options && routerEvents.forEach(function (hookName) {
      var hookFn = options[hookName];
      if(typeof hookFn === 'function') {
        options[hookName] = function () {
          var args = Array.prototype.slice.call(arguments);
          zone.setInfo(type, {
            name: this.route && this.route.name,
            hook: hookName,
            path: this.path
          });
          return hookFn.apply(this, args);
        }
      }
    });

    return original.apply(this, args);
  }
}

function hijackRouteController(original, type) {
  return function (options) {
    var args = Array.prototype.slice.call(arguments);
    options && routerEvents.forEach(function (hookName) {
      var hookFn = options[hookName];
      if(typeof hookFn === 'function') {
        options[hookName] = function () {
          var args = Array.prototype.slice.call(arguments);
          zone.setInfo(type, {
            name: this.route && this.route.name,
            hook: hookName,
            path: this.path
          });
          return hookFn.apply(this, args);
        }
      }
    });
    return original.apply(this, args);
  }
}

//--------------------------------------------------------------------------\\

var originalFunctions = [];
function backupOriginals(obj, methodNames) {
  if(obj && Array.isArray(methodNames)) {
    var backup = {obj: obj};
    backup.methods = {};
    methodNames.forEach(function (name) {
      backup.methods[name] = obj[name];
    });
    originalFunctions.push(backup);
  };
}

function restoreOriginals() {
  originalFunctions.forEach(function (backup) {
    for(var name in backup.methods) {
      backup.obj[name] = backup.methods[name];
    };
  });
}

function pickAllArgs(context, args) {
  return args;
}
<commit_msg>Fix observe/observeChanges bug<commit_after>function hijackConnection(original, type) {
  return function () {
    var self = this;
    var args = Array.prototype.slice.call(arguments);

    // if this comes from a Method.call we don't need to track it
    var isFromCall = Zone.fromCall.get();

    if(!isFromCall && args.length) {
      var callback = args[args.length - 1];
      if(typeof callback === 'function') {
        var methodName = args[0];
        var methodArgs = args.slice(1, args.length - 1);
        var ownerInfo = {type: type, name: methodName, args: methodArgs};
        var zoneInfo = {type: type, name: methodName, args: methodArgs};
        zone.setInfo(type, zoneInfo);
        args[args.length - 1] = function (argument) {
          var args = Array.prototype.slice.call(arguments);
          return callback.apply(this, args);
        }
        args[args.length - 1] = zone.bind(args[args.length - 1], false, ownerInfo, pickAllArgs);
      }
    }

    if(type == "Meteor.call") {
      // make sure this won't get tracked another time
      return Zone.fromCall.withValue(true, function() {
        return original.apply(self, args);
      });
    } else {
      return original.apply(this, args);
    }
  }
}

function hijackSubscribe(originalFunction, type) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    if(args.length) {
      var callback = args[args.length - 1];
      var subName = args[0];
      var subArgs = args.slice(1, args.length - 1);
      if(typeof callback === 'function') {
        var ownerInfo = {type: type, name: subName, args: subArgs};
        var zoneInfo = {type: type, name: subName, args: subArgs};
        zone.setInfo(type, zoneInfo);
        args[args.length - 1] = function (argument) {
          var args = Array.prototype.slice.call(arguments);
          return callback.apply(this, args);
        }
        args[args.length - 1] = zone.bind(args[args.length - 1], false, ownerInfo, pickAllArgs);
      } else if(callback) {
        ['onReady', 'onError'].forEach(function (funName) {
          var ownerInfo = {type: type, name: subName, args: subArgs, callbackType: funName};
          if(typeof callback[funName] === "function") {
            var zoneInfo = {type: type, name: subName, args: subArgs, callbackType: funName};
            zone.setInfo(type, zoneInfo);
            callback[funName] = function (argument) {
              var args = Array.prototype.slice.call(arguments);
              return callback.apply(this, args);
            }
            callback[funName] = zone.bind(callback[funName], false, ownerInfo, pickAllArgs);
          }
        })
      }
    }
    return originalFunction.apply(this, args);
  }
}

function hijackCursor(Cursor) {

  hijackFunction('observe', [
    'added', 'addedAt', 'changed', 'changedAt',
    'removed', 'removedAt', 'movedTo'
  ]);

  hijackFunction('observeChanges', [
    'added', 'addedBefore', 'changed',
    'removed', 'movedBefore'
  ]);

  // hijack Cursor.fetch
  var originalCursorFetch = Cursor.fetch;
  Cursor.fetch = function () {
    var self = this;
    var args = Array.prototype.slice.call(arguments);
    var type = 'MongoCursor.fetch';
    if(zone && !this._avoidZones) {
      var collection = this.collection && this.collection.name;
      var query = this.matcher && this.matcher._selector;
      var zoneInfo = {type: type, collection: collection, query: query};
      zone.setInfo(type, zoneInfo)
    };
    return Zone.notFromForEach.withValue(true, function() {
      return originalCursorFetch.apply(self, args);
    });
  };

  ['forEach', 'map'].forEach(function (name) {
    var original = Cursor[name];
    Cursor[name] = function (callback, thisArg) {
      var self = thisArg || this;
      var args = Array.prototype.slice.call(arguments);
      var type = 'MongoCursor.' + name;
      var notFromForEach = Zone.notFromForEach.get();
      if(!this._avoidZones
        && !notFromForEach
        && typeof callback === 'function') {
        args[0] = function (doc, index) {
          var args = Array.prototype.slice.call(arguments);
          var collection = self.collection && self.collection.name;
          var query = self.matcher && self.matcher._selector;
          var ownerInfo = {type: type, collection: collection, query: query};
          var zoneInfo = {type: type, collection: collection, query: query, document: doc, index: index};
          zone.setInfo(type, zoneInfo);
          callback = zone.bind(callback, false, ownerInfo, pickAllArgs);
          return callback.apply(this, args);
        };
      }

      if(name !== 'forEach') {
        return Zone.notFromForEach.withValue(true, function() {
          return original.apply(self, args);
        });
      } else {
        return original.apply(self, args);
      }
    }
  });

  function hijackFunction(type, callbacks) {
    var original = Cursor[type];
    Cursor[type] = function (options) {
      var self = this;
      var eventType = 'MongoCursor.' + type;
      // check this request comes from an observer call
      // if so, we don't need to track this request
      var isFromObserve = Zone.fromObserve.get();

      if(!this._avoidZones && !isFromObserve && options) {
        callbacks.forEach(function (funName) {
          var callback = options[funName];
          if(typeof callback === 'function') {
            var ownerInfo = {
              type: eventType,
              callbackType: funName,
              collection: self.collection.name
            };
            zone.setInfo(eventType, {
              type: eventType,
              callbackType: funName,
              collection: self.collection.name
            });
            options[funName] = zone.bind(callback, false, ownerInfo, pickAllArgs);
          }
        });
      }

      if(type == 'observe') {
        // notify observeChanges to not to track again
        return Zone.fromObserve.withValue(true, function() {
          return original.call(self, options);
        });
      } else {
        return original.call(this, options);
      }
    };
  }
}

function hijackComponentEvents(original) {
  var type = 'Template.event';
  return function (dict) {
    var self = this;
    var name = this.__templateName || this.kind.split('_')[1];
    for (var target in dict) {
      var handler = dict[target];
      if (typeof handler === 'function') {
        dict[target] = prepareHandler(handler, target);
      }
    }

    return original.call(this, dict);

    function prepareHandler(handler, target) {
      return function () {
        var args = Array.prototype.slice.call(arguments);
        var ownerInfo = {type: type, event: target, template: name};
        zone.owner = ownerInfo;
        handler.apply(this, args);
      };
    }

  }
}

function hijackDepsFlush(original, type) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    if(zone.owner && window.zone.owner.type == 'setTimeout') {
      zone.owner = {type: type};
    }
    return original.apply(this, args);
  }
}

function hijackSessionSet(original, type) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    zone.addEvent({type: type, key: args[0], value: args[1]});
    return original.apply(this, args);
  }
}

var TemplateCoreFunctions = ['prototype', '__makeView', '__render'];

function hijackTemplateHelpers(template, templateName) {
  _.each(template, function (hookFn, name) {
    template[name] = hijackHelper(hookFn, name, templateName);
  });
}

function hijackNewTemplateHelpers(original, templateName) {
  return function (dict) {
    dict && _.each(dict, function (hookFn, name) {
      dict[name] = hijackHelper(hookFn, name, templateName);
    });

    var args = Array.prototype.slice.call(arguments);
    return original.apply(this, args);
  }
}

function hijackHelper(hookFn, name, templateName) {
  if(hookFn
    && typeof hookFn === 'function'
    && _.indexOf(TemplateCoreFunctions, name) === -1) {
    // Assuming the value is a template helper
    return function () {
      var args = Array.prototype.slice.call(arguments);
      zone.setInfo('Template.helper', {name: name, template: templateName});
      var result = hookFn.apply(this, args);
      if(result && typeof result.observe === 'function') {
        result._avoidZones = true;
      }
      return result;
    }
  } else {
    return hookFn;
  }
}

function hijackGlobalHelpers(helpers) {
  var _ = Package.underscore._;
  _(helpers || {}).each(function (helperFn, name) {
    helpers[name] = hijackGlobalHelper(helperFn, name)
  });
}

function hijackNewGlobalHelpers (original) {
  return function (name, helperFn) {
    var args = Array.prototype.slice.call(arguments);
    args[1] = hijackGlobalHelper(helperFn, name);
    return original.apply(this, args);
  };
}

function hijackGlobalHelper(helperFn, name) {
  var _ = Package.underscore._;
  if(helperFn
    && typeof helperFn === 'function'
    && _.indexOf(TemplateCoreFunctions, name) === -1) {
    return function () {
      var args = Array.prototype.slice.call(arguments);
      var result = helperFn.apply(this, args);
      if(result && typeof result.observe === 'function') {
        result._avoidZones = true;
        zone.setInfo('Global.helper', {name: name, args: args});
      } else {
        var zoneInfo = {name: name, args: args, result: result};
        zone.setInfo('Global.helper', zoneInfo);
      }
      return result;
    }
  } else {
    return helperFn;
  }
}

//--------------------------------------------------------------------------\\

var routerEvents = [
  'onRun', 'onData', 'onBeforeAction', 'onAfterAction', 'onStop', 'waitOn',
  'load', 'before', 'after', 'unload',
  'data', 'waitOn'
];

function hijackRouterConfigure(original, type) {
  return function (options) {
    var args = Array.prototype.slice.call(arguments);
    options && routerEvents.forEach(function (hookName) {
      var hookFn = options[hookName];
      if(typeof hookFn === 'function') {
        options[hookName] = function () {
          var args = Array.prototype.slice.call(arguments);
          zone.setInfo(type, {
            name: this.route && this.route.name,
            hook: hookName,
            path: this.path
          });
          return hookFn.apply(this, args);
        }
      }
    });
    return original.apply(this, args);
  }
}

function hijackRouterGlobalHooks(Router, type) {
  routerEvents.forEach(function (hookName) {
    var hookFn = Router[hookName];
    /**
     * Example
     * Router.onBeforeAction( handler-function, options )
     */
    Router[hookName] = function (hook, options) {
      var args = Array.prototype.slice.call(arguments);
      var hook = args[0];
      if(hook && typeof hook === 'function') {
        // override hook function before sending to iron-router
        args[0] = function () {
          var args = Array.prototype.slice.call(arguments);
          zone.setInfo(type, {
            name: this.route && this.route.name,
            hook: hookName,
            path: this.path
          });
          return hook.apply(this, args);
        }
      }
      return hookFn.apply(this, args);
    }
  });

  return Router;
}

function hijackRouterOptions(original, type) {
  return function (name, options) {
    var args = Array.prototype.slice.call(arguments);

    // hijack options
    options && routerEvents.forEach(function (hookName) {
      var hookFn = options[hookName];
      if(typeof hookFn === 'function') {
        options[hookName] = function () {
          var args = Array.prototype.slice.call(arguments);
          zone.setInfo(type, {
            name: this.route && this.route.name,
            hook: hookName,
            path: this.path
          });
          return hookFn.apply(this, args);
        }
      }
    });

    return original.apply(this, args);
  }
}

function hijackRouteController(original, type) {
  return function (options) {
    var args = Array.prototype.slice.call(arguments);
    options && routerEvents.forEach(function (hookName) {
      var hookFn = options[hookName];
      if(typeof hookFn === 'function') {
        options[hookName] = function () {
          var args = Array.prototype.slice.call(arguments);
          zone.setInfo(type, {
            name: this.route && this.route.name,
            hook: hookName,
            path: this.path
          });
          return hookFn.apply(this, args);
        }
      }
    });
    return original.apply(this, args);
  }
}

//--------------------------------------------------------------------------\\

var originalFunctions = [];
function backupOriginals(obj, methodNames) {
  if(obj && Array.isArray(methodNames)) {
    var backup = {obj: obj};
    backup.methods = {};
    methodNames.forEach(function (name) {
      backup.methods[name] = obj[name];
    });
    originalFunctions.push(backup);
  };
}

function restoreOriginals() {
  originalFunctions.forEach(function (backup) {
    for(var name in backup.methods) {
      backup.obj[name] = backup.methods[name];
    };
  });
}

function pickAllArgs(context, args) {
  return args;
}
<|endoftext|>


<commit_before>/*global chai:true, describe:true, it:true, before: true, beforeEach:true, after:true, afterEach:true, expect:true, should:true, sinon:true */
// define('wrapper-backbone', [], function () {
//   "use strict";
//   return Backbone;
// });

// define('model-application-mobile', [], function () {
//   "use strict";
//   return Backbone.Model.extend();
// });

// define('model-interaction-mobile', [], function () {
//   "use strict";
//   return Backbone.Model.extend();
// });

// define('view-interaction-mobile', [], function () {
//   "use strict";
//   return Backbone.View.extend();
// });

// define('jquerymobile', [], function () {
//   "use strict";
//   console.log("Subtituting jQuery Mobile");
// });

define(function () {
  "use strict";
  describe('Router - jQuery Mobile Implementation', function () {
    var router, originalModel, originalView;

    before(function (done) {
      require(['model-application', 'view-interaction'], function (app, InteractionView) {

        originalModel = app;
        originalView = InteractionView;
        requirejs.undef('model-application');
        requirejs.undef('view-interaction');

        define('model-application', [], function () {
          return function (param) {console.log(param)};
        });

        define('view-interaction', [], function () {
          return function (param) {console.log(param)};
        });

        require(['router'], function (rRouter) {
          router = rRouter;
          done();
        });
      });
    });

    after(function () {
      requirejs.undef('model-application');
      requirejs.undef('view-interaction');
      define('model-application', [], function () {
          return originalModel;
        });

        define('view-interaction', [], function () {
          return originalView;
        });
    });

    it("should exist", function () {
      should.exist(router);
    });

    describe('initialize', function () {
      it("should contain the function initialize", function () {
        router.should.respondTo('initialize');
      });

      it("should bind to pagebeforeload");

      it("should prevent the default action");

      it("should detect if the interaction is specified by ID (instead of name)");

      it("should prepare the inheritance chain");

      it("should prepare any GET attributes");

      it("should tell the model to prepare for the view");

      it("should create the view");

      it("should bind view attribute creation to render event");

      it("should resolve the deferred on render event");

      it("should start the render process");
    });

    describe('inheritanceChain(data)', function () {
      it("should contain the function inheritanceChain", function () {
        router.should.respondTo('inheritanceChain');
      });

      it("should set the inheritance chain on relevant interactions");
    });
  });
});
<commit_msg>Clean up router's unit tests<commit_after>/*global chai:true, describe:true, it:true, before: true, beforeEach:true, after:true, afterEach:true, expect:true, should:true, sinon:true */
define(function () {
  "use strict";
  describe('Router - jQuery Mobile Implementation', function () {
    var router, originalModel, originalView;

    before(function (done) {
      require(['model-application', 'view-interaction'], function (app, InteractionView) {

        originalModel = app;
        originalView = InteractionView;
        requirejs.undef('model-application');
        requirejs.undef('view-interaction');

        define('model-application', [], function () {
          return function (param) {console.log(param)};
        });

        define('view-interaction', [], function () {
          return function (param) {console.log(param)};
        });

        require(['router'], function (rRouter) {
          router = rRouter;
          done();
        });
      });
    });

    after(function () {
      requirejs.undef('model-application');
      requirejs.undef('view-interaction');
      define('model-application', [], function () {
          return originalModel;
        });

        define('view-interaction', [], function () {
          return originalView;
        });
    });

    it("should exist", function () {
      should.exist(router);
    });

    describe('initialize', function () {
      it("should contain the function initialize", function () {
        router.should.respondTo('initialize');
      });

      it("should bind to pagebeforeload");

      it("should prevent the default action");

      it("should detect if the interaction is specified by ID (instead of name)");

      it("should prepare the inheritance chain");

      it("should prepare any GET attributes");

      it("should tell the model to prepare for the view");

      it("should create the view");

      it("should bind view attribute creation to render event");

      it("should resolve the deferred on render event");

      it("should start the render process");
    });

    describe('inheritanceChain(data)', function () {
      it("should contain the function inheritanceChain", function () {
        router.should.respondTo('inheritanceChain');
      });

      it("should set the inheritance chain on relevant interactions");
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

const co = require('co');

const logger = require('../shared/logger');

const AppService = require('./app/app-service');
const PrefManager = require('./preferences/pref-manager');
const WorkerClient = require('./worker/worker-client');
const WorkerProxy = require('./worker/worker-proxy');
const WorkerHandler = require('./worker/worker-handler');
const ApiService = require('./api/api-service');

module.exports = class Server {
  constructor() {
    this.workerClient = new WorkerClient();
    this.workerProxy = new WorkerProxy(this.workerClient);
    this.prefManager = new PrefManager(this.workerProxy);
    this.appService = new AppService(this.prefManager, this.workerClient, this.workerProxy);
    this.apiService = new ApiService(this.appService);
    this.workerHandler = new WorkerHandler(this.workerClient, this.appService, this.apiService);
  }
  launch() {
    this.apiService.loadApiModules();
    this.workerHandler.initialize();
    return this.appService.initializeAndLaunch()
      .then(() => {
        this.workerClient.loadWorker();
        this.workerProxy.initialize(this.prefManager.appPref.get());
      });
  }
};
<commit_msg>Code cleanup<commit_after>'use strict';

const AppService = require('./app/app-service');
const PrefManager = require('./preferences/pref-manager');
const WorkerClient = require('./worker/worker-client');
const WorkerProxy = require('./worker/worker-proxy');
const WorkerHandler = require('./worker/worker-handler');
const ApiService = require('./api/api-service');

module.exports = class Server {
  constructor() {
    this.workerClient = new WorkerClient();
    this.workerProxy = new WorkerProxy(this.workerClient);
    this.prefManager = new PrefManager(this.workerProxy);
    this.appService = new AppService(this.prefManager, this.workerClient, this.workerProxy);
    this.apiService = new ApiService(this.appService);
    this.workerHandler = new WorkerHandler(this.workerClient, this.appService, this.apiService);
  }
  launch() {
    this.apiService.loadApiModules();
    this.workerHandler.initialize();
    return this.appService.initializeAndLaunch()
      .then(() => {
        this.workerClient.loadWorker();
        this.workerProxy.initialize(this.prefManager.appPref.get());
      });
  }
};
<|endoftext|>


<commit_before>window.name = 'NG_DEFER_BOOTSTRAP!';

require.config({
    waitSeconds: 120,
    baseUrl : '/app',
    paths: {
      'authentication'   : 'services/authentication',
      'angular'          : 'libs/angular-flex/angular-flex',
      'ngRoute'          : 'libs/angular-route/angular-route.min',
      'ngSanitize'       : 'libs/angular-sanitize/angular-sanitize.min',
      'domReady'         : 'libs/requirejs-domready/domReady',
      'text'             : 'libs/requirejs-text/text',
      'bootstrap'        : 'libs/bootstrap/dist/js/bootstrap.min',
      'lodash'           : 'libs/lodash/lodash.min',
      'URIjs'            : 'libs/uri.js/src',
      'linqjs'           : 'libs/linqjs/linq.min',
      'leaflet'          : 'libs/leaflet/dist/leaflet',
      'jquery'           : 'libs/jquery/dist/jquery.min',
      'moment'           : 'libs/moment/moment',
      'leaflet-directive': 'js/libs/leaflet/angular-leaflet-directive',
      'ng-breadcrumbs'   : 'libs/ng-breadcrumbs/dist/ng-breadcrumbs.min',
      'bootstrap-datepicker': 'libs/bootstrap-datepicker/js/bootstrap-datepicker',
      'ionsound'         : 'libs/ionsound/js/ion.sound.min',
      'jqvmap'           : 'js/libs/jqvmap/jqvmap/jquery.vmap',
      'jqvmapworld'      : 'js/libs/jqvmap/jqvmap/maps/jquery.vmap.world',
      'ngAnimate'        : 'libs/angular-animate/angular-animate.min',
      'ngAria'           : 'libs/angular-aria/angular-aria.min',
      'ngMaterial'       : 'libs/angular-material/angular-material.min',
      'ngSmoothScroll'   : 'libs/ngSmoothScroll/angular-smooth-scroll.min',
      'ammap3WorldLow'   : 'libs/ammap3/ammap/maps/js/worldLow',
      'ammap3'           : 'libs/ammap3/ammap/ammap',
      'ammap-theme'      : 'libs/ammap3/ammap/themes/light',
      // "ammap-resp"       : 'libs/ammap3/ammap/plugins/responsive/responsive',

    },
    shim: {
      'libs/angular/angular'     : { deps: ['jquery'] },
      'angular'                  : { deps: ['libs/angular/angular'] },
      'ngRoute'                  : { deps: ['angular'] },
      'ngSanitize'               : { deps: ['angular'] },
      'leaflet-directive'        : { deps: ['angular', 'leaflet'], exports : 'L' },
      'ng-breadcrumbs'           : { deps: ['angular'] },
      'bootstrap'                : { deps: ['jquery'] },
      'linqjs'                   : { deps: [], exports : 'Enumerable' },
      'leaflet'                  : { deps: [], exports : 'L' },
      'bootstrap-datepicker'     : { deps: ['bootstrap'] },
      'jqvmap'                   : { deps: ['jquery'] },
      'jqvmapworld'              : { deps: ['jqvmap'] },
      'ionsound'                 : { deps: ['jquery'] },
      'ngAnimate'                : { deps: ['angular'] },
      'ngAria'                   : { deps: ['angular'] },
      'ngMaterial'               : { deps: ['angular', 'ngAnimate', 'ngAria'] },
      'ngSmoothScroll'           : { deps: ['angular'] },
      'ammap3WorldLow'           : { deps: ['ammap3'] },
      'ammap-theme'              : { deps: ['ammap3']},
      'ammap-resp'               : { deps: ['ammap3']}
    },
});

// BOOT

require(['angular', 'domReady!', 'bootstrap', 'app', 'routes', 'index'], function(ng, doc){

    ng.bootstrap(doc, ['kmApp']);
    ng.resumeBootstrap();

});
<commit_msg>Turn on responsiveness on map after solving version issuees<commit_after>window.name = 'NG_DEFER_BOOTSTRAP!';

require.config({
    waitSeconds: 120,
    baseUrl : '/app',
    paths: {
      'authentication'   : 'services/authentication',
      'angular'          : 'libs/angular-flex/angular-flex',
      'ngRoute'          : 'libs/angular-route/angular-route.min',
      'ngSanitize'       : 'libs/angular-sanitize/angular-sanitize.min',
      'domReady'         : 'libs/requirejs-domready/domReady',
      'text'             : 'libs/requirejs-text/text',
      'bootstrap'        : 'libs/bootstrap/dist/js/bootstrap.min',
      'lodash'           : 'libs/lodash/lodash.min',
      'URIjs'            : 'libs/uri.js/src',
      'linqjs'           : 'libs/linqjs/linq.min',
      'leaflet'          : 'libs/leaflet/dist/leaflet',
      'jquery'           : 'libs/jquery/dist/jquery.min',
      'moment'           : 'libs/moment/moment',
      'leaflet-directive': 'js/libs/leaflet/angular-leaflet-directive',
      'ng-breadcrumbs'   : 'libs/ng-breadcrumbs/dist/ng-breadcrumbs.min',
      'bootstrap-datepicker': 'libs/bootstrap-datepicker/js/bootstrap-datepicker',
      'ionsound'         : 'libs/ionsound/js/ion.sound.min',
      'jqvmap'           : 'js/libs/jqvmap/jqvmap/jquery.vmap',
      'jqvmapworld'      : 'js/libs/jqvmap/jqvmap/maps/jquery.vmap.world',
      'ngAnimate'        : 'libs/angular-animate/angular-animate.min',
      'ngAria'           : 'libs/angular-aria/angular-aria.min',
      'ngMaterial'       : 'libs/angular-material/angular-material.min',
      'ngSmoothScroll'   : 'libs/ngSmoothScroll/angular-smooth-scroll.min',
      'ammap3WorldLow'   : 'libs/ammap3/ammap/maps/js/worldLow',
      'ammap3'           : 'libs/ammap3/ammap/ammap',
      'ammap-theme'      : 'libs/ammap3/ammap/themes/light',
      'ammap-resp'       : 'libs/ammap3/ammap/plugins/responsive/responsive',

    },
    shim: {
      'libs/angular/angular'     : { deps: ['jquery'] },
      'angular'                  : { deps: ['libs/angular/angular'] },
      'ngRoute'                  : { deps: ['angular'] },
      'ngSanitize'               : { deps: ['angular'] },
      'leaflet-directive'        : { deps: ['angular', 'leaflet'], exports : 'L' },
      'ng-breadcrumbs'           : { deps: ['angular'] },
      'bootstrap'                : { deps: ['jquery'] },
      'linqjs'                   : { deps: [], exports : 'Enumerable' },
      'leaflet'                  : { deps: [], exports : 'L' },
      'bootstrap-datepicker'     : { deps: ['bootstrap'] },
      'jqvmap'                   : { deps: ['jquery'] },
      'jqvmapworld'              : { deps: ['jqvmap'] },
      'ionsound'                 : { deps: ['jquery'] },
      'ngAnimate'                : { deps: ['angular'] },
      'ngAria'                   : { deps: ['angular'] },
      'ngMaterial'               : { deps: ['angular', 'ngAnimate', 'ngAria'] },
      'ngSmoothScroll'           : { deps: ['angular'] },
      'ammap3WorldLow'           : { deps: ['ammap3'] },
      'ammap-theme'              : { deps: ['ammap3']},
      'ammap-resp'               : { deps: ['ammap3']}
    },
});

// BOOT

require(['angular', 'domReady!', 'bootstrap', 'app', 'routes', 'index'], function(ng, doc){

    ng.bootstrap(doc, ['kmApp']);
    ng.resumeBootstrap();

});
<|endoftext|>


<commit_before>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
// load the master sakai object to access all Sakai OAE API methods
require(["jquery", "sakai/sakai.api.core"], function($, sakai){

    /**
     * @name sakai_global.recentactivity
     *
     * @class recentactivity
     *
     * @version 0.0.1
     * @param {String} tuid Unique id of the widget
     * @param {Boolean} showSettings Show the settings of the widget or not
     */
    sakai_global.recentactivity = function(tuid, showSettings){

        // Templates
        var recentactivityActivityItemTemplate = "recentactivity_activity_item_template";

        // Container
        var $recentactivityActivityContainer = $("#recentactivity_activity_container");

        var activityMap = {
            CONTENT_ADDED_COMMENT: "comment",
            CREATED_FILE: "upload",
            GROUP_CREATED: "new",
            JOINED_GROUP: "new",
            SENT_MESSAGE: "upload",
            UPDATED_CONTENT: "new",
            UPDATED_DESCRIPTION: "new",
            UPLOADED_CONTENT: "upload",
            UPDATED_COPYRIGHT: "new",
            UPDATED_URL: "new",
            UPDATED_TAGS: "new",
            USER_CREATED: "new"
        };

        var t = "";
        var numItems = 0;
        var numDiff = 0;

        var parseActivity = function(success, data, initialLoad){
            if (success) {
                var results = [];
                numDiff = data.total - numItems;
                numItems = data.total;
                var total = 0;
                $.each(data.results, function(index, item){
                    if (item["sakai:pooled-content-file-name"] && activityMap[item["sakai:activityMessage"]] && item["who"] && item["who"].basic && total < 5) {
                        if (index < numDiff) {
                            item.fadeIn = true;
                        }
                        item.showdetails = true;
                        if (item["sakai:activity-type"] && item["sakai:activity-type"] == "message" || item["sakai:activity-type"] == "group") {
                            item.showdetails = false;
                        }
                        item.who.name = sakai.api.User.getDisplayName(item.who);
                        item["sakai:activity-appid"] = activityMap[item["sakai:activityMessage"]];
                        item["sakai:activityMessage"] = sakai.api.i18n.getValueForKey(item["sakai:activityMessage"], "recentactivity");
                        if (item.who.picture) {
                            item.who.picture = "/~" + sakai.api.Util.safeURL(item.who.userid) + "/public/profile/" + $.parseJSON(item.who.picture).name;
                        }
                        else {
                            item.who.picture = "/dev/images/default_User_icon_50x50.png";
                        }
                        item.usedin = sakai.api.Content.getPlaceCount(item);
                        results.push(item);
                        total++;
                    }
                });
                var json = {
                    "data": results,
                    "sakai": sakai
                };
                sakai.api.Util.TemplateRenderer(recentactivityActivityItemTemplate, json, $recentactivityActivityContainer);
                applyThreeDots();
            }

            var $recentactivity_activity_item_container = $(".recentactivity_activity_item_container");
            $recentactivity_activity_item_container.filter(":visible").css("opacity", 1);
            if (!initialLoad) {
                $recentactivity_activity_item_container.filter(":hidden").animate({
                    height: 100,
                    "opacity": 1
                }, {
                    duration: 1000,
                    specialEasing: {
                        height: 'easeOutBounce',
                        opacity: 'linear'
                    },
                    step: function(now, fx){
                        $(fx.elem).css("display", "block");
                        applyThreeDots();
                    }
                });
            } else {
                $recentactivity_activity_item_container.filter(":hidden").show();
                $recentactivity_activity_item_container.filter(":visible").css("opacity", 1);
                applyThreeDots();
            }

            t = setTimeout(fetchActivity, 8000);
        };

        var applyThreeDots = function(){
            $.each($(".recentactivity_activity_item_text"), function(index, element) {
                var $el = $(element);
                var width = effectiveWidth($el, $el.siblings("a").find("img"));
                $el.html(sakai.api.Util.applyThreeDots($el.html(), width, {max_rows: 1}, $el.attr("class"), true));
            });
            $.each($(".recentactivity_activity_item_description"), function(index, element) {
                var $el = $(element);
                var width = effectiveWidth($el, $el.siblings("a").find("img"));
                $el.html(sakai.api.Util.applyThreeDots($el.html(), width, undefined, $el.attr("class"), true));
            });
        };

        var effectiveWidth = function(container, floated) {
            var eWidth = $(container).width();
            $.each(floated, function(index, floater) {
                eWidth -= $(floater).outerWidth(true);
            });
            return eWidth;
        };

        var fetchActivity = function(initialLoad){
            sakai.api.Server.loadJSON(sakai.config.URL.SEARCH_ACTIVITY_ALL_URL, function(success, data){
                parseActivity(success, data, initialLoad);
            }, {
                "items": 12
            });
        };

        var doInit = function(initialLoad){
            fetchActivity(initialLoad);
        };

        doInit(true);

    };

    sakai.api.Widgets.widgetLoader.informOnLoad("recentactivity");
});
<commit_msg>SAKIII-3980 get correct profile picture in recent activity widget<commit_after>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
// load the master sakai object to access all Sakai OAE API methods
require(["jquery", "sakai/sakai.api.core"], function($, sakai){

    /**
     * @name sakai_global.recentactivity
     *
     * @class recentactivity
     *
     * @version 0.0.1
     * @param {String} tuid Unique id of the widget
     * @param {Boolean} showSettings Show the settings of the widget or not
     */
    sakai_global.recentactivity = function(tuid, showSettings){

        // Templates
        var recentactivityActivityItemTemplate = "recentactivity_activity_item_template";

        // Container
        var $recentactivityActivityContainer = $("#recentactivity_activity_container");

        var activityMap = {
            CONTENT_ADDED_COMMENT: "comment",
            CREATED_FILE: "upload",
            GROUP_CREATED: "new",
            JOINED_GROUP: "new",
            SENT_MESSAGE: "upload",
            UPDATED_CONTENT: "new",
            UPDATED_DESCRIPTION: "new",
            UPLOADED_CONTENT: "upload",
            UPDATED_COPYRIGHT: "new",
            UPDATED_URL: "new",
            UPDATED_TAGS: "new",
            USER_CREATED: "new"
        };

        var t = "";
        var numItems = 0;
        var numDiff = 0;

        var parseActivity = function(success, data, initialLoad){
            if (success) {
                var results = [];
                numDiff = data.total - numItems;
                numItems = data.total;
                var total = 0;
                $.each(data.results, function(index, item){
                    if (item["sakai:pooled-content-file-name"] && activityMap[item["sakai:activityMessage"]] && item["who"] && item["who"].basic && total < 5) {
                        if (index < numDiff) {
                            item.fadeIn = true;
                        }
                        item.showdetails = true;
                        if (item["sakai:activity-type"] && item["sakai:activity-type"] == "message" || item["sakai:activity-type"] == "group") {
                            item.showdetails = false;
                        }
                        item.who.name = sakai.api.User.getDisplayName(item.who);
                        item["sakai:activity-appid"] = activityMap[item["sakai:activityMessage"]];
                        item["sakai:activityMessage"] = sakai.api.i18n.getValueForKey(item["sakai:activityMessage"], "recentactivity");
                        item.who.picture = sakai.api.User.getProfilePicture(item.who);
                        item.usedin = sakai.api.Content.getPlaceCount(item);
                        results.push(item);
                        total++;
                    }
                });
                var json = {
                    "data": results,
                    "sakai": sakai
                };
                sakai.api.Util.TemplateRenderer(recentactivityActivityItemTemplate, json, $recentactivityActivityContainer);
                applyThreeDots();
            }

            var $recentactivity_activity_item_container = $(".recentactivity_activity_item_container");
            $recentactivity_activity_item_container.filter(":visible").css("opacity", 1);
            if (!initialLoad) {
                $recentactivity_activity_item_container.filter(":hidden").animate({
                    height: 100,
                    "opacity": 1
                }, {
                    duration: 1000,
                    specialEasing: {
                        height: 'easeOutBounce',
                        opacity: 'linear'
                    },
                    step: function(now, fx){
                        $(fx.elem).css("display", "block");
                        applyThreeDots();
                    }
                });
            } else {
                $recentactivity_activity_item_container.filter(":hidden").show();
                $recentactivity_activity_item_container.filter(":visible").css("opacity", 1);
                applyThreeDots();
            }

            t = setTimeout(fetchActivity, 8000);
        };

        var applyThreeDots = function(){
            $.each($(".recentactivity_activity_item_text"), function(index, element) {
                var $el = $(element);
                var width = effectiveWidth($el, $el.siblings("a").find("img"));
                $el.html(sakai.api.Util.applyThreeDots($el.html(), width, {max_rows: 1}, $el.attr("class"), true));
            });
            $.each($(".recentactivity_activity_item_description"), function(index, element) {
                var $el = $(element);
                var width = effectiveWidth($el, $el.siblings("a").find("img"));
                $el.html(sakai.api.Util.applyThreeDots($el.html(), width, undefined, $el.attr("class"), true));
            });
        };

        var effectiveWidth = function(container, floated) {
            var eWidth = $(container).width();
            $.each(floated, function(index, floater) {
                eWidth -= $(floater).outerWidth(true);
            });
            return eWidth;
        };

        var fetchActivity = function(initialLoad){
            sakai.api.Server.loadJSON(sakai.config.URL.SEARCH_ACTIVITY_ALL_URL, function(success, data){
                parseActivity(success, data, initialLoad);
            }, {
                "items": 12
            });
        };

        var doInit = function(initialLoad){
            fetchActivity(initialLoad);
        };

        doInit(true);

    };

    sakai.api.Widgets.widgetLoader.informOnLoad("recentactivity");
});
<|endoftext|>


<commit_before>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

/*global $, Config, jQuery, sakai */

/**
 * @name sakai.recentmessages
 *
 * @class recentmessages
 *
 * @description
 * Initialize the recentmessages widget
 *
 * @version 0.0.1
 * @param {String} tuid Unique id of the widget
 * @param {Boolean} showSettings Show the settings of the widget or not
 */
sakai.recentmessages = function(tuid, showSettings){

    /////////////////////////////
    // Configuration variables //
    /////////////////////////////

    var rootel = $("#" + tuid);

    // IDs
    var $recentmessagesContainer = $("#recentmessages_container", rootel);
    var $recentmessagesErrorNomessages = $("#recentmessages_error_nomessages", rootel);
    var $recentmessagesErrorNotConnected = $("#recentmessages_error_notconnected", rootel);
    var $recentmessagesListItems = $("#recentmessages_container ul li a", rootel);
    var recentmessagesTemplate = "recentmessages_template";

    ///////////////////////
    // Utility functions //
    ///////////////////////

    /**
     * Render the json object in the browser.
     * @param {Object|String} response
     *     This is the json response from the server.
     *     If this parameter is a string, it is an error.
     */
    var renderRecentMessages = function(response){

        if(response === "NOT_CONNECTED"){

            // If it wasn't possible to connect to the server, show the not connected error
            $recentmessagesContainer.html($recentmessagesErrorNotConnected);
        } else if (response.total === 0){

            // If the user doesn't have any messages, show the no messages error.
            $recentmessagesContainer.html($recentmessagesErrorNomessages);
        } else {

            // Only if everything went fine, show the recent messages
            $recentmessagesContainer.html($.TemplateRenderer(recentmessagesTemplate, response));

            // Activate the ThreeDots plug-in
            $("#recentmessages_container ul li a", rootel).ThreeDots({max_rows:1});
        }
    };

    /**
     * Load the recent messages for the current user
     * @param {Object|Boolean} response
     *     The response that the server has send.
     *     If the response is false, it means we were not able to connect to the server
     */
    var loadRecentMessages = function(response){

        // Check if the request was successful
        if (response) {

            // Render the recent message for the current user.
            renderRecentMessages(response);
        }else {
            renderRecentMessages("NOT_CONNECTED");
        }
    };

    /**
     * Send a request to the message service.to get your recent messages
     */
    var doInit = function() {

        // Set a params object to set which params should be passed into the request
        var params = $.param({
            box: "inbox",
            category: "message",
            items: 4,
            page: 0
        });

        // Fire an Ajax request to get the recent messages for the current user
        $.ajax({
            url: sakai.config.URL.MESSAGE_BOXCATEGORY_SERVICE + "?" + params,
            cache: false,
            success: function(data){
                loadRecentMessages(data);
            },
            error: function() {
                loadRecentMessages(false);
            }
        });
    };

    ////////////////////
    // Event Handlers //
    ////////////////////

    doInit();

};
sakai.api.Widgets.widgetLoader.informOnLoad("recentmessages");
<commit_msg>SAKIII-578 - Make invitations show up in the recent messages widget<commit_after>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

/*global $, Config, jQuery, sakai */

/**
 * @name sakai.recentmessages
 *
 * @class recentmessages
 *
 * @description
 * Initialize the recentmessages widget
 *
 * @version 0.0.1
 * @param {String} tuid Unique id of the widget
 * @param {Boolean} showSettings Show the settings of the widget or not
 */
sakai.recentmessages = function(tuid, showSettings){

    /////////////////////////////
    // Configuration variables //
    /////////////////////////////

    var rootel = $("#" + tuid);

    // IDs
    var $recentmessagesContainer = $("#recentmessages_container", rootel);
    var $recentmessagesErrorNomessages = $("#recentmessages_error_nomessages", rootel);
    var $recentmessagesErrorNotConnected = $("#recentmessages_error_notconnected", rootel);
    var $recentmessagesListItems = $("#recentmessages_container ul li a", rootel);
    var recentmessagesTemplate = "recentmessages_template";

    ///////////////////////
    // Utility functions //
    ///////////////////////

    /**
     * Render the json object in the browser.
     * @param {Object|String} response
     *     This is the json response from the server.
     *     If this parameter is a string, it is an error.
     */
    var renderRecentMessages = function(response){

        if(response === "NOT_CONNECTED"){

            // If it wasn't possible to connect to the server, show the not connected error
            $recentmessagesContainer.html($recentmessagesErrorNotConnected);
        } else if (response.total === 0){

            // If the user doesn't have any messages, show the no messages error.
            $recentmessagesContainer.html($recentmessagesErrorNomessages);
        } else {

            // Only if everything went fine, show the recent messages
            $recentmessagesContainer.html($.TemplateRenderer(recentmessagesTemplate, response));

            // Activate the ThreeDots plug-in
            $("#recentmessages_container ul li a", rootel).ThreeDots({max_rows:1});
        }
    };

    /**
     * Load the recent messages for the current user
     * @param {Object|Boolean} response
     *     The response that the server has send.
     *     If the response is false, it means we were not able to connect to the server
     */
    var loadRecentMessages = function(response){

        // Check if the request was successful
        if (response) {

            // Render the recent message for the current user.
            renderRecentMessages(response);
        }else {
            renderRecentMessages("NOT_CONNECTED");
        }
    };

    /**
     * Send a request to the message service.to get your recent messages
     */
    var doInit = function() {

        // Set a params object to set which params should be passed into the request
        var params = $.param({
            box: "inbox",
            //category: "message",
            items: 4,
            page: 0
        });

        // Fire an Ajax request to get the recent messages for the current user
        $.ajax({
            url: sakai.config.URL.MESSAGE_BOX_SERVICE + "?" + params,
            cache: false,
            success: function(data){
                loadRecentMessages(data);
            },
            error: function() {
                loadRecentMessages(false);
            }
        });
    };

    ////////////////////
    // Event Handlers //
    ////////////////////

    doInit();

};
sakai.api.Widgets.widgetLoader.informOnLoad("recentmessages");
<|endoftext|>


<commit_before>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

/*global $, Config, jQuery, sakai */

/**
 * @name sakai.recentmessages
 *
 * @class recentmessages
 *
 * @description
 * Initialize the recentmessages widget
 *
 * @version 0.0.1
 * @param {String} tuid Unique id of the widget
 * @param {Boolean} showSettings Show the settings of the widget or not
 */
sakai.recentmessages = function(tuid, showSettings){

    /////////////////////////////
    // Configuration variables //
    /////////////////////////////

    var rootel = $("#" + tuid);

    // IDs
    var $recentmessagesContainer = $("#recentmessages_container", rootel);
    var $recentmessagesErrorNomessages = $("#recentmessages_error_nomessages", rootel);
    var $recentmessagesErrorNotConnected = $("#recentmessages_error_notconnected", rootel);
    var $recentmessagesListItems = $("#recentmessages_container ul li a", rootel);
    var recentmessagesTemplate = "recentmessages_template";

    ///////////////////////
    // Utility functions //
    ///////////////////////

    /**
     * Render the json object in the browser.
     * @param {Object|String} response
     *     This is the json response from the server.
     *     If this parameter is a string, it is an error.
     */
    var renderRecentMessages = function(response){

        if(response === "NOT_CONNECTED"){

            // If it wasn't possible to connect to the server, show the not connected error
            $recentmessagesContainer.html($recentmessagesErrorNotConnected);
        } else if (response.total === 0){

            // If the user doesn't have any messages, show the no messages error.
            $recentmessagesContainer.html($recentmessagesErrorNomessages);
        } else {

            // Only if everything went fine, show the recent messages
            $recentmessagesContainer.html($.TemplateRenderer(recentmessagesTemplate, response));

            // Activate the ThreeDots plug-in
            $("#recentmessages_container ul li a", rootel).ThreeDots({max_rows:1});
        }
    };

    /**
     * Load the recent messages for the current user
     * @param {Object|Boolean} response
     *     The response that the server has send.
     *     If the response is false, it means we were not able to connect to the server
     */
    var loadRecentMessages = function(response){

        // Check if the request was successful
        if (response) {

            // Render the recent message for the current user.
            renderRecentMessages(response);
        }else {
            renderRecentMessages("NOT_CONNECTED");
        }
    };

    /**
     * Send a request to the message service.to get your recent messages
     */
    var doInit = function() {

        // Set a params object to set which params should be passed into the request
        var params = $.param({
            box: "inbox",
			category: "message",
            items: 4,
            page: 0
        });

        // Fire an Ajax request to get the recent messages for the current user
        $.ajax({
            url: sakai.config.URL.MESSAGE_BOXCATEGORY_SERVICE + "?" + params,
            cache: false,
            success: function(data){
                loadRecentMessages(data);
            },
            error: function() {
                loadRecentMessages(false);
            }
        });
    };

    ////////////////////
    // Event Handlers //
    ////////////////////

    doInit();

};
sakai.api.Widgets.widgetLoader.informOnLoad("recentmessages");
<commit_msg>fixed recent messages widget to display message subject in Firefox<commit_after>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

/*global $, Config, jQuery, sakai */

/**
 * @name sakai.recentmessages
 *
 * @class recentmessages
 *
 * @description
 * Initialize the recentmessages widget
 *
 * @version 0.0.1
 * @param {String} tuid Unique id of the widget
 * @param {Boolean} showSettings Show the settings of the widget or not
 */
sakai.recentmessages = function(tuid, showSettings){

    /////////////////////////////
    // Configuration variables //
    /////////////////////////////

    var rootel = $("#" + tuid);

    // IDs
    var $recentmessagesContainer = $("#recentmessages_container", rootel);
    var $recentmessagesErrorNomessages = $("#recentmessages_error_nomessages", rootel);
    var $recentmessagesErrorNotConnected = $("#recentmessages_error_notconnected", rootel);
    var $recentmessagesListItems = $("#recentmessages_container ul li a", rootel);
    var recentmessagesTemplate = "recentmessages_template";

    ///////////////////////
    // Utility functions //
    ///////////////////////

    /**
     * Render the json object in the browser.
     * @param {Object|String} response
     *     This is the json response from the server.
     *     If this parameter is a string, it is an error.
     */
    var renderRecentMessages = function(response){

        if(response === "NOT_CONNECTED"){

            // If it wasn't possible to connect to the server, show the not connected error
            $recentmessagesContainer.html($recentmessagesErrorNotConnected);
        } else if (response.total === 0){

            // If the user doesn't have any messages, show the no messages error.
            $recentmessagesContainer.html($recentmessagesErrorNomessages);
        } else {

            // Only if everything went fine, show the recent messages
            $recentmessagesContainer.html($.TemplateRenderer(recentmessagesTemplate, response));

            // Activate the ThreeDots plug-in
            $("#recentmessages_container ul li a span", rootel).ThreeDots({max_rows:1});
        }
    };

    /**
     * Load the recent messages for the current user
     * @param {Object|Boolean} response
     *     The response that the server has send.
     *     If the response is false, it means we were not able to connect to the server
     */
    var loadRecentMessages = function(response){

        // Check if the request was successful
        if (response) {

            // Render the recent message for the current user.
            renderRecentMessages(response);
        }else {
            renderRecentMessages("NOT_CONNECTED");
        }
    };

    /**
     * Send a request to the message service.to get your recent messages
     */
    var doInit = function() {

        // Set a params object to set which params should be passed into the request
        var params = $.param({
            box: "inbox",
			category: "message",
            items: 4,
            page: 0
        });

        // Fire an Ajax request to get the recent messages for the current user
        $.ajax({
            url: sakai.config.URL.MESSAGE_BOXCATEGORY_SERVICE + "?" + params,
            cache: false,
            success: function(data){
                loadRecentMessages(data);
            },
            error: function() {
                loadRecentMessages(false);
            }
        });
    };

    ////////////////////
    // Event Handlers //
    ////////////////////

    doInit();

};
sakai.api.Widgets.widgetLoader.informOnLoad("recentmessages");
<|endoftext|>


<commit_before>
requirejs.config({
    baseUrl: '/js',
    paths: {
        underscore: 'lib/underscore'
    }
});

var standardDimension = 100;

requirejs(['app/app'], function(app) {

    // at first I just want to make a HUD for my glider.

    // so things like
    // attitude indicator
    // moving map
    // g-meter
    // current heading
    // altitude
    // sink rate
    // velocity vector/intercept point

    function AttitudeIndicator() {

    }

    AttitudeIndicator.prototype.draw = function (ctx, roll, pitch) {
        var dimensionPerDegree = .1 / 10;
        var pitchDimension = standardDimension * pitch * dimensionPerDegree;
        var root2 = 1.414213562373095;
        var hemisphereHeight = standardDimension * 1.2;

        ctx.save();
        ctx.beginPath();
        ctx.rect(-standardDimension / 2, -standardDimension / 2, standardDimension, standardDimension);
        ctx.clip();

        ctx.rotate(roll / 180 * Math.PI);
        ctx.translate(0, pitchDimension);

        ctx.fillStyle = "#0000ff";
        ctx.fillRect(-standardDimension / 2 * root2, -hemisphereHeight, standardDimension * root2, hemisphereHeight);

        ctx.fillStyle = "#705010";
        ctx.fillRect(-standardDimension / 2 * root2, 0, standardDimension * root2, hemisphereHeight);

        var ticks = 18;
        var halfTicks = 9;
        for (var i = 0; i <= ticks; i++) {
            var height = i == halfTicks ? standardDimension * .02 : standardDimension * .01;
            var width = i == halfTicks ? root2 : .5;
            var degrees = (i - halfTicks) * 10;

            ctx.fillStyle = "#ffffff";
            ctx.fillRect(-standardDimension * width / 2, standardDimension * dimensionPerDegree * degrees, standardDimension * width, height)

            var rectWidth = standardDimension * .2;
            ctx.font = (standardDimension * .05) + "px Futura";
            ctx.textAlign = "center";
            ctx.textBaseline = "middle";
            var labelText = -1 * degrees;
            ctx.fillText(labelText,
                -standardDimension * width / 2 - (rectWidth / 2),
                standardDimension * dimensionPerDegree * degrees,
                rectWidth);
            ctx.fillText(labelText,
                standardDimension * width / 2 + (rectWidth / 2),
                standardDimension * dimensionPerDegree * degrees,
                rectWidth);

        //     NSString *label = [NSString stringWithFormat:@"%d", (-1 * (degrees))];
        //     CGFloat rectWidth = standardDimension * .15;
        //     CGFloat rectHeight = standardDimension * .06;
        //     [label drawInRect:CGRectMake(-standardDimension * width / 2 - rectWidth, standardDimension * dimensionPerDegree * degrees - rectHeight / 2, rectWidth, rectHeight)
        //        withAttributes:@{
        //                         NSForegroundColorAttributeName: [UIColor whiteColor],
        //                         //NSBackgroundColorAttributeName: [UIColor colorWithWhite:1 alpha:.2],
        //                         NSFontAttributeName: font,
        //                         NSParagraphStyleAttributeName: style
        //                         }];

        //     [label drawInRect:CGRectMake(standardDimension * width / 2, standardDimension * dimensionPerDegree * degrees - rectHeight / 2, rectWidth, rectHeight)
        //        withAttributes:@{
        //                         NSForegroundColorAttributeName: [UIColor whiteColor],
        //                         //NSBackgroundColorAttributeName: [UIColor colorWithWhite:1 alpha:.2],
        //                         NSFontAttributeName: font,
        //                         NSParagraphStyleAttributeName: style
        //                         }];
        }

        ctx.restore();

        // arrow

        ctx.fillStyle = "#ffffff";
        ctx.fillRect(-standardDimension * .2, 0, standardDimension * .4, standardDimension * .01);
        ctx.fillRect(0, -standardDimension * .05, standardDimension * .01, standardDimension * .1);

    }

    function SensorDisplayView() {
        this.element = $("

");
        this.attitude = new AttitudeIndicator();
    };

    SensorDisplayView.prototype.recreateCanvas = function() {
        var c = $("<canvas></canvas>");
        this.element.empty().append(c);
        c[0].width = $(window).width();
        c[0].height = $(window).height();
        this.ctx = c[0].getContext('2d');

    }

    SensorDisplayView.prototype.draw = function() {
        var width = this.element.width();
        var height = this.element.height();

        this.ctx.clearRect(0, 0, width, height);

        this.ctx.save();

        this.ctx.translate(width / 2, height / 2);
        this.ctx.scale(3,3);

        this.attitude.draw(this.ctx, this.state.euler.roll, this.state.euler.pitch);

        this.ctx.restore();
    }

    SensorDisplayView.prototype.attachListeners = function () {
        var self = this;
        $(window).resize(function() { self.recreateCanvas(); })
        this.recreateCanvas();
    };

    SensorDisplayView.prototype.setState = function(value) {
        this.state = value;
        this.draw();
        // this.element.find(".lat").html(value);
    };

    function SensorDisplay(messageSource) {
        this.messageSource = messageSource;
    };

    SensorDisplay.prototype.loadView = function() {
        this.view = new SensorDisplayView();
        this.view.attachListeners();
    };

    SensorDisplay.prototype.viewWillAppear = function() {
        this.messageSource.setDelegate(this);
    };

    SensorDisplay.prototype.viewWillDisappear = function() {
        this.messageSource.setDelegate(null);
        this.view.detachListeners()
        this.view = null;
    };

    SensorDisplay.prototype.viewDidAppear = function() {
        this.messageSource.connect();
    }

    SensorDisplay.prototype.onMessage = function(m) {
        this.view.setState(m);
    };

    var d = new SensorDisplay(new app.MessageSource());
    d.loadView();
    d.viewWillAppear();

    var state = 0;
    setInterval(function() {
        state += 1;
        d.onMessage({
            euler: {
                pitch: 20 * Math.sin(state / 15),
                roll: 60 * Math.cos(state / 30)
            }
        });
    }, 50);

    $(".global-wrapper").append(d.view.element);

    d.viewDidAppear();
});<commit_msg>more monochrome<commit_after>
requirejs.config({
    baseUrl: '/js',
    paths: {
        underscore: 'lib/underscore'
    }
});

var standardDimension = 100;

requirejs(['app/app'], function(app) {

    // at first I just want to make a HUD for my glider.

    // so things like
    // attitude indicator
    // moving map
    // g-meter
    // current heading
    // altitude
    // sink rate
    // velocity vector/intercept point

    function AttitudeIndicator() {

    }

    AttitudeIndicator.prototype.draw = function (ctx, roll, pitch, aspect) {
        var color = "#fff";
        var dimensionPerDegree = .3 / 10;
        var pitchDimension = standardDimension * pitch * dimensionPerDegree;
        var root2 = 1.414213562373095;
        var hemisphereHeight = standardDimension * 1.2;

        ctx.save();
        ctx.beginPath();

        var normalizedWidth = aspect * standardDimension;
        var normalizedHeight = standardDimension;
        console.log(normalizedWidth);
        console.log(normalizedHeight);
        ctx.rect(-normalizedWidth / 2, -normalizedHeight / 2, normalizedWidth, normalizedHeight);
        ctx.clip();

        ctx.rotate(roll / 180 * Math.PI);
        ctx.translate(0, pitchDimension);

        // ctx.fillStyle = "#0000ff";
        // ctx.fillRect(-standardDimension / 2 * root2, -hemisphereHeight, standardDimension * root2, hemisphereHeight);

        // ctx.fillStyle = "#705010";
        // ctx.fillRect(-standardDimension / 2 * root2, 0, standardDimension * root2, hemisphereHeight);

        var ticks = 18 * 2;
        var halfTicks = 9 * 2;
        for (var i = 0; i <= ticks; i++) {
            var height = i == halfTicks ? standardDimension * .002 : standardDimension * .002;
            var width = i == halfTicks ? normalizedWidth : .3;
            var degrees = (i - halfTicks) * 10 / 2;

            ctx.fillStyle = color;
            ctx.fillRect(-standardDimension * width / 2, standardDimension * dimensionPerDegree * degrees, standardDimension * width, height)

            var rectWidth = standardDimension * .2;
            ctx.font = (standardDimension * .04) + "px Futura";
            ctx.textAlign = "center";
            ctx.textBaseline = "middle";
            var labelText = -1 * degrees;
            ctx.fillText(labelText,
                -standardDimension * width / 2 - (rectWidth / 2),
                standardDimension * dimensionPerDegree * degrees,
                rectWidth);
            ctx.fillText(labelText,
                standardDimension * width / 2 + (rectWidth / 2),
                standardDimension * dimensionPerDegree * degrees,
                rectWidth);
        }
        ctx.restore();

        // arrow
        var lineWidth = .003;
        ctx.fillStyle = color;
        ctx.fillRect(-standardDimension * .1, -(standardDimension * lineWidth) / 2, standardDimension * .2, standardDimension * lineWidth);
        ctx.fillRect(-(standardDimension * lineWidth) / 2, -standardDimension * .05, lineWidth * standardDimension, standardDimension * .1);
    }

    function SensorDisplayView() {
        this.element = $("

");
        this.attitude = new AttitudeIndicator();
    };

    SensorDisplayView.prototype.recreateCanvas = function() {
        var c = $("<canvas></canvas>");
        this.element.empty().append(c);
        c[0].width = $(window).width();
        c[0].height = $(window).height();
        this.ctx = c[0].getContext('2d');

    }

    SensorDisplayView.prototype.draw = function() {
        var width = this.element.width();
        var height = this.element.height();
        var aspect = width / height;

        var scale = Math.min(width, height) / standardDimension;

        this.ctx.clearRect(0, 0, width, height);
        this.ctx.fillStyle = "#000";
        this.ctx.fillRect(0,0,width,height);

        this.ctx.save();

        this.ctx.translate(width / 2, height / 2);
        this.ctx.scale(scale, scale);

        this.attitude.draw(this.ctx, this.state.euler.roll, this.state.euler.pitch, aspect);

        this.ctx.restore();
    }

    SensorDisplayView.prototype.attachListeners = function () {
        var self = this;
        $(window).resize(function() { self.recreateCanvas(); })
        this.recreateCanvas();
    };

    SensorDisplayView.prototype.setState = function(value) {
        this.state = value;
        this.draw();
        // this.element.find(".lat").html(value);
    };

    function SensorDisplay(messageSource) {
        this.messageSource = messageSource;
    };

    SensorDisplay.prototype.loadView = function() {
        this.view = new SensorDisplayView();
        this.view.attachListeners();
    };

    SensorDisplay.prototype.viewWillAppear = function() {
        this.messageSource.setDelegate(this);
    };

    SensorDisplay.prototype.viewWillDisappear = function() {
        this.messageSource.setDelegate(null);
        this.view.detachListeners()
        this.view = null;
    };

    SensorDisplay.prototype.viewDidAppear = function() {
        this.messageSource.connect();
    }

    SensorDisplay.prototype.onMessage = function(m) {
        this.view.setState(m);
    };

    var d = new SensorDisplay(new app.MessageSource());
    d.loadView();
    d.viewWillAppear();

    var state = 0;
    setInterval(function() {
        state += .5;
        d.onMessage({
            euler: {
                pitch: 20 * Math.sin(state / 15),
                roll: 60 * Math.cos(state / 30)
            }
        });
    }, 50);

    $(".global-wrapper").append(d.view.element);

    d.viewDidAppear();
});<|endoftext|>