<commit_before>const React = require("react");
const {connect} = require("react-redux");
const {justDispatch} = require("common/selectors/selectors");
const {FormattedMessage} = require("react-intl");
const CollapsibleSection = require("components/CollapsibleSection/CollapsibleSection");
const {SpotlightItem, renderPlaceholderList} = require("components/Spotlight/Spotlight");
const {actions} = require("common/action-manager");
const {pocket_read_more_endpoint, pocket_learn_more_endpoint, pocket_survey_link} = require("../../../pocket.json");
const {POCKET_TOPICS_LENGTH} = require("common/constants");

const PocketStories = React.createClass({
  getDefaultProps() { return {prefs: {}}; },
  onClickFactory(index, story) {
    return () => {
      let payload = {
        event: "CLICK",
        page: this.props.page,
        source: "RECOMMENDED",
        action_position: index
      };
      this.props.dispatch(actions.NotifyEvent(payload));

      this.props.dispatch(actions.NotifyImpressionStats({
        source: "pocket",
        click: 0,
        tiles: [{id: story.guid, pos: index}]
      }));
    };
  },

  onTopicClick(index, topic, topic_url) {
    return () => {
      let payload = {
        event: "CLICK",
        page: this.props.page,
        source: "RECOMMENDED",
        action_position: index,
        recommender_type: topic,
        url: topic_url
      };
      this.props.dispatch(actions.NotifyEvent(payload));
    };
  },

  renderStories() {
    const stories = this.props.stories.slice(0, this.props.length);

    this.props.dispatch(actions.NotifyImpressionStats({
      source: "pocket",
      tiles: stories.map(story => ({id: story.guid}))
    }));

    return stories.map((story, i) =>
        <SpotlightItem
          index={i}
          key={story.url || i}
          page={this.props.page}
          source="RECOMMENDED"
          onClick={this.onClickFactory(i, story)}
          dispatch={this.props.dispatch}
          {...story}
          prefs={this.props.prefs} />
      );
  },

  renderReadMoreTopic(index, topic, url) {
    return (
{topic}
);
  },

  renderReadMoreTopics() {
    return (

        <FormattedMessage id="pocket_read_more" />

{this.props.topics.map((t, i) => this.renderReadMoreTopic(i, t.name, t.url))}

          <FormattedMessage id="pocket_read_even_more" />

    );
  },

  render() {
    if (this.props.stories.length < 1) {
      console.log("No Pocket stories available."); // eslint-disable-line no-console
      return null;
    }

    return (
      <CollapsibleSection className="pocket-stories spotlight" titleId="header_stories" prefName="collapsePocket" prefs={this.props.prefs}>

                <FormattedMessage id="header_stories_from" />

                Pocket

              Info

<FormattedMessage id="pocket_feedback_header" />

<FormattedMessage id="pocket_feedback_body" />

                    <FormattedMessage id="pocket_send_feedback" />

          {this.props.placeholder ? renderPlaceholderList() : this.renderStories()}

        {this.renderReadMoreTopics()}
      </CollapsibleSection>
    );
  }
});

PocketStories.propTypes = {
  page: React.PropTypes.string.isRequired,
  stories: React.PropTypes.array.isRequired,
  topics: React.PropTypes.array.isRequired,
  length: React.PropTypes.number,
  prefs: React.PropTypes.object
};

module.exports = connect(justDispatch)(PocketStories);
module.exports.PocketStories = PocketStories;
<commit_msg>fix(tests): Intermittent test failures of PocketStories on Travis<commit_after>const React = require("react");
const {connect} = require("react-redux");
const {justDispatch} = require("common/selectors/selectors");
const {FormattedMessage} = require("react-intl");
const CollapsibleSection = require("components/CollapsibleSection/CollapsibleSection");
const {SpotlightItem, renderPlaceholderList} = require("components/Spotlight/Spotlight");
const {actions} = require("common/action-manager");
const {pocket_read_more_endpoint, pocket_learn_more_endpoint, pocket_survey_link} = require("../../../pocket.json");
const {POCKET_TOPICS_LENGTH} = require("common/constants");

const PocketStories = React.createClass({
  getDefaultProps() { return {prefs: {}}; },
  onClickFactory(index, story) {
    return () => {
      let payload = {
        event: "CLICK",
        page: this.props.page,
        source: "RECOMMENDED",
        action_position: index
      };
      this.props.dispatch(actions.NotifyEvent(payload));

      this.props.dispatch(actions.NotifyImpressionStats({
        source: "pocket",
        click: 0,
        tiles: [{id: story.guid, pos: index}]
      }));
    };
  },

  onTopicClick(index, topic, topic_url) {
    return () => {
      let payload = {
        event: "CLICK",
        page: this.props.page,
        source: "RECOMMENDED",
        action_position: index,
        recommender_type: topic,
        url: topic_url
      };
      this.props.dispatch(actions.NotifyEvent(payload));
    };
  },

  renderStories() {
    const stories = this.props.stories.slice(0, this.props.length);

    this.props.dispatch(actions.NotifyImpressionStats({
      source: "pocket",
      tiles: stories.map(story => ({id: story.guid}))
    }));

    return stories.map((story, i) =>
        <SpotlightItem
          index={i}
          key={story.guid || story.url || i}
          page={this.props.page}
          source="RECOMMENDED"
          onClick={this.onClickFactory(i, story)}
          dispatch={this.props.dispatch}
          {...story}
          prefs={this.props.prefs} />
      );
  },

  renderReadMoreTopic(index, topic, url) {
    return (
{topic}
);
  },

  renderReadMoreTopics() {
    return (

        <FormattedMessage id="pocket_read_more" />

{this.props.topics.map((t, i) => this.renderReadMoreTopic(i, t.name, t.url))}

          <FormattedMessage id="pocket_read_even_more" />

    );
  },

  render() {
    if (this.props.stories.length < 1) {
      console.log("No Pocket stories available."); // eslint-disable-line no-console
      return null;
    }

    return (
      <CollapsibleSection className="pocket-stories spotlight" titleId="header_stories" prefName="collapsePocket" prefs={this.props.prefs}>

                <FormattedMessage id="header_stories_from" />

                Pocket

              Info

<FormattedMessage id="pocket_feedback_header" />

<FormattedMessage id="pocket_feedback_body" />

                    <FormattedMessage id="pocket_send_feedback" />

          {this.props.placeholder ? renderPlaceholderList() : this.renderStories()}

        {this.renderReadMoreTopics()}
      </CollapsibleSection>
    );
  }
});

PocketStories.propTypes = {
  page: React.PropTypes.string.isRequired,
  stories: React.PropTypes.array.isRequired,
  topics: React.PropTypes.array.isRequired,
  length: React.PropTypes.number,
  prefs: React.PropTypes.object
};

module.exports = connect(justDispatch)(PocketStories);
module.exports.PocketStories = PocketStories;
<|endoftext|>


