<commit_before>angular.module('roadmaps.ctrl', ['roadmaps.factory', 'services.server', 'services.user'])

.controller('RoadMapsController', [ '$scope', '$http', '$stateParams', 'RoadMapsFactory', 'Server', 'User', '$timeout', '$state', function($scope, $http, $stateParams, RoadMapsFactory, Server, User, $timeout, $state){
  angular.extend($scope, RoadMapsFactory);

  var roadmapId = $stateParams.roadmapID;
  $scope.currentRoadMapData = {};
  $scope.renderedNodes = [];
  $('.tooltipped').tooltip({delay: 50});

  $scope.showComments = false;

  $scope.toggleComments = function(){
    $scope.showComments = true;
  };

  $scope.hideText = function ($index, field){
    var id = field + '-' + $index;
    if( $scope[id] ){
      return  true;
    } else {
      return false;
    }
  };

  $scope.showEditor = function ($index, field, boolean){
    var id = field + '-' + $index;
    $scope[id] = boolean;
  };

  $scope.getPlaceholder = function($index, field){
    return $scope.renderedNodes[$index][field];
  };

  $scope.saveEdit = function($index, field){
    var elementID = '#' + field + '-' + $index;
    var newProperty = $(elementID).val();

    Server.updateNode({ _id: $scope.renderedNodes[$index]._id, title: newProperty})
      .then(function(node) {
      console.log(node);
    });
  };

 // Get the current number of upvotes from current map
 $scope.getCountVotes = function(votes){
    $scope.votesCount = 0;
    for(var i = 0; i < votes.length; i++){
      $scope.votesCount++;
    }
    return $scope.votesCount;
 }

 // Renders the nodes for the current roadmap to the page
  $scope.renderNodes = function(){
    var title = $scope.currentRoadMapData.title || 'test title';
    var nodes = $scope.currentRoadMapData.nodes || ['testnode1', 'testnode2'];
    // Add an index to nodes to make ng-clicking easier
    nodes.map(function(node,index){
      node.index = index;
    });

    $scope.renderedNodes = nodes;
    $scope.roadMapTitle = title;

    // User Logged in Data in the future
    // Some variable that holds that the user is logged in
    $scope.currentNode = nodes[0];
    $scope.renderCurrentNode();
  };
  // Make a $scope.renderComments()
  $scope.renderComments = function(){
    var comments = $scope.currentRoadMapData.comments;
    console.log(comments);
    comments.map(function(comment,index){
      comment.index = index;
    })
    $scope.renderedComments = comments;
  }

  // When roadmap (identified by its id) data is fetched, set it
  Server.getRoadmapById(roadmapId).then(function (res){
      $scope.currentRoadMapData = res;
      console.log($scope.currentRoadMapData,'I am the roadmap');
    }, function(err){
      if (err) return console.log(err);
    })
    .then(function(){
      $scope.renderNodes();
      $scope.renderComments();
      // Set the upvotes and downvotes
      var currentMapUpVotes = $scope.currentRoadMapData.upvotes;
      var currentMapDownVotes = $scope.currentRoadMapData.downvotes;
      $scope.upVoteCount = $scope.getCountVotes(currentMapUpVotes);
      $scope.downVoteCount = $scope.getCountVotes(currentMapDownVotes);
  });

  // Render Title
  // Assumes title links and description properties from get method
  $scope.renderCurrentNode = function(){
    // For now lets make $scope.loggedIn be false, if logged in we can change it to true later.
    $scope.loggedin = false;
    if($scope.loggedIn) {
      // Get node index
      // set currentNode into node at that index;
    } else {
      //links from a node
      var links = $scope.renderedNodes[0].resourceURL;
      //description of a node
      var description = $scope.renderedNodes[0].description;
      var title = $scope.renderedNodes[0].title;
    }

    $scope.currentTitle = title;
    $scope.currentLinks = [links];
    $scope.currentNodeDescription = description;
  }

  $scope.selectNode = function(index) {

    var links = $scope.renderedNodes[index].resourceURL;
    var description = $scope.renderedNodes[index].description;
    var title = $scope.renderedNodes[index].title;

    $scope.currentIndex = index;
    $scope.currentTitle = title;
    $scope.currentLinks = [links];
    $scope.currentNodeDescription = description;
    $scope.currentNode = $scope.renderedNodes[index];

  };
  // Submits a node to the user's inProgress.nodes array.
  $scope.submitCompletedNode = function() {
    var nodeId = $scope.currentNode._id;
    User.completeNodeById(nodeId);
    Materialize.toast('Node Complete!', 4000, 'orangeToast');
  }

  // Submits a roadmap to the user's completedRoadmaps array.
  $scope.submitCompletedRoadmap = function() {
    Materialize.toast('Map Complete!', 4000, 'orangeToast');
    User.completeRoadmapById(roadmapId);
    $state.go('home.dashboard', {type: 'completed'});
  }

  // After upvote, submits vote update to the roadmap's upvotes and downvotes array
  $scope.upVoteMap = function () {
    User.upvoteMapById(roadmapId)
    .then(function(data){
      var dataUpVoteCount = data.upvotes;
      var dataDownVoteCount = data.downvotes;
      // Update the upvote count
      $scope.upVoteCount = $scope.getCountVotes(dataUpVoteCount);
      // Update the downvote count
      $scope.downVoteCount = $scope.getCountVotes(dataDownVoteCount);
    })
  }

  // After downvote, submits vote update to the roadmap's upvotes and downvotes array
  $scope.downVoteMap = function () {
    User.downvoteMapById(roadmapId)
    .then(function(data){
      var dataUpVoteCount = data.upvotes;
      var dataDownVoteCount = data.downvotes;
      // Update the upvote count
      $scope.upVoteCount = $scope.getCountVotes(dataUpVoteCount);
      // Update the downvote count
      $scope.downVoteCount = $scope.getCountVotes(dataDownVoteCount);
    });
  };

  $scope.connectLines = function(){
    $('.endPointForConnection').connections();
  };

  // We need async because ng-repeat creates the nodes before this function runs set timeout changes the loop.
  $scope.asyncConnectLines = function(cb){
    setTimeout($scope.connectLines,0);
  };

  $scope.subject = '';
  $scope.content = '';

  $scope.postComment = function(){
    // Will probably need to refactor
    $scope.currentRoadMapData.comments = $scope.currentRoadMapData.comments || [];

    Server.createComment({
      subject: $scope.subject,
      content: $scope.content,
      roadmap: $scope.currentRoadMapData._id
    });
  };

}]);<commit_msg>(fix) Smoothe out bugs in editor element<commit_after>angular.module('roadmaps.ctrl', ['roadmaps.factory', 'services.server', 'services.user'])

.controller('RoadMapsController', [ '$scope', '$http', '$stateParams', 'RoadMapsFactory', 'Server', 'User', '$timeout', '$state', function($scope, $http, $stateParams, RoadMapsFactory, Server, User, $timeout, $state){
  angular.extend($scope, RoadMapsFactory);

  var roadmapId = $stateParams.roadmapID;
  $scope.currentRoadMapData = {};
  $scope.renderedNodes = [];
  $('.tooltipped').tooltip({delay: 50});

  $scope.showComments = false;

  $scope.toggleComments = function(){
    $scope.showComments = true;
  };

  $scope.hideText = function ($index, field){
    var id = field + '-' + $index;
    if( $scope[id] ){
      return  true;
    } else {
      return false;
    }
  };

  $scope.showEditor = function ($index, field, boolean){
    if(boolean === false){
      var elementID = '#' + field + '-' + $index;
      console.log('want to reset', $(elementID).val());
      $(elementID).val($scope.renderedNodes[$index][field]);
    }
    var id = field + '-' + $index;
    $scope[id] = boolean;
  };

  $scope.getPlaceholder = function($index, field){
    return $scope.renderedNodes[$index][field];
  };

  $scope.saveEdit = function($index, field){
    var elementID = '#' + field + '-' + $index;
    var newProperty = $(elementID).val();

    Server.updateNode({ _id: $scope.renderedNodes[$index]._id, title: newProperty})
      .then(function(node) {
      $scope.showEditor($index, field, false);
      $scope.renderedNodes[$index][field] = newProperty;
    })
      .catch(function(){
        console.log('problem updating node', err);
      });
  };

 // Get the current number of upvotes from current map
 $scope.getCountVotes = function(votes){
    $scope.votesCount = 0;
    for(var i = 0; i < votes.length; i++){
      $scope.votesCount++;
    }
    return $scope.votesCount;
 }

 // Renders the nodes for the current roadmap to the page
  $scope.renderNodes = function(){
    var title = $scope.currentRoadMapData.title || 'test title';
    var nodes = $scope.currentRoadMapData.nodes || ['testnode1', 'testnode2'];
    // Add an index to nodes to make ng-clicking easier
    nodes.map(function(node,index){
      node.index = index;
    });

    $scope.renderedNodes = nodes;
    $scope.roadMapTitle = title;

    // User Logged in Data in the future
    // Some variable that holds that the user is logged in
    $scope.currentNode = nodes[0];
    $scope.renderCurrentNode();
  };
  // Make a $scope.renderComments()
  $scope.renderComments = function(){
    var comments = $scope.currentRoadMapData.comments;
    console.log(comments);
    comments.map(function(comment,index){
      comment.index = index;
    })
    $scope.renderedComments = comments;
  }

  // When roadmap (identified by its id) data is fetched, set it
  Server.getRoadmapById(roadmapId).then(function (res){
      $scope.currentRoadMapData = res;
      console.log($scope.currentRoadMapData,'I am the roadmap');
    }, function(err){
      if (err) return console.log(err);
    })
    .then(function(){
      $scope.renderNodes();
      $scope.renderComments();
      // Set the upvotes and downvotes
      var currentMapUpVotes = $scope.currentRoadMapData.upvotes;
      var currentMapDownVotes = $scope.currentRoadMapData.downvotes;
      $scope.upVoteCount = $scope.getCountVotes(currentMapUpVotes);
      $scope.downVoteCount = $scope.getCountVotes(currentMapDownVotes);
  });

  // Render Title
  // Assumes title links and description properties from get method
  $scope.renderCurrentNode = function(){
    // For now lets make $scope.loggedIn be false, if logged in we can change it to true later.
    $scope.loggedin = false;
    if($scope.loggedIn) {
      // Get node index
      // set currentNode into node at that index;
    } else {
      //links from a node
      var links = $scope.renderedNodes[0].resourceURL;
      //description of a node
      var description = $scope.renderedNodes[0].description;
      var title = $scope.renderedNodes[0].title;
    }

    $scope.currentTitle = title;
    $scope.currentLinks = [links];
    $scope.currentNodeDescription = description;
  }

  $scope.selectNode = function(index) {

    var links = $scope.renderedNodes[index].resourceURL;
    var description = $scope.renderedNodes[index].description;
    var title = $scope.renderedNodes[index].title;

    $scope.currentIndex = index;
    $scope.currentTitle = title;
    $scope.currentLinks = [links];
    $scope.currentNodeDescription = description;
    $scope.currentNode = $scope.renderedNodes[index];

  };
  // Submits a node to the user's inProgress.nodes array.
  $scope.submitCompletedNode = function() {
    var nodeId = $scope.currentNode._id;
    User.completeNodeById(nodeId);
    Materialize.toast('Node Complete!', 4000, 'orangeToast');
  }

  // Submits a roadmap to the user's completedRoadmaps array.
  $scope.submitCompletedRoadmap = function() {
    Materialize.toast('Map Complete!', 4000, 'orangeToast');
    User.completeRoadmapById(roadmapId);
    $state.go('home.dashboard', {type: 'completed'});
  }

  // After upvote, submits vote update to the roadmap's upvotes and downvotes array
  $scope.upVoteMap = function () {
    User.upvoteMapById(roadmapId)
    .then(function(data){
      var dataUpVoteCount = data.upvotes;
      var dataDownVoteCount = data.downvotes;
      // Update the upvote count
      $scope.upVoteCount = $scope.getCountVotes(dataUpVoteCount);
      // Update the downvote count
      $scope.downVoteCount = $scope.getCountVotes(dataDownVoteCount);
    })
  }

  // After downvote, submits vote update to the roadmap's upvotes and downvotes array
  $scope.downVoteMap = function () {
    User.downvoteMapById(roadmapId)
    .then(function(data){
      var dataUpVoteCount = data.upvotes;
      var dataDownVoteCount = data.downvotes;
      // Update the upvote count
      $scope.upVoteCount = $scope.getCountVotes(dataUpVoteCount);
      // Update the downvote count
      $scope.downVoteCount = $scope.getCountVotes(dataDownVoteCount);
    });
  };

  $scope.connectLines = function(){
    $('.endPointForConnection').connections();
  };

  // We need async because ng-repeat creates the nodes before this function runs set timeout changes the loop.
  $scope.asyncConnectLines = function(cb){
    setTimeout($scope.connectLines,0);
  };

  $scope.subject = '';
  $scope.content = '';

  $scope.postComment = function(){
    // Will probably need to refactor
    $scope.currentRoadMapData.comments = $scope.currentRoadMapData.comments || [];

    Server.createComment({
      subject: $scope.subject,
      content: $scope.content,
      roadmap: $scope.currentRoadMapData._id
    });
  };

}]);<|endoftext|>


