<commit_before>describe('Testing map module', function() {

  beforeEach(module('anol.map'));

  describe('Testing LayersService', function() {
    var BACKGROUND_LAYER = new anol.layer.TiledWMS({
      name: 'background',
      title: 'Background',
      isBackground: true,
      olLayer: {
        source: {
          url: 'http://www.example.org?',
          format: 'image/png',
          params: {
            LAYERS: 'example',
            SRS: 'EPSG:4326'
          }
        }
      }
    });

    var OVERLAY_LAYER = new anol.layer.TiledWMS({
      name: 'overlay',
      title: 'Overlay',
      olLayer: {
        source: {
          url: 'http://www.example.org?',
          format: 'image/png',
          params: {
            LAYERS: 'example',
            SRS: 'EPSG:4326'
          }
        }
      }
    });

    var OTHER_OVERLAY_LAYER = new anol.layer.Feature({
      name: 'feature',
      title: 'Feature',
      olLayer: {
        source: {}
      }
    });

    var layersService;

    beforeEach(function () {
      inject(function($injector) {
        layersService = $injector.get('LayersService');
      });
    });

    it('should add a background layer and create olLayer and olSource correct', function() {
      layersService.addBackgroundLayer(BACKGROUND_LAYER);
      expect(layersService.backgroundLayers.length).toBe(1);
      expect(layersService.backgroundLayers[0]).toEqual(BACKGROUND_LAYER);
      expect(BACKGROUND_LAYER.olLayer instanceof ol.layer.Tile).toBe(true);
      expect(BACKGROUND_LAYER.olLayer.getSource() instanceof ol.source.TileWMS).toBe(true);
      expect(layersService.activeBackgroundLayer()).toEqual(BACKGROUND_LAYER);
      expect(layersService.layerByName('background')).toEqual(BACKGROUND_LAYER);
    });

    it('should add a overlay layer and create olLayer and olSource correct', function() {
      layersService.addOverlayLayer(OVERLAY_LAYER);
      expect(layersService.overlayLayers.length).toBe(1);
      expect(layersService.overlayLayers[0]).toEqual(OVERLAY_LAYER);
      expect(OVERLAY_LAYER.olLayer instanceof ol.layer.Tile).toBe(true);
      expect(OVERLAY_LAYER.olLayer.getSource() instanceof ol.source.TileWMS).toBe(true);
      expect(layersService.layerByName('overlay')).toEqual(OVERLAY_LAYER);
    });

    it('should add a group of overlay layers correct', function() {
      var GROUP = new anol.layer.Group({
        name: 'group',
        title: 'Group',
        layers: [
          OVERLAY_LAYER,
          OTHER_OVERLAY_LAYER
        ]
      });
      layersService.addOverlayLayer(GROUP);
      expect(layersService.overlayLayers[0]).toEqual(GROUP);
      expect(layersService.groupByName('group')).toEqual(GROUP);
      expect(layersService.layerByName('overlay')).toEqual(OVERLAY_LAYER);
      expect(layersService.layerByName('feature')).toEqual(OTHER_OVERLAY_LAYER);
    });

    it('should have same source for both layers', function() {
      layersService.addBackgroundLayer(BACKGROUND_LAYER);
      expect(layersService.backgroundLayers.length).toBe(1);
      layersService.addOverlayLayer(OVERLAY_LAYER);
      expect(layersService.overlayLayers.length).toBe(1);

      expect(layersService.backgroundLayers[0].olLayer.getSource()).toEqual(layersService.overlayLayers[0].olLayer.getSource());
    });

    it('should add background ol layer below overlay ol layer', function() {
      layersService.addOverlayLayer(OVERLAY_LAYER);
      layersService.addBackgroundLayer(BACKGROUND_LAYER);

      expect(layersService.backgroundLayers[0]).toEqual(layersService.layers()[0]);
      expect(layersService.overlayLayers[0]).toEqual(layersService.layers()[1]);
    });
  });

  describe('Testing MapService', function() {

    var VIEW = new ol.View({
      projection: 'EPSG:4326',
      center: [8.2175, 53.1512],
      zoom: 14
    });

    var mapService;

    beforeEach(function() {
      module(function(MapServiceProvider) {
        MapServiceProvider.addView(VIEW);
      });

      inject(function($injector) {
        mapService = $injector.get('MapService');
      });
    });

    it('should create a ol map without anything', function() {
      var olMap = mapService.getMap();
      expect(olMap instanceof ol.Map).toBe(true);
      expect(olMap.getView()).toEqual(VIEW);
      expect(olMap.getControls().getLength()).toBe(0);
      expect(olMap.getInteractions().getLength()).toBe(0);
      expect(olMap.getLayers().getLength()).toBe(0);
      expect(olMap.getTarget()).toBe(undefined);
    });

    it('should add, execute and remove pointer condition callback', function() {
      var targetStyle = {style: {}};
      var olMap = mapService.getMap();
      // mock used olMap functions
      var getEventPixelSpy = spyOn(olMap, 'getEventPixel').and.returnValue([123, 321]);
      var getTargetSpy = spyOn(olMap, 'getTarget').and.returnValue(targetStyle);
      var cursorPointerConditionSpy = jasmine.createSpy('pointerCondition').and.returnValues(false, true);

      mapService.addCursorPointerCondition(cursorPointerConditionSpy);

      expect(getEventPixelSpy).not.toHaveBeenCalled();
      expect(getTargetSpy).not.toHaveBeenCalled();
      expect(cursorPointerConditionSpy).not.toHaveBeenCalled();

      olMap.dispatchEvent('pointermove');

      expect(getEventPixelSpy).toHaveBeenCalled();
      expect(getTargetSpy).toHaveBeenCalled();
      expect(cursorPointerConditionSpy).toHaveBeenCalled();
      expect(targetStyle.style).toEqual({cursor: ''});

      olMap.dispatchEvent('pointermove');

      expect(getEventPixelSpy.calls.count()).toBe(2);
      expect(getTargetSpy.calls.count()).toBe(2);
      expect(cursorPointerConditionSpy.calls.count()).toBe(2);
      expect(targetStyle.style).toEqual({cursor: 'pointer'});

      mapService.removeCursorPointerCondition(cursorPointerConditionSpy);

      olMap.dispatchEvent('pointermove');

      expect(getEventPixelSpy.calls.count()).toBe(2);
      expect(getTargetSpy.calls.count()).toBe(2);
      expect(cursorPointerConditionSpy.calls.count()).toBe(2);
    });
  });

  describe('Testing ControlsService', function() {
    var controlsService, CONTROL, EXCLUSIVE_CONTROL, SUBORDINATE_CONTROL;

    beforeEach(function() {
      inject(function($injector) {
        controlsService = $injector.get('ControlsService');
      });

      CONTROL = new anol.control.Control({});
      EXCLUSIVE_CONTROL = new anol.control.Control({
        exclusive: true
      });
      SUBORDINATE_CONTROL = new anol.control.Control({
        subordinate: true
      });
    });

    it('should have rotationControl wrapped in anol.control.Control', function() {
      expect(controlsService.controls.length).toBe(1);
      expect(controlsService.controls[0] instanceof anol.control.Control).toBe(true);
      expect(controlsService.controls[0].olControl instanceof ol.control.Rotate).toBe(true);
    });

    it('should add controls', function() {
      var addControlSpy = spyOn(controlsService, 'addControl').and.callThrough();
      controlsService.addControls([
        CONTROL,
        EXCLUSIVE_CONTROL,
        SUBORDINATE_CONTROL
      ]);
      expect(addControlSpy.calls.count()).toBe(3);
      expect(controlsService.controls.length).toBe(4);
    });

    describe('Testing activate / deactivate controls', function() {
      var CONTROL_2, EXCLUSIVE_CONTROL_2, SUBORDINATE_CONTROL_2;

      beforeEach(function() {

        CONTROL_2 = new anol.control.Control({});
        EXCLUSIVE_CONTROL_2 = new anol.control.Control({
          exclusive: true
        });
        SUBORDINATE_CONTROL_2 = new anol.control.Control({
          subordinate: true
        });

        controlsService.addControls([
          CONTROL,
          CONTROL_2,
          EXCLUSIVE_CONTROL,
          EXCLUSIVE_CONTROL_2,
          SUBORDINATE_CONTROL,
          SUBORDINATE_CONTROL_2
        ]);
      });

      it('should have no active non default control', function() {
        // 0 is default control (Rotate)
        expect(controlsService.controls[0].active).toBe(true);
        // just added controls
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);
      });

      it('should activate a control', function() {
        CONTROL.activate();

        // 0 is default control (Rotate)
        expect(controlsService.controls[0].active).toBe(true);
        // just added controls
        expect(CONTROL.active).toBe(true);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);
      });

      it('should keep normal controls active', function() {
        CONTROL.activate();
        CONTROL_2.activate();
        expect(CONTROL.active).toBe(true);
        expect(CONTROL_2.active).toBe(true);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);

        SUBORDINATE_CONTROL.activate();
        expect(CONTROL.active).toBe(true);
        expect(CONTROL_2.active).toBe(true);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(true);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);

        EXCLUSIVE_CONTROL.activate();
        expect(CONTROL.active).toBe(true);
        expect(CONTROL_2.active).toBe(true);
        expect(EXCLUSIVE_CONTROL.active).toBe(true);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);
      });

      it('should have only one active exclusive control at a time', function() {
        EXCLUSIVE_CONTROL.activate();
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(true);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);

        EXCLUSIVE_CONTROL_2.activate();
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(true);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);
      });

      it('should deactivate all subordinate controls when exclusive control activated', function() {
        SUBORDINATE_CONTROL.activate();
        SUBORDINATE_CONTROL_2.activate();
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(true);
        expect(SUBORDINATE_CONTROL_2.active).toBe(true);

        EXCLUSIVE_CONTROL.activate();
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(true);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);
      });

      it('should activate subordinate controls when exclusiv control deactivated', function() {
        EXCLUSIVE_CONTROL.activate();
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(true);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);

        EXCLUSIVE_CONTROL.deactivate();
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(true);
        expect(SUBORDINATE_CONTROL_2.active).toBe(true);
      });
    });
  });

});<commit_msg>Added MapDirective tests<commit_after>describe('Testing map module', function() {

  var BACKGROUND_LAYER, OVERLAY_LAYER, VIEW;

  beforeEach(module('anol.map'));

  beforeEach(function() {
    BACKGROUND_LAYER = new anol.layer.TiledWMS({
      name: 'background',
      title: 'Background',
      isBackground: true,
      olLayer: {
        source: {
          url: 'http://www.example.org?',
          format: 'image/png',
          params: {
            LAYERS: 'example',
            SRS: 'EPSG:4326'
          }
        }
      }
    });

    OVERLAY_LAYER = new anol.layer.TiledWMS({
      name: 'overlay',
      title: 'Overlay',
      olLayer: {
        source: {
          url: 'http://www.example.org?',
          format: 'image/png',
          params: {
            LAYERS: 'example',
            SRS: 'EPSG:4326'
          }
        }
      }
    });

    VIEW = new ol.View({
      projection: 'EPSG:4326',
      center: [8.2175, 53.1512],
      zoom: 14
    });
  });

  describe('Testing LayersService', function() {
    // TODO test addLayerHandler

    var OTHER_OVERLAY_LAYER = new anol.layer.Feature({
      name: 'feature',
      title: 'Feature',
      olLayer: {
        source: {}
      }
    });

    var layersService;

    beforeEach(function () {
      inject(function($injector) {
        layersService = $injector.get('LayersService');
      });
    });

    it('should add a background layer and create olLayer and olSource correct', function() {
      layersService.addBackgroundLayer(BACKGROUND_LAYER);
      expect(layersService.backgroundLayers.length).toBe(1);
      expect(layersService.backgroundLayers[0]).toEqual(BACKGROUND_LAYER);
      expect(BACKGROUND_LAYER.olLayer instanceof ol.layer.Tile).toBe(true);
      expect(BACKGROUND_LAYER.olLayer.getSource() instanceof ol.source.TileWMS).toBe(true);
      expect(layersService.activeBackgroundLayer()).toEqual(BACKGROUND_LAYER);
      expect(layersService.layerByName('background')).toEqual(BACKGROUND_LAYER);
    });

    it('should add a overlay layer and create olLayer and olSource correct', function() {
      layersService.addOverlayLayer(OVERLAY_LAYER);
      expect(layersService.overlayLayers.length).toBe(1);
      expect(layersService.overlayLayers[0]).toEqual(OVERLAY_LAYER);
      expect(OVERLAY_LAYER.olLayer instanceof ol.layer.Tile).toBe(true);
      expect(OVERLAY_LAYER.olLayer.getSource() instanceof ol.source.TileWMS).toBe(true);
      expect(layersService.layerByName('overlay')).toEqual(OVERLAY_LAYER);
    });

    it('should add a group of overlay layers correct', function() {
      var GROUP = new anol.layer.Group({
        name: 'group',
        title: 'Group',
        layers: [
          OVERLAY_LAYER,
          OTHER_OVERLAY_LAYER
        ]
      });
      layersService.addOverlayLayer(GROUP);
      expect(layersService.overlayLayers[0]).toEqual(GROUP);
      expect(layersService.groupByName('group')).toEqual(GROUP);
      expect(layersService.layerByName('overlay')).toEqual(OVERLAY_LAYER);
      expect(layersService.layerByName('feature')).toEqual(OTHER_OVERLAY_LAYER);
    });

    it('should have same source for both layers', function() {
      layersService.addBackgroundLayer(BACKGROUND_LAYER);
      expect(layersService.backgroundLayers.length).toBe(1);
      layersService.addOverlayLayer(OVERLAY_LAYER);
      expect(layersService.overlayLayers.length).toBe(1);

      expect(layersService.backgroundLayers[0].olLayer.getSource()).toEqual(layersService.overlayLayers[0].olLayer.getSource());
    });

    it('should add background ol layer below overlay ol layer', function() {
      layersService.addOverlayLayer(OVERLAY_LAYER);
      layersService.addBackgroundLayer(BACKGROUND_LAYER);

      expect(layersService.backgroundLayers[0]).toEqual(layersService.layers()[0]);
      expect(layersService.overlayLayers[0]).toEqual(layersService.layers()[1]);
    });
  });

  describe('Testing MapService', function() {
    var mapService;

    beforeEach(function() {
      module(function(MapServiceProvider) {
        MapServiceProvider.addView(VIEW);
      });

      inject(function($injector) {
        mapService = $injector.get('MapService');
      });
    });

    it('should create a ol map without anything', function() {
      var olMap = mapService.getMap();
      expect(olMap instanceof ol.Map).toBe(true);
      expect(olMap.getView()).toEqual(VIEW);
      expect(olMap.getControls().getLength()).toBe(0);
      expect(olMap.getInteractions().getLength()).toBe(0);
      expect(olMap.getLayers().getLength()).toBe(0);
      expect(olMap.getTarget()).toBe(undefined);
    });

    it('should add, execute and remove pointer condition callback', function() {
      var targetStyle = {style: {}};
      var olMap = mapService.getMap();
      // mock used olMap functions
      var getEventPixelSpy = spyOn(olMap, 'getEventPixel').and.returnValue([123, 321]);
      var getTargetSpy = spyOn(olMap, 'getTarget').and.returnValue(targetStyle);
      var cursorPointerConditionSpy = jasmine.createSpy('pointerCondition').and.returnValues(false, true);

      mapService.addCursorPointerCondition(cursorPointerConditionSpy);

      expect(getEventPixelSpy).not.toHaveBeenCalled();
      expect(getTargetSpy).not.toHaveBeenCalled();
      expect(cursorPointerConditionSpy).not.toHaveBeenCalled();

      olMap.dispatchEvent('pointermove');

      expect(getEventPixelSpy).toHaveBeenCalled();
      expect(getTargetSpy).toHaveBeenCalled();
      expect(cursorPointerConditionSpy).toHaveBeenCalled();
      expect(targetStyle.style).toEqual({cursor: ''});

      olMap.dispatchEvent('pointermove');

      expect(getEventPixelSpy.calls.count()).toBe(2);
      expect(getTargetSpy.calls.count()).toBe(2);
      expect(cursorPointerConditionSpy.calls.count()).toBe(2);
      expect(targetStyle.style).toEqual({cursor: 'pointer'});

      mapService.removeCursorPointerCondition(cursorPointerConditionSpy);

      olMap.dispatchEvent('pointermove');

      expect(getEventPixelSpy.calls.count()).toBe(2);
      expect(getTargetSpy.calls.count()).toBe(2);
      expect(cursorPointerConditionSpy.calls.count()).toBe(2);
    });
  });

  describe('Testing ControlsService', function() {
    // TODO add ControlsServiceProviderTest
    var controlsService, CONTROL, EXCLUSIVE_CONTROL, SUBORDINATE_CONTROL;

    beforeEach(function() {
      inject(function($injector) {
        controlsService = $injector.get('ControlsService');
      });

      CONTROL = new anol.control.Control({});
      EXCLUSIVE_CONTROL = new anol.control.Control({
        exclusive: true
      });
      SUBORDINATE_CONTROL = new anol.control.Control({
        subordinate: true
      });
    });

    it('should have rotationControl wrapped in anol.control.Control', function() {
      expect(controlsService.controls.length).toBe(1);
      expect(controlsService.controls[0] instanceof anol.control.Control).toBe(true);
      expect(controlsService.controls[0].olControl instanceof ol.control.Rotate).toBe(true);
    });

    it('should add controls', function() {
      var addControlSpy = spyOn(controlsService, 'addControl').and.callThrough();
      controlsService.addControls([
        CONTROL,
        EXCLUSIVE_CONTROL,
        SUBORDINATE_CONTROL
      ]);
      expect(addControlSpy.calls.count()).toBe(3);
      expect(controlsService.controls.length).toBe(4);
    });

    describe('Testing activate / deactivate controls', function() {
      var CONTROL_2, EXCLUSIVE_CONTROL_2, SUBORDINATE_CONTROL_2;

      beforeEach(function() {

        CONTROL_2 = new anol.control.Control({});
        EXCLUSIVE_CONTROL_2 = new anol.control.Control({
          exclusive: true
        });
        SUBORDINATE_CONTROL_2 = new anol.control.Control({
          subordinate: true
        });

        controlsService.addControls([
          CONTROL,
          CONTROL_2,
          EXCLUSIVE_CONTROL,
          EXCLUSIVE_CONTROL_2,
          SUBORDINATE_CONTROL,
          SUBORDINATE_CONTROL_2
        ]);
      });

      it('should have no active non default control', function() {
        // 0 is default control (Rotate)
        expect(controlsService.controls[0].active).toBe(true);
        // just added controls
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);
      });

      it('should activate a control', function() {
        CONTROL.activate();

        // 0 is default control (Rotate)
        expect(controlsService.controls[0].active).toBe(true);
        // just added controls
        expect(CONTROL.active).toBe(true);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);
      });

      it('should keep normal controls active', function() {
        CONTROL.activate();
        CONTROL_2.activate();
        expect(CONTROL.active).toBe(true);
        expect(CONTROL_2.active).toBe(true);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);

        SUBORDINATE_CONTROL.activate();
        expect(CONTROL.active).toBe(true);
        expect(CONTROL_2.active).toBe(true);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(true);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);

        EXCLUSIVE_CONTROL.activate();
        expect(CONTROL.active).toBe(true);
        expect(CONTROL_2.active).toBe(true);
        expect(EXCLUSIVE_CONTROL.active).toBe(true);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);
      });

      it('should have only one active exclusive control at a time', function() {
        EXCLUSIVE_CONTROL.activate();
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(true);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);

        EXCLUSIVE_CONTROL_2.activate();
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(true);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);
      });

      it('should deactivate all subordinate controls when exclusive control activated', function() {
        SUBORDINATE_CONTROL.activate();
        SUBORDINATE_CONTROL_2.activate();
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(true);
        expect(SUBORDINATE_CONTROL_2.active).toBe(true);

        EXCLUSIVE_CONTROL.activate();
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(true);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);
      });

      it('should activate subordinate controls when exclusiv control deactivated', function() {
        EXCLUSIVE_CONTROL.activate();
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(true);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(false);
        expect(SUBORDINATE_CONTROL_2.active).toBe(false);

        EXCLUSIVE_CONTROL.deactivate();
        expect(CONTROL.active).toBe(false);
        expect(CONTROL_2.active).toBe(false);
        expect(EXCLUSIVE_CONTROL.active).toBe(false);
        expect(EXCLUSIVE_CONTROL_2.active).toBe(false);
        expect(SUBORDINATE_CONTROL.active).toBe(true);
        expect(SUBORDINATE_CONTROL_2.active).toBe(true);
      });
    });
  });

  describe('Testing InteractionsService', function() {
    var interactionsService;

    beforeEach(function() {
      inject(function($injector) {
        interactionsService = $injector.get('InteractionsService');
      });
    });

    // TODO write tests
  });

  describe('Testing MapDirecitve', function() {
    var CONTROL, CONTROL_2;
    var directiveElement, $compile, $rootScope, $scope, $timeout, mapService, olMap, addControlSpy;

    beforeEach(function() {
      module(function(LayersServiceProvider) {
        LayersServiceProvider.setLayers([
          BACKGROUND_LAYER,
          OVERLAY_LAYER
        ]);
      });

      CONTROL = new anol.control.Control({});
      CONTROL_2 = new anol.control.Control({});

      module(function(ControlsServiceProvider) {
        ControlsServiceProvider.setControls([
          CONTROL,
          CONTROL_2
        ]);
      });

      module(function(MapServiceProvider) {
        MapServiceProvider.addView(VIEW);
      });

      inject(function($injector) {
        $rootScope = $injector.get('$rootScope');
        $scope = $rootScope.$new();
        $compile = $injector.get('$compile');
        $timeout = $injector.get('$timeout');
        mapService = $injector.get('MapService');
      });

      var element = '<div anol-map></div>';
      directiveElement = $compile(element)($scope);
      $scope.$digest();

      olMap = directiveElement.isolateScope().map;
      // olMap.addControl make dom operations on not existing elements in this test
      // so we need a spy
      addControlSpy = spyOn(olMap, 'addControl');

      $timeout.flush();
    });

    it('should have added default id and class to element', function() {
      expect(directiveElement.attr('id')).toBe('anol-map');
      expect(directiveElement.hasClass('anol-map')).toBe(true);
    });

    it('should have an olMap with defined layers and controls', function() {
      expect(olMap instanceof ol.Map).toBe(true);
      expect(mapService.getMap()).toEqual(olMap);

      var layers = olMap.getLayers();
      expect(layers.getLength()).toBe(2);
      expect(layers.item(0)).toEqual(BACKGROUND_LAYER.olLayer);
      expect(layers.item(1)).toEqual(OVERLAY_LAYER.olLayer);

      expect(addControlSpy.calls.count()).toBe(2);
    });
  });

});<|endoftext|>


