<commit_before>/* jshint expr: true */
import Ember from 'ember';
import layout from '../templates/components/power-select-tree';
const { get, set, computed, A, Component } = Ember;

export default Component.extend({
  layout,
  currentOptions: computed('treeOptions.[]', function() {
    // TODO if all leaf of a tree are selected check the parent node
    const treeOptions = get(this, 'treeOptions');
    return treeOptions
      .map(o => this._collapsableOption(o))
      .map(o => this._buildPath(o));
  }),

  __selectedOptions: computed('selectedOptions.[]', 'currentOptions.[]', function() {
    const newOpts = A();
    const setPath = o => {
      if (A(get(this, 'selectedOptions')).isAny('key', get(o, 'key'))) {
        set(o, 'path', get(o, 'path'));
        set(o, 'isChecked', true);
        newOpts.pushObject(o);
      }
    };

    A(get(this, 'currentOptions')).forEach(o => this._traverseTree(o, setPath));
    return newOpts;
  }),
  // TODO: property that groups selectedOptions by path

  _buildPath(node, currPath = []) {
    if (!get(node, 'nodeName')) {
      set(node, 'path', currPath.join(' > '));
    } else {
      currPath.push(node.nodeName);
      get(node, 'options').forEach(o => this._buildPath(o, currPath));
      currPath = [];
    }

    return node;
  },

  _collapsableOption(opt) {
    const isSelectable = get(opt, 'isSelectable');
    const isChecked = get(opt, 'isChecked');
    const groupName = get(opt, 'groupName');
    const options = get(opt, 'options') || [];
    const isCollapsed = get(opt, 'isCollapsed') || true;
    if (groupName) {
      return {
        isSelectable,
        isCollapsed,
        isChecked,
        nodeName: groupName,
        options: options.map(o => this._collapsableOption(o))
      };
    }

    set(opt, 'isSelectable', true);
    return opt;
  },

  _getLeaves(root, leaves = A()) {
    (get(root, 'options') || A()).forEach(
      o => !o.nodeName ? leaves.pushObject(o) : this._getLeaves(o, leaves)
    );
    return leaves;
  },

  _traverseTree(root, func) {
    func(root);
    const options = A(get(root, 'options'));
    if (options.length) {
      options.forEach(o => this._traverseTree(o, func));
    }
  },

  actions: {
    onToggleGroup(nodeOrLeaf) {
      const selectedOptions = A(get(this, 'selectedOptions'));
      if (nodeOrLeaf.nodeName) {
        return set(nodeOrLeaf, 'isCollapsed', !get(nodeOrLeaf, 'isCollapsed'));
      }

      const isLeafChecked = get(nodeOrLeaf, 'isChecked');
      if (isLeafChecked) {
        selectedOptions.removeObject(nodeOrLeaf);
      } else {
        selectedOptions.pushObject(nodeOrLeaf);
      }
      set(nodeOrLeaf, 'isChecked', !isLeafChecked);
      set(this, 'selectedOptions', selectedOptions);
    },
    handleChecked(nodeOrLeaf) {
      const newVal = !get(nodeOrLeaf, 'isChecked');
      const setChecked = node => set(node, 'isChecked', newVal);
      const selectedOptions = A(get(this, 'selectedOptions'));
      const leaves = this._getLeaves(nodeOrLeaf);

      this._traverseTree(nodeOrLeaf, setChecked);

      if (nodeOrLeaf.nodeName) {
        !newVal ?
          selectedOptions.removeObjects(leaves) :
          selectedOptions.pushObjects(leaves);
      } else {
        !newVal ?
          selectedOptions.removeObject(nodeOrLeaf) : // TODO is not removed beacuse object now has 'path'
          selectedOptions.pushObject(nodeOrLeaf);
      }
      set(this, 'selectedOptions', selectedOptions);
    }
  }
});
<commit_msg>FIX: correctly remove objects<commit_after>/* jshint expr: true */
import Ember from 'ember';
import layout from '../templates/components/power-select-tree';
const { get, set, computed, A, Component } = Ember;

export default Component.extend({
  layout,
  currentOptions: computed('treeOptions.[]', function() {
    // TODO if all leaf of a tree are selected check the parent node
    const treeOptions = get(this, 'treeOptions');
    return treeOptions
      .map(o => this._collapsableOption(o))
      .map(o => this._buildPath(o));
  }),

  __selectedOptions: computed('selectedOptions.[]', 'currentOptions.[]', function() {
    const newOpts = A();
    const setPath = o => {
      if (A(get(this, 'selectedOptions')).isAny('key', get(o, 'key'))) {
        set(o, 'path', get(o, 'path'));
        set(o, 'isChecked', true);
        newOpts.pushObject(o);
      }
    };

    A(get(this, 'currentOptions')).forEach(o => this._traverseTree(o, setPath));
    return newOpts;
  }),
  // TODO: property that groups selectedOptions by path

  _buildPath(node, currPath = []) {
    if (!get(node, 'nodeName')) {
      set(node, 'path', currPath.join(' > '));
    } else {
      currPath.push(node.nodeName);
      get(node, 'options').forEach(o => this._buildPath(o, currPath));
      currPath = [];
    }

    return node;
  },

  _collapsableOption(opt) {
    const isSelectable = get(opt, 'isSelectable');
    const isChecked = get(opt, 'isChecked');
    const groupName = get(opt, 'groupName');
    const options = get(opt, 'options') || [];
    const isCollapsed = get(opt, 'isCollapsed') || true;
    if (groupName) {
      return {
        isSelectable,
        isCollapsed,
        isChecked,
        nodeName: groupName,
        options: options.map(o => this._collapsableOption(o))
      };
    }

    set(opt, 'isSelectable', true);
    return opt;
  },

  _getLeaves(root, leaves = A()) {
    (get(root, 'options') || A()).forEach(
      o => !o.nodeName ? leaves.pushObject(o) : this._getLeaves(o, leaves)
    );
    return leaves;
  },

  _traverseTree(root, func) {
    func(root);
    const options = A(get(root, 'options'));
    if (options.length) {
      options.forEach(o => this._traverseTree(o, func));
    }
  },

  // onTreeSelectionChange() {
  //   return get(this, 'onTreeSelectionChange')(get(this, '__selectedOptions'));
  // },

  actions: {
    onToggleGroup(nodeOrLeaf) {
      const selectedOptions = A(get(this, 'selectedOptions'));
      const nodeKey = get(nodeOrLeaf, 'key');
      if (nodeOrLeaf.nodeName) {
        return set(nodeOrLeaf, 'isCollapsed', !get(nodeOrLeaf, 'isCollapsed'));
      }

      const isLeafChecked = get(nodeOrLeaf, 'isChecked');
      if (isLeafChecked) {
        selectedOptions.removeObject(selectedOptions.findBy('key', nodeKey));
      } else {
        selectedOptions.pushObject(nodeOrLeaf);
      }
      set(nodeOrLeaf, 'isChecked', !isLeafChecked);
      // this.onTreeSelectionChange();
      set(this, 'selectedOptions', selectedOptions);
    },
    handleChecked(nodeOrLeaf) {
      const newVal = !get(nodeOrLeaf, 'isChecked');
      const setChecked = node => set(node, 'isChecked', newVal);
      const selectedOptions = A(get(this, 'selectedOptions'));
      const nodeKey = get(nodeOrLeaf, 'key');
      const leaves = this._getLeaves(nodeOrLeaf);

      this._traverseTree(nodeOrLeaf, setChecked);

      if (nodeOrLeaf.nodeName) {
        !newVal ?
          leaves.forEach(l => selectedOptions.removeObject(selectedOptions.findBy('key', get(l, 'key')))) :
          selectedOptions.pushObjects(leaves);
      } else {
        !newVal ?
          selectedOptions.removeObject(selectedOptions.findBy('key', nodeKey)) :
          selectedOptions.pushObject(nodeOrLeaf);
      }
      // this.onTreeSelectionChange();
      set(this, 'selectedOptions', selectedOptions);
    }
  }
});
<|endoftext|>


<commit_before>
var IFOBLOCKTYPE = {
  MapInformation: 0,
  Object: 1,
  NPC: 2,
  Building: 3,
  Sound: 4,
  Effect: 5,
  Animation: 6,
  WaterPatch: 7,
  MonsterSpawn: 8,
  WaterPlane: 9,
  WarpPoint: 10,
  CollisionObject: 11,
  EventObject: 12
};
function IFOData() {
  this.buildings = [];
  this.objects = [];
}
var IFOLoader = {};
IFOLoader.load = function(path, callback) {
  ROSELoader.load(path, function(b) {
    var data = new IFOData();

    var blockCount = b.readUint32();
    function readMapObject() {
      var obj = {};
      obj.name = b.readByteStr();
      obj.warpId = b.readUint16();
      obj.eventId = b.readUint16();
      obj.objectType = b.readUint32();
      obj.objectId = b.readUint32();
      /*obj.mapPosition*/ b.skip(2*4);
      obj.rotation = b.readQuat();
      obj.position = b.readVector3().multiplyScalar(ZZ_SCALE_IN);
      obj.scale = b.readVector3();
      return obj;
    }
    function readBlock(blockType) {
      if (blockType === IFOBLOCKTYPE.Building) {
        var entryCount = b.readUint32();
        for (var i = 0; i < entryCount; ++i) {
          var obj = readMapObject();
          data.buildings.push(obj);
        }
      } else if (blockType === IFOBLOCKTYPE.Object) {
        var entryCount = b.readUint32();
        for (var i = 0; i < entryCount; ++i) {
          var obj = readMapObject();
          data.objects.push(obj);
        }
      }
    }
    for (var i = 0; i < blockCount; ++i) {
      var blockType = b.readUint32();
      var blockOffset = b.readUint32();
      var nextBlockPos = b.tell();
      b.seek(blockOffset);
      readBlock(blockType);
      b.seek(nextBlockPos);
    }

    callback(data);
  });
};
<commit_msg>Update ifo.js to read all blocks<commit_after>/**
 * @constructor
 * @property {MapInfo.Object[]} objects
 * @property {MapInfo.Npc[]} npcs
 * @property {MapInfo.Building[]} buildings
 * @property {MapInfo.Sound[]} sounds
 * @property {MapInfo.Effect[]} effects
 * @property {MapInfo.Animation[]} animations
 * @property {MapInfo.WaterPatches} waterPatches
 * @property {MapInfo.MonsterSpawn[]} monsterSpawns
 * @property {MapInfo.WaterPlane[]} waterPlanes
 * @property {MapInfo.WarpPoint[]} warps
 * @property {MapInfo.Collision[]} collisions
 * @property {MapInfo.Event[]} events
 */