<commit_before>angular.module('roadmaps.ctrl', ['roadmaps.factory', 'services.server', 'services.user', 'scraper.ctrl'])

.controller('RoadMapsController', [ '$scope', '$http', '$stateParams', 'RoadmapsFactory', 'Server', 'User', '$timeout', '$state', function($scope, $http, $stateParams, RoadmapsFactory, Server, User, $timeout, $state){
  angular.extend($scope, RoadmapsFactory);

  var roadmapId = $stateParams.roadmapID;

  $scope.currentRoadMapData = {};
  $scope.renderedNodes = [];
  $('.tooltipped').tooltip({delay: 50});

  $scope.isAuthor = false;
  $scope.showComments = false;
  $scope.currentIndex = 0;
  $scope.hideTitle = false;
  $scope.hideDesc = false;

  $scope.toggleComments = function(){
    $scope.showComments = !$scope.showComments;
  };

  resetCreationForm();

  $scope.checkAndSubmit = function() {
    var url = $scope.urlToScrape;
    if (url.length < 4) return;
    if (url.substring(0, 4) !== 'http') url = 'http://' + url;

    Server.scrape(url)
    .then(function (data) {
      console.log('web scrape data is', data);
        $scope.currentCreationTitle = data.title;
        $scope.currentCreationDescription = data.description;
        $scope.currentCreationType = data.type;
        $scope.currentCreationLink = url;
        $scope.currentCreationImage = data.imageUrl;
    });
  };

  $scope.showNodeCreator = function($index, boolean){
    $scope.currentAddIndex = $index + 1;
    if( !$scope.isAuthor ){
      $scope.nodeCreator = false;
    } else {
      $scope.displayNodeCreator = boolean;
    }
  }

  $scope.createNode = function($index) {
    console.log($scope.currentCreationImage);
    if( $scope.currentCreationImage === 'New node image (optional)' ){
      $scope.currentCreationImage = NODE_DEFAULTS.imageUrl;
    }
    $('#editor-placeholder').remove();
    console.log("CREATE NODE $index", $index);

    return Server.createNode({
      title: $scope.currentCreationTitle || NODE_DEFAULTS.title,
      description: $scope.currentCreationDescription || NODE_DEFAULTS.description,
      resourceType: $scope.currentCreationType || NODE_DEFAULTS.resourceType,
      resourceURL: $scope.currentCreationLink || NODE_DEFAULTS.resourceURL,
      imageUrl: $scope.currentCreationImage || NODE_DEFAULTS.imageUrl,
      parentRoadmap: roadmapId,
      saveAtIndex: $index

    })
    .then(function(res){
      populateData();
      $scope.displayNodeCreator = false;
      Materialize.toast('Node Added!', 4000, 'orangeToast');
      resetCreationForm();
    });
  };

  $scope.closeNodeCreator = function(){
    $scope.displayNodeCreator = false;
    resetCreationForm();
  }

  $scope.hideText = function ($index, field, idPrefix){
    var elementID = '#' + idPrefix + '-' + field + '-' + $index;
    if( !$scope.isAuthor ){
      return false;
    } else {
      if( !$scope[elementID] ){
        return  false;
      } else {
        return true;
      }
    }
  };

  $scope.showEditor = function ($index, field, boolean, idPrefix){
    var elementID = '#' + idPrefix + '-' + field + '-' + $index;
    $scope.currentIndex = $index;

    if( !$scope.isAuthor ){
      $scope[elementID] = false;
    } else {
      if( field === 'circle' && idPrefix === 'mini'){
        resetCreationForm();
      }
      if( !$scope.currentResourceURL ) {
        $scope.currentResourceURL = $scope.currentLinks[0];
      }

      if(boolean === false && field !== 'circle'){
        $(elementID).val($scope.renderedNodes[$index][field]);
      }

      $scope[elementID] = boolean;
    }

  };

  $scope.getPlaceholder = function($index, field){
    var capitalizedField = field.substr(0, 1).toUpperCase() + field.substr(1);
    return $scope['current' + capitalizedField];
  };

  $scope.saveEdit = function($index, field, idPrefix){
    var elementID = '#' + idPrefix + '-' + field + '-' + $index;
    var newProperty = $(elementID).val();
    var updateObj = {};
    updateObj['_id'] = $scope.renderedNodes[$index]._id;
    updateObj[field] = newProperty;
    Server.updateNode(updateObj)
      .then(function(node) {
      $scope.showEditor($index, field, false, idPrefix);
      $scope.renderedNodes[$index][field] = newProperty;
      var capitalizedField = field.substr(0, 1).toUpperCase() + field.substr(1);
      $scope['current' + capitalizedField] = newProperty;
      if( field === 'resourceURL' ){
        $scope.currentLinks[0] = newProperty;
      }
    })
      .catch(function(){
        console.log('problem updating node', err);
      });
  };

  $scope.showTitleEditor = function (boolean){
    if( !$scope.isAuthor ){
      $scope.hideTitle = false;
    } else {
      $scope.hideTitle = boolean;
      return $scope.hideTitle;
    }
  };

  $scope.saveTitleEdit = function (){
    var newProperty = $('#main-title').val();
    var updateObj = {};
    updateObj['_id'] = roadmapId;
    updateObj['title'] = newProperty;
    Server.updateRoadmap(updateObj)
      .then(function(node) {
      $scope.hideTitle = false;
      $scope.roadMapTitle = newProperty;
    })
      .catch(function(){
        console.log('problem updating map title', err);
      });
  }

  $scope.showDescEditor = function (boolean){
    if( !$scope.isAuthor ){
      $scope.hideDesc= false;
    } else {
      $scope.hideDesc = boolean;
      return $scope.hideDesc;
    }
  };

  $scope.saveDescEdit = function (){
    updateObj['_id'] = roadmapId;
    updateObj['description'] = $('#main-desc').val();
    console.log('new desc', newProperty);
    Server.updateRoadmap(updateObj)
      .then(function(node) {
      $scope.hideDesc = false;
      $scope.roadMapDesc = newProperty;
    })
      .catch(function(){
        console.log('problem updating map description', err);
      });
  }

 // Get the current number of upvotes from current map

 // Renders the nodes for the current roadmap to the page
  $scope.renderNodes = function(){
    var title = $scope.currentRoadMapData.title || 'test title';
    var nodes = $scope.currentRoadMapData.nodes || ['testnode1', 'testnode2'];
    var desc =  $scope.currentRoadMapData.description || 'default roadmap description - click to edit!';
    // Add an index to nodes to make ng-clicking easier
    nodes.map(function(node,index){
      node.index = index;
    });

    $scope.renderedNodes = nodes;
    $scope.roadMapTitle = title;
    $scope.roadMapDesc = desc;
    $scope.currentNode = nodes[0];
    $scope.currentTitle = $scope.renderedNodes[0].title;
    $scope.currentLinks = [$scope.renderedNodes[0].resourceURL];
    $scope.currentDescription = $scope.renderedNodes[0].description;
  };

  // When roadmap (identified by its id) data is fetched, set it
  function populateData (stop){
    // conditional populateData call can't be called more than once
    stop = stop || false;
    Server.getRoadmapById(roadmapId).then(function (res){
      if( !res.nodes.length && stop === false){
        populateData(true);
      }
      $scope.currentRoadMapData = res;
      console.log($scope.currentRoadMapData,'I am the roadmap');
    }, function(err){
      if (err) return console.log(err);
    })
    .then(function(){
      $scope.renderNodes();
      $scope.renderedComments = RoadmapsFactory.renderComments($scope.currentRoadMapData.comments);
      // Set the upvotes and downvotes
      $scope.upVoteCount = RoadmapsFactory.getCountVotes($scope.currentRoadMapData.upvotes);
      $scope.downVoteCount = RoadmapsFactory.getCountVotes($scope.currentRoadMapData.downvotes);

      // append Editor Mode message
      username = localStorage.getItem('user.username');
      roadmapAuthor = $scope.currentRoadMapData.author.username;
      $scope.isAuthor = username === roadmapAuthor;

      if( !$scope.isAuthor ){
        $('#editor-placeholder').append(RoadmapsFactory.editorMsgHTML);
      }
    });
  }

  populateData();

  $scope.selectNode = function($index) {
    $scope.currentIndex = $index;
    $scope.currentTitle = $scope.renderedNodes[$index].title;
    $scope.currentLinks = $scope.renderedNodes[$index].resourceURL;
    $scope.currentResourceURL = $scope.currentLinks[0];
    $scope.currentDescription = $scope.renderedNodes[$index].description;
    $scope.currentNode = $scope.renderedNodes[$index];
    $scope.currentImageUrl = $scope.renderedNodes[$index].imageUrl;
  };
  // Submits a node to the user's inProgress.nodes array.
  $scope.submitCompletedNode = function() {
    var nodeId = $scope.currentNode._id;
    User.completeNodeById(nodeId);
    Materialize.toast('Node Complete!', 4000, 'orangeToast');
  }

  // Submits a roadmap to the user's completedRoadmaps array.
  $scope.submitCompletedRoadmap = function() {
    Materialize.toast('Map Complete!', 4000, 'orangeToast');
    User.completeRoadmapById(roadmapId);
    $state.go('home.dashboard', {type: 'completed'});
  }

  // After upvote, submits vote update to the roadmap's upvotes and downvotes array
  $scope.upVoteMap = function () {
    User.upvoteMapById(roadmapId)
    .then(function(data){
      var dataUpVoteCount = data.upvotes;
      var dataDownVoteCount = data.downvotes;
      // Update the upvote count
      $scope.upVoteCount = RoadmapsFactory.getCountVotes(dataUpVoteCount);
      // Update the downvote count
      $scope.downVoteCount = RoadmapsFactory.getCountVotes(dataDownVoteCount);
    })
  }

  // After downvote, submits vote update to the roadmap's upvotes and downvotes array
  $scope.downVoteMap = function () {
    User.downvoteMapById(roadmapId)
    .then(function(data){
      var dataUpVoteCount = data.upvotes;
      var dataDownVoteCount = data.downvotes;
      // Update the upvote count
      $scope.upVoteCount = RoadmapsFactory.getCountVotes(dataUpVoteCount);
      // Update the downvote count
      $scope.downVoteCount = RoadmapsFactory.getCountVotes(dataDownVoteCount);
    });
  };

  $scope.subject = '';
  $scope.content = '';

  $scope.postComment = function(){
    // Will probably need to refactor
    $scope.currentRoadMapData.comments = $scope.currentRoadMapData.comments || [];

    Server.createComment({
      subject: $scope.subject,
      content: $scope.content,
      roadmap: $scope.currentRoadMapData._id
    });
  };

  // utility functions
  function resetCreationForm () {
    $scope.urlToScrape = "Paste a link here to get info automatically";
    $scope.currentCreationTitle = RoadmapsFactory.NODE_DEFAULTS.title;
    $scope.currentCreationDescription = RoadmapsFactory.NODE_DEFAULTS.description;
    $scope.currentCreationType = RoadmapsFactory.NODE_DEFAULTS.resourceType;
    $scope.currentCreationLink = RoadmapsFactory.NODE_DEFAULTS.resourceURL;
    $scope.currentCreationImage = 'New node image (optional)';
  }

}]);
<commit_msg>(refactor) Remove unnecessary lines<commit_after>angular.module('roadmaps.ctrl', ['roadmaps.factory', 'services.server', 'services.user', 'scraper.ctrl'])

