<commit_before>(function($) {
  $(document).ready(function() {
    /*-------------------- EXPANDABLE PANELS ----------------------*/
    var panelspeed = 500; //panel animate speed in milliseconds
    var totalpanels = 37; //total number of collapsible panels
    var defaultopenpanel = 0; //leave 0 for no panel open
    var accordian = true; //set panels to behave like an accordian, with one panel only ever open at once
    var panelheight = new Array();
    var currentpanel = defaultopenpanel;
    var iconheight = parseInt($('.icon-close-open').css('height'));
    var highlightopen = true;
    var panelCounts = [8, 9, 10, 9, 7, 7, 4, 5, 5, 5,
                       5, 5, 6, 6, 6, 6, 5, 7, 7, 7,
                       7, 6, 1, 4, 4, 4, 1, 10, 11, 10,
                       11, 4, 10, 12, 17, 11, 11]

    // Hash Step 1: On Page Load, read URL hash and parse it, checking boxes where available.
    var numStories = 263;
    var hashLen = Math.ceil(numStories / 5);
    // read hash string from URL
    var hash = (window.location.hash.slice(1) + "00000000000000000000000000000000000000000000000000000").substr(0, hashLen);

    // set the N-th character in a string (strings are zero-indexed)
    function setCharAt(str, index, chr) {
      if (index > str.length - 1) return str;
      return str.substr(0, index) + chr + str.substr(index + 1);
    }

    // Initialize checkbox states
    function checkboxInit() {
      var hashChar = '';
      var hashBin = '';
      var hashBit = '';
      var storyIndex = 0;
      var totalInit = 0;
      var userCountInit = 0;

      // loop through each character in the hash string
      for (i = 0; i < hashLen; i++) {
        hashChar = hash[i];
        hashBin = ('00000' + parseInt(hashChar, 36).toString(2)).substring(-5);
        // loop through each bit in the 5-bit hash letter
        for (j = 1; j <= 5; j++) {
          storyIndex = 5 * i + j;
          if (storyIndex > numStories) {
            break;
          }
          hashBit = hashBin[hashBin.length - j];
          if (hashBit == '1') {
            document.getElementById('story' + storyIndex).checked = true;
            userCountInit = document.getElementById(document.getElementById('story' + storyIndex).className + "-userCount");
            userCountInit.value = parseInt(userCountInit.value) + 1;
            totalInit += 1;
          } else {
            document.getElementById('story' + storyIndex).checked = false;
          }
        }
      }

      // init count and Q at top of page
      document.getElementById('total').value = '' + Math.round(totalInit);
      document.getElementById('q').value = formatDecimal(totalInit / numStories);

      // init counter labels
      var panUseCount = 0;
      var panTotal = 1;
      var panLabel = '';
      for (var k=1; k <= totalpanels; k++) {
        panUseCount = parseInt(document.getElementById("cp-" + k.toString() + "-panel-userCount").value);
        panTotal = parseInt(panelCounts[k - 1]);
        panLabel = document.getElementById("cp-" + k.toString() + "-panelLabel");
        if (panUseCount == 0) {
          panLabel.innerHTML = "";
        } else if (panUseCount == panTotal) {
          panLabel.innerHTML = "✔";
        } else {
          panLabel.innerHTML = "(" + panUseCount.toString() + "/" + panTotal.toString() + ")";
        }
      }
    }

    // Initialise collapsible panels
    function panelinit() {
      for (var i = 1; i <= totalpanels; i++) {
        panelheight[i] = parseInt($('#cp-' + i).find('.expandable-panel-content').css('height'));
        $('#cp-' + i).find('.expandable-panel-content').css('margin-top', -panelheight[i]);
        if (defaultopenpanel == i) {
          $('#cp-' + i).find('.icon-close-open').css('background-position', '0px -' + iconheight + 'px');
          $('#cp-' + i).find('.expandable-panel-content').css('margin-top', 0);
        }
      }

      // init user count value for each panel
      for (var k=1; k <= totalpanels; k++) {
          document.getElementById("cp-" + k.toString() + "-panel-userCount").value = 0;
      }
    }

    $('.expandable-panel-heading').click(function() {
      var obj = $(this).next();
      var objid = parseInt($(this).parent().attr('ID').substr(3, 2));
      currentpanel = objid;
      if (accordian == true) {
        resetpanels();
      }

      if (parseInt(obj.css('margin-top')) <= (panelheight[objid] * -1)) {
        obj.clearQueue();
        obj.stop();
        obj.prev().find('.icon-close-open').css('background-position', '0px -' + iconheight + 'px');
        obj.animate({
          'margin-top': 0
        }, panelspeed);
        if (highlightopen == true) {
          $('#cp-' + currentpanel + ' .expandable-panel-heading').addClass('header-active');
        }
      } else {
        obj.clearQueue();
        obj.stop();
        obj.prev().find('.icon-close-open').css('background-position', '0px 0px');
        obj.animate({
          'margin-top': (panelheight[objid] * -1)
        }, panelspeed);
        if (highlightopen == true) {
          $('#cp-' + currentpanel + ' .expandable-panel-heading').removeClass('header-active');
        }
      }
    });

    function resetpanels() {
      for (var i = 1; i <= totalpanels; i++) {
        if (currentpanel != i) {
          $('#cp-' + i).find('.icon-close-open').css('background-position', '0px 0px');
          $('#cp-' + i).find('.expandable-panel-content').animate({
            'margin-top': -panelheight[i]
          }, panelspeed);
          if (highlightopen == true) {
            $('#cp-' + i + ' .expandable-panel-heading').removeClass('header-active');
          }
        }
      }
    }

    //Uncomment these lines if the expandable panels are not a fixed width and need to resize
    /* $( window ).resize(function() {
       panelinit();
     });*/

    $(window).load(function() {
      panelinit();
      checkboxInit();
    }); //END LOAD

    // call onload or in script segment below form
    function attachCheckboxHandlers() {
      // assign updateTotal function to onclick property of each checkbox
      for (var i = 1, len = numStories; i <= len; i++) {
        box = document.getElementById('story' + i);
        box.onclick = updateTotal;
      }
    }

    // called onclick of toppings checkboxes
    function updateTotal(e) {
      // 'this' is reference to checkbox clicked on
      var form = this.form;

      // get current value in total text box, using parseFloat since it is a string
      var total = parseFloat(form.elements['total'].value);

      // if check box is checked, add its value to val, otherwise subtract it
      if (this.checked) {
        total += 1.0;
      } else {
        total -= 1.0;
      }

      // format val with correct number of decimal places
      // and use it to update value of total text box
      form.elements['total'].value = '' + Math.round(total);
      form.elements['q'].value = formatDecimal(total / numStories);

      // Hash Step 2: On box (un)check, change hash value in URL.
      var storyNumber = parseInt(this.id.split("story")[1]);
      var hashPosition = Math.floor((storyNumber - 1) / 5);
      var thisBinary = ('00000' + parseInt(hash[hashPosition], 36).toString(2)).substr(-5);
      var binaryPosition = 5 - (storyNumber % 5);
      if (binaryPosition == 5) {
        binaryPosition = 0;
      }

      if (document.getElementById(this.id).checked) {
        thisBinary = setCharAt(thisBinary, binaryPosition, '1');
      } else {
        thisBinary = setCharAt(thisBinary, binaryPosition, '0');
      }
      hash = setCharAt(hash, hashPosition, parseInt(thisBinary, 2).toString(36));
      window.location.hash = hash;

      // Update panel Count
      var panelName = this.className
      var panelLabel = document.getElementById(panelName + "Label");
      var panelUserCount = document.getElementById(panelName + "-userCount");
      var panelTotal = parseInt(panelCounts[panelName.split('-')[1] - 1]);
      if (document.getElementById(this.id).checked) {
        panelUserCount.value = parseInt(panelUserCount.value) + 1;
      } else {
        panelUserCount.value = parseInt(panelUserCount.value) - 1;
      }
      if (panelUserCount.value == 0) {
          panelLabel.innerHTML = "";
      } else if (panelUserCount.value == panelTotal) {
          panelLabel.innerHTML = "✔";
      } else {
          panelLabel.innerHTML = "(" + panelUserCount.value.toString() + "/" + panelTotal.toString() + ")";
      }
    }

    // format val to n number of decimal places
    // modified version of Danny Goodman's (JS Bible)
    function formatDecimal(val, n) {
      n = n || 2;
      var str = "" + Math.round(parseFloat(val) * Math.pow(10, n));
      while (str.length <= n) {
        str = "0" + str;
      }
      var pt = str.length - n;
      return str.slice(0, pt) + "." + str.slice(pt);
    }

    // in script segment below form
    attachCheckboxHandlers();
  }); //END READY
})(jQuery);
<commit_msg>trying to fix mobile issues<commit_after>(function($) {
  $(document).ready(function() {
    /*-------------------- EXPANDABLE PANELS ----------------------*/
    var panelspeed = 500; //panel animate speed in milliseconds
    var totalpanels = 37; //total number of collapsible panels
    var defaultopenpanel = 0; //leave 0 for no panel open
    var accordian = true; //set panels to behave like an accordian, with one panel only ever open at once
    var panelheight = new Array();
    var currentpanel = defaultopenpanel;
    var iconheight = parseInt($('.icon-close-open').css('height'));
    var highlightopen = true;
    var panelCounts = [8, 9, 10, 9, 7, 7, 4, 5, 5, 5,
                       5, 5, 6, 6, 6, 6, 5, 7, 7, 7,
                       7, 6, 1, 4, 4, 4, 1, 10, 11, 10,
                       11, 4, 10, 12, 17, 11, 11]

    // Hash Step 1: On Page Load, read URL hash and parse it, checking boxes where available.
    var numStories = 263;
    var hashLen = Math.ceil(numStories / 5);
    // read hash string from URL
    var hash = (window.location.hash.slice(1) + "00000000000000000000000000000000000000000000000000000").substr(0, hashLen);

    // set the N-th character in a string (strings are zero-indexed)
    function setCharAt(str, index, chr) {
      if (index > str.length - 1) return str;
      return str.substr(0, index) + chr + str.substr(index + 1);
    }

    // Initialize checkbox states
    function checkboxInit() {
      var hashChar = '';
      var hashBin = '';
      var hashBit = '';
      var storyIndex = 0;
      var totalInit = 0;
      var userCountInit = 0;

      // loop through each character in the hash string
      for (i = 0; i < hashLen; i++) {
        hashChar = hash[i];
        hashBin = ('00000' + parseInt(hashChar, 36).toString(2)).substring(-5);
        // loop through each bit in the 5-bit hash letter
        for (j = 1; j <= 5; j++) {
          storyIndex = 5 * i + j;
          if (storyIndex > numStories) {
            break;
          }
          hashBit = hashBin[hashBin.length - j];
          if (hashBit == '1') {
            document.getElementById('story' + storyIndex).checked = true;
            userCountInit = document.getElementById(document.getElementById('story' + storyIndex).className + "-userCount");
            userCountInit.value = parseInt(userCountInit.value) + 1;
            totalInit += 1;
          } else {
            document.getElementById('story' + storyIndex).checked = false;
          }
        }
      }

      // init count and Q at top of page
      document.getElementById('total').value = '' + Math.round(totalInit);
      document.getElementById('q').value = formatDecimal(totalInit / numStories);

      // init counter labels
      var panUseCount = 0;
      var panTotal = 1;
      var panLabel = '';
      for (var k=1; k <= totalpanels; k++) {
        panUseCount = parseInt(document.getElementById("cp-" + k.toString() + "-panel-userCount").value);
        panTotal = parseInt(panelCounts[k - 1]);
        panLabel = document.getElementById("cp-" + k.toString() + "-panelLabel");
        if (panUseCount == 0) {
          panLabel.innerHTML = "";
        } else if (panUseCount == panTotal) {
          panLabel.innerHTML = "✔";
        } else {
          panLabel.innerHTML = "(" + panUseCount.toString() + "/" + panTotal.toString() + ")";
        }
      }
    }

    // Initialise collapsible panels
    function panelinit() {
      for (var i = 1; i <= totalpanels; i++) {
        panelheight[i] = parseInt($('#cp-' + i).find('.expandable-panel-content').css('height'));
        $('#cp-' + i).find('.expandable-panel-content').css('margin-top', -panelheight[i]);
        if (defaultopenpanel == i) {
          $('#cp-' + i).find('.icon-close-open').css('background-position', '0px -' + iconheight + 'px');
          $('#cp-' + i).find('.expandable-panel-content').css('margin-top', 0);
        }
      }

      // init user count value for each panel
      for (var k=1; k <= totalpanels; k++) {
          document.getElementById("cp-" + k.toString() + "-panel-userCount").value = 0;
      }
    }

    $('.expandable-panel-heading').click(function() {
      var obj = $(this).next();
      var objid = parseInt($(this).parent().attr('ID').substr(3, 2));
      currentpanel = objid;
      if (accordian == true) {
        resetpanels();
      }

      if (parseInt(obj.css('margin-top')) <= (panelheight[objid] * -1)) {
        obj.clearQueue();
        obj.stop();
        obj.prev().find('.icon-close-open').css('background-position', '0px -' + iconheight + 'px');
        obj.animate({
          'margin-top': 0
        }, panelspeed);
        if (highlightopen == true) {
          $('#cp-' + currentpanel + ' .expandable-panel-heading').addClass('header-active');
        }
      } else {
        obj.clearQueue();
        obj.stop();
        obj.prev().find('.icon-close-open').css('background-position', '0px 0px');
        obj.animate({
          'margin-top': (panelheight[objid] * -1)
        }, panelspeed);
        if (highlightopen == true) {
          $('#cp-' + currentpanel + ' .expandable-panel-heading').removeClass('header-active');
        }
      }
    });

    function resetpanels() {
      for (var i = 1; i <= totalpanels; i++) {
        if (currentpanel != i) {
          $('#cp-' + i).find('.icon-close-open').css('background-position', '0px 0px');
          $('#cp-' + i).find('.expandable-panel-content').animate({
            'margin-top': -panelheight[i]
          }, panelspeed);
          if (highlightopen == true) {
            $('#cp-' + i + ' .expandable-panel-heading').removeClass('header-active');
          }
        }
      }
    }

    //Uncomment these lines if the expandable panels are not a fixed width and need to resize
    $( window ).resize(function() {
       panelinit();
     });

    $(window).load(function() {
      panelinit();
      checkboxInit();
    }); //END LOAD

    // call onload or in script segment below form
    function attachCheckboxHandlers() {
      // assign updateTotal function to onclick property of each checkbox
      for (var i = 1, len = numStories; i <= len; i++) {
        box = document.getElementById('story' + i);
        box.onclick = updateTotal;
      }
    }

    // called onclick of toppings checkboxes
    function updateTotal(e) {
      // 'this' is reference to checkbox clicked on
      var form = this.form;

      // get current value in total text box, using parseFloat since it is a string
      var total = parseFloat(form.elements['total'].value);

      // if check box is checked, add its value to val, otherwise subtract it
      if (this.checked) {
        total += 1.0;
      } else {
        total -= 1.0;
      }

      // format val with correct number of decimal places
      // and use it to update value of total text box
      form.elements['total'].value = '' + Math.round(total);
      form.elements['q'].value = formatDecimal(total / numStories);

      // Hash Step 2: On box (un)check, change hash value in URL.
      var storyNumber = parseInt(this.id.split("story")[1]);
      var hashPosition = Math.floor((storyNumber - 1) / 5);
      var thisBinary = ('00000' + parseInt(hash[hashPosition], 36).toString(2)).substr(-5);
      var binaryPosition = 5 - (storyNumber % 5);
      if (binaryPosition == 5) {
        binaryPosition = 0;
      }

      if (document.getElementById(this.id).checked) {
        thisBinary = setCharAt(thisBinary, binaryPosition, '1');
      } else {
        thisBinary = setCharAt(thisBinary, binaryPosition, '0');
      }
      hash = setCharAt(hash, hashPosition, parseInt(thisBinary, 2).toString(36));
      window.location.hash = hash;

      // Update panel Count
      var panelName = this.className
      var panelLabel = document.getElementById(panelName + "Label");
      var panelUserCount = document.getElementById(panelName + "-userCount");
      var panelTotal = parseInt(panelCounts[panelName.split('-')[1] - 1]);
      if (document.getElementById(this.id).checked) {
        panelUserCount.value = parseInt(panelUserCount.value) + 1;
      } else {
        panelUserCount.value = parseInt(panelUserCount.value) - 1;
      }
      if (panelUserCount.value == 0) {
          panelLabel.innerHTML = "";
      } else if (panelUserCount.value == panelTotal) {
          panelLabel.innerHTML = "✔";
      } else {
          panelLabel.innerHTML = "(" + panelUserCount.value.toString() + "/" + panelTotal.toString() + ")";
      }
    }

    // format val to n number of decimal places
    // modified version of Danny Goodman's (JS Bible)
    function formatDecimal(val, n) {
      n = n || 2;
      var str = "" + Math.round(parseFloat(val) * Math.pow(10, n));
      while (str.length <= n) {
        str = "0" + str;
      }
      var pt = str.length - n;
      return str.slice(0, pt) + "." + str.slice(pt);
    }

    // in script segment below form
    attachCheckboxHandlers();
  }); //END READY
})(jQuery);
<|endoftext|>