var MapInfo = function() {
  this.objects = [];
  this.npcs = [];
  this.buildings = [];
  this.sounds = [];
  this.effects = [];
  this.animations = [];
  this.monsterSpawns = [];
  this.waterPlanes = [];
  this.warps = [];
  this.collisions = [];
  this.events = [];
};

/**
 * @enum {Number}
 * @readonly
 */
MapInfo.BLOCK_TYPE = {
  INFO: 0,
  OBJECT: 1,
  NPC: 2,
  BUILDING: 3,
  SOUND: 4,
  EFFECT: 5,
  ANIMATION: 6,
  WATER_PATCH: 7,
  MONSTER_SPAWN: 8,
  WATER_PLANE: 9,
  WARP_POINT: 10,
  COLLISION_OBJECT: 11,
  EVENT_OBJECT: 12
};

/**
 * @constructor
 * @property {String} name
 * @property {Number} warpId
 * @property {Number} eventId
 * @property {Number} objectType
 * @property {Number} objectId
 * @property {THREE.Vector2} mapPosition
 * @property {THREE.Quaternion} rotation
 * @property {THREE.Vector3} position
 * @property {THREE.Vector3} scale
 */
MapInfo.MapObject = function() {
};

/**
 * @constructor
 * @extends {MapInfo.MapObject}
 */
MapInfo.Object = function() {
};

/**
 * @constructor
 * @extends {MapInfo.MapObject}
 * @property {Number} aiIndex
 * @property {String} conFilePath
 */
MapInfo.Npc = function() {
};

/**
 * @constructor
 * @extends {MapInfo.MapObject}
 */
MapInfo.Building = function() {
};

/**
 * @constructor
 * @extends {MapInfo.MapObject}
 * @property {String} filePath
 * @property {Number} range
 * @property {Number} interval
 */
MapInfo.Sound = function() {
};

/**
 * @constructor
 * @extends {MapInfo.MapObject}
 * @property {String} filePath
 */
MapInfo.Effect = function() {
};

/**
 * @constructor
 * @extends {MapInfo.MapObject}
 */
MapInfo.Animation = function() {
};

/**
 * @constructor
 * @extends {MapInfo.MapObject}
 * @property {Number} width
 * @property {Number} height
 * @property {MapInfo.WaterPatches.Patch[]} patches
 */
MapInfo.WaterPatches = function() {
};

/**
 * @constructor
 * @property {Boolean} hasWater
 * @property {Number} height
 * @property {Number} type
 * @property {Number} id
 * @property {Number} unknown
 */
MapInfo.WaterPatches.Patch = function() {
};

/**
 * @constructor
 * @extends {MapInfo.MapObject}
 * @property {String} name
 * @property {MapInfo.MonsterSpawn.Spawn[]} normal
 * @property {MapInfo.MonsterSpawn.Spawn[]} tactical
 * @property {Number} interval
 * @property {Number} limit
 * @property {Number} range
 * @property {Number} tacticalPoints
 */
MapInfo.MonsterSpawn = function() {
};

/**
 * @constructor
 * @property {String} name
 * @property {Number} monster
 * @property {Number} count
 */
MapInfo.MonsterSpawn.Spawn = function() {
};

/**
 * @constructor
 * @property {THREE.Vector3} start
 * @property {THREE.Vector3} end
 */
MapInfo.WaterPlane = function() {
};

/**
 * @constructor
 * @extends {MapInfo.MapObject}
 */
MapInfo.WarpPoint = function() {
};

/**
 * @constructor
 * @extends {MapInfo.MapObject}
 */
MapInfo.Collision = function() {
};

/**
 * @constructor
 * @extends {MapInfo.MapObject}
 * @property {String} funcName
 * @property {String} conFilePath
 */
MapInfo.Event = function() {
};

/**
 * @param {BinaryReader} rh
 * @param {Object} object
 * @returns {Object}
 */
MapInfo.loadMapObject = function(rh, object) {
  object.name        = rh.readByteStr();
  object.warpId      = rh.readUint16();
  object.eventId     = rh.readUint16();
  object.objectType  = rh.readUint32();
  object.objectId    = rh.readUint32();
  object.mapPosition = rh.readIntVector2();
  object.rotation    = rh.readQuat();
  object.position    = rh.readVector3().multiplyScalar(ZZ_SCALE_IN);
  object.scale       = rh.readVector3();
  return object;
};

/**
 * @callback MapInfo~onLoad
 * @param {MapInfo} mapInfo
 */

/**
 * @param {String} path
 * @param {MapInfo~onLoad} callback
 */
MapInfo.load = function(path, callback) {
  ROSELoader.load(path, function(/** BinaryReader */rh) {
    var blocks, count, i, j, k, object, offset, pos, type;
    var data = new MapInfo();

    blocks = rh.readUint32();
    for (i = 0; i < blocks; ++i) {
      type   = rh.readUint32();
      offset = rh.readUint32();
      pos    = rh.tell();

      rh.seek(offset);
      if (type === MapInfo.BLOCK_TYPE.INFO) {
        // Unknown format
      } else if (type === MapInfo.BLOCK_TYPE.WATER_PATCH) {
        object = MapInfo.loadMapObject(rh, new MapInfo.WaterPatches());
        object.width  = rh.readUint32();
        object.height = rh.readUint32();

        for (j = 0; j < object.width * object.height; ++j) {
          var patch = new MapInfo.WaterPatches.Patch();
          patch.hasWater = rh.readUint8() !== 0;
          patch.height   = rh.readFloat();
          patch.type     = rh.readUint32();
          patch.id       = rh.readUint32();
          patch.unknown  = rh.readUint32();
          object.patches[j] = patch;
        }

        data.waterPatches = object;
      } else {
        if (type === MapInfo.BLOCK_TYPE.WATER_PLANE) {
          data.waterPlanes.waterSize = rh.readFloat();
        }

        var objects = rh.readUint32();
        for (j = 0; j < objects; ++j) {
          switch (type) {
          case MapInfo.BLOCK_TYPE.OBJECT:
            object = MapInfo.loadMapObject(rh, new MapInfo.Object());
            data.objects.push(object);
            break;
          case MapInfo.BLOCK_TYPE.NPC:
            object = MapInfo.loadMapObject(rh, new MapInfo.Npc());
            object.aiIndex = rh.readUint32();
            object.conFilePath = rh.readByteStr();
            data.npcs.push(object);
            break;
          case MapInfo.BLOCK_TYPE.BUILDING:
            object = MapInfo.loadMapObject(rh, new MapInfo.Building());
            data.buildings.push(object);
            break;
          case MapInfo.BLOCK_TYPE.SOUND:
            object = MapInfo.loadMapObject(rh, new MapInfo.Sound());
            object.filePath = rh.readByteStr();
            object.range = rh.readUint32();
            object.interval = rh.readUint32();
            data.sounds.push(object);
            break;
          case MapInfo.BLOCK_TYPE.EFFECT:
            object = MapInfo.loadMapObject(rh, new MapInfo.Effect());
            object.filePath = rh.readByteStr();
            data.effects.push(object);
            break;
          case MapInfo.BLOCK_TYPE.ANIMATION:
            object = MapInfo.loadMapObject(rh, new MapInfo.Animation());
            data.animations.push(object);
            break;
          case MapInfo.BLOCK_TYPE.MONSTER_SPAWN:
            object = MapInfo.loadMapObject(rh, new MapInfo.MonsterSpawn());
            object.name = rh.readByteStr();

            count = rh.readUint32();
            for (k = 0; k < count; ++k) {
              var spawn = new MapInfo.MonsterSpawn.Spawn();
              spawn.name = rh.readByteStr();
              spawn.monster = rh.readUint32();
              spawn.count = rh.readUint32();
              object.normal.push(spawn);
            }

            count = rh.readUint32();
            for (k = 0; k < count; ++k) {
              var spawn = new MapInfo.MonsterSpawn.Spawn();
              spawn.name = rh.readByteStr();
              spawn.monster = rh.readUint32();
              spawn.count = rh.readUint32();
              object.tactical.push(spawn);
            }

            object.interval = rh.readUint32();
            object.limit = rh.readUint32();
            object.range = rh.readUint32();
            object.tacticalPoints = rh.readUint32();
            data.monsterSpawns.push(object);
            break;
          case MapInfo.BLOCK_TYPE.WATER_PLANE:
            object = new MapInfo.WaterPlane();
            object.start = rh.readVector3();
            object.end = rh.readVector3();
            data.waterPlanes.push(object);
            break;
          case MapInfo.BLOCK_TYPE.WARP_POINT:
            object = MapInfo.loadMapObject(rh, new MapInfo.WarpPoint());
            data.warps.push(object);
            break;
          case MapInfo.BLOCK_TYPE.COLLISION_OBJECT:
            object = MapInfo.loadMapObject(rh, new MapInfo.Collision());
            data.collisions.push(object);
            break;
          case MapInfo.BLOCK_TYPE.EVENT_OBJECT:
            object = MapInfo.loadMapObject(rh, new MapInfo.Event());
            object.funcName = rh.readByteStr();
            object.conFilePath = rh.readByteStr();
            data.events.push(object);
            break;
          default:
            break;
          }
        }
      }
      rh.seek(pos);
    }

    callback(data);
  });
};
<|endoftext|>


<commit_before>import Ember from 'ember';
import _ from 'lodash/lodash';

const {
  computed,
  observer
} = Ember;

const {
  sort,
  alias,
  bool
} = computed;

const { keys } = Object;