.controller('RoadMapsController', [ '$scope', '$http', '$stateParams', 'RoadmapsFactory', 'Server', 'User', '$timeout', '$state', function($scope, $http, $stateParams, RoadmapsFactory, Server, User, $timeout, $state){
  angular.extend($scope, RoadmapsFactory);

  var roadmapId = $stateParams.roadmapID;

  $scope.currentRoadMapData = {};
  $scope.renderedNodes = [];
  $('.tooltipped').tooltip({delay: 50});

  $scope.isAuthor = false;
  $scope.showComments = false;
  $scope.currentIndex = 0;
  $scope.hideTitle = false;
  $scope.hideDesc = false;

  $scope.toggleComments = function(){
    $scope.showComments = !$scope.showComments;
  };

  resetCreationForm();

  $scope.checkAndSubmit = function() {
    var url = $scope.urlToScrape;
    if (url.length < 4) return;
    if (url.substring(0, 4) !== 'http') url = 'http://' + url;

    Server.scrape(url)
    .then(function (data) {
      console.log('web scrape data is', data);
        $scope.currentCreationTitle = data.title;
        $scope.currentCreationDescription = data.description;
        $scope.currentCreationType = data.type;
        $scope.currentCreationLink = url;
        $scope.currentCreationImage = data.imageUrl;
    });
  };

  $scope.showNodeCreator = function($index, boolean){
    $scope.currentAddIndex = $index + 1;
    if( !$scope.isAuthor ){
      $scope.nodeCreator = false;
    } else {
      $scope.displayNodeCreator = boolean;
    }
  }

  $scope.createNode = function($index) {
    console.log($scope.currentCreationImage);
    if( $scope.currentCreationImage === 'New node image (optional)' ){
      $scope.currentCreationImage = NODE_DEFAULTS.imageUrl;
    }
    $('#editor-placeholder').remove();
    console.log("CREATE NODE $index", $index);

    return Server.createNode({
      title: $scope.currentCreationTitle || NODE_DEFAULTS.title,
      description: $scope.currentCreationDescription || NODE_DEFAULTS.description,
      resourceType: $scope.currentCreationType || NODE_DEFAULTS.resourceType,
      resourceURL: $scope.currentCreationLink || NODE_DEFAULTS.resourceURL,
      imageUrl: $scope.currentCreationImage || NODE_DEFAULTS.imageUrl,
      parentRoadmap: roadmapId,
      saveAtIndex: $index

    })
    .then(function(res){
      populateData();
      $scope.displayNodeCreator = false;
      Materialize.toast('Node Added!', 4000, 'orangeToast');
      resetCreationForm();
    });
  };

  $scope.closeNodeCreator = function(){
    $scope.displayNodeCreator = false;
    resetCreationForm();
  }

  $scope.hideText = function ($index, field, idPrefix){
    var elementID = '#' + idPrefix + '-' + field + '-' + $index;
    if( !$scope.isAuthor ){
      return false;
    } else {
      if( !$scope[elementID] ){
        return  false;
      } else {
        return true;
      }
    }
  };

  $scope.showEditor = function ($index, field, boolean, idPrefix){
    var elementID = '#' + idPrefix + '-' + field + '-' + $index;
    $scope.currentIndex = $index;

    if( !$scope.isAuthor ){
      $scope[elementID] = false;
    } else {
      if( field === 'circle' && idPrefix === 'mini'){
        resetCreationForm();
      }
      if( !$scope.currentResourceURL ) {
        $scope.currentResourceURL = $scope.currentLinks[0];
      }

      if(boolean === false && field !== 'circle'){
        $(elementID).val($scope.renderedNodes[$index][field]);
      }

      $scope[elementID] = boolean;
    }

  };

  $scope.getPlaceholder = function($index, field){
    var capitalizedField = field.substr(0, 1).toUpperCase() + field.substr(1);
    return $scope['current' + capitalizedField];
  };

  $scope.saveEdit = function($index, field, idPrefix){
    var elementID = '#' + idPrefix + '-' + field + '-' + $index;
    var newProperty = $(elementID).val();
    var updateObj = {};
    updateObj['_id'] = $scope.renderedNodes[$index]._id;
    updateObj[field] = newProperty;
    Server.updateNode(updateObj)
      .then(function(node) {
      $scope.showEditor($index, field, false, idPrefix);
      $scope.renderedNodes[$index][field] = newProperty;
      var capitalizedField = field.substr(0, 1).toUpperCase() + field.substr(1);
      $scope['current' + capitalizedField] = newProperty;
      if( field === 'resourceURL' ){
        $scope.currentLinks[0] = newProperty;
      }
    })
      .catch(function(){
        console.log('problem updating node', err);
      });
  };

  $scope.showTitleEditor = function (boolean){
    if( !$scope.isAuthor ){
      $scope.hideTitle = false;
    } else {
      $scope.hideTitle = boolean;
      return $scope.hideTitle;
    }
  };

  $scope.saveTitleEdit = function (){
    var newProperty = $('#main-title').val();
    var updateObj = {};
    updateObj['_id'] = roadmapId;
    updateObj['title'] = newProperty;
    Server.updateRoadmap(updateObj)
      .then(function(node) {
      $scope.hideTitle = false;
      $scope.roadMapTitle = newProperty;
    })
      .catch(function(){
        console.log('problem updating map title', err);
      });
  }

  $scope.showDescEditor = function (boolean){
    if( !$scope.isAuthor ){
      $scope.hideDesc= false;
    } else {
      $scope.hideDesc = boolean;
      return $scope.hideDesc;
    }
  };

  $scope.saveDescEdit = function (){
    updateObj['_id'] = roadmapId;
    updateObj['description'] = $('#main-desc').val();
    console.log('new desc', newProperty);
    Server.updateRoadmap(updateObj)
      .then(function(node) {
      $scope.hideDesc = false;
      $scope.roadMapDesc = newProperty;
    })
      .catch(function(){
        console.log('problem updating map description', err);
      });
  }

 // Get the current number of upvotes from current map

 // Renders the nodes for the current roadmap to the page
  $scope.renderNodes = function(){
    var title = $scope.currentRoadMapData.title || 'test title';
    var nodes = $scope.currentRoadMapData.nodes || ['testnode1', 'testnode2'];
    var desc =  $scope.currentRoadMapData.description || 'default roadmap description - click to edit!';
    // Add an index to nodes to make ng-clicking easier
    nodes.map(function(node,index){
      node.index = index;
    });

    $scope.renderedNodes = nodes;
    $scope.roadMapTitle = title;
    $scope.roadMapDesc = desc;
    $scope.currentNode = nodes[0];
    $scope.currentTitle = $scope.renderedNodes[0].title;
    $scope.currentLinks = [$scope.renderedNodes[0].resourceURL];
    $scope.currentDescription = $scope.renderedNodes[0].description;
  };

  // When roadmap (identified by its id) data is fetched, set it
  function populateData (stop){
    // conditional populateData call can't be called more than once
    stop = stop || false;
    Server.getRoadmapById(roadmapId).then(function (res){
      if( !res.nodes.length && stop === false){
        populateData(true);
      }
      $scope.currentRoadMapData = res;
      console.log($scope.currentRoadMapData,'I am the roadmap');
    }, function(err){
      if (err) return console.log(err);
    })
    .then(function(){
      $scope.renderNodes();
      $scope.renderedComments = RoadmapsFactory.renderComments($scope.currentRoadMapData.comments);
      // Set the upvotes and downvotes
      $scope.upVoteCount = RoadmapsFactory.getCountVotes($scope.currentRoadMapData.upvotes);
      $scope.downVoteCount = RoadmapsFactory.getCountVotes($scope.currentRoadMapData.downvotes);

      // append Editor Mode message
      username = localStorage.getItem('user.username');
      roadmapAuthor = $scope.currentRoadMapData.author.username;
      $scope.isAuthor = username === roadmapAuthor;

      if( !$scope.isAuthor ){
        $('#editor-placeholder').append(RoadmapsFactory.editorMsgHTML);
      }
    });
  }

  populateData();

  $scope.selectNode = function($index) {
    $scope.currentIndex = $index;
    $scope.currentTitle = $scope.renderedNodes[$index].title;
    $scope.currentLinks = $scope.renderedNodes[$index].resourceURL;
    $scope.currentResourceURL = $scope.currentLinks[0];
    $scope.currentDescription = $scope.renderedNodes[$index].description;
    $scope.currentNode = $scope.renderedNodes[$index];
    $scope.currentImageUrl = $scope.renderedNodes[$index].imageUrl;
  };

  $scope.submitCompletedNode = function() {
    var nodeId = $scope.currentNode._id;
    User.completeNodeById(nodeId);
    Materialize.toast('Node Complete!', 4000, 'orangeToast');
  }

  $scope.submitCompletedRoadmap = function() {
    Materialize.toast('Map Complete!', 4000, 'orangeToast');
    User.completeRoadmapById(roadmapId);
    $state.go('home.dashboard', {type: 'completed'});
  }

  $scope.upVoteMap = function () {
    User.upvoteMapById(roadmapId)
    .then(function(data){
      $scope.upVoteCount = RoadmapsFactory.getCountVotes();
      $scope.downVoteCount = RoadmapsFactory.getCountVotes(data.downvotes);
    })
  }

  $scope.downVoteMap = function () {
    User.downvoteMapById(roadmapId)
    .then(function(data){
      $scope.upVoteCount = RoadmapsFactory.getCountVotes(data.upvotes);
      $scope.downVoteCount = RoadmapsFactory.getCountVotes(data.downvotes);
    });
  };

  $scope.subject = '';
  $scope.content = '';

  $scope.postComment = function(){
    // Will probably need to refactor
    $scope.currentRoadMapData.comments = $scope.currentRoadMapData.comments || [];

    Server.createComment({
      subject: $scope.subject,
      content: $scope.content,
      roadmap: $scope.currentRoadMapData._id
    });
  };

  // utility functions
  function resetCreationForm () {
    $scope.urlToScrape = "Paste a link here to get info automatically";
    $scope.currentCreationTitle = RoadmapsFactory.NODE_DEFAULTS.title;
    $scope.currentCreationDescription = RoadmapsFactory.NODE_DEFAULTS.description;
    $scope.currentCreationType = RoadmapsFactory.NODE_DEFAULTS.resourceType;
    $scope.currentCreationLink = RoadmapsFactory.NODE_DEFAULTS.resourceURL;
    $scope.currentCreationImage = 'New node image (optional)';
  }

}]);
<|endoftext|>


