<commit_before>var modCommon = require('module.common');

var roleArchitect = {

  //Function to determin if there are buildable structures that need to be
  //assigned a construction site (marked by named flags)
  ableToBuild:function(controllerLvl, flag){
    var structureType = flag.name;
    var wallBool = (structureType.substring(0,4)==="Wall");
    var containerBool = (structureType.substring(0,9)==="Container" || structureType.substring(0,7)==="DropOff" || structureType.substring(0,8)==="GDropOff" || structureType.substring(0,7)==="Deliver");
    var marked = flag.memory.marked;
    switch(controllerLvl){
      case 1:
        return containerBool && !marked;
      case 2:
        return (wallBool || structureType === "Extensions1" || containerBool) && !marked;
      case 3:
        return (wallBool || structureType === "Extensions1" || structureType === "Extensions2" || containerBool || structureType === "Tower1") && !marked;
      case 4:
        return (wallBool || structureType === "Extensions1" || structureType === "Extensions2" || structureType === "Extensions3" || containerBool || structureType === "Tower1" || structureType === "Storage") && !marked;
      case 5:
        return (wallBool || structureType === "Extensions1" || structureType === "Extensions2" || structureType === "Extensions3" || structureType === "Extensions4" || containerBool || structureType === "Tower1" || structureType === "Tower2" || structureType.substring(0,4)==="Link" || structureType === "Storage") && !marked;
      case 6:
        return (wallBool || structureType === "Extensions1" || structureType === "Extensions2" || structureType === "Extensions3" || structureType === "Extensions4" || containerBool || structureType === "Tower1" || structureType === "Tower2" || structureType.substring(0,4)==="Link" || structureType === "Storage" || structureType === "Extractor" || structureType === "Terminal") && !marked;
      case 7:
        return (wallBool || structureType === "Extensions1" || structureType === "Extensions2" || structureType === "Extensions3" || structureType === "Extensions4" || containerBool || structureType === "Tower1" || structureType === "Tower2" || structureType === "Tower3" || structureType.substring(0,4)==="Link" || structureType === "Storage" || structureType === "Extractor" || structureType === "Terminal") && !marked;
      case 8:
        var extensionsBool =  structureType === "Extensions1" || structureType === "Extensions2" || structureType === "Extensions3" || structureType === "Extensions4";

        var towerBool = structureType === "Tower1" || structureType === "Tower2" || structureType === "Tower3" || structureType === "Tower4";

        return (wallBool || extensionsBool || containerBool || towerBool || structureType.substring(0,4)==="Link" || structureType === "Storage" || structureType === "Extractor" || structureType === "Terminal") && !marked;

      default:
        return false;
    }
  },

  //Function to mark the pattern of 5 extensions that are granted at
  //controler level 2 and 3
  markExtensions1: function(flag){
    var x = flag.pos.x;
    var y = flag.pos.y;
    flag.room.createConstructionSite(x, y, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x+1, y, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x-1, y, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x, y+1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x, y-1, STRUCTURE_EXTENSION);

    flag.memory.marked = true;
  },

  //Function to mark the pattern of 5 extensions that are granted at
  //controler level 4 and 5
  markExtensions2: function(flag){
    var x = flag.pos.x;
    var y = flag.pos.y;
    flag.room.createConstructionSite(x-2, y-1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x-1, y-1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x, y-1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x+1, y-1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x+2, y-1, STRUCTURE_EXTENSION);

    flag.room.createConstructionSite(x-2, y+1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x-1, y+1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x, y+1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x+1, y+1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x+2, y+1, STRUCTURE_EXTENSION);

    flag.memory.marked = true;
  },

  // marks a container site
  markContainer:function(flag){
    flag.room.createConstructionSite(flag.pos, STRUCTURE_CONTAINER);
    flag.memory.marked = true;
  },

  //marks a tower site
  markTower: function(flag){
      flag.room.createConstructionSite(flag.pos, STRUCTURE_TOWER);
      flag.memory.marked = true;
  },

  //marks wall sites starting at the flag, going in the specified
  //direction for the given amount of blocks
  markWall:function(flag, flagName){
    var len = parseInt(flagName.substring(5));
    var direction = flagName.substring(4,5);
    var x = flag.pos.x;
    var y = flag.pos.y;
    if(direction === "U"){
        for(i=0; i<=len; i++){
          flag.room.createConstructionSite(x, y-i, STRUCTURE_WALL);
        }
        flag.memory.marked = true;
    }else if(direction === "D"){
      for(i=0; i<=len; i++){
        flag.room.createConstructionSite(x,y+i, STRUCTURE_WALL);
      }
      flag.memory.marked = true;
    }else if(direction === "R"){
      for(i=0; i<=len; i++){
        flag.room.createConstructionSite(x+i,y, STRUCTURE_WALL);
      }
      flag.memory.marked = true;
    }else if(direction === "L"){
      for(i=0; i<=len; i++){
        flag.room.createConstructionSite(x-i,+y, STRUCTURE_WALL);
      }
      flag.memory.marked = true;
    }
  },

  markExtractor:function(flag){
      flag.room.createConstructionSite(flag.pos, STRUCTURE_EXTRACTOR);
      flag.memory.marked = true;
  },
  markTerminal:function(flag){
      flag.room.createConstructionSite(flag.pos, STRUCTURE_TERMINAL);
      flag.memory.marked = true;
  },
  markStorage:function(flag){
      flag.room.createConstructionSite(flag.pos, STRUCTURE_STORAGE);
      flag.memory.marked = true;
  },
  markLink:function(flag){
      flag.room.createConstructionSite(flag.pos, STRUCTURE_LINK);
      flag.memory.marked = true;
  },

  /** @param {Creep} creep **/
  run: function(creep) {
    var controllerLvl = creep.room.controller.level;
    var flags = _.filter(creep.room.find(FIND_FLAGS), (flag) => this.ableToBuild(controllerLvl, flag));
    if(creep.memory.working && flags.length<1) {
        creep.memory.working = false;
        creep.memory.path = null;
    }
    if(!creep.memory.working && flags.length) {
        creep.memory.working = true;
        creep.memory.path = null;
    }

    if(!creep.memory.working){
      var roomName = creep.room.name;
      Memory.rooms[roomName].roles.numArchitects = Memory.rooms[roomName].roles.numArchitects - 1;
      Memory.rooms[roomName].roles.numBuilders = Memory.rooms[roomName].roles.numBuilders + 1;
      creep.memory.role = 'builder';
      if(!creep.room.storage){
        creep.memory.selfHarvest = true;
      }
    }else{
      var flag = flags[0];
      var structureType = flag.name;
      var wallBool = (structureType.substring(0,4)==="Wall");
      var containerBool = (structureType.substring(0,9)==="Container" || structureType.substring(0,7)==="DropOff" || structureType.substring(0,8)==="GDropOff" || structureType.substring(0,7)==="Deliver");
      if(containerBool){
        this.markContainer(flag);
        if(structureType.substring(0,9) === "Container"){
          flag.remove();
        }
      }else if(structureType.substring(0,5) === "Tower"){
          this.markTower(flag);
          flag.remove();
      }else if(structureType === "Extensions1" || structureType ==="Extensions2"){
          this.markExtensions1(flag);
          flag.remove();
      }else if(structureType === "Extensions3" || structureType ==="Extensions4"){
          this.markExtensions2(flag);
          flag.remove();
      }else if(wallBool){
          this.markWall(flag, structureType);
          flag.remove();
      }else if(structureType === "Link"){
        this.markLink(flag);
        flag.remove();
      }else if(structureType === "Storage"){
        this.markStorage(flag);
        flag.remove();
      }else if(structureType === "Terminal"){
        this.markTerminal(flag);
        flag.remove();
      }else if(structureType === "Extractor"){
        this.markExtractor(flag);
        flag.remove();
      }

    }
  }
};

module.exports = roleArchitect;
<commit_msg>changed the container placement to only build deliver one first To centralize the energy to begin with<commit_after>var modCommon = require('module.common');