<commit_before>/*
 * This code is awful, are you sure you want to look?
 *
 * https://github.com/zuzak/topiccat
 *
 * ISC license
 */

var projects = {
  "enwikibooks": "wikibooks",
  "commonswiki": "commons",
  "enwiki": "wikipedia",
  "enwikiquote": "wikiquote",
  "enwikisource": "wikisource",
  "enwiktionary": "wiktionary",
  "enwikiversity": "wikiversity",
  "enwikivoyage": "wikivoyage",
  "wikidata": "wikidata" // placeholder
}
$(document).ready(function() {
  updateWikitext();
  /*$('.name').on('input',function() {
    getDesc($('.name').val());
    updatePreview();
  })*/
  $('.name').keyup(function(e) {
    if(e.keyCode==13) {
      getDesc($('.name').val());
      updatePreview();
    } else {
      $('.desc').text('<press return>');
      updatePreview();
      updateWikitext();
    }
  })
  $('.blurb').on('input', updatePreview)
  $('input').on('input', function(){updateWikitext()});
  $('input').on('change', function(){updateWikitext()});
  $('.img').on('input', function() {
    $('.image').hide().attr('src','https://commons.wikimedia.org/wiki/Special:Filepath/' + $('.img').val()).show();
  })
  $('.img').on('load', function() {
    $('.img').slideDown();
  })
  $('.force').click(function(){updateWikitext()});
  $('.desc, .preview, pre').click(function(){
    updatePreview();
    updateWikitext();
  })
})