<commit_before>"use strict";

import _                                 from "lodash";
import Immutable                         from "immutable";
import { Constants as MessageConstants } from "../actions/message";
import ErrorTypes                        from "../constants/error";
import messages                          from "./messages";

describe("message reducer", () => {

  describe("initial state", () => {

    it("has no messages", () => {
      const state = messages(undefined, {});
      expect(state.toJS()).toEqual([]);
    });

  });

  describe("TIMEOUT", () => {

    it("adds a timeout message", () => {
      const initialState = Immutable.fromJS([]);
      const state = messages(initialState, {
        type: ErrorTypes.TIMEOUT,
        payload: {
          message: "No response"
        }
      });
      expect(_.contains(state.get(0),"Request timed out")).toBe(true);
    });

  });

  describe("NOT_AUTHORIZED", () => {

    it("Adds a not authorized error", () => {
      const initialState = Immutable.fromJS([]);
      const state = messages(initialState, {
        type: ErrorTypes.NOT_AUTHORIZED,
        payload: {
          message: "Not authorized"
        }
      });
      expect(_.contains(state.get(0),"Request not authorized")).toBe(true);
    });

  });

  describe("ERROR", () => {

    it("Adds an error", () => {
      const initialState = Immutable.fromJS([]);
      const state = messages(initialState, {
        type: ErrorTypes.ERROR,
        payload: {
          message: "Error"
        }
      });
      expect(_.contains(state.get(0),"Request error")).toBe(true);
    });

  });

  describe("ADD_MESSAGE", () => {

    it("Adds a message", () => {
      const initialState = Immutable.fromJS([]);
      const action = {
        type: MessageConstants.ADD_MESSAGE,
        payload: {
          message: "Things are great"
        }
      }
      const state = messages(initialState, action);
      expect(_.contains(state.get(0),action.payload.message)).toBe(true);
    });

  });

  describe("REMOVE_MESSAGE", () => {

    it("Removes message", () => {
      const action = {
        type: MessageConstants.ADD_MESSAGE,
        payload: {
          message: "Things are great"
        }
      };
      const removeAction = {
        type: MessageConstants.REMOVE_MESSAGE,
        payload: {
          message: "Things are great"
        }
      };
      const initialState = Immutable.fromJS([action.payload.message]);
      const state = messages(initialState, action);
      expect(_.contains(state.get(0),action.payload.message)).toBe(true);
      const newState = messages(state, removeAction);
      expect(newState.toJS()).toEqual([]);
    });

  });

  describe("CLEAR_MESSAGES", () => {

    it("Removes message", () => {
      const action = {
        type: MessageConstants.ADD_MESSAGE,
        payload: {
          message: "Things are great"
        }
      };
      const removeAction = {
        type: MessageConstants.CLEAR_MESSAGES
      };
      const initialState = Immutable.fromJS([action.payload.message]);
      const state = messages(initialState, action);
      expect(_.contains(state.get(0),action.payload.message)).toBe(true);
      const newState = messages(state, removeAction);
      expect(newState.toJS()).toEqual([]);
    });

  });

});<commit_msg>Update for lodash 4<commit_after>"use strict";

import _                                 from "lodash";
import Immutable                         from "immutable";
import { Constants as MessageConstants } from "../actions/message";
import ErrorTypes                        from "../constants/error";
import messages                          from "./messages";

describe("message reducer", () => {

  describe("initial state", () => {

    it("has no messages", () => {
      const state = messages(undefined, {});
      expect(state.toJS()).toEqual([]);
    });

  });

  describe("TIMEOUT", () => {

    it("adds a timeout message", () => {
      const initialState = Immutable.fromJS([]);
      const state = messages(initialState, {
        type: ErrorTypes.TIMEOUT,
        payload: {
          message: "No response"
        }
      });
      expect(_.includes(state.get(0),"Request timed out")).toBe(true);
    });

  });

  describe("NOT_AUTHORIZED", () => {

    it("Adds a not authorized error", () => {
      const initialState = Immutable.fromJS([]);
      const state = messages(initialState, {
        type: ErrorTypes.NOT_AUTHORIZED,
        payload: {
          message: "Not authorized"
        }
      });
      expect(_.includes(state.get(0),"Request not authorized")).toBe(true);
    });

  });

  describe("ERROR", () => {

    it("Adds an error", () => {
      const initialState = Immutable.fromJS([]);
      const state = messages(initialState, {
        type: ErrorTypes.ERROR,
        payload: {
          message: "Error"
        }
      });
      expect(_.includes(state.get(0),"Request error")).toBe(true);
    });

  });

  describe("ADD_MESSAGE", () => {

    it("Adds a message", () => {
      const initialState = Immutable.fromJS([]);
      const action = {
        type: MessageConstants.ADD_MESSAGE,
        payload: {
          message: "Things are great"
        }
      }
      const state = messages(initialState, action);
      expect(_.includes(state.get(0),action.payload.message)).toBe(true);
    });

  });

  describe("REMOVE_MESSAGE", () => {

    it("Removes message", () => {
      const action = {
        type: MessageConstants.ADD_MESSAGE,
        payload: {
          message: "Things are great"
        }
      };
      const removeAction = {
        type: MessageConstants.REMOVE_MESSAGE,
        payload: {
          message: "Things are great"
        }
      };
      const initialState = Immutable.fromJS([action.payload.message]);
      const state = messages(initialState, action);
      expect(_.includes(state.get(0),action.payload.message)).toBe(true);
      const newState = messages(state, removeAction);
      expect(newState.toJS()).toEqual([]);
    });

  });

  describe("CLEAR_MESSAGES", () => {

    it("Removes message", () => {
      const action = {
        type: MessageConstants.ADD_MESSAGE,
        payload: {
          message: "Things are great"
        }
      };
      const removeAction = {
        type: MessageConstants.CLEAR_MESSAGES
      };
      const initialState = Immutable.fromJS([action.payload.message]);
      const state = messages(initialState, action);
      expect(_.includes(state.get(0),action.payload.message)).toBe(true);
      const newState = messages(state, removeAction);
      expect(newState.toJS()).toEqual([]);
    });

  });

});<|endoftext|>


<commit_before>/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule LinkedValueUtils
 * @typechecks static-only
 */

'use strict';

var ReactPropTypes = require('ReactPropTypes');

var invariant = require('invariant');
var warning = require('warning');

var hasReadOnlyValue = {
  'button': true,
  'checkbox': true,
  'image': true,
  'hidden': true,
  'radio': true,
  'reset': true,
  'submit': true,
};

function _assertSingleLink(inputProps) {
  invariant(
    inputProps.checkedLink == null || inputProps.valueLink == null,
    'Cannot provide a checkedLink and a valueLink. If you want to use ' +
    'checkedLink, you probably don\'t want to use valueLink and vice versa.'
  );
}
function _assertValueLink(inputProps) {
  _assertSingleLink(inputProps);
  invariant(
    inputProps.value == null && inputProps.onChange == null,
    'Cannot provide a valueLink and a value or onChange event. If you want ' +
    'to use value or onChange, you probably don\'t want to use valueLink.'
  );
}

function _assertCheckedLink(inputProps) {
  _assertSingleLink(inputProps);
  invariant(
    inputProps.checked == null && inputProps.onChange == null,
    'Cannot provide a checkedLink and a checked property or onChange event. ' +
    'If you want to use checked or onChange, you probably don\'t want to ' +
    'use checkedLink'
  );
}

var propTypes = {
  value: function(props, propName, componentName) {
    if (!props[propName] ||
        hasReadOnlyValue[props.type] ||
        props.onChange ||
        props.readOnly ||
        props.disabled) {
      return null;
    }
    return new Error(
      'You provided a `value` prop to a form field without an ' +
      '`onChange` handler. This will render a read-only field. If ' +
      'the field should be mutable use `defaultValue`. Otherwise, ' +
      'set either `onChange` or `readOnly`.'
    );
  },
  checked: function(props, propName, componentName) {
    if (!props[propName] ||
        props.onChange ||
        props.readOnly ||
        props.disabled) {
      return null;
    }
    return new Error(
      'You provided a `checked` prop to a form field without an ' +
      '`onChange` handler. This will render a read-only field. If ' +
      'the field should be mutable use `defaultChecked`. Otherwise, ' +
      'set either `onChange` or `readOnly`.'
    );
  },
  onChange: ReactPropTypes.func,
};

var loggedTypeFailures = {};
function getDeclarationErrorAddendum(owner) {
  if (owner) {
    var name = owner.getName();
    if (name) {
      return ' Check the render method of `' + name + '`.';
    }
  }
  return '';
}

/**
 * Provide a linked `value` attribute for controlled forms. You should not use
 * this outside of the ReactDOM controlled form components.
 */
var LinkedValueUtils = {
  checkPropTypes: function (tagName, props, owner) {
    for (var propName in propTypes) {
      if (propTypes.hasOwnProperty(propName)) {
        var error = propTypes[propName](props, propName, tagName, location);
      }
      if (error instanceof Error && !(error.message in loggedTypeFailures)) {
        // Only monitor this failure once because there tends to be a lot of the
        // same error.
        loggedTypeFailures[error.message] = true;

        var addendum = getDeclarationErrorAddendum(owner);
        warning(false, 'Failed form propType: %s%s', error.message, addendum);
      }
    }
  },

  /**
   * @param {object} inputProps Props for form component
   * @return {*} current value of the input either from value prop or link.
   */
  getValue: function(inputProps) {
    if (inputProps.valueLink) {
      _assertValueLink(inputProps);
      return inputProps.valueLink.value;
    }
    return inputProps.value;
  },

  /**
   * @param {object} inputProps Props for form component
   * @return {*} current checked status of the input either from checked prop
   *             or link.
   */
  getChecked: function(inputProps) {
    if (inputProps.checkedLink) {
      _assertCheckedLink(inputProps);
      return inputProps.checkedLink.value;
    }
    return inputProps.checked;
  },

  /**
   * @param {object} inputProps Props for form component
   * @param {SyntheticEvent} event change event to handle
   */
  executeOnChange: function(inputProps, event) {
    if (inputProps.valueLink) {
      _assertValueLink(inputProps);
      return inputProps.valueLink.requestChange(event.target.value);
    } else if (inputProps.checkedLink) {
      _assertCheckedLink(inputProps);
      return inputProps.checkedLink.requestChange(event.target.checked);
    } else if (inputProps.onChange) {
      return inputProps.onChange.call(undefined, event);
    }
  },
};