var roleArchitect = {

  //Function to determin if there are buildable structures that need to be
  //assigned a construction site (marked by named flags)
  ableToBuild:function(controllerLvl, flag){
    var structureType = flag.name;
    var wallBool = (structureType.substring(0,4)==="Wall");
    var containerBool = (structureType.substring(0,9)==="Container" || structureType.substring(0,7)==="DropOff" || structureType.substring(0,8)==="GDropOff" || structureType.substring(0,7)==="Deliver");
    var containerBoolEarly = (structureType.substring(0,9)==="Container" ||  structureType.substring(0,7)==="Deliver");
    var marked = flag.memory.marked;
    switch(controllerLvl){
      case 1:
        return containerBoolEarly && !marked;
      case 2:
        return (wallBool || structureType === "Extensions1" || containerBool) && !marked;
      case 3:
        return (wallBool || structureType === "Extensions1" || structureType === "Extensions2" || containerBool || structureType === "Tower1") && !marked;
      case 4:
        return (wallBool || structureType === "Extensions1" || structureType === "Extensions2" || structureType === "Extensions3" || containerBool || structureType === "Tower1" || structureType === "Storage") && !marked;
      case 5:
        return (wallBool || structureType === "Extensions1" || structureType === "Extensions2" || structureType === "Extensions3" || structureType === "Extensions4" || containerBool || structureType === "Tower1" || structureType === "Tower2" || structureType.substring(0,4)==="Link" || structureType === "Storage") && !marked;
      case 6:
        return (wallBool || structureType === "Extensions1" || structureType === "Extensions2" || structureType === "Extensions3" || structureType === "Extensions4" || containerBool || structureType === "Tower1" || structureType === "Tower2" || structureType.substring(0,4)==="Link" || structureType === "Storage" || structureType === "Extractor" || structureType === "Terminal") && !marked;
      case 7:
        return (wallBool || structureType === "Extensions1" || structureType === "Extensions2" || structureType === "Extensions3" || structureType === "Extensions4" || containerBool || structureType === "Tower1" || structureType === "Tower2" || structureType === "Tower3" || structureType.substring(0,4)==="Link" || structureType === "Storage" || structureType === "Extractor" || structureType === "Terminal") && !marked;
      case 8:
        var extensionsBool =  structureType === "Extensions1" || structureType === "Extensions2" || structureType === "Extensions3" || structureType === "Extensions4";

        var towerBool = structureType === "Tower1" || structureType === "Tower2" || structureType === "Tower3" || structureType === "Tower4";

        return (wallBool || extensionsBool || containerBool || towerBool || structureType.substring(0,4)==="Link" || structureType === "Storage" || structureType === "Extractor" || structureType === "Terminal") && !marked;

      default:
        return false;
    }
  },

  //Function to mark the pattern of 5 extensions that are granted at
  //controler level 2 and 3
  markExtensions1: function(flag){
    var x = flag.pos.x;
    var y = flag.pos.y;
    flag.room.createConstructionSite(x, y, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x+1, y, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x-1, y, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x, y+1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x, y-1, STRUCTURE_EXTENSION);

    flag.memory.marked = true;
  },

  //Function to mark the pattern of 5 extensions that are granted at
  //controler level 4 and 5
  markExtensions2: function(flag){
    var x = flag.pos.x;
    var y = flag.pos.y;
    flag.room.createConstructionSite(x-2, y-1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x-1, y-1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x, y-1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x+1, y-1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x+2, y-1, STRUCTURE_EXTENSION);

    flag.room.createConstructionSite(x-2, y+1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x-1, y+1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x, y+1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x+1, y+1, STRUCTURE_EXTENSION);
    flag.room.createConstructionSite(x+2, y+1, STRUCTURE_EXTENSION);

    flag.memory.marked = true;
  },

  // marks a container site
  markContainer:function(flag){
    flag.room.createConstructionSite(flag.pos, STRUCTURE_CONTAINER);
    flag.memory.marked = true;
  },

  //marks a tower site
  markTower: function(flag){
      flag.room.createConstructionSite(flag.pos, STRUCTURE_TOWER);
      flag.memory.marked = true;
  },

  //marks wall sites starting at the flag, going in the specified
  //direction for the given amount of blocks
  markWall:function(flag, flagName){
    var len = parseInt(flagName.substring(5));
    var direction = flagName.substring(4,5);
    var x = flag.pos.x;
    var y = flag.pos.y;
    if(direction === "U"){
        for(i=0; i<=len; i++){
          flag.room.createConstructionSite(x, y-i, STRUCTURE_WALL);
        }
        flag.memory.marked = true;
    }else if(direction === "D"){
      for(i=0; i<=len; i++){
        flag.room.createConstructionSite(x,y+i, STRUCTURE_WALL);
      }
      flag.memory.marked = true;
    }else if(direction === "R"){
      for(i=0; i<=len; i++){
        flag.room.createConstructionSite(x+i,y, STRUCTURE_WALL);
      }
      flag.memory.marked = true;
    }else if(direction === "L"){
      for(i=0; i<=len; i++){
        flag.room.createConstructionSite(x-i,+y, STRUCTURE_WALL);
      }
      flag.memory.marked = true;
    }
  },

  markExtractor:function(flag){
      flag.room.createConstructionSite(flag.pos, STRUCTURE_EXTRACTOR);
      flag.memory.marked = true;
  },
  markTerminal:function(flag){
      flag.room.createConstructionSite(flag.pos, STRUCTURE_TERMINAL);
      flag.memory.marked = true;
  },
  markStorage:function(flag){
      flag.room.createConstructionSite(flag.pos, STRUCTURE_STORAGE);
      flag.memory.marked = true;
  },
  markLink:function(flag){
      flag.room.createConstructionSite(flag.pos, STRUCTURE_LINK);
      flag.memory.marked = true;
  },

  /** @param {Creep} creep **/
  run: function(creep) {
    var controllerLvl = creep.room.controller.level;
    var flags = _.filter(creep.room.find(FIND_FLAGS), (flag) => this.ableToBuild(controllerLvl, flag));
    if(creep.memory.working && flags.length<1) {
        creep.memory.working = false;
        creep.memory.path = null;
    }
    if(!creep.memory.working && flags.length) {
        creep.memory.working = true;
        creep.memory.path = null;
    }

    if(!creep.memory.working){
      var roomName = creep.room.name;
      Memory.rooms[roomName].roles.numArchitects = Memory.rooms[roomName].roles.numArchitects - 1;
      Memory.rooms[roomName].roles.numBuilders = Memory.rooms[roomName].roles.numBuilders + 1;
      creep.memory.role = 'builder';
      if(!creep.room.storage){
        creep.memory.selfHarvest = true;
      }
    }else{
      var flag = flags[0];
      var structureType = flag.name;
      var wallBool = (structureType.substring(0,4)==="Wall");
      var containerBool = (structureType.substring(0,9)==="Container" || structureType.substring(0,7)==="DropOff" || structureType.substring(0,8)==="GDropOff" || structureType.substring(0,7)==="Deliver");
      if(containerBool){
        this.markContainer(flag);
        if(structureType.substring(0,9) === "Container"){
          flag.remove();
        }
      }else if(structureType.substring(0,5) === "Tower"){
          this.markTower(flag);
          flag.remove();
      }else if(structureType === "Extensions1" || structureType ==="Extensions2"){
          this.markExtensions1(flag);
          flag.remove();
      }else if(structureType === "Extensions3" || structureType ==="Extensions4"){
          this.markExtensions2(flag);
          flag.remove();
      }else if(wallBool){
          this.markWall(flag, structureType);
          flag.remove();
      }else if(structureType === "Link"){
        this.markLink(flag);
        flag.remove();
      }else if(structureType === "Storage"){
        this.markStorage(flag);
        flag.remove();
      }else if(structureType === "Terminal"){
        this.markTerminal(flag);
        flag.remove();
      }else if(structureType === "Extractor"){
        this.markExtractor(flag);
        flag.remove();
      }

    }
  }
};

module.exports = roleArchitect;
<|endoftext|>


<commit_before>let $carousels = [];
let loadedCarousels = {};
let slidesPerScreen = 1;
let currentElement = null;
let css = {
    'containers': '.carousel__js',
    'handles': '.carousel__link--next, .carousel__link--prev'
};

export function init() {
    $carousels = $(css.containers);

    /* $(".article-video__link").on("click", function (e) {
     e.preventDefault();
     }); */

    // prevent flicker effect on page load
    $carousels.on('init', function () {
        $(css.containers).css("visibility", "visible");
    });

    // img carousels
    $.each($carousels, function (i, carousel) {
        var $carousel = $(carousel),
            id = $carousel.attr("id");
        loadedCarousels[id] = false;

        $carousel.slick({
            speed: 300,
            slidesToShow: 1,
            infinite: false,
            appendArrows: "#" + id + " .slick-list",
            prevArrow: '<button class="carousel__link--prev">Vorhergehendes Bild</button>',
            nextArrow: '<button class="carousel__link--next carousel__link--waggle">Nächstes Bild</button>',
            slide: ".carousel__item"
        });
        registerListener($carousel);
    });

    // video carousels
    $(".video_carousel__js").on("init", function (slick) {
        $(this).css("visibility", "visible");
        // triggering a "recalculation of dots" (via "setPosition" below)
        $(window).trigger('resize');
    });

    // video carousel:
    $.each($('.video_carousel__js'), function (i, carousel) {
        let $carousel = $(carousel),
            id = $carousel.attr("id");

        loadedCarousels[id] = false;

        $carousel.slick({
            infinite: false,
            slide: ".carousel__item",
            slidesToShow: 1, // we need all dots - initially
            slidesToScroll: 1,
            accessibility: false, // default?
            // focusOnSelect: false, // <-- not adjustable "on the fly" :/
            appendArrows: "#" + id,
            dots: true,
            centerPadding: 0,
            variableWidth: true,
            prevArrow: '<button class="carousel__link--prev">Vorhergehender Slide</button>',
            nextArrow: '<button class="carousel__link--next">Nächster Slide</button>'
        });
    });

    // "position change" (resize page or "activate" slider in any way)
    $(".video_carousel__js").on("setPosition", function (slick) {
        slidesPerScreen = getNumberOfSlidesPerScreen(1);
        let slidesToShow = slidesPerScreen, // mobile : 1
            $carousel = $(this),
            currentSlide = $carousel.slick("slickCurrentSlide");

        // button / dot text info for screenreaders, initial & on slide change
        if ($carousel.find(".slick-dots button").first().text() == "1" || currentElement != currentSlide) {
            addTextToDots($carousel);
            currentElement = currentSlide;
        }

        // if previous num. of slides shown != the num. we'll see now (window resize)
        if ($carousel.slick("slickGetOption", "slidesToShow") != slidesToShow) {
            let screensToShow = Math.ceil($carousel.find(".carousel__item").length / slidesToShow);

            // desktop / more than one slide / arrows displayed
            if (slidesToShow > 1) {
                // slider not at initial pos.
                if (currentSlide > 0) {
                    // move it to 0 - so the "arrows" don't get "confused"
                    currentSlide = 0;
                    currentElement = currentSlide;
                    $carousel.slick("slickGoTo", currentSlide, true);
                }

                // disabling dots if arrows present (accessibility)
                disableDots($carousel);

                // no right arrow when at the rightmost position within the carousel
                handleRightArrow($carousel, currentSlide, screensToShow);
            }

            // adjust num. of dots (after resize)
            rePaintDots($carousel, screensToShow);

            // adjust num. of slides per page
            $carousel.slick("slickSetOption", "slidesToShow", slidesToShow, false);
            $carousel.slick("slickSetOption", "slidesToScroll", slidesToShow, false);
        }

        // unhide the following slidesToShow - 1 from screenreaders as well:
        let currentPage = Math.floor(currentElement / slidesPerScreen) + 1; // $carousel.find(".slick-dots .slick-active").data("page-no"); // Math.floor(currentElement / slidesPerScreen) + 1; // [0,1,2|3,4,5|6,7,8]

        // remove not currently visible slides from tabindex
        let to = (slidesPerScreen * currentPage) - 1; // zero indexed
        let from = to - (slidesPerScreen - 1);

        $carousel.find(".carousel__item").each(function (i) {
            i >= from && i <= to
                ? $(this).attr("aria-hidden", false).find(".article-video__link").attr("tabindex", 0)
                : $(this).attr("aria-hidden", true).find(".article-video__link").attr("tabindex", -1);
        });

    }).on("afterChange", function (slick, currentSlide) { // instead of: ... .on("keyup", ".carousel__link--next", function (e) {
        // as soon as slick's ready, we put the focus on the current elm
        if (slidesPerScreen > 1) {
            $(this).find(".slick-current .article-video__link").focus();
        }
    }).on("click", ".article-video__link", function (e) {
        // unfortunately $carousel.slick("slickSetOption", "focusOnSelect", ...); cannot be set "on the fly" :/

        if (e.type == "click" && slidesPerScreen === 1) {
            /// vo has a crazy problem: it fires click for the video left to the "selected" one - from the 3rd on
            gotTo($(this)); // enable selecting "barely visible next video"
        }
    }).on("keyup", ".article-video__link", function (e) {
        // someone is tabbing => clicked <enter> (desktop)
        if (e.keyCode === 13) {
            $(this).trigger("click");
        }
        // }).on("keyup", ".carousel__link--prev, .carousel__link--next", function (e) {
    }).on("keyup", ".carousel__link--next", function (e) { // this is too late!
        // someone is tabbing => clicked <enter> on the arrow going to the next page
        if (e.keyCode === 13) {
            // we select the first video-link available on the page
            $(this).closest(".video_carousel__js").find(".slick-current .article-video__link").focus();
        }
    });
}