function getDesc(name) {
  $('.desc').text('Working…');
  var url = "https://en.wikinews.org/w/index.php?action=edit&title=Category:"+encodeURIComponent(name);
  url += "&preload=User:Microchip08/placeholder&preloadparams%5b%5d="+encodeURI($('.wikitext').text());
  $('.editlink').attr('href', url);
  $.getJSON('wikidata.php?name=' + encodeURIComponent(name), function (data) {
    var entry = data[Object.keys(data)[0]]; // use the first
    $('.wikidatalink').attr('href','https://www.wikidata.org/wiki/'+Object.keys(data)[0]);
    $('.wikidatalink').text(Object.keys(data)[0]);
    if(!entry) {
      return;
    }
    if(entry.desc) {
      $('.desc').text(entry.desc)
      $('.blurb').val(indefiniteArticle($('.desc').text()) + ' '+ $('.desc').text());
      updatePreview();
      updateWikitext();
    } else {
      $('.desc').html('[Nothing found.]');
    }
    $('input').prop('checked', false);
    for (project in entry.sites) {
      if(projects[project]) {
        $('.' + projects[project] + ' input').prop('checked', 'true');
        $('.' + projects[project] + ' input').attr('data-article', entry.sites[project]);
      }
    }
    if(entry.image) {
      $('.img').val(entry.image);
      $('.image').attr('src','https://commons.wikimedia.org/wiki/Special:Filepath/' + $('.img').val()).show();
    } else {
      $('.img').val('');
      $('.image').slideUp();
    }
    updateWikitext();
  }).error(function() {
    $('.desc').text('');
  })
}

function updatePreview() {
  var blurb = $('.blurb').val();
  var name = $('.name').val();
  if (blurb && name) {
    $('.preview').html('This is the category for ' + name + ', ' + blurb + '.');
  } else if (name) {
    $('.preview').html('This is the category for ' + name + '.');
  } else {
    $('.preview').html('');
  }
}

function updateWikitext() {
  var wikitext = "{{topic cat\n|offset={{{offset|0}}}";
  if($('.blurb').val()) {
    wikitext += "\n|intro=" + $('.blurb').val();
  }
  if($('.img').val()) {
    var img = $('.img').val();
    wikitext += "\n|image=" + img.substr(img.indexOf(':')+1);
  }
  if($('.caption').val()) {
    var img = $('.img').val();
    wikitext += "\n|caption=" + img.substr(img.indexOf(':')+1);
  }
  var sp = false;
  for (var key in projects) {
    if($('.' + projects[key] + ' input').is(':checked')) {
      var article = $('.'+projects[key]+' input').attr('data-article');
      if(typeof article == 'undefined') {
        article = '{{PAGENAME}}';
      } else {
        article = article.replace($('.name').val(),'{{PAGENAME}}');
      }
      wikitext += '\n|' + projects[key] + '=' + article;
    }
  }
  if (sp) {
    wikitext += "\n|sisterprojects=yes"
  }
  wikitext += "\n}}";
  $('.wikitext').text(wikitext);
}
<commit_msg>editintro<commit_after>/*
 * This code is awful, are you sure you want to look?
 *
 * https://github.com/zuzak/topiccat
 *
 * ISC license
 */

var projects = {
  "enwikibooks": "wikibooks",
  "commonswiki": "commons",
  "enwiki": "wikipedia",
  "enwikiquote": "wikiquote",
  "enwikisource": "wikisource",
  "enwiktionary": "wiktionary",
  "enwikiversity": "wikiversity",
  "enwikivoyage": "wikivoyage",
  "wikidata": "wikidata" // placeholder
}
$(document).ready(function() {
  updateWikitext();
  /*$('.name').on('input',function() {
    getDesc($('.name').val());
    updatePreview();
  })*/
  $('.name').keyup(function(e) {
    if(e.keyCode==13) {
      getDesc($('.name').val());
      updatePreview();
    } else {
      $('.desc').text('<press return>');
      updatePreview();
      updateWikitext();
    }
  })
  $('.blurb').on('input', updatePreview)
  $('input').on('input', function(){updateWikitext()});
  $('input').on('change', function(){updateWikitext()});
  $('.img').on('input', function() {
    $('.image').hide().attr('src','https://commons.wikimedia.org/wiki/Special:Filepath/' + $('.img').val()).show();
  })
  $('.img').on('load', function() {
    $('.img').slideDown();
  })
  $('.force').click(function(){updateWikitext()});
  $('.desc, .preview, pre').click(function(){
    updatePreview();
    updateWikitext();
  })
})

function getDesc(name) {
  $('.desc').text('Working…');
  var url = "https://en.wikinews.org/w/index.php?action=edit&title=Category:"+encodeURIComponent(name);
  url += "&preload=User:Microchip08/placeholder&preloadparams%5b%5d="+encodeURI($('.wikitext').text());
  url += "&summary=Adding {{[[Template:Topic cat|topic cat]]}} ([[User:Microchip08/topiccat|assisted]])"
  url += "&editintro=User:Microchip08/topiccat";
  $('.editlink').attr('href', url);
  $.getJSON('wikidata.php?name=' + encodeURIComponent(name), function (data) {
    var entry = data[Object.keys(data)[0]]; // use the first
    $('.wikidatalink').attr('href','https://www.wikidata.org/wiki/'+Object.keys(data)[0]);
    $('.wikidatalink').text(Object.keys(data)[0]);
    if(!entry) {
      return;
    }
    if(entry.desc) {
      $('.desc').text(entry.desc)
      $('.blurb').val(indefiniteArticle($('.desc').text()) + ' '+ $('.desc').text());
      updatePreview();
      updateWikitext();
    } else {
      $('.desc').html('[Nothing found.]');
    }
    $('input').prop('checked', false);
    for (project in entry.sites) {
      if(projects[project]) {
        $('.' + projects[project] + ' input').prop('checked', 'true');
        $('.' + projects[project] + ' input').attr('data-article', entry.sites[project]);
      }
    }
    if(entry.image) {
      $('.img').val(entry.image);
      $('.image').attr('src','https://commons.wikimedia.org/wiki/Special:Filepath/' + $('.img').val()).show();
    } else {
      $('.img').val('');
      $('.image').slideUp();
    }
    updateWikitext();
  }).error(function() {
    $('.desc').text('');
  })
}

function updatePreview() {
  var blurb = $('.blurb').val();
  var name = $('.name').val();
  if (blurb && name) {
    $('.preview').html('This is the category for ' + name + ', ' + blurb + '.');
  } else if (name) {
    $('.preview').html('This is the category for ' + name + '.');
  } else {
    $('.preview').html('');
  }
}

function updateWikitext() {
  var wikitext = "{{topic cat\n|offset={{{offset|0}}}";
  if($('.blurb').val()) {
    wikitext += "\n|intro=" + $('.blurb').val();
  }
  if($('.img').val()) {
    var img = $('.img').val();
    wikitext += "\n|image=" + img.substr(img.indexOf(':')+1);
  }
  if($('.caption').val()) {
    var img = $('.img').val();
    wikitext += "\n|caption=" + img.substr(img.indexOf(':')+1);
  }
  var sp = false;
  for (var key in projects) {
    if($('.' + projects[key] + ' input').is(':checked')) {
      var article = $('.'+projects[key]+' input').attr('data-article');
      if(typeof article == 'undefined') {
        article = '{{PAGENAME}}';
      } else {
        article = article.replace($('.name').val(),'{{PAGENAME}}');
      }
      wikitext += '\n|' + projects[key] + '=' + article;
    }
  }
  if (sp) {
    wikitext += "\n|sisterprojects=yes"
  }
  wikitext += "\n}}";
  $('.wikitext').text(wikitext);
}
<|endoftext|>