<commit_before>function add(a , b){
    return a + b;
}
function subtract(x , y){
    return x - y;
}
var multiplication = function(a, b){
    return (a * b);
};
var division = function(a, b){
    return (a / b);
};
<commit_msg>modulus function<commit_after>function add(a , b){
    return a + b;
}
function subtract(x , y){
    return x - y;
}
var multiplication = function(a, b){
    return (a * b);
};
var division = function(a, b){
    return (a / b);
};
var modulo = function(a, b){
    return (a % b);
};
<|endoftext|>


<commit_before>// Chris Konstad, 2016
// TODO remove alerts for production?

// important variables
var storage = chrome.storage.sync;
var subs = [];  // list of all subreddits
var counts = {};  // subreddit => visit count

// Mark subreddit as visited
function saveSubreddit(subreddit) {
  // Add if not already in subreddit list
  if(-1 == subs.indexOf(subreddit)) {
    subs.push(subreddit);
  }

  // Get the current visit count for the subreddit
  storage.get(subreddit, function(items) {
    var count = items[subreddit];
    if(undefined === count) {
      count = 0;
    }

    count++;

    // Save the incremented visit count for the subreddit
    counts[subreddit] = count;
    var data = {};
    data[subreddit] = count;
    storage.set(data, function() {
      if(chrome.runtime.lastError) {
        console.error(chrome.runtime.lastError);
        alert(chrome.runtime.lastError);
      }
    });
  });
}

function loadData() {
  console.log("loading data");
  storage.get(null, function(items) {
    subs = [];
    for(var key in items) {
        counts = items;
        subs.push(key);
    }
    //console.log(JSON.stringify(items));
    //console.log(JSON.stringify(subs));
    //console.log(JSON.stringify(counts));
  });
}

// Load the data at startup
chrome.omnibox.onInputStarted.addListener(
  function() {
    loadData();
  }
);

// Filter a list using substrings
function filterSubreddits(text, subs) {
  var ret = [];
  subs.forEach(function(sub) {
    if(-1 != sub.indexOf(text)) {
      ret.push(sub);
    }
  });
  return ret;
}

// This event is fired each time the user updates the text in the omnibox,
// as long as the extension's keyword mode is still active.
chrome.omnibox.onInputChanged.addListener(
  function(text, suggest) {
    console.log('inputChanged: ' + text);
    // TODO add smart suggestions
    // TODO match fuzzy substrings
    // TODO sort by closeness

    // Get visited subreddits that contain the text as a substring
    var subsToSuggest = filterSubreddits(text, subs);

    // Build suggestions to display
    var suggestions = [];
    subsToSuggest.forEach(function(sub) {
      suggestions.push({
        content: sub,
        description: sub + "(" + counts[sub] + ")"
      });
    });

    // Sort by visit count
    suggestions.sort(function(a,b) {
      if(counts[a.content] < counts[b.content])
        return 1;
      else if(counts[a.content] > counts[b.content])
        return -1;
      else
        return 0;
    });
    suggest(suggestions);
  });