function gotTo($selectedLink) {
    $selectedLink.closest(".video_carousel__js")
        .slick("slickGoTo", $selectedLink.closest(".carousel__item").data("slick-index"));
}

function registerListener($carousel) {
    // load all images after user starts interacting with carousel
    $carousel.on('beforeChange', function (event, slick, currentSlide, nextSlide) {
        if (loadedCarousels[$carousel.attr("id")] === false) {
            loadedCarousels[$carousel.attr("id")] = true;
            loadLazyImages(slick.$slides.find(".image-figure__js"));
        }
    });

    $carousel.on('swipe', function (event, slick, direction) {
        // on "interacting" with the carousel => no more animation
        $(this).find(".carousel__link--next").removeClass("carousel__link--waggle");
    });

    $carousel.find(css.handles).on("touchstart mousedown mouseenter", function () {
        $(this).removeClass("untouched");
        // if the handles are clicked / touched: stop the animation
        $(this).removeClass("carousel__link--waggle");
    }).on("touchend touchcancel", function () {
        $(this).addClass("untouched");
    });
}

function loadLazyImages(images) {
    images.each(function (i, image) {
        var $image = $(image);
        if ($image.data("src")) {
            $image.attr("srcset", $image.data("srcset"));
            $image.attr("src", $image.data("src"));
        }
    });
}

function rePaintDots($carousel, screensToShow) {
    if (screensToShow > 1) {
        let x = screensToShow + 1;
        $carousel.find(".slick-dots li").removeClass("h-element--hide");
        // adding text to dots
        addTextToDots($carousel);
        $carousel.find(".slick-dots li:nth-child(1n + " + x + ")").addClass("h-element--hide");
    } else {
        $carousel.find(".slick-dots").addClass("h-element--hide");
    }
}

function addTextToDots($carousel) {
    // adding text to dots
    $carousel.find(".slick-dots li").each(function (i) {
        let $elm = $(this);
        // reenabling buttons (after slick) for mobile :/
        $elm.find("button").text($elm.hasClass("slick-active") // and provide textual info
            ? $carousel.data("dot-current")
            : (i + 1) + ". " + $carousel.data("dot-info")
        ); // button (dot)

        // reenabling dots for mobile
        if (slidesPerScreen == 1) {
            enableDots($elm);
        }
    }); // this is silly and not informative :/
}

function enableDots($list) {
    $list.attr("aria-hidden", false).find("button")
        .attr("tabindex", "0").attr("aria-hidden", false).attr("role", "button"); // li
}

function disableDots($carousel) {
    $carousel.find(".slick-dots button").attr("tabindex", "-1")
        .attr("aria-hidden", true).attr("role", "presentation");
}

function handleRightArrow($carousel, currentSlide, screensToShow) {
    if ((currentSlide + 1) == screensToShow) {
        $carousel.find(".carousel__link--next").addClass("h-element--hide").attr("aria-disabled", true);
    } else {
        $carousel.find(".carousel__link--next").removeClass("h-element--hide").attr("aria-disabled", false);
    }
}

function getNumberOfSlidesPerScreen(slidesToShow = 1) {
    // let slidesToShow = 1; // mobile

    if (matchMedia('screen and (min-width: 720px) and (max-width: 1023px)').matches) {
        slidesToShow = 2; // tablet
    } else if (matchMedia('screen and (min-width: 1024px)').matches) {
        slidesToShow = 3; // larger
    }
    return slidesToShow
}
<commit_msg>give dots back - if they've "gone"<commit_after>let $carousels = [];
let loadedCarousels = {};
let slidesPerScreen = 1;
let currentElement = null;
let css = {
    'containers': '.carousel__js',
    'handles': '.carousel__link--next, .carousel__link--prev'
};

export function init() {
    $carousels = $(css.containers);

    /* $(".article-video__link").on("click", function (e) {
     e.preventDefault();
     }); */

    // prevent flicker effect on page load
    $carousels.on('init', function () {
        $(css.containers).css("visibility", "visible");
    });

    // img carousels
    $.each($carousels, function (i, carousel) {
        var $carousel = $(carousel),
            id = $carousel.attr("id");
        loadedCarousels[id] = false;

        $carousel.slick({
            speed: 300,
            slidesToShow: 1,
            infinite: false,
            appendArrows: "#" + id + " .slick-list",
            prevArrow: '<button class="carousel__link--prev">Vorhergehendes Bild</button>',
            nextArrow: '<button class="carousel__link--next carousel__link--waggle">Nächstes Bild</button>',
            slide: ".carousel__item"
        });
        registerListener($carousel);
    });

    // video carousels
    $(".video_carousel__js").on("init", function (slick) {
        $(this).css("visibility", "visible");
        // triggering a "recalculation of dots" (via "setPosition" below)
        $(window).trigger('resize');
    });

    // video carousel:
    $.each($('.video_carousel__js'), function (i, carousel) {
        let $carousel = $(carousel),
            id = $carousel.attr("id");

        loadedCarousels[id] = false;

        $carousel.slick({
            infinite: false,
            slide: ".carousel__item",
            slidesToShow: 1, // we need all dots - initially
            slidesToScroll: 1,
            accessibility: false, // default?
            // focusOnSelect: false, // <-- not adjustable "on the fly" :/
            appendArrows: "#" + id,
            dots: true,
            centerPadding: 0,
            variableWidth: true,
            prevArrow: '<button class="carousel__link--prev">Vorhergehender Slide</button>',
            nextArrow: '<button class="carousel__link--next">Nächster Slide</button>'
        });
    });

    // "position change" (resize page or "activate" slider in any way)
    $(".video_carousel__js").on("setPosition", function (slick) {
        slidesPerScreen = getNumberOfSlidesPerScreen(1);
        let slidesToShow = slidesPerScreen, // mobile : 1
            $carousel = $(this),
            currentSlide = $carousel.slick("slickCurrentSlide");

        // button / dot text info for screenreaders, initial & on slide change
        if ($carousel.find(".slick-dots button").first().text() == "1" || currentElement != currentSlide) {
            addTextToDots($carousel);
            currentElement = currentSlide;
        }

        // if previous num. of slides shown != the num. we'll see now (window resize)
        if ($carousel.slick("slickGetOption", "slidesToShow") != slidesToShow) {
            let screensToShow = Math.ceil($carousel.find(".carousel__item").length / slidesToShow);

            // desktop / more than one slide / arrows displayed
            if (slidesToShow > 1) {
                // slider not at initial pos.
                if (currentSlide > 0) {
                    // move it to 0 - so the "arrows" don't get "confused"
                    currentSlide = 0;
                    currentElement = currentSlide;
                    $carousel.slick("slickGoTo", currentSlide, true);
                }

                // disabling dots if arrows present (accessibility)
                disableDots($carousel);

                // no right arrow when at the rightmost position within the carousel
                handleRightArrow($carousel, currentSlide, screensToShow);
            }

            // adjust num. of dots (after resize)
            rePaintDots($carousel, screensToShow);

            // adjust num. of slides per page
            $carousel.slick("slickSetOption", "slidesToShow", slidesToShow, false);
            $carousel.slick("slickSetOption", "slidesToScroll", slidesToShow, false);
        }

        // unhide the following slidesToShow - 1 from screenreaders as well:
        let currentPage = Math.floor(currentElement / slidesPerScreen) + 1; // $carousel.find(".slick-dots .slick-active").data("page-no"); // Math.floor(currentElement / slidesPerScreen) + 1; // [0,1,2|3,4,5|6,7,8]

        // remove not currently visible slides from tabindex
        let to = (slidesPerScreen * currentPage) - 1; // zero indexed
        let from = to - (slidesPerScreen - 1);

        $carousel.find(".carousel__item").each(function (i) {
            i >= from && i <= to
                ? $(this).attr("aria-hidden", false).find(".article-video__link").attr("tabindex", 0)
                : $(this).attr("aria-hidden", true).find(".article-video__link").attr("tabindex", -1);
        });

    }).on("afterChange", function (slick, currentSlide) { // instead of: ... .on("keyup", ".carousel__link--next", function (e) {
        // as soon as slick's ready, we put the focus on the current elm
        if (slidesPerScreen > 1) {
            $(this).find(".slick-current .article-video__link").focus();
        }
    }).on("click", ".article-video__link", function (e) {
        // unfortunately $carousel.slick("slickSetOption", "focusOnSelect", ...); cannot be set "on the fly" :/

        if (e.type == "click" && slidesPerScreen === 1) {
            /// vo has a crazy problem: it fires click for the video left to the "selected" one - from the 3rd on
            gotTo($(this)); // enable selecting "barely visible next video"
        }
    }).on("keyup", ".article-video__link", function (e) {
        // someone is tabbing => clicked <enter> (desktop)
        if (e.keyCode === 13) {
            $(this).trigger("click");
        }
        // }).on("keyup", ".carousel__link--prev, .carousel__link--next", function (e) {
    }).on("keyup", ".carousel__link--next", function (e) { // this is too late!
        // someone is tabbing => clicked <enter> on the arrow going to the next page
        if (e.keyCode === 13) {
            // we select the first video-link available on the page
            $(this).closest(".video_carousel__js").find(".slick-current .article-video__link").focus();
        }
    });
}

function gotTo($selectedLink) {
    $selectedLink.closest(".video_carousel__js")
        .slick("slickGoTo", $selectedLink.closest(".carousel__item").data("slick-index"));
}

function registerListener($carousel) {
    // load all images after user starts interacting with carousel
    $carousel.on('beforeChange', function (event, slick, currentSlide, nextSlide) {
        if (loadedCarousels[$carousel.attr("id")] === false) {
            loadedCarousels[$carousel.attr("id")] = true;
            loadLazyImages(slick.$slides.find(".image-figure__js"));
        }
    });

    $carousel.on('swipe', function (event, slick, direction) {
        // on "interacting" with the carousel => no more animation
        $(this).find(".carousel__link--next").removeClass("carousel__link--waggle");
    });

    $carousel.find(css.handles).on("touchstart mousedown mouseenter", function () {
        $(this).removeClass("untouched");
        // if the handles are clicked / touched: stop the animation
        $(this).removeClass("carousel__link--waggle");
    }).on("touchend touchcancel", function () {
        $(this).addClass("untouched");
    });
}