/**
  Sortable Filterable Table Component

  @class SortFilterTable
  @extends Ember.Component
*/
export default Ember.Component.extend({
  hasBlock: bool('template').readOnly(),

  /**
   Config: Signal if filter input field should be included

   @property filterable
   @returns Bool
   @public
  */
  filterable: true,

  /**
    Map raw data in to Ember A and Ember Objects

    @property _rows
    @returns Array
    @private
  */
  _rows: computed('table.rows', function() {
    let rows = this.get('table.rows');
    return Ember.A(rows.map((row) => {
      return Ember.Object.create(row);
    }));
  }),

  /**
    Array of properties to determine sort order

    @property _sortOrder
    @returns Array
    @private
  */
  _sortOrder: Ember.A([]),

  /**
    Rows sorted by specified sort order

    @property sortedRows
    @returns Array
    @public
  */
  sortedRows: sort('_rows', '_sortOrder'),

  /**
   Extract column headers from keys

   @property headers
   @returns Array
   @public
  */
  headers: computed('sortedRows', function() {
    return Ember.A(keys(this.get('sortedRows.firstObject')));
  }),

  /**
    Store separator for headers

    @property _separator
    @returns String
    @private
  */
  _separator: null,

  /**
    Replaces hyphens or underscores with spaces (used to prettify headers)

    @method _handleSeparators
    @private
  */
  _handleSeparators(str) {
    if ((/-/).test(str)) {
      //hyphen
      this.set('_separator', '-');
      return str.replace(/-/, ' ');
    } else if ((/_/).test(str)) {
      //underscore
      this.set('_separator', '_');
      return str.replace(/_/g, ' ');
    } else if ((/ /).test(str)) {
      //space
      this.set('_separator', ' ');
      return str;
    } else {
      return str;
    }
  },

  /**
    Assemble pretty labels from column headers/keys

    @property labels
    @returns Array
    @public

  */
  labels: computed('headers', function() {
    let headers = this.get('headers');
    return Ember.A(headers.map((item) => {
      return Ember.Object.create({
        _key: item,
        name: this._handleSeparators(item),
        sort: 'null'
      });
    }));
  }),

  /**
    Signal wether current sort param is asc or desc

    @property _ascending
    @type Bool
    @private
  */
  _ascending: true,

  /**
    Calculated total number of columns (colspan)

    @property totalColumns
    @returns Number
    @public
  */
  totalColumns: alias('labels.length'),

  /**
    Filter by search param from input

    @method _applyFilter
    @private
  */
  _applyFilter: observer('filter', function() {
    let rows = this.get('sortedRows');

    //case insensitive
    let filterQuery = (this.get('filter')).toLowerCase();

    rows.filter((row) => {
      let values = _.values(row);
      let filterExp = new RegExp(filterQuery);
      return row.set('_filtered', !(filterExp).test((values.join(',')).toLowerCase()));
    });

  }),

  actions: {
    /**
      Toggle sort by property asc/desc

      @method sortBy
    */
    sortBy(label) {
      let header = label.get('name').replace(/ /g, this.get('_separator'));
      let labels = this.get('labels');

      this.toggleProperty('_ascending');
      let direction = this.get('_ascending') ? 'asc' : 'desc';

      labels.setEach('sort', null);
      label.set('sort', direction);

      this.set('_sortOrder', [ header + ':' + direction ]);
    },

    /**
      Send values up to actions

      @method sendEditAction
    */
    sendEditAction(row, key, value, action) {
      if (this.get(action)) {
        this.sendAction(action, {
          'row' : row,
          'key' : key,
          'value' : value
        });
        row.toggleProperty('_editingRow');
      }
    },

    /**
      Display input field for editing

      @method
    */
    editValue(row, key) {
      let rows = this.get('_rows');
      rows.setEach('_editingRow', null);
      row.set('_editingRow', key);
    },
  }
});
<commit_msg>simplify _handleSeparators method for scalability<commit_after>import Ember from 'ember';
import _ from 'lodash/lodash';

const {
  computed,
  observer
} = Ember;

const {
  sort,
  alias,
  bool
} = computed;

const { keys } = Object;

/**
  Sortable Filterable Table Component

  @class SortFilterTable
  @extends Ember.Component
*/
export default Ember.Component.extend({
  hasBlock: bool('template').readOnly(),

  /**
   Config: Signal if filter input field should be included

   @property filterable
   @returns Bool
   @public
  */
  filterable: true,

  /**
    Map raw data in to Ember A and Ember Objects

    @property _rows
    @returns Array
    @private
  */
  _rows: computed('table.rows', function() {
    let rows = this.get('table.rows');
    return Ember.A(rows.map((row) => {
      return Ember.Object.create(row);
    }));
  }),

  /**
    Array of properties to determine sort order

    @property _sortOrder
    @returns Array
    @private
  */
  _sortOrder: Ember.A([]),

  /**
    Rows sorted by specified sort order

    @property sortedRows
    @returns Array
    @public
  */
  sortedRows: sort('_rows', '_sortOrder'),

  /**
   Extract column headers from keys

   @property headers
   @returns Array
   @public
  */
  headers: computed('sortedRows', function() {
    return Ember.A(keys(this.get('sortedRows.firstObject')));
  }),

  /**
    Store separator for headers

    @property _separator
    @returns String
    @private
  */
  _separator: null,

  /**
    Replaces hyphens or underscores with spaces (used to prettify headers)

    @method _handleSeparators
    @private
  */
  _handleSeparators(str) {
    let separator = str.match(/[-  _]/);
    if (separator && separator.length) {
      this.set('_separator', separator[0]);
      return str.replace(new RegExp(separator[0]), ' ');
    } else {
      return str;
    }
  },

  /**
    Assemble pretty labels from column headers/keys

    @property labels
    @returns Array
    @public

  */
  labels: computed('headers', function() {
    let headers = this.get('headers');
    return Ember.A(headers.map((item) => {
      return Ember.Object.create({
        _key: item,
        name: this._handleSeparators(item),
        sort: 'null'
      });
    }));
  }),

  /**
    Signal wether current sort param is asc or desc

    @property _ascending
    @type Bool
    @private
  */
  _ascending: true,

  /**
    Calculated total number of columns (colspan)

    @property totalColumns
    @returns Number
    @public
  */
  totalColumns: alias('labels.length'),

  /**
    Filter by search param from input

    @method _applyFilter
    @private
  */
  _applyFilter: observer('filter', function() {
    let rows = this.get('sortedRows');

    //case insensitive
    let filterQuery = (this.get('filter')).toLowerCase();

    rows.filter((row) => {
      let values = _.values(row);
      let filterExp = new RegExp(filterQuery);
      return row.set('_filtered', !(filterExp).test((values.join(',')).toLowerCase()));
    });

  }),

  actions: {
    /**
      Toggle sort by property asc/desc

      @method sortBy
    */
    sortBy(label) {
      let header = label.get('name').replace(/ /g, this.get('_separator'));
      let labels = this.get('labels');

      this.toggleProperty('_ascending');
      let direction = this.get('_ascending') ? 'asc' : 'desc';

      labels.setEach('sort', null);
      label.set('sort', direction);

      this.set('_sortOrder', [ header + ':' + direction ]);
    },

    /**
      Send values up to actions

      @method sendEditAction
    */
    sendEditAction(row, key, value, action) {
      if (this.get(action)) {
        this.sendAction(action, {
          'row' : row,
          'key' : key,
          'value' : value
        });
        row.toggleProperty('_editingRow');
      }
    },

    /**
      Display input field for editing

      @method
    */
    editValue(row, key) {
      let rows = this.get('_rows');
      rows.setEach('_editingRow', null);
      row.set('_editingRow', key);
    },
  }
});
<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Mixin.create({
  dropdownExpanded: false,

  dropdownToggleSelector: '.rl-dropdown-toggle',

  dropdownSelector: '.rl-dropdown',

  closingEventNamespace: 'rl-dropdown',

  closeOnEscape: true,

  actions: {
    toggleDropdown: function () {
      this.toggleProperty('dropdownExpanded');
    },

    openDropdown: function () {
      this.set('dropdownExpanded', true);
    },

    closeDropdown: function () {
      this.set('dropdownExpanded', false);
    }
  },

  manageClosingEvents: Ember.on('didInsertElement', Ember.observer('dropdownExpanded', function () {
    var namespace = this.get('closingEventNamespace');
    var clickEventName = 'click.'+ namespace;
    var escapeEventName = 'keydown.'+ namespace;
    var component = this;

    if (this.get('dropdownExpanded')) {

      /* Add clickout handler with 1ms delay, to allow opening the dropdown
       * by clicking e.g. a checkbox and binding to dropdownExpanded, without
       * having the handler close the dropdown immediately. */
      Ember.run.later(function() {
        Ember.$(document).bind(clickEventName, {component: component}, component.clickoutHandler);
      }, 1);

      if (this.get('closeOnEscape')) {
        Ember.$(document).bind(escapeEventName, {component: component}, component.escapeHandler);
      }
    } else {
      Ember.$(document).unbind(clickEventName, component.clickoutHandler);
      Ember.$(document).unbind(escapeEventName, component.escapeHandler);
    }
  })),

  unbindClosingEvents: Ember.on('willDestroyElement', function () {
    var namespace = this.get('closingEventNamespace');

    Ember.$(document).unbind('click.'+ namespace, this.clickoutHandler);
    Ember.$(document).unbind('keydown.'+ namespace, this.escapeHandler);
  }),

  clickoutHandler: function (event) {
    var component = event.data.component;
    var $c = component.$();
    var $target = Ember.$(event.target);

    /* There is an issue when the click triggered a dom change in the
     * dropdown that unloaded the target element. The ancestry of the target
     * can no longer be determined. We can check if html is still an ancestor
     * to determine if this has happened. The safe option then seems to be to
     * not close the dropdown, as occasionaly not closing the dropdown when it
     * should have closed, seems to be less bad for usability than occasionaly
     * closing the dropdown when it should not have closed.
     */
    if(component.get('dropdownExpanded') && $target.closest('html').length !== 0 &&
      !($target.closest($c.find(component.get('dropdownToggleSelector'))).length ||
        $target.closest($c.find(component.get('dropdownSelector'))).length)
    ) {
      component.set('dropdownExpanded', false);
    }
  },

  escapeHandler: function (event) {
    if (event.keyCode === 27) {
      event.data.component.set('dropdownExpanded', false);
    }
  }
});
<commit_msg>Adds touch events to document so the dropdown closes when tapping outside<commit_after>import Ember from 'ember';

