<commit_before>var todos = new Array;
var doneDos = new Array;
show();

function show() {
    if (todos.length > 0) {
    var fill = '
';
    for (var i = 0; i < todos.length; i += 1) {
        fill += '
' + todos[i]
        + ' <button class=\'rem\' id=\'' + i + '\'>x</button>'
        + ' <button class=\'addBtn\' id=\'' + '10' + i + '\'>Done</button>'
        + '
';
    };
    fill += '
';
    } else {
        if(doneDos.length === 0){
        fill = '
There is nothing to do!
';
      } else {
        fill = '
You have done all ' + doneDos.length + ' these! GZ!
';
      }
    }
    document.getElementById("toDoList").innerHTML = fill;

    if (doneDos.length > 0) {
      var fillD = '
';
      for (var iii = 0; iii < doneDos.length; iii += 1) {
        fillD += '
' + doneDos[iii]
        + ' <button class="remFromAdd" id="' + iii + '">remove</button>'
        + '
';
      }
      fillD += '
';
    } else {
      fillD = "";
    }
    document.getElementById("ListOfDone").innerHTML = fillD;

    var buttons = document.getElementsByClassName('rem');
    for (var n = 0; n < buttons.length; n += 1) {
        buttons[n].addEventListener('click', removeElement);
    };
    var donebuttons = document.getElementsByClassName('addBtn');
    for (var x = 0; x < donebuttons.length; x += 1) {
        donebuttons[x].addEventListener('click', doneWItem);
    };
    var btnRemoveDone = document.getElementsByClassName('remFromAdd');
    for (var nnn = 0; nnn < btnRemoveDone.length; nnn += 1) {
        btnRemoveDone[nnn].addEventListener('click', removeDoneElement);
    };
};

var addElement = function() {
    var newText = document.getElementById("toDoText").value;
    if (newText != "") {
            todos.push(newText);
            show();
            document.getElementById("toDoText").value = "";
        }
    if (newText === "Why no jQuery") {
      location.href = "http://formatted.github.io/todowjQuery/";
    }
};

var removeElement = function() {
    var id = this.getAttribute('id');
    todos.splice(id, 1);
    show();
};

var removeDoneElement = function() {
    var id = this.getAttribute('id');
    doneDos.splice(id, 1);
    show();
};

var doneWItem = function() {
  var id = this.getAttribute('id');
  id = id - 100;
  doneDos.push(todos[id]);
  console.log(doneDos);
  todos.splice(id, 1);
  show();
}

var addOnEnter = function(e) {
    if (e.charCode == "13") {
        var newText = document.getElementById("toDoText").value;
        if (newText != "") {
            todos.push(newText);
            show();
            document.getElementById("toDoText").value = "";
        }
        if (newText === "Why no jQuery") {
          location.href = "http://formatted.github.io/todowjQuery/";
        }
    };
};
document.getElementById("addToList").addEventListener("click", addElement);
document.getElementById("toDoText").addEventListener("keypress", addOnEnter, false);
<commit_msg>corrected the url for jQuery gh-page<commit_after>var todos = new Array;
var doneDos = new Array;
show();

function show() {
    if (todos.length > 0) {
    var fill = '
';
    for (var i = 0; i < todos.length; i += 1) {
        fill += '
' + todos[i]
        + ' <button class=\'rem\' id=\'' + i + '\'>x</button>'
        + ' <button class=\'addBtn\' id=\'' + '10' + i + '\'>Done</button>'
        + '
';
    };
    fill += '
';
    } else {
        if(doneDos.length === 0){
        fill = '
There is nothing to do!
';
      } else {
        fill = '
You have done all ' + doneDos.length + ' these! GZ!
';
      }
    }
    document.getElementById("toDoList").innerHTML = fill;

    if (doneDos.length > 0) {
      var fillD = '
';
      for (var iii = 0; iii < doneDos.length; iii += 1) {
        fillD += '
' + doneDos[iii]
        + ' <button class="remFromAdd" id="' + iii + '">remove</button>'
        + '
';
      }
      fillD += '
';
    } else {
      fillD = "";
    }
    document.getElementById("ListOfDone").innerHTML = fillD;

    var buttons = document.getElementsByClassName('rem');
    for (var n = 0; n < buttons.length; n += 1) {
        buttons[n].addEventListener('click', removeElement);
    };
    var donebuttons = document.getElementsByClassName('addBtn');
    for (var x = 0; x < donebuttons.length; x += 1) {
        donebuttons[x].addEventListener('click', doneWItem);
    };
    var btnRemoveDone = document.getElementsByClassName('remFromAdd');
    for (var nnn = 0; nnn < btnRemoveDone.length; nnn += 1) {
        btnRemoveDone[nnn].addEventListener('click', removeDoneElement);
    };
};

var addElement = function() {
    var newText = document.getElementById("toDoText").value;
    if (newText != "") {
            todos.push(newText);
            show();
            document.getElementById("toDoText").value = "";
        }
    if (newText === "Why no jQuery") {
      location.href = "http://formatted.github.io/todowJQBootS/";
    }
};

var removeElement = function() {
    var id = this.getAttribute('id');
    todos.splice(id, 1);
    show();
};

var removeDoneElement = function() {
    var id = this.getAttribute('id');
    doneDos.splice(id, 1);
    show();
};

var doneWItem = function() {
  var id = this.getAttribute('id');
  id = id - 100;
  doneDos.push(todos[id]);
  console.log(doneDos);
  todos.splice(id, 1);
  show();
}

var addOnEnter = function(e) {
    if (e.charCode == "13") {
        var newText = document.getElementById("toDoText").value;
        if (newText != "") {
            todos.push(newText);
            show();
            document.getElementById("toDoText").value = "";
        }
        if (newText === "Why no jQuery") {
          location.href = "http://formatted.github.io/todowjQuery/";
        }
    };
};
document.getElementById("addToList").addEventListener("click", addElement);
document.getElementById("toDoText").addEventListener("keypress", addOnEnter, false);
<|endoftext|>


<commit_before>(() => {
    'use strict';

    var nextPlayer = "0";
    var moves = [];
    var winningCombos = [
        ["1", "2", "3"],
        ["4", "5", "6"],
        ["7", "8", "9"],
        ["1", "5", "9"],
        ["3", "5", "7"],
        ["1", "4", "7"],
        ["2", "5", "8"],
        ["3", "6", "9"]];

    window.play = (sq) => {
        if (sq.innerHTML !== "0" && sq.innerHTML !== "X") {
            drawMark(sq);
            saveMove(sq);
            if (isWinner()) {
                colourWinner();
            };
            changePlayer();
        }
    };

    var drawMark = td => td.innerHTML = nextPlayer;

    var saveMove = td => moves[td.id] = nextPlayer;

    var isWinner = () => (winningCombos.filter(isWinningCombo).length > 0);

    var isWinningCombo = combo => (combo.filter(sq => moves[sq] === nextPlayer).length === 3);

    var colourWinner = () => winningCombos.filter(isWinningCombo).forEach(colourCombo);

    var colourCombo = combo => combo.forEach(sq => document.getElementById(sq + "").style.backgroundColor = "green");

    var changePlayer = () => (nextPlayer === "0") ? nextPlayer = "X" : nextPlayer = "0";

})();<commit_msg>Revert last change<commit_after>(() => {
    'use strict';

    var player = "0";
    var moves = [];
    var winningCombos = [
        ["1", "2", "3"],
        ["4", "5", "6"],
        ["7", "8", "9"],
        ["1", "5", "9"],
        ["3", "5", "7"],
        ["1", "4", "7"],
        ["2", "5", "8"],
        ["3", "6", "9"]];

    window.play = (sq) => {
        if (sq.innerHTML !== "0" && sq.innerHTML !== "X") {
            drawMark(sq);
            saveMove(sq);
            if (isWinner()) {
                colourWinner();
            };
            changePlayer();
        }
    };

    var drawMark = td => td.innerHTML = player;

    var saveMove = td => moves[td.id] = player;

    var isWinner = () => (winningCombos.filter(isWinningCombo).length > 0);

    var isWinningCombo = combo => (combo.filter(sq => moves[sq] === player).length === 3);

    var colourWinner = () => winningCombos.filter(isWinningCombo).forEach(colourCombo);

    var colourCombo = combo => combo.forEach(sq => document.getElementById(sq + "").style.backgroundColor = "green");

    var changePlayer = () => (player === "0") ? player = "X" : player = "0";

})();<|endoftext|>


<commit_before>var parser = new DOMParser();
var my_games_list = {};
var my_wishlist = {};
var my_steam_name = null;
var table = null;
var page = 1;
var shouldScroll = true;

function getGames(callback, forceupdate) {
    chrome.extension.sendRequest({method: (forceupdate === true) ? "updateGames" : "getGames"}, function(settings) {
        games = settings.games;
        if ( games === undefined ) {
            games = {};
        }

        for (var i = 0; i < games.length; i++) {
            my_games_list[games[i].id] = true;
        }

        if (typeof callback == "function") {
            callback();
        }
    });
}

function getWishlist(callback, forceupdate) {
    chrome.extension.sendRequest({method: (forceupdate === true) ? "updateWishlist" : "getWishlist"}, function(settings) {
        wishlist = settings.wishlist;

        if (wishlist === undefined) {
            wishlist = {};
        }

        for (var i = 0; i < wishlist.length; i++) {
            my_wishlist[wishlist[i].id] = true;
        }

        if (typeof callback == "function") {
            callback();
        }
    });
}

function getUser(callback) {
    chrome.extension.sendRequest({method: "getSteamName"}, function(settings) {
        my_steam_name = settings.user;
        if (typeof callback == "function") {
            callback();
        }
    });
}

getUser(function() {
    getWishlist(function() {
        getGames(main);
    });
});

$("head").append('<link href="//netdna.bootstrapcdn.com/font-awesome/3.0/css/font-awesome.css" rel="stylesheet">');