module.exports = LinkedValueUtils;
<commit_msg>Use correct location when running LinkedValueUtils proptype checks<commit_after>/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule LinkedValueUtils
 * @typechecks static-only
 */

'use strict';

var ReactPropTypes = require('ReactPropTypes');
var ReactPropTypeLocations = require('ReactPropTypeLocations');

var invariant = require('invariant');
var warning = require('warning');

var hasReadOnlyValue = {
  'button': true,
  'checkbox': true,
  'image': true,
  'hidden': true,
  'radio': true,
  'reset': true,
  'submit': true,
};

function _assertSingleLink(inputProps) {
  invariant(
    inputProps.checkedLink == null || inputProps.valueLink == null,
    'Cannot provide a checkedLink and a valueLink. If you want to use ' +
    'checkedLink, you probably don\'t want to use valueLink and vice versa.'
  );
}
function _assertValueLink(inputProps) {
  _assertSingleLink(inputProps);
  invariant(
    inputProps.value == null && inputProps.onChange == null,
    'Cannot provide a valueLink and a value or onChange event. If you want ' +
    'to use value or onChange, you probably don\'t want to use valueLink.'
  );
}

function _assertCheckedLink(inputProps) {
  _assertSingleLink(inputProps);
  invariant(
    inputProps.checked == null && inputProps.onChange == null,
    'Cannot provide a checkedLink and a checked property or onChange event. ' +
    'If you want to use checked or onChange, you probably don\'t want to ' +
    'use checkedLink'
  );
}

var propTypes = {
  value: function(props, propName, componentName) {
    if (!props[propName] ||
        hasReadOnlyValue[props.type] ||
        props.onChange ||
        props.readOnly ||
        props.disabled) {
      return null;
    }
    return new Error(
      'You provided a `value` prop to a form field without an ' +
      '`onChange` handler. This will render a read-only field. If ' +
      'the field should be mutable use `defaultValue`. Otherwise, ' +
      'set either `onChange` or `readOnly`.'
    );
  },
  checked: function(props, propName, componentName) {
    if (!props[propName] ||
        props.onChange ||
        props.readOnly ||
        props.disabled) {
      return null;
    }
    return new Error(
      'You provided a `checked` prop to a form field without an ' +
      '`onChange` handler. This will render a read-only field. If ' +
      'the field should be mutable use `defaultChecked`. Otherwise, ' +
      'set either `onChange` or `readOnly`.'
    );
  },
  onChange: ReactPropTypes.func,
};

var loggedTypeFailures = {};
function getDeclarationErrorAddendum(owner) {
  if (owner) {
    var name = owner.getName();
    if (name) {
      return ' Check the render method of `' + name + '`.';
    }
  }
  return '';
}

/**
 * Provide a linked `value` attribute for controlled forms. You should not use
 * this outside of the ReactDOM controlled form components.
 */
var LinkedValueUtils = {
  checkPropTypes: function (tagName, props, owner) {
    for (var propName in propTypes) {
      if (propTypes.hasOwnProperty(propName)) {
        var error = propTypes[propName](
          props,
          propName,
          tagName,
          ReactPropTypeLocations.prop
        );
      }
      if (error instanceof Error && !(error.message in loggedTypeFailures)) {
        // Only monitor this failure once because there tends to be a lot of the
        // same error.
        loggedTypeFailures[error.message] = true;

        var addendum = getDeclarationErrorAddendum(owner);
        warning(false, 'Failed form propType: %s%s', error.message, addendum);
      }
    }
  },

  /**
   * @param {object} inputProps Props for form component
   * @return {*} current value of the input either from value prop or link.
   */
  getValue: function(inputProps) {
    if (inputProps.valueLink) {
      _assertValueLink(inputProps);
      return inputProps.valueLink.value;
    }
    return inputProps.value;
  },

  /**
   * @param {object} inputProps Props for form component
   * @return {*} current checked status of the input either from checked prop
   *             or link.
   */
  getChecked: function(inputProps) {
    if (inputProps.checkedLink) {
      _assertCheckedLink(inputProps);
      return inputProps.checkedLink.value;
    }
    return inputProps.checked;
  },

  /**
   * @param {object} inputProps Props for form component
   * @param {SyntheticEvent} event change event to handle
   */
  executeOnChange: function(inputProps, event) {
    if (inputProps.valueLink) {
      _assertValueLink(inputProps);
      return inputProps.valueLink.requestChange(event.target.value);
    } else if (inputProps.checkedLink) {
      _assertCheckedLink(inputProps);
      return inputProps.checkedLink.requestChange(event.target.checked);
    } else if (inputProps.onChange) {
      return inputProps.onChange.call(undefined, event);
    }
  },
};

module.exports = LinkedValueUtils;
<|endoftext|>


<commit_before>define(["./textTagView", "backbone","jquery","handlebar"], function(TextTagView){

  var textTagsView = Backbone.Collection.extend({

    initialize: function(options) {
      _.extend(this.options);
      this.collection.on('add', this.render, this);//could be updated in future.
    },

    render: function(textTag) {
      //to do: setTimeout parameters
      //to do : add connection lines;
      debugger;
      var self = this;
      this.collection.each(function(textTag){
        var currentView = new TextTagView({
            model: textTag,
            map: self.map
        });
        currentView.on
      });
      var models = this.collectionModel.models;
      var init = function(i, currentView) {
        setTimeout(function() {
          debugger;
          if (currentView) { currentView.destroyView();}
          if (i < models.length -1) {
            init(i+1, currentView);
          }
        },3000);
      };
      init(0);
    }

  });

  return textTagsView;
});<commit_msg>use add to trigger single textTag view<commit_after>define(["./textTagView", "backbone","jquery","handlebar"], function(TextTagView){

  var textTagsView = Backbone.View.extend({

    initialize: function(options) {
      _.extend(this, options);

      this.datum = this.model.get('content');
      this.textTags = this.model.get('textTags');
      this.textTags.on('add', this.renderNext, this);//could be updated in future.
    },

    render: function() {
      console.log(this.model);
      //to do : add connection lines;
      if (this.textTags.length === 0) {
        this.textTags.add([this.datum[0]]);
      }
    },

    renderNext: function(textTagModel) {
      debugger;
      console.log(textTagModel);
    }

    //   var currentMarker = new TextTagView({
    //       model: textTag,
    //       map: self.map
    //   });

    //   var self = this;
    //   this.collection.each(function(textTag){
    //     currentView.on
    //   });
    //   var models = this.collectionModel.models;
    //   var init = function(i, currentView) {
    //     setTimeout(function() {
    //       debugger;
    //       if (currentView) { currentView.destroyView();}
    //       if (i < models.length -1) {
    //         init(i+1, currentView);
    //       }
    //     },3000);
    //   };
    //   init(0);
    // }

  });

  return textTagsView;
});<|endoftext|>


<commit_before>import React from "react";
import { connect } from "react-redux";
import { NavLink } from "react-router-dom";
import styled from "styled-components";
import { logout } from "../../account/actions";
import { DropdownItem, Icon, VTLogo } from "../../base";
import { getSoftwareUpdates } from "../../updates/actions";
import { isHomeActive } from "../utils";
import { NavDropdown } from "./Dropdown";
import Update from "./Update";

const NavBarItem = styled(NavLink)`
    color: white;
    cursor: pointer;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 0 15px;

    &:focus {
        text-decoration: none;
    }

    &:hover {
        opacity: 1;
        text-decoration: none;
        color: #245251;
    }

    &.active {
        color: white;
        opacity: 1;
        background-color: rgb(50, 112, 111);
    }
`;

const NavBar = styled.div`
    z-index: 1000;
    position: fixed;
    top: 0;
    width: 100%;
    height: 45px;

    display: flex;
    justify-content: space-between;

    background-color: teal;
    color: white;
`;

const NavBarLeft = styled.div`
    display: flex;
    align-items: center;
`;

const NavBarRight = styled.div`
    display: flex;
    align-items: center;
    margin-right: 15px;
`;

const BarLogo = styled(VTLogo)`
    margin-left: 35px;
    margin-right: 25px;
    svg {
        margin-left: 3px;
    }
`;

export class Bar extends React.Component {
    componentDidMount() {
        this.props.onGet();
    }

    render() {
        return (
            <NavBar className="vt-header">
                <NavBarLeft>
                    <BarLogo />

                    <NavBarItem to="/home" isActive={isHomeActive}>
                        Home
                    </NavBarItem>

                    <NavBarItem to="/jobs">Jobs</NavBarItem>

                    <NavBarItem to="/samples">Samples</NavBarItem>

                    <NavBarItem to="/refs">References</NavBarItem>

                    <NavBarItem to="/hmm">HMM</NavBarItem>

                    <NavBarItem to="/subtraction">Subtraction</NavBarItem>
                </NavBarLeft>

                <NavBarRight>
                    <Update />

                    <NavBarItem target="_blank" to="//gitter.im/virtool/virtool" rel="noopener noreferrer">
                        <Icon name="comments" />
                    </NavBarItem>

                    <NavBarItem target="_blank" to="//virtool.ca/docs/manual" rel="noopener noreferrer">
                        <Icon name="book" />
                    </NavBarItem>

                    <NavDropdown userId={this.props.id}>
                        <DropdownItem to="/account">Account</DropdownItem>

                        {this.props.administrator && <DropdownItem to="/administration">Administration </DropdownItem>}

                        <DropdownItem
                            to="//gitreports.com/issue/virtool/virtool"
                            target="_blank"
                            rel="noopener noreferrer"
                        >
                            Report Issue
                        </DropdownItem>

                        <DropdownItem onClick={this.props.logout}>Logout</DropdownItem>
                    </NavDropdown>
                </NavBarRight>
            </NavBar>
        );
    }
}

export const mapStateToProps = state => ({
    ...state.account,
    pending: state.app.pending
});

export const mapDispatchToProps = dispatch => ({
    logout: () => {
        dispatch(logout());
    },

    onGet: () => {
        dispatch(getSoftwareUpdates());
    }
});

export default connect(mapStateToProps, mapDispatchToProps)(Bar);
<commit_msg>Fix Navbar background color<commit_after>import React from "react";
import { connect } from "react-redux";
import { NavLink } from "react-router-dom";
import styled from "styled-components";
import { logout } from "../../account/actions";
import { DropdownItem, Icon, VTLogo } from "../../base";
import { getSoftwareUpdates } from "../../updates/actions";
import { isHomeActive } from "../utils";
import { NavDropdown } from "./Dropdown";
import Update from "./Update";

const NavBarItem = styled(NavLink)`
    color: white;
    cursor: pointer;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 0 15px;

    &:focus {
        text-decoration: none;
    }

    &:hover {
        opacity: 1;
        text-decoration: none;
        color: #245251;
    }

    &.active {
        color: white;
        opacity: 1;
        background-color: rgb(50, 112, 111);
    }
`;

const NavBar = styled.div`
    background-color: ${props => props.theme.color.primary};
    color: white;
    display: flex;
    height: 45px;
    justify-content: space-between;
    position: fixed;
    top: 0;
    width: 100%;
    z-index: 1000;
`;

const NavBarLeft = styled.div`
    display: flex;
    align-items: center;
`;

const NavBarRight = styled.div`
    display: flex;
    align-items: center;
    margin-right: 15px;
`;