// This event is fired with the user accepts the input in the omnibox.
chrome.omnibox.onInputEntered.addListener(
  function(subreddit) {
    chrome.tabs.getSelected(null, function(tab){
      var url = "https://reddit.com/r/" + subreddit;
      console.log("Redirecting to: " + url);
      chrome.tabs.update(tab.id, {url: url});

      // Add subreddit to visited-subreddit list
      saveSubreddit(subreddit);
    })
  });
<commit_msg>Case insensitive filtering and fixed UI up a bit<commit_after>// Chris Konstad, 2016
// TODO remove alerts for production?

// important variables
var storage = chrome.storage.sync;
var subs = [];  // list of all subreddits
var counts = {};  // subreddit => visit count

// Mark subreddit as visited
function saveSubreddit(subreddit) {
  // Add if not already in subreddit list
  if(-1 == subs.indexOf(subreddit)) {
    subs.push(subreddit);
  }

  // Get the current visit count for the subreddit
  storage.get(subreddit, function(items) {
    var count = items[subreddit];
    if(undefined === count) {
      count = 0;
    }

    count++;

    // Save the incremented visit count for the subreddit
    counts[subreddit] = count;
    var data = {};
    data[subreddit] = count;
    storage.set(data, function() {
      if(chrome.runtime.lastError) {
        console.error(chrome.runtime.lastError);
        alert(chrome.runtime.lastError);
      }
    });
  });
}

function loadData() {
  console.log("loading data");
  storage.get(null, function(items) {
    subs = [];
    for(var key in items) {
        counts = items;
        subs.push(key);
    }
    //console.log(JSON.stringify(items));
    //console.log(JSON.stringify(subs));
    //console.log(JSON.stringify(counts));
  });
}

// Load the data at startup
chrome.omnibox.onInputStarted.addListener(
  function() {
    loadData();
  }
);

// Filter a list using substrings
function filterSubreddits(text, subs) {
  var ret = [];
  subs.forEach(function(sub) {
    if(-1 != sub.toLowerCase().indexOf(text.toLowerCase())) {
      ret.push(sub);
    }
  });
  return ret;
}

// This event is fired each time the user updates the text in the omnibox,
// as long as the extension's keyword mode is still active.
chrome.omnibox.onInputChanged.addListener(
  function(text, suggest) {
    console.log('inputChanged: "' + text + '"');
    // TODO add smart suggestions
    // TODO match fuzzy substrings
    // TODO sort by closeness

    // Get visited subreddits that contain the text as a substring
    var subsToSuggest = filterSubreddits(text, subs);

    // Build suggestions to display
    var suggestions = [];
    subsToSuggest.forEach(function(sub) {
      suggestions.push({
        content: sub,
        description: sub
      });
    });

    // Sort by visit count
    suggestions.sort(function(a,b) {
      if(counts[a.content] < counts[b.content])
        return 1;
      else if(counts[a.content] > counts[b.content])
        return -1;
      else
        return 0;
    });
    suggest(suggestions);
  });

// This event is fired with the user accepts the input in the omnibox.
chrome.omnibox.onInputEntered.addListener(
  function(subreddit) {
    chrome.tabs.getSelected(null, function(tab){
      var url = "https://reddit.com/r/" + subreddit;
      console.log("Redirecting to: " + url);
      chrome.tabs.update(tab.id, {url: url});

      // Add subreddit to visited-subreddit list
      saveSubreddit(subreddit);
    })
  });
<|endoftext|>


<commit_before>'use strict';

var windowId = null;

function respondsWith200(url) {
  try {
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open('GET', url, false);
    xmlHttp.send(null);
    return xmlHttp.status === 200;
  } catch (e) {
    return false;
  }
}

function openWindow(targetAddress) {
  var createData = {
    url: targetAddress,
    focused: true,
    type: 'popup'
  };
  chrome.windows.create(
    createData,
    (window) => windowId = window.id
  );
}

function poll() {
  chrome.storage.local.get({
    address: 'http://foo.bar/baz',
    targetAddress: 'https://www.youtube.com/watch?v=wZZ7oFKsKzY',
    active: false
  },
                           (config) => checkStatus(config));
}

function checkStatus(config) {
  if(!config.active) return;
  if(respondsWith200(config.address)) {
    chrome.browserAction.setBadgeText({ text: 'OK' });
    chrome.browserAction.setBadgeBackgroundColor({ color: '#5cb85c' });
    if(windowId !== null) {
      chrome.windows.remove(windowId);
      windowId = null;
    }
  }
  else {
    chrome.browserAction.setBadgeText({ text: 'N/A' });
    chrome.browserAction.setBadgeBackgroundColor({ color: '#dd3f3a' });
    if (windowId === null) {
      openWindow(config.targetAddress);
    }
  }
}

chrome.storage.local.get({ pollingInterval: 60 },
                         (config) => {
                           setInterval(poll, config.pollingInterval * 1000);
                         });
<commit_msg>fix: add http status 204<commit_after>'use strict';

var windowId = null;

function respondsWith200(url) {
  try {
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open('GET', url, false);
    xmlHttp.send(null);
    return xmlHttp.status === 200 || xmlHttp.status === 204;
  } catch (e) {
    return false;
  }
}

function openWindow(targetAddress) {
  var createData = {
    url: targetAddress,
    focused: true,
    type: 'popup'
  };
  chrome.windows.create(
    createData,
    (window) => windowId = window.id
  );
}

function poll() {
  chrome.storage.local.get({
    address: 'http://foo.bar/baz',
    targetAddress: 'https://www.youtube.com/watch?v=wZZ7oFKsKzY',
    active: false
  },
                           (config) => checkStatus(config));
}

function checkStatus(config) {
  if(!config.active) return;
  if(respondsWith200(config.address)) {
    chrome.browserAction.setBadgeText({ text: 'OK' });
    chrome.browserAction.setBadgeBackgroundColor({ color: '#5cb85c' });
    if(windowId !== null) {
      chrome.windows.remove(windowId);
      windowId = null;
    }
  }
  else {
    chrome.browserAction.setBadgeText({ text: 'N/A' });
    chrome.browserAction.setBadgeBackgroundColor({ color: '#dd3f3a' });
    if (windowId === null) {
      openWindow(config.targetAddress);
    }
  }
}

chrome.storage.local.get({ pollingInterval: 60 },
                         (config) => {
                           setInterval(poll, config.pollingInterval * 1000);
                         });
<|endoftext|>


<commit_before>var TW = {};
var startup;
// Declare this global namespace so it can be used from popup.js

require([
  'settings',
  'tabmanager',
  'util',
  'updater',
  'menus'
], function(settings, tabmanager, util, updater, menus) {

/**
 * @todo: refactor into "get the ones to close" and "close 'em"
 * So it can be tested.
 */
var checkToClose = function(cutOff) {
  var i;

  if (settings.get('paused') === true) {
    return;
  }
  cutOff = cutOff || new Date().getTime() - settings.get('stayOpen');
  var minTabs = settings.get('minTabs');
  // Tabs which have been locked via the checkbox.
  var lockedIds = settings.get("lockedIds");

  // Update the selected one to make sure it doesn't get closed.
  chrome.tabs.getSelected(null, tabmanager.updateLastAccessed);

  /**
   * Idlechecker stuff, needs to be refactored
   *

  var sleepTime = TW.idleChecker.timeSinceLastRun(now) - settings.checkInterval * 1.1;
  // sleepTime is the time elapsed between runs.  This is probably time when the computer was asleep.

  if (sleepTime < 0) {
    sleepTime = 0;
  }
  TW.idleChecker.logRun(now);

  */

  var toCut = tabmanager.getOlderThen(cutOff);
  var tabsToSave = [];
  var allTabs = tabmanager.getAll();

  // If cutting will reduce us below 5 tabs, only remove the first N to get to 5.
  if ((allTabs.length - minTabs) >= 0) {
    toCut = toCut.splice(0, allTabs.length - minTabs);
  } else {
    // We have less than minTab tabs, abort.
    // Also, let's reset the last accessed time of our current tabs so they
    // don't get closed when we add a new one.
    for (i = 0; i < allTabs.length; i++) {
      tabmanager.updateLastAccessed(allTabs[i]);
    }
    return;
  }

  if (toCut.length === 0) {
    return;
  }

  var closeTab = function(tab) {
    if (true === tab.pinned) {
        return;
      }
      if (tabmanager.isWhitelisted(tab.url)) {
        return;
      }

      tabmanager.closedTabs.saveTabs([tab]);
      // Close it in Chrome.
      chrome.tabs.remove(tab.id);
  };

  for (i=0; i < toCut.length; i++) {
    var tabIdToCut = toCut[i];
    // @todo: move to tabmanager.
    if (lockedIds.indexOf(tabIdToCut) != -1) {
      // Update its time so it gets checked less frequently.
      // Would also be smart to just never add it.
      // @todo: fix that.
      tabmanager.updateLastAccessed(tabIdToCut);
      continue;
    }

    chrome.tabs.get(tabIdToCut, closeTab);
  }
};

var onNewTab = function(tab) {
  // Check if it exists in corral already
  // The 2nd argument is an array of filters, we add one filter
  // which checks for an exact URL match.  If we match throw the old
  // entry away.
  tabmanager.searchTabs(function(tabs) {
    if (tabs.length) {
      _.each(tabs, function(t) {
        tabmanager.closedTabs.removeTab(t.id);
      });
    }
  }, [tabmanager.filters.exactUrl(tab.url)]);

  // Add the new one;
  tabmanager.updateLastAccessed(tab.id);
};

startup = function() {
  alert('fuck this');
  console.log('fuuuuuu');
  console.log('startup');
  settings.init();
  updater.run();
  tabmanager.closedTabs.init();

  TW.settings = settings;
  TW.updater = updater;
  TW.tabmanager = tabmanager;
  console.log(TW);

  if (settings.get('purgeClosedTabs') !== false) {
    tabmanager.closedTabs.clear();
  }
  settings.set('lockedIds', []);

  // Move this to a function somehwere so we can restart the process.
  chrome.tabs.query({
    windowType: 'normal'
  }, tabmanager.initTabs);
  chrome.tabs.onCreated.addListener(onNewTab);
  chrome.tabs.onUpdated.addListener(tabmanager.updateLastAccessed);
  chrome.tabs.onRemoved.addListener(tabmanager.removeTab);
  chrome.tabs.onActivated.addListener(function(tabInfo) {
    menus.updateContextMenus(tabInfo['tabId']);
    tabmanager.updateLastAccessed(tabInfo['tabId']);
    });
  window.setInterval(checkToClose, settings.get('checkInterval'));
  window.setInterval(tabmanager.updateClosedCount, settings.get('badgeCounterInterval'));

  // Create the "lock tab" context menu:
  menus.createContextMenus();
};

window.onload = startup;

});
window.onload = startup;<commit_msg>removed some swears :)<commit_after>var TW = {};
var startup;
// Declare this global namespace so it can be used from popup.js