function rearrangeTable(table, elements, desired_count, detach) {
    elements.each(function() {
        if (detach) {
            $(this).detach();
        }
        var row = $("> tbody > tr", table).filter(function() {
            return $(this).children("td").length < desired_count;
        }).first();

        if (row.length === 0) {
            row = $("
").appendTo(table);
        }
        row.append($(this));
    });
}

function getLinks(doc) {
    return $('td:not(.tabella-features1, tabella-features2) > a[href^="/GA/"]:has(img)', doc);
}

function getIdFromLink(elem) {
    td = $(elem).closest("td");
    var match = (/(?:apps|subs)\/(\d+)/).exec(td.attr("style"));
    return match[1];
}

function hasLinks(doc) {
    return getLinks(doc).length > 0;
}

function cleanUp(doc) {
    var links = getLinks(doc);

    links.each(function(){
        if (getIdFromLink(this) in my_games_list) {
            $(this).closest("td").remove();
        }
    });
}

function lineUp(doc) {
    var links = getLinks(doc);
    rearrangeTable(table, links.closest("td"), 4, true);
}

function showWishlist(doc) {
    var hilite = chrome.extension.getURL("wishlist.png");
    var links = getLinks(doc);

    links.each(function (){
        if (getIdFromLink(this) in my_wishlist) {
            $("img", this).attr("src", hilite);
        }
    });
}

function quickView(content) {
    if ($("div.quickview.overlay").length === 0) {
        var div = $('
').appendTo("body").addClass("quickview overlay")
        .css({
            opacity: 0.4,
            backgroundColor: "black",
            position: "fixed",
            top: 0,
            left: 0,
            width: "100%",
            height: "100%",
            zIndex: 25
        }).click(function() {
            $(".quickview").remove();
        });
    }

    if ($("div.quickview.waiting").length === 0) {
        $("
").addClass("quickview waiting tabella-forum").appendTo("body").css({
            opacity: 1,
            position: "fixed",
            top: "50%",
            left: "50%",
            width: "297px",
            height: "136px",
            marginLeft: "-149px",
            marginTop: "-68px",
            textAlign: "center",
            zIndex: 100
        }).append($('')).hide();
    }

    if ($("div.quickview.content").length === 0) {
        $("
").addClass("quickview content").appendTo("body").css({
            opacity: 1,
            position: "fixed",
            top: "50%",
            left: "50%",
            textAlign: "center",
            zIndex: 100
        }).hide();
    }

    $("div.quickview.overlay").show();
    if (content !== undefined) {
        handleSteamLinks(content);
        $("div.quickview.waiting").hide();
        $("div.quickview.content").show().empty().append(content).css({
            width: $(content).width(),
            height: $(content).height(),
            marginLeft: -($(content).width() / 2),
            marginTop: -($(content).height() / 2)
        });
    } else {
        $("div.quickview.waiting").show();
        $("div.quickview.content").hide();
    }
}

function handleSteamLinks(doc) {
    $('a[href^="http://store.steampowered.com/app/"]', doc).attr("target", "_blank");
}