<commit_before>$(document).ready(function(){
 url = location.search;
 query = "";
 i = 0;

 function Display_Load() {
  $(".spinner").fadeIn(900,0);
  $(".spinner").html("");
 };

 function Hide_Load() {
  $(".spinner").fadeOut('slow');
 };

 function Build_Pagination() {
  Hide_Load();  //Hide spinner
  var monitorName = $("#inptMonitorName").attr("value"); // Get the currently selected monitor.  This is only needed for the first page load, before any filters are set.
  $(".pagination li").click(function() { //If page is changed
   Display_Load(); //Show spinner
   var pageNum = this.id; //Set page number
   if (!(query == "")) {
    $("#events").load("/skins/new/views/pagination_data.php?page=" + pageNum + query, function () { Build_Pagination() }); //Load data to page then rebuild Build_Pagination function
   } else {
    $("#events").load("/skins/new/views/pagination_data.php?page=" + pageNum + "&filter[terms][0][attr]=MonitorName&filter[terms][0][op]==&filter[terms][0][val]=" + monitorName, function () { Build_Pagination() }); //Load data to page then rebuild Build_Pagination function
   }
  });

 // Auto-check the default monitor filter box
 $("#sidebarHistory input").each(function() {
  if ((this.id) == $("#inptMonitorName").attr("value")) {
    $(this).attr("checked", true);
  }
 });

 };

 $("#liSpecificDate").click(function() {
  $("#filterSpecificDate").css("display", "block");
 });

 $("#divSubmit").click(function() {
  var from = $("#inptFrom").val();
  var to = $("#inptTo").val();
  var q = "";
  var x = "";

  var num = [];
  $("#sidebarHistory input:checked").each(function() {
   num.push(this.id);
  });
  i = num.length;

  if (i == 1) {
   x =  "&filter[terms][1][cnj]=and&filter[terms][1][obr]=0&filter[terms][1][attr]=DateTime&filter[terms][1][op]=%3E&filter[terms][1][val]=" + from + "&filter[terms][1][cbr]=0";
   x += "&filter[terms][2][cnj]=and&filter[terms][2][obr]=0&filter[terms][2][attr]=DateTime&filter[terms][2][op]=%3C&filter[terms][2][val]=" + to + "&filter[terms][2][cbr]=0";
   q = url + x;
  } else {
   x =  "&filter[terms][" + i + "][cnj]=and&filter[terms][" + i + "][obr]=0&filter[terms][" + i + "][attr]=DateTime&filter[terms][" + i + "][op]=%3E&filter[terms][" + i + "][val]=" + from + "&filter[terms][" + i + "][cbr]=0";
   i++;
   x += "&filter[terms][" + i + "][cnj]=and&filter[terms][" + i + "][obr]=0&filter[terms][" + i + "][attr]=DateTime&filter[terms][" + i + "][op]=%3C&filter[terms][" + i + "][val]=" + to + "&filter[terms][" + i + "][cbr]=0";
   q = query + x;
  }

  $("#events").load("/skins/new/views/pagination_data.php?page=1" + q, function() { Build_Pagination() });
 });

 Display_Load(); //First thing that happens - display spinner
 $("#events").load("/skins/new/views/pagination_data.php" + url, function() { Build_Pagination() }); //Second, load data into #events then build Build_Pagination function

 $('#sidebarHistory input').change(function() { //When a checkbox is checked
  if ($(this).attr("checked") == true) {
  var allVals = []; //Make the array
  $("#sidebarHistory input:checked").each(function() { //For each checked box
   allVals.push(this.id); //Push the checkbox id into the array
  });
  var x = allVals.length; //Get the number of checked boxes
  for (i=0;i<x;i++) { //For each checked box
   if (i>0){ //If more than 1 checked box
    query += "&filter[terms][" + i + "][cnj]=or&filter[terms][" + i + "][attr]=MonitorName&filter[terms][" + i + "][op]==&filter[terms][" + i + "][val]=" + allVals[i]; // add "or"
   } else {
    query = "&filter[terms][" + i + "][attr]=MonitorName&filter[terms][" + i + "][op]==&filter[terms][" + i + "][val]=" + allVals[i]; // Add nothing
   }
  };
  monitorName = this.id
  Display_Load(); //Display spinner
  $("#events").load("/skins/new/views/pagination_data.php?page=1" + query, function() { Build_Pagination()}); // Load data into #events
 }});
});
<commit_msg>Changing pages while filtering on monitor and date seems to mostly work, though the query is still getting skewed.<commit_after>$(document).ready(function(){
 url = location.search;
 query = "";
 i = 0;

 function Display_Load() {
  $(".spinner").fadeIn(900,0);
  $(".spinner").html("");
 };

 function Hide_Load() {
  $(".spinner").fadeOut('slow');
 };

 function Build_Pagination() {
  Hide_Load();  //Hide spinner
  var monitorName = $("#inptMonitorName").attr("value"); // Get the currently selected monitor.  This is only needed for the first page load, before any filters are set.
  $(".pagination li").click(function() { //If page is changed
   Display_Load(); //Show spinner
   var pageNum = this.id; //Set page number
   if (!(query == "")) {
    $("#events").load("/skins/new/views/pagination_data.php?page=" + pageNum + query, function () { Build_Pagination() }); //Load data to page then rebuild Build_Pagination function
   } else {
    $("#events").load("/skins/new/views/pagination_data.php?page=" + pageNum + "&filter[terms][0][attr]=MonitorName&filter[terms][0][op]==&filter[terms][0][val]=" + monitorName, function () { Build_Pagination() }); //Load data to page then rebuild Build_Pagination function
   }
  });

 // Auto-check the default monitor filter box
 $("#sidebarHistory input").each(function() {
  if ((this.id) == $("#inptMonitorName").attr("value")) {
    $(this).attr("checked", true);
  }
 });

 };

 $("#liSpecificDate").click(function() {
  $("#filterSpecificDate").css("display", "block");
 });

 $("#divSubmit").click(function() {
  var from = $("#inptFrom").val();
  var to = $("#inptTo").val();
  var q = "";

  var num = [];
  $("#sidebarHistory input:checked").each(function() {
   num.push(this.id);
  });
  i = num.length;

  if (i == 1) {
   x =  "&filter[terms][1][cnj]=and&filter[terms][1][obr]=0&filter[terms][1][attr]=DateTime&filter[terms][1][op]=%3E&filter[terms][1][val]=" + from + "&filter[terms][1][cbr]=0";
   x += "&filter[terms][2][cnj]=and&filter[terms][2][obr]=0&filter[terms][2][attr]=DateTime&filter[terms][2][op]=%3C&filter[terms][2][val]=" + to + "&filter[terms][2][cbr]=0";
   q = url + x;
  } else {
   var x = "";
   x =  "&filter[terms][" + i + "][cnj]=and&filter[terms][" + i + "][obr]=0&filter[terms][" + i + "][attr]=DateTime&filter[terms][" + i + "][op]=%3E&filter[terms][" + i + "][val]=" + from + "&filter[terms][" + i + "][cbr]=0";
   i++;
   x += "&filter[terms][" + i + "][cnj]=and&filter[terms][" + i + "][obr]=0&filter[terms][" + i + "][attr]=DateTime&filter[terms][" + i + "][op]=%3C&filter[terms][" + i + "][val]=" + to + "&filter[terms][" + i + "][cbr]=0";
   query = query + x;
  }

  $("#events").load("/skins/new/views/pagination_data.php?page=1" + query, function() { Build_Pagination() });
 });

 Display_Load(); //First thing that happens - display spinner
 $("#events").load("/skins/new/views/pagination_data.php" + url, function() { Build_Pagination() }); //Second, load data into #events then build Build_Pagination function

 $('#sidebarHistory input').change(function() { //When a checkbox is checked
  if ($(this).attr("checked") == true) {
  var allVals = []; //Make the array
  $("#sidebarHistory input:checked").each(function() { //For each checked box
   allVals.push(this.id); //Push the checkbox id into the array
  });
  var x = allVals.length; //Get the number of checked boxes
  for (i=0;i<x;i++) { //For each checked box
   if (i>0){ //If more than 1 checked box
    query += "&filter[terms][" + i + "][cnj]=or&filter[terms][" + i + "][attr]=MonitorName&filter[terms][" + i + "][op]==&filter[terms][" + i + "][val]=" + allVals[i]; // add "or"
   } else {
    query = "&filter[terms][" + i + "][attr]=MonitorName&filter[terms][" + i + "][op]==&filter[terms][" + i + "][val]=" + allVals[i]; // Add nothing
   }
  };
  monitorName = this.id
  Display_Load(); //Display spinner
  $("#events").load("/skins/new/views/pagination_data.php?page=1" + query, function() { Build_Pagination()}); // Load data into #events
 }});
});
<|endoftext|>


<commit_before>/*!
 * Language Selector JS plugin
 * Copyright 2017 Clement G., Inc.
 * Licensed under MIT
 */

var dropdownmenu={
	animspeed: 200, 			//reveal animation speed (in milliseconds)
	showhidedelay: [150, 150], 	//delay before menu appears and disappears when mouse rolls over it, in milliseconds

	//***** NO NEED TO EDIT BEYOND HERE
	builtdropdownids: [], 		//ids of dropdown already built (to prevent repeated building of same dropdown)
	stubboxenable: false,

	showbox:function($, $dropdown){
		this.stubboxenable = false;
		clearTimeout($dropdown.data('timers').hidetimer);
		$dropdown.data('timers').showtimer=setTimeout(function(){$dropdown.show(dropdownmenu.animspeed)}, this.showhidedelay[0])
	},

	hidebox:function($, $dropdown){
		if(this.stubboxenable === false) {
			clearTimeout($dropdown.data('timers').showtimer);
			$dropdown.data('timers').hidetimer=setTimeout(function(){$dropdown.hide(100)}, this.showhidedelay[1]) //hide dropdown plus all of its sub ULs
		}
	},

	stubbox:function($, $dropdown){
		this.stubboxenable = true;
		clearTimeout($dropdown.data('timers').hidetimer);
		$dropdown.data('timers').showtimer=setTimeout(function(){$dropdown.show(dropdownmenu.animspeed)}, this.showhidedelay[0])
	},

	builddropdown:function($, $menu, $target){
		$menu.css({display:'none'}).addClass('jqdropdown');
		$menu.bind('mouseenter', function(){
			clearTimeout($menu.data('timers').hidetimer)
		});
		$menu.bind('mouseleave', function(){ //hide menu when mouse moves out of it
			dropdownmenu.hidebox($, $menu)
		});
		$menu.data('dimensions', {w:$menu.outerWidth(), h:$menu.outerHeight()}); //remember main menu's dimensions
		$menu.data('timers', {});
		this.builtdropdownids.push($menu.get(0).id) //remember id of dropdown that was just built
	},

	init:function($, $target, $dropdown){
		if (this.builtdropdownids.length === 0){ //only bind click event to document once
			$(document).bind("click", function(e){
				if (e.button === 0){ //hide all dropdown (and their sub ULs) when left mouse button is clicked
					$('.jqdropdown').find('ul').andSelf().hide()
				}
			})
		}
		if (jQuery.inArray($dropdown.get(0).id, this.builtdropdownids) === -1) //if this dropdown hasn't been built yet
			this.builddropdown($, $dropdown, $target);
		if ($target.parents().filter('ul.jqdropdown').length>0) //if $target matches an element within the dropdown markup, don't bind ondropdown to that element
			return;
		$target.bind("mouseenter", function(e){
			dropdownmenu.showbox($, $dropdown)
		});
		$target.bind("mouseleave", function(e){
			dropdownmenu.hidebox($, $dropdown)
		});
		$target.bind("click", function(e){
			dropdownmenu.stubbox($, $dropdown)
		})
	}
};