export default Ember.Mixin.create({
  dropdownExpanded: false,

  dropdownToggleSelector: '.rl-dropdown-toggle',

  dropdownSelector: '.rl-dropdown',

  closingEventNamespace: 'rl-dropdown',

  closeOnEscape: true,

  actions: {
    toggleDropdown: function () {
      this.toggleProperty('dropdownExpanded');
    },

    openDropdown: function () {
      this.set('dropdownExpanded', true);
    },

    closeDropdown: function () {
      this.set('dropdownExpanded', false);
    }
  },

  manageClosingEvents: Ember.on('didInsertElement', Ember.observer('dropdownExpanded', function () {
    var namespace = this.get('closingEventNamespace');
    var clickEventName = 'click.'+ namespace;
    var touchEventName = 'touchstart.'+ namespace;
    var escapeEventName = 'keydown.'+ namespace;
    var component = this;

    if (this.get('dropdownExpanded')) {

      /* Add clickout handler with 1ms delay, to allow opening the dropdown
       * by clicking e.g. a checkbox and binding to dropdownExpanded, without
       * having the handler close the dropdown immediately. */
      Ember.run.later(function() {
        Ember.$(document).bind(clickEventName, {component: component}, component.clickoutHandler);
        Ember.$(document).bind(touchEventName, {component: component}, component.clickoutHandler);
      }, 1);

      if (this.get('closeOnEscape')) {
        Ember.$(document).bind(escapeEventName, {component: component}, component.escapeHandler);
      }
    } else {
      Ember.$(document).unbind(clickEventName, component.clickoutHandler);
      Ember.$(document).unbind(touchEventName, component.clickoutHandler);
      Ember.$(document).unbind(escapeEventName, component.escapeHandler);
    }
  })),

  unbindClosingEvents: Ember.on('willDestroyElement', function () {
    var namespace = this.get('closingEventNamespace');

    Ember.$(document).unbind('click.'+ namespace, this.clickoutHandler);
    Ember.$(document).unbind('touchstart.'+ namespace, this.clickoutHandler);
    Ember.$(document).unbind('keydown.'+ namespace, this.escapeHandler);
  }),

  clickoutHandler: function (event) {
    var component = event.data.component;
    var $c = component.$();
    var $target = Ember.$(event.target);

    /* There is an issue when the click triggered a dom change in the
     * dropdown that unloaded the target element. The ancestry of the target
     * can no longer be determined. We can check if html is still an ancestor
     * to determine if this has happened. The safe option then seems to be to
     * not close the dropdown, as occasionaly not closing the dropdown when it
     * should have closed, seems to be less bad for usability than occasionaly
     * closing the dropdown when it should not have closed.
     */
    if(component.get('dropdownExpanded') && $target.closest('html').length !== 0 &&
      !($target.closest($c.find(component.get('dropdownToggleSelector'))).length ||
        $target.closest($c.find(component.get('dropdownSelector'))).length)
    ) {
      component.set('dropdownExpanded', false);
    }
  },

  escapeHandler: function (event) {
    if (event.keyCode === 27) {
      event.data.component.set('dropdownExpanded', false);
    }
  }
});
<|endoftext|>