function cleanHeader(doc) {
    var table = $("table.header", doc).find("tr:last").remove().end();

    // Remove Privacy Policy link?
    //table.find("td:nth-child(10)").remove();

    // Remove the text around points, we know what they are
    var points = table.find("td:eq(8)");
    var match = /\[([0-9,]+)\]/.exec(points.text());
    points.text(match[1]);

    // Remove Profile entry, we'll make the user image link to profile
    var cell = table.find("td:nth-child(5)");
    var link = cell.find("a").text("");
    cell.remove();

    // Move Logout to the end
    table.find("td:nth-child(6)").detach().appendTo(table.find("tr")).find("a").text("Logout");

    // Add Create GA link under points
    cell = table.find("td:nth-child(5)");
    var ga = cell.find("a");
    cell.remove();

    // Move profile image/points to the front
    table.find("td:nth-child(5), td:nth-child(6)").detach().prependTo(table.find("tr"))
        .filter(':last').append("
").append(ga).end() // Add create GA link under points
        .filter(':first').css("width", 32).find('img').wrap(link); // Link image to profile
}

function updateHeader(doc) {
    // Updated the table basedon changes in the table.
    cleanHeader(doc);
    $('table.header').replaceWith($('table.header', doc)).find("tr:last").remove();
}

function handleGiveawayForm(event) {
    $(this).find("button").attr("disabled", "disabled");
    $("#resp_message").remove();
    event.preventDefault();
    var form = event.target;
    $.post($(this).attr("action"), $(this).serialize(), function(data) {
        var resp = parser.parseFromString(data, "text/html");
        var respMsg = $("table ~ script", resp)[0].nextSibling.textContent;
        var div = $("
").text(respMsg);

        if (/You entered this Giveaway/.exec(respMsg) ||
            /You left this Giveaway/.exec(respMsg)) {
            div.css("color", "green");
        }
        else {
            div.css("color", "red");
        }

        var newForm = $('table:has(form[action^="/enterGA"],form[action^="/leaveGA"]) form', resp);
        newForm.submit(handleGiveawayForm);
        $(form).after(div).replaceWith(newForm);

        updateHeader(resp);
    });
}

function quickLook(data) {
    var doc = parser.parseFromString(data, "text/html");

    // Look for table with form (this means the giveaway is active)
    var _table = $('table:has(form[action^="/enterGA"],form[action^="/leaveGA"])', doc);
    if (_table.length !== 0) {
        $(_table).find("form").submit(handleGiveawayForm);
    }
    else {
        // Otherwise grab the info and the winner's list
        _table = $('table.tabella-forum:first, table.tabella-forum:last', doc);
        if ($(_table).length === 0) {
            _table = $('a[href^="/GA/"]', doc).closest('table:not(.riga3,.riga)').addClass("tabella-forum").css({
                padding: 5
            });
            if ($(_table).length !== 0) {
                quickEnter(_table);
            }
        }
    }
    quickView(_table);
}

function quickEnter(doc) {
    entry = $('a[href^="/GA/"]:has(b > u):not(.quick)', doc).addClass('quick');

    td = $("").css({
        textAlign: "center"
    }).appendTo($(entry).closest("tr").prev("tr"));

    $('').click(function(event) {
        event.preventDefault();
        window.open("http://store.steampowered.com/app/" + getIdFromLink($(this).closest(".riga")));
    }).append(" ").appendTo(td);

    $('').click(function(){
        event.preventDefault();
        quickView();
        $.get("http://www.galagiveaways.com/games/" + getIdFromLink($(this).closest(".riga")), quickLook);
    }).append(" ").appendTo(td);

    $('').click(function(event) {
        event.preventDefault();
        quickView();
        $.get($(this).closest("tr").next("tr").find("a").attr("href"), quickLook);
    }).appendTo(td);
}

function cleanGameList(doc) {
    if (hasLinks(doc)) {
        cleanUp(doc);
        showWishlist(doc);
        handleSteamLinks(doc);
        quickEnter(doc);
        // this needs to be the last line as it attachs stuff to the actual view
        lineUp(doc);
        shouldScroll = true;
    }
}

function getNextPage() {
    page += 1;
    shouldScroll = false;
    td = $("").css({
            verticalAlign: "middle",
            textAlign: "center"
        }).append($(''));
    rearrangeTable(table, td, 4, false);

    $.get("http://www.galagiveaways.com/home/" + page, function(data) {
        $('td.spinner').remove();
        cleanGameList(parser.parseFromString(data, "text/html"));
    });
}

function main() {
    var icon = $("").appendTo("body");

    icon.css({
        position: "fixed",
        top: $(window).innerHeight() - 21,
        left: $(window).innerWidth() - 21
    }).click(function(event){
        if ($(this).hasClass("icon-spin")) return;
        $(this).addClass('icon-spin');
        getGames(function() {
            getWishlist(function() {
                $(icon).removeClass('icon-spin');
                if (/^\/home/.test(window.location.pathname)) {
                    cleanGameList(document);
                }
            }, true);
        }, true);
    });

    $(window).resize(function() {
        icon.css({
            top: $(window).innerHeight() - 21,
            left: $(window).innerWidth() - 21
        });
    });

    $("
").css({
        width: "100%",
        position: "fixed",
        backgroundImage: "url(http://1-ps.googleusercontent.com/x/s.galagive.appspot.com/www.galagiveaways.com/img/xslate.jpg.pagespeed.ic.K9-NSGsDLG.jpg)",
        top: 0,
        left: 0
    }).hide().appendTo("body");

    cleanHeader(document);

    $(window).scroll(function(event) {
        if (window.pageYOffset >= 1) {
            $("div#iges_header").append($("table.header")).show();
        }
        else {
            if (shouldScroll)
            $("table.header").prependTo("body");
            $("div#iges_header").hide();
        }

        if (window.innerHeight + window.pageYOffset >= document.height && shouldScroll) {
            getNextPage();
        }
    });

    if (/^\/home/.test(window.location.pathname)) {
        // Store the table we are about to fuck up
        table = getLinks(document).closest("table");
        cleanGameList(document);
    }
    else if (/^\/games\/\d+/.test(window.location.pathname)) {
        quickEnter(document);
    }
    else if (/^\/profile/.test(window.location.pathname)) {
        $('a[href^="/GA/"] img').click(function(event){
            event.preventDefault();
            quickView();
            $.get($(this).closest("a").attr("href"), quickLook);
        });
    }
    else if (/^\/topic\/[a-f0-9]+/.test(window.location.pathname)) {
        $('.tabella-forum:not(:first) tr:nth-child(2) td:last-child, .tabella-forum tr:nth-child(3) td:last')
            .each(function() {
                $(this).html($(this).html().replace(/(\S+:\/\/\S+)/g, "$1"));
            });
    }
}<commit_msg>Scroll when we get to the footer, don't make me scroll through it.<commit_after>var parser = new DOMParser();
var my_games_list = {};
var my_wishlist = {};
var my_steam_name = null;
var table = null;
var page = 1;
var shouldScroll = true;

function getGames(callback, forceupdate) {
    chrome.extension.sendRequest({method: (forceupdate === true) ? "updateGames" : "getGames"}, function(settings) {
        games = settings.games;
        if ( games === undefined ) {
            games = {};
        }

        for (var i = 0; i < games.length; i++) {
            my_games_list[games[i].id] = true;
        }

        if (typeof callback == "function") {
            callback();
        }
    });
}

function getWishlist(callback, forceupdate) {
    chrome.extension.sendRequest({method: (forceupdate === true) ? "updateWishlist" : "getWishlist"}, function(settings) {
        wishlist = settings.wishlist;

        if (wishlist === undefined) {
            wishlist = {};
        }

        for (var i = 0; i < wishlist.length; i++) {
            my_wishlist[wishlist[i].id] = true;
        }

        if (typeof callback == "function") {
            callback();
        }
    });
}

function getUser(callback) {
    chrome.extension.sendRequest({method: "getSteamName"}, function(settings) {
        my_steam_name = settings.user;
        if (typeof callback == "function") {
            callback();
        }
    });
}

getUser(function() {
    getWishlist(function() {
        getGames(main);
    });
});

$("head").append('<link href="//netdna.bootstrapcdn.com/font-awesome/3.0/css/font-awesome.css" rel="stylesheet">');

function rearrangeTable(table, elements, desired_count, detach) {
    elements.each(function() {
        if (detach) {
            $(this).detach();
        }
        var row = $("> tbody > tr", table).filter(function() {
            return $(this).children("td").length < desired_count;
        }).first();

        if (row.length === 0) {
            row = $("
").appendTo(table);
        }
        row.append($(this));
    });
}

function getLinks(doc) {
    return $('td:not(.tabella-features1, tabella-features2) > a[href^="/GA/"]:has(img)', doc);
}

function getIdFromLink(elem) {
    td = $(elem).closest("td");
    var match = (/(?:apps|subs)\/(\d+)/).exec(td.attr("style"));
    return match[1];
}

function hasLinks(doc) {
    return getLinks(doc).length > 0;
}

function cleanUp(doc) {
    var links = getLinks(doc);

    links.each(function(){
        if (getIdFromLink(this) in my_games_list) {
            $(this).closest("td").remove();
        }
    });
}

function lineUp(doc) {
    var links = getLinks(doc);
    rearrangeTable(table, links.closest("td"), 4, true);
}

function showWishlist(doc) {
    var hilite = chrome.extension.getURL("wishlist.png");
    var links = getLinks(doc);

    links.each(function (){
        if (getIdFromLink(this) in my_wishlist) {
            $("img", this).attr("src", hilite);
        }
    });
}

function quickView(content) {
    if ($("div.quickview.overlay").length === 0) {
        var div = $('
').appendTo("body").addClass("quickview overlay")
        .css({
            opacity: 0.4,
            backgroundColor: "black",
            position: "fixed",
            top: 0,
            left: 0,
            width: "100%",
            height: "100%",
            zIndex: 25
        }).click(function() {
            $(".quickview").remove();
        });
    }

    if ($("div.quickview.waiting").length === 0) {
        $("
").addClass("quickview waiting tabella-forum").appendTo("body").css({
            opacity: 1,
            position: "fixed",
            top: "50%",
            left: "50%",
            width: "297px",
            height: "136px",
            marginLeft: "-149px",
            marginTop: "-68px",
            textAlign: "center",
            zIndex: 100
        }).append($('')).hide();
    }

    if ($("div.quickview.content").length === 0) {
        $("
").addClass("quickview content").appendTo("body").css({
            opacity: 1,
            position: "fixed",
            top: "50%",
            left: "50%",
            textAlign: "center",
            zIndex: 100
        }).hide();
    }

    $("div.quickview.overlay").show();
    if (content !== undefined) {
        handleSteamLinks(content);
        $("div.quickview.waiting").hide();
        $("div.quickview.content").show().empty().append(content).css({
            width: $(content).width(),
            height: $(content).height(),
            marginLeft: -($(content).width() / 2),
            marginTop: -($(content).height() / 2)
        });
    } else {
        $("div.quickview.waiting").show();
        $("div.quickview.content").hide();
    }
}

function handleSteamLinks(doc) {
    $('a[href^="http://store.steampowered.com/app/"]', doc).attr("target", "_blank");
}

function cleanHeader(doc) {
    var table = $("table.header", doc).find("tr:last").remove().end();

    // Remove Privacy Policy link?
    //table.find("td:nth-child(10)").remove();

    // Remove the text around points, we know what they are
    var points = table.find("td:eq(8)");
    var match = /\[([0-9,]+)\]/.exec(points.text());
    points.text(match[1]);

    // Remove Profile entry, we'll make the user image link to profile
    var cell = table.find("td:nth-child(5)");
    var link = cell.find("a").text("");
    cell.remove();

    // Move Logout to the end
    table.find("td:nth-child(6)").detach().appendTo(table.find("tr")).find("a").text("Logout");

    // Add Create GA link under points
    cell = table.find("td:nth-child(5)");
    var ga = cell.find("a");
    cell.remove();

    // Move profile image/points to the front
    table.find("td:nth-child(5), td:nth-child(6)").detach().prependTo(table.find("tr"))
        .filter(':last').append("
").append(ga).end() // Add create GA link under points
        .filter(':first').css("width", 32).find('img').wrap(link); // Link image to profile
}

function updateHeader(doc) {
    // Updated the table basedon changes in the table.
    cleanHeader(doc);
    $('table.header').replaceWith($('table.header', doc)).find("tr:last").remove();
}

function handleGiveawayForm(event) {
    $(this).find("button").attr("disabled", "disabled");
    $("#resp_message").remove();
    event.preventDefault();
    var form = event.target;
    $.post($(this).attr("action"), $(this).serialize(), function(data) {
        var resp = parser.parseFromString(data, "text/html");
        var respMsg = $("table ~ script", resp)[0].nextSibling.textContent;
        var div = $("
").text(respMsg);

        if (/You entered this Giveaway/.exec(respMsg) ||
            /You left this Giveaway/.exec(respMsg)) {
            div.css("color", "green");
        }
        else {
            div.css("color", "red");
        }

        var newForm = $('table:has(form[action^="/enterGA"],form[action^="/leaveGA"]) form', resp);
        newForm.submit(handleGiveawayForm);
        $(form).after(div).replaceWith(newForm);

        updateHeader(resp);
    });
}

function quickLook(data) {
    var doc = parser.parseFromString(data, "text/html");

    // Look for table with form (this means the giveaway is active)
    var _table = $('table:has(form[action^="/enterGA"],form[action^="/leaveGA"])', doc);
    if (_table.length !== 0) {
        $(_table).find("form").submit(handleGiveawayForm);
    }
    else {
        // Otherwise grab the info and the winner's list
        _table = $('table.tabella-forum:first, table.tabella-forum:last', doc);
        if ($(_table).length === 0) {
            _table = $('a[href^="/GA/"]', doc).closest('table:not(.riga3,.riga)').addClass("tabella-forum").css({
                padding: 5
            });
            if ($(_table).length !== 0) {
                quickEnter(_table);
            }
        }
    }
    quickView(_table);
}

function quickEnter(doc) {
    entry = $('a[href^="/GA/"]:has(b > u):not(.quick)', doc).addClass('quick');

    td = $("").css({
        textAlign: "center"
    }).appendTo($(entry).closest("tr").prev("tr"));

    $('').click(function(event) {
        event.preventDefault();
        window.open("http://store.steampowered.com/app/" + getIdFromLink($(this).closest(".riga")));
    }).append(" ").appendTo(td);

    $('').click(function(){
        event.preventDefault();
        quickView();
        $.get("http://www.galagiveaways.com/games/" + getIdFromLink($(this).closest(".riga")), quickLook);
    }).append(" ").appendTo(td);

    $('').click(function(event) {
        event.preventDefault();
        quickView();
        $.get($(this).closest("tr").next("tr").find("a").attr("href"), quickLook);
    }).appendTo(td);
}

function cleanGameList(doc) {
    if (hasLinks(doc)) {
        cleanUp(doc);
        showWishlist(doc);
        handleSteamLinks(doc);
        quickEnter(doc);
        // this needs to be the last line as it attachs stuff to the actual view
        lineUp(doc);
        shouldScroll = true;
    }
}

function getNextPage() {
    page += 1;
    shouldScroll = false;
    td = $("").css({
            verticalAlign: "middle",
            textAlign: "center"
        }).append($(''));
    rearrangeTable(table, td, 4, false);

    $.get("http://www.galagiveaways.com/home/" + page, function(data) {
        $('td.spinner').remove();
        cleanGameList(parser.parseFromString(data, "text/html"));
    });
}

function main() {
    var icon = $("").appendTo("body");

    icon.css({
        position: "fixed",
        top: $(window).innerHeight() - 21,
        left: $(window).innerWidth() - 21
    }).click(function(event){
        if ($(this).hasClass("icon-spin")) return;
        $(this).addClass('icon-spin');
        getGames(function() {
            getWishlist(function() {
                $(icon).removeClass('icon-spin');
                if (/^\/home/.test(window.location.pathname)) {
                    cleanGameList(document);
                }
            }, true);
        }, true);
    });

    $(window).resize(function() {
        icon.css({
            top: $(window).innerHeight() - 21,
            left: $(window).innerWidth() - 21
        });
    });

    $("
").css({
        width: "100%",
        position: "fixed",
        backgroundImage: "url(http://1-ps.googleusercontent.com/x/s.galagive.appspot.com/www.galagiveaways.com/img/xslate.jpg.pagespeed.ic.K9-NSGsDLG.jpg)",
        top: 0,
        left: 0
    }).hide().appendTo("body");

    cleanHeader(document);

    $(window).scroll(function(event) {
        if (window.pageYOffset >= 1) {
            $("div#iges_header").append($("table.header")).show();
        }
        else {
            if (shouldScroll)
            $("table.header").prependTo("body");
            $("div#iges_header").hide();
        }

        if (window.innerHeight + window.pageYOffset >= (document.height - $("table:last").height()) && shouldScroll) {
            getNextPage();
        }
    });

    if (/^\/home/.test(window.location.pathname)) {
        // Store the table we are about to fuck up
        table = getLinks(document).closest("table");
        cleanGameList(document);
    }
    else if (/^\/games\/\d+/.test(window.location.pathname)) {
        quickEnter(document);
    }
    else if (/^\/profile/.test(window.location.pathname)) {
        $('a[href^="/GA/"] img').click(function(event){
            event.preventDefault();
            quickView();
            $.get($(this).closest("a").attr("href"), quickLook);
        });
    }
    else if (/^\/topic\/[a-f0-9]+/.test(window.location.pathname)) {
        $('.tabella-forum:not(:first) tr:nth-child(2) td:last-child, .tabella-forum tr:nth-child(3) td:last')
            .each(function() {
                $(this).html($(this).html().replace(/(\S+:\/\/\S+)/g, "$1"));
            });
    }
}<|endoftext|>


<commit_before>var request = require("request"),
    fs = require("fs"),
    moment = require('moment'),
    Bunzip = require('seek-bzip'),
    utility = require('./utility'),
    matches = utility.matches,
    AWS = require('aws-sdk'),
    winston = require('winston'),
    async = require('async');
var kue = utility.kue;
var jobs = utility.jobs;
var replay_dir = "replays/"
var retrievers = process.env.RETRIEVER_HOST.split(",")

if (!fs.existsSync(replay_dir)) {
    fs.mkdir(replay_dir)
}
var transports = [new(winston.transports.Console)(),
    new(winston.transports.File)({
        filename: 'parser.log',
        level: 'info'
    })
]
var logger = new(winston.Logger)({
    transports: transports
});
utility.clearActiveJobs('parse', function(err) {
    jobs.process('parse', 3, function(job, done) {
        parseReplay(job, done)
    })
})

/*
 * Downloads a match replay
 */

function download(job, cb) {
    var match_id = job.data.payload.match_id
    var fileName = replay_dir + match_id + ".dem"
    if (fs.existsSync(fileName)) {
        logger.info("[PARSER] found local replay for match %s", match_id)
        cb(null, fileName);
    }
    else {
        getReplayUrl(job, function(err, url) {
            if (err) {
                return cb(err)
            }
            logger.info("[PARSER] downloading from %s", url)
            var t1 = new Date().getTime();
            request({
                url: url,
                encoding: null
            }, function(err, response, body) {
                if (err || response.statusCode !== 200) {
                    logger.info("[PARSER] failed to download from %s", url)
                    return cb("DOWNLOAD TIMEOUT")
                }
                else {
                    var t2 = new Date().getTime();
                    logger.info("[PARSER] dl time: %s", (t2 - t1) / 1000)
                    try {
                        var decomp = Bunzip.decode(body)
                        fs.writeFile(fileName, decomp, function(err) {
                            if (err) {
                                return cb(err)
                            }
                            var t3 = new Date().getTime();
                            logger.info("[PARSER] decomp time: %s", (t3 - t2) / 1000)
                            logger.info("[PARSER] downloaded/decompressed replay for match %s", match_id)
                            var archiveName = match_id + ".dem.bz2"
                            uploadToS3(archiveName, body, function(err) {
                                return cb(err, fileName)
                            })
                        })
                    }
                    catch (e) {
                        return cb(e)
                    }
                }
            })
        })
    }
}

function getReplayUrl(job, cb) {
    if ('url' in job.data) {
        return cb(null, job.data.url)
    }
    var match = job.data.payload
    if (match.start_time > moment().subtract(7, 'days').format('X')) {
        var t = new Date().getMinutes();
        var retriever = t % retrievers.length;
        logger.info(retriever);
        utility.getData(retrievers[retriever] + "?match_id=" + job.data.payload.match_id, function(body) {
            var url = "http://replay" + body.match.cluster + ".valve.net/570/" + match.match_id + "_" + body.match.replaySalt + ".dem.bz2";
            job.data['url'] = url;
            job.update();
            return cb(url);
        })
    }
    else {
        getS3URL(match.match_id, function(err, url) {
            cb(err, url)
        })
    }
}

function getS3URL(match_id, cb) {
    if (process.env.AWS_S3_BUCKET) {
        var archiveName = match_id + ".dem.bz2"
        var s3 = new AWS.S3()
        var params = {
            Bucket: process.env.AWS_S3_BUCKET,
            Key: archiveName
        }
        s3.headObject(params, function(err, data) {
            if (!err) {
                var url = s3.getSignedUrl('getObject', params);
                cb(null, url)
            }
            else {
                logger.info("[S3] %s not in S3", match_id)
                cb("S3 UNAVAILABLE")
            }
        })
    }
    else {
        cb("S3 UNAVAILABLE")
    }
}

function uploadToS3(archiveName, body, cb) {
        if (process.env.AWS_S3_BUCKET) {
            var s3 = new AWS.S3()
            var params = {
                Bucket: process.env.AWS_S3_BUCKET,
                Key: archiveName
            }
            s3.headObject(params, function(err, data) {
                if (err) {
                    params.Body = body
                    s3.putObject(params, function(err, data) {
                        if (err) {
                            logger.info('[S3] could not upload to S3')
                        }
                        else {
                            logger.info('[S3] Successfully uploaded replay to S3: %s ', archiveName)
                        }
                        cb(err)
                    })
                }
                else {
                    logger.info('[S3] replay already exists in S3')
                    cb(err)
                }
            })
        }
        else {
            logger.info("[S3] S3 not defined (skipping upload)")
            cb(null)
        }
    }
    /*
     * Parses a replay for a match
     */

function parseReplay(job, cb) {
    var match_id = job.data.payload.match_id
    logger.info("[PARSER] match %s", match_id)
    matches.findOne({
        match_id: match_id
    }, function(err, doc) {
        if (doc && doc.parsed_data) {
            cb(null);
        }
        else {
            download(job, function(err, fileName) {
                if (err) {
                    logger.info("[PARSER] Error for match %s: %s", match_id, err)
                    if (job.attempts.remaining === 0 || err === "S3 UNAVAILABLE") {
                        matches.update({
                            match_id: job.data.payload.match_id
                        }, {
                            $set: {
                                parse_status: 1
                            }
                        })
                        job.failed().error(err);
                    }
                    return cb(err);
                }
                utility.runParse(fileName, function(err, output) {
                    if (!err) {
                        //process parser output
                        matches.update({
                            match_id: match_id
                        }, {
                            $set: {
                                parsed_data: JSON.parse(output),
                                parse_status: 2
                            }
                        })
                    }
                    return cb(err);
                })
            })
        }
    })
}
<commit_msg>added error check to retriever response<commit_after>var request = require("request"),
    fs = require("fs"),
    moment = require('moment'),
    Bunzip = require('seek-bzip'),
    utility = require('./utility'),
    matches = utility.matches,
    AWS = require('aws-sdk'),
    winston = require('winston'),
    async = require('async');
var kue = utility.kue;
var jobs = utility.jobs;
var replay_dir = "replays/"
var retrievers = process.env.RETRIEVER_HOST.split(",")

if (!fs.existsSync(replay_dir)) {
    fs.mkdir(replay_dir)
}
var transports = [new(winston.transports.Console)(),
    new(winston.transports.File)({
        filename: 'parser.log',
        level: 'info'
    })
]
var logger = new(winston.Logger)({
    transports: transports
});
utility.clearActiveJobs('parse', function(err) {
    jobs.process('parse', 3, function(job, done) {
        parseReplay(job, done)
    })
})

/*
 * Downloads a match replay
 */

function download(job, cb) {
    var match_id = job.data.payload.match_id
    var fileName = replay_dir + match_id + ".dem"
    if (fs.existsSync(fileName)) {
        logger.info("[PARSER] found local replay for match %s", match_id)
        cb(null, fileName);
    }
    else {
        getReplayUrl(job, function(err, url) {
            if (err) {
                return cb(err)
            }
            logger.info("[PARSER] downloading from %s", url)
            var t1 = new Date().getTime();
            request({
                url: url,
                encoding: null
            }, function(err, response, body) {
                if (err || response.statusCode !== 200) {
                    logger.info("[PARSER] failed to download from %s", url)
                    return cb("DOWNLOAD TIMEOUT")
                }
                else {
                    var t2 = new Date().getTime();
                    logger.info("[PARSER] dl time: %s", (t2 - t1) / 1000)
                    try {
                        var decomp = Bunzip.decode(body)
                        fs.writeFile(fileName, decomp, function(err) {
                            if (err) {
                                return cb(err)
                            }
                            var t3 = new Date().getTime();
                            logger.info("[PARSER] decomp time: %s", (t3 - t2) / 1000)
                            logger.info("[PARSER] downloaded/decompressed replay for match %s", match_id)
                            var archiveName = match_id + ".dem.bz2"
                            uploadToS3(archiveName, body, function(err) {
                                return cb(err, fileName)
                            })
                        })
                    }
                    catch (e) {
                        return cb(e)
                    }
                }
            })
        })
    }
}

function getReplayUrl(job, cb) {
    if ('url' in job.data) {
        return cb(null, job.data.url)
    }
    var match = job.data.payload
    if (match.start_time > moment().subtract(7, 'days').format('X')) {
        var t = new Date().getMinutes();
        var retriever = t % retrievers.length;
        logger.info(retriever);
        utility.getData(retrievers[retriever] + "?match_id=" + job.data.payload.match_id, function(body) {
            if (body && body.match) {
                var url = "http://replay" + body.match.cluster + ".valve.net/570/" + body.match.match_id + "_" + body.match.replaySalt + ".dem.bz2";
                job.data['url'] = url;
                job.update();
                return cb(url);
            }
            else {
                return cb(true)
            }
        })
    }
    else {
        getS3URL(match.match_id, function(err, url) {
            cb(err, url)
        })
    }
}

function getS3URL(match_id, cb) {
    if (process.env.AWS_S3_BUCKET) {
        var archiveName = match_id + ".dem.bz2"
        var s3 = new AWS.S3()
        var params = {
            Bucket: process.env.AWS_S3_BUCKET,
            Key: archiveName
        }
        s3.headObject(params, function(err, data) {
            if (!err) {
                var url = s3.getSignedUrl('getObject', params);
                cb(null, url)
            }
            else {
                logger.info("[S3] %s not in S3", match_id)
                cb("S3 UNAVAILABLE")
            }
        })
    }
    else {
        cb("S3 UNAVAILABLE")
    }
}

function uploadToS3(archiveName, body, cb) {
        if (process.env.AWS_S3_BUCKET) {
            var s3 = new AWS.S3()
            var params = {
                Bucket: process.env.AWS_S3_BUCKET,
                Key: archiveName
            }
            s3.headObject(params, function(err, data) {
                if (err) {
                    params.Body = body
                    s3.putObject(params, function(err, data) {
                        if (err) {
                            logger.info('[S3] could not upload to S3')
                        }
                        else {
                            logger.info('[S3] Successfully uploaded replay to S3: %s ', archiveName)
                        }
                        cb(err)
                    })
                }
                else {
                    logger.info('[S3] replay already exists in S3')
                    cb(err)
                }
            })
        }
        else {
            logger.info("[S3] S3 not defined (skipping upload)")
            cb(null)
        }
    }
    /*
     * Parses a replay for a match
     */

function parseReplay(job, cb) {
    var match_id = job.data.payload.match_id
    logger.info("[PARSER] match %s", match_id)
    matches.findOne({
        match_id: match_id
    }, function(err, doc) {
        if (doc && doc.parsed_data) {
            cb(null);
        }
        else {
            download(job, function(err, fileName) {
                if (err) {
                    logger.info("[PARSER] Error for match %s: %s", match_id, err)
                    if (job.attempts.remaining === 0 || err === "S3 UNAVAILABLE") {
                        matches.update({
                            match_id: job.data.payload.match_id
                        }, {
                            $set: {
                                parse_status: 1
                            }
                        })
                        job.failed().error(err);
                    }
                    return cb(err);
                }
                utility.runParse(fileName, function(err, output) {
                    if (!err) {
                        //process parser output
                        matches.update({
                            match_id: match_id
                        }, {
                            $set: {
                                parsed_data: JSON.parse(output),
                                parse_status: 2
                            }
                        })
                    }
                    return cb(err);
                })
            })
        }
    })
}
<|endoftext|>


<commit_before>$( document ).ready(function() {

var thumbApiUrl="http://jsonplaceholder.typicode.com/photos";

AjaxThumbNails();

  $('.btn').click(function(){
    AjaxThumbNails()
  });

  // ajaxcall(loopappened(append(scoreGenerate)))

  function AjaxThumbNails(){
    $.ajax({
      url:thumbApiUrl,
      dataType:"JSON",
      type: "Get",
      success: function(resp){loopAddThumbnail(resp)},
      error: function(err){alert('Error: '+ err)}
    });
  }

  function loopAddThumbnail(resp){
   var resp = resp;
    for (var i = 0; i < 6; i++) {
     var thumbnailUrl = resp[i].thumbnailUrl;
      addThumbnail(thumbnailUrl)
    };
  };

  function addThumbnail(thumbUrl){
    $(".thumbnails-container").append(
      $("<div/>")
      .addClass("thumb-well")
      .append($("<img/>").attr('src',thumbUrl))
      .append($("<p/>").text(scoreGenerate()))
      )
  };

  function scoreGenerate(){
    var score = Math.floor((Math.random()*100)+ 1);
    return score
  };

});<commit_msg>fix bug with loop<commit_after>$( document ).ready(function() {
var stopper = 0
var thumbApiUrl="http://jsonplaceholder.typicode.com/photos";

//load ajax call
AjaxThumbNails();

//click event ajax call
  $('.btn').click(function(){
    AjaxThumbNails()
  });

//methods structure
// ajaxcall(loopappened(append(scoreGenerate)))

  function AjaxThumbNails(){
    $.ajax({
      url:thumbApiUrl,
      dataType:"JSON",
      type: "Get",
      success: function(resp){loopAddThumbnail(resp)},
      error: function(err){alert('Error: '+ err)}
    });
  }

  function loopAddThumbnail(resp){
   var resp = resp;
   var wheretostop = stopper;
    for (var i = stopper; i < wheretostop + 6 ; i++) {
     var thumbnailUrl = resp[i].thumbnailUrl;
      addThumbnail(thumbnailUrl)
      stopper += 1
    };
  };

  function addThumbnail(thumbUrl){
    $(".thumbnails-container").append(
      $("<div/>")
      .addClass("thumb-well")
      .append($("<img/>").attr('src',thumbUrl))
      .append($("<p/>").text(scoreGenerate()))
      )
  };

  function scoreGenerate(){
    var score = Math.floor((Math.random()*100)+ 1);
    return score
  };

});<|endoftext|>


<commit_before>/*jshint esnext: true */
module.exports = {
  getCommentSections: function(contents) {
    var sections = [];
    var parts = contents.split(/\/\*\*/g);
    for (var i=0; i<parts.length; i++) {
      var endCommentLocation = parts[i].indexOf("*/");
      if (endCommentLocation > -1) {
        sections.push(parts[i].substring(0, endCommentLocation));
      }
    }
    return sections;
  },
  clean: function(line) {
    return line.replace(/\s\*\s/gm, "").trim();
  },
  addClassCore: function(cls, comment, filename) {
    var rgx = /[\s\S]*@class ([a-zA-Z\.]+)[\s\S]*@extends ([a-zA-Z\.]+)([\s\S]*)@example([\s\S]*)/gm;
    var props = rgx.exec(comment);
    if (props && props.length === 5) {
      cls.name = this.clean(props[1]);
      cls.ext = this.clean(props[2]);
      cls.comments = this.clean(props[3]);
      cls.example = this.clean(props[4]);
    } else {
      process.stderr.write(filename + " : couldn't find all core properties @class, @extends, @example... missing something?\n");
    }
    return cls;
  },
  addClassProp: function(cls, comment, filename) {
    var rgx = /@prop \{([^\}]*)\} ([^\s]*) \[(.*)\]([\s\S]*)/gm;
    var props = rgx.exec(comment);
    if (props && props.length === 5) {
      if (!cls.properties) {
        cls.properties = [];
      }
      cls.properties.push({
        type: this.clean(props[1]),
        name: this.clean(props[2]),
        def: this.clean(props[3]),
        comments: this.clean(props[4])
      });
    }
    return cls;
  },
  parse: function(contents, filename) {
    if (contents.indexOf("@class") < 0) return undefined;
    var comments = this.getCommentSections(contents);
    var cls = {};
    for (var i=0; i<comments.length; i++) {
      var comment = comments[i];
      if (comment.indexOf("@class") > -1) {
        cls = this.addClassCore(cls, comment, filename);
      } else if (comment.indexOf("@prop") > -1) {
        cls = this.addClassProp(cls, comment, filename);
      }
    }
    return cls;
  }

};
<commit_msg>Updated parser to parse @link directives and to convert them to HTML anchor tags.<commit_after>/*jshint esnext: true */
module.exports = {
  getCommentSections: function(contents) {
    var sections = [];
    var parts = contents.split(/\/\*\*/g);
    for (var i=0; i<parts.length; i++) {
      var endCommentLocation = parts[i].indexOf("*/");
      if (endCommentLocation > -1) {
        sections.push(parts[i].substring(0, endCommentLocation));
      }
    }
    return sections;
  },
  clean: function(line) {
    return line.replace(/\s\*\s/gm, "").trim();
  },
  parseLinks: function(line) {
    var rgx = /\{@link ([^\s\}]+){1}( [^\}]+)?\}/gm; // parse @link directives
    return line.replace(rgx, function(match, href, content) {
      var target = href.startsWith('#') ? '_self' : '_blank',
          text = (content || href).trim();
      return '' + text + '';
    });
  },
  addClassCore: function(cls, comment, filename) {
    var rgx = /[\s\S]*@class ([a-zA-Z\.]+)[\s\S]*@extends ([a-zA-Z\.]+)([\s\S]*)@example([\s\S]*)/gm;
    var props = rgx.exec(comment);
    if (props && props.length === 5) {
      cls.name = this.clean(props[1]);
      cls.ext = this.clean(props[2]);
      cls.comments = this.parseLinks(this.clean(props[3]));
      cls.example = this.clean(props[4]);
    } else {
      process.stderr.write(filename + " : couldn't find all core properties @class, @extends, @example... missing something?\n");
    }
    return cls;
  },
  addClassProp: function(cls, comment, filename) {
    var rgx = /@prop \{([^\}]*)\} ([^\s]*) \[(.*)\]([\s\S]*)/gm;
    var props = rgx.exec(comment);
    if (props && props.length === 5) {
      if (!cls.properties) {
        cls.properties = [];
      }
      cls.properties.push({
        type: this.clean(props[1]),
        name: this.clean(props[2]),
        def: this.clean(props[3]),
        comments: this.parseLinks(this.clean(props[4]))
      });
    }
    return cls;
  },
  parse: function(contents, filename) {
    if (contents.indexOf("@class") < 0) return undefined;
    var comments = this.getCommentSections(contents);
    var cls = {};
    for (var i=0; i<comments.length; i++) {
      var comment = comments[i];
      if (comment.indexOf("@class") > -1) {
        cls = this.addClassCore(cls, comment, filename);
      } else if (comment.indexOf("@prop") > -1) {
        cls = this.addClassProp(cls, comment, filename);
      }
    }
    return cls;
  }

};
<|endoftext|>