//By default, add dropdown to anchor links with attribute "data-dropdown"
jQuery(document).ready(function($){

  jQuery.fn.adddropdown=function(dropdownid){
    var $=jQuery;
    return this.each(function(){ //return jQuery obj
      var $target=$(this);
      var $dropdownId = $('#'+dropdownid);
      if ($dropdownId.length === 1) //check dropdown is defined
        dropdownmenu.init($, $target, $dropdownId)
    })
  };

	var $anchors=$('*[data-dropdown]');
	$anchors.each(function(){
		$(this).adddropdown(this.getAttribute('data-dropdown'))
	})
});
<commit_msg>Replaced .andSelf() function which was removed in jQuery 3.0: https://api.jquery.com/andself/<commit_after>/*!
 * Language Selector JS plugin
 * Copyright 2017 Clement G., Inc.
 * Licensed under MIT
 */

var dropdownmenu={
	animspeed: 200, 			//reveal animation speed (in milliseconds)
	showhidedelay: [150, 150], 	//delay before menu appears and disappears when mouse rolls over it, in milliseconds

	//***** NO NEED TO EDIT BEYOND HERE
	builtdropdownids: [], 		//ids of dropdown already built (to prevent repeated building of same dropdown)
	stubboxenable: false,

	showbox:function($, $dropdown){
		this.stubboxenable = false;
		clearTimeout($dropdown.data('timers').hidetimer);
		$dropdown.data('timers').showtimer=setTimeout(function(){$dropdown.show(dropdownmenu.animspeed)}, this.showhidedelay[0])
	},

	hidebox:function($, $dropdown){
		if(this.stubboxenable === false) {
			clearTimeout($dropdown.data('timers').showtimer);
			$dropdown.data('timers').hidetimer=setTimeout(function(){$dropdown.hide(100)}, this.showhidedelay[1]) //hide dropdown plus all of its sub ULs
		}
	},

	stubbox:function($, $dropdown){
		this.stubboxenable = true;
		clearTimeout($dropdown.data('timers').hidetimer);
		$dropdown.data('timers').showtimer=setTimeout(function(){$dropdown.show(dropdownmenu.animspeed)}, this.showhidedelay[0])
	},

	builddropdown:function($, $menu, $target){
		$menu.css({display:'none'}).addClass('jqdropdown');
		$menu.bind('mouseenter', function(){
			clearTimeout($menu.data('timers').hidetimer)
		});
		$menu.bind('mouseleave', function(){ //hide menu when mouse moves out of it
			dropdownmenu.hidebox($, $menu)
		});
		$menu.data('dimensions', {w:$menu.outerWidth(), h:$menu.outerHeight()}); //remember main menu's dimensions
		$menu.data('timers', {});
		this.builtdropdownids.push($menu.get(0).id) //remember id of dropdown that was just built
	},

	init:function($, $target, $dropdown){
		if (this.builtdropdownids.length === 0){ //only bind click event to document once
			$(document).bind("click", function(e){
				if (e.button === 0){ //hide all dropdown (and their sub ULs) when left mouse button is clicked
					$('.jqdropdown').find('ul').addBack().hide()
				}
			})
		}
		if (jQuery.inArray($dropdown.get(0).id, this.builtdropdownids) === -1) //if this dropdown hasn't been built yet
			this.builddropdown($, $dropdown, $target);
		if ($target.parents().filter('ul.jqdropdown').length>0) //if $target matches an element within the dropdown markup, don't bind ondropdown to that element
			return;
		$target.bind("mouseenter", function(e){
			dropdownmenu.showbox($, $dropdown)
		});
		$target.bind("mouseleave", function(e){
			dropdownmenu.hidebox($, $dropdown)
		});
		$target.bind("click", function(e){
			dropdownmenu.stubbox($, $dropdown)
		})
	}
};

//By default, add dropdown to anchor links with attribute "data-dropdown"
jQuery(document).ready(function($){

  jQuery.fn.adddropdown=function(dropdownid){
    var $=jQuery;
    return this.each(function(){ //return jQuery obj
      var $target=$(this);
      var $dropdownId = $('#'+dropdownid);
      if ($dropdownId.length === 1) //check dropdown is defined
        dropdownmenu.init($, $target, $dropdownId)
    })
  };

	var $anchors=$('*[data-dropdown]');
	$anchors.each(function(){
		$(this).adddropdown(this.getAttribute('data-dropdown'))
	})
});
<|endoftext|>


<commit_before>/* jslint asi:true, browser:true */

var Rainbow = {
    colours: ["cyan", "blue", "purple", "magenta", "red", "yellow", "green", "teal"],
    parseDocument: undefined,
    parseText: undefined
};

Rainbow.parse = function(data, starting_index) {

    var colour_index = 0;
    var i;
    var j;
    var r;
    if (!isNaN(Number(starting_index))) colour_index = Number(starting_index) % 8;
    else if (Rainbow.colours.indexOf(starting_index) !== -1) colour_index = Rainbow.colours.indexOf(starting_index);

    switch (typeof text) {

        case "text":
            r = document.createElement("SPAN");
            var final_text = "";
            for (i = 0; i < data.length; i++) {
                if (/\s/.test(data[i])) {
                    final_text += data[i];
                }
                else {
                    final_text += '' + data[i] + "";
                    colour_index %= Rainbow.colours.length;
                }
            }
            r.innerHTML = final_text;
            r.dataset.colour = "transparent";
            break;

        case "undefined":
        case "object":
            if (!data) data = document.body;
            else if (data instanceof Document) data = data.documentElement;
            else if (!(data instanceof Element)) break;
            var elements = data.querySelectorAll("*[data-rainbow]");
            for (i = 0; i < elements.length; i++) {
                var children = elements.item(i).childNodes;
                var element_starting_index = elements.item(i).dataset.rainbow;
                if (element_starting_index === "" || (isNaN(Number(element_starting_index)) && Rainbow.colours.indexOf(starting_index) !== -1)) element_starting_index = colour_index;
                for (j = 0; j < children.length; j++) {
                    if (children.item(j).nodeType !== 3) continue;
                    elements.item(i).replaceChild(Rainbow.parseText(children.item(j).textContent, elements.item(i).dataset.rainbow), children.item(j));
                }
            }
            r = data;

    }

    return r;

}

Rainbow.parse = function(element) {
}
<commit_msg>NOOOOOOOOOOOO okayfixed<commit_after>/* jslint asi:true, browser:true */

var Rainbow = {
    colours: ["cyan", "blue", "purple", "magenta", "red", "yellow", "green", "teal"],
    parseDocument: undefined,
    parseText: undefined
};

Rainbow.parse = function(data, starting_index) {

    var colour_index = 0;
    var i;
    var j;
    var r;
    if (!isNaN(Number(starting_index))) colour_index = Number(starting_index) % 8;
    else if (Rainbow.colours.indexOf(starting_index) !== -1) colour_index = Rainbow.colours.indexOf(starting_index);

    switch (typeof text) {

        case "text":
            r = document.createElement("SPAN");
            var final_text = "";
            for (i = 0; i < data.length; i++) {
                if (/\s/.test(data[i])) {
                    final_text += data[i];
                }
                else {
                    final_text += '' + data[i] + "";
                    colour_index %= Rainbow.colours.length;
                }
            }
            r.innerHTML = final_text;
            r.dataset.colour = "transparent";
            break;

        case "undefined":
        case "object":
            if (!data) data = document.body;
            else if (data instanceof Document) data = data.documentElement;
            else if (!(data instanceof Element)) break;
            var elements = data.querySelectorAll("*[data-rainbow]");
            for (i = 0; i < elements.length; i++) {
                var children = elements.item(i).childNodes;
                var element_starting_index = elements.item(i).dataset.rainbow;
                if (element_starting_index === "" || (isNaN(Number(element_starting_index)) && Rainbow.colours.indexOf(starting_index) !== -1)) element_starting_index = colour_index;
                for (j = 0; j < children.length; j++) {
                    if (children.item(j).nodeType !== 3) continue;
                    elements.item(i).replaceChild(Rainbow.parseText(children.item(j).textContent, elements.item(i).dataset.rainbow), children.item(j));
                }
            }
            r = data;

    }

    return r;

}
<|endoftext|>


<commit_before>/**
 * @ngdoc directive
 * @name refigureApp.directive:collectionsItem
 * @restrict E
 * @description
 * Single collection page
 * @example
 * <collections-item></collections-item>
 */