function loadLazyImages(images) {
    images.each(function (i, image) {
        var $image = $(image);
        if ($image.data("src")) {
            $image.attr("srcset", $image.data("srcset"));
            $image.attr("src", $image.data("src"));
        }
    });
}

function rePaintDots($carousel, screensToShow) {
    if (screensToShow > 1) {
        $carousel.find(".slick-dots").removeClass("h-element--hide");
        let x = screensToShow + 1;
        $carousel.find(".slick-dots li").removeClass("h-element--hide");
        // adding text to dots
        addTextToDots($carousel);
        $carousel.find(".slick-dots li:nth-child(1n + " + x + ")").addClass("h-element--hide");
    } else {
        $carousel.find(".slick-dots").addClass("h-element--hide");
    }
}

function addTextToDots($carousel) {
    // adding text to dots
    $carousel.find(".slick-dots li").each(function (i) {
        let $elm = $(this);
        // reenabling buttons (after slick) for mobile :/
        $elm.find("button").text($elm.hasClass("slick-active") // and provide textual info
            ? $carousel.data("dot-current")
            : (i + 1) + ". " + $carousel.data("dot-info")
        ); // button (dot)

        // reenabling dots for mobile
        if (slidesPerScreen == 1) {
            enableDots($elm);
        }
    }); // this is silly and not informative :/
}

function enableDots($list) {
    $list.attr("aria-hidden", false).find("button")
        .attr("tabindex", "0").attr("aria-hidden", false).attr("role", "button"); // li
}

function disableDots($carousel) {
    $carousel.find(".slick-dots button").attr("tabindex", "-1")
        .attr("aria-hidden", true).attr("role", "presentation");
}

function handleRightArrow($carousel, currentSlide, screensToShow) {
    if ((currentSlide + 1) == screensToShow) {
        $carousel.find(".carousel__link--next").addClass("h-element--hide").attr("aria-disabled", true);
    } else {
        $carousel.find(".carousel__link--next").removeClass("h-element--hide").attr("aria-disabled", false);
    }
}

function getNumberOfSlidesPerScreen(slidesToShow = 1) {
    // let slidesToShow = 1; // mobile

    if (matchMedia('screen and (min-width: 720px) and (max-width: 1023px)').matches) {
        slidesToShow = 2; // tablet
    } else if (matchMedia('screen and (min-width: 1024px)').matches) {
        slidesToShow = 3; // larger
    }
    return slidesToShow
}
<|endoftext|>


<commit_before>/**
 * @fileoverview Helpers and types for JSON objects returned by the server.
 */
goog.provide('camlistore.ServerType');

/**
 * @typedef {{
 *   currentPermanode: string,
 *   name: string,
 *   prefix: Array.<string>
 * }}
 */
camlistore.ServerType.DiscoveryRoot;

/**
 * @typedef {{
 *   blobRoot: string,
 *   directoryHelper: string,
 *   downloadHelper: string,
 *   jsonSignRoot: string,
 *   ownerName: string,
 *   publishRoots: Array.<camlistore.ServerType.DiscoveryRoot>,
 *   searchRoot: string,
 *   storageGeneration: string,
 *   storageInitTime: string,
 *   uploadHelper: string
 * }}
 */
camlistore.ServerType.DiscoveryDocument;

/**
 * @typedef {{
 *   fileName: string,
 *   mimeType: string,
 *   size: number
 * }}
 */
camlistore.ServerType.IndexerFileMeta;

/**
 * @typedef {{
 *   title: string,
 *   camliContent: Array.<camlistore.ServerType.IndexerMeta>
 * }}
 */
camlistore.ServerType.IndexerPermanodeAttrMeta;

/**
 * @typedef {{
 *   attr: camlistore.ServerType.IndexerPermanodeAttrMeta?
 * }}
 */
camlistore.ServerType.IndexerPermanodeMeta;

/**
 * @typedef {{
 *   blobRef: string,
 *   camliType: string,
 *   file: camlistore.ServerType.IndexerFileMeta?,
 *   mimeType: string,
 *   permanode: camlistore.ServerType.IndexerPermanodeMeta?,
 *   size: number,
 *   thumbnailHeight: number?,
 *   thumbnailWidth: number?,
 *   thumbnailSrc: string?
 * }}
 */
camlistore.ServerType.IndexerMeta;

/**
 * @typedef {Object.<string, camlistore.ServerType.IndexerMeta>}
 */
camlistore.ServerType.IndexerMetaBag;
<commit_msg>newui: more js type annotation fixes<commit_after>/**
 * @fileoverview Helpers and types for JSON objects returned by the server.
 */
goog.provide('camlistore.ServerType');

/**
 * @typedef {{
 *   currentPermanode: string,
 *   name: string,
 *   prefix: Array.<string>
 * }}
 */
camlistore.ServerType.DiscoveryRoot;

/**
 * @typedef {{
 *   blobRoot: string,
 *   directoryHelper: string,
 *   downloadHelper: string,
 *   jsonSignRoot: string,
 *   ownerName: string,
 *   publishRoots: Array.<camlistore.ServerType.DiscoveryRoot>,
 *   searchRoot: string,
 *   storageGeneration: string,
 *   storageInitTime: string,
 *   signing: camlistore.ServerType.SigningDiscoveryDocument,
 *   uploadHelper: string
 * }}
 */
camlistore.ServerType.DiscoveryDocument;

/**
 * @typedef {{
 *   publicKey: string,
 *   publicKeyBlobRef: string,
 *   publicKeyId: string,
 *   signHandler: string,
 *   verifyHandler: string
 * }}
 */
camlistore.ServerType.SigningDiscoveryDocument;

/**
 * @typedef {{
 *   fileName: string,
 *   mimeType: string,
 *   size: number
 * }}
 */
camlistore.ServerType.IndexerFileMeta;

/**
 * @typedef {{
 *   title: string,
 *   camliContent: Array.<camlistore.ServerType.IndexerMeta>
 * }}
 */
camlistore.ServerType.IndexerPermanodeAttrMeta;

/**
 * @typedef {{
 *   attr: camlistore.ServerType.IndexerPermanodeAttrMeta?
 * }}
 */
camlistore.ServerType.IndexerPermanodeMeta;

/**
 * @typedef {{
 *   blobRef: string,
 *   camliType: string,
 *   file: camlistore.ServerType.IndexerFileMeta?,
 *   mimeType: string,
 *   permanode: camlistore.ServerType.IndexerPermanodeMeta?,
 *   size: number,
 *   thumbnailHeight: number?,
 *   thumbnailWidth: number?,
 *   thumbnailSrc: string?
 * }}
 */
camlistore.ServerType.IndexerMeta;

/**
 * @typedef {Object.<string, camlistore.ServerType.IndexerMeta>}
 */
camlistore.ServerType.IndexerMetaBag;
<|endoftext|>


<commit_before>/*jslint node: true */

/*
 * #%L
 * %%
 * Copyright (C) 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

let joynr = require("joynr");
const testbase = require("test-base");
const fs = require("fs");
const provisioning = testbase.provisioning_common;
const log = testbase.logging.log;

if (process.env.domain === undefined) {
    log("please pass a domain as argument");
    process.exit(-1);
}

if (process.env.cchost === undefined) {
    log("please pass cchost as argument");
    process.exit(-1);
}

if (process.env.ccport === undefined) {
    log("please pass ccport as argument");
    process.exit(-1);
}

log("domain: " + process.env.domain);
log("cchost: " + process.env.cchost);
log("ccport: " + process.env.ccport);
log("ccprotocol: " + process.env.ccprotocol);
log("tlsCertPath: " + process.env.tlsCertPath);
log("tlsKeyPath: " + process.env.tlsKeyPath);
log("tlsCaPath: " + process.env.tlsCaPath);
log("ownerId: " + process.env.ownerId);

const domain = process.env.domain;
provisioning.ccAddress.host = process.env.cchost;
provisioning.ccAddress.port = process.env.ccport;
provisioning.ccAddress.protocol = process.env.ccprotocol;

if (process.env.tlsCertPath || process.env.tlsKeyPath || process.env.tlsCertPath || process.env.ownerId) {
    provisioning.keychain = {};

    if (process.env.tlsCertPath) {
        provisioning.keychain.tlsCert = fs.readFileSync(process.env.tlsCertPath, 'utf8');
    }
    if (process.env.tlsKeyPath) {
        provisioning.keychain.tlsKey = fs.readFileSync(process.env.tlsKeyPath, 'utf8');
    }
    if (process.env.tlsCaPath) {
        provisioning.keychain.tlsCa = fs.readFileSync(process.env.tlsCaPath, 'utf8');
    }
    provisioning.keychain.ownerId = process.env.ownerId;
}

const SystemIntegrationTestProxy = require("../generated-sources/joynr/test/SystemIntegrationTestProxy.js");

const runTest = function(systemIntegrationTestProxy) {
    const addends = {
        addendA : 123,
        addendB : 321
    };
    return systemIntegrationTestProxy.add(addends).then((opArgs) => {
        if (opArgs.result === undefined) {
            throw new Error("systemIntegrationTestProxy.add failed: result undefined");
        }
        if (opArgs.result !== (addends.addendA + addends.addendB)) {
            log (opArgs.result + " != " + addends.addendA + " + " + addends.addendB);
            throw new Error("systemIntegrationTestProxy.add failed: " + opArgs.result + " != " + addends.addendA + " + " + addends.addendB);
        }
    });
};

joynr.load(provisioning).then((loadedJoynr) => {
    joynr = loadedJoynr;
    const messagingQos = new joynr.messaging.MessagingQos({
        ttl : 60000
    });

    const discoveryQos = new joynr.proxy.DiscoveryQos({
        discoveryTimeoutMs : 120000 // 2 Mins
    });

    return joynr.proxyBuilder.build(SystemIntegrationTestProxy, {
        domain,
        messagingQos,
        discoveryQos
    });
}).then((systemIntegrationTestProxy) => {
  return runTest(systemIntegrationTestProxy);
}).then(() => {
  log("SIT RESULT success: node consumer -> " + domain);
  process.exit(0);
}).catch((error) => {
  log("SIT RESULT error: node consumer -> " + domain + " error: " + JSON.stringify(error));
  process.exit(1);
}).catch((error) => {
    throw error;
});
<commit_msg>[JS, SIT] make sure SIT fails on uncaught Exception<commit_after>/*jslint node: true */