<commit_before>/**
 * ConfirmationModal test
 */

import React from 'react';

import { expect } from 'chai';
import { describe, beforeEach, it } from '@bigtest/mocha';
import { mountWithContext } from '../../../tests/helpers';

import ConfirmationModal from '../ConfirmationModal';
import ConfirmationModalInteractor from './interactor';

describe.only('ConfirmationModal', () => {
  const confirmationModal = new ConfirmationModalInteractor();
  let confirmed;
  let cancelled;

  const message = 'Something will happen if you do this.';
  const heading = 'Are you sure?';
  const cancelLabel = 'Cancel this action';
  const confirmLabel = 'Confirm this action';

  beforeEach(async () => {
    confirmed = false;
    cancelled = false;

    await mountWithContext(
      <ConfirmationModal
        open
        id="confirmation-modal-test"
        heading={heading}
        message={message}
        onConfirm={() => { confirmed = true; }}
        onCancel={() => { cancelled = true; }}
        cancelLabel={cancelLabel}
        confirmLabel={confirmLabel}
      />
    );
  });

  describe('When clicking the confirm button', () => {
    beforeEach(async () => {
      await confirmationModal.confirmButton.click();
    });

    it('The onConfirm callback should be fired', () => {
      expect(confirmed).to.be.true;
    });
  });

  describe('When clicking the cancel button', () => {
    beforeEach(async () => {
      await confirmationModal.cancelButton.click();
    });

    it('The onCancel callback should be fired', () => {
      expect(cancelled).to.be.true;
    });
  });
});
<commit_msg>Minor<commit_after>/**
 * ConfirmationModal test
 */