require([
  'settings',
  'tabmanager',
  'util',
  'updater',
  'menus'
], function(settings, tabmanager, util, updater, menus) {

/**
 * @todo: refactor into "get the ones to close" and "close 'em"
 * So it can be tested.
 */
var checkToClose = function(cutOff) {
  var i;

  if (settings.get('paused') === true) {
    return;
  }
  cutOff = cutOff || new Date().getTime() - settings.get('stayOpen');
  var minTabs = settings.get('minTabs');
  // Tabs which have been locked via the checkbox.
  var lockedIds = settings.get("lockedIds");

  // Update the selected one to make sure it doesn't get closed.
  chrome.tabs.getSelected(null, tabmanager.updateLastAccessed);

  /**
   * Idlechecker stuff, needs to be refactored
   *

  var sleepTime = TW.idleChecker.timeSinceLastRun(now) - settings.checkInterval * 1.1;
  // sleepTime is the time elapsed between runs.  This is probably time when the computer was asleep.

  if (sleepTime < 0) {
    sleepTime = 0;
  }
  TW.idleChecker.logRun(now);

  */

  var toCut = tabmanager.getOlderThen(cutOff);
  var tabsToSave = [];
  var allTabs = tabmanager.getAll();

  // If cutting will reduce us below 5 tabs, only remove the first N to get to 5.
  if ((allTabs.length - minTabs) >= 0) {
    toCut = toCut.splice(0, allTabs.length - minTabs);
  } else {
    // We have less than minTab tabs, abort.
    // Also, let's reset the last accessed time of our current tabs so they
    // don't get closed when we add a new one.
    for (i = 0; i < allTabs.length; i++) {
      tabmanager.updateLastAccessed(allTabs[i]);
    }
    return;
  }

  if (toCut.length === 0) {
    return;
  }

  var closeTab = function(tab) {
    if (true === tab.pinned) {
        return;
      }
      if (tabmanager.isWhitelisted(tab.url)) {
        return;
      }

      tabmanager.closedTabs.saveTabs([tab]);
      // Close it in Chrome.
      chrome.tabs.remove(tab.id);
  };

  for (i=0; i < toCut.length; i++) {
    var tabIdToCut = toCut[i];
    // @todo: move to tabmanager.
    if (lockedIds.indexOf(tabIdToCut) != -1) {
      // Update its time so it gets checked less frequently.
      // Would also be smart to just never add it.
      // @todo: fix that.
      tabmanager.updateLastAccessed(tabIdToCut);
      continue;
    }

    chrome.tabs.get(tabIdToCut, closeTab);
  }
};

var onNewTab = function(tab) {
  // Check if it exists in corral already
  // The 2nd argument is an array of filters, we add one filter
  // which checks for an exact URL match.  If we match throw the old
  // entry away.
  tabmanager.searchTabs(function(tabs) {
    if (tabs.length) {
      _.each(tabs, function(t) {
        tabmanager.closedTabs.removeTab(t.id);
      });
    }
  }, [tabmanager.filters.exactUrl(tab.url)]);

  // Add the new one;
  tabmanager.updateLastAccessed(tab.id);
};

startup = function() {
  settings.init();
  updater.run();
  tabmanager.closedTabs.init();

  TW.settings = settings;
  TW.updater = updater;
  TW.tabmanager = tabmanager;
  console.log(TW);

  if (settings.get('purgeClosedTabs') !== false) {
    tabmanager.closedTabs.clear();
  }
  settings.set('lockedIds', []);

  // Move this to a function somehwere so we can restart the process.
  chrome.tabs.query({
    windowType: 'normal'
  }, tabmanager.initTabs);
  chrome.tabs.onCreated.addListener(onNewTab);
  chrome.tabs.onUpdated.addListener(tabmanager.updateLastAccessed);
  chrome.tabs.onRemoved.addListener(tabmanager.removeTab);
  chrome.tabs.onActivated.addListener(function(tabInfo) {
    menus.updateContextMenus(tabInfo['tabId']);
    tabmanager.updateLastAccessed(tabInfo['tabId']);
    });
  window.setInterval(checkToClose, settings.get('checkInterval'));
  window.setInterval(tabmanager.updateClosedCount, settings.get('badgeCounterInterval'));

  // Create the "lock tab" context menu:
  menus.createContextMenus();
};

});
window.onload = startup;<|endoftext|>


<commit_before>// ---------------------------------------------
// [Author] Christopher Ciufo
// [Description] Omnibox App Launcher controller
// [Created] 2015/06/18
// ---------------------------------------------
(function () {
  'use strict';

  var fuse;
  var searchList;
  var currentContent = "";
  var previousText = "";

  chrome.omnibox.onInputStarted.addListener(function () {
    chrome.management.getAll(function (results) {
      searchList = results;
      fuse = new Fuse(searchList, {
        keys:['name', 'description']
      });
    });
  });

  chrome.omnibox.onInputChanged.addListener(function (text, suggest) {
    if (text) {
      var results = fuse.search(text);
      if (results) {
        var topSuggestion = {
          description: "<dim>Launch</dim> " + results[0].name + " - <dim>" + results[0].description + "</dim>"
        };
        currentContent = results[0].name;
        previousText = text;

        chrome.omnibox.setDefaultSuggestion(topSuggestion);

        // var suggestions = [];
        // var numItems = Math.min(results.length, 5);

        // for (var i = 1; i < numItems; i++) {
        //   suggestions.push({
        //     content: results[i].name,
        //     description: results[i].name + (results[i].description ? " - <dim>" + results[i].description + "</dim>" : "")
        //   });
        // }

        // console.log(numItems);
        // console.log(suggestions);
        // suggest(suggestions);
      }
    }
  });

  chrome.omnibox.onInputEntered.addListener(function (text, disposition) {
    var searchKey;
    if (text == previousText) {
      searchKey = currentContent;
    } else {
      searchKey = text;
    }
    alert(searchKey);
  });

})();
<commit_msg>Fixed xml escaping issue. Now filtering apps and extensions works and correct suggestion list is displayed.<commit_after>// ---------------------------------------------
// [Author] Christopher Ciufo
// [Description] Omnibox App Launcher controller
// [Created] 2015/06/18
// ---------------------------------------------
(function () {
  'use strict';

  function escapeText(text) {
    return text
        .replace(/&/g, '&')
        .replace(/</g, '<')
        .replace(/>/g, '>');
  }

  function generateDescription (result) {
    return escapeText(result.name) + (escapeText(result.description) ? " - <dim>" + escapeText(result.description) + "</dim>" : "");
  }

  var fuse;
  var currentContent = "";
  var previousText = "";

  chrome.omnibox.onInputChanged.addListener(function (text, suggest) {
    if (text.length) {
      if (typeof fuse === 'undefined') {
        chrome.management.getAll(function (searchList) {
          fuse = new Fuse(searchList, {
            keys:['name', 'description']
          });
          displaySuggestions(text, suggest);
        });
      } else {
        displaySuggestions(text, suggest);
      }
    }
  });

  function displaySuggestions(text, suggest) {
    var results = fuse.search(text);
    if (results.length) {
      var topSuggestion = {
        description: "<dim>Launch</dim> " + generateDescription(results[0])
      };
      currentContent = results[0].name;
      previousText = text;

      chrome.omnibox.setDefaultSuggestion(topSuggestion);

      var suggestions = [];
      for (var i = 1; i < Math.min(results.length, 5); i++) {
        suggestions.push({
          content: results[i].name,
          description: generateDescription(results[i])
        });
      }
      suggest(suggestions);
    }
  }

  chrome.omnibox.onInputEntered.addListener(function (text, disposition) {
    var searchKey;
    if (text == previousText) {
      searchKey = currentContent;
    } else {
      searchKey = text;
    }
    alert(searchKey);
  });

})();
<|endoftext|>


<commit_before>// Declarations
var contentPort, popupPort,
	passFields, formFields,
	passwordMenuId, passId;