<commit_before>$(document).ready(function() {
  var selectedMainCodes = {};
  //selectedMainCodes['388420'] = {code: '38.84.20', short_code: '388420', text_de: 'Sonstiger chirurgischer Verschluss der Aorta abdominalis'};
  var selectedSideCodes = {};
  var selectedProcedureCodes = {};
    //selectedProcedureCodes['388511'] = {code: '38.85.11', short_code: '388511', text_de: 'Sonstiger chirurgischer Verschluss der A. subclavia'};
  var selectedCodes = {mainDiagnoses: selectedMainCodes, sideDiagnoses: selectedSideCodes, procedures: selectedProcedureCodes};
  var tempSavedCodes = {mainDiagnoses: {}, sideDiagnoses: {}, procedures: {}};

  var editButton = "<button class='zbutton editButton' type='button'>Edit</button>";
  var doneButton = "<button class='zbutton doneButton' type='button'>Done</button>";
  var doneAddButton = "<button class='zbutton doneButton' type='button'>Add</button>";
  var newMainCode = "

";

  var ulSelector = $("ul");
  ulSelector.on("click", ".codeItem", function() {
      var id = this.id;
      var idSelector = $("#"+id);
      var category = $(this).attr("data-category");
      if (category == "mainDiagnoses" && !jQuery.isEmptyObject(selectedMainCodes)) {
          alert("Nur eine Hauptdiagnose ist erlaubt");
          return;
          //var oldMainCode = $("#allListMask li.mainDiagnoses");
          //var oldId = oldMainCode.id;
          //$("#mainDiagnosesList").prepend(oldMainCode);
          //delete selectedCodes["mainDiagnoses"][id];
          //$("#newMainCode").remove();
      }
      // first add buttons and change class
      idSelector.append(editButton);
      idSelector.append(doneButton);
      idSelector.removeClass("codeItem");
      idSelector.addClass("codeMaskItem");
      // then add the code to the codemask lists
      if(tempSavedCodes[category][id]){
          selectedCodes[category][id] = tempSavedCodes[category][id];
      }else if(tempSavedCodes){
          selectedCodes[category][id] = suggestedCodes[category][id];
      }
      $("#allListMask").append(this);
      $("#codeLists #"+id).remove();
      if(!$("#maskTabs ."+category).hasClass("active") && !$("#maskTabs #allTab").hasClass("active")){
          idSelector.hide();
      }
      else{
          idSelector.show();
      }
  });

  $("#mainDiagnosesList").on("click", "li.codeItem", function() {
      $("#newMainCode").remove();
  });

  ulSelector.on("click", ".codeMaskItem div", function() {
      var thisLi = this.parentNode;
      var id = this.parentNode.id;
      var idSelector = $("#"+id);
      // add the code first to the appropriate list
      var category = $(thisLi).attr("data-category");
      delete selectedCodes[category][id];
      $("#" + category +"List").prepend(thisLi);
      // finally change class and remove buttons
      idSelector.removeClass("codeMaskItem");
      idSelector.addClass("codeItem");
      $("#"+id+" button").remove();
  });

  ulSelector.on("click", "li.codeMaskItem.mainDiagnoses div", function() {
      $("#allListMask").append(newMainCode);
      $("#newMainCode").append(editButton);
      $("#newMainCode").append(doneButton);
      $("#newMainCode .doneButton").show();
      var id = this.parentNode.id;
      var category = $("#"+id).attr("data-category");
      if($("#maskTabs ."+category).hasClass("active")){
          $("#newMainCode").show();
      }
      else{
          $("#newMainCode").hide();
      }

  });

  ulSelector.on("click", "button.editButton", function() {
    var id = this.parentNode.id;
    $("#"+id).removeClass("codeMaskItem");
    $("#"+id+" .text_field").attr("contenteditable", "true");
    var divDropdown = "

";
    $("#"+id).append(divDropdown);
    $("#"+id+" .doneButton").show();
    $("#"+id+" .editButton").hide();
    $("#"+id+" div").addClass("editing");
  });

  ulSelector.on("click", "button.doneButton", function() {
    var id = this.parentNode.id;
    $("#"+id+" .text_field").attr("contenteditable", "false");
    $("#"+id+" .doneButton").hide();
    $("#"+id+" .editButton").show();
    $("#"+id+" div").removeClass("editing");

    var codeId = $("#"+id).attr("id");
    var code = $("#"+id).attr("data-code");
    var text = $("#"+id).attr("data-text");
    var category = $("#"+id).attr("data-category");
    $("#"+id).attr("id", codeId);
    $("#"+codeId).attr("data-code", code);
    $("#"+codeId).attr("data-text", text);
    selectedCodes[category][codeId] = {code: code, short_code: codeId, text_de: text};
    tempSavedCodes[category][codeId] = selectedCodes[category][codeId];
    setTimeout(function() {
      $("#"+id).addClass("codeMaskItem");
    }, 100);
    // remove it from the code list
      $("#" + category +"List li#"+codeId).remove();
    //remove datas
  });

  $("#analyse").click(function() {
      var plainText = $("#textArea").text();
      $.ajax({
          url: "/application/analyse",
          type: "post",
          data: { text_field: plainText, selected_codes: selectedCodes}
      });
  });

  $("#textArea, #synonymsList").on("click", ".showWordDetails", function() {
      var word = this.text;
      $.ajax({
          url: "/application/show_word_details",
          type: "post",
          data: { word: word, selected_codes: selectedCodes }
      });
  });

  var key = 0;
  $("#addCodeButton").click(function() {
      key = key+1;
      var id = "newCode"+key;
      var category = $(this).attr("data-category");
      var newLiElement = "

";
      $("#allListMask").append(newLiElement); // codeMaskItem
      var divText = "

";
      $("#"+id).append(divText);
      var divDropdown = "

";
      $("#"+id).append(divDropdown);
      $("#"+id).append(doneAddButton);
      $("#"+id).append(editButton);
      $("#"+id+" .doneButton").show();
      $(this).hide();
  });

  ulSelector.on("keyup", "li div.editing", function() {
      var id = this.parentNode.id;
      interactiveProposals(id);
  });

  function interactiveProposals(id) {
      var searchText = $("#"+id+" div.text_field").text();
      var category = $("#"+id).attr("data-category");
      if(searchText.length >= 2)
      {
          $.ajax({
              url: "/application/search",
              type: "post",
              data: { search_text: searchText, li_id: id, category: category, selected_codes: selectedCodes}
          });
      }
  };

  $("ul#allListMask").on("click","li.dropdown-element", function() {
      var liId = this.parentNode.parentNode.parentNode.id;
      $("#"+liId+" div.text_field").text($(this).text());
      var codeId = $(this).attr("id");
      var code = $(this).attr("data-code");
      var text = $(this).attr("data-text");
      var category = $("#"+liId).attr("data-category");
      $("#"+liId).addClass(category);
      $("#"+liId).attr("id", codeId);
      $("#"+codeId+" .doneButton").show();
      $("#"+codeId).attr("data-code", code);
      $("#"+codeId).attr("data-text", text);
      $("#"+codeId+" div.text_field").removeClass("redBackground");
  });

  ulSelector.on("click", ".newCode button.doneButton", function() {
      var thisLi = this.parentNode;
      var id = this.parentNode.id;
      $("#"+id).removeClass("newCode");
      $("#"+id+" div.dropdown").remove();
      $("#addCodeButton").show();
  });

  function deleteIncompleteCodes(){
      $('#allListMask li.newCode').remove();
  }

  $("#maskTabs li a.filterTab").click(function () {
        var category = $(this).attr("data-category");
        $('#allListMask li').hide();
        $('#allListMask li').filter(function () {
            liCategory = $(this).attr("data-category");
            return  liCategory == category;
        }).show();
        $('#addCodeButton').removeAttr("data-category");
        $('#addCodeButton').hide();
        $('.codeMaskItem .editButton').show();
        deleteIncompleteCodes();
  });

  $("#maskTabs li a#allMaskLink").click(function () {
      $('#allListMask li').show();
      $('#addCodeButton').removeAttr("data-category");
      $('#addCodeButton').hide();
      $('.editButton').hide();
      $('#allListMask li#newMainCode').hide();
      deleteIncompleteCodes();
  });

  $("#maskTabs li a.withAddButton").click(function () {
      var category = $(this).attr("data-category");
      $('#addCodeButton').attr("data-category", category);
      $('#addCodeButton').show();
      $('#allListMask li#newMainCode').hide();
      deleteIncompleteCodes();
  });

});<commit_msg>changed single quotes to double quotes in the jquery selectors<commit_after>$(document).ready(function() {
  var selectedMainCodes = {};
  //selectedMainCodes['388420'] = {code: '38.84.20', short_code: '388420', text_de: 'Sonstiger chirurgischer Verschluss der Aorta abdominalis'};
  var selectedSideCodes = {};
  var selectedProcedureCodes = {};
    //selectedProcedureCodes['388511'] = {code: '38.85.11', short_code: '388511', text_de: 'Sonstiger chirurgischer Verschluss der A. subclavia'};
  var selectedCodes = {mainDiagnoses: selectedMainCodes, sideDiagnoses: selectedSideCodes, procedures: selectedProcedureCodes};
  var tempSavedCodes = {mainDiagnoses: {}, sideDiagnoses: {}, procedures: {}};

  var editButton = "<button class='zbutton editButton' type='button'>Edit</button>";
  var doneButton = "<button class='zbutton doneButton' type='button'>Done</button>";
  var doneAddButton = "<button class='zbutton doneButton' type='button'>Add</button>";
  var newMainCode = "

";

  var ulSelector = $("ul");
  ulSelector.on("click", ".codeItem", function() {
      var id = this.id;
      var idSelector = $("#"+id);
      var category = $(this).attr("data-category");
      if (category == "mainDiagnoses" && !jQuery.isEmptyObject(selectedMainCodes)) {
          alert("Nur eine Hauptdiagnose ist erlaubt");
          return;
          //var oldMainCode = $("#allListMask li.mainDiagnoses");
          //var oldId = oldMainCode.id;
          //$("#mainDiagnosesList").prepend(oldMainCode);
          //delete selectedCodes["mainDiagnoses"][id];
          //$("#newMainCode").remove();
      }
      // first add buttons and change class
      idSelector.append(editButton);
      idSelector.append(doneButton);
      idSelector.removeClass("codeItem");
      idSelector.addClass("codeMaskItem");
      // then add the code to the codemask lists
      if(tempSavedCodes[category][id]){
          selectedCodes[category][id] = tempSavedCodes[category][id];
      }else if(tempSavedCodes){
          selectedCodes[category][id] = suggestedCodes[category][id];
      }
      $("#allListMask").append(this);
      $("#codeLists #"+id).remove();
      if(!$("#maskTabs ."+category).hasClass("active") && !$("#maskTabs #allTab").hasClass("active")){
          idSelector.hide();
      }
      else{
          idSelector.show();
      }
  });

  $("#mainDiagnosesList").on("click", "li.codeItem", function() {
      $("#newMainCode").remove();
  });

  ulSelector.on("click", ".codeMaskItem div", function() {
      var thisLi = this.parentNode;
      var id = this.parentNode.id;
      var idSelector = $("#"+id);
      // add the code first to the appropriate list
      var category = $(thisLi).attr("data-category");
      delete selectedCodes[category][id];
      $("#" + category +"List").prepend(thisLi);
      // finally change class and remove buttons
      idSelector.removeClass("codeMaskItem");
      idSelector.addClass("codeItem");
      $("#"+id+" button").remove();
  });

  ulSelector.on("click", "li.codeMaskItem.mainDiagnoses div", function() {
      $("#allListMask").append(newMainCode);
      $("#newMainCode").append(editButton);
      $("#newMainCode").append(doneButton);
      $("#newMainCode .doneButton").show();
      var id = this.parentNode.id;
      var category = $("#"+id).attr("data-category");
      if($("#maskTabs ."+category).hasClass("active")){
          $("#newMainCode").show();
      }
      else{
          $("#newMainCode").hide();
      }

  });

  ulSelector.on("click", "button.editButton", function() {
    var id = this.parentNode.id;
    $("#"+id).removeClass("codeMaskItem");
    $("#"+id+" .text_field").attr("contenteditable", "true");
    var divDropdown = "

";
    $("#"+id).append(divDropdown);
    $("#"+id+" .doneButton").show();
    $("#"+id+" .editButton").hide();
    $("#"+id+" div").addClass("editing");
  });

  ulSelector.on("click", "button.doneButton", function() {
    var id = this.parentNode.id;
    $("#"+id+" .text_field").attr("contenteditable", "false");
    $("#"+id+" .doneButton").hide();
    $("#"+id+" .editButton").show();
    $("#"+id+" div").removeClass("editing");

    var codeId = $("#"+id).attr("id");
    var code = $("#"+id).attr("data-code");
    var text = $("#"+id).attr("data-text");
    var category = $("#"+id).attr("data-category");
    $("#"+id).attr("id", codeId);
    $("#"+codeId).attr("data-code", code);
    $("#"+codeId).attr("data-text", text);
    selectedCodes[category][codeId] = {code: code, short_code: codeId, text_de: text};
    tempSavedCodes[category][codeId] = selectedCodes[category][codeId];
    setTimeout(function() {
      $("#"+id).addClass("codeMaskItem");
    }, 100);
    // remove it from the code list
      $("#" + category +"List li#"+codeId).remove();
    //remove datas
  });

  $("#analyse").click(function() {
      var plainText = $("#textArea").text();
      $.ajax({
          url: "/application/analyse",
          type: "post",
          data: { text_field: plainText, selected_codes: selectedCodes}
      });
  });

  $("#textArea, #synonymsList").on("click", ".showWordDetails", function() {
      var word = this.text;
      $.ajax({
          url: "/application/show_word_details",
          type: "post",
          data: { word: word, selected_codes: selectedCodes }
      });
  });

  var key = 0;
  $("#addCodeButton").click(function() {
      key = key+1;
      var id = "newCode"+key;
      var category = $(this).attr("data-category");
      var newLiElement = "

";
      $("#allListMask").append(newLiElement); // codeMaskItem
      var divText = "

";
      $("#"+id).append(divText);
      var divDropdown = "

";
      $("#"+id).append(divDropdown);
      $("#"+id).append(editButton);
      $("#"+id).append(doneAddButton);
      $("#"+id+" .doneButton").show();
      $(this).hide();
  });

  ulSelector.on("keyup", "li div.editing", function() {
      var id = this.parentNode.id;
      interactiveProposals(id);
  });

  function interactiveProposals(id) {
      var searchText = $("#"+id+" div.text_field").text();
      var category = $("#"+id).attr("data-category");
      if(searchText.length >= 2)
      {
          $.ajax({
              url: "/application/search",
              type: "post",
              data: { search_text: searchText, li_id: id, category: category, selected_codes: selectedCodes}
          });
      }
  };

  $("ul#allListMask").on("click","li.dropdown-element", function() {
      var liId = this.parentNode.parentNode.parentNode.id;
      $("#"+liId+" div.text_field").text($(this).text());
      var codeId = $(this).attr("id");
      var code = $(this).attr("data-code");
      var text = $(this).attr("data-text");
      var category = $("#"+liId).attr("data-category");
      $("#"+liId).addClass(category);
      $("#"+liId).attr("id", codeId);
      $("#"+codeId+" .doneButton").show();
      $("#"+codeId).attr("data-code", code);
      $("#"+codeId).attr("data-text", text);
      $("#"+codeId+" div.text_field").removeClass("redBackground");
  });

  ulSelector.on("click", ".newCode button.doneButton", function() {
      var thisLi = this.parentNode;
      var id = this.parentNode.id;
      $("#"+id).removeClass("newCode");
      $("#"+id+" div.dropdown").remove();
      $("#addCodeButton").show();
  });

  function deleteIncompleteCodes(){
      $("#allListMask li.newCode").remove();
  }

  $("#maskTabs li a.filterTab").click(function () {
        var category = $(this).attr("data-category");
        $("#allListMask li").hide();
        $("#allListMask li").filter(function () {
            liCategory = $(this).attr("data-category");
            return  liCategory == category;
        }).show();
        $("#addCodeButton").removeAttr("data-category");
        $("#addCodeButton").hide();
        $(".codeMaskItem .editButton").show();
        deleteIncompleteCodes();
  });

  $("#maskTabs li a#allMaskLink").click(function () {
      $("#allListMask li").show();
      $("#addCodeButton").removeAttr("data-category");
      $("#addCodeButton").hide();
      $(".editButton").hide();
      $("#allListMask li#newMainCode").hide();
      deleteIncompleteCodes();
  });

  $("#maskTabs li a.withAddButton").click(function () {
      var category = $(this).attr("data-category");
      $("#addCodeButton").attr("data-category", category);
      $("#addCodeButton").show();
      $("#allListMask li#newMainCode").hide();
      deleteIncompleteCodes();
  });

});<|endoftext|>