import React from 'react';

import { expect } from 'chai';
import { describe, beforeEach, it } from '@bigtest/mocha';
import { mountWithContext } from '../../../tests/helpers';

import ConfirmationModal from '../ConfirmationModal';
import ConfirmationModalInteractor from './interactor';

describe('ConfirmationModal', () => {
  const confirmationModal = new ConfirmationModalInteractor();
  let confirmed;
  let cancelled;

  const message = 'Something will happen if you do this.';
  const heading = 'Are you sure?';
  const cancelLabel = 'Cancel this action';
  const confirmLabel = 'Confirm this action';

  beforeEach(async () => {
    confirmed = false;
    cancelled = false;

    await mountWithContext(
      <ConfirmationModal
        open
        id="confirmation-modal-test"
        heading={heading}
        message={message}
        onConfirm={() => { confirmed = true; }}
        onCancel={() => { cancelled = true; }}
        cancelLabel={cancelLabel}
        confirmLabel={confirmLabel}
      />
    );
  });

  describe('When clicking the confirm button', () => {
    beforeEach(async () => {
      await confirmationModal.confirmButton.click();
    });

    it('The onConfirm callback should be fired', () => {
      expect(confirmed).to.be.true;
    });
  });

  describe('When clicking the cancel button', () => {
    beforeEach(async () => {
      await confirmationModal.cancelButton.click();
    });

    it('The onCancel callback should be fired', () => {
      expect(cancelled).to.be.true;
    });
  });
});
<|endoftext|>