function contextFunction(info, tab) {
	console.log(passId);
	mod_url = tab.url.match(/(\w*\.\w{2,3})\//)[1];
	console.log(mod_url);
}

function handleContentMessages(msg) {
	if(msg.type === "pass") {
		if((msg.passId != null) && (!passwordMenuId)) {
			passwordMenuId = chrome.contextMenus.create(
				{"title": "Setup a half-life password",
				 "contexts": ["all"],
				 "onclick": contextFunction});
			passId = msg.passId;
			//console.log(msg.passId + " " + msg.formId);
		}
		else if((msg.passId == null) && (passwordMenuId)) {
			chrome.contextMenus.remove(passwordMenuId);
			passwordMenuId = null;
		}
	} // context menu messages
	if(msg.type === "show"){
		chrome.tabs.getSelected(null, function(t){
			chrome.pageAction.show(t.id);
		});
		passFields = msg.fields;
		formFields = msg.forms;
		console.log(msg.fields);
	}
}

function handlePopupMessages(msg) {
	static var passIndex = 0;
	if(msg.type === "wantNext") {
		contentPort.postMessage({"type": "highlight", "id": passFields[++passIndex].id});
	} else if(msg.type === "wantPrev") {
		contentPort.postMessage({"type": "highlight", "id": passFields[--passIndex].id});
	}
	console.log(msg.type);
}

// Scripting
chrome.extension.onConnect.addListener(function(port) {
	if(port.name === "content"){
		contentPort = port;
		port.onMessage.addListener(handleContentMessages);
	} else if(port.name === "popup"){
		popupPort = port;
		port.onMessage.addListener(handlePopupMessages);
	}
});

<commit_msg>Resolved merge<commit_after>// Declarations
var contentPort, popupPort,
	passFields, formFields,
	passwordMenuId, passId;

var passfields = [];
var formfields = []
var i = 0;
function contextFunction(info, tab) {
	console.log(passId);
	mod_url = tab.url.match(/(\w*\.\w{2,3})\//)[1];
	console.log(mod_url);
}

function handleContentMessages(msg) {
	if(msg.type === "pass") {
		if((msg.passId != null) && (!passwordMenuId)) {
			passwordMenuId = chrome.contextMenus.create(
				{"title": "Setup a half-life password",
				 "contexts": ["all"],
				 "onclick": contextFunction});
			passId = msg.passId;
			//console.log(msg.passId + " " + msg.formId);
		}
		else if((msg.passId == null) && (passwordMenuId)) {
			chrome.contextMenus.remove(passwordMenuId);
			passwordMenuId = null;
		}
	} // context menu messages
	if(msg.type === "show"){
		chrome.tabs.getSelected(null, function(t){
			chrome.pageAction.show(t.id);
		});
		passFields = msg.fields;
		formFields = msg.forms;
		console.log(msg.fields);
	}
}

function handlePopupMessages(msg) {
	static var passIndex = 0;
	if(msg.type === "wantNext") {
		contentPort.postMessage({"type": "highlight", "id": passFields[++passIndex].id});
	} else if(msg.type === "wantPrev") {
		contentPort.postMessage({"type": "highlight", "id": passFields[--passIndex].id});
	}
	console.log(msg.type);
}

// Scripting
chrome.extension.onConnect.addListener(function(port) {
	if(port.name === "content"){
		contentPort = port;
		port.onMessage.addListener(handleContentMessages);
	} else if(port.name === "popup"){
		popupPort = port;
		port.onMessage.addListener(handlePopupMessages);
	}
});

<|endoftext|>


<commit_before>//Version 0.3
var manifestData = chrome.runtime.getManifest();
var version = manifestData.version;
//Declare rules:
var match_rules = {
    conditions: [
	   new chrome.declarativeContent.PageStateMatcher({
	       pageUrl: { hostSuffix: '.scoutbook.com',  schemes: ['https'] },
               css: ["#report"]
	   })
	],
	//If found, display the Page Action icon registered in the manifest.json
	actions: [ new chrome.declarativeContent.ShowPageAction() ]
};

//Register rules:
chrome.runtime.onInstalled.addListener(function(details) {
    chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
        chrome.declarativeContent.onPageChanged.addRules([match_rules]);
    });
});

// Called when the user clicks on the browser action.
chrome.pageAction.onClicked.addListener(function(tab) {
  console.log('Clicked!');
  chrome.tabs.insertCSS(null, {file: "bower_components/sweetalert/lib/sweet-alert.css"},
    executeScripts(null, [
        { file: "bower_components/excellentexport/excellentexport.min.js" },
        { file: "bower_components/sweetalert/lib/sweet-alert.min.js" },
        { file: "content_script.js" },
        { code: "exportTable();" }
    ])
  )
});

//From http://stackoverflow.com/questions/21535233/injecting-multiple-scripts-through-executescript-in-google-chrome
function executeScripts(tabId, injectDetailsArray)
{
    function createCallback(tabId, injectDetails, innerCallback) {
        return function () {
            chrome.tabs.executeScript(tabId, injectDetails, innerCallback);
        };
    }

    var callback = function(response){ console.log('v'+version+' '+response); };

    for (var i = injectDetailsArray.length - 1; i >= 0; --i)
        callback = createCallback(tabId, injectDetailsArray[i], callback);

    if (callback !== null)
        callback();   // execute outermost function
}

<commit_msg>Added new rules for trained leader report. Corrected rule for Roster Export.<commit_after>//Version 0.3
var manifestData = chrome.runtime.getManifest();
var version = manifestData.version;
//Declare rules:
//Report page
var reportRule = {
    conditions: [
	   new chrome.declarativeContent.PageStateMatcher({
	       pageUrl: { hostSuffix: '.scoutbook.com',  schemes: ['https'] },
               css: ["#report"]
	   })],
   actions: [ new chrome.declarativeContent.ShowPageAction() ]
};
//Trained Leader Report Page
var leaderRule = {
    conditions: [
        new chrome.declarativeContent.PageStateMatcher({
            pageUrl: { hostSuffix: '.scoutbook.com', schemes: ['https'],
                pathSuffix: ['leadertraining.asp'] }
        })],
    actions: [ new chrome.declarativeContent.ShowPageAction() ]
};
//Roster page
var rosterRule = {
    conditions: [
           new chrome.declarativeContent.PageStateMatcher({
	       pageUrl: { hostSuffix: '.scoutbook.com',  schemes: ['https'] },
               css: ["#scoutRoster"]
	   })

	],
	//If found, display the Page Action icon registered in the manifest.json
	actions: [ new chrome.declarativeContent.ShowPageAction() ]
};

//Register rules:
chrome.runtime.onInstalled.addListener(function(details) {
    chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
        chrome.declarativeContent.onPageChanged.addRules([reportRule, rosterRule, leaderRule]);
    });
});

// Called when the user clicks on the browser action.
chrome.pageAction.onClicked.addListener(function(tab) {
  console.log('Clicked '+version+' '+tab.url);
  if ( /report\.asp/i.test(tab.url) ) {
      chrome.pageAction.setTitle({'tabid': tab.id, 'title': 'Export this report to Excel'});
      chrome.tabs.insertCSS(null, {file: "bower_components/sweetalert/lib/sweet-alert.css"},
        executeScripts(null, [
            { file: "bower_components/excellentexport/excellentexport.min.js" },
            { file: "bower_components/sweetalert/lib/sweet-alert.min.js" },
            { file: "report_export_script.js" },
            { code: "exportTable();" }
        ])
      );
  }
  if ( /messages\/default.asp/i.test(tab.url) ) {
      //chrome.pageAction.setTitle({'tabid': tab.id, 'title': 'Add your signature to this message'});
      console.log("This is the messages screen.");
  }
});

//From http://stackoverflow.com/questions/21535233/injecting-multiple-scripts-through-executescript-in-google-chrome
function executeScripts(tabId, injectDetailsArray)
{
    function createCallback(tabId, injectDetails, innerCallback) {
        return function () {
            chrome.tabs.executeScript(tabId, injectDetails, innerCallback);
        };
    }

    var callback = function(response){ console.log('v'+version+' '+response); };

    for (var i = injectDetailsArray.length - 1; i >= 0; --i)
        callback = createCallback(tabId, injectDetailsArray[i], callback);

    if (callback !== null)
        callback();   // execute outermost function
}

<|endoftext|>


<commit_before>const APPLICABLE_PROTOCOLS = ["http:", "https:"];
const RATING_TEXT = {
	"D": "The terms of service are very uneven or there are some important issues that need your attention.",
	"E": "The terms of service raise very serious concerns."
};

var services = [];

/******************* UTILS ****************/
function log(message) {
	console.log(message);
}

function createRegExpForServiceUrl(serviceUrl) {
	if (/^http/.exec(serviceUrl)) {
		return new RegExp(serviceUrl + '.*');
	} else {
		return new RegExp('https?://[^:/]*\\b' + serviceUrl + '.*');
	}
}

/*
Returns true only if the URL's protocol is in APPLICABLE_PROTOCOLS.
*/
function protocolIsApplicable(url) {
	var anchor =  document.createElement('a');
	anchor.href = url;
	return APPLICABLE_PROTOCOLS.includes(anchor.protocol);
}

function loadService(serviceName, serviceIndexData) {
	let requestURL = 'https://tosdr.org/services/' + serviceName + '.json';

	const driveRequest = new Request(requestURL, {
		method: "GET"
	});

	return fetch(driveRequest).then((response) => {
		if (response.status === 200) {
			return response.json();
		} else {
			throw response.status;
		}
	});
}

function getServices() {
  const requestURL = "https://tosdr.org/index/services.json";

  const driveRequest = new Request(requestURL, {
    method: "GET"
  });

  return fetch(driveRequest).then((response) => {
    if (response.status === 200) {
      return response.json();
    } else {
      throw response.status;
    }
  });

}

getServices().then((servicesIndex)=>{
	let promiseChain = [];

	for (let serviceName in servicesIndex) {
		promiseChain.push(loadService(serviceName, servicesIndex[serviceName]));
	}

	return Promise.all(promiseChain)
	.then((servicesResponse)=>{
		var setchain = [];

		for (let s of servicesResponse) {
			if (!s.url) {
				continue;
			}
			s.urlRegExp = createRegExpForServiceUrl(s.url);
			s.points = s.points;
			s.class = s.class;
			s.links = s.links;
			if (!s.tosdr) {
				s.tosdr = { rated: false };
			}
			var service = {};
			service[s.id]= s;

			setchain.push(browser.storage.local.set(service));
		}
		return Promise.all(setchain);
	}).then((setchain)=>{
		/*When first loaded, initialize the page action for all tabs.
		*/
		var gettingAllTabs = browser.tabs.query({});
		return gettingAllTabs.then((tabs) => {
			for (let tab of tabs) {
				initializePageAction(tab);
			}
		});
	});
});

function getService(tab) {
	return browser.storage.local.get().then((services)=>{
		var matchingServices = Object.keys(services).filter(function (service) {
			return services[service].urlRegExp.exec(tab.url);
		});

		return matchingServices.length > 0 ? services[matchingServices[0]] : null;
	});
}

function getIconForService(service) {
	var rated = false;
	if(service.tosdr !== undefined){
		rated = service.tosdr.rated;
	}
	var imageName = rated ? rated.toLowerCase() : 'false';
	return 'icons/class/' + imageName + '.png';
}