/*
 * #%L
 * %%
 * Copyright (C) 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

process.on('uncaughtException', (e) =>{
   log("SIT RESULT error: received uncaught Exception" + e);
   process.exit(1);
});

let joynr = require("joynr");
const testbase = require("test-base");
const fs = require("fs");
const provisioning = testbase.provisioning_common;
const log = testbase.logging.log;

if (process.env.domain === undefined) {
    log("please pass a domain as argument");
    process.exit(-1);
}

if (process.env.cchost === undefined) {
    log("please pass cchost as argument");
    process.exit(-1);
}

if (process.env.ccport === undefined) {
    log("please pass ccport as argument");
    process.exit(-1);
}

log("domain: " + process.env.domain);
log("cchost: " + process.env.cchost);
log("ccport: " + process.env.ccport);
log("ccprotocol: " + process.env.ccprotocol);
log("tlsCertPath: " + process.env.tlsCertPath);
log("tlsKeyPath: " + process.env.tlsKeyPath);
log("tlsCaPath: " + process.env.tlsCaPath);
log("ownerId: " + process.env.ownerId);

const domain = process.env.domain;
provisioning.ccAddress.host = process.env.cchost;
provisioning.ccAddress.port = process.env.ccport;
provisioning.ccAddress.protocol = process.env.ccprotocol;

if (process.env.tlsCertPath || process.env.tlsKeyPath || process.env.tlsCertPath || process.env.ownerId) {
    provisioning.keychain = {};

    if (process.env.tlsCertPath) {
        provisioning.keychain.tlsCert = fs.readFileSync(process.env.tlsCertPath, 'utf8');
    }
    if (process.env.tlsKeyPath) {
        provisioning.keychain.tlsKey = fs.readFileSync(process.env.tlsKeyPath, 'utf8');
    }
    if (process.env.tlsCaPath) {
        provisioning.keychain.tlsCa = fs.readFileSync(process.env.tlsCaPath, 'utf8');
    }
    provisioning.keychain.ownerId = process.env.ownerId;
}

const SystemIntegrationTestProxy = require("../generated-sources/joynr/test/SystemIntegrationTestProxy.js");

const runTest = function(systemIntegrationTestProxy) {
    const addends = {
        addendA : 123,
        addendB : 321
    };
    return systemIntegrationTestProxy.add(addends).then((opArgs) => {
        if (opArgs.result === undefined) {
            throw new Error("systemIntegrationTestProxy.add failed: result undefined");
        }
        if (opArgs.result !== (addends.addendA + addends.addendB)) {
            log (opArgs.result + " != " + addends.addendA + " + " + addends.addendB);
            throw new Error("systemIntegrationTestProxy.add failed: " + opArgs.result + " != " + addends.addendA + " + " + addends.addendB);
        }
    });
};

joynr.load(provisioning).then((loadedJoynr) => {
    joynr = loadedJoynr;
    const messagingQos = new joynr.messaging.MessagingQos({
        ttl : 60000
    });

    const discoveryQos = new joynr.proxy.DiscoveryQos({
        discoveryTimeoutMs : 120000 // 2 Mins
    });

    return joynr.proxyBuilder.build(SystemIntegrationTestProxy, {
        domain,
        messagingQos,
        discoveryQos
    });
}).then((systemIntegrationTestProxy) => {
  return runTest(systemIntegrationTestProxy);
}).then(() => {
  log("SIT RESULT success: node consumer -> " + domain);
  process.exit(0);
}).catch((error) => {
  log("SIT RESULT error: node consumer -> " + domain + " error: " + JSON.stringify(error));
  process.exit(1);
}).catch((error) => {
    throw error;
});
<|endoftext|>


<commit_before>
import assert from 'assert';
import Fetched from '../../src/Fetched';

let fetched;

let fetch = function(url, param){
    return [
        url,
        param
    ]
}

describe('Fetched API tests', () => {

    beforeEach(() => {
        fetched = new Fetched(fetch);
    });

    afterEach(() => {
        fetched = '';
    });

    it('Testing for methods', () => {

        let methods = [
            'post',
            'get',
            'delete',
            'put',
            'set',
            'send',
            'json',
            'withCredentials',
            'format',
            'using'
        ];

        methods.forEach((key) => {
            assert.equal(typeof fetched[key], 'function');
        });
    });

});

<commit_msg>updated method<commit_after>
import assert from 'assert';
import Fetched from '../../src/Fetched';

let fetched;

let fetch = function(url, param){
    return [
        url,
        param
    ]
}

describe('Fetched API tests', () => {

    beforeEach(() => {
        fetched = new Fetched(fetch);
    });

    afterEach(() => {
        fetched = '';
    });

    it('Testing for methods', () => {

        let methods = [
            'post',
            'get',
            'del',
            'put',
            'set',
            'send',
            'json',
            'withCredentials',
            'format',
            'using'
        ];

        methods.forEach((key) => {
            assert.equal(typeof fetched[key], 'function');
        });
    });

});

<|endoftext|>


<commit_before>
// demonstrate the effect of modifying an objects prototype before and after the object is constructed

module("About Prototypal Inheritance (topics/about_prototypal_inheritance.js)");

// this 'class' pattern defines a class by its constructor
var Mammal = function(name) {
    this.name = name;
}
// things that don't need to be set in the constructor should be added to the constructor's prototype property.
Mammal.prototype = {
    sayHi: function() {
        return "Hello, my name is " + this.name;
    }
}

test("defining a 'class'", function() {
    var eric  = new Mammal("Eric");
    equal(__, eric.sayHi(), 'what will Eric say?');
});

// add another function to the Mammal 'type' that uses the sayHi function
Mammal.prototype.favouriteSaying = function() {
    return this.name + "'s favourite saying is " + this.sayHi();
}

test("more functions", function() {
    var bobby = new Mammal("Bobby");
    equal(__, bobby.favouriteSaying(), "what is Bobby's favourite saying?");
});

test("calling functions added to a prototype after an object was created", function() {
    var paul = new Mammal("Paul");
    Mammal.prototype.numberOfLettersInName = function() {
        return this.name.length;
    };
    // the following statement asks the paul object to call a function that was added
    // to the Mammal prototype after paul was constructed.
    equal(__, paul.numberOfLettersInName(), "how long is Paul's name?");
});

// helper function for inheritance.
// From https://developer.mozilla.org/en/JavaScript/Guide/Inheritance_Revisited
function extend(child, supertype){
    child.prototype = supertype.prototype;
}

// "Subclass" Mammal
function Bat(name, wingspan) {
    Mammal.call(this, name);
    this.wingspan = wingspan;
}

// configure inheritance
extend(Bat, Mammal);

test("Inheritance", function() {
    var lenny = new Bat("Lenny", "1.5m");
    equal(__, lenny.sayHi(), "what does Lenny say?");
    equal(__, lenny.wingspan, "what is Lenny's wingspan?");
});
<commit_msg>About prototypal inheritance done<commit_after>
// demonstrate the effect of modifying an objects prototype before and after the object is constructed

module("About Prototypal Inheritance (topics/about_prototypal_inheritance.js)");

// this 'class' pattern defines a class by its constructor
var Mammal = function(name) {
    this.name = name;
}
// things that don't need to be set in the constructor should be added to the constructor's prototype property.
Mammal.prototype = {
    sayHi: function() {
        return "Hello, my name is " + this.name;
    }
}

test("defining a 'class'", function() {
    var eric  = new Mammal("Eric");
    equal("Hello, my name is Eric", eric.sayHi(), 'what will Eric say?');
});

// add another function to the Mammal 'type' that uses the sayHi function
Mammal.prototype.favouriteSaying = function() {
    return this.name + "'s favourite saying is " + this.sayHi();
}

test("more functions", function() {
    var bobby = new Mammal("Bobby");
    equal("Bobby's favourite saying is Hello, my name is Bobby", bobby.favouriteSaying(), "what is Bobby's favourite saying?");
});

test("calling functions added to a prototype after an object was created", function() {
    var paul = new Mammal("Paul");
    Mammal.prototype.numberOfLettersInName = function() {
        return this.name.length;
    };
    // the following statement asks the paul object to call a function that was added
    // to the Mammal prototype after paul was constructed.
    equal(4, paul.numberOfLettersInName(), "how long is Paul's name?");
});

// helper function for inheritance.
// From https://developer.mozilla.org/en/JavaScript/Guide/Inheritance_Revisited
function extend(child, supertype){
    child.prototype = supertype.prototype;
}

// "Subclass" Mammal
function Bat(name, wingspan) {
    Mammal.call(this, name);
    this.wingspan = wingspan;
}

// configure inheritance
extend(Bat, Mammal);

test("Inheritance", function() {
    var lenny = new Bat("Lenny", "1.5m");
    equal("Hello, my name is Lenny", lenny.sayHi(), "what does Lenny say?");
    equal("1.5m", lenny.wingspan, "what is Lenny's wingspan?");
});
<|endoftext|>


<commit_before>/* eslint-env node, mocha */
'use strict';

const assert = require('chai').assert
      , subject = require('./socketHandler')
      , events = require('harken');