<commit_before>(function () { /* Begin of privacy scope */
    "use strict";

    var
        gpfI = gpf.interfaces;

    //region ITokenizer

    gpfI.ITokenizer = gpfI.Interface.extend({

        /**
         * Submit a character to the tokenizer, result indicates if the token
         * is recognized
         *
         * @param {string} char One character to analyze
         * @returns {number} < 0 means won't recognize
         *                     0 means need more chars
         *                   > 0 means a token is recognized (length returned)
         *
         * NOTE: if the result is positive, you may submit more chars until
         */
        write: function (char) {
            gpf.interfaces.ignoreParameter(char);
            return 0;
        }

    });

    // endregion

    //region Pattern

    /*
     * Pattern 'grammar'
     *
     * pattern
     *      : expression+
     *
     * expression
     *      : item ( '|' item )*
     *
     * item
     *      : match count?
     *
     * count
     *      : '?'
     *      | '*'
     *      | '+'
     *      | '{' <number> '}'
     *
     * match
     *      : '[' char_match_include
     *      | '(' expression ')'
     *      | char
     *
     * char_match_include : '^' char_match_exclude
     *                    | ']'
     *                    | char char_range_sep? char_match_include
     *
     * char_match_exclude : ']'
     *                    | char char_range_sep? char_match_exclude
     *
     * char_range_sep : '-' char
     *
     * char : '\' escaped_char
     *      | <any char but ?*+{[(-[>
     */

/*
    var
        // abc
        _sample1 = {seq: "abc"},
        // [a-z]
        _sample2 = {inc: "abc...xyz"},
        // [a-z^de]
        _sample3 = {inc: "abc...xyz", exc: "de"},
        // a|b|c
        _sample4 = {or: [{seq: "a"}, {seq: "b"}, {seq: "c"}]}
        // ? => max: 1
        // * => min:0
        // + => min:1
        // Each item is connected to
        // - parent item: parent: {}
        // - next item: next: {}
    ;
*/

    var
        PatternItem = gpf.Class.extend({

            _type: -1,
            _parent: null,
            _next: null,
            _min: null,
            _max: null,

            init: function (type) {
                this._type = type;
            },

            type: function () {
                return this._type;
            },

            add: function (char, inRange) {
                gpf.interfaces.ignoreParameter(char);
                gpf.interfaces.ignoreParameter(inRange);
            },

            finalize: function () {
            }

        }),

        PatternSimpleItem  = gpf.Class.extend({

            _seq: "",

            init: function () {
                this._super(PatternItem.SIMPLE);
                this._seq = [];
            },

            add: function (char, inRange) {
                gpf.interfaces.ignoreParameter(inRange);
                this._seq.push(char);
            },

            finalize: function () {
                this._seq = this._seq.join("");
            }

        }),

        PatternRangeItem = gpf.Class.extend({

            _inc: "",
            _exc: null,

            init: function () {
                this._super(PatternItem.RANGE);
                this._inc = [];
            },

            add: function (char, inRange) {
                var
                    arrayOfChars,
                    first,
                    last,
                    idx;
                if (this._exc) {
                    arrayOfChars = this._exc;
                } else {
                    arrayOfChars = this._inc;
                }
                if (inRange) {
                    first = arrayOfChars[arrayOfChars.length - 1].charCodeAt(0);
                    last = char.charCodeAt(0);
                    for (idx = first + 1; idx < last; ++idx) {
                        arrayOfChars.push(String.fromCharCode(idx));
                    }
                    arrayOfChars.push(char);
                } else {
                    // First char of a range
                    arrayOfChars.push(char);
                }
            },

            finalize: function () {
                this._inc = this._inc.join("");
                if (this._exc) {
                    this._exc = this._exc.join("");
                }
            }

        });

    PatternItem.SIMPLE = 0;
    PatternItem.RANGE = 1;
    PatternItem.CHOICE = 2;

    PatternItem.create = function (type) {
        if (PatternItem.SIMPLE === type) {
            return new PatternSimpleItem();
        } else if (PatternItem.SIMPLE === type) {
            return new PatternRangeItem();
        } else {
            return new PatternItem(type);
        }
    };

    var PatternParserContext = gpf.Class.extend({

        _root: null,
        _item : null,
        _inRange: false,
        _afterChar: null,

        parse: null, // Will be overridden

        init: function() {
            this.parse = this._stateItem;
        },

        get: function () {
            if (this.parse !== this._stateItem
                && this.parse !== this._stateCount) {
                throw {
                    message: "Invalid syntax"
                };
            }
            this._root.finalize();
            return this._root;
        },

        // Get or create the item corresponding to the requested type
        _getItem: function (type) {
            var item = this._item;
            if (null === item || type !== item.type()) {
                if (null !== item) {
                    item.finalize();
                }
                item = this._item = PatternItem.create(type);
            }
            return item;
        },

        _stateItem: function (char) {
            if ("[" === char) {
                this.parse = this._stateCharMatchRange;
            } else {
                this._getItem(PatternItem.SIMPLE);
                this._afterChar = this._stateCount;
                this._stateChar(char);
            }
        },

        _stateCharMatchRange: function (char) {
            var curItem = this._getItem(PatternItem.RANGE);
            if ("^" === char && !curItem._exc) {
                curItem._exc = [];
                // this.parse = this._stateCharMatchRange;
            } else if ("]" === char) {
                this.parse = this._stateCount;
            } else {
                this._inRange = false;
                this._afterChar = this._stateCharRangeSep;
                this._stateChar(char);
            }
        },

        _stateCharRangeSep: function (char) {
            if ("-" === char) {
                this._inRange = true;
                this._afterChar = this._stateCharMatchRange;
                this.parse = this._stateChar;
            } else {
                this._stateCharMatchRange(char);
            }
        },

        _stateChar: function (char) {
            if ("\\" === char) {
                this.parse = this.stateEscapedChar;
            } else {
                this._item.add(char, this._inRange);
                this.parse = this._afterChar;
            }
        },

        stateEscapedChar: function (char) {
            this._item.add(char, this._inRange);
            this.parse = this._afterChar;
        },

        _stateCountByChar: {

            "?": function () {
                this._item.min = 0;
                this._item.max = 1;
            },

            "+": function () {
                this._item.min = 1;
            },

            "*": function () {
                this._item.min = 0;
            },

            "|": function () {
                var
                    item;
                if (1 === this._stack.length
                    || undefined === this._stack[1][0].or) {
                    // New OR
                    item = {
                        or: [this._stack[0]]
                    };
                    this._stack.splice(1, 0, [item]);
                    if (this._root === this._stack[0]) {
                        this._root = this._stack[1];
                    }
                } else {
                    item = this._stack[1][0];
                }
                this._stack[0] = [];
                item.or.push(this._stack[0]);
                this._item = null;
            }

        },

        _stateCount: function (char) {
            var byChar = this._stateCountByChar[char];
            if (undefined === byChar) {
                this._stateItem(char);
            } else {
                byChar.apply(this, arguments);
                this.parse = this._stateItem;
            }
        }

    });

    var PatternTokenizer = gpf.Class.extend({

        "[Class]": [gpf.$InterfaceImplement(gpfI.ITokenizer)],

        /**
         * @member {gpf.Pattern} _pattern
         * @private
         */
        _pattern: null,

        /**
         * @member {object[]} _items Current items
         * @private
         */
        _items: null,

        /**
         * @member {number} _itemIdx Current item index
         * @private
         */
        _itemIdx: 0,

        /**
         * @member {number} _pos Current position inside the current item
         * @private
         */
        _pos: 0,

        /**
         * @member {number} _length Match length
         * @private
         */
        _length: 0,

        /**
         *
         * @param {gpf.Pattern} pattern
         */
        init: function (pattern) {
            this._pattern = pattern;
            this._items = pattern._root;
        },

        //region ITokenizer

        /**
         * @implements gpf.interfaces.ITokenizer:write
         */
        write: function (char) {
            if (this._itemIdx === this._items.length || -1 === this._length) {
                // Nothing else to match
                return this._length;
            }
            var item = this._items[this._itemIdx];
            if (undefined !== item.seq) {
                if (char !== item.seq.charAt(this._pos)) {
                    this._length = -1;
                    return -1; // No match
                }
                ++this._length;
                if (++this._pos < item.seq.length) {
                    return 0; // Need more data
                }
            } else if (undefined !== item.inc) {
                if ((item.inc.length !== 0 && -1 === item.inc.indexOf(char))
                    || (item.exc && -1 < item.exc.indexOf(char))) {
                    this._length = -1;
                    return -1; // No match
                }
                ++this._length;
            } else if (undefined !== item.or) {

            }
            this._pos = 0;
            if (++this._itemIdx < this._items.length) {
                return 0; // Need more data (what if optional?)
            }
            return this._length;
        }

        //endregion

    });

    /**
     * Patterns are designed to be an efficient and stream-able alternative to
     * regular expressions. However, the coverage is not the same
     *
     * Supported operators:
     *  [a-z^0-9], [^abc], ., ?, +, *
     *  [^a-z] exclude
     *  . any character
     *
     *
     * @class gpf.Pattern
     */
    gpf.Pattern = gpf.Class.extend({

        _root: null,

        /**
         * Constructor, check and compile the pattern
         *
         * @param {string} pattern
         */
        init: function (pattern) {
            var
                context = new PatternParserContext(),
                idx,
                len = pattern.length;
            for (idx = 0; idx < len; ++idx) {
                context.parse(pattern.charAt(idx));
            }
            this._root = context.get();
        },

        /**
         * Allocate a context to be used with write.
         * Context content may change, do not rely on its structure.
         *
         * @returns {PatternTokenizer}
         */
        allocate: function () {
            return new PatternTokenizer(this);
        }

    });

    //endregion

    //region Parser

    /**
     * This parser base class maintain the current stream position
     * And also offers some basic features to improve parsing speed
     *
     * @class gpf.Parser
     */
    gpf.Parser = gpf.Class.extend({

        "[Class]": [gpf.$InterfaceImplement(gpfI.ITextStream)],

        _pos: 0,
        _line: 0,
        _column: 0,
        _state: 0, // Initial state

        init: function () {
            this._init();
        },

        /**
         * Initialize Parser specific members
         *
         * @private
         */
        _init: function () {
            this._pos = 0;
            this._line = 0;
            this._column = 0;
            this._state = 0;
        },

        /**
         * Get current position
         *
         * @returns {{pos: number, line: number, column: number}}
         */
        currentPos: function () {
            return {
                pos: this._pos,
                line: this._line,
                column: this._column
            };
        },

        /**
         * Process the character
         *
         * @param {string} char
         *
         * @abstract
         * @private
         */
        _parse: function (char) {
            gpf.interfaces.ignoreParameter(char);
        },

        /**
         * Consider the current state and finalize the current token (if any),
         * go back to the initial state
         *
         * @abstract
         * @private
         */
        _reset: function () {
        },

        //region gpf.interfaces.ITextStream

        /**
         * @implements gpf.interfaces.ITextStream.read
         */
        read: function(count) {
            gpf.interfaces.ignoreParameter(count);
            return "";
        },

        /**
         * @implements gpf.interfaces.ITextStream.write
         */
        write: gpfI.ITextStream._write,

        write_: function (buffer) {
            var
                idx,
                char;
            if (null === buffer) {
                this._reset();
                this._init();
            } else {
                for (idx = 0; idx < buffer.length; ++idx) {
                    char = buffer.charAt(idx);
                    this._parse(char);
                    ++this._pos;
                    if ("\n" === char) {
                        ++this._line;
                        this._column = 0;
                    } else {
                        ++this._column;
                    }
                }
            }
        }

        //endregion

    });

    //endregion

}()); /* End of privacy scope */
<commit_msg>Pattern parser (continued)<commit_after>(function () { /* Begin of privacy scope */
    "use strict";

    var
        gpfI = gpf.interfaces;

    //region ITokenizer

    gpfI.ITokenizer = gpfI.Interface.extend({

        /**
         * Submit a character to the tokenizer, result indicates if the token
         * is recognized
         *
         * @param {string} char One character to analyze
         * @returns {number} < 0 means won't recognize
         *                     0 means need more chars
         *                   > 0 means a token is recognized (length returned)
         *
         * NOTE: if the result is positive, you may submit more chars until
         */
        write: function (char) {
            gpf.interfaces.ignoreParameter(char);
            return -1;
        }

    });

    // endregion

    //region Pattern

    /*
     * Pattern 'grammar'
     *
     * pattern
     *      : expression+
     *
     * expression
     *      : item ( '|' item )*
     *
     * item
     *      : match count?
     *
     * count
     *      : '?'
     *      | '*'
     *      | '+'
     *      | '{' <number> '}'
     *
     * match
     *      : '[' char_match_include
     *      | '(' expression ')'
     *      | char
     *
     * char_match_include : '^' char_match_exclude
     *                    | ']'
     *                    | char char_range_sep? char_match_include
     *
     * char_match_exclude : ']'
     *                    | char char_range_sep? char_match_exclude
     *
     * char_range_sep : '-' char
     *
     * char : '\' escaped_char
     *      | <any char but ?*+{[(-[>
     */

/*
    var
        // abc
        _sample1 = {seq: "abc"},
        // [a-z]
        _sample2 = {inc: "abc...xyz"},
        // [a-z^de]
        _sample3 = {inc: "abc...xyz", exc: "de"},
        // a|b|c
        _sample4 = {or: [{seq: "a"}, {seq: "b"}, {seq: "c"}]}
        // ? => max: 1
        // * => min:0
        // + => min:1
        // Each item is connected to
        // - parent item: parent: {}
        // - next item: next: {}
    ;
*/

    var
        PatternItem = gpf.Class.extend({

            "[_type]": [gpf.$ClassProperty()],
            _type: -1,

            "[_parent]": [gpf.$ClassProperty(true)],
            _parent: null,

            "[_next]": [gpf.$ClassProperty(true)],
            _next: null,

            "[_min]": [gpf.$ClassProperty(true)],
            _min: null,

            "[_max]": [gpf.$ClassProperty(true)],
            _max: null,

            init: function (type) {
                this._type = type;
            },

            add: function (char, inRange) {
                gpf.interfaces.ignoreParameter(char);
                gpf.interfaces.ignoreParameter(inRange);
            },

            finalize: function () {
            },

            reset: function (state) {
                state.count = 0;
            },

            write: function (state, char) {
                gpf.interfaces.ignoreParameter(char);
                return this;
            }

        }),

        PatternSimpleItem  = PatternItem.extend({

            _seq: "",

            init: function () {
                this._super(PatternItem.SIMPLE);
                this._seq = [];
            },

            add: function (char, inRange) {
                gpf.interfaces.ignoreParameter(inRange);
                this._seq.push(char);
            },

            finalize: function () {
                this._seq = this._seq.join("");
            },

            reset: function (state) {
                state.pos = 0;
            },

            write: function (state, char) {
                if (char !== this._seq.charAt(this._pos)) {
                    this._length = -1;
                    return -1; // No match
                }

                gpf.interfaces.ignoreParameter(char);
                return this;
            }
        }),

        PatternRangeItem = PatternItem.extend({

            _inc: "",
            _exc: null,

            init: function () {
                this._super(PatternItem.RANGE);
                this._inc = [];
            },

            add: function (char, inRange) {
                var
                    arrayOfChars,
                    first,
                    last,
                    idx;
                if (this._exc) {
                    arrayOfChars = this._exc;
                } else {
                    arrayOfChars = this._inc;
                }
                if (inRange) {
                    first = arrayOfChars[arrayOfChars.length - 1].charCodeAt(0);
                    last = char.charCodeAt(0);
                    for (idx = first + 1; idx < last; ++idx) {
                        arrayOfChars.push(String.fromCharCode(idx));
                    }
                    arrayOfChars.push(char);
                } else {
                    // First char of a range
                    arrayOfChars.push(char);
                }
            },

            finalize: function () {
                this._inc = this._inc.join("");
                if (this._exc) {
                    this._exc = this._exc.join("");
                }
            }

        }),

        PatternRangeChoice = PatternItem.extend({

            init: function () {
                this._super(PatternItem.Choice);
            },

            add: function (char, inRange) {
                gpf.interfaces.ignoreParameter(char);
                gpf.interfaces.ignoreParameter(inRange);
            },

            finalize: function () {
            }

        });

    PatternItem.SIMPLE = 0;
    PatternItem.RANGE = 1;
    PatternItem.CHOICE = 2;
    PatternItem._factory = null;

    PatternItem.create = function (type) {
        if (!PatternItem._factory) {
            PatternItem._factory = {};
            PatternItem._factory[PatternItem.SIMPLE] = PatternSimpleItem;
            PatternItem._factory[PatternItem.RANGE] = PatternRangeItem;
            PatternItem._factory[PatternItem.CHOICE] = PatternRangeChoice;
        }
        return new (PatternItem._factory[type])();
    };

    var PatternParserContext = gpf.Class.extend({

        _root: null,
        _item : null,
        _inRange: false,
        _afterChar: null,

        parse: null, // Will be overridden

        init: function() {
            this.parse = this._stateItem;
        },

        get: function () {
            if (this.parse !== this._stateItem
                && this.parse !== this._stateCount) {
                throw {
                    message: "Invalid syntax"
                };
            }
            this._root.finalize();
            return this._root;
        },

        // Get or create the item corresponding to the requested type
        _getItem: function (type) {
            var
                item = this._item,
                nextItem;
            if (null === item || type !== item.type()) {
                nextItem = PatternItem.create(type);
                if (null !== item) {
                    item.finalize();
                    item.next(nextItem);
                } else {
                    this._root = nextItem;
                }
                this._item = nextItem;
            }
            return item;
        },

        _stateItem: function (char) {
            if ("[" === char) {
                this.parse = this._stateCharMatchRange;
            } else {
                this._getItem(PatternItem.SIMPLE);
                this._afterChar = this._stateCount;
                this._stateChar(char);
            }
        },

        _stateCharMatchRange: function (char) {
            var curItem = this._getItem(PatternItem.RANGE);
            if ("^" === char && !curItem._exc) {
                curItem._exc = [];
                // this.parse = this._stateCharMatchRange;
            } else if ("]" === char) {
                this.parse = this._stateCount;
            } else {
                this._inRange = false;
                this._afterChar = this._stateCharRangeSep;
                this._stateChar(char);
            }
        },

        _stateCharRangeSep: function (char) {
            if ("-" === char) {
                this._inRange = true;
                this._afterChar = this._stateCharMatchRange;
                this.parse = this._stateChar;
            } else {
                this._stateCharMatchRange(char);
            }
        },

        _stateChar: function (char) {
            if ("\\" === char) {
                this.parse = this.stateEscapedChar;
            } else {
                this._item.add(char, this._inRange);
                this.parse = this._afterChar;
            }
        },

        stateEscapedChar: function (char) {
            this._item.add(char, this._inRange);
            this.parse = this._afterChar;
        },

        _stateCountByChar: {

            "?": function () {
                this._item.min(0);
                this._item.max(1);
            },

            "+": function () {
                this._item.min(1);
            },

            "*": function () {
                this._item.min(0);
            },

            "|": function () {
/*
                var
                    item;
                if (1 === this._stack.length
                    || undefined === this._stack[1][0].or) {
                    // New OR
                    item = {
                        or: [this._stack[0]]
                    };
                    this._stack.splice(1, 0, [item]);
                    if (this._root === this._stack[0]) {
                        this._root = this._stack[1];
                    }
                } else {
                    item = this._stack[1][0];
                }
                this._stack[0] = [];
                item.or.push(this._stack[0]);
                this._item = null;
*/
            }

        },

        _stateCount: function (char) {
            var byChar = this._stateCountByChar[char];
            if (undefined === byChar) {
                this._stateItem(char);
            } else {
                byChar.apply(this, arguments);
                this.parse = this._stateItem;
            }
        }

    });

    var PatternTokenizer = gpf.Class.extend({

        "[Class]": [gpf.$InterfaceImplement(gpfI.ITokenizer)],

        /**
         * @member {gpf.Pattern} _pattern
         * @private
         */
        _pattern: null,

        /**
         * @member {PatternIten} _item Current item
         * @private
         */
        _item: null,

        _state: {},

        /**
         *
         * @param {gpf.Pattern} pattern
         */
        init: function (pattern) {
            this._pattern = pattern;
            this._item = pattern._root;
            this._state = {};
            this._item.reset(this._state);
        },

        //region ITokenizer

        /**
         * @implements gpf.interfaces.ITokenizer:write
         */
        write: function (char) {
            if (this._itemIdx === this._items.length || -1 === this._length) {
                // Nothing else to match
                return this._length;
            }
            var item = this._items[this._itemIdx];
            if (undefined !== item.seq) {
                if (char !== item.seq.charAt(this._pos)) {
                    this._length = -1;
                    return -1; // No match
                }
                ++this._length;
                if (++this._pos < item.seq.length) {
                    return 0; // Need more data
                }
            } else if (undefined !== item.inc) {
                if ((item.inc.length !== 0 && -1 === item.inc.indexOf(char))
                    || (item.exc && -1 < item.exc.indexOf(char))) {
                    this._length = -1;
                    return -1; // No match
                }
                ++this._length;
            } else if (undefined !== item.or) {

            }
            this._pos = 0;
            if (++this._itemIdx < this._items.length) {
                return 0; // Need more data (what if optional?)
            }
            return this._length;
        }

        //endregion

    });

    /**
     * Patterns are designed to be an efficient and stream-able alternative to
     * regular expressions. However, the coverage is not the same
     *
     * Supported operators:
     *  [a-z^0-9], [^abc], ., ?, +, *
     *  [^a-z] exclude
     *  . any character
     *
     *
     * @class gpf.Pattern
     */
    gpf.Pattern = gpf.Class.extend({

        _root: null,

        /**
         * Constructor, check and compile the pattern
         *
         * @param {string} pattern
         */
        init: function (pattern) {
            var
                context = new PatternParserContext(),
                idx,
                len = pattern.length;
            for (idx = 0; idx < len; ++idx) {
                context.parse(pattern.charAt(idx));
            }
            this._root = context.get();
        },

        /**
         * Allocate a context to be used with write.
         * Context content may change, do not rely on its structure.
         *
         * @returns {PatternTokenizer}
         */
        allocate: function () {
            return new PatternTokenizer(this);
        }

    });

    //endregion

    //region Parser

    /**
     * This parser base class maintain the current stream position
     * And also offers some basic features to improve parsing speed
     *
     * @class gpf.Parser
     */
    gpf.Parser = gpf.Class.extend({

        "[Class]": [gpf.$InterfaceImplement(gpfI.ITextStream)],

        _pos: 0,
        _line: 0,
        _column: 0,
        _state: 0, // Initial state

        init: function () {
            this._init();
        },

        /**
         * Initialize Parser specific members
         *
         * @private
         */
        _init: function () {
            this._pos = 0;
            this._line = 0;
            this._column = 0;
            this._state = 0;
        },

        /**
         * Get current position
         *
         * @returns {{pos: number, line: number, column: number}}
         */
        currentPos: function () {
            return {
                pos: this._pos,
                line: this._line,
                column: this._column
            };
        },

        /**
         * Process the character
         *
         * @param {string} char
         *
         * @abstract
         * @private
         */
        _parse: function (char) {
            gpf.interfaces.ignoreParameter(char);
        },

        /**
         * Consider the current state and finalize the current token (if any),
         * go back to the initial state
         *
         * @abstract
         * @private
         */
        _reset: function () {
        },

        //region gpf.interfaces.ITextStream

        /**
         * @implements gpf.interfaces.ITextStream.read
         */
        read: function(count) {
            gpf.interfaces.ignoreParameter(count);
            return "";
        },

        /**
         * @implements gpf.interfaces.ITextStream.write
         */
        write: gpfI.ITextStream._write,

        write_: function (buffer) {
            var
                idx,
                char;
            if (null === buffer) {
                this._reset();
                this._init();
            } else {
                for (idx = 0; idx < buffer.length; ++idx) {
                    char = buffer.charAt(idx);
                    this._parse(char);
                    ++this._pos;
                    if ("\n" === char) {
                        ++this._line;
                        this._column = 0;
                    } else {
                        ++this._column;
                    }
                }
            }
        }

        //endregion

    });

    //endregion

}()); /* End of privacy scope */
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'react-flexbox-grid';