<commit_before>(function(angular){
    'use strict';

    var app = angular.module('lesson.controllers', ['ngSanitize']);

    app.controller('MainCtrl', ['$scope', '$sce', 'LessonData', 'Answer', 'Progress', '$location', 'youtubePlayerApi', 'resolveActivityTemplate', '$uibModal', 'Student',
        function ($scope, $sce, LessonData, Answer, Progress, $location, youtubePlayerApi, resolveActivityTemplate, $uibModal, Student) {

            youtubePlayerApi.events.onStateChange = function(event){
                window.onPlayerStateChange.call($scope.currentUnit, event);
                if (event.data === YT.PlayerState.ENDED) {
                    $scope.nextStep();
                    if(!$scope.$$phase) {
                        $scope.$apply();
                    }
                }
            };

            $scope.section = $scope.section || 'video';

            $scope.selectUnit = function(unit) {
                $scope.currentUnit = unit;
                if(unit.video) {
                    $scope.section = 'video';
                    $scope.play(unit.video.youtube_id);
                } else {
                    $scope.section = 'activity';
                }
                $scope.selectActivity(0);
            };

            $scope.locationChange = function(unitIndex) {
                $location.path('/' + unitIndex);
            };

            $scope.nextUnit = function() {
                var index = $scope.lesson.units.indexOf($scope.currentUnit);
                index++;

                if(index < $scope.lesson.units.length) {
                    $location.path('/{0}'.format(index+1));
                } else {
                    // no next unit, so mark it as the end,
                    // and the template will show a next lesson
                    $scope.section = 'end';
                }
            };

            $scope.play = function() {
                if($scope.currentUnit.video){
                    var youtube_id = $scope.currentUnit.video.youtube_id;
                    $scope.section = 'video';

                    youtubePlayerApi.loadPlayer().then(function(player){
                            if(player.getVideoData() &&
                                player.getVideoData().video_id === youtube_id) return;
                            player.cueVideoById(youtube_id);
                    });
                } else {
                    $scope.section = 'activity';
                }
            };

            $scope.getReadingActivityHtml = function() {
                return $sce.trustAsHtml($scope.currentActivity.data.question);
            };

            $scope.selectActivity = function(index) {

                if($scope.currentUnit.activities && $scope.currentUnit.activities.length) {
                    $scope.currentActivity = $scope.currentUnit.activities[index];
                    $scope.activityTemplateUrl = resolveActivityTemplate($scope.currentActivity.type);

                    $scope.answer = Answer.get({activityId: $scope.currentActivity.id}, function(answer) {
                        var exp = $scope.currentActivity.expected;
                        var giv = answer.given;

                        // Test if the answer type is array.
                        // See https://github.com/hacklabr/timtec/wiki/Atividades for details
                        // FIXME should compare $scope.currentActivity.type
                        if ($scope.currentActivity === 'relationship' ||
                            $scope.currentActivity === 'trueorfalse' ||
                            $scope.currentActivity === 'multiplechoice') {
                            // FIXME why this name?
                            // TODO test if professor changes the activity (create a new alternative, the user lost his answer?
                            var shouldUseLastAnswer = (exp !== null && exp !== undefined) &&
                                (angular.isArray(exp) && angular.isArray(giv) && giv.length === exp.length);

                            if (!shouldUseLastAnswer) {
                                // Initialize empty given answer
                                if(angular.isArray($scope.currentActivity.expected)) {
                                    answer.given = $scope.currentActivity.expected.map(function(){});
                                }
                                delete answer.correct;
                            }
                        }
                    },
                    function (error) {
                        console.log('answer does not exists or other errors');
                        var answer = {};
                        if(angular.isArray($scope.currentActivity.expected)) {
                            answer.given = $scope.currentActivity.expected.map(function(){});
                        }
                        $scope.$root.changed = true;
                        $scope.answer = new Answer(answer);
                    });
                } else {
                    $scope.currentActivity = null;
                    $scope.activityTemplateUrl = null;
                }
            };

            $scope.sendAnswer = function() {
                $scope.answer.activity = $scope.currentActivity.id;
                if ($scope.currentActivity.type === 'image')
                    $scope.answer.given = 'image';
                $scope.answer.$update({activityId: $scope.answer.activity}).then(function(answer){
                    $scope.$root.changed = false;
                    $scope.currentUnit.progress = Progress.get({unit: $scope.currentUnit.id});
                    answer.updated = true;
                    return answer;
                });
            };

            $scope.sendAnswerText = function() {
                $scope.currentUnit.progress = Progress.save({unit: $scope.currentUnit.id});
                $scope.nextUnit();
            };

            $scope.sendAnswerText = function() {
                var progress;
                progress = Progress.complete($scope.currentUnit.id);
                $scope.currentUnit.progress = progress;
                $scope.nextUnit();
            };

            $scope.nextStep = function(skipComment) {
                var progress;
                if($scope.section === 'video') {
                    // Test if currentUnit has an activity
                    if(angular.isArray($scope.currentUnit.activities) &&
                        $scope.currentUnit.activities.length > 0) {
                        $scope.section = 'activity';
                    } else {
                        $scope.currentUnit.progress = Progress.save({unit: $scope.currentUnit.id});
                        $scope.nextUnit();
                    }
                } else {
                    // Test if must display activity comments
                    if($scope.section === 'activity' && !skipComment && $scope.currentActivity.comment) {
                        $scope.section = 'comment';
                    } else {
                        var index = $scope.currentUnit.activities.indexOf($scope.currentActivity);
                        // Test if this is the last activity in the currentUnit unit
                        if(index+1 === $scope.currentUnit.activities.length) {
                            $scope.currentUnit.progress = Progress.save({unit: $scope.currentUnit.id});
                            $scope.nextUnit();
                        } else {
                            $scope.selectActivity(index + 1);
                            $scope.section = 'activity';
                        }
                    }
                }
            };

            $scope.slide_activity_update_position = function(){
                $scope.current_position_slides = $scope.currentUnit.activities.indexOf($scope.currentActivity) + 1;
            };

            $scope.next_activity_from_image = function() {
                $scope.sendAnswer();
                $scope.nextStep(true);
                $scope.slide_activity_update_position();
            };

            $scope.previous_activity_from_image = function() {
                if($scope.section === 'activity') {
                    var index = $scope.currentUnit.activities.indexOf($scope.currentActivity);
                    if (index > 0) {
                        $scope.selectActivity(index - 1);
                        $scope.section = 'activity';
                    } else {
                        // Volta pra unidade anterior?
//                        $scope.currentUnit.progress = Progress.get({unit: $scope.currentUnit.id});
//                        $scope.nextUnit();
                    }
                    $scope.slide_activity_update_position();
                }
            };

            LessonData.then(function(lesson){
                $scope.lesson = lesson;

                var index = /\/(\d+)/.extract($location.path(), 1);
                index = parseInt(index, 10) - 1 || 0;
                $scope.selectUnit(lesson.units[index]);
                $scope.play();

                $scope.$on('$locationChangeSuccess', function (event, newLoc, oldLoc){
                   index = /#\/(\d+)/.extract(document.location.hash, 1);
                   index = parseInt(index, 10) - 1 || 0;
                   $scope.selectUnit(lesson.units[index]);
                });
            });

            $scope.$watch("section", function(currentSection, lastSection){
                if($scope.lesson && $scope.lesson.is_course_last_lesson && currentSection === 'end'){
                    $scope.courseComplete();
                }
            });

            $scope.courseComplete = function () {
                var modalInstance = $uibModal.open({
                    templateUrl: 'courseCompleteModal.html',
                    controller: ['$scope', '$uibModalInstance', 'course_slug', 'Student', 'CourseCertification',
                        'CertificationProcess', CourseCompleteModalInstanceCtrl],
                    resolve: {
                        course_slug: function () {
                            return $scope.lesson.course;
                        }
                    }
                });
                modalInstance.result.then(function (new_message) {

                });
            };

            var CourseCompleteModalInstanceCtrl = function ($scope, $uibModalInstance, course_slug, Student,
                CourseCertification, CertificationProcess) {
                // Show spinner while creating the receipt

                $scope.cs = false;

                Student.query({'course__slug' : course_slug}, function(cs){
                    $scope.cs = cs.pop();
                    if($scope.cs.can_emmit_receipt){
                        CourseCertification.query({'course_student' : $scope.cs.id}, function(receipt){
                            $scope.receipt = receipt.pop();
                        });
                    }
                });

                $scope.createCertificationProcess = function (){
                    if(!$scope.cs) return;
                    var cp = new CertificationProcess();
                    var cs = $scope.cs;

                    cp.student = cs.user.id;
                    cp.klass = cs.current_class.id;
                    if(!cs.certificate)
                        cp.course_certification = null;
                    else {
                        cp.course_certification = cs.certificate.link_hash;
                    }
                    cp.evaluation = null;
                    cp.$save(function(new_cp){
                        cs.certificate.processes = cs.certificate.processes || [];
                        cs.certificate.processes.push(new_cp);
                    });
                }
                $scope.cancel = function () {
                        $uibModalInstance.dismiss();
                };
            }
        }
    ]);

})(angular);