describe('WebSocket handler Tests', () => {
  // NOTE: These test cover the moving parts of the web socket setup
  //  they don't cover the actual web socket server itself, that module
  //  is maintained outside the code base and should be tested independently
  //  but this is a nice comprimise.

  describe('Web Socket Handler Type: false tests', () => {
    const handler = subject(false);

    afterEach(() => {
      events.off('data:set:test');
      events.off('data:get:test');
      events.off('some:event');
    });

    it('should be a function and return a function', () => {
      assert.isFunction(subject);
      assert.isFunction(subject(false));
    });

    it('should not emit events for data event messages', () => {
      const socket = {};

      handler(socket);

      socket.onmessage({
        data: '{ "event": "data:get:test" }'
      });

      assert.isUndefined(events.listeners('data:set:test'));
    });

    it('should not emit events for non-data event messages', (done) => {
      const socket = {};

      handler(socket);
      events.on('some:event', (data) => {
        if (typeof data === 'undefined') {
          assert.strictEqual(true, false);
        } else {
          done();
        }
      });

      socket.onmessage({
        data: '{ "event": "some:event" }'
      });

      setTimeout(() => {
        events.emit('some:event', true);
      }, 0);
    });
  });

  describe('Web Socket Handler Type: true tests', () => {
    const handler = subject(true);

    afterEach(() => {
      events.off('data:set:test');
      events.off('data:get:test');
    });

    it('should be a function and return a function', () => {
      assert.isFunction(subject);
      assert.isFunction(subject(true));
    });

    it('should emit events for data event messages', (done) => {
      const socket = {};

      events.once('data:get:test', (test) => {
        assert.isUndefined(test);
        done();
      });

      handler(socket);

      socket.onmessage({
        data: '{ "event": "data:get:test" }'
      });
    });

    it('should pass message and socket through to data new events', (done) => {
      const socket = {};

      handler(socket);

      events.once('data:new:person', (data) => {
        assert.isObject(data);
        assert.isObject(data.message);
        assert.isObject(data.message.payload);
        assert.isObject(data.socket);
        assert.strictEqual(socket, data.socket);
        assert.strictEqual(data.message.event, 'data:new:person');
        done();
      });

      socket.onmessage({
        data: '{ "event": "data:new:person", "payload": { "name": "daniel" } }'
      });
    });

    it('should emit events for non-data event messages', (done) => {
      const socket = {};

      handler(socket);

      events.once('some:event', () => {
        assert.strictEqual(true, true);
        done();
      });

      socket.onmessage({
        data: '{ "event": "some:event" }'
      });
    });

    it('should pass the message and socket through to passthrough events', (done) => {
      const socket = {};

      handler(socket);

      events.once('some:event', (data) => {
        assert.isObject(data);
        assert.isObject(data.message);
        assert.isObject(data.socket);
        assert.strictEqual(socket, data.socket);
        assert.strictEqual(data.message.event, 'some:event');
        done();
      });

      socket.onmessage({
        data: '{ "event": "some:event" }'
      });
    });
  });

  describe('Web Socket Handler Type: data tests', () => {
    const handler = subject('data');

    afterEach(() => {
      events.off('data:set:test');
      events.off('data:get:test');
    });

    it('should be a function and return a function', () => {
      assert.isFunction(subject);
      assert.isFunction(subject('data'));
    });

    it('should emit events for data event messages', (done) => {
      const socket = {};

      events.once('data:get:test', (test) => {
        assert.isUndefined(test);
        done();
      });

      handler(socket);

      socket.onmessage({
        data: '{ "event": "data:get:test" }'
      });
    });

    it('should not emit events for non-data event messages', () => {
      const socket = {};

      handler(socket);

      socket.onmessage({
        data: '{ "event": "some:event" }'
      });

      assert.strictEqual(events.listeners('some:event').length, 0);
    });

    it('should return a string when responding to a socket', (done) => {
      const socket = {
        send: (message) => {
          assert.isString(message);
          done();
        }
      };

      handler(socket);

      events.once('data:get:test', () => {
        events.emit('data:set:test', { test: true });
      });

      socket.onmessage({
        data: '{ "event": "data:get:test" }'
      });
    });
  });

  describe('Web Socket Handler Type: passthrough tests', () => {
    const handler = subject('passthrough');

    afterEach(() => {
      events.off('data:set:test');
      events.off('data:get:test');
    });

    it('should be a function and return a function', () => {
      assert.isFunction(subject);
      assert.isFunction(subject('passthrough'));
    });

    it('should not emit events for data event messages', () => {
      const socket = {};

      handler(socket);

      socket.onmessage({
        data: '{ "event": "data:get:test" }'
      });

      assert.strictEqual(events.listeners('data:set:test').length, 0);
    });

    it('should emit events for non-data event messages', (done) => {
      const socket = {};

      handler(socket);

      events.once('some:event', () => {
        assert.strictEqual(true, true);
        done();
      });

      socket.onmessage({
        data: '{ "event": "some:event" }'
      });
    });

    it('should pass the message and socket through to passthrough events', (done) => {
      const socket = {};

      handler(socket);

      events.once('some:event', (data) => {
        assert.isObject(data);
        assert.isObject(data.message);
        assert.isObject(data.socket);
        assert.strictEqual(socket, data.socket);
        assert.strictEqual(data.message.event, 'some:event');
        done();
      });

      socket.onmessage({
        data: '{ "event": "some:event" }'
      });
    });

    it('should pass message and socket through to data new events', (done) => {
      const socket = {};

      handler(socket);

      events.once('data:new:person', (data) => {
        assert.isObject(data);
        assert.isObject(data.message);
        assert.isObject(data.message.payload);
        assert.isObject(data.socket);
        assert.strictEqual(socket, data.socket);
        assert.strictEqual(data.message.event, 'data:new:person');
        done();
      });

      socket.onmessage({
        data: '{ "event": "data:new:person", "payload": { "name": "daniel" } }'
      });
    });
  });
});
<commit_msg>expand test coverage in socketHandler to 100%<commit_after>/* eslint-env node, mocha */
'use strict';

const assert = require('chai').assert
      , subject = require('./socketHandler')
      , events = require('harken');

describe('WebSocket handler Tests', () => {
  // NOTE: These test cover the moving parts of the web socket setup
  //  they don't cover the actual web socket server itself, that module
  //  is maintained outside the code base and should be tested independently
  //  but this is a nice comprimise.

  describe('Web Socket Handler Type: false tests', () => {
    const handler = subject(false);

    afterEach(() => {
      events.off('data:set:test');
      events.off('data:get:test');
      events.off('some:event');
    });

    it('should be a function and return a function', () => {
      assert.isFunction(subject);
      assert.isFunction(subject(false));
    });

    it('should not emit events for data event messages', () => {
      const socket = {};

      handler(socket);

      socket.onmessage({
        data: '{ "event": "data:get:test" }'
      });

      assert.isUndefined(events.listeners('data:set:test'));
    });

    it('should not emit events for non-data event messages', (done) => {
      const socket = {};

      handler(socket);
      events.on('some:event', (data) => {
        if (typeof data === 'undefined') {
          assert.strictEqual(true, false);
        } else {
          done();
        }
      });

      socket.onmessage({
        data: '{ "event": "some:event" }'
      });

      setTimeout(() => {
        events.emit('some:event', true);
      }, 0);
    });
  });

  describe('Web Socket Handler Type: true tests', () => {
    const handler = subject(true);

    afterEach(() => {
      events.off('data:set:test');
      events.off('data:get:test');
    });

    it('should be a function and return a function', () => {
      assert.isFunction(subject);
      assert.isFunction(subject(true));
    });

    it('should emit events for data event messages', (done) => {
      const socket = {};

      events.once('data:get:test', (test) => {
        assert.isUndefined(test);
        done();
      });

      handler(socket);

      socket.onmessage({
        data: '{ "event": "data:get:test" }'
      });
    });

    it('should pass message and socket through to data new events', (done) => {
      const socket = {};

      handler(socket);

      events.once('data:new:person', (data) => {
        assert.isObject(data);
        assert.isObject(data.message);
        assert.isObject(data.message.payload);
        assert.isObject(data.socket);
        assert.strictEqual(socket, data.socket);
        assert.strictEqual(data.message.event, 'data:new:person');
        done();
      });

      socket.onmessage({
        data: '{ "event": "data:new:person", "payload": { "name": "daniel" } }'
      });
    });

    it('should emit events for non-data event messages', (done) => {
      const socket = {};

      handler(socket);

      events.once('some:event', () => {
        assert.strictEqual(true, true);
        done();
      });

      socket.onmessage({
        data: '{ "event": "some:event" }'
      });
    });

    it('should pass the message and socket through to passthrough events', (done) => {
      const socket = {};

      handler(socket);

      events.once('some:event', (data) => {
        assert.isObject(data);
        assert.isObject(data.message);
        assert.isObject(data.socket);
        assert.strictEqual(socket, data.socket);
        assert.strictEqual(data.message.event, 'some:event');
        done();
      });

      socket.onmessage({
        data: '{ "event": "some:event" }'
      });
    });

    it('should emit error:ws when error is occuring', (done) => {
      const socket = {
        send: (message, callback) => {
          callback('Some error');
          assert.strictEqual(events.listeners('error:ws').length, 1);
          done();
        }
      };

      handler(socket);

      socket.onmessage({
        data: '{ "event": "data:get:test" }'
      });

      events.once('data:get:test', () => {
        events.emit('data:set:test', { test: true });
      });

      events.once('error:ws', (message) => {
        assert.isObject(message);
      });
    });
  });

  describe('Web Socket Handler Type: data tests', () => {
    const handler = subject('data');

    afterEach(() => {
      events.off('data:set:test');
      events.off('data:get:test');
    });

    it('should be a function and return a function', () => {
      assert.isFunction(subject);
      assert.isFunction(subject('data'));
    });

    it('should emit events for data event messages', (done) => {
      const socket = {};

      events.once('data:get:test', (test) => {
        assert.isUndefined(test);
        done();
      });

      handler(socket);

      socket.onmessage({
        data: '{ "event": "data:get:test" }'
      });
    });

    it('should not emit events for non-data event messages', () => {
      const socket = {};

      handler(socket);

      socket.onmessage({
        data: '{ "event": "some:event" }'
      });

      assert.strictEqual(events.listeners('some:event').length, 0);
    });

    it('should not emit events for invalid JSON data', () => {
      const socket = {};

      handler(socket);

      socket.onmessage({
        data: '"event" : "some:event"'
      });

      assert.strictEqual(events.listeners('some:event').length, 0);
    });

    it('should return a string when responding to a socket', (done) => {
      const socket = {
        send: (message) => {
          assert.isString(message);
          done();
        }
      };

      handler(socket);

      events.once('data:get:test', () => {
        events.emit('data:set:test', { test: true });
      });

      socket.onmessage({
        data: '{ "event": "data:get:test" }'
      });
    });
  });

  describe('Web Socket Handler Type: passthrough tests', () => {
    const handler = subject('passthrough');

    afterEach(() => {
      events.off('data:set:test');
      events.off('data:get:test');
    });

    it('should be a function and return a function', () => {
      assert.isFunction(subject);
      assert.isFunction(subject('passthrough'));
    });

    it('should not emit events for data event messages', () => {
      const socket = {};

      handler(socket);

      socket.onmessage({
        data: '{ "event": "data:get:test" }'
      });

      assert.strictEqual(events.listeners('data:set:test').length, 0);
    });

    it('should emit events for non-data event messages', (done) => {
      const socket = {};

      handler(socket);

      events.once('some:event', () => {
        assert.strictEqual(true, true);
        done();
      });

      socket.onmessage({
        data: '{ "event": "some:event" }'
      });
    });

    it('should pass the message and socket through to passthrough events', (done) => {
      const socket = {};

      handler(socket);

      events.once('some:event', (data) => {
        assert.isObject(data);
        assert.isObject(data.message);
        assert.isObject(data.socket);
        assert.strictEqual(socket, data.socket);
        assert.strictEqual(data.message.event, 'some:event');
        done();
      });

      socket.onmessage({
        data: '{ "event": "some:event" }'
      });
    });

    it('should pass message and socket through to data new events', (done) => {
      const socket = {};

      handler(socket);

      events.once('data:new:person', (data) => {
        assert.isObject(data);
        assert.isObject(data.message);
        assert.isObject(data.message.payload);
        assert.isObject(data.socket);
        assert.strictEqual(socket, data.socket);
        assert.strictEqual(data.message.event, 'data:new:person');
        done();
      });

      socket.onmessage({
        data: '{ "event": "data:new:person", "payload": { "name": "daniel" } }'
      });
    });
  });
});
<|endoftext|>