function checkNotification(ser) {

	return browser.storage.local.get(ser.name).then((service)=>{
		var service = service[ser.name];
		var last = localStorage.getItem('notification/' + service.name + '/last/update');
		var lastRate = localStorage.getItem('notification/' + service.name + '/last/rate');
		var shouldShow = false;

		if(service.tosdr !== undefined){
			if (!service.tosdr.rated) { return; }
		}

		var rate = service.tosdr.rated;
		if (rate === 'D' || rate === 'E') {

			if (last) {
				var lastModified = parseInt(Date.parse(last));
				log(lastModified);
				var daysSinceLast = (new Date().getTime() - lastModified) / (1000 * 60 * 60 * 24);
				log(daysSinceLast);

				if (daysSinceLast > 7) {
					shouldShow = true;
				}
			} else {
				shouldShow = true;
			}

		} else if (lastRate === 'D' || lastRate === 'E') {
			shouldShow = true;
		}

		if (shouldShow) {
			localStorage.setItem('notification/' + service.name + '/last/update', new Date().toDateString());
			localStorage.setItem('notification/' + service.name + '/last/rate', rate);

			var opt = {
				type: "basic",
				title: service.id,
				message: RATING_TEXT[rate],
				iconUrl: './images/icon-128.png'
			}

			var notification = browser.notifications.create('tosdr-notify', opt, function(event){
				console.log(event)
			});

			browser.notifications.onButtonClicked.addListener(function(){
				browser.tabs.create({
					url: 'https://tosdr.org/#' + service.id
				});
			});

		}

	});
}

/*
Initialize the page action: set icon and title, then show.
Only operates on tabs whose URL's protocol is applicable.
*/
function initializePageAction(tab) {
	if (protocolIsApplicable(tab.url)) {
		return getService(tab).then((service)=>{
			if (service) {
				browser.pageAction.setIcon({
					tabId: tab.id,
					path: getIconForService(service)
				});
				browser.pageAction.setPopup({
					tabId: tab.id,
					popup: 'popup/popup.html#' + service.id
				})
				browser.pageAction.show(tab.id);
				checkNotification(service);
			}else{
				browser.pageAction.setIcon({
					tabId: tab.id,
					path: 'icons/class/none.png'
				});
				browser.pageAction.setPopup({
					tabId: tab.id,
					popup: 'popup/popup.html#none'
				})
				browser.pageAction.show(tab.id);
			}
		});

	}
}

browser.tabs.onUpdated.addListener((id, changeInfo, tab) => {
	initializePageAction(tab);
});<commit_msg>Get service data using ID not name<commit_after>const APPLICABLE_PROTOCOLS = ["http:", "https:"];
const RATING_TEXT = {
	"D": "The terms of service are very uneven or there are some important issues that need your attention.",
	"E": "The terms of service raise very serious concerns."
};

var services = [];

/******************* UTILS ****************/
function log(message) {
	console.log(message);
}

function createRegExpForServiceUrl(serviceUrl) {
	if (/^http/.exec(serviceUrl)) {
		return new RegExp(serviceUrl + '.*');
	} else {
		return new RegExp('https?://[^:/]*\\b' + serviceUrl + '.*');
	}
}

/*
Returns true only if the URL's protocol is in APPLICABLE_PROTOCOLS.
*/
function protocolIsApplicable(url) {
	var anchor =  document.createElement('a');
	anchor.href = url;
	return APPLICABLE_PROTOCOLS.includes(anchor.protocol);
}

function loadService(serviceName, serviceIndexData) {
	let requestURL = 'https://tosdr.org/services/' + serviceName + '.json';

	const driveRequest = new Request(requestURL, {
		method: "GET"
	});

	return fetch(driveRequest).then((response) => {
		if (response.status === 200) {
			return response.json();
		} else {
			throw response.status;
		}
	});
}

function getServices() {
  const requestURL = "https://tosdr.org/index/services.json";

  const driveRequest = new Request(requestURL, {
    method: "GET"
  });

  return fetch(driveRequest).then((response) => {
    if (response.status === 200) {
      return response.json();
    } else {
      throw response.status;
    }
  });

}

getServices().then((servicesIndex)=>{
	let promiseChain = [];

	for (let serviceName in servicesIndex) {
		promiseChain.push(loadService(serviceName, servicesIndex[serviceName]));
	}

	return Promise.all(promiseChain)
	.then((servicesResponse)=>{
		var setchain = [];

		for (let s of servicesResponse) {
			if (!s.url) {
				continue;
			}
			s.urlRegExp = createRegExpForServiceUrl(s.url);
			s.points = s.points;
			s.class = s.class;
			s.links = s.links;
			if (!s.tosdr) {
				s.tosdr = { rated: false };
			}
			var service = {};
			service[s.id]= s;

			setchain.push(browser.storage.local.set(service));
		}
		return Promise.all(setchain);
	}).then((setchain)=>{
		/*When first loaded, initialize the page action for all tabs.
		*/
		var gettingAllTabs = browser.tabs.query({});
		return gettingAllTabs.then((tabs) => {
			for (let tab of tabs) {
				initializePageAction(tab);
			}
		});
	});
});

function getService(tab) {
	return browser.storage.local.get().then((services)=>{
		var matchingServices = Object.keys(services).filter(function (service) {
			return services[service].urlRegExp.exec(tab.url);
		});

		return matchingServices.length > 0 ? services[matchingServices[0]] : null;
	});
}

function getIconForService(service) {
	var rated = false;
	if(service.tosdr !== undefined){
		rated = service.tosdr.rated;
	}
	var imageName = rated ? rated.toLowerCase() : 'false';
	return 'icons/class/' + imageName + '.png';
}

function checkNotification(ser) {

	return browser.storage.local.get(ser.id).then((service)=>{
		var service = service[ser.name];
		var last = localStorage.getItem('notification/' + service.name + '/last/update');
		var lastRate = localStorage.getItem('notification/' + service.name + '/last/rate');
		var shouldShow = false;

		if(service.tosdr !== undefined){
			if (!service.tosdr.rated) { return; }
		}

		var rate = service.tosdr.rated;
		if (rate === 'D' || rate === 'E') {

			if (last) {
				var lastModified = parseInt(Date.parse(last));
				log(lastModified);
				var daysSinceLast = (new Date().getTime() - lastModified) / (1000 * 60 * 60 * 24);
				log(daysSinceLast);

				if (daysSinceLast > 7) {
					shouldShow = true;
				}
			} else {
				shouldShow = true;
			}

		} else if (lastRate === 'D' || lastRate === 'E') {
			shouldShow = true;
		}

		if (shouldShow) {
			localStorage.setItem('notification/' + service.name + '/last/update', new Date().toDateString());
			localStorage.setItem('notification/' + service.name + '/last/rate', rate);

			var opt = {
				type: "basic",
				title: service.id,
				message: RATING_TEXT[rate],
				iconUrl: './images/icon-128.png'
			}

			var notification = browser.notifications.create('tosdr-notify', opt, function(event){
				console.log(event)
			});

			browser.notifications.onButtonClicked.addListener(function(){
				browser.tabs.create({
					url: 'https://tosdr.org/#' + service.id
				});
			});

		}

	});
}

/*
Initialize the page action: set icon and title, then show.
Only operates on tabs whose URL's protocol is applicable.
*/
function initializePageAction(tab) {
	if (protocolIsApplicable(tab.url)) {
		return getService(tab).then((service)=>{
			if (service) {
				browser.pageAction.setIcon({
					tabId: tab.id,
					path: getIconForService(service)
				});
				browser.pageAction.setPopup({
					tabId: tab.id,
					popup: 'popup/popup.html#' + service.id
				})
				browser.pageAction.show(tab.id);
				checkNotification(service);
			}else{
				browser.pageAction.setIcon({
					tabId: tab.id,
					path: 'icons/class/none.png'
				});
				browser.pageAction.setPopup({
					tabId: tab.id,
					popup: 'popup/popup.html#none'
				})
				browser.pageAction.show(tab.id);
			}
		});

	}
}

browser.tabs.onUpdated.addListener((id, changeInfo, tab) => {
	initializePageAction(tab);
});<|endoftext|>


<commit_before>var ChatController = RouteController.extend({
    template: 'chat',
    findOrCreateChat : function (chatName) {
      // subscribe to the given chat
      Meteor.subscribe('chat', chatName, function(){
        // Once the data has loaded, set the session as true to indicate that the data have been loaded
        Session.set('chats_loaded', true);

      });

      if (Session.get('chats_loaded')) {
        chat = Chat.findOne({name: chatName});
        if(typeof chat == "undefined"){
          chat = Chat.insert({name: chatName, messages: [{name:"System", message:"This is your initial test message"}]}, function(error, result) {
            console.log(error,result);
          });
        }
        Session.set("id", chat._id);
        return chat;
      }
    }
  });

Router.map(function () {
    this.route('chat', {
        path :  '/c/:name',
        data : function() { return this.findOrCreateChat(this.params.name.toLowerCase()); },
        controller :  ChatController
    });
});
<commit_msg>improved welcome message<commit_after>var ChatController = RouteController.extend({
    template: 'chat',
    findOrCreateChat : function (chatName) {
      // subscribe to the given chat
      Meteor.subscribe('chat', chatName, function(){
        // Once the data has loaded, set the session as true to indicate that the data have been loaded
        Session.set('chats_loaded', true);

      });

      if (Session.get('chats_loaded')) {
        chat = Chat.findOne({name: chatName});
        if(typeof chat == "undefined"){
          chat = Chat.insert({name: chatName, messages: [{name:"The Clinkbot", message:"Welcome to the chatroom!"}]}, function(error, result) {
            console.log(error,result);
          });
        }
        Session.set("id", chat._id);
        return chat;
      }
    }
  });

Router.map(function () {
    this.route('chat', {
        path :  '/c/:name',
        data : function() { return this.findOrCreateChat(this.params.name.toLowerCase()); },
        controller :  ChatController
    });
});
<|endoftext|>


<commit_before>/*
 * Vimari injected script.
 *
 * This script is called before the requested page is loaded.  This allows us
 * to intercept events before they are passed to the requested pages code and
 * therefore we can stop certain pages (google) stealing the focus.
 */