(function() {
    var _pauseFlag = false;
    var start, whole;

    var lastState = -1;

    function  onPlayerStateChange (event) {
        var video_id = event.target.getVideoData().video_id;

        if (event.data == YT.PlayerState.ENDED){
            if(! (lastState === YT.PlayerState.PAUSED ||   // workaround, YT in html5 mode will fire
                  lastState === YT.PlayerState.PLAYING)) { // event with ENDED state after cue video.
                event.data = lastState;
            } else {
                if (whole === 'started') {
                    var stop = new Date().getTime();
                    var delta_s = (stop - start) / 1000;
                    whole = 'ended';
                }
            }
        }

        if (event.data == YT.PlayerState.PLAYING){
                _pauseFlag = false;
                if (whole !== 'ended' && whole !== 'started') {
                    start = new Date().getTime();
                    whole = 'started';
                }
        }

        if (event.data == YT.PlayerState.PAUSED && _pauseFlag === false){
            _pauseFlag = true;
        }

        lastState = event.data;
    }
    window.onPlayerStateChange = onPlayerStateChange;
})();
<commit_msg>Fixed bug that made a slide count error when changing units<commit_after>(function(angular){
    'use strict';

    var app = angular.module('lesson.controllers', ['ngSanitize']);

    app.controller('MainCtrl', ['$scope', '$sce', 'LessonData', 'Answer', 'Progress', '$location', 'youtubePlayerApi', 'resolveActivityTemplate', '$uibModal', 'Student',
        function ($scope, $sce, LessonData, Answer, Progress, $location, youtubePlayerApi, resolveActivityTemplate, $uibModal, Student) {

            youtubePlayerApi.events.onStateChange = function(event){
                window.onPlayerStateChange.call($scope.currentUnit, event);
                if (event.data === YT.PlayerState.ENDED) {
                    $scope.nextStep();
                    if(!$scope.$$phase) {
                        $scope.$apply();
                    }
                }
            };

            $scope.section = $scope.section || 'video';

            $scope.selectUnit = function(unit) {
                $scope.currentUnit = unit;
                if(unit.video) {
                    $scope.section = 'video';
                    $scope.play(unit.video.youtube_id);
                } else {
                    $scope.section = 'activity';
                }
                $scope.selectActivity(0);
            };

            $scope.locationChange = function(unitIndex) {
                $location.path('/' + unitIndex);
            };

            $scope.nextUnit = function() {
                var index = $scope.lesson.units.indexOf($scope.currentUnit);
                index++;

                if(index < $scope.lesson.units.length) {
                    $location.path('/{0}'.format(index+1));
                } else {
                    // no next unit, so mark it as the end,
                    // and the template will show a next lesson
                    $scope.section = 'end';
                }
            };

            $scope.play = function() {
                if($scope.currentUnit.video){
                    var youtube_id = $scope.currentUnit.video.youtube_id;
                    $scope.section = 'video';

                    youtubePlayerApi.loadPlayer().then(function(player){
                            if(player.getVideoData() &&
                                player.getVideoData().video_id === youtube_id) return;
                            player.cueVideoById(youtube_id);
                    });
                } else {
                    $scope.section = 'activity';
                }
            };

            $scope.getReadingActivityHtml = function() {
                return $sce.trustAsHtml($scope.currentActivity.data.question);
            };

            $scope.selectActivity = function(index) {

                if($scope.currentUnit.activities && $scope.currentUnit.activities.length) {
                    $scope.currentActivity = $scope.currentUnit.activities[index];
                    $scope.activityTemplateUrl = resolveActivityTemplate($scope.currentActivity.type);

                    $scope.answer = Answer.get({activityId: $scope.currentActivity.id}, function(answer) {
                        var exp = $scope.currentActivity.expected;
                        var giv = answer.given;

                        // Test if the answer type is array.
                        // See https://github.com/hacklabr/timtec/wiki/Atividades for details
                        // FIXME should compare $scope.currentActivity.type
                        if ($scope.currentActivity === 'relationship' ||
                            $scope.currentActivity === 'trueorfalse' ||
                            $scope.currentActivity === 'multiplechoice') {
                            // FIXME why this name?
                            // TODO test if professor changes the activity (create a new alternative, the user lost his answer?
                            var shouldUseLastAnswer = (exp !== null && exp !== undefined) &&
                                (angular.isArray(exp) && angular.isArray(giv) && giv.length === exp.length);

                            if (!shouldUseLastAnswer) {
                                // Initialize empty given answer
                                if(angular.isArray($scope.currentActivity.expected)) {
                                    answer.given = $scope.currentActivity.expected.map(function(){});
                                }
                                delete answer.correct;
                            }
                        }
                    },
                    function (error) {
                        console.log('answer does not exists or other errors');
                        var answer = {};
                        if(angular.isArray($scope.currentActivity.expected)) {
                            answer.given = $scope.currentActivity.expected.map(function(){});
                        }
                        $scope.$root.changed = true;
                        $scope.answer = new Answer(answer);
                    });
                } else {
                    $scope.currentActivity = null;
                    $scope.activityTemplateUrl = null;
                }
            };

            $scope.sendAnswer = function() {
                $scope.answer.activity = $scope.currentActivity.id;
                if ($scope.currentActivity.type === 'image')
                    $scope.answer.given = 'image';
                $scope.answer.$update({activityId: $scope.answer.activity}).then(function(answer){
                    $scope.$root.changed = false;
                    $scope.currentUnit.progress = Progress.get({unit: $scope.currentUnit.id});
                    answer.updated = true;
                    return answer;
                });
            };

            $scope.sendAnswerText = function() {
                $scope.currentUnit.progress = Progress.save({unit: $scope.currentUnit.id});
                $scope.nextUnit();
            };

            $scope.sendAnswerText = function() {
                var progress;
                progress = Progress.complete($scope.currentUnit.id);
                $scope.currentUnit.progress = progress;
                $scope.nextUnit();
            };

            $scope.nextStep = function(skipComment) {
                var progress;
                if($scope.section === 'video') {
                    // Test if currentUnit has an activity
                    if(angular.isArray($scope.currentUnit.activities) &&
                        $scope.currentUnit.activities.length > 0) {
                        $scope.section = 'activity';
                    } else {
                        $scope.currentUnit.progress = Progress.save({unit: $scope.currentUnit.id});
                        $scope.nextUnit();
                    }
                } else {
                    // Test if must display activity comments
                    if($scope.section === 'activity' && !skipComment && $scope.currentActivity.comment) {
                        $scope.section = 'comment';
                    } else {
                        var index = $scope.currentUnit.activities.indexOf($scope.currentActivity);
                        // Test if this is the last activity in the currentUnit unit
                        if(index+1 === $scope.currentUnit.activities.length) {
                            $scope.currentUnit.progress = Progress.save({unit: $scope.currentUnit.id});
                            $scope.nextUnit();
                        } else {
                            $scope.selectActivity(index + 1);
                            $scope.section = 'activity';
                        }
                    }
                }
            };

            $scope.slide_activity_update_position = function(){
                $scope.current_position_slides = $scope.currentUnit.activities.indexOf($scope.currentActivity) + 1;
            };

            $scope.next_activity_from_image = function() {
              var changeUnit = false;
              if($scope.current_position_slides === $scope.currentUnit.activities.length){
                  changeUnit = true;
              }

              $scope.sendAnswer();
              $scope.nextStep(true);
              if(changeUnit === false){
                  $scope.slide_activity_update_position();
              } else {
                  $scope.current_position_slides = 1;
              }
            };

            $scope.previous_activity_from_image = function() {
                if($scope.section === 'activity') {
                    var index = $scope.currentUnit.activities.indexOf($scope.currentActivity);
                    if (index > 0) {
                        $scope.selectActivity(index - 1);
                        $scope.section = 'activity';
                    } else {
                        // Volta pra unidade anterior?
//                        $scope.currentUnit.progress = Progress.get({unit: $scope.currentUnit.id});
//                        $scope.nextUnit();
                    }
                    $scope.slide_activity_update_position();
                }
            };

            LessonData.then(function(lesson){
                $scope.lesson = lesson;

                var index = /\/(\d+)/.extract($location.path(), 1);
                index = parseInt(index, 10) - 1 || 0;
                $scope.selectUnit(lesson.units[index]);
                $scope.play();

                $scope.$on('$locationChangeSuccess', function (event, newLoc, oldLoc){
                   index = /#\/(\d+)/.extract(document.location.hash, 1);
                   index = parseInt(index, 10) - 1 || 0;
                   $scope.selectUnit(lesson.units[index]);
                });
            });

            $scope.$watch("section", function(currentSection, lastSection){
                if($scope.lesson && $scope.lesson.is_course_last_lesson && currentSection === 'end'){
                    $scope.courseComplete();
                }
            });

            $scope.courseComplete = function () {
                var modalInstance = $uibModal.open({
                    templateUrl: 'courseCompleteModal.html',
                    controller: ['$scope', '$uibModalInstance', 'course_slug', 'Student', 'CourseCertification',
                        'CertificationProcess', CourseCompleteModalInstanceCtrl],
                    resolve: {
                        course_slug: function () {
                            return $scope.lesson.course;
                        }
                    }
                });
                modalInstance.result.then(function (new_message) {

                });
            };

            var CourseCompleteModalInstanceCtrl = function ($scope, $uibModalInstance, course_slug, Student,
                CourseCertification, CertificationProcess) {
                // Show spinner while creating the receipt

                $scope.cs = false;

                Student.query({'course__slug' : course_slug}, function(cs){
                    $scope.cs = cs.pop();
                    if($scope.cs.can_emmit_receipt){
                        CourseCertification.query({'course_student' : $scope.cs.id}, function(receipt){
                            $scope.receipt = receipt.pop();
                        });
                    }
                });

                $scope.createCertificationProcess = function (){
                    if(!$scope.cs) return;
                    var cp = new CertificationProcess();
                    var cs = $scope.cs;

                    cp.student = cs.user.id;
                    cp.klass = cs.current_class.id;
                    if(!cs.certificate)
                        cp.course_certification = null;
                    else {
                        cp.course_certification = cs.certificate.link_hash;
                    }
                    cp.evaluation = null;
                    cp.$save(function(new_cp){
                        cs.certificate.processes = cs.certificate.processes || [];
                        cs.certificate.processes.push(new_cp);
                    });
                }
                $scope.cancel = function () {
                        $uibModalInstance.dismiss();
                };
            }
        }
    ]);

})(angular);