(function (angular) {
    'use strict';

    angular
        .module('refigureApp')
        .component('collectionsItem', {
            templateUrl: 'view/collectionsItem.component.html',
            controllerAs: 'vm',
            controller: ItemController
        });

    ItemController.$inject = [
        '$scope',
        '$state',
        'MESSAGES',
        'collections',
        'modalDialog',
        'auth'
    ];

    function ItemController($scope, $state, MESSAGES, collections, modal, auth) {
        var vm = this;
        var currentLastInRow = -1;

        var imgSrcParsers = [
            {
                name: 'plos',
                matcher: function (str) {
                    return str.match(/plos\.org/);
                },
                replacer: function (str) {
                    return str.replace('size=inline', 'size=large');
                }
            }, {
                name: 'elifescinces',
                matcher: function (str) {
                    return str.match(/elifesciences\.org/);
                },
                replacer: function (str) {
                    return str.replace('-480w.', '.').replace('-300w.', '.');
                }
            }, {
                name: 'pmc',
                matcher: function (str) {
                    return str.match(/ncbi\.nlm\.nih\.gov\/pmc/);
                },
                replacer: function (str) {
                    return str.replace('.gif', '.jpg');
                }
            }
        ];

        vm.url = window.location.href;

        vm.refigure = {};
        vm.details = null;
        vm.user = {};

        vm.imageDetails = imageDetails;
        vm.toggleFlag = toggleFlag;
        vm.isAdmin = isAdmin;
        vm.showFullScreen = showFullScreen;

        vm.$onInit = activate;

        ///////////////////////

        function activate() {
            $scope.$watch(function () {
                return $state.params.view;
            }, function (view) {
                vm.view = view || 'grid';
            });

            if (auth.isAuthenticated()) {
                auth.usrInfo().then(function (user) {
                    vm.user = user;
                });
            }
            $scope.$on('refigureUpdated', function (e, updated) {
                e.stopPropagation();
                setRefigure(updated);
            });

            $state.get('collections.item').data.headerTitle = '';
            collections
                .get($state.params.id)
                .then(function (resp) {
                    window.postMessage({
                        type: MESSAGES.MSG_TYPE_REFIGURE_IMAGES_COLLECTED,
                        images: resp.Figures
                    }, '*');
                    setRefigure(resp);
                });
        }

        function imageDetails(e, index) {
            var el = e.target,
                nextElement;
            if (el.tagName === 'IMG') {
                el = el.parentNode;
            }
            if (vm.details && vm.details.ID === vm.refigure.Figures[index].ID) {
                //close current
                currentLastInRow = -1;
                vm.refigure.Figures[index].lastInRow = false;
                vm.details = null;
            } else {
                if (currentLastInRow !== -1) {
                    //close previously opened
                    vm.refigure.Figures[currentLastInRow].lastInRow = false;
                }
                //search for last in row
                currentLastInRow = index;
                while (el) {
                    nextElement = getNextImage(el);
                    if (
                        currentLastInRow === vm.refigure.Figures.length - 1 || //is last element
                        el.getBoundingClientRect().right > nextElement.getBoundingClientRect().right //last in row
                    ) {
                        vm.refigure.Figures[currentLastInRow].lastInRow = true;
                        break;
                    }
                    currentLastInRow++;
                    el = el.nextElementSibling;
                }
                vm.details = vm.refigure.Figures[index];
            }

            function getNextImage(el) {
                var ret = el.nextElementSibling;
                if (ret && ret.tagName === 'MD-CARD') {
                    ret = ret.nextElementSibling;
                }
                return ret || el;
            }
        }

        function toggleFlag() {
            collections.toggleFlag(vm.refigure.ID)
                .then(function () {
                    vm.refigure.Flagged = !vm.refigure.Flagged * 1;
                });
        }

        function isAdmin() {
            return vm.user.Type === 2;
        }

        function showFullScreen(e, src) {
            for (var i = 0; i < imgSrcParsers.length; i++) {
                if (imgSrcParsers[i].matcher(src)) {
                    src = imgSrcParsers[i].replacer(src);
                    console.info('SRC matched: ', imgSrcParsers[i].name, ', set to: ', src);
                    break;
                }
            }

            modal.show({
                template: '',
                targetEvent: e,
                onShowing: function (s, el) {
                    el[0].classList.add('md-dialog-autoheight');
                },
                disableParentScroll: false,
                clickOutsideToClose: true,
                parent: '.r-page-content'
            });
        }

        function setRefigure(refigure) {
            angular.merge(vm.refigure, refigure);
            $state.get('collections.item').data.headerTitle = '"' + vm.refigure.Title + '"';
            if (vm.refigure.Keywords) {
                vm.refigure.KeywordsChips = vm.refigure.Keywords.split(/(?:(?:&[^;]+;)|\s|\||,|;)+/);
            }
        }

    }
})(window.angular);
<commit_msg>~ github bug: duplication of last image after deletion<commit_after>/**
 * @ngdoc directive
 * @name refigureApp.directive:collectionsItem
 * @restrict E
 * @description
 * Single collection page
 * @example
 * <collections-item></collections-item>
 */
(function (angular) {
    'use strict';

    angular
        .module('refigureApp')
        .component('collectionsItem', {
            templateUrl: 'view/collectionsItem.component.html',
            controllerAs: 'vm',
            controller: ItemController
        });

    ItemController.$inject = [
        '$scope',
        '$state',
        'MESSAGES',
        'collections',
        'modalDialog',
        'auth'
    ];

    function ItemController($scope, $state, MESSAGES, collections, modal, auth) {
        var vm = this;
        var currentLastInRow = -1;

        var imgSrcParsers = [
            {
                name: 'plos',
                matcher: function (str) {
                    return str.match(/plos\.org/);
                },
                replacer: function (str) {
                    return str.replace('size=inline', 'size=large');
                }
            }, {
                name: 'elifescinces',
                matcher: function (str) {
                    return str.match(/elifesciences\.org/);
                },
                replacer: function (str) {
                    return str.replace('-480w.', '.').replace('-300w.', '.');
                }
            }, {
                name: 'pmc',
                matcher: function (str) {
                    return str.match(/ncbi\.nlm\.nih\.gov\/pmc/);
                },
                replacer: function (str) {
                    return str.replace('.gif', '.jpg');
                }
            }
        ];

        vm.url = window.location.href;

        vm.refigure = {};
        vm.details = null;
        vm.user = {};

        vm.imageDetails = imageDetails;
        vm.toggleFlag = toggleFlag;
        vm.isAdmin = isAdmin;
        vm.showFullScreen = showFullScreen;

        vm.$onInit = activate;

        ///////////////////////

        function activate() {
            $scope.$watch(function () {
                return $state.params.view;
            }, function (view) {
                vm.view = view || 'grid';
            });

            if (auth.isAuthenticated()) {
                auth.usrInfo().then(function (user) {
                    vm.user = user;
                });
            }
            $scope.$on('refigureUpdated', function (e, updated) {
                e.stopPropagation();
                setRefigure(updated);
            });

            $state.get('collections.item').data.headerTitle = '';
            collections
                .get($state.params.id)
                .then(function (resp) {
                    window.postMessage({
                        type: MESSAGES.MSG_TYPE_REFIGURE_IMAGES_COLLECTED,
                        images: resp.Figures
                    }, '*');
                    setRefigure(resp);
                });
        }

        function imageDetails(e, index) {
            var el = e.target,
                nextElement;
            if (el.tagName === 'IMG') {
                el = el.parentNode;
            }
            if (vm.details && vm.details.ID === vm.refigure.Figures[index].ID) {
                //close current
                currentLastInRow = -1;
                vm.refigure.Figures[index].lastInRow = false;
                vm.details = null;
            } else {
                if (currentLastInRow !== -1) {
                    //close previously opened
                    vm.refigure.Figures[currentLastInRow].lastInRow = false;
                }
                //search for last in row
                currentLastInRow = index;
                while (el) {
                    nextElement = getNextImage(el);
                    if (
                        currentLastInRow === vm.refigure.Figures.length - 1 || //is last element
                        el.getBoundingClientRect().right > nextElement.getBoundingClientRect().right //last in row
                    ) {
                        vm.refigure.Figures[currentLastInRow].lastInRow = true;
                        break;
                    }
                    currentLastInRow++;
                    el = el.nextElementSibling;
                }
                vm.details = vm.refigure.Figures[index];
            }

            function getNextImage(el) {
                var ret = el.nextElementSibling;
                if (ret && ret.tagName === 'MD-CARD') {
                    ret = ret.nextElementSibling;
                }
                return ret || el;
            }
        }

        function toggleFlag() {
            collections.toggleFlag(vm.refigure.ID)
                .then(function () {
                    vm.refigure.Flagged = !vm.refigure.Flagged * 1;
                });
        }

        function isAdmin() {
            return vm.user.Type === 2;
        }

        function showFullScreen(e, src) {
            for (var i = 0; i < imgSrcParsers.length; i++) {
                if (imgSrcParsers[i].matcher(src)) {
                    src = imgSrcParsers[i].replacer(src);
                    console.info('SRC matched: ', imgSrcParsers[i].name, ', set to: ', src);
                    break;
                }
            }

            modal.show({
                template: '',
                targetEvent: e,
                onShowing: function (s, el) {
                    el[0].classList.add('md-dialog-autoheight');
                },
                disableParentScroll: false,
                clickOutsideToClose: true,
                parent: '.r-page-content'
            });
        }

        function setRefigure(refigure) {
            angular.merge(vm.refigure, refigure);
            vm.refigure.Figures = refigure.Figures;
            $state.get('collections.item').data.headerTitle = '"' + vm.refigure.Title + '"';
            if (vm.refigure.Keywords) {
                vm.refigure.KeywordsChips = vm.refigure.Keywords.split(/(?:(?:&[^;]+;)|\s|\||,|;)+/);
            }
        }

    }
})(window.angular);
<|endoftext|>