/*
 * Global vars
 *
 * topWindow        - true if top window, false if iframe
 * settings         - stores user settings
 * currentZoomLevel - required for vimium scripts to run correctly
 * linkHintCss      - required from vimium scripts
 * extensionActive  - is the extension currently enabled (should only be true when tab is active)
 * shiftKeyToggle   - is shift key currently toggled
 */

var topWindow = (window.top === window),
	settings = {},
	currentZoomLevel = 100,
	linkHintCss = {},
	extensionActive = true,
	insertMode = false,
	shiftKeyToggle = false;

var actionMap = {
	'hintToggle': function() {
		HUD.show('Link hints mode');
		activateLinkHintsMode(false, false); },

	'newTabHintToggle': function() {
		HUD.show('Link hints mode');
		activateLinkHintsMode(true, false); },

	'tabForward': function() {
		safari.self.tab.dispatchMessage('changeTab', 1); },

	'tabBack': function() {
		safari.self.tab.dispatchMessage('changeTab', 0); },

	'scrollDown':
		function() { window.scrollBy(0, settings.scrollSize); },

	'scrollUp':
		function() { window.scrollBy(0, -settings.scrollSize); },

	'scrollLeft':
		function() { window.scrollBy(-settings.scrollSize, 0); },

	'scrollRight':
		function() { window.scrollBy(settings.scrollSize, 0); },

	'goBack':
		function() { window.history.back(); },

	'goForward':
		function() { window.history.forward(); },

	'reload':
		function() { window.location.reload(); },

	'openTab':
		function() { safari.self.tab.dispatchMessage('openTab'); },

	'closeTab':
		function() { safari.self.tab.dispatchMessage('closeTab', 0); },

	'closeTabReverse':
		function() { safari.self.tab.dispatchMessage('closeTab', 1); },

	'scrollDownHalfPage':
		function() { window.scrollBy(0, window.innerHeight / 2); },

	'scrollUpHalfPage':
		function() { window.scrollBy(0, window.innerHeight / -2); },

	'goToPageBottom':
		function() { window.scrollBy(0, document.body.scrollHeight); },

	'goToPageTop':
		function() { window.scrollBy(0, -document.body.scrollHeight); }
};

// Meant to be overridden, but still has to be copy/pasted from the original...
Mousetrap.stopCallback = function(e, element, combo) {
	// Escape key is special, no need to stop. Vimari-specific.
	if (combo === 'esc' || combo === 'ctrl+[') { return false; }

  // Preserve the behavior of allowing ex. ctrl-j in an input
  if (settings.modifier) { return false; }

	// if the element has the class "mousetrap" then no need to stop
	if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) {
		return false;
	}

    var tagName = element.tagName;
    var contentIsEditable = (element.contentEditable && element.contentEditable === 'true');

    // stop for input, select, and textarea
    return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA' || contentIsEditable;
};

// Set up key codes to event handlers
function bindKeyCodesToActions() {
	// Only add if topWindow... not iframe
	if (topWindow && !isExcludedUrl(settings.excludedUrls, document.URL)) {
		Mousetrap.reset();
		Mousetrap.bind('esc', enterNormalMode);
		Mousetrap.bind('ctrl+[', enterNormalMode);
		Mousetrap.bind('i', enterInsertMode);
		for (var actionName in actionMap) {
			if (actionMap.hasOwnProperty(actionName)) {
				var keyCode = getKeyCode(actionName);
				Mousetrap.bind(keyCode, executeAction(actionName), 'keydown');
			}
		}
	}
}

function enterNormalMode() {
	// Clear input focus
	document.activeElement.blur();

	// Clear link hints (if any)
	deactivateLinkHintsMode();

	// Re-enable if in insert mode
	insertMode = false;
	Mousetrap.bind('i', enterInsertMode);
}

// Calling it 'insert mode', but it's really just a user-triggered
// off switch for the actions.
function enterInsertMode() {
	insertMode = true;
	Mousetrap.unbind('i');
}

function executeAction(actionName) {
	return function() {
		// don't do anything if we're not supposed to
		if (linkHintsModeActivated || !extensionActive || insertMode)
			return;

		//Call the action function
		actionMap[actionName]();

		// Tell mousetrap to stop propagation
		return false;
	}
}

function unbindKeyCodes() {
	Mousetrap.reset();
}

// Adds an optional modifier to the configured key code for the action
function getKeyCode(actionName) {
	var keyCode = '';
	if(settings.modifier) {
		keyCode += settings.modifier + '+';
	}
	return keyCode + settings[actionName];
}

/*
 * Adds the given CSS to the page.
 * This function is required by vimium but depracated for vimari as the
 * css is pre loaded into the page.
 */
function addCssToPage(css) {
	return;
}

/*
 * Input or text elements are considered focusable and able to receive their own keyboard events,
 * and will enter enter mode if focused. Also note that the "contentEditable" attribute can be set on
 * any element which makes it a rich text editor, like the notes on jjot.com.
 * Note: we used to discriminate for text-only inputs, but this is not accurate since all input fields
 * can be controlled via the keyboard, particularly SELECT combo boxes.
 */
function isEditable(target) {
	if (target.getAttribute("contentEditable") === "true")
		return true;
	var focusableInputs = ["input", "textarea", "select", "button"];
	return focusableInputs.indexOf(target.tagName.toLowerCase()) >= 0;
}

/*
 * Embedded elements like Flash and quicktime players can obtain focus but cannot be programmatically
 * unfocused.
 */
function isEmbed(element) { return ["EMBED", "OBJECT"].indexOf(element.tagName) > 0; }

// ==========================
// Message handling functions
// ==========================

/*
 * All messages are handled by this function
 */
function handleMessage(msg) {
	// Attempt to call a function with the same name as the message name
	switch(msg.name) {
		case 'setSettings':
			setSettings(msg.message);
			break;
		case 'setActive':
			setActive(msg.message);
			break;
	}
}

/*
 * Callback to pass settings to injected script
 */
function setSettings(msg) {
	settings = msg;
	bindKeyCodesToActions();
}

/*
 * Enable or disable the extension on this tab
 */
function setActive(msg) {
	extensionActive = msg;
	if(msg) {
		bindKeyCodesToActions();
	} else {
		unbindKeyCodes();
	}
}

function isExcludedUrl(storedExcludedUrls, currentUrl) {
    var excludedUrls, regexp, url, _i, _len;
    excludedUrls = storedExcludedUrls.split(",");
    for (_i = 0, _len = excludedUrls.length; _i < _len; _i++) {
        url = excludedUrls[_i];
        regexp = new RegExp("^" + url.replace(/\*/g, ".*") + "$");
        if (currentUrl.match(regexp)) {
            return true;
        }
    }
    return false;
}

// Add event listener
safari.self.addEventListener("message", handleMessage, false);
// Retrieve settings
safari.self.tab.dispatchMessage('getSettings', '');

// Export to make it testable
window.isExcludedUrl = isExcludedUrl;
<commit_msg>Set HUD to fade after 2.5 seconds<commit_after>/*
 * Vimari injected script.
 *
 * This script is called before the requested page is loaded.  This allows us
 * to intercept events before they are passed to the requested pages code and
 * therefore we can stop certain pages (google) stealing the focus.
 */

/*
 * Global vars
 *
 * topWindow        - true if top window, false if iframe
 * settings         - stores user settings
 * currentZoomLevel - required for vimium scripts to run correctly
 * linkHintCss      - required from vimium scripts
 * extensionActive  - is the extension currently enabled (should only be true when tab is active)
 * shiftKeyToggle   - is shift key currently toggled
 */

var topWindow = (window.top === window),
	settings = {},
	currentZoomLevel = 100,
	linkHintCss = {},
	extensionActive = true,
	insertMode = false,
	shiftKeyToggle = false,
	hudDuration = 2500;

var actionMap = {
	'hintToggle' : function() {
		HUD.showForDuration('Link hints mode', hudDuration);
		activateLinkHintsMode(false, false); },

	'newTabHintToggle' : function() {
		HUD.showForDuration('Link hints mode', hudDuration);
		activateLinkHintsMode(true, false); },

	'tabForward': function() {
		safari.self.tab.dispatchMessage('changeTab', 1); },

	'tabBack': function() {
		safari.self.tab.dispatchMessage('changeTab', 0); },

	'scrollDown':
		function() { window.scrollBy(0, settings.scrollSize); },

	'scrollUp':
		function() { window.scrollBy(0, -settings.scrollSize); },

	'scrollLeft':
		function() { window.scrollBy(-settings.scrollSize, 0); },

	'scrollRight':
		function() { window.scrollBy(settings.scrollSize, 0); },

	'goBack':
		function() { window.history.back(); },

	'goForward':
		function() { window.history.forward(); },

	'reload':
		function() { window.location.reload(); },

	'openTab':
		function() { safari.self.tab.dispatchMessage('openTab'); },

	'closeTab':
		function() { safari.self.tab.dispatchMessage('closeTab', 0); },

	'closeTabReverse':
		function() { safari.self.tab.dispatchMessage('closeTab', 1); },

	'scrollDownHalfPage':
		function() { window.scrollBy(0, window.innerHeight / 2); },

	'scrollUpHalfPage':
		function() { window.scrollBy(0, window.innerHeight / -2); },

	'goToPageBottom':
		function() { window.scrollBy(0, document.body.scrollHeight); },

	'goToPageTop':
		function() { window.scrollBy(0, -document.body.scrollHeight); }
};

// Meant to be overridden, but still has to be copy/pasted from the original...
Mousetrap.stopCallback = function(e, element, combo) {
	// Escape key is special, no need to stop. Vimari-specific.
	if (combo === 'esc' || combo === 'ctrl+[') { return false; }

  // Preserve the behavior of allowing ex. ctrl-j in an input
  if (settings.modifier) { return false; }

	// if the element has the class "mousetrap" then no need to stop
	if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) {
		return false;
	}

    var tagName = element.tagName;
    var contentIsEditable = (element.contentEditable && element.contentEditable === 'true');

    // stop for input, select, and textarea
    return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA' || contentIsEditable;
};