<commit_before>/* globals chrome, console, XMLHttpRequest, Image, document, setTimeout, navigator */
/* globals loadSelector, analytics, communication, catcher, makeUuid */
window.main = (function () {
  let exports = {};

  const pasteSymbol = (window.navigator.platform.match(/Mac/i)) ? "\u2318" : "Ctrl";
  const { sendEvent } = analytics;

  let manifest = chrome.runtime.getManifest();
  let backend;

  exports.setBackend = function (newBackend) {
    backend = newBackend;
    backend = backend.replace(/\/*$/, "");
  };

  exports.getBackend = function () {
    return backend;
  };

  for (let permission of manifest.permissions) {
    if (permission.search(/^https?:\/\//i) != -1) {
      exports.setBackend(permission);
      break;
    }
  }

  chrome.runtime.onInstalled.addListener(function () {
  });

  chrome.browserAction.onClicked.addListener(function(tab) {
    if(tab.url.match(/about:(newtab|blank)/i)) {
     chrome.tabs.update({url: backend + "/shots"});
    }
    else {
    sendEvent("start-shot", "toolbar-pageshot-button");
    catcher.watchPromise(loadSelector());
  }
  });

  chrome.contextMenus.create({
    id: "create-pageshot",
    title: "Create Page Shot",
    contexts: ["page"]
  }, () => {
    if (chrome.runtime.lastError) {
      catcher.unhandled(new Error(chrome.runtime.lastError.message));
    }
  });

  chrome.contextMenus.onClicked.addListener(catcher.watchFunction((info, tab) => {
    if (! tab) {
      // Not in a page/tab context, ignore
      return;
    }
    sendEvent("start-shot", "context-menu");
    catcher.watchPromise(loadSelector());
  }));

  communication.register("sendEvent", (...args) => {
    catcher.watchPromise(sendEvent(...args));
    // We don't wait for it to complete:
    return null;
  });

  communication.register("openMyShots", () => {
    chrome.tabs.create({url: backend + "/shots"});
  });

  communication.register("openShot", ({url, copied}) => {
    if (copied) {
      const id = makeUuid();
      chrome.notifications.create(id, {
        type: "basic",
        iconUrl: "../icons/clipboard-32.png",
        title: "Link Copied",
        message: "The link to your shot has been copied to the clipboard. Press "
        + pasteSymbol + "-V to paste."
      });
    }
  });

  return exports;
})();
<commit_msg>Added an event for about:newtab navigation, fixed up indentation<commit_after>/* globals chrome, console, XMLHttpRequest, Image, document, setTimeout, navigator */
/* globals loadSelector, analytics, communication, catcher, makeUuid */
window.main = (function () {
  let exports = {};

  const pasteSymbol = (window.navigator.platform.match(/Mac/i)) ? "\u2318" : "Ctrl";
  const { sendEvent } = analytics;

  let manifest = chrome.runtime.getManifest();
  let backend;

  exports.setBackend = function (newBackend) {
    backend = newBackend;
    backend = backend.replace(/\/*$/, "");
  };

  exports.getBackend = function () {
    return backend;
  };

  for (let permission of manifest.permissions) {
    if (permission.search(/^https?:\/\//i) != -1) {
      exports.setBackend(permission);
      break;
    }
  }

  chrome.runtime.onInstalled.addListener(function () {
  });

  chrome.browserAction.onClicked.addListener(function(tab) {
    if(tab.url.match(/about:(newtab|blank)/i)) {
      sendEvent("goto-myshots", "about-newtab");
      chrome.tabs.update({url: backend + "/shots"});
    } else {
      sendEvent("start-shot", "toolbar-pageshot-button");
      catcher.watchPromise(loadSelector());
    }
  });

  chrome.contextMenus.create({
    id: "create-pageshot",
    title: "Create Page Shot",
    contexts: ["page"]
  }, () => {
    if (chrome.runtime.lastError) {
      catcher.unhandled(new Error(chrome.runtime.lastError.message));
    }
  });

  chrome.contextMenus.onClicked.addListener(catcher.watchFunction((info, tab) => {
    if (! tab) {
      // Not in a page/tab context, ignore
      return;
    }
    sendEvent("start-shot", "context-menu");
    catcher.watchPromise(loadSelector());
  }));

  communication.register("sendEvent", (...args) => {
    catcher.watchPromise(sendEvent(...args));
    // We don't wait for it to complete:
    return null;
  });

  communication.register("openMyShots", () => {
    chrome.tabs.create({url: backend + "/shots"});
  });

  communication.register("openShot", ({url, copied}) => {
    if (copied) {
      const id = makeUuid();
      chrome.notifications.create(id, {
        type: "basic",
        iconUrl: "../icons/clipboard-32.png",
        title: "Link Copied",
        message: "The link to your shot has been copied to the clipboard. Press "
        + pasteSymbol + "-V to paste."
      });
    }
  });

  return exports;
})();
<|endoftext|>


<commit_before>(function($){
    var actionLabels = {
        "opened"   : "label-warning",
        "closed"   : "label-danger",
        "accepted" : "label-success",
    };

    $(document).ready(function(){
        var projects = config.getActiveProjects();
        var ajaxProjectEvents = [];
        var allProjectEvents = [];

        // remove notification count when show popup
        // because) can not use both chrome.browserAction.onClicked and popup
        // https://developer.chrome.com/extensions/browserAction.html#event-onClicked
        chrome.browserAction.setBadgeText({text: ""});

        var currentTime = new Date();
        var newMilliSeconds = config.getNewMarkMinute() * 60 * 1000;
        $.each(config.getNotifiedHistories(), function(index, projectEvent){
            var li = $("<li/>");

            if(currentTime.getTime() - newMilliSeconds < (new Date(projectEvent.notified_at)).getTime()){
                li.addClass("new");
            }

            if(projectEvent.target_type == "Issue"){
                $("<span/>").addClass("glyphicon glyphicon-warning-sign").attr({title: "Issue"}).appendTo(li);
            } else if(projectEvent.target_type == "MergeRequest"){
                $("<span/>").addClass("glyphicon glyphicon-upload").attr({title: "MergeRequest"}).appendTo(li);
            } else if(projectEvent.target_type == "Milestone"){
                $("<span/>").addClass("glyphicon glyphicon-calendar").attr({title: "Milestone"}).appendTo(li);
            }

            var projectUrl = config.getGitlabPath() + projectEvent.project_name;
            var eventUrl = gitlab.getEventUrl(projectEvent);

            $("<span/>").text(" ").appendTo(li);
            $("<a/>").attr({href: projectUrl, target: "_blank"}).text("["+ projectEvent.project_name +"]").appendTo(li);
            $("<span/>").text(" ").appendTo(li);
            $("<a/>").attr({
                href:                "#",
                "data-project-name": projectEvent.project_name,
                "data-target-type" : projectEvent.target_type,
                "data-target-id"   : projectEvent.target_id
            }).addClass("eventLink").text("#" + projectEvent.target_id + " " + projectEvent.target_title).appendTo(li);
            $("<span/>").text(" ").appendTo(li);
            $("<span/>").addClass("label").addClass(actionLabels[projectEvent.action_name]).text(projectEvent.action_name).appendTo(li);
            $("<span/>").text(" ").appendTo(li);
            $("<abbr/>").addClass("timeago").attr({title: projectEvent.notified_at}).appendTo(li);

            li.appendTo($("#notifyHistories"));
        });

        $("abbr.timeago").timeago();

        $("a.eventLink").click(function(){
            // open event page
            gitlab.getEventInternalUrl({
                project_name: $(this).attr("data-project-name"),
                target_type:  $(this).attr("data-target-type"),
                target_id:    $(this).attr("data-target-id")
            }, function(url){
                chrome.tabs.create({url: url});
            });
        });
    });

})(jQuery);
<commit_msg>[bugfix] Uncaught TypeError: Cannot read property 'name' of undefined<commit_after>(function($){
    var actionLabels = {
        "opened"   : "label-warning",
        "closed"   : "label-danger",
        "accepted" : "label-success",
    };

    $(document).ready(function(){
        var projects = config.getActiveProjects();
        var ajaxProjectEvents = [];
        var allProjectEvents = [];

        // remove notification count when show popup
        // because) can not use both chrome.browserAction.onClicked and popup
        // https://developer.chrome.com/extensions/browserAction.html#event-onClicked
        chrome.browserAction.setBadgeText({text: ""});

        var currentTime = new Date();
        var newMilliSeconds = config.getNewMarkMinute() * 60 * 1000;
        $.each(config.getNotifiedHistories(), function(index, projectEvent){
            var li = $("<li/>");

            if(currentTime.getTime() - newMilliSeconds < (new Date(projectEvent.notified_at)).getTime()){
                li.addClass("new");
            }

            if(projectEvent.target_type == "Issue"){
                $("<span/>").addClass("glyphicon glyphicon-warning-sign").attr({title: "Issue"}).appendTo(li);
            } else if(projectEvent.target_type == "MergeRequest"){
                $("<span/>").addClass("glyphicon glyphicon-upload").attr({title: "MergeRequest"}).appendTo(li);
            } else if(projectEvent.target_type == "Milestone"){
                $("<span/>").addClass("glyphicon glyphicon-calendar").attr({title: "Milestone"}).appendTo(li);
            }

            var projectUrl = config.getGitlabPath() + projectEvent.project_name;

            $("<span/>").text(" ").appendTo(li);
            $("<a/>").attr({href: projectUrl, target: "_blank"}).text("["+ projectEvent.project_name +"]").appendTo(li);
            $("<span/>").text(" ").appendTo(li);
            $("<a/>").attr({
                href:                "#",
                "data-project-name": projectEvent.project_name,
                "data-target-type" : projectEvent.target_type,
                "data-target-id"   : projectEvent.target_id
            }).addClass("eventLink").text("#" + projectEvent.target_id + " " + projectEvent.target_title).appendTo(li);
            $("<span/>").text(" ").appendTo(li);
            $("<span/>").addClass("label").addClass(actionLabels[projectEvent.action_name]).text(projectEvent.action_name).appendTo(li);
            $("<span/>").text(" ").appendTo(li);
            $("<abbr/>").addClass("timeago").attr({title: projectEvent.notified_at}).appendTo(li);

            li.appendTo($("#notifyHistories"));
        });

        $("abbr.timeago").timeago();

        $("a.eventLink").click(function(){
            // open event page
            gitlab.getEventInternalUrl({
                project_name: $(this).attr("data-project-name"),
                target_type:  $(this).attr("data-target-type"),
                target_id:    $(this).attr("data-target-id")
            }, function(url){
                chrome.tabs.create({url: url});
            });
        });
    });

})(jQuery);
<|endoftext|>


<commit_before>var config = require('config');
var mapModule = require('map');
var plugins = require('./leaflet_plugins');
var polyUtil = require('./polyline_encoded.js');
var routeboxer = require('./leaflet_routeboxer.js');
var leaflet_label = require('./leaflet_label/leaflet.label-src.js');
var collision = require('./leaflet_layergroup_collision.js');
var session = require('session');

var center = config.geocode().center.split(',').map(parseFloat)
if (config.map_provider && config.map_provider() !== 'AmigoCloud') {
  L.mapbox.accessToken = config.mapbox_access_token();
}

module.exports = function(el) {
  var map, realtime, southWest, northEast, blurLayer;
  localStorage.removeItem('dataplan');
  if (config.map_provider && config.map_provider() === 'AmigoCloud') {
    southWest = L.latLng(35.946877085397,-123.480610897013);
    northEast = L.latLng(40.763279543715,-118.789317362500);
    map = (new L.amigo.map(el, {
      amigoLogo: 'right',
      loadAmigoLayers: false,
      inertia: false,
      zoomAnimation: $('.hide-map').css('display') !== 'none',
      maxBounds: L.latLngBounds(southWest, northEast),
      minZoom: 8
    })).setView([center[1], center[0]], config.geocode().zoom);

    L.amigo.auth.setToken(config.support_data_token());

    blurLayer = L.tileLayer(
    'https://www.amigocloud.com/api/v1/users/'+
	'23/projects/3019/datasets/23835/tiles/{z}/{x}/{y}.png?' +
	'token=' + config.support_data_token(),
      {
        name: 'Uncovered Area'
      }
    );

    map.addAuthLayer({
      id: config.mapbox_map_id(),
      accessToken: config.mapbox_access_token(),
      name: 'Gray',
      provider: 'mapbox'
    });
    map.addBaseLayer(L.amigo.AmigoGray);
    map.layersControl.addBaseLayer(
      L.bingLayer(
        config.bing_key(),
	{
	  type: 'Road',
	  attribution: 'Bing Maps'
	}
      ),
      'Bing Road'
    );
    map.layersControl.addOverlay(blurLayer);
    blurLayer.addTo(map);

    module.exports.activeMap = map;

    map.realtimeControl = L.control.toggleRealTime().addTo(map);

    realtime = mapModule.realtime();

  } else {

    map = L.mapbox.map(el, config.mapbox_map_id(), {
      attributionControl: false,
      inertia: false,
      zoomAnimation: false
    }).setView([center[1], center[0]], config.geocode().zoom);
  }

  return map;
};

module.exports.getMap = function () {
  return this.activeMap;
};

module.exports.cleanRoute = function() {
    module.exports.activeRoute.removeLayer();
    module.exports.activeRoute = null;
};

module.exports.polyline_creadas = [];
module.exports.marker_creadas = [];
module.exports.makerpoint_creadas = [];
module.exports.collision_group = {};
module.exports.marker_collision_group = [];

module.exports.drawMakerCollision = function () {
    var collision_group = L.layerGroup.collision();
    collision_group.addLayer(this.marker_collision_group);
    collision_group.onAdd(this.activeMap);
    this.collision_group =  collision_group;

};

module.exports.getpolyline_creadas = function () {
  return this.polyline_creadas;
};

module.exports.getMarker_creadas = function () {
  return this.marker_creadas;
};

module.exports.cleanPolyline = function() {
    var polyline_creadas = this.getpolyline_creadas();
    var map = this.activeMap;
    for (i in polyline_creadas) {
        try {
                map.removeLayer(polyline_creadas[i]);

            } catch (e) {
                console.log("problema al eliminar " + e);
            }

  }
  this.polyline_creadas = [];

};

module.exports.cleanMarkerCollision = function() {
    for (i in this.marker_collision_group) {
        this.collision_group.removeLayer(this.marker_collision_group[i]);
    }

}
module.exports.cleanMarker = function() {
    var map = this.activeMap;
    for (i in this.marker_creadas) {
        try {
                map.removeLayer(this.marker_creadas[i]);

            } catch (e) {
                console.log("problema al eliminar " + e);
            }
    }

  this.marker_creadas = [];

};

module.exports.cleanMarkerpoint = function() {
    var map = this.activeMap;
    for (i in this.makerpoint_creadas) {
        try {
                map.removeLayer(this.makerpoint_creadas[i]);

            } catch (e) {
                console.log("problema al eliminar " + e);
            }
    }

  this.makerpoint_creadas = [];

};

module.exports.marker_map = function(from, to){
     var IconStart = L.icon({
        iconUrl: 'assets/images/graphics/start.svg',
        iconSize: [25, 25],
        iconAnchor: [0, 0],
        popupAnchor:  [0, -50]
    });
    var IconEnd = L.icon({
        iconUrl: 'assets/images/graphics/end.svg',
        iconSize: [15, 15],
        iconAnchor: [0, 0],
        popupAnchor:  [0, -50]
    });

    var markerform = new L.marker([from[0],from[1]], {icon: IconStart, draggable: true})
        .addTo(this.activeMap);
    var markerto = new L.marker([to[0],to[1]], {icon: IconEnd, draggable: true})
        .addTo(this.activeMap);
    var _this = this;

    markerform.on('dragend', function(e){
       var marker = e.target;
       var result = marker.getLatLng();
       _this.cleanPolyline();
       _this.cleanMarkerpoint();
       _this.cleanMarkerCollision();
       var plan = session.plan();

            plan.setAddress('from', result.lng + ',' + result.lat, function(err, rees) {
                plan.updateRoutes();
          });
    });

    markerto.on('dragend', function(e){
       var marker = e.target;
       var result = marker.getLatLng();
       _this.cleanPolyline();
       _this.cleanMarkerpoint();
       _this.cleanMarkerCollision();
       var plan = session.plan();
            plan.setAddress('to', result.lng + ',' + result.lat, function(err, rees) {
                plan.updateRoutes();
          });
    });

    this.marker_creadas.push(markerform);
    this.marker_creadas.push(markerto);
};

module.exports.marker_map_point = function(to, map, set_hover){

    var name = to[2];
    var class_name = '';
    var html;
      //html = "
" + name + "
";
    if (!set_hover){
        class_name = 'leaflet-div-icon1';
        html = "
" + name + "
";
    }else{
        class_name = 'leaflet-div-icon2';
        html = "";
    }
    var marker = L.marker({"lat":to[0], "lng": to[1]}, {
				icon: L.divIcon({
                    className: class_name,
                    iconSize: [15, 15],
                    iconAnchor: [0, 0],
                    html:html
				})
				,interactive: false
				,clickable:   false
				});

    this.marker_collision_group.push(marker);
};

module.exports.drawRouteAmigo = function(legs,mode, option) {

    var route = legs.legGeometry.points;
    var circle_from = [legs.from.lat, legs.from.lon, legs.from.name];
    var circle_to = [legs.to.lat, legs.to.lon, legs.to.name];
    var color = '#000000';
    var weight = 5;
    var set_hover = false;
    if (option.stroke){
        set_hover = true;
    }
    if(mode=="BUS") {
      console.log("legs ->", legs);
    }

    var dasharray= '';

        if (mode=="CAR") {
            color = '#9E9E9E';
            dasharray= '6';
            weight = 3;

        }else if(mode=="BICYCLE") {
            color = '#FF0000';
            if(!(legs.routeColor === undefined)) {
                color = "#"+legs.routeColor;
             }
            dasharray= '6';
            weight = 3;

        }else if(mode=="SUBWAY" || mode=="RAIL") {
             if(!(legs.routeColor === undefined)) {
                if (legs.routeColor != "" || legs.routeColor.length == 6) {
                    color = "#"+legs.routeColor;
                }

             }
             weight = 8;
             this.marker_map_point(circle_from, this.activeMap, set_hover);
             this.marker_map_point(circle_to, this.activeMap, set_hover);

        }
        else if(mode == "WALK") {
            color = '#0BC8F4';
            dasharray= '6';
             weight = 3;
        }

        else if(mode=="BUS") {
            //color = '#FEF0B5';
            if(!(legs.routeColor === undefined)) {
                if (legs.routeColor != "" || legs.routeColor.length == 6) {
                    color = "#"+legs.routeColor;
                }
             }
             weight = 5;
             this.marker_map_point(circle_from, this.activeMap, set_hover);
             this.marker_map_point(circle_to, this.activeMap, set_hover);
        }

       var color_options = {
            color:color,
            weight: weight,
            opacity:1,
            dashArray: dasharray
        };

       if (option.stroke){
         delete color_options.opacity;
       }else{
          color_options.color = color;
          color_options.stroke = false;
       }
       if (option.class_name){
            //color_options.className = 'message_';
           color_options.className = 'fade-out four';
       }

       color_options.className = 'message_';
       color_options.fillColor = '#F2F2F2';
       color_options.fillOpacity = '0.25';

       console.log("color");
      var argpolyline = L.PolylineUtil.decode(route, 5);
      argpolyline.unshift(circle_from);
      route = new L.Polyline(argpolyline, color_options);
      this.polyline_creadas.push(route);
      var boxes = L.RouteBoxer.box(route, 5);
      var boxpolys = new Array(boxes.length);
      route.addTo(this.activeMap);
};

<commit_msg>changes styles<commit_after>var config = require('config');
var mapModule = require('map');
var plugins = require('./leaflet_plugins');
var polyUtil = require('./polyline_encoded.js');
var routeboxer = require('./leaflet_routeboxer.js');
var leaflet_label = require('./leaflet_label/leaflet.label-src.js');
var collision = require('./leaflet_layergroup_collision.js');
var session = require('session');

var center = config.geocode().center.split(',').map(parseFloat)
if (config.map_provider && config.map_provider() !== 'AmigoCloud') {
  L.mapbox.accessToken = config.mapbox_access_token();
}

module.exports = function(el) {
  var map, realtime, southWest, northEast, blurLayer;
  localStorage.removeItem('dataplan');
  if (config.map_provider && config.map_provider() === 'AmigoCloud') {
    southWest = L.latLng(35.946877085397,-123.480610897013);
    northEast = L.latLng(40.763279543715,-118.789317362500);
    map = (new L.amigo.map(el, {
      amigoLogo: 'right',
      loadAmigoLayers: false,
      inertia: false,
      zoomAnimation: $('.hide-map').css('display') !== 'none',
      maxBounds: L.latLngBounds(southWest, northEast),
      minZoom: 8
    })).setView([center[1], center[0]], config.geocode().zoom);

    L.amigo.auth.setToken(config.support_data_token());

    blurLayer = L.tileLayer(
    'https://www.amigocloud.com/api/v1/users/'+
	'23/projects/3019/datasets/23835/tiles/{z}/{x}/{y}.png?' +
	'token=' + config.support_data_token(),
      {
        name: 'Uncovered Area'
      }
    );

    map.addAuthLayer({
      id: config.mapbox_map_id(),
      accessToken: config.mapbox_access_token(),
      name: 'Gray',
      provider: 'mapbox'
    });
    map.addBaseLayer(L.amigo.AmigoGray);
    map.layersControl.addBaseLayer(
      L.bingLayer(
        config.bing_key(),
	{
	  type: 'Road',
	  attribution: 'Bing Maps'
	}
      ),
      'Bing Road'
    );
    map.layersControl.addOverlay(blurLayer);
    blurLayer.addTo(map);

    module.exports.activeMap = map;

    map.realtimeControl = L.control.toggleRealTime().addTo(map);

    realtime = mapModule.realtime();

  } else {

    map = L.mapbox.map(el, config.mapbox_map_id(), {
      attributionControl: false,
      inertia: false,
      zoomAnimation: false
    }).setView([center[1], center[0]], config.geocode().zoom);
  }

  return map;
};

module.exports.getMap = function () {
  return this.activeMap;
};

module.exports.cleanRoute = function() {
    module.exports.activeRoute.removeLayer();
    module.exports.activeRoute = null;
};

module.exports.polyline_creadas = [];
module.exports.marker_creadas = [];
module.exports.makerpoint_creadas = [];
module.exports.collision_group = {};
module.exports.marker_collision_group = [];

module.exports.drawMakerCollision = function () {
    var collision_group = L.layerGroup.collision();
    collision_group.addLayer(this.marker_collision_group);
    collision_group.onAdd(this.activeMap);
    this.collision_group =  collision_group;

};

module.exports.getpolyline_creadas = function () {
  return this.polyline_creadas;
};

module.exports.getMarker_creadas = function () {
  return this.marker_creadas;
};

module.exports.cleanPolyline = function() {
    var polyline_creadas = this.getpolyline_creadas();
    var map = this.activeMap;
    for (i in polyline_creadas) {
        try {
                map.removeLayer(polyline_creadas[i]);

            } catch (e) {
                console.log("problema al eliminar " + e);
            }

  }
  this.polyline_creadas = [];

};

module.exports.cleanMarkerCollision = function() {
    for (i in this.marker_collision_group) {
        this.collision_group.removeLayer(this.marker_collision_group[i]);
    }

}
module.exports.cleanMarker = function() {
    var map = this.activeMap;
    for (i in this.marker_creadas) {
        try {
                map.removeLayer(this.marker_creadas[i]);

            } catch (e) {
                console.log("problema al eliminar " + e);
            }
    }

  this.marker_creadas = [];

};

module.exports.cleanMarkerpoint = function() {
    var map = this.activeMap;
    for (i in this.makerpoint_creadas) {
        try {
                map.removeLayer(this.makerpoint_creadas[i]);

            } catch (e) {
                console.log("problema al eliminar " + e);
            }
    }

  this.makerpoint_creadas = [];

};

module.exports.marker_map = function(from, to){
     var IconStart = L.icon({
        iconUrl: 'assets/images/graphics/start.svg',
        iconSize: [25, 25],
        iconAnchor: [0, 0],
        popupAnchor:  [0, -50]
    });
    var IconEnd = L.icon({
        iconUrl: 'assets/images/graphics/end.svg',
        iconSize: [15, 15],
        iconAnchor: [0, 0],
        popupAnchor:  [0, -50]
    });

    var markerform = new L.marker([from[0],from[1]], {icon: IconStart, draggable: true})
        .addTo(this.activeMap);
    var markerto = new L.marker([to[0],to[1]], {icon: IconEnd, draggable: true})
        .addTo(this.activeMap);
    var _this = this;

    markerform.on('dragend', function(e){
       var marker = e.target;
       var result = marker.getLatLng();
       _this.cleanPolyline();
       _this.cleanMarkerpoint();
       _this.cleanMarkerCollision();
       var plan = session.plan();

            plan.setAddress('from', result.lng + ',' + result.lat, function(err, rees) {
                plan.updateRoutes();
          });
    });

    markerto.on('dragend', function(e){
       var marker = e.target;
       var result = marker.getLatLng();
       _this.cleanPolyline();
       _this.cleanMarkerpoint();
       _this.cleanMarkerCollision();
       var plan = session.plan();
            plan.setAddress('to', result.lng + ',' + result.lat, function(err, rees) {
                plan.updateRoutes();
          });
    });

    this.marker_creadas.push(markerform);
    this.marker_creadas.push(markerto);
};

module.exports.marker_map_point = function(to, map, set_hover){

    var name = to[2];
    var class_name = '';
    var html;
      //html = "
" + name + "
";
    if (!set_hover){
        class_name = 'leaflet-div-icon1';
        html = "
" + name + "
";
    }else{
        class_name = 'leaflet-div-icon2';
        html = "";
    }
    var marker = L.marker({"lat":to[0], "lng": to[1]}, {
				icon: L.divIcon({
                    className: class_name,
                    iconSize: [15, 15],
                    iconAnchor: [0, 0],
                    html:html
				})
				,interactive: false
				,clickable:   false
				});

    this.marker_collision_group.push(marker);
};

module.exports.drawRouteAmigo = function(legs,mode, option) {

    var route = legs.legGeometry.points;
    var circle_from = [legs.from.lat, legs.from.lon, legs.from.name];
    var circle_to = [legs.to.lat, legs.to.lon, legs.to.name];
    var color = '#000000';
    var weight = 5;
    var set_hover = false;
    if (option.stroke){
        set_hover = true;
    }
    if(mode=="BUS") {
      console.log("legs ->", legs);
    }

    var dasharray= '';

        if (mode=="CAR") {
            color = '#9E9E9E';
            dasharray= '6';
            weight = 3;

        }else if(mode=="BICYCLE") {
            color = '#FF0000';
            if(!(legs.routeColor === undefined)) {
                color = "#"+legs.routeColor;
             }
            dasharray= '6';
            weight = 3;

        }else if(mode=="SUBWAY" || mode=="RAIL") {
             if(!(legs.routeColor === undefined)) {
                if (legs.routeColor != "" || legs.routeColor.length == 6) {
                    color = "#"+legs.routeColor;
                }

             }
             weight = 8;
             this.marker_map_point(circle_from, this.activeMap, set_hover);
             this.marker_map_point(circle_to, this.activeMap, set_hover);

        }
        else if(mode == "WALK") {
            color = '#0BC8F4';
            dasharray= '6';
             weight = 3;
        }

        else if(mode=="BUS") {
            //color = '#FEF0B5';
            if(!(legs.routeColor === undefined)) {
                if (legs.routeColor != "" || legs.routeColor.length == 6) {
                    color = "#"+legs.routeColor;
                }
             }
             weight = 5;
             this.marker_map_point(circle_from, this.activeMap, set_hover);
             this.marker_map_point(circle_to, this.activeMap, set_hover);
        }

       var color_options = {
            color:color,
            weight: weight,
            opacity:1,
            dashArray: dasharray
        };

       if (option.stroke){
         delete color_options.opacity;
       }else{
          color_options.color = color;
          color_options.stroke = false;
       }
       if (option.class_name){
            //color_options.className = 'message_';
           color_options.className = 'fade-out four';
       }

       color_options.className = 'message_';
       color_options.fillColor = '#000';
       color_options.fillOpacity = '0.25';

       console.log("color");
      var argpolyline = L.PolylineUtil.decode(route, 5);
      argpolyline.unshift(circle_from);
      route = new L.Polyline(argpolyline, color_options);
      this.polyline_creadas.push(route);
      var boxes = L.RouteBoxer.box(route, 5);
      var boxpolys = new Array(boxes.length);
      route.addTo(this.activeMap);
};

<|endoftext|>


<commit_before>var chrome = chrome || {};

var popup = (function () {

    var service = analytics.getService('Design_Grid_Overlay');
    service.getConfig().addCallback(initAnalyticsConfig);
    var tracker = service.getTracker('UA-80131763-3');
    tracker.sendAppView('MainView');

    function initAnalyticsConfig(config) {
        var checkbox = document.getElementById('tracking-permitted');
        checkbox.checked = config.isTrackingPermitted();
        checkbox.onchange = function() {
            config.setTrackingPermitted(checkbox.checked);
        };
    }

    var gridForm = document.getElementById('gridForm');
    var gridToggle = document.getElementById('gridToggle');
    var horizontalLinesToggle = document.getElementById('horizontalLinesToggle');
    var reportForm = document.getElementById('reportForm');
    var advancedForm = document.getElementById('advancedForm');
    var tabContentContainer = document.getElementById('gridsettings');
    var tabLabelContainer = document.getElementById('tabContainer');
    var currentChromeTabId = undefined;

    /**
     * Set the click event for the tabs
     */
    var setTabAction = function (tabOuter, tabInner, contentId) {
        $('#' + tabInner).bind("click", function (event) {
            $('.' + tabOuter + ' div[aria-selected=true]').attr("aria-selected", "false");
            this.setAttribute("aria-selected", "true");
            $('.' + tabOuter).find("[aria-hidden=false]").attr("aria-hidden", "true");
            $('#' + contentId).eq($(this).attr('tabindex')).attr("aria-hidden", "false");
        });
    };

    /**
     * Setup tab actions for each tab label and its corresponding tab panel
     */
    setTabAction('tabs', 'tab1', 'panel1');
    setTabAction('tabs', 'tab2', 'panel2');
    setTabAction('tabs', 'tab3', 'panel3');

    /**
     * Allows a user to click any of our external links and open a tab
     */
    var externalLinks = document.getElementsByClassName("extlink");
    for (var i = 0; i < externalLinks.length; i++) {
        externalLinks[i].addEventListener('click', function(e){
            if (this.href !== undefined) {
                chrome.tabs.create({url: this.href})
            }
        });
    }

    /**
     * Will stop the advanced form from submitting
     */
    advancedForm.onsubmit = function () {
        return false;
    };

    /**
     * Will stop the report settings form from submitting
     */
    reportForm.onsubmit = function () {
        return false;
    };

    /**
     * Called when the popup is load. A call
     * to save the tab state and check the grid status is
     * made.
     */
    window.addEventListener('load', function () {

        chrome.tabs.query({currentWindow: true, active: true}, function (tabs) {

            currentChromeTabId = tabs[0].id;

            document.getElementById('tabContainer').addEventListener('click', function () {
                //Save UI state, which includes tab state
                settingStorageController.saveSettings(currentChromeTabId, false);
            });

            //Initialize state
            popup.init();

            chrome.tabs.executeScript(currentChromeTabId, {file: 'src/executedScripts/gridStatus.js'});

            //tabController.getCurrentTabState(tabs[0].id);
        });

        chrome.commands.getAll(function(commands) { // use chrome extension api to get the defined shortcut
            var toggle_columns_html = '';
            var toggle_lines_html = '';
            var activate_extension = '';

            commands.forEach(function(element) {

                switch (element.name) {
                    case 'toggle-columns':
                      toggle_columns_html = element.shortcut;
                      break;
                    case 'toggle-lines':
                      toggle_lines_html = element.shortcut;
                      break;
                    case '_execute_browser_action':
                      activate_html = element.shortcut;
                      break;
                    }
                });

            document.getElementById("toggle-v").innerHTML = (toggle_columns_html).split('+').join(' + '); // get and replace shortcut from chrome extension api
            document.getElementById("toggle-h").innerHTML = (toggle_lines_html).split('+').join(' + ');
            document.getElementById("activate-extension").innerHTML = (activate_html).split('+').join(' + ');
        });

    });

    /**
     * Event that changes the toggle based on if
     * the grid is active or not
     */
    chrome.runtime.onMessage.addListener(
        function (request, sender, sendResponse) {
            if (request.status !== undefined) {
                if (request.status === 1 && gridToggle.checked === false) {
                    console.log('Grid already enabled on page');
                    gridToggle.checked = true;
                } else if (request.status === 0 && gridToggle.checked === true) {
                    gridToggle.checked = false;
                }
            }
            if (request.horizontalLinesStatus !== undefined) {
                if (request.horizontalLinesStatus === 1 && horizontalLinesToggle.checked === false) {
                    console.log('Horizontal lines already enabled on page');
                    horizontalLinesToggle.checked = true;
                } else if (request.horizontalLinesStatus === 0 && horizontalLinesToggle.checked === true) {
                    horizontalLinesToggle.checked = false;
                }
            }
        }
    );

    /**
     * A click event listen that will change the values
     * off the grid based on the popup values.
     */
    gridToggle.addEventListener('click', function () {
        var settings = settingStorageController.saveSettings(currentChromeTabId, false);
        gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
        reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
    });

    horizontalLinesToggle.addEventListener('click', function () {
        var settings = settingStorageController.saveSettings(currentChromeTabId, false);
        gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
    });

    /**
     * Adds an event to the reset button
     * in order to reset all the values on
     * the grid to the default values in the
     * popup window.
     */
    gridForm.addEventListener('reset', function () {

        // SetTimeout is used to delay the execution of this code and storage of the DOM state until AFTER the reset
        // event has finished resetting the form values - this reset event is fired BEFORE the DOM state has changed
        setTimeout(function () {
            var settings = settingStorageController.saveSettings(currentChromeTabId, true);
            gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
            reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
            reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                settings.formData.reportForm.settings, settings.formData.advancedForm.settings);
        }, 0);
    });

    /**
     * Shift+Up/Down to go up/down by 10px (issue #25).
     * ----
     * In this case I made it for all
     * number inputs in a "Settings" tab.
     */
    gridForm.addEventListener('keydown', function (e) {
        var target = e.target;

        // check if keydown was in some number input
        if (target.nodeName === 'INPUT') {
            if (target.getAttribute('type').toUpperCase() === 'NUMBER') {
                if (e.shiftKey && e.key === 'ArrowUp') {
                    target.value = parseInt(target.value) + 10;

                    if (target.hasAttribute('max')) {
                        var value = parseInt(target.value);
                        var maxValue = parseInt(target.getAttribute('max'));

                        if (value > maxValue)
                            target.value = maxValue;
                    }

                    e.preventDefault();
                }
                if (e.shiftKey && e.key === 'ArrowDown') {
                    target.value = parseInt(target.value) - 10;

                    if (target.hasAttribute('min')) {
                        var value = parseInt(target.value);
                        var minValue = parseInt(target.getAttribute('min'));

                        if (value < minValue)
                            target.value = minValue;
                    }

                    e.preventDefault();
                }
            }
        }
        var settings = settingStorageController.saveSettings(currentChromeTabId, true);
        gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
    });

    /**
     * Adds an event to the reset button
     * in order to reset all the values on
     * the grid to the default values in the
     * popup window.
     */
    reportForm.addEventListener('reset', function () {

        // SetTimeout is used to delay the execution of this code and storage of the DOM state until AFTER the reset
        // event has finished resetting the form values - this reset event is fired BEFORE the DOM state has changed
        setTimeout(function () {
            console.log('reset');
            var settings = settingStorageController.saveSettings(currentChromeTabId, true);
            gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
            reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
            reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                settings.formData.reportForm.settings, settings.formData.advancedForm.settings);

        }, 0);
    });

    /**
     * Adds an event to the reset button
     * in order to reset all the values on
     * the grid to the default values in the
     * popup window.
     */
    advancedForm.addEventListener('reset', function () {

        // SetTimeout is used to delay the execution of this code and storage of the DOM state until AFTER the reset
        // event has finished resetting the form values - this reset event is fired BEFORE the DOM state has changed
        setTimeout(function () {
            var settings = settingStorageController.saveSettings(currentChromeTabId, true);
            gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
            reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
            reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                settings.formData.reportForm.settings, settings.formData.advancedForm.settings);

        }, 0);
    });

    /**
     * Used to stop a user from incrementing the
     * number field to fast. This stops the event from
     * firing to fast and stops multiple grids
     * from appearing stacked on the page
     */
    var throttle = function (fn, threshhold, scope) {
        threshhold || (threshhold = 250);
        var last,
            deferTimer;
        return function () {
            var context = scope || this;
            var now = +new Date,
                args = arguments;
            if (last && now < last + threshhold) {
                // hold on to it
                clearTimeout(deferTimer);
                deferTimer = setTimeout(function () {
                    last = now;
                    fn.apply(context, args);
                }, threshhold);
            }
            else {
                last = now;
                fn.apply(context, args);
            }
        };
    };

    /**
     * Used to initialize the state of the popup window and inject in-page scripts.
     * Saves the current tab state, generates the grid, and calculates the report.
     */
    var init = function () {

        settingStorageController.init(gridForm, reportForm, advancedForm, tabContentContainer, tabLabelContainer);

        /**
         * Heartbeat pattern to determine whether content script is already inject
         * If not it will be injected.
         */
        chrome.tabs.sendMessage(currentChromeTabId, {greeting: "hello"}, function (response) {

            if (response) {
                console.log("Design Grid Overlay JS already injected.");

                // Load all stored settings from chrome local storage, and then update the report overlay
                settingStorageController.loadSettings(currentChromeTabId, function (settings) {
                    reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
                    reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                        settings.formData.reportForm.settings, settings.formData.advancedForm.settings);
                });
            }
            else {
                console.log("Design Grid Overlay JS not already injected, injecting now.");
                chrome.tabs.executeScript(currentChromeTabId, {file: "src/executedScripts/grid.js"});
                chrome.tabs.executeScript(currentChromeTabId, {file: "src/executedScripts/calcReport.js"}, function () {

                    // Load all stored settings from chrome local storage, and then update the report overlay
                    settingStorageController.loadSettings(currentChromeTabId, function (settings) {
                        reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
                        reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                            settings.formData.reportForm.settings, settings.formData.advancedForm.settings);
                    });
                });

                // call addCSS on load
                // it's a hack to do posiible use keyboard commands to show grid and lines at the very first time (before checkbox click)
                var settings = settingStorageController.saveSettings(currentChromeTabId, false);
                gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
            }
        });

        //Grid form event binding
        var gridFormInputs = gridForm.getElementsByTagName('input');
        for (var i = 0; i < gridFormInputs.length; i++) {
            gridFormInputs[i].addEventListener("change", throttle(function (event) {
                if (event.target.id !== 'gridToggle') {
                    //Updated just grid and report calculations
                    var settings = settingStorageController.saveSettings(currentChromeTabId, true);
                    gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
                    reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
                }
            }, 1000));
        }

        //Report form input event binding
        var reportFormInputs = reportForm.getElementsByTagName('input');
        for (var i = 0; i < reportFormInputs.length; i++) {
            reportFormInputs[i].addEventListener("change", throttle(function (event) {
                if (event.target.id !== 'gridToggle') {
                    //Update just report overlay
                    var settings = settingStorageController.saveSettings(currentChromeTabId, true);
                    reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                        settings.formData.reportForm.settings, settings.formData.advancedForm.settings);
                }
            }, 1000));
        }

        //Advanced form input event binding
        var advancedFormInputs = advancedForm.getElementsByTagName('input');
        for (var i = 0; i < advancedFormInputs.length; i++) {
            advancedFormInputs[i].addEventListener("change", throttle(function (event) {
                if (event.target.id !== 'gridToggle') {
                    //Update grid, report, report overlay
                    var settings = settingStorageController.saveSettings(currentChromeTabId, true);
                    reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
                    gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
                    reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                        settings.formData.reportForm.settings, settings.formData.advancedForm.settings);
                }
            }, 1000));
        }

    };

    /**
     * Return the publicly accessible methods
     */
    return {
        init: init
    }

})();
<commit_msg>remove unnecessary hacky way to toggle grid overlay - it's not working and causing issue from remembering the last setting after refresh<commit_after>var chrome = chrome || {};