const BarLogo = styled(VTLogo)`
    margin-left: 35px;
    margin-right: 25px;
    svg {
        margin-left: 3px;
    }
`;

export class Bar extends React.Component {
    componentDidMount() {
        this.props.onGet();
    }

    render() {
        return (
            <NavBar className="vt-header">
                <NavBarLeft>
                    <BarLogo />

                    <NavBarItem to="/home" isActive={isHomeActive}>
                        Home
                    </NavBarItem>

                    <NavBarItem to="/jobs">Jobs</NavBarItem>

                    <NavBarItem to="/samples">Samples</NavBarItem>

                    <NavBarItem to="/refs">References</NavBarItem>

                    <NavBarItem to="/hmm">HMM</NavBarItem>

                    <NavBarItem to="/subtraction">Subtraction</NavBarItem>
                </NavBarLeft>

                <NavBarRight>
                    <Update />

                    <NavBarItem target="_blank" to="//gitter.im/virtool/virtool" rel="noopener noreferrer">
                        <Icon name="comments" />
                    </NavBarItem>

                    <NavBarItem target="_blank" to="//virtool.ca/docs/manual" rel="noopener noreferrer">
                        <Icon name="book" />
                    </NavBarItem>

                    <NavDropdown userId={this.props.id}>
                        <DropdownItem to="/account">Account</DropdownItem>

                        {this.props.administrator && <DropdownItem to="/administration">Administration </DropdownItem>}

                        <DropdownItem
                            to="//gitreports.com/issue/virtool/virtool"
                            target="_blank"
                            rel="noopener noreferrer"
                        >
                            Report Issue
                        </DropdownItem>

                        <DropdownItem onClick={this.props.logout}>Logout</DropdownItem>
                    </NavDropdown>
                </NavBarRight>
            </NavBar>
        );
    }
}

export const mapStateToProps = state => ({
    ...state.account,
    pending: state.app.pending
});

export const mapDispatchToProps = dispatch => ({
    logout: () => {
        dispatch(logout());
    },

    onGet: () => {
        dispatch(getSoftwareUpdates());
    }
});

export default connect(mapStateToProps, mapDispatchToProps)(Bar);
<|endoftext|>


<commit_before>var gulp       = require('gulp');
var gutil      = require('gulp-util');

var cssConcat  = require('gulp-concat-css');
var jshint     = require('gulp-jshint');
var stylish    = require('jshint-stylish');
var beautify   = require('gulp-js-prettify');

var browserify = require('browserify');
var source = require('vinyl-source-stream');
var AtomShellDownload = require('atom-shell-pull');

var connect = require('connect');
var http    = require('http');
var path    = require('path');
var fs      = require('fs');

var JS_FILES = ['app/js/**/*.js'];
var packageJson = require(path.join(__dirname, 'package.json'));

gulp.task('lint', ['code-clean'], function() {
    gulp.src(JS_FILES)
        // Note: the following options need to be enabled sometime later:
        // ~> es3 : true
        // ~> quotmark : 'single'
        // ~> unused : true

        // Note JSHint finds configuration options in the .jshintrc
        .pipe(jshint())
        .pipe(jshint.reporter(stylish))
        .pipe(jshint.reporter('fail'));
});

gulp.task('code-build', ['code-clean'], function() {
    process.env.NODE_PATH = path.join(__dirname, 'app')

    browserify('./app/js/main.js')
        .bundle({
            insertGlobals : true,
            ignoreMissing : true // For things like 'remote' which are atom-shell only.
        })
        .pipe(source('application.js'))
        .pipe(gulp.dest('./public/dist'));

    gulp.src('app/css/styles.css')
        .pipe(cssConcat(''))
        .pipe(gulp.dest('public/dist/styles.css'))

    // TODO: now we bundle all the Handlebars templates into one file.

});

gulp.task('code-clean', function () {
    gulp.src(JS_FILES)
        .pipe(beautify({
            preserve_newlines : false,
            jslint_happy : true,
            break_chained_methods : true,
            good_stuff : true
        }))
        .pipe(gulp.dest('app/js'));
});

gulp.task('download-shell', function () {
    var download = new AtomShellDownload({
        outputDir : 'build',
        platforms : ['linux', 'win32'],
        bits : [32, 64]
    });

    download.prepare(function (start) {
        start();
    });
});

// This should be used in conjunction with the browser-build. To run the desktop
// version, do `./run.sh`.
gulp.task('server', ['web-build'], function() {
    var port = process.env.PORT || 5000;
    var app = connect()
        .use(connect.logger('dev'))
        .use(connect['static'](path.join(__dirname, 'public')));
    http.createServer(app).listen(port);
    gutil.log('Server started on port ' + port);
});
<commit_msg>Avoid race conditions by not running clean before lint and build.<commit_after>var gulp       = require('gulp');
var gutil      = require('gulp-util');

var cssConcat  = require('gulp-concat-css');
var jshint     = require('gulp-jshint');
var stylish    = require('jshint-stylish');
var beautify   = require('gulp-js-prettify');

var browserify = require('browserify');
var source = require('vinyl-source-stream');
var AtomShellDownload = require('atom-shell-pull');

var connect = require('connect');
var http    = require('http');
var path    = require('path');
var fs      = require('fs');

var JS_FILES = ['app/js/**/*.js'];
var packageJson = require(path.join(__dirname, 'package.json'));

gulp.task('lint', function() {
    gulp.src(JS_FILES)
        // Note: the following options need to be enabled sometime later:
        // ~> es3 : true
        // ~> quotmark : 'single'
        // ~> unused : true

        // Note JSHint finds configuration options in the .jshintrc
        .pipe(jshint())
        .pipe(jshint.reporter(stylish))
        .pipe(jshint.reporter('fail'));
});

gulp.task('code-build', function() {
    process.env.NODE_PATH = path.join(__dirname, 'app')

    browserify('./app/js/main.js')
        .bundle({
            insertGlobals : true,
            ignoreMissing : true // For things like 'remote' which are atom-shell only.
        })
        .pipe(source('application.js'))
        .pipe(gulp.dest('./public/dist'));

    gulp.src('app/css/styles.css')
        .pipe(cssConcat(''))
        .pipe(gulp.dest('public/dist/styles.css'))

    // TODO: now we bundle all the Handlebars templates into one file.

});

gulp.task('code-clean', function () {
    gulp.src(JS_FILES)
        .pipe(beautify({
            preserve_newlines : false,
            jslint_happy : true,
            break_chained_methods : true,
            good_stuff : true
        }))
        .pipe(gulp.dest('app/js'));
});

gulp.task('download-shell', function () {
    var download = new AtomShellDownload({
        outputDir : 'build',
        platforms : ['linux', 'win32'],
        bits : [32, 64]
    });

    download.prepare(function (start) {
        start();
    });
});

// This should be used in conjunction with the browser-build. To run the desktop
// version, do `./run.sh`.
gulp.task('server', ['web-build'], function() {
    var port = process.env.PORT || 5000;
    var app = connect()
        .use(connect.logger('dev'))
        .use(connect['static'](path.join(__dirname, 'public')));
    http.createServer(app).listen(port);
    gutil.log('Server started on port ' + port);
});
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp'),
    sass = require('gulp-sass'),
    rename = require('gulp-rename'),
    cssnano = require('gulp-cssnano'),
    kss = require('kss'),
    sassLint = require('gulp-sass-lint'),
    autoprefixer = require('gulp-autoprefixer'),
    gitVersion = require('gulp-gitversion'),
    scssMerge = require('./lib/gulp-scss-merge.js'),
    uglify = require('gulp-uglify'),
    del = require('del'),
    runSequence = require('run-sequence'),
    connect = require('gulp-connect'),
    svg2png = require('gulp-svg2png'),
    webpack = require('webpack-stream'),
    zip = require('gulp-zip'),
    imagemin = require('gulp-imagemin')
    ;

var paths = {
    assets: './assets/**/*.*',
    assetsDir: './assets',
    scssDir: './assets/sass/**/*.scss',
    scssTemplatesDir: './assets/sass/components/templates',
    kssScssDir: './kss-builder/kss-assets/*.scss',
    kssCssDir: './kss-builder/kss-assets',
    examples: './examples/*.html',
    examplePartialsDir: './examples/partials',
    kssBuilderDir: './kss-builder/**/*.*',
    images: './assets/img/**/*.+(png|svg|jpg)',
    scss: './assets/sass/ui-kit.scss',
    js: './assets/js/ui-kit.js',
    markdown: './*.md',
    readme: './README.md',
    outputAssets: './build/latest',
    outputCSS: './build/latest/*.css',
    outputHTML: './build'
};

var options = {
    autoprefixer: {
        browsers: ['last 2 versions', 'ie 7-10', 'iOS >= 4']
    },
    sass: {
        functions: {
            'image-url($img)': function(img) {
              var sass = require('node-sass');
              var String = sass.types.String;
              return new String('/latest/img/' + img.getValue());
            }
        },
        includePaths: [
          './node_modules'
        ]
    },
    webpack: {
        output: {
            filename: 'ui-kit.js',
        }
    },
    handlebars: {
      batch: [ paths.scssTemplatesDir, paths.examplePartialsDir ]
    }
};

gulp.task('lint', function () {
    return gulp.src([paths.scssDir, paths.kssScssDir, '!./assets/sass/vendor/**/*.scss'])
        .pipe(sassLint({
            configFile: '.sass-lint.yml'
        }))
        .pipe(sassLint.format())
        .pipe(sassLint.failOnError());
});

gulp.task('ui-kit', function () {
    gulp.start(['ui-kit.scss', 'ui-kit.js']);
});

gulp.task('ui-kit.scss', function () {
  return gulp.src(paths.scssDir)
    .pipe(sass.sync().on('error', sass.logError))
    .pipe(autoprefixer(options.autoprefixer))
    .pipe(gitVersion())
    .pipe(gulp.dest(paths.outputAssets));
});

gulp.task('ui-kit.js', function () {
    return gulp.src(paths.js)
        .pipe(webpack(options.webpack))
        .pipe(gitVersion())
        .pipe(gulp.dest(paths.outputAssets));
});

gulp.task('ui-kit.scssmerge', function () {
    return gulp.src(paths.scss)
        .pipe(scssMerge('_ui-kit.scss'))
        .pipe(gulp.dest(paths.outputAssets));
});

gulp.task('ui-kit.min', function () {
    gulp.start(['ui-kit.min.scss', 'ui-kit.min.js']);
});

gulp.task('ui-kit.min.scss', ['ui-kit.scss'], function () {
    return gulp.src([paths.outputCSS, '!./**/*.min.css'])
        .pipe(cssnano())
        .pipe(gitVersion())
        .pipe(rename({
            suffix: '.min'
        }))
        .pipe(gulp.dest(paths.outputAssets));
});

gulp.task('ui-kit.min.js', function () {
    return gulp.src(paths.js)
        .pipe(webpack({
            output: {
                filename: 'ui-kit.min.js',
            }
        }))
        .pipe(uglify())
        .pipe(gitVersion())
        .pipe(gulp.dest(paths.outputAssets));
});

gulp.task('ui-kit.img', ['svg2png'], function () {
    return gulp.src(paths.images)
        .pipe(imagemin())
        .pipe(gulp.dest(paths.outputAssets + '/img/'));
});