// Set up key codes to event handlers
function bindKeyCodesToActions() {
	// Only add if topWindow... not iframe
	if (topWindow && !isExcludedUrl(settings.excludedUrls, document.URL)) {
		Mousetrap.reset();
		Mousetrap.bind('esc', enterNormalMode);
		Mousetrap.bind('ctrl+[', enterNormalMode);
		Mousetrap.bind('i', enterInsertMode);
		for (var actionName in actionMap) {
			if (actionMap.hasOwnProperty(actionName)) {
				var keyCode = getKeyCode(actionName);
				Mousetrap.bind(keyCode, executeAction(actionName), 'keydown');
			}
		}
	}
}

function enterNormalMode() {
	// Clear input focus
	document.activeElement.blur();

	// Clear link hints (if any)
	deactivateLinkHintsMode();

	// Re-enable if in insert mode
	insertMode = false;
	Mousetrap.bind('i', enterInsertMode);
}

// Calling it 'insert mode', but it's really just a user-triggered
// off switch for the actions.
function enterInsertMode() {
	insertMode = true;
	Mousetrap.unbind('i');
}

function executeAction(actionName) {
	return function() {
		// don't do anything if we're not supposed to
		if (linkHintsModeActivated || !extensionActive || insertMode)
			return;

		//Call the action function
		actionMap[actionName]();

		// Tell mousetrap to stop propagation
		return false;
	}
}

function unbindKeyCodes() {
	Mousetrap.reset();
}

// Adds an optional modifier to the configured key code for the action
function getKeyCode(actionName) {
	var keyCode = '';
	if(settings.modifier) {
		keyCode += settings.modifier + '+';
	}
	return keyCode + settings[actionName];
}

/*
 * Adds the given CSS to the page.
 * This function is required by vimium but depracated for vimari as the
 * css is pre loaded into the page.
 */
function addCssToPage(css) {
	return;
}

/*
 * Input or text elements are considered focusable and able to receive their own keyboard events,
 * and will enter enter mode if focused. Also note that the "contentEditable" attribute can be set on
 * any element which makes it a rich text editor, like the notes on jjot.com.
 * Note: we used to discriminate for text-only inputs, but this is not accurate since all input fields
 * can be controlled via the keyboard, particularly SELECT combo boxes.
 */
function isEditable(target) {
	if (target.getAttribute("contentEditable") === "true")
		return true;
	var focusableInputs = ["input", "textarea", "select", "button"];
	return focusableInputs.indexOf(target.tagName.toLowerCase()) >= 0;
}

/*
 * Embedded elements like Flash and quicktime players can obtain focus but cannot be programmatically
 * unfocused.
 */
function isEmbed(element) { return ["EMBED", "OBJECT"].indexOf(element.tagName) > 0; }

// ==========================
// Message handling functions
// ==========================

/*
 * All messages are handled by this function
 */
function handleMessage(msg) {
	// Attempt to call a function with the same name as the message name
	switch(msg.name) {
		case 'setSettings':
			setSettings(msg.message);
			break;
		case 'setActive':
			setActive(msg.message);
			break;
	}
}

/*
 * Callback to pass settings to injected script
 */
function setSettings(msg) {
	settings = msg;
	bindKeyCodesToActions();
}

/*
 * Enable or disable the extension on this tab
 */
function setActive(msg) {
	extensionActive = msg;
	if(msg) {
		bindKeyCodesToActions();
	} else {
		unbindKeyCodes();
	}
}

function isExcludedUrl(storedExcludedUrls, currentUrl) {
    var excludedUrls, regexp, url, _i, _len;
    excludedUrls = storedExcludedUrls.split(",");
    for (_i = 0, _len = excludedUrls.length; _i < _len; _i++) {
        url = excludedUrls[_i];
        regexp = new RegExp("^" + url.replace(/\*/g, ".*") + "$");
        if (currentUrl.match(regexp)) {
            return true;
        }
    }
    return false;
}

// Add event listener
safari.self.addEventListener("message", handleMessage, false);
// Retrieve settings
safari.self.tab.dispatchMessage('getSettings', '');

// Export to make it testable
window.isExcludedUrl = isExcludedUrl;
<|endoftext|>


<commit_before>app.test = app.test || {};

app.test.dataservicesReturnData = function () {

    //ARRANGE
    var retrievalTests = [
        { name: 'Retrieve session briefs', delegate: app.dataservice.session.getSessionBriefs},
        { name: 'Retrieve sessions', delegate: app.dataservice.session.getSessions},
        { name: 'Retrieve 1 session', delegate: app.dataservice.session.getSession, args: [1] },
        { name: 'Retrieve rooms', delegate: app.dataservice.lookup.getRooms },
        { name: 'Retrieve timeslots', delegate: app.dataservice.lookup.getTimeslots },
        { name: 'Retrieve tracks', delegate: app.dataservice.lookup.getTracks}
    ];

    //ACT

    module('Data Services results return data');

    test('Lookups url should return array of Rooms, Tracks, TimeSlots',
        function() {
            stop();
            app.dataservice.lookup.getLookups({
                success: function(data){
                    ok(!!data.Rooms && !!data.Tracks && !!data.TimeSlots,
                            'Got Rooms, Tracks, TimeSlots');
                    start();
                },
                error: function(data) {
                    ok(false, 'Failed with: ' + data.responseText);
                    start();
                }
            });
        })

    for (var i = 0; i < retrievalTests.length; i++) {
        var t = retrievalTests[i];
        test(t.name,
            function() {
                stop();
                var params = [];
                if (t.args) {
                    params = t.args;
                }
                params.unshift({
                        success: function(data) {
                            ok(!!data, 'Retrieved some data');
                            start();
                        },
                        error: function(data) {
                            ok(false, 'Failed with: ' + data.responseText);
                            start();
                        }
                });
                t.delegate.apply({}, params)
            })
    }
};

$(function () {
    app.test.dataservicesReturnData();
});
<commit_msg>Fixed dataservice iterating test to avoid capture issue. Reports # of items retrieved. Also use push instead of unshift.<commit_after>app.test = app.test || {};

app.test.dataservicesReturnData = function () {

    //ARRANGE
    var retrievalTests = [
        { name: 'Retrieve session briefs', delegate: app.dataservice.session.getSessionBriefs},
        { name: 'Retrieve sessions', delegate: app.dataservice.session.getSessions},
        { name: 'Retrieve 1 session', delegate: app.dataservice.session.getSession, args: [1] },
        { name: 'Retrieve rooms', delegate: app.dataservice.lookup.getRooms },
        { name: 'Retrieve timeslots', delegate: app.dataservice.lookup.getTimeslots },
        { name: 'Retrieve tracks', delegate: app.dataservice.lookup.getTracks}
    ];

    //ACT

    module('Data Services results return data');

    test('Lookups url should return array of Rooms, Tracks, TimeSlots',
        function() {
            stop();
            app.dataservice.lookup.getLookups({
                success: function(data){
                    ok(!!data.Rooms && !!data.Tracks && !!data.TimeSlots,
                            'Got Rooms, Tracks, TimeSlots');
                    start();
                },
                error: function(data) {
                    ok(false, 'Failed with: ' + data.responseText);
                    start();
                }
            });
        })

    var retrievalTest = function (t) {
        stop();
        var params = [];
        if (t.args) {
            params = t.args;
        }
        params.push({
            success: function (data) {
                var prefix = 'Test \"' + t.name + '" retrieved ';
                if (!!data && data.length > 0) {
                    ok(true, prefix + data.length+' items.');
                } else {
                    ok(!!data, prefix + 'one item.');
                }
                start();
            },
            error: function (data) {
                ok(false, 'Failed with: ' + data.responseText);
                start();
            }
        });
        t.delegate.apply({ }, params);
    };

    for (var i = 0; i < retrievalTests.length; i++) {
        var t = retrievalTests[i];
        test(t.name,
            (function (t) { return function() { retrievalTest(t); }; })(t));
    }
};

$(function () {
    app.test.dataservicesReturnData();
});
<|endoftext|>


<commit_before>#! /usr/bin/env node
var shell = require('shelljs');
var fs = require('fs-extra');
var path = require('path');

function exec(command, afterCb) {
shell.exec(command, function (code, stdout, stderr) {
    console.log('Exit code:', code);
    if (stdout) {
        console.log('Program output:', stdout);
    }
    if (stderr) {
        console.log('\x1b[31m%s\x1b[0m', 'Program stderr:', stderr);
    }
    if (afterCb && typeof afterCb === 'function') {
        afterCb();
    }
});
}

exec('npm run docs:build', function () {
    let sourceDirPath = path.join(__dirname, '../vuepress/.vuepress/dist');
    let targetDirPath = path.join(__dirname, '../docs');
    fs.move(sourceDirPath, targetDirPath, { overwrite: true }, err => {
        if (err) {
            return console.error('\x1b[31m%s\x1b[0m', err);
        }
        console.log('\x1b[32m%s\x1b[0m', 'Documentation was moved successfully to docs folder');
        exec('git add --all && git commit -m "Deploying documentation" && git push', function () {
            console.log('\x1b[32m%s\x1b[0m', 'Documentation was deployed successfully');
        });
      })
});<commit_msg>cubbles/cubbles#38 Improve deploy script<commit_after>#! /usr/bin/env node
var shell = require('shelljs');
var fs = require('fs-extra');
var path = require('path');

function exec(command, afterCb) {
shell.exec(command, function (code) {
    console.log('Exit code:', code);
    if (afterCb && typeof afterCb === 'function') {
        afterCb();
    }
});
}

exec('npm run docs:build', function () {
    let sourceDirPath = path.join(__dirname, '../vuepress/.vuepress/dist');
    let targetDirPath = path.join(__dirname, '../docs');
    fs.move(sourceDirPath, targetDirPath, { overwrite: true }, err => {
        if (err) {
            return console.error('\x1b[31m%s\x1b[0m', err);
        }
        console.log('\x1b[32m%s\x1b[0m', 'Documentation was moved successfully to docs folder');
        exec('git add --all && git commit -m "Deploying documentation" && git push', function () {
            console.log('\x1b[32m%s\x1b[0m', 'Documentation was deployed successfully');
        });
      })
});<|endoftext|>