<commit_before>$(function(){"use strict";function e(){$(window).width()<568?($(".wrapper").addClass("hidden"),$("footer").addClass("hidden")):($(".wrapper").show(""),$("footer").show(""))}function n(){$(window).width()<568?($(".wrapper").removeClass("hidden"),$("footer").removeClass("hidden")):($(".wrapper").show(""),$("footer").show(""))}let t=$("body");`
\n
Start a Project
\n
\n            <form id="start-project-form" class="form-styles">\n
\n
\n                        <input type="text" name="FNAME" placeholder="Full name">\n

\n
    \n
\n
\n
\n                        <input type="email" name="EMAIL" placeholder="Email">\n

\n
\n
\n
\n

\n
\n
\n
\n                        <button class="btn-popup cancel-modal-btn">Cancel</button>\n
\n
\n                        <button class="btn-popup" type="button" id="submit-modal-form">Submit</button>\n
\n
\n            </form>\n
\n
`,`
\n
Become a Partner
\n
\n          <form id="become-partner-form" class="form-styles">\n
\n
\n                      <input type="text" name="FNAME" placeholder="Full name">\n

\n
    \n
\n
\n
\n                      <input type="text" name="COMPANY" placeholder="Company">\n

\n
    \n
\n
\n
\n                      <input type="email" name="EMAIL" placeholder="Email">\n

\n
\n
\n
\n

\n
\n
\n
\n                      <button class="btn-popup cancel-modal-btn">Cancel</button>\n
\n
\n                      <button class="btn-popup" type="button" id="submit-modal-form">Submit</button>\n
\n
\n          </form>\n
`;$(".become-partner").popup({content:'
\n
Become a Partner
\n
\n          <form id="become-partner-form" class="form-styles">\n
\n
\n                      <input type="text" name="FNAME" placeholder="Full name">\n

\n
    \n
\n
\n
\n                      <input type="text" name="COMPANY" placeholder="Company">\n

\n
    \n
\n
\n
\n                      <input type="email" name="EMAIL" placeholder="Email">\n

\n
\n
\n
\n

\n
\n
\n
\n                      <button class="btn-popup cancel-modal-btn">Cancel</button>\n
\n
\n                      <button class="btn-popup" type="button" id="submit-modal-form">Submit</button>\n
\n
\n          </form>\n
',type:"html",preloaderContent:"",beforeOpen:function(n){e()},afterOpen:function(){$("#become-partner-form").MailChimpForm({url:"//mitocgroup.us11.list-manage.com/subscribe/post?u=13a7a5fca813b378c24ec9fe3&id=7257663d85",fields:"EMAIL,FNAME,COMPANY",submitSelector:"#submit-modal-form",onFail:function(e){let n=$("#mc-general-error-partner");n.text(e),setTimeout(()=>{n.text("")},5e3)},onOk:function(e){window.location=`/confirm/become-partner/?mc-message=${e}`}})},beforeClose:function(){n()}}),$(".start-project").popup({content:'
\n
Start a Project
\n
\n            <form id="start-project-form" class="form-styles">\n
\n
\n                        <input type="text" name="FNAME" placeholder="Full name">\n

\n
    \n
\n
\n
\n                        <input type="email" name="EMAIL" placeholder="Email">\n

\n
\n
\n
\n

\n
\n
\n
\n                        <button class="btn-popup cancel-modal-btn">Cancel</button>\n
\n
\n                        <button class="btn-popup" type="button" id="submit-modal-form">Submit</button>\n
\n
\n            </form>\n
\n
',type:"html",preloaderContent:"",beforeOpen:function(n){e()},afterOpen:function(){$("#start-project-form").MailChimpForm({url:"//mitocgroup.us11.list-manage.com/subscribe/post?u=13a7a5fca813b378c24ec9fe3&id=f6629ecf38",fields:"EMAIL,FNAME",submitSelector:"#submit-modal-form",onFail:function(e){let n=$("#mc-general-error-project");n.text(e),setTimeout(()=>{n.text("")},5e3)},onOk:function(e){window.location=`/confirm/start-project/?mc-message=${e}`}})},beforeClose:function(){n()}}),$("#contact-us-form").MailChimpForm({url:"//mitocgroup.us11.list-manage.com/subscribe/post?u=13a7a5fca813b378c24ec9fe3&id=daffe46160",fields:"EMAIL,FNAME,COMPANY,PHONE,MESSAGE",submitSelector:"#submit-contact-form",onFail:function(e){let n=$("#mc-general-error");n.html(`<div class="error-mc">${e}</div>`),setTimeout(()=>{n.html("")},5e3)},onOk:function(e){window.location=`/confirm/contact-us/?mc-message=${e}`}}),t.on("click",".cancel-modal-btn",function(e){e.preventDefault(),e.stopPropagation(),$(".popup_back").trigger("click")})});<commit_msg>#MG recompile js<commit_after><|endoftext|>


<commit_before>function createInitCmsMessageBox(status, message) {
    status = status == 'error'?'danger':status;
    var messageHtml = '
×' + message + '
';

    jQuery('.notice-block').html(messageHtml);
}

function trim(str) {
    str = str.replace(/^\s+/, '');
    for (var i = str.length - 1; i >= 0; i--) {
        if (/\S/.test(str.charAt(i))) {
            str = str.substring(0, i + 1);
            break;
        }
    }
    return str;
}

function uploadError(xhr) {
    alert(xhr.error);
}
(function ($) {

    var noticeBlock = $('.notice-block');

    noticeBlock.on('DOMNodeInserted', function () {
        $(this).fadeIn().delay('3000').fadeOut(500);
    });

    noticeBlock.each(function (k, e) {
        if (trim($(e).html()) != '') {
            $(e).fadeIn().delay('3000').fadeOut(500);
        }
    });

    $('.show-tooltip, [data-toggle="tooltip"]').tooltip({placement:'bottom', container: 'body', delay:{ show:800, hide:100 }});

    var openModals = [];

    $(document).on('shown.bs.modal', '.modal', function (e) {
        var modalBody = $(this).find('.modal-body');
        modalBody.css('overflow-y', 'auto');
        modalBody.css('max-height', '55vh');
        openModals.push($(this).attr('id'));
    }).on('hide.bs.modal', '.modal', function(){
        var index = openModals.indexOf($(this).attr('id'));
        if (index > -1) {
            openModals.splice(index, 1);
        }
    }).on('hidden.bs.modal', function(){
        if(openModals.length > 0){
            $('body').addClass('modal-open');
        }
    });

    // handle the #toggle click event
    $("#toggleNav").on("click", function () {
        // apply/remove the active class to the row-offcanvas element
        $(".row-offcanvas").toggleClass("active");
        return false;
    });
    var toggleWidthBtn = $('#toggleWidth');
    var resizeIcon = toggleWidthBtn.find('i.glyphicon');
    var initialSizeSmall = resizeIcon.hasClass('glyphicon-resize-full');

    toggleWidthBtn.on('click', function(){
        if(resizeIcon.hasClass('glyphicon-resize-full')){
            resizeWindowFull();
            $.ajax('/admin/set_admin_portal_width', {data: {'size': 'full'}});
        }else{
            resizeWindowSmall();
            $.ajax('/admin/set_admin_portal_width', {data: {'size': 'small'}});
        }
        return false;
    });

    $( window ).resize(function() {
        if($( window ).width() < 993 && initialSizeSmall){
            resizeWindowFull();
        }

        if($( window ).width() > 994 && initialSizeSmall){
            resizeWindowSmall();
        }
    });

    function resizeWindowFull(){
        $(".container").switchClass('container', "container-fluid", 500, "easeOutSine");
        resizeIcon.removeClass('glyphicon-resize-full').addClass('glyphicon-resize-small');
    }

    function resizeWindowSmall(){
        $(".container-fluid").switchClass('container-fluid', "container", 500, "easeOutSine");
        resizeIcon.removeClass('glyphicon-resize-small').addClass('glyphicon-resize-full');
    }

    $(window).trigger('resize');
})(jQuery);

$.fn.select2.defaults.set( "theme", "bootstrap" );
$.fn.modal.Constructor.prototype.enforceFocus = function() {
    $(document)
        .off('focusin.bs.modal') // guard against infinite focus loop
        .on('focusin.bs.modal', $.proxy(function (e) {
            if (this.$element[0] !== e.target && !this.$element.has(e.target).length
                    // add whatever conditions you need here:
                && !$(e.target).hasClass('select2-input')
                && !$(e.target.parentNode).hasClass('cke')
            ) {
                this.$element.blur(); //fix for IE (focus to blur for IE 11)
            }
        }, this))
};<commit_msg>use graduated chrome only fallback for modal fenster height<commit_after>function createInitCmsMessageBox(status, message) {
    status = status == 'error'?'danger':status;
    var messageHtml = '
×' + message + '
';

    jQuery('.notice-block').html(messageHtml);
}

function trim(str) {
    str = str.replace(/^\s+/, '');
    for (var i = str.length - 1; i >= 0; i--) {
        if (/\S/.test(str.charAt(i))) {
            str = str.substring(0, i + 1);
            break;
        }
    }
    return str;
}

function uploadError(xhr) {
    alert(xhr.error);
}
(function ($) {

    // Opera 8.0+
    var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;

    // Firefox 1.0+
    var isFirefox = typeof InstallTrigger !== 'undefined';

    // Safari 3.0+ "[object HTMLElementConstructor]"
    var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) {
        return p.toString() === "[object SafariRemoteNotification]";
    })(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification));

    // Internet Explorer 6-11
    var isIE = /*@cc_on!@*/false || !!document.documentMode;

    // Edge 20+
    var isEdge = !isIE && !!window.StyleMedia;

    // Chrome 1+
    var isChrome = !!window.chrome && !!window.chrome.webstore;

    var noticeBlock = $('.notice-block');

    noticeBlock.on('DOMNodeInserted', function () {
        $(this).fadeIn().delay('3000').fadeOut(500);
    });

    noticeBlock.each(function (k, e) {
        if (trim($(e).html()) != '') {
            $(e).fadeIn().delay('3000').fadeOut(500);
        }
    });

    $('.show-tooltip, [data-toggle="tooltip"]').tooltip({placement:'bottom', container: 'body', delay:{ show:800, hide:100 }});

    var openModals = [];

    $(document).on('shown.bs.modal', '.modal', function (e) {
        var modalBody = $(this).find('.modal-body');
        modalBody.css('overflow-y', 'auto');
        modalBody.css('max-height', 'calc(55vh)');
        if(isChrome){
            var windowHeight = $(window).height();
            if(windowHeight > 860){
                modalBody.css('max-height', '70vh');
            }else if(windowHeight > 740){
                modalBody.css('max-height', '65vh');
            }else if(windowHeight > 640){
                modalBody.css('max-height', '60vh');
            }else{
                modalBody.css('max-height', '55vh');
            }
        }else{
            modalBody.css('max-height', '70vh');
        }

        openModals.push($(this).attr('id'));
    }).on('hide.bs.modal', '.modal', function(){
        var index = openModals.indexOf($(this).attr('id'));
        if (index > -1) {
            openModals.splice(index, 1);
        }
    }).on('hidden.bs.modal', function(){
        if(openModals.length > 0){
            $('body').addClass('modal-open');
        }
    });

    // handle the #toggle click event
    $("#toggleNav").on("click", function () {
        // apply/remove the active class to the row-offcanvas element
        $(".row-offcanvas").toggleClass("active");
        return false;
    });
    var toggleWidthBtn = $('#toggleWidth');
    var resizeIcon = toggleWidthBtn.find('i.glyphicon');
    var initialSizeSmall = resizeIcon.hasClass('glyphicon-resize-full');

    toggleWidthBtn.on('click', function(){
        if(resizeIcon.hasClass('glyphicon-resize-full')){
            resizeWindowFull();
            $.ajax('/admin/set_admin_portal_width', {data: {'size': 'full'}});
        }else{
            resizeWindowSmall();
            $.ajax('/admin/set_admin_portal_width', {data: {'size': 'small'}});
        }
        return false;
    });

    $( window ).resize(function() {
        if($( window ).width() < 993 && initialSizeSmall){
            resizeWindowFull();
        }

        if($( window ).width() > 994 && initialSizeSmall){
            resizeWindowSmall();
        }
    });

    function resizeWindowFull(){
        $(".container").switchClass('container', "container-fluid", 500, "easeOutSine");
        resizeIcon.removeClass('glyphicon-resize-full').addClass('glyphicon-resize-small');
    }

    function resizeWindowSmall(){
        $(".container-fluid").switchClass('container-fluid', "container", 500, "easeOutSine");
        resizeIcon.removeClass('glyphicon-resize-small').addClass('glyphicon-resize-full');
    }

    $(window).trigger('resize');
})(jQuery);

$.fn.select2.defaults.set( "theme", "bootstrap" );
$.fn.modal.Constructor.prototype.enforceFocus = function() {
    $(document)
        .off('focusin.bs.modal') // guard against infinite focus loop
        .on('focusin.bs.modal', $.proxy(function (e) {
            if (this.$element[0] !== e.target && !this.$element.has(e.target).length
                    // add whatever conditions you need here:
                && !$(e.target).hasClass('select2-input')
                && !$(e.target.parentNode).hasClass('cke')
            ) {
                this.$element.blur(); //fix for IE (focus to blur for IE 11)
            }
        }, this))
};<|endoftext|>


<commit_before>import React from 'react'
import QuickInterface from 'quick-interface'
import {transaction} from 'afflatus'
import {Panel} from 'react-matterkit'
import {createNameSettings} from '../utils'
import OverlayPanel from './OverlayPanel'

export default class TimelineSelector extends React.Component {
  render () {
    const {state} = BETON.require('project-manager')
    const {onRequestClose} = this.props

    function selectProjectAndTimeline(item) {
      const {state} = BETON.require('project-manager')

      if (item.type === 'Project' && state.currentProject === item) {
        return
      }

      const [project, timeline] = item.type === 'Project'
        ? [item, item.timelines[0]]
        : [item.parent('Project'), item]

      transaction(() => {
        state.currentProject = project
        project.currentTimeline = timeline
      })

      onRequestClose()
    }

    function addTimeline(project) {
      transaction(() => {
        const timeline = project.addTimeline({name: 'new-timeline'})
        selectProjectAndTimeline(timeline)
      })

      onRequestClose()
    }

    function createTimelineSettings(timeline) {
      const {state} = BETON.require('project-manager')
      return {
        describeRow: () => ({
          onClick: () => selectProjectAndTimeline(timeline),
          items: [
            createNameSettings(timeline),
            {
              type: 'button',
              describe: () => ({
                icon: 'cancel',
                tooltip: 'delete this timeline',
                onClick: () => {}
              }),
            }
          ],
          highlighted: state.currentTimeline === timeline,
          contextMenu: {
            items: [
              {
                label: 'rename',
                onClick: () => {
                  timeline.isRenaming = true
                }
              }
            ]
          }
        })
      }
    }

    function createProjectSettings(project) {
      const {state} = BETON.require('project-manager')
      return {
        open: true,
        describeRow: () => ({
          onClick: () => selectProjectAndTimeline(project),
          items: [
            createNameSettings(project),
            {
              type: 'button',
              describe: () => ({
                icon: 'plus',
                tooltip: 'add a new timeline to this project',
                onClick: () => addTimeline(project)
              }),
            }
          ],
          highlighted: state.currentProject === project,
          contextMenu: {
            items: [
              {
                label: 'new timeline',
                icon: 'plus',
                onClick: () => addTimeline(project)
              }, {
                label: 'rename',
                onClick: () => {
                  project.isRenaming = true
                }
              }
            ]
          },
        }),
        describeChildren: () => project.timelines.map(timeline => (
          <QuickInterface
            key = {timeline.uid}
            describe = {() => createTimelineSettings(timeline)}/>
        ))
      }
    }

    const renderProjects = projects => {
      return projects
        .map(project => (
          <QuickInterface {...{
            key: project.uid,
            describe: () => createProjectSettings(project)
          }}/>
        ))
    }

    return (
      <OverlayPanel>
        <QuickInterface
          describe={() => ({
            hiddenHead: true,
            describeChildren: () => renderProjects(state.projects)
          })}
        />
      </OverlayPanel>
    )
  }
}
<commit_msg>fix timeline adding and renaming<commit_after>import React from 'react'
import QuickInterface from 'quick-interface'
import {transaction} from 'afflatus'
import {Panel} from 'react-matterkit'
import {createNameSettings} from '../utils'
import OverlayPanel from './OverlayPanel'

export default class TimelineSelector extends React.Component {
  render () {
    const {state} = BETON.require('project-manager')
    const {onRequestClose} = this.props

    function selectProjectAndTimeline(item) {
      const {state} = BETON.require('project-manager')

      if (item.type === 'Project' && state.currentProject === item) {
        return
      }

      const [project, timeline] = item.type === 'Project'
        ? [item, item.timelines[0]]
        : [item.parent('Project'), item]

      transaction(() => {
        state.currentProject = project
        project.currentTimeline = timeline
      })

      // onRequestClose()
    }

    function addTimeline(project) {
      transaction(() => {
        const timeline = project.addTimeline({name: 'new-timeline'})
        timeline.isRenaming = true
        selectProjectAndTimeline(timeline)
      })

      // onRequestClose()
    }

    function createTimelineSettings(timeline) {
      const {state} = BETON.require('project-manager')
      return {
        describeRow: () => ({
          onClick: () => selectProjectAndTimeline(timeline),
          items: [
            createNameSettings(timeline),
            {
              type: 'button',
              describe: () => ({
                icon: 'cancel',
                tooltip: 'delete this timeline',
                onClick: () => {}
              }),
            }
          ],
          highlighted: state.currentTimeline === timeline,
          contextMenu: {
            items: [
              {
                label: 'rename',
                onClick: () => {
                  timeline.isRenaming = true
                }
              }
            ]
          }
        })
      }
    }

    function createProjectSettings(project) {
      const {state} = BETON.require('project-manager')
      return {
        open: true,
        describeRow: () => ({
          onClick: () => selectProjectAndTimeline(project),
          items: [
            createNameSettings(project),
            {
              type: 'button',
              describe: () => ({
                icon: 'plus',
                tooltip: 'add a new timeline to this project',
                onClick: () => addTimeline(project)
              }),
            }
          ],
          highlighted: state.currentProject === project,
          contextMenu: {
            items: [
              {
                label: 'new timeline',
                icon: 'plus',
                onClick: () => addTimeline(project)
              }, {
                label: 'rename',
                onClick: () => {
                  project.isRenaming = true
                }
              }
            ]
          },
        }),
        describeChildren: () => project.timelines.map(timeline => (
          <QuickInterface
            key = {timeline.uid}
            describe = {() => createTimelineSettings(timeline)}/>
        ))
      }
    }

    const renderProjects = projects => {
      return projects
        .map(project => (
          <QuickInterface {...{
            key: project.uid,
            describe: () => createProjectSettings(project)
          }}/>
        ))
    }

    return (
      <OverlayPanel>
        <QuickInterface
          describe={() => ({
            hiddenHead: true,
            describeChildren: () => renderProjects(state.projects)
          })}
        />
      </OverlayPanel>
    )
  }
}
<|endoftext|>


<commit_before>///<reference path="Order.js"/>
//Self-Executing Anonymous Function
//Adding New Functionality to Purchasing for Edit
(function (purchasing, $, undefined) {
    "use strict";
    //Private Property
    var lineItemAndSplitSections = "#line-items-section, #order-split-section, #order-account-section";

    //Public Method
    purchasing.initEdit = function () {
        loadLineItemsAndSplits({ disableModification: true });
        attachModificationEvents();
    };

    //Public Method
    purchasing.initCopy = function () {
        loadLineItemsAndSplits({ disableModification: false });
    };

    function loadLineItemsAndSplits(options) {
        $.getJSON(purchasing._getOption("GetLineItemsAndSplitsUrl"), null, function (result) {
            //manual mapping for now.  can look into mapping plugin later
            var model = purchasing.OrderModel;
            model.items.removeAll();
            model.splitType(result.splitType);
            model.shipping(purchasing.displayAmount(result.orderDetail.Shipping));
            model.freight(purchasing.displayAmount(result.orderDetail.Freight));
            model.tax(purchasing.displayPercent(result.orderDetail.Tax));

            purchasing.OrderModel.disableSubaccountLoading = true; //Don't search subaccounts when loading existing selections
            $.each(result.lineItems, function (index, lineResult) {
                var lineItem = new purchasing.LineItem(index, model);

                lineItem.quantity(lineResult.Quantity);
                lineItem.unit(lineResult.Units);
                lineItem.desc(lineResult.Description);
                lineItem.price(lineResult.Price);
                lineItem.catalogNumber(lineResult.CatalogNumber);

                lineItem.commodity(lineResult.CommodityCode);
                lineItem.url(lineResult.Url);
                lineItem.note(lineResult.Notes);

                if (lineItem.hasDetails()) {
                    lineItem.showDetails(true);
                }

                if (model.splitType() === "Line") {
                    $.each(result.splits, function (i, split) {
                        if (split.LineItemId === lineResult.Id) {
                            //Add split because it's for this line
                            var newSplit = new purchasing.LineSplit(model.lineSplitCount(), lineItem);

                            addAccountIfNeeded(split.Account, split.AccountName);
                            addSubAccountIfNeeded(split.SubAccount, newSplit.subAccounts);

                            newSplit.amountComputed(split.Amount);
                            newSplit.account(split.Account);
                            newSplit.subAccount(split.SubAccount);
                            newSplit.project(split.Project);

                            lineItem.splits.push(newSplit);
                        }
                    });
                }

                model.items.push(lineItem);
            });

            //Lines are in, now add Order splits if needed
            if (model.splitType() === "Order") {
                $.each(result.splits, function (i, split) {
                    //Create a new split, index starting at 0, and the model is the order/$root
                    var newSplit = new purchasing.OrderSplit(i, model);

                    addAccountIfNeeded(split.Account, split.AccountName);
                    addSubAccountIfNeeded(split.SubAccount, newSplit.subAccounts);

                    newSplit.amountComputed(split.Amount);
                    newSplit.account(split.Account);
                    newSplit.subAccount(split.SubAccount);
                    newSplit.project(split.Project);

                    model.splits.push(newSplit);
                });
            }

            //Add the basic account info if there are no splits (aka just one split)
            if (model.splitType() === "None") {
                var singleSplit = result.splits[0];
                addAccountIfNeeded(singleSplit.Account, singleSplit.AccountName);
                addSubAccountIfNeeded(split.SubAccount, model.subAccounts);

                model.account(singleSplit.Account);
                model.subAccount(singleSplit.SubAccount);
                model.project(singleSplit.Project);
            }

            $(".account-number").change(); //notify that account numbers were changed to update tip UI

            if (options.disableModification) {
                disableLineItemAndSplitModification();
            }

            purchasing.OrderModel.disableSubaccountLoading = false; //Turn auto subaccount loading back on now that we are finished
        });
    }

    //If the account is not in list of accounts, add it
    function addAccountIfNeeded(account, accountName) {
        if (account) {
            var accountIfFound = ko.utils.arrayFirst(purchasing.OrderModel.accounts(), function (item) {
                return item.id === account;
            });

            if (accountIfFound === null) { //not found, add to list
                purchasing.OrderModel.addAccount(account, account, accountName);
            }
        }
    }

    //If the subAccount is not in the associated subAccount list, add it
    function addSubAccountIfNeeded(subAccount, subAccounts) {
        if (subAccount) {
            var subAccountIfFound = ko.utils.arrayFirst(subAccounts(), function (item) {
                return item === subAccount;
            });

            if (subAccountIfFound === null) { //not found, add to list
                subAccounts.push(subAccount);
            }
        }
    }

    function attachModificationEvents() {
        $("#item-modification-template").tmpl({}).insertBefore("#line-items-section");

        purchasing.updateNav(); //Update navigation now that we inserted a new section

        $("#item-modification-button").click(function (e, data) {
            e.preventDefault();

            var automate = data === undefined ? false : data.automate;

            if (!automate && !confirm(purchasing.getMessage("ConfirmModification"))) {
                return;
            }

            enableLineItemAndSplitModification();
        });
    }

    function disableLineItemAndSplitModification() {
        $(":input", lineItemAndSplitSections).attr("disabled", "disabled");
        $("a.button, a.biggify", lineItemAndSplitSections).hide();
        purchasing.OrderModel.adjustRouting("False");
    }

    function enableLineItemAndSplitModification() {
        $(":input", lineItemAndSplitSections).removeAttr("disabled");
        $("a.button, a.biggify", lineItemAndSplitSections).show();
        $("#item-modification-section").hide();

        //adjust the routing and for a reevaluation of the the split type so the UI updates
        purchasing.OrderModel.adjustRouting("True");
        purchasing.OrderModel.splitType.valueHasMutated();
    }

    purchasing.lowerCaseFirstLetter = function (w) {
        return w.charAt(0).toLowerCase() + w.slice(1);
    };

    purchasing.selectListContainsValue = function ($select, val) {
        var exists = false;
        $select.find("option").each(function () {
            if (this.value === val) {
                exists = true;
            }
        });

        return exists;
    };

} (window.purchasing = window.purchasing || {}, jQuery));
<commit_msg>edit/copy now tracks split indexes properly<commit_after>///<reference path="Order.js"/>
//Self-Executing Anonymous Function
//Adding New Functionality to Purchasing for Edit
(function (purchasing, $, undefined) {
    "use strict";
    //Private Property
    var lineItemAndSplitSections = "#line-items-section, #order-split-section, #order-account-section";

    //Public Method
    purchasing.initEdit = function () {
        loadLineItemsAndSplits({ disableModification: true });
        attachModificationEvents();
    };

    //Public Method
    purchasing.initCopy = function () {
        loadLineItemsAndSplits({ disableModification: false });
    };

    function loadLineItemsAndSplits(options) {
        $.getJSON(purchasing._getOption("GetLineItemsAndSplitsUrl"), null, function (result) {
            //manual mapping for now.  can look into mapping plugin later
            var model = purchasing.OrderModel;
            model.items.removeAll();
            model.splitType(result.splitType);
            model.shipping(purchasing.displayAmount(result.orderDetail.Shipping));
            model.freight(purchasing.displayAmount(result.orderDetail.Freight));
            model.tax(purchasing.displayPercent(result.orderDetail.Tax));

            purchasing.OrderModel.disableSubaccountLoading = true; //Don't search subaccounts when loading existing selections
            $.each(result.lineItems, function (index, lineResult) {
                var lineItem = new purchasing.LineItem(index, model);

                lineItem.quantity(lineResult.Quantity);
                lineItem.unit(lineResult.Units);
                lineItem.desc(lineResult.Description);
                lineItem.price(lineResult.Price);
                lineItem.catalogNumber(lineResult.CatalogNumber);

                lineItem.commodity(lineResult.CommodityCode);
                lineItem.url(lineResult.Url);
                lineItem.note(lineResult.Notes);

                if (lineItem.hasDetails()) {
                    lineItem.showDetails(true);
                }

                if (model.splitType() === "Line") {
                    var lineSplitCount = model.lineSplitCount(); //keep starting split count, and increment until we push the lineItem
                    $.each(result.splits, function (i, split) {
                        if (split.LineItemId === lineResult.Id) {
                            //Add split because it's for this line
                            var newSplit = new purchasing.LineSplit(lineSplitCount++, lineItem);

                            addAccountIfNeeded(split.Account, split.AccountName);
                            addSubAccountIfNeeded(split.SubAccount, newSplit.subAccounts);

                            newSplit.amountComputed(split.Amount);
                            newSplit.account(split.Account);
                            newSplit.subAccount(split.SubAccount);
                            newSplit.project(split.Project);

                            lineItem.splits.push(newSplit);
                        }
                    });
                }

                model.items.push(lineItem);
            });

            //Lines are in, now add Order splits if needed
            if (model.splitType() === "Order") {
                $.each(result.splits, function (i, split) {
                    //Create a new split, index starting at 0, and the model is the order/$root
                    var newSplit = new purchasing.OrderSplit(i, model);

                    addAccountIfNeeded(split.Account, split.AccountName);
                    addSubAccountIfNeeded(split.SubAccount, newSplit.subAccounts);

                    newSplit.amountComputed(split.Amount);
                    newSplit.account(split.Account);
                    newSplit.subAccount(split.SubAccount);
                    newSplit.project(split.Project);

                    model.splits.push(newSplit);
                });
            }

            //Add the basic account info if there are no splits (aka just one split)
            if (model.splitType() === "None") {
                var singleSplit = result.splits[0];
                addAccountIfNeeded(singleSplit.Account, singleSplit.AccountName);
                addSubAccountIfNeeded(split.SubAccount, model.subAccounts);

                model.account(singleSplit.Account);
                model.subAccount(singleSplit.SubAccount);
                model.project(singleSplit.Project);
            }

            $(".account-number").change(); //notify that account numbers were changed to update tip UI

            if (options.disableModification) {
                disableLineItemAndSplitModification();
            }

            purchasing.OrderModel.disableSubaccountLoading = false; //Turn auto subaccount loading back on now that we are finished
        });
    }

    //If the account is not in list of accounts, add it
    function addAccountIfNeeded(account, accountName) {
        if (account) {
            var accountIfFound = ko.utils.arrayFirst(purchasing.OrderModel.accounts(), function (item) {
                return item.id === account;
            });

            if (accountIfFound === null) { //not found, add to list
                purchasing.OrderModel.addAccount(account, account, accountName);
            }
        }
    }

    //If the subAccount is not in the associated subAccount list, add it
    function addSubAccountIfNeeded(subAccount, subAccounts) {
        if (subAccount) {
            var subAccountIfFound = ko.utils.arrayFirst(subAccounts(), function (item) {
                return item === subAccount;
            });

            if (subAccountIfFound === null) { //not found, add to list
                subAccounts.push(subAccount);
            }
        }
    }

    function attachModificationEvents() {
        $("#item-modification-template").tmpl({}).insertBefore("#line-items-section");

        purchasing.updateNav(); //Update navigation now that we inserted a new section

        $("#item-modification-button").click(function (e, data) {
            e.preventDefault();

            var automate = data === undefined ? false : data.automate;

            if (!automate && !confirm(purchasing.getMessage("ConfirmModification"))) {
                return;
            }

            enableLineItemAndSplitModification();
        });
    }

    function disableLineItemAndSplitModification() {
        $(":input", lineItemAndSplitSections).attr("disabled", "disabled");
        $("a.button, a.biggify", lineItemAndSplitSections).hide();
        purchasing.OrderModel.adjustRouting("False");
    }

    function enableLineItemAndSplitModification() {
        $(":input", lineItemAndSplitSections).removeAttr("disabled");
        $("a.button, a.biggify", lineItemAndSplitSections).show();
        $("#item-modification-section").hide();

        //adjust the routing and for a reevaluation of the the split type so the UI updates
        purchasing.OrderModel.adjustRouting("True");
        purchasing.OrderModel.splitType.valueHasMutated();
    }

    purchasing.lowerCaseFirstLetter = function (w) {
        return w.charAt(0).toLowerCase() + w.slice(1);
    };

    purchasing.selectListContainsValue = function ($select, val) {
        var exists = false;
        $select.find("option").each(function () {
            if (this.value === val) {
                exists = true;
            }
        });

        return exists;
    };

} (window.purchasing = window.purchasing || {}, jQuery));
<|endoftext|>


<commit_before>function _gaLt(event) {

    /* If GA is blocked or not loaded, or not main|middle|touch click then don't track */
    if (!ga.hasOwnProperty("loaded") || ga.loaded != true || (event.which != 1 && event.which != 2)) {
        return;
    }

    var el = event.srcElement || event.target;

    /* Loop up the DOM tree through parent elements if clicked element is not a link (eg: an image inside a link) */
    while (el && (typeof el.tagName == 'undefined' || el.tagName.toLowerCase() != 'a' || !el.href)) {
        el = el.parentNode;
    }

    /* if a link with valid href has been clicked */
    if (el && el.href) {

        var link = el.href;

        /* Only if it is an external link */
        if (link.indexOf(location.host) == -1 && !link.match(/^javascript\:/i)) {

            /* Is actual target set and not _(self|parent|top)? */
            var target = (el.target && !el.target.match(/^_(self|parent|top)$/i)) ? el.target : false;

            /* Assume a target if Ctrl|shift|meta-click */
            if (event.ctrlKey || event.shiftKey || event.metaKey || event.which == 2) {
                target = "_blank";
            }

            var hbrun = false; // tracker has not yet run

            /* HitCallback to open link in same window after tracker */
            var hitBack = function() {
                /* run once only */
                if (hbrun) return;
                hbrun = true;
                window.location.href = link;
            };

            if (target) { /* If target opens a new window then just track */
                ga(
                    "send", "event", "Outgoing Links", link,
                    document.location.pathname + document.location.search
                );
            } else { /* Prevent standard click, track then open */
                event.preventDefault ? event.preventDefault() : event.returnValue = !1;
                /* send event with callback */
                ga(
                    "send", "event", "Outgoing Links", link,
                    document.location.pathname + document.location.search, {
                        "hitCallback": hitBack
                    }
                );

                /* Run hitCallback again if GA takes longer than 1 second */
                setTimeout(hitBack, 1000);
            }
        }
    }
}

var _w = window;
/* Use "click" if touchscreen device, else "mousedown" */
var _gaLtEvt = ("ontouchstart" in _w) ? "click" : "mousedown";
/* Attach the event to all clicks in the document after page has loaded */
_w.addEventListener ? _w.addEventListener("load", function() {document.body.addEventListener(_gaLtEvt, _gaLt, !1)}, !1)
    : _w.attachEvent && _w.attachEvent("onload", function() {document.body.attachEvent("on" + _gaLtEvt, _gaLt)});
<commit_msg>Fix outbound tracking script<commit_after>function _gaLt(event) {

    /* If GA is blocked or not loaded, or not main|middle|touch click then don't track */
    if (!ga.hasOwnProperty("loaded") || ga.loaded != true || (event.which != 1 && event.which != 2)) {
        return;
    }

    var el = event.srcElement || event.target;

    /* Loop up the DOM tree through parent elements if clicked element is not a link (eg: an image inside a link) */
    while (el && (typeof el.tagName == 'undefined' || el.tagName.toLowerCase() != 'a' || !el.href)) {
        el = el.parentNode;
    }

    /* if a link with valid href has been clicked */
    if (el && el.href) {

        var link = el.href;

        /* Only if it is an external link */
        if ((link.indexOf(location.host) == -1 || link.indexOf('.' + location.host) > 0) && !link.match(/^javascript\:/i)) {

            /* Is actual target set and not _(self|parent|top)? */
            var target = (el.target && !el.target.match(/^_(self|parent|top)$/i)) ? el.target : false;

            /* Assume a target if Ctrl|shift|meta-click */
            if (event.ctrlKey || event.shiftKey || event.metaKey || event.which == 2) {
                target = "_blank";
            }

            var hbrun = false; // tracker has not yet run

            /* HitCallback to open link in same window after tracker */
            var hitBack = function() {
                /* run once only */
                if (hbrun) return;
                hbrun = true;
                window.location.href = link;
            };

            if (target) { /* If target opens a new window then just track */
                ga(
                    "send", "event", "Outgoing Links", link,
                    document.location.pathname + document.location.search
                );
            } else { /* Prevent standard click, track then open */
                event.preventDefault ? event.preventDefault() : event.returnValue = !1;
                /* send event with callback */
                ga(
                    "send", "event", "Outgoing Links", link,
                    document.location.pathname + document.location.search, {
                        "hitCallback": hitBack
                    }
                );

                /* Run hitCallback again if GA takes longer than 1 second */
                setTimeout(hitBack, 1000);
            }
        }
    }
}

var _w = window;
/* Use "click" if touchscreen device, else "mousedown" */
var _gaLtEvt = ("ontouchstart" in _w) ? "click" : "mousedown";
/* Attach the event to all clicks in the document after page has loaded */
_w.addEventListener ? _w.addEventListener("load", function() {document.body.addEventListener(_gaLtEvt, _gaLt, !1)}, !1)
    : _w.attachEvent && _w.attachEvent("onload", function() {document.body.attachEvent("on" + _gaLtEvt, _gaLt)});
<|endoftext|>