gulp.task('ui-kit.img.zip', ['ui-kit.img'], function () {
    return gulp.src(paths.outputAssets + '/img/**/*')
        .pipe(zip('images.zip'))
        .pipe(gulp.dest(paths.outputAssets));
});

gulp.task('svg2png', function () {
    return gulp.src(paths.assetsDir + '/img/icons/*.svg')
        .pipe(svg2png())
        .pipe(gulp.dest(paths.outputAssets + '/img/icons/'));
});

gulp.task('examples', function () {

    return gulp.src(paths.examples)
      .pipe(handlebars({}, options.handlebars))
      .pipe(rename({
        extname: '.html'
      }))
      .pipe(gulp.dest(paths.outputHTML + '/examples')).pipe(connect.reload());
});

gulp.task('markdown', function () {
    return gulp.src(paths.markdown)
        .pipe(gulp.dest(paths.outputHTML));
});

gulp.task('nginx', function () {
    return gulp.src('nginx.conf')
        .pipe(gulp.dest(paths.outputHTML));
});

gulp.task('htmlvalidate', ['examples', 'styleguide'], function (cb) {
    try {
        var validator = require('gulp-html');
        return gulp.src(['build/*.html', 'build/**/*.html'])
            .pipe(validator({'verbose': true}));
    } catch (err) {
        if (err.code === 'MODULE_NOT_FOUND') {
            console.log('WARNING: optional HTML validator not installed, to resolve run:');
            console.log('> npm install AusDTO/gulp-html');
            return cb;
        }
        else {
            throw err;
        }
    }
});

gulp.task('styleguide', ['styleguide.scss'], function () {
    var kssresult = kss({
        source: 'assets/sass',
        destination: paths.outputHTML,
        homepage: '../../README.md',
        builder: 'kss-builder'
    });
    kssresult.then(function () {
        gulp.src('./build/*.html').pipe(connect.reload());
    });

});

gulp.task('styleguide.data', function () {
  var fs = require('fs');
  var source = 'assets/sass';
  var outputFile = 'data-sections.json';
  var customFields = ['tags'];
  var data;

  kss.traverse(source, {'custom': customFields}).then(function(styleData) {
    data = JSON.stringify(styleData.data.sections);
    fs.writeFile(outputFile, data, (err) => {
      if (err) throw err;
      console.log(outputFile, 'saved successfully')
    });
  });
});

gulp.task('styleguide.scss', function () {
    return gulp.src(paths.kssScssDir)
        .pipe(sass(options.sass).on('error', sass.logError))
        .pipe(autoprefixer(options.autoprefixer))
        .pipe(gitVersion())
        .pipe(gulp.dest(paths.kssCssDir));
});

gulp.task('clean', function (done) {
    return del([paths.outputAssets, paths.outputHTML], done);
});

gulp.task('default', ['build']);

gulp.task('build', ['lint', 'ui-kit', 'markdown', 'examples', 'styleguide']);

gulp.task('build.prod', function (callback) {
    runSequence('clean',
        ['lint', 'nginx', 'ui-kit', 'ui-kit.min', 'ui-kit.img.zip', 'ui-kit.scssmerge', 'markdown', 'htmlvalidate'],
        callback);
});

gulp.task('watch', ['watch.build']);

gulp.task('watch.build', function () {
    gulp.watch([
            paths.assets,
            paths.examples,
            paths.readme,
            paths.kssBuilderDir,
            '!./kss-builder/kss-assets/kss.css'
        ],
        {verbose: true},
        ['build']);
});

gulp.task('serve', ['webserver', 'build', 'watch.build', 'livereload']);

gulp.task('livereload', function () {
    gulp.watch(['./build/latest/'], () => {
        gulp.src('./build/latest/**/*').pipe(connect.reload());
    });
});

gulp.task('webserver', function () {
    connect.server({
        livereload: true,
        root: 'build'
    });
});
<commit_msg>Modifies gulp styleguide.data JSON export task to strucuture child sections in the JSON output.<commit_after>'use strict';

var gulp = require('gulp'),
    sass = require('gulp-sass'),
    rename = require('gulp-rename'),
    cssnano = require('gulp-cssnano'),
    kss = require('kss'),
    sassLint = require('gulp-sass-lint'),
    autoprefixer = require('gulp-autoprefixer'),
    gitVersion = require('gulp-gitversion'),
    scssMerge = require('./lib/gulp-scss-merge.js'),
    uglify = require('gulp-uglify'),
    del = require('del'),
    runSequence = require('run-sequence'),
    connect = require('gulp-connect'),
    svg2png = require('gulp-svg2png'),
    webpack = require('webpack-stream'),
    zip = require('gulp-zip'),
    imagemin = require('gulp-imagemin')
    ;

var paths = {
    assets: './assets/**/*.*',
    assetsDir: './assets',
    scssDir: './assets/sass/**/*.scss',
    scssTemplatesDir: './assets/sass/components/templates',
    kssScssDir: './kss-builder/kss-assets/*.scss',
    kssCssDir: './kss-builder/kss-assets',
    examples: './examples/*.html',
    examplePartialsDir: './examples/partials',
    kssBuilderDir: './kss-builder/**/*.*',
    images: './assets/img/**/*.+(png|svg|jpg)',
    scss: './assets/sass/ui-kit.scss',
    js: './assets/js/ui-kit.js',
    markdown: './*.md',
    readme: './README.md',
    outputAssets: './build/latest',
    outputCSS: './build/latest/*.css',
    outputHTML: './build'
};

var options = {
    autoprefixer: {
        browsers: ['last 2 versions', 'ie 7-10', 'iOS >= 4']
    },
    sass: {
        functions: {
            'image-url($img)': function(img) {
              var sass = require('node-sass');
              var String = sass.types.String;
              return new String('/latest/img/' + img.getValue());
            }
        },
        includePaths: [
          './node_modules'
        ]
    },
    webpack: {
        output: {
            filename: 'ui-kit.js',
        }
    },
    handlebars: {
      batch: [ paths.scssTemplatesDir, paths.examplePartialsDir ]
    }
};

gulp.task('lint', function () {
    return gulp.src([paths.scssDir, paths.kssScssDir, '!./assets/sass/vendor/**/*.scss'])
        .pipe(sassLint({
            configFile: '.sass-lint.yml'
        }))
        .pipe(sassLint.format())
        .pipe(sassLint.failOnError());
});

gulp.task('ui-kit', function () {
    gulp.start(['ui-kit.scss', 'ui-kit.js']);
});

gulp.task('ui-kit.scss', function () {
  return gulp.src(paths.scssDir)
    .pipe(sass.sync().on('error', sass.logError))
    .pipe(autoprefixer(options.autoprefixer))
    .pipe(gitVersion())
    .pipe(gulp.dest(paths.outputAssets));
});

gulp.task('ui-kit.js', function () {
    return gulp.src(paths.js)
        .pipe(webpack(options.webpack))
        .pipe(gitVersion())
        .pipe(gulp.dest(paths.outputAssets));
});

gulp.task('ui-kit.scssmerge', function () {
    return gulp.src(paths.scss)
        .pipe(scssMerge('_ui-kit.scss'))
        .pipe(gulp.dest(paths.outputAssets));
});

gulp.task('ui-kit.min', function () {
    gulp.start(['ui-kit.min.scss', 'ui-kit.min.js']);
});

gulp.task('ui-kit.min.scss', ['ui-kit.scss'], function () {
    return gulp.src([paths.outputCSS, '!./**/*.min.css'])
        .pipe(cssnano())
        .pipe(gitVersion())
        .pipe(rename({
            suffix: '.min'
        }))
        .pipe(gulp.dest(paths.outputAssets));
});

gulp.task('ui-kit.min.js', function () {
    return gulp.src(paths.js)
        .pipe(webpack({
            output: {
                filename: 'ui-kit.min.js',
            }
        }))
        .pipe(uglify())
        .pipe(gitVersion())
        .pipe(gulp.dest(paths.outputAssets));
});

gulp.task('ui-kit.img', ['svg2png'], function () {
    return gulp.src(paths.images)
        .pipe(imagemin())
        .pipe(gulp.dest(paths.outputAssets + '/img/'));
});

gulp.task('ui-kit.img.zip', ['ui-kit.img'], function () {
    return gulp.src(paths.outputAssets + '/img/**/*')
        .pipe(zip('images.zip'))
        .pipe(gulp.dest(paths.outputAssets));
});

gulp.task('svg2png', function () {
    return gulp.src(paths.assetsDir + '/img/icons/*.svg')
        .pipe(svg2png())
        .pipe(gulp.dest(paths.outputAssets + '/img/icons/'));
});

gulp.task('examples', function () {

    return gulp.src(paths.examples)
      .pipe(handlebars({}, options.handlebars))
      .pipe(rename({
        extname: '.html'
      }))
      .pipe(gulp.dest(paths.outputHTML + '/examples')).pipe(connect.reload());
});

gulp.task('markdown', function () {
    return gulp.src(paths.markdown)
        .pipe(gulp.dest(paths.outputHTML));
});

gulp.task('nginx', function () {
    return gulp.src('nginx.conf')
        .pipe(gulp.dest(paths.outputHTML));
});

gulp.task('htmlvalidate', ['examples', 'styleguide'], function (cb) {
    try {
        var validator = require('gulp-html');
        return gulp.src(['build/*.html', 'build/**/*.html'])
            .pipe(validator({'verbose': true}));
    } catch (err) {
        if (err.code === 'MODULE_NOT_FOUND') {
            console.log('WARNING: optional HTML validator not installed, to resolve run:');
            console.log('> npm install AusDTO/gulp-html');
            return cb;
        }
        else {
            throw err;
        }
    }
});

gulp.task('styleguide', ['styleguide.scss'], function () {
    var kssresult = kss({
        source: 'assets/sass',
        destination: paths.outputHTML,
        homepage: '../../README.md',
        builder: 'kss-builder'
    });
    kssresult.then(function () {
        gulp.src('./build/*.html').pipe(connect.reload());
    });

});

gulp.task('styleguide.data', function () {
  var fs = require('fs');
  var source = 'assets/sass';
  var outputFile = 'data-sections.json';
  var customFields = ['tags'];
  var data;

  kss.traverse(source, {'custom': customFields}).then(function(styleData) {
    data = JSON.parse(JSON.stringify(styleData.data.sections));

    var output = [];
    for (var i = 0; i < data.length; i++ ) {
      var section = data[i];

      if (section.depth === 1) {
        console.log("section " + section.header + " ref " + section.referenceNumber);
        for (var j =i+1 ; j < data.length; j++ ) {
          //console.log("ref " + data[j].referenceNumber);
          if (data[j].referenceNumber.startsWith(section.referenceNumber + ".")) {
            console.log("child section " + data[j].header);
            if (section.children) {
              section.children.push(data[j]);
            }
            else {
              section.children = [data[j]];
            }
          }
        }
        output.push(section);
      }
    }

    fs.writeFile(outputFile, JSON.stringify(output), (err) => {
      if (err) throw err;
      console.log(outputFile, 'saved successfully')
    });
  });
});

gulp.task('styleguide.scss', function () {
    return gulp.src(paths.kssScssDir)
        .pipe(sass(options.sass).on('error', sass.logError))
        .pipe(autoprefixer(options.autoprefixer))
        .pipe(gitVersion())
        .pipe(gulp.dest(paths.kssCssDir));
});

gulp.task('clean', function (done) {
    return del([paths.outputAssets, paths.outputHTML], done);
});