<commit_before>import React from 'react';
import {NavLink, navigateAction} from 'fluxible-router';
import classNames from 'classnames/bind';
import {connectToStores} from 'fluxible-addons-react';
import ContentUtil from '../util/ContentUtil';
import DeckTreeStore from '../../../../stores/DeckTreeStore';
import UserProfileStore from '../../../../stores/UserProfileStore';
import addTreeNodeAndNavigate from '../../../../actions/decktree/addTreeNodeAndNavigate';
import deleteTreeNodeAndNavigate from '../../../../actions/decktree/deleteTreeNodeAndNavigate';
import AttachSubdeck from '../AttachSubdeck/AttachSubdeckModal';
import AttachSlides from '../AttachSubdeck/AttachSlidesModal';
import PermissionsStore from '../../../../stores/PermissionsStore';
import ContentStore from '../../../../stores/ContentStore';
import showNoPermissionsModal from '../../../../actions/permissions/showNoPermissionsModal';
import saveClick from '../../../../actions/slide/saveClick';
import cancelClick from '../../../../actions/slide/cancelClick';
import undoClick from '../../../../actions/slide/undoClick';
import redoClick from '../../../../actions/slide/redoClick';
import {defineMessages} from 'react-intl';

class ContentActionsHeader extends React.Component {
    constructor(props){
        super(props);
        this.messages = defineMessages({
            viewButtonText:{
                id: 'ContentActionsHeader.viewButtonText',
                defaultMessage:'View'
            },
            viewButtonAriaText:{
                id: 'ContentActionsHeader.viewButtonAriaText',
                defaultMessage:'View Mode'
            },
            editButtonText:{
                id: 'ContentActionsHeader.editButtonText',
                defaultMessage:'Edit'
            },
            editButtonAriaText:{
                id: 'ContentActionsHeader.editButtonAriaText',
                defaultMessage:'Edit Mode'
            },
            addSlideButtonAriaText:{
                id: 'ContentActionsHeader.addSlideButtonAriaText',
                defaultMessage:'Add Slide'
            },
            addDeckButtonAriaText:{
                id: 'ContentActionsHeader.addDeckButtonAriaText',
                defaultMessage:'Add Deck'
            },
            duplicateAriaText:{
                id: 'ContentActionsHeader.duplicateAriaText',
                defaultMessage:'Duplicate'
            },
            deleteAriaText:{
                id: 'ContentActionsHeader.deleteAriaText',
                defaultMessage:'Delete'
            },

        });

    }

    handleAddNode(selector, nodeSpec) {
        //selector: Object {id: "56", stype: "deck", sid: 67, spath: "67:2"}
        //nodeSec: Object {type: "slide", id: "0"}
        this.context.executeAction(addTreeNodeAndNavigate, {selector: selector, nodeSpec: nodeSpec});
    }

    handleDeleteNode(selector) {
        this.context.executeAction(deleteTreeNodeAndNavigate, selector);
    }

    handleSaveButtonClick(){
        this.context.executeAction(saveClick, {});
    }
    handleUndoButtonClick (){
        //this.context.executeAction(undoClick, {});
        //console.log('undo');
    }
    handleRedoButtonClick(){
        //this.context.executeAction(redoClick, {});
        //console.log('redo');
    }
    handleCancelButtonClick(selector){
        this.context.executeAction(cancelClick, {
            selector: selector
        });
    }
    handleViewButton(selector) {
        const nodeURL = ContentUtil.makeNodeURL(selector, 'view');
        this.context.executeAction(navigateAction, {
            url: nodeURL
        });

    }