(function() {
    var _pauseFlag = false;
    var start, whole;

    var lastState = -1;

    function  onPlayerStateChange (event) {
        var video_id = event.target.getVideoData().video_id;

        if (event.data == YT.PlayerState.ENDED){
            if(! (lastState === YT.PlayerState.PAUSED ||   // workaround, YT in html5 mode will fire
                  lastState === YT.PlayerState.PLAYING)) { // event with ENDED state after cue video.
                event.data = lastState;
            } else {
                if (whole === 'started') {
                    var stop = new Date().getTime();
                    var delta_s = (stop - start) / 1000;
                    whole = 'ended';
                }
            }
        }

        if (event.data == YT.PlayerState.PLAYING){
                _pauseFlag = false;
                if (whole !== 'ended' && whole !== 'started') {
                    start = new Date().getTime();
                    whole = 'started';
                }
        }

        if (event.data == YT.PlayerState.PAUSED && _pauseFlag === false){
            _pauseFlag = true;
        }

        lastState = event.data;
    }
    window.onPlayerStateChange = onPlayerStateChange;
})();
<|endoftext|>


<commit_before>// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';

foam.CLASS({
  package: 'org.chromium.webidl',
  name: 'IDLFragmentExtractor',
  documentation: 'extracts IDL Fragments from HTML files',
  requires: [
    'foam.parsers.html.HTMLLexer'
  ],

  properties: [
    {
      name: 'file',
      of: 'org.chromium.webidl.HTMLFileContent',
      postSet: function(_, file) {
        this.idlFragments = this.extract();
      },
    },
    {
      name: 'idlFragments',
      // description: 'all idlFragments found in the parsed HTML file',
    },
  ],

  methods: [
    function extract() {
      var self = this;
      var lexer = self.HTMLLexer.create();
      var OPEN = lexer.TagType.OPEN.name;
      var CLOSE = lexer.TagType.CLOSE.name;
      var extractAttr = function(node, attrName) {
        var retVal;
        node.attributes.some(function(attr) {
          if (attr.name === attrName) {
            retVal = attr.value.split(' ');
          }
        });
        return retVal;
      };

      var results = lexer.parseString(self.file.content).value;

      var idlFragments = [];
      var tagStack = [];            // Used for tag matching.
      var excludeStack = [];        // Used for tracking excluded (example/note) tags.
      var tagMatching = true;       // Set whe not inside a pre tag of interest.
      var content = '';             // Used to group together related content.
      for (var i = 0; i < results.length; i++) {
        var item = results[i];
        var isTag = lexer.Tag.isInstance(item);

        if (!tagMatching) {
          // Ignoring all tags. Only extracting text within pre tags.
          if (isTag && item.nodeName === 'pre') {
            tagMatching = true;
            tagStack.pop();
            idlFragments.push(lexer.lib.unescapeString(content));
            content = '';
          } else {
            content += isTag ? '' : item;
          }
        } else if (isTag) {
          var top = tagStack[tagStack.length - 1];
          var classes = extractAttr(item, 'class');
          var isIDL = classes && classes.includes('idl');
          var isExcluded = function(cls) {
            return cls && (cls.includes('example') || cls.includes('note'));
          };

          if (item.type.name === OPEN) {
            if (isExcluded(classes)) {
              excludeStack.push(item);
            } else if (excludeStack.length === 0 && item.nodeName === 'pre' && isIDL) {
              // Found a
.
              // Ignore tags and only extract text now.
              tagMatching = false;
            }
            tagStack.push(item);
          } else if (top && item.type.name === CLOSE && top.nodeName === item.nodeName) {
            var parentCls = extractAttr(top, 'class');
            var excludeStackTop = excludeStack[excludeStack.length - 1];
            if (isExcluded(parentCls) && item.nodeName === excludeStackTop.nodeName) {
              excludeStack.pop();
            }
            tagStack.pop();
          } else {
            // Mismatched close tags and OPEN_CLOSE tags are ignored.
          }
        }
      }
      return idlFragments;
    }
  ]
});

<commit_msg>Adding Future message with regards to nested pre tags<commit_after>// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';

foam.CLASS({
  package: 'org.chromium.webidl',
  name: 'IDLFragmentExtractor',
  documentation: 'extracts IDL Fragments from HTML files',
  requires: [
    'foam.parsers.html.HTMLLexer'
  ],

  properties: [
    {
      name: 'file',
      of: 'org.chromium.webidl.HTMLFileContent',
      postSet: function(_, file) {
        this.idlFragments = this.extract();
      },
    },
    {
      name: 'idlFragments',
      // description: 'all idlFragments found in the parsed HTML file',
    },
  ],

  methods: [
    function extract() {
      var self = this;
      var lexer = self.HTMLLexer.create();
      var OPEN = lexer.TagType.OPEN.name;
      var CLOSE = lexer.TagType.CLOSE.name;
      var extractAttr = function(node, attrName) {
        var retVal;
        node.attributes.some(function(attr) {
          if (attr.name === attrName) {
            retVal = attr.value.split(' ');
          }
        });
        return retVal;
      };

      var results = lexer.parseString(self.file.content).value;

      var idlFragments = [];
      var tagStack = [];            // Used for tag matching.
      var excludeStack = [];        // Used for tracking excluded (example/note) tags.
      var tagMatching = true;       // Set whe not inside a pre tag of interest.
      var content = '';             // Used to group together related content.
      for (var i = 0; i < results.length; i++) {
        var item = results[i];
        var isTag = lexer.Tag.isInstance(item);

        // FUTURE: Handle nested pre tags.
        // As of this writing, there has not been any IDL fragments
        // that has been found within nested pre tags.
        if (!tagMatching) {
          // Ignoring all tags. Only extracting text within pre tags.
          if (isTag && item.nodeName === 'pre') {
            tagMatching = true;
            tagStack.pop();
            idlFragments.push(lexer.lib.unescapeString(content));
            content = '';
          } else {
            content += isTag ? '' : item;
          }
        } else if (isTag) {
          var top = tagStack[tagStack.length - 1];
          var classes = extractAttr(item, 'class');
          var isIDL = classes && classes.includes('idl');
          var isExcluded = function(cls) {
            return cls && (cls.includes('example') || cls.includes('note'));
          };

          if (item.type.name === OPEN) {
            if (isExcluded(classes)) {
              excludeStack.push(item);
            } else if (excludeStack.length === 0 && item.nodeName === 'pre' && isIDL) {
              // Found a
.
              // Ignore tags and only extract text now.
              tagMatching = false;
            }
            tagStack.push(item);
          } else if (top && item.type.name === CLOSE && top.nodeName === item.nodeName) {
            var parentCls = extractAttr(top, 'class');
            var excludeStackTop = excludeStack[excludeStack.length - 1];
            if (isExcluded(parentCls) && item.nodeName === excludeStackTop.nodeName) {
              excludeStack.pop();
            }
            tagStack.pop();
          } else {
            // Mismatched close tags and OPEN_CLOSE tags are ignored.
          }
        }
      }
      return idlFragments;
    }
  ]
});

<|endoftext|>