gulp.task('default', ['build']);

gulp.task('build', ['lint', 'ui-kit', 'markdown', 'examples', 'styleguide']);

gulp.task('build.prod', function (callback) {
    runSequence('clean',
        ['lint', 'nginx', 'ui-kit', 'ui-kit.min', 'ui-kit.img.zip', 'ui-kit.scssmerge', 'markdown', 'htmlvalidate'],
        callback);
});

gulp.task('watch', ['watch.build']);

gulp.task('watch.build', function () {
    gulp.watch([
            paths.assets,
            paths.examples,
            paths.readme,
            paths.kssBuilderDir,
            '!./kss-builder/kss-assets/kss.css'
        ],
        {verbose: true},
        ['build']);
});

gulp.task('serve', ['webserver', 'build', 'watch.build', 'livereload']);

gulp.task('livereload', function () {
    gulp.watch(['./build/latest/'], () => {
        gulp.src('./build/latest/**/*').pipe(connect.reload());
    });
});

gulp.task('webserver', function () {
    connect.server({
        livereload: true,
        root: 'build'
    });
});
<|endoftext|>


<commit_before>var gulp = require('gulp');

var javascripts = [
  'Gulpfile.js',
  'index.js',
  'lib/**/*.js',
  'test/**/*.js'
];

gulp.task('jscs', function () {
  var jscs = require('gulp-jscs');
  return gulp.src(javascripts)
    .pipe(jscs({
      preset: 'yandex',
      disallowMultipleVarDecl: 'exceptUndefined'
    }));
});

gulp.task('lint', function () {
  var jshint = require('gulp-jshint');
  return gulp.src(javascripts)
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(jshint.reporter('fail'));
});

gulp.task('test', function () {
  var mocha = require('gulp-mocha');
  return gulp.src('test/**/*.js', {
    read: false
  })
    .pipe(mocha({
      bail: true
    }));
});

gulp.task('watch', function () {
  return gulp.watch(javascripts, ['default']);
});

gulp.task('default', ['test']);
<commit_msg>Add JSCS and JSHint to default task<commit_after>var gulp = require('gulp');

var javascripts = [
  'Gulpfile.js',
  'index.js',
  'lib/**/*.js',
  'test/**/*.js'
];

gulp.task('jscs', function () {
  var jscs = require('gulp-jscs');
  return gulp.src(javascripts)
    .pipe(jscs({
      preset: 'yandex',
      disallowMultipleVarDecl: 'exceptUndefined'
    }));
});

gulp.task('lint', function () {
  var jshint = require('gulp-jshint');
  return gulp.src(javascripts)
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(jshint.reporter('fail'));
});

gulp.task('test', function () {
  var mocha = require('gulp-mocha');
  return gulp.src('test/**/*.js', {
    read: false
  })
    .pipe(mocha({
      bail: true
    }));
});

gulp.task('watch', function () {
  return gulp.watch(javascripts, ['default']);
});

gulp.task('default', ['lint', 'jscs', 'test']);
<|endoftext|>


<commit_before>var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('styles', function() {
    gulp.src('sass/**/*.scss')
        .pipe(sass().on('error', sass.logError))
        .pipe(gulp.dest('./css/'))
});

gulp.task('watch',function() {
    gulp.watch('sass/**/*.scss',['styles']);
});<commit_msg>Reviews gulpfile<commit_after>var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('dependencies', function() {
    gulp.src('bower_components/font-awesome/scss/font-awesome.scss')
        .pipe(gulp.dest('./scss/libs/_font-awesome.scss'))
//    .pipe(gulp.src('bower_components/normalize-scss/_normalize.scss')
//        .pipe(gulp.dest('./scss/libs/')))
});

gulp.task('styles', function() {
    gulp.src('scss/style.scss')
        .pipe(sass().on('error', sass.logError))
        .pipe(gulp.dest('./css/'))
});

gulp.task('watch',function() {
    gulp.watch('scss/**/*.scss',['styles']);
});<|endoftext|>


<commit_before>var gulp = require('gulp')
var plugins = require('gulp-load-plugins')()
var del = require('del')
var run_sequence = require('run-sequence')
var util = require('util')
var path = require('path')

// TODO svg2png, favicons, etc. Look at Köttet!
// TODO Unit tests!

var postcss_url = require('postcss-url')({
  url: function (url, decl, from, dirname, to, options, result) {
    if (url.slice(0, 1) === '/') {
      return url
    }

    return '../images/' + url
  }
})

var sequence_error = function (callback, error) {
  if (error) {
    plugins.util.log(plugins.util.colors.red('There was an error running the sequence!'))
    process.exit(1)
  }

  callback()
}

var paths = {
  js: [
    'src/js/**/*.js'
  ],

  less: [
    'src/less/**/*.less'
  ],

  images: [
    'src/images/**/*',
  ],
}

gulp.task('pre-build', function (callback) {
  return run_sequence('clean', function (error) {
    sequence_error(callback, error)
  })
})

gulp.task('build', function (callback) {
  return run_sequence(Object.keys(paths), function (error) {
    sequence_error(callback, error)
  })
})

gulp.task('clean', function (callback) {
  del(['public'], callback)
})

var watch

gulp.task('js', function () {
  return gulp.src(paths.js)
        .pipe(!watch ? plugins.util.noop() : plugins.plumber(function (error) {
          plugins.util.log(plugins.util.colors.red('Error (' + error.plugin + '): ' + error.message))

          this.emit('end')
        }))
        .pipe(plugins.jshint())
        .pipe(plugins.jshint.reporter('jshint-stylish'))
        .pipe(watch ? plugins.util.noop() : plugins.jshint.reporter('fail'))
        .pipe(plugins.jscs())
        .pipe(plugins.sourcemaps.init())
        .pipe(plugins.concat('app.js'))
        .pipe(plugins.uglify())
        .pipe(plugins.sourcemaps.write('maps'))
        .pipe(gulp.dest('public/assets/js'))
})

gulp.task('less', function () {
  return gulp.src(paths.less)
        .pipe(!watch ? plugins.util.noop() : plugins.plumber(function (error) {
          plugins.util.log(plugins.util.colors.red('Error (' + error.plugin + '): ' + error.message))

          this.emit('end')
        }))
        .pipe(plugins.sourcemaps.init())
        .pipe(plugins.less())
        .pipe(plugins.autoprefixer({
            browsers: ['last 2 versions']
        }))
        .pipe(plugins.postcss([
          postcss_url
        ]))
        .pipe(plugins.concat('style.css'))
        .pipe(plugins.minifyCss())
        .pipe(plugins.sourcemaps.write('maps'))
        .pipe(gulp.dest('public/assets/css'))
})

gulp.task('images', function () {
  return gulp.src(paths.images)
        .pipe(gulp.dest('public/assets/images'))
})

gulp.task('watch', function () {
  for (var task in paths) {
    gulp.watch(paths[task], [task])
  }
})

gulp.task('serve', function () {
    var server = plugins.liveServer('index.js')
    server.start()
    setTimeout(function () {
      require('open')('http://local.vegosvar.se:8080')
    }, 1000)

    gulp.watch(['views/**/*.ejs', 'views/**/*.html', 'public/**/*'], function () {
      server.notify.apply(server, arguments)
    })

    gulp.watch('*.js', function () {
      server.start()
    })
})

gulp.task('default', function (callback) {
  watch = true
  return run_sequence('pre-build', 'build', ['watch', 'serve'], function (error) {
    sequence_error(callback, error)
  })
})

gulp.task('prod', function (callback) {
  return run_sequence('pre-build', 'build', function (error) {
    sequence_error(callback, error)
  })
})<commit_msg>Do not attempt to open browser if config.headless is set<commit_after>var gulp = require('gulp')
var plugins = require('gulp-load-plugins')()
var del = require('del')
var run_sequence = require('run-sequence')
var util = require('util')
var path = require('path')
var config = require('./config')

// TODO svg2png, favicons, etc. Look at Köttet!
// TODO Unit tests!

var postcss_url = require('postcss-url')({
  url: function (url, decl, from, dirname, to, options, result) {
    if (url.slice(0, 1) === '/') {
      return url
    }

    return '../images/' + url
  }
})

var sequence_error = function (callback, error) {
  if (error) {
    plugins.util.log(plugins.util.colors.red('There was an error running the sequence!'))
    process.exit(1)
  }

  callback()
}

var paths = {
  js: [
    'src/js/**/*.js'
  ],

  less: [
    'src/less/**/*.less'
  ],

  images: [
    'src/images/**/*',
  ],
}

gulp.task('pre-build', function (callback) {
  return run_sequence('clean', function (error) {
    sequence_error(callback, error)
  })
})

gulp.task('build', function (callback) {
  return run_sequence(Object.keys(paths), function (error) {
    sequence_error(callback, error)
  })
})

gulp.task('clean', function (callback) {
  del(['public'], callback)
})

var watch

gulp.task('js', function () {
  return gulp.src(paths.js)
        .pipe(!watch ? plugins.util.noop() : plugins.plumber(function (error) {
          plugins.util.log(plugins.util.colors.red('Error (' + error.plugin + '): ' + error.message))

          this.emit('end')
        }))
        .pipe(plugins.jshint())
        .pipe(plugins.jshint.reporter('jshint-stylish'))
        .pipe(watch ? plugins.util.noop() : plugins.jshint.reporter('fail'))
        .pipe(plugins.jscs())
        .pipe(plugins.sourcemaps.init())
        .pipe(plugins.concat('app.js'))
        .pipe(plugins.uglify())
        .pipe(plugins.sourcemaps.write('maps'))
        .pipe(gulp.dest('public/assets/js'))
})

gulp.task('less', function () {
  return gulp.src(paths.less)
        .pipe(!watch ? plugins.util.noop() : plugins.plumber(function (error) {
          plugins.util.log(plugins.util.colors.red('Error (' + error.plugin + '): ' + error.message))

          this.emit('end')
        }))
        .pipe(plugins.sourcemaps.init())
        .pipe(plugins.less())
        .pipe(plugins.autoprefixer({
            browsers: ['last 2 versions']
        }))
        .pipe(plugins.postcss([
          postcss_url
        ]))
        .pipe(plugins.concat('style.css'))
        .pipe(plugins.minifyCss())
        .pipe(plugins.sourcemaps.write('maps'))
        .pipe(gulp.dest('public/assets/css'))
})

gulp.task('images', function () {
  return gulp.src(paths.images)
        .pipe(gulp.dest('public/assets/images'))
})

gulp.task('watch', function () {
  for (var task in paths) {
    gulp.watch(paths[task], [task])
  }
})

gulp.task('serve', function () {
    var server = plugins.liveServer('index.js')
    server.start()

    if( ! ('headless' in config) ) {
      setTimeout(function () {
        require('open')('http://local.vegosvar.se:8080')
      }, 1000)
    }

    gulp.watch(['views/**/*.ejs', 'views/**/*.html', 'public/**/*'], function () {
      server.notify.apply(server, arguments)
    })

    gulp.watch('*.js', function () {
      server.start()
    })
})

gulp.task('default', function (callback) {
  watch = true
  return run_sequence('pre-build', 'build', ['watch', 'serve'], function (error) {
    sequence_error(callback, error)
  })
})

gulp.task('prod', function (callback) {
  return run_sequence('pre-build', 'build', function (error) {
    sequence_error(callback, error)
  })
})<|endoftext|>