var popup = (function () {

    var service = analytics.getService('Design_Grid_Overlay');
    service.getConfig().addCallback(initAnalyticsConfig);
    var tracker = service.getTracker('UA-80131763-3');
    tracker.sendAppView('MainView');

    function initAnalyticsConfig(config) {
        var checkbox = document.getElementById('tracking-permitted');
        checkbox.checked = config.isTrackingPermitted();
        checkbox.onchange = function() {
            config.setTrackingPermitted(checkbox.checked);
        };
    }

    var gridForm = document.getElementById('gridForm');
    var gridToggle = document.getElementById('gridToggle');
    var horizontalLinesToggle = document.getElementById('horizontalLinesToggle');
    var reportForm = document.getElementById('reportForm');
    var advancedForm = document.getElementById('advancedForm');
    var tabContentContainer = document.getElementById('gridsettings');
    var tabLabelContainer = document.getElementById('tabContainer');
    var currentChromeTabId = undefined;

    /**
     * Set the click event for the tabs
     */
    var setTabAction = function (tabOuter, tabInner, contentId) {
        $('#' + tabInner).bind("click", function (event) {
            $('.' + tabOuter + ' div[aria-selected=true]').attr("aria-selected", "false");
            this.setAttribute("aria-selected", "true");
            $('.' + tabOuter).find("[aria-hidden=false]").attr("aria-hidden", "true");
            $('#' + contentId).eq($(this).attr('tabindex')).attr("aria-hidden", "false");
        });
    };

    /**
     * Setup tab actions for each tab label and its corresponding tab panel
     */
    setTabAction('tabs', 'tab1', 'panel1');
    setTabAction('tabs', 'tab2', 'panel2');
    setTabAction('tabs', 'tab3', 'panel3');

    /**
     * Allows a user to click any of our external links and open a tab
     */
    var externalLinks = document.getElementsByClassName("extlink");
    for (var i = 0; i < externalLinks.length; i++) {
        externalLinks[i].addEventListener('click', function(e){
            if (this.href !== undefined) {
                chrome.tabs.create({url: this.href})
            }
        });
    }

    /**
     * Will stop the advanced form from submitting
     */
    advancedForm.onsubmit = function () {
        return false;
    };

    /**
     * Will stop the report settings form from submitting
     */
    reportForm.onsubmit = function () {
        return false;
    };

    /**
     * Called when the popup is load. A call
     * to save the tab state and check the grid status is
     * made.
     */
    window.addEventListener('load', function () {

        chrome.tabs.query({currentWindow: true, active: true}, function (tabs) {

            currentChromeTabId = tabs[0].id;

            document.getElementById('tabContainer').addEventListener('click', function () {
                //Save UI state, which includes tab state
                settingStorageController.saveSettings(currentChromeTabId, false);
            });

            //Initialize state
            popup.init();

            chrome.tabs.executeScript(currentChromeTabId, {file: 'src/executedScripts/gridStatus.js'});

            //tabController.getCurrentTabState(tabs[0].id);
        });

    });

    /**
     * Event that changes the toggle based on if
     * the grid is active or not
     */
    chrome.runtime.onMessage.addListener(
        function (request, sender, sendResponse) {
            if (request.status !== undefined) {
                if (request.status === 1 && gridToggle.checked === false) {
                    console.log('Grid already enabled on page');
                    gridToggle.checked = true;
                } else if (request.status === 0 && gridToggle.checked === true) {
                    gridToggle.checked = false;
                }
            }
            if (request.horizontalLinesStatus !== undefined) {
                if (request.horizontalLinesStatus === 1 && horizontalLinesToggle.checked === false) {
                    console.log('Horizontal lines already enabled on page');
                    horizontalLinesToggle.checked = true;
                } else if (request.horizontalLinesStatus === 0 && horizontalLinesToggle.checked === true) {
                    horizontalLinesToggle.checked = false;
                }
            }
        }
    );

    /**
     * A click event listen that will change the values
     * off the grid based on the popup values.
     */
    gridToggle.addEventListener('click', function () {
        var settings = settingStorageController.saveSettings(currentChromeTabId, false);
        gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
        reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
    });

    horizontalLinesToggle.addEventListener('click', function () {
        var settings = settingStorageController.saveSettings(currentChromeTabId, false);
        gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
    });

    /**
     * Adds an event to the reset button
     * in order to reset all the values on
     * the grid to the default values in the
     * popup window.
     */
    gridForm.addEventListener('reset', function () {

        // SetTimeout is used to delay the execution of this code and storage of the DOM state until AFTER the reset
        // event has finished resetting the form values - this reset event is fired BEFORE the DOM state has changed
        setTimeout(function () {
            var settings = settingStorageController.saveSettings(currentChromeTabId, true);
            gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
            reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
            reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                settings.formData.reportForm.settings, settings.formData.advancedForm.settings);
        }, 0);
    });

    /**
     * Adds an event to the reset button
     * in order to reset all the values on
     * the grid to the default values in the
     * popup window.
     */
    reportForm.addEventListener('reset', function () {

        // SetTimeout is used to delay the execution of this code and storage of the DOM state until AFTER the reset
        // event has finished resetting the form values - this reset event is fired BEFORE the DOM state has changed
        setTimeout(function () {
            var settings = settingStorageController.saveSettings(currentChromeTabId, true);
            gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
            reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
            reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                settings.formData.reportForm.settings, settings.formData.advancedForm.settings);

        }, 0);
    });

    /**
     * Adds an event to the reset button
     * in order to reset all the values on
     * the grid to the default values in the
     * popup window.
     */
    advancedForm.addEventListener('reset', function () {

        // SetTimeout is used to delay the execution of this code and storage of the DOM state until AFTER the reset
        // event has finished resetting the form values - this reset event is fired BEFORE the DOM state has changed
        setTimeout(function () {
            var settings = settingStorageController.saveSettings(currentChromeTabId, true);
            gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
            reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
            reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                settings.formData.reportForm.settings, settings.formData.advancedForm.settings);

        }, 0);
    });

    /**
     * Used to stop a user from incrementing the
     * number field to fast. This stops the event from
     * firing to fast and stops multiple grids
     * from appearing stacked on the page
     */
    var throttle = function (fn, threshhold, scope) {
        threshhold || (threshhold = 250);
        var last,
            deferTimer;
        return function () {
            var context = scope || this;
            var now = +new Date,
                args = arguments;
            if (last && now < last + threshhold) {
                // hold on to it
                clearTimeout(deferTimer);
                deferTimer = setTimeout(function () {
                    last = now;
                    fn.apply(context, args);
                }, threshhold);
            }
            else {
                last = now;
                fn.apply(context, args);
            }
        };
    };

    /**
     * Used to initialize the state of the popup window and inject in-page scripts.
     * Saves the current tab state, generates the grid, and calculates the report.
     */
    var init = function () {

        settingStorageController.init(gridForm, reportForm, advancedForm, tabContentContainer, tabLabelContainer);

        /**
         * Heartbeat pattern to determine whether content script is already inject
         * If not it will be injected.
         */
        chrome.tabs.sendMessage(currentChromeTabId, {greeting: "hello"}, function (response) {

            if (response) {
                console.log("Design Grid Overlay JS already injected.");

                // Load all stored settings from chrome local storage, and then update the report overlay
                settingStorageController.loadSettings(currentChromeTabId, function (settings) {
                    reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
                    reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                        settings.formData.reportForm.settings, settings.formData.advancedForm.settings);
                });
            }
            else {
                console.log("Design Grid Overlay JS not already injected, injecting now.");
                chrome.tabs.executeScript(currentChromeTabId, {file: "src/executedScripts/grid.js"});
                chrome.tabs.executeScript(currentChromeTabId, {file: "src/executedScripts/calcReport.js"}, function () {

                    // Load all stored settings from chrome local storage, and then update the report overlay
                    settingStorageController.loadSettings(currentChromeTabId, function (settings) {
                        reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
                        reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                            settings.formData.reportForm.settings, settings.formData.advancedForm.settings);
                    });
                });

            }
        });

        //Grid form event binding
        var gridFormInputs = gridForm.getElementsByTagName('input');
        for (var i = 0; i < gridFormInputs.length; i++) {
            gridFormInputs[i].addEventListener("change", throttle(function (event) {
                if (event.target.id !== 'gridToggle') {
                    //Updated just grid and report calculations
                    var settings = settingStorageController.saveSettings(currentChromeTabId, true);
                    gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
                    reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
                }
            }, 1000));
        }

        //Report form input event binding
        var reportFormInputs = reportForm.getElementsByTagName('input');
        for (var i = 0; i < reportFormInputs.length; i++) {
            reportFormInputs[i].addEventListener("change", throttle(function (event) {
                if (event.target.id !== 'gridToggle') {
                    //Update just report overlay
                    var settings = settingStorageController.saveSettings(currentChromeTabId, true);
                    reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                        settings.formData.reportForm.settings, settings.formData.advancedForm.settings);
                }
            }, 1000));
        }

        //Advanced form input event binding
        var advancedFormInputs = advancedForm.getElementsByTagName('input');
        for (var i = 0; i < advancedFormInputs.length; i++) {
            advancedFormInputs[i].addEventListener("change", throttle(function (event) {
                if (event.target.id !== 'gridToggle') {
                    //Update grid, report, report overlay
                    var settings = settingStorageController.saveSettings(currentChromeTabId, true);
                    reportController.calculateReport(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
                    gridController.updateGrid(currentChromeTabId, settings.formData.gridForm.settings, settings.formData.advancedForm.settings);
                    reportController.updateReportOverlay(currentChromeTabId, gridToggle.checked,
                        settings.formData.reportForm.settings, settings.formData.advancedForm.settings);
                }
            }, 1000));
        }

    };

    /**
     * Return the publicly accessible methods
     */
    return {
        init: init
    }

})();
<|endoftext|>