export class RenderPatronGroupLastUpdated extends React.Component {
  static propTypes = {
    resources: PropTypes.shape({
      createdBy: PropTypes.object,
      updatedBy: PropTypes.object,
    }).isRequired,
    mutator: PropTypes.shape({
      createdBy: PropTypes.shape({
        GET: PropTypes.func,
        reset: PropTypes.func,
      }),
      updatedBy: PropTypes.shape({
        GET: PropTypes.func,
        reset: PropTypes.func,
      }),
    }).isRequired
  };

  static defaultProps = {

  };

  static manifest = Object.freeze({
    createdBy: {
      type: 'okapi',
      path: 'users/!{item.metadata.createdByUserId}',
      accumulate: 'false',
      fetch: false,
    },
    updatedBy: {
      type: 'okapi',
      path: 'users/!{item.metadata.updatedByUserId}',
      accumulate: 'false',
      fetch: false,
    }
  });

  constructor(props) {
    super(props);
    this.state = {
      value: undefined,
      item: undefined,
    };
  }

  formatDate(date) {
    const year = date.getFullYear();
    const month = date.getMonth();
    const day = date.getDate();
    return [year, month < 10 ? "0" + month : month, day < 10 ? "0" + day : day].join("-")
  }

  buildValue(record) {
    let date = new Date(this.props.item.metadata.updatedDate);
    return this.formatDate(date) + " by " +
      record.personal.lastName + ", " +
      record.personal.firstName;
  }