    handleEditButton(selector) {
        const nodeURL = ContentUtil.makeNodeURL(selector, 'edit');
        if (this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit) {
            this.context.executeAction(showNoPermissionsModal, {selector: selector, user: this.props.UserProfileStore.userid, permissions: this.props.PermissionsStore.permissions});
        } else {
            this.context.executeAction(navigateAction, {
                url: nodeURL
            });
        }
    }
    render() {
        const contentDetails = this.props.ContentStore;
        //config buttons based on the selected item
        const editClass = classNames({
            'ui button basic': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const viewClass = classNames({
            ' ui small basic button': true,
            'disabled': contentDetails.mode ==='view'
        });
        const addSlideClass = classNames({
            'ui small basic left attached button': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const addDeckClass = classNames({
            'ui small basic left attached button': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const duplicateItemClass = classNames({
            'ui small basic left attached button': true,
            'disabled': contentDetails.selector.id === contentDetails.selector.sid || contentDetails.selector.stype==='deck' || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const deleteItemClass = classNames({
            'ui small basic left attached button': true,
            'disabled': contentDetails.selector.id === contentDetails.selector.sid || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const red = {
            backgroundColor: 'red'
        };

        let selectorImm = this.props.DeckTreeStore.selector;
        let selector = {id: selectorImm.get('id'), stype: selectorImm.get('stype'), sid: selectorImm.get('sid'), spath: selectorImm.get('spath')};

        let buttonStyle = {
            classNames : classNames({
                'small left attached':true,
                'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
            }),
            iconSize : 'large',
            attached : 'left',
            noTabIndex : this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        } ;
        let editButton, saveButton, cancelButton, undoButton, redoButton;

        if (contentDetails.mode === 'edit' && this.props.UserProfileStore.username !== ''){
            //edit mode & logged UserProfileStore
            editButton = '';
            //ref="" --> we can't use string refs as they are legacy. ref={(refName)=>{this.refName=refName}}
            if(contentDetails.selector.stype === 'slide'){
                saveButton =
                    <button tabIndex="0"  className="ui button primary " onClick={this.handleSaveButtonClick.bind(this)} onChange={this.handleSaveButtonClick.bind(this)}>

                        Save
                    </button>;
                cancelButton =
                    <button tabIndex="0"  className="ui button " onClick={this.handleCancelButtonClick.bind(this, selector)} onChange={this.handleCancelButtonClick.bind(this, selector)}>

                        Cancel
                    </button>;
            } else {
                saveButton ='';
                cancelButton ='';
            }

            /*It were not displayed in master...but the code is prepared for it*/
            undoButton ='';
            redoButton ='';

            /* discomment when we want to see them
            undoButton =
                    <button tabIndex="0"  className="ui orange button " onClick={this.handleUndoButtonClick.bind(this)} onChange={this.handleUndoButtonClick.bind(this)}>

                    </button>;
            redoButton =
                    <button tabIndex="0"  className="ui orange button " onClick={this.handleRedoButtonClick.bind(this)} onChange={this.handleRedoButtonClick.bind(this)}>

                    </button>;
            */

        } else{ //No buttons
            if(this.props.UserProfileStore.username !== '') /* Edit button only visible if logged user*/
            {
                editButton =
                    <button className={editClass} onClick={this.handleEditButton.bind(this,selector)}
                        type="button"
                        aria-label={this.context.intl.formatMessage(this.messages.editButtonAriaText)}
                        /*data-tooltip={this.context.intl.formatMessage(this.messages.editButtonAriaText)}*/
                        tabIndex = {contentDetails.mode ==='edit'?-1:0}
                        >
                        {this.context.intl.formatMessage(this.messages.editButtonText)}
                    </button>;
            }
            saveButton ='';
            cancelButton ='';
            undoButton ='';
            redoButton ='';

        }
        /*
        <button className={viewClass} onClick={this.handleViewButton.bind(this,selector)}
          type="button"
          aria-label={this.context.intl.formatMessage(this.messages.viewButtonAriaText)}
          data-tooltip={this.context.intl.formatMessage(this.messages.viewButtonAriaText)}
          tabIndex = {contentDetails.mode ==='edit'?0:-1}
        >
          {this.context.intl.formatMessage(this.messages.viewButtonText)}
        </button>
        */

        return (

                            {editButton}
                            {saveButton}
                            {cancelButton}
                            {undoButton}
                            {redoButton}

                        {this.props.UserProfileStore.username === '' ? '' :

                            <button className={addSlideClass} onClick={this.handleAddNode.bind(this, selector, {type: 'slide', id: '0'}) }
                                type="button"
                                aria-label={this.context.intl.formatMessage(this.messages.addSlideButtonAriaText)}
                                data-tooltip={this.context.intl.formatMessage(this.messages.addSlideButtonAriaText)}
                                tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                            </button>
                            <AttachSlides buttonStyle={buttonStyle} selector={selector} />
                            <button className={addDeckClass} onClick={this.handleAddNode.bind(this, selector, {type: 'deck', id: '0'})}
                                type="button"
                                aria-label={this.context.intl.formatMessage(this.messages.addDeckButtonAriaText)}
                                data-tooltip={this.context.intl.formatMessage(this.messages.addDeckButtonAriaText)}
                                tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                            </button>
                            <AttachSubdeck buttonStyle={buttonStyle} selector={selector} />
                            <button className={duplicateItemClass} onClick={this.handleAddNode.bind(this, selector, {type: selector.stype, id: selector.sid})}
                                type="button"
                                aria-label={this.context.intl.formatMessage(this.messages.duplicateAriaText)}
                                data-tooltip={this.context.intl.formatMessage(this.messages.duplicateAriaText)}
                                tabIndex={contentDetails.selector.id === contentDetails.selector.sid || contentDetails.selector.stype==='deck' || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                            </button>
                            <button className={deleteItemClass} onClick={this.handleDeleteNode.bind(this, selector)}
                                type="button"
                                aria-label={this.context.intl.formatMessage(this.messages.deleteAriaText)}
                                data-tooltip={this.context.intl.formatMessage(this.messages.deleteAriaText)}
                                tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                            </button>
                            {/*
                          <button className="item ui small basic right attached disabled button">

                          </button>
                          */}

                        }

        );
    }
}
ContentActionsHeader.contextTypes = {
    executeAction: React.PropTypes.func.isRequired,
    intl: React.PropTypes.object.isRequired
};
//it should listen to decktree store in order to handle adding slides/decks
ContentActionsHeader = connectToStores(ContentActionsHeader, [DeckTreeStore, UserProfileStore, PermissionsStore, ContentStore], (context, props) => {
    return {
        DeckTreeStore: context.getStore(DeckTreeStore).getState(),
        UserProfileStore: context.getStore(UserProfileStore).getState(),
        PermissionsStore: context.getStore(PermissionsStore).getState(),
        ContentStore: context.getStore(ContentStore).getState()
    };
});
export default ContentActionsHeader;
<commit_msg>Add border to edit button<commit_after>import React from 'react';
import {NavLink, navigateAction} from 'fluxible-router';
import classNames from 'classnames/bind';
import {connectToStores} from 'fluxible-addons-react';
import ContentUtil from '../util/ContentUtil';
import DeckTreeStore from '../../../../stores/DeckTreeStore';
import UserProfileStore from '../../../../stores/UserProfileStore';
import addTreeNodeAndNavigate from '../../../../actions/decktree/addTreeNodeAndNavigate';
import deleteTreeNodeAndNavigate from '../../../../actions/decktree/deleteTreeNodeAndNavigate';
import AttachSubdeck from '../AttachSubdeck/AttachSubdeckModal';
import AttachSlides from '../AttachSubdeck/AttachSlidesModal';
import PermissionsStore from '../../../../stores/PermissionsStore';
import ContentStore from '../../../../stores/ContentStore';
import showNoPermissionsModal from '../../../../actions/permissions/showNoPermissionsModal';
import saveClick from '../../../../actions/slide/saveClick';
import cancelClick from '../../../../actions/slide/cancelClick';
import undoClick from '../../../../actions/slide/undoClick';
import redoClick from '../../../../actions/slide/redoClick';
import {defineMessages} from 'react-intl';

class ContentActionsHeader extends React.Component {
    constructor(props){
        super(props);
        this.messages = defineMessages({
            viewButtonText:{
                id: 'ContentActionsHeader.viewButtonText',
                defaultMessage:'View'
            },
            viewButtonAriaText:{
                id: 'ContentActionsHeader.viewButtonAriaText',
                defaultMessage:'View Mode'
            },
            editButtonText:{
                id: 'ContentActionsHeader.editButtonText',
                defaultMessage:'Edit'
            },
            editButtonAriaText:{
                id: 'ContentActionsHeader.editButtonAriaText',
                defaultMessage:'Edit Mode'
            },
            addSlideButtonAriaText:{
                id: 'ContentActionsHeader.addSlideButtonAriaText',
                defaultMessage:'Add Slide'
            },
            addDeckButtonAriaText:{
                id: 'ContentActionsHeader.addDeckButtonAriaText',
                defaultMessage:'Add Deck'
            },
            duplicateAriaText:{
                id: 'ContentActionsHeader.duplicateAriaText',
                defaultMessage:'Duplicate'
            },
            deleteAriaText:{
                id: 'ContentActionsHeader.deleteAriaText',
                defaultMessage:'Delete'
            },

        });

    }

    handleAddNode(selector, nodeSpec) {
        //selector: Object {id: "56", stype: "deck", sid: 67, spath: "67:2"}
        //nodeSec: Object {type: "slide", id: "0"}
        this.context.executeAction(addTreeNodeAndNavigate, {selector: selector, nodeSpec: nodeSpec});
    }

    handleDeleteNode(selector) {
        this.context.executeAction(deleteTreeNodeAndNavigate, selector);
    }

    handleSaveButtonClick(){
        this.context.executeAction(saveClick, {});
    }
    handleUndoButtonClick (){
        //this.context.executeAction(undoClick, {});
        //console.log('undo');
    }
    handleRedoButtonClick(){
        //this.context.executeAction(redoClick, {});
        //console.log('redo');
    }
    handleCancelButtonClick(selector){
        this.context.executeAction(cancelClick, {
            selector: selector
        });
    }
    handleViewButton(selector) {
        const nodeURL = ContentUtil.makeNodeURL(selector, 'view');
        this.context.executeAction(navigateAction, {
            url: nodeURL
        });

    }

    handleEditButton(selector) {
        const nodeURL = ContentUtil.makeNodeURL(selector, 'edit');
        if (this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit) {
            this.context.executeAction(showNoPermissionsModal, {selector: selector, user: this.props.UserProfileStore.userid, permissions: this.props.PermissionsStore.permissions});
        } else {
            this.context.executeAction(navigateAction, {
                url: nodeURL
            });
        }
    }
    render() {
        const contentDetails = this.props.ContentStore;
        //config buttons based on the selected item
        const editClass = classNames({
            'ui button attached basic': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const viewClass = classNames({
            ' ui small basic button': true,
            'disabled': contentDetails.mode ==='view'
        });
        const addSlideClass = classNames({
            'ui small basic left attached button': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const addDeckClass = classNames({
            'ui small basic left attached button': true,
            'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const duplicateItemClass = classNames({
            'ui small basic left attached button': true,
            'disabled': contentDetails.selector.id === contentDetails.selector.sid || contentDetails.selector.stype==='deck' || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const deleteItemClass = classNames({
            'ui small basic left attached button': true,
            'disabled': contentDetails.selector.id === contentDetails.selector.sid || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        });
        const red = {
            backgroundColor: 'red'
        };

        let selectorImm = this.props.DeckTreeStore.selector;
        let selector = {id: selectorImm.get('id'), stype: selectorImm.get('stype'), sid: selectorImm.get('sid'), spath: selectorImm.get('spath')};

        let buttonStyle = {
            classNames : classNames({
                'small left attached':true,
                'disabled': this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
            }),
            iconSize : 'large',
            attached : 'left',
            noTabIndex : this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'
        } ;
        let editButton, saveButton, cancelButton, undoButton, redoButton;

        if (contentDetails.mode === 'edit' && this.props.UserProfileStore.username !== ''){
            //edit mode & logged UserProfileStore
            editButton = '';
            //ref="" --> we can't use string refs as they are legacy. ref={(refName)=>{this.refName=refName}}
            if(contentDetails.selector.stype === 'slide'){
                saveButton =
                    <button tabIndex="0"  className="ui button primary " onClick={this.handleSaveButtonClick.bind(this)} onChange={this.handleSaveButtonClick.bind(this)}>

                        Save
                    </button>;
                cancelButton =
                    <button tabIndex="0"  className="ui button " onClick={this.handleCancelButtonClick.bind(this, selector)} onChange={this.handleCancelButtonClick.bind(this, selector)}>

                        Cancel
                    </button>;
            } else {
                saveButton ='';
                cancelButton ='';
            }

            /*It were not displayed in master...but the code is prepared for it*/
            undoButton ='';
            redoButton ='';

            /* discomment when we want to see them
            undoButton =
                    <button tabIndex="0"  className="ui orange button " onClick={this.handleUndoButtonClick.bind(this)} onChange={this.handleUndoButtonClick.bind(this)}>

                    </button>;
            redoButton =
                    <button tabIndex="0"  className="ui orange button " onClick={this.handleRedoButtonClick.bind(this)} onChange={this.handleRedoButtonClick.bind(this)}>

                    </button>;
            */

        } else{ //No buttons
            if(this.props.UserProfileStore.username !== '') /* Edit button only visible if logged user*/
            {
                editButton =
                    <button className={editClass} onClick={this.handleEditButton.bind(this,selector)}
                        type="button"
                        aria-label={this.context.intl.formatMessage(this.messages.editButtonAriaText)}
                        /*data-tooltip={this.context.intl.formatMessage(this.messages.editButtonAriaText)}*/
                        tabIndex = {contentDetails.mode ==='edit'?-1:0}
                        >
                        {this.context.intl.formatMessage(this.messages.editButtonText)}
                    </button>;
            }
            saveButton ='';
            cancelButton ='';
            undoButton ='';
            redoButton ='';

        }
        /*
        <button className={viewClass} onClick={this.handleViewButton.bind(this,selector)}
          type="button"
          aria-label={this.context.intl.formatMessage(this.messages.viewButtonAriaText)}
          data-tooltip={this.context.intl.formatMessage(this.messages.viewButtonAriaText)}
          tabIndex = {contentDetails.mode ==='edit'?0:-1}
        >
          {this.context.intl.formatMessage(this.messages.viewButtonText)}
        </button>
        */

        return (

                            {editButton}
                            {saveButton}
                            {cancelButton}
                            {undoButton}
                            {redoButton}

                        {this.props.UserProfileStore.username === '' ? '' :

                            <button className={addSlideClass} onClick={this.handleAddNode.bind(this, selector, {type: 'slide', id: '0'}) }
                                type="button"
                                aria-label={this.context.intl.formatMessage(this.messages.addSlideButtonAriaText)}
                                data-tooltip={this.context.intl.formatMessage(this.messages.addSlideButtonAriaText)}
                                tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                            </button>
                            <AttachSlides buttonStyle={buttonStyle} selector={selector} />
                            <button className={addDeckClass} onClick={this.handleAddNode.bind(this, selector, {type: 'deck', id: '0'})}
                                type="button"
                                aria-label={this.context.intl.formatMessage(this.messages.addDeckButtonAriaText)}
                                data-tooltip={this.context.intl.formatMessage(this.messages.addDeckButtonAriaText)}
                                tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                            </button>
                            <AttachSubdeck buttonStyle={buttonStyle} selector={selector} />
                            <button className={duplicateItemClass} onClick={this.handleAddNode.bind(this, selector, {type: selector.stype, id: selector.sid})}
                                type="button"
                                aria-label={this.context.intl.formatMessage(this.messages.duplicateAriaText)}
                                data-tooltip={this.context.intl.formatMessage(this.messages.duplicateAriaText)}
                                tabIndex={contentDetails.selector.id === contentDetails.selector.sid || contentDetails.selector.stype==='deck' || this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                            </button>
                            <button className={deleteItemClass} onClick={this.handleDeleteNode.bind(this, selector)}
                                type="button"
                                aria-label={this.context.intl.formatMessage(this.messages.deleteAriaText)}
                                data-tooltip={this.context.intl.formatMessage(this.messages.deleteAriaText)}
                                tabIndex={this.props.PermissionsStore.permissions.readOnly || !this.props.PermissionsStore.permissions.edit || contentDetails.mode ==='edit'?-1:0}>

                            </button>
                            {/*
                          <button className="item ui small basic right attached disabled button">

                          </button>
                          */}

                        }

        );
    }
}
ContentActionsHeader.contextTypes = {
    executeAction: React.PropTypes.func.isRequired,
    intl: React.PropTypes.object.isRequired
};
//it should listen to decktree store in order to handle adding slides/decks
ContentActionsHeader = connectToStores(ContentActionsHeader, [DeckTreeStore, UserProfileStore, PermissionsStore, ContentStore], (context, props) => {
    return {
        DeckTreeStore: context.getStore(DeckTreeStore).getState(),
        UserProfileStore: context.getStore(UserProfileStore).getState(),
        PermissionsStore: context.getStore(PermissionsStore).getState(),
        ContentStore: context.getStore(ContentStore).getState()
    };
});
export default ContentActionsHeader;
<|endoftext|>