<commit_before>/* _TO_SVG_START_ */
(function() {
  var toFixed = fabric.util.toFixed,
      NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;

  fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {

    /**
     * @private
     */
    _setSVGTextLineText: function(lineIndex, textSpans, height, textLeftOffset, textTopOffset, textBgRects) {
      if (!this.styles[lineIndex]) {
        fabric.Text.prototype._setSVGTextLineText.call(this,
          lineIndex, textSpans, height, textLeftOffset, textTopOffset);
      }
      else {
        this._setSVGTextLineChars(
          lineIndex, textSpans, height, textLeftOffset, textBgRects);
      }
    },

    /**
     * @private
     */
    _setSVGTextLineChars: function(lineIndex, textSpans, height, textLeftOffset, textBgRects) {

      var chars = this._textLines[lineIndex],
          charOffset = 0,
          lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex)) - this.width / 2,
          lineOffset = this._getSVGLineTopOffset(lineIndex),
          heightOfLine = this._getHeightOfLine(this.ctx, lineIndex);

      for (var i = 0, len = chars.length; i < len; i++) {
        var styleDecl = this._getStyleDeclaration(lineIndex, i) || { };

        textSpans.push(
          this._createTextCharSpan(
            chars[i], styleDecl, lineLeftOffset, lineOffset.lineTop + lineOffset.offset, charOffset));

        var charWidth = this._getWidthOfChar(this.ctx, chars[i], lineIndex, i);

        if (styleDecl.textBackgroundColor) {
          textBgRects.push(
            this._createTextCharBg(
              styleDecl, lineLeftOffset, lineOffset.lineTop, heightOfLine, charWidth, charOffset));
        }

        charOffset += charWidth;
      }
    },

    /**
     * @private
     */
    _getSVGLineTopOffset: function(lineIndex) {
      var lineTopOffset = 0, lastHeight = 0;
      for (var j = 0; j < lineIndex; j++) {
        lineTopOffset += this._getHeightOfLine(this.ctx, j);
      }
      lastHeight = this._getHeightOfLine(this.ctx, j);
      return {
        lineTop: lineTopOffset,
        offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult)
      };
    },

    /**
     * @private
     */
    _createTextCharBg: function(styleDecl, lineLeftOffset, lineTopOffset, heightOfLine, charWidth, charOffset) {
      return [
        //jscs:disable validateIndentation
        '\t\t<rect fill="', styleDecl.textBackgroundColor,
        '" x="', toFixed(lineLeftOffset + charOffset, NUM_FRACTION_DIGITS),
        '" y="', toFixed(lineTopOffset - this.height/2, NUM_FRACTION_DIGITS),
        '" width="', toFixed(charWidth, NUM_FRACTION_DIGITS),
        '" height="', toFixed(heightOfLine / this.lineHeight, NUM_FRACTION_DIGITS),
        '"></rect>\n'
        //jscs:enable validateIndentation
      ].join('');
    },

    /**
     * @private
     */
    _createTextCharSpan: function(_char, styleDecl, lineLeftOffset, lineTopOffset, charOffset) {

      var fillStyles = this.getSvgStyles.call(fabric.util.object.extend({
        visible: true,
        fill: this.fill,
        stroke: this.stroke,
        type: 'text',
        getSvgFilter: fabric.Object.prototype.getSvgFilter
      }, styleDecl));

      return [
        //jscs:disable validateIndentation
        '\t\t\t<tspan x="', toFixed(lineLeftOffset + charOffset, NUM_FRACTION_DIGITS), '" y="',
          toFixed(lineTopOffset - this.height/2, NUM_FRACTION_DIGITS), '" ',
          (styleDecl.fontFamily ? 'font-family="' + styleDecl.fontFamily.replace(/"/g, '\'') + '" ': ''),
          (styleDecl.fontSize ? 'font-size="' + styleDecl.fontSize + '" ': ''),
          (styleDecl.fontStyle ? 'font-style="' + styleDecl.fontStyle + '" ': ''),
          (styleDecl.fontWeight ? 'font-weight="' + styleDecl.fontWeight + '" ': ''),
          (styleDecl.textDecoration ? 'text-decoration="' + styleDecl.textDecoration + '" ': ''),
          'style="', fillStyles, '">',
          fabric.util.string.escapeXml(_char),
        '</tspan>\n'
        //jscs:enable validateIndentation
      ].join('');
    }
  });
})();
/* _TO_SVG_END_ */
<commit_msg>Proper fix for style detection<commit_after>/* _TO_SVG_START_ */
(function() {
  var toFixed = fabric.util.toFixed,
      NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;

  fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {

    /**
     * @private
     */
    _setSVGTextLineText: function(lineIndex, textSpans, height, textLeftOffset, textTopOffset, textBgRects) {
      if (!this._getLineStyle(lineIndex)) {
        fabric.Text.prototype._setSVGTextLineText.call(this,
          lineIndex, textSpans, height, textLeftOffset, textTopOffset);
      }
      else {
        this._setSVGTextLineChars(
          lineIndex, textSpans, height, textLeftOffset, textBgRects);
      }
    },

    /**
     * @private
     */
    _setSVGTextLineChars: function(lineIndex, textSpans, height, textLeftOffset, textBgRects) {

      var chars = this._textLines[lineIndex],
          charOffset = 0,
          lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex)) - this.width / 2,
          lineOffset = this._getSVGLineTopOffset(lineIndex),
          heightOfLine = this._getHeightOfLine(this.ctx, lineIndex);

      for (var i = 0, len = chars.length; i < len; i++) {
        var styleDecl = this._getStyleDeclaration(lineIndex, i) || { };

        textSpans.push(
          this._createTextCharSpan(
            chars[i], styleDecl, lineLeftOffset, lineOffset.lineTop + lineOffset.offset, charOffset));

        var charWidth = this._getWidthOfChar(this.ctx, chars[i], lineIndex, i);

        if (styleDecl.textBackgroundColor) {
          textBgRects.push(
            this._createTextCharBg(
              styleDecl, lineLeftOffset, lineOffset.lineTop, heightOfLine, charWidth, charOffset));
        }

        charOffset += charWidth;
      }
    },

    /**
     * @private
     */
    _getSVGLineTopOffset: function(lineIndex) {
      var lineTopOffset = 0, lastHeight = 0;
      for (var j = 0; j < lineIndex; j++) {
        lineTopOffset += this._getHeightOfLine(this.ctx, j);
      }
      lastHeight = this._getHeightOfLine(this.ctx, j);
      return {
        lineTop: lineTopOffset,
        offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult)
      };
    },

    /**
     * @private
     */
    _createTextCharBg: function(styleDecl, lineLeftOffset, lineTopOffset, heightOfLine, charWidth, charOffset) {
      return [
        //jscs:disable validateIndentation
        '\t\t<rect fill="', styleDecl.textBackgroundColor,
        '" x="', toFixed(lineLeftOffset + charOffset, NUM_FRACTION_DIGITS),
        '" y="', toFixed(lineTopOffset - this.height/2, NUM_FRACTION_DIGITS),
        '" width="', toFixed(charWidth, NUM_FRACTION_DIGITS),
        '" height="', toFixed(heightOfLine / this.lineHeight, NUM_FRACTION_DIGITS),
        '"></rect>\n'
        //jscs:enable validateIndentation
      ].join('');
    },

    /**
     * @private
     */
    _createTextCharSpan: function(_char, styleDecl, lineLeftOffset, lineTopOffset, charOffset) {

      var fillStyles = this.getSvgStyles.call(fabric.util.object.extend({
        visible: true,
        fill: this.fill,
        stroke: this.stroke,
        type: 'text',
        getSvgFilter: fabric.Object.prototype.getSvgFilter
      }, styleDecl));

      return [
        //jscs:disable validateIndentation
        '\t\t\t<tspan x="', toFixed(lineLeftOffset + charOffset, NUM_FRACTION_DIGITS), '" y="',
          toFixed(lineTopOffset - this.height/2, NUM_FRACTION_DIGITS), '" ',
          (styleDecl.fontFamily ? 'font-family="' + styleDecl.fontFamily.replace(/"/g, '\'') + '" ': ''),
          (styleDecl.fontSize ? 'font-size="' + styleDecl.fontSize + '" ': ''),
          (styleDecl.fontStyle ? 'font-style="' + styleDecl.fontStyle + '" ': ''),
          (styleDecl.fontWeight ? 'font-weight="' + styleDecl.fontWeight + '" ': ''),
          (styleDecl.textDecoration ? 'text-decoration="' + styleDecl.textDecoration + '" ': ''),
          'style="', fillStyles, '">',
          fabric.util.string.escapeXml(_char),
        '</tspan>\n'
        //jscs:enable validateIndentation
      ].join('');
    }
  });
})();
/* _TO_SVG_END_ */
<|endoftext|>


<commit_before>import { createGlobalStyle } from 'styled-components'

import {
  colorTextPrimary,
  colorTextFaint,
  colorBackground,
  amberA200,
  amberA400,
  grey700,
  grey800,
  CardLayer,
} from './colors'

const GlobalStyle = createGlobalStyle`
  * {
    box-sizing: border-box;
  }

  html {
    font-family: Roboto, sans-serif;
    font-weight: normal;
    color: ${colorTextPrimary};
    font-size: 14px;
    line-height: 1.5;
    background-color: ${colorBackground};
  }

  html, body, #app, #app > div {
    -webkit-text-size-adjust: 100%;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    -webkit-touch-callout: none;
    height: 100%;
    margin: 0;
    padding: 0;
    position: relative;
  }

  [disabled] {
    color: ${colorTextFaint};
  }

  a:link, a:visited {
    color: ${amberA400};
    text-decoration: none;
  }

  a:hover, a:active {
    color: ${amberA200};
    text-decoration: underline;
  }

  svg {
    fill: currentColor;
  }

  input:-webkit-autofill {
    -webkit-box-shadow: 0 0 0px 1000px ${grey800} inset !important;
    -webkit-text-fill-color: ${colorTextPrimary} !important;
    caret-color: #fff !important;

    ${CardLayer} & {
      -webkit-box-shadow: 0 0 0px 1000px ${grey700} inset !important;
      -webkit-text-fill-color: ${colorTextPrimary} !important;
      caret-color: #fff !important;
    }
  }
`

export default GlobalStyle
<commit_msg>Ensure box-sizing applies to ::before and ::after elements as well (* does not cover this, for whatever reason).<commit_after>import { createGlobalStyle } from 'styled-components'

import {
  colorTextPrimary,
  colorTextFaint,
  colorBackground,
  amberA200,
  amberA400,
  grey700,
  grey800,
  CardLayer,
} from './colors'

const GlobalStyle = createGlobalStyle`
  *, *::before, *::after {
    box-sizing: border-box;
  }

  html {
    font-family: Roboto, sans-serif;
    font-weight: normal;
    color: ${colorTextPrimary};
    font-size: 14px;
    line-height: 1.5;
    background-color: ${colorBackground};
  }

  html, body, #app, #app > div {
    -webkit-text-size-adjust: 100%;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    -webkit-touch-callout: none;
    height: 100%;
    margin: 0;
    padding: 0;
    position: relative;
  }

  [disabled] {
    color: ${colorTextFaint};
  }

  a:link, a:visited {
    color: ${amberA400};
    text-decoration: none;
  }

  a:hover, a:active {
    color: ${amberA200};
    text-decoration: underline;
  }

  svg {
    fill: currentColor;
  }

  input:-webkit-autofill {
    -webkit-box-shadow: 0 0 0px 1000px ${grey800} inset !important;
    -webkit-text-fill-color: ${colorTextPrimary} !important;
    caret-color: #fff !important;

    ${CardLayer} & {
      -webkit-box-shadow: 0 0 0px 1000px ${grey700} inset !important;
      -webkit-text-fill-color: ${colorTextPrimary} !important;
      caret-color: #fff !important;
    }
  }
`

export default GlobalStyle
<|endoftext|>