  componentDidMount() {
    const { mutator, item } = this.props;
    if(item.id) {
      mutator.createdBy.reset();
      mutator.createdBy.GET();
      mutator.updatedBy.reset();
      mutator.updatedBy.GET().then((record) => {
        this.setState({
          value: this.buildValue(record),
          item: item,
        })
      });
    }
  }

  render() {
    return (
      <Col key={this.props.key} xs>{this.state.value}</Col>
    );
  }
}
<commit_msg>declarative approach for patron group last updated<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'react-flexbox-grid';

export class RenderPatronGroupLastUpdated extends React.Component {
  static propTypes = {
    mutator: PropTypes.shape({
      createdBy: PropTypes.shape({
        GET: PropTypes.func,
      }),
      updatedBy: PropTypes.shape({
        GET: PropTypes.func,
      }),
    }).isRequired,
  };

  static defaultProps = {};

  static manifest = Object.freeze({
    createdBy: {
      type: 'okapi',
      path: 'users/!{item.metadata.createdByUserId}',
    },
    updatedBy: {
      type: 'okapi',
      path: 'users/!{item.metadata.updatedByUserId}',
    }
  });

  constructor(props) {
    super(props);
    this.state = {};
  }

  formatDate(date) {
    const year = date.getFullYear();
    const month = date.getMonth();
    const day = date.getDate();
    return [year, month < 10 ? "0" + month : month, day < 10 ? "0" + day : day].join("-")
  }

  buildValue(user, group) {
    let date = new Date(group.metadata.updatedDate);
    return this.formatDate(date) + " by " +
      user.personal.lastName + ", " +
      user.personal.firstName;
  }

  render() {
    let value;
    if(this.props.resources.updatedBy && this.props.resources.updatedBy.hasLoaded && this.props.item.metadata) {
      value = this.buildValue(this.props.resources.updatedBy.records[0], this.props.item);
    }
    return (
      <Col key={this.props.key} xs>{value}</Col>
    );
  }
}
<|endoftext|>