<commit_before>/*
	Simple jQuery tabs plugin
*/
(function($){

	$.fn.bookingtabs = function(options){
		if(options.tabContainer === undefined){
			return false;
		}

		var nav = $(this),
			settings = {
				activeClass: "current",
				useHash: true,
				hashPrefix: "tab-",
				el: "a"
			};

		settings = $.extend({}, settings, options);

		return this.each(function(){
			var $tabContainers = $(settings.tabContainer),
				hash = location.hash && ("#"+ settings.hashPrefix + location.hash.replace("#","")),
				which = (settings.useHash && hash) || ":first";

			$tabContainers.hide().filter(which).show();

			$(this).find(settings.el).on("click", function(evt){
				evt.preventDefault();
				var tab = $tabContainers.filter(this.hash);

				$tabContainers.hide();
				tab.show();

				nav.find(settings.el).removeClass(settings.activeClass);
				$(this).addClass(settings.activeClass);
				location.hash = tab.attr("id").replace(settings.hashPrefix, "");

			});

			if(which == ":first")
				$(this).find(settings.el).filter(which).click();
			else
				$(this).find(settings.el).filter('[href="'+which+'"]').click();

		});
	};

})(jQuery);

/*
	Javascript functions for the Bookings plugin
 */

/**
 * Correct date parsing
 *
 * @param Date on the format YYYY-mm-dd
 * @return Date object from param
 */
function parseDateFromString(input) {
	var parts = input.match(/(\d+)/g);
	return new Date(parts[0], parts[1]-1, parts[2]);
}

function formatDate(date) {
	var month = date.getMonth() + 1;
	if(month < 10) {
		month = "0"+month;
	}

	return date.getFullYear()+"-"+ month +"-"+date.getDate();
}

function formatDateFromString(date) {
	// Strip non-numeric stuff and build new string (YYYY-mm-dd)
	var d = date.replace(/[^0-9]/g, ""),
		year = d.substr(0, 4),
		month = d.substr(4, 2),
		day = d.substr(6, 2);

	return year+"-"+month+"-"+day;
}

$(function() {

	// Set up tabs
	$(".bookingtabs").tabs({
		tabContainer: ".tab-container > div",
		activeClass: "tab-current"
	});

	$(".booking-list > li").on("click", function() {
		var self = $(this),
			others = $(".booking-list > li");

		others.fadeTo(0, 1.0);

		self.toggleClass("collapsed").find(".booking-details").slideToggle(200);

		var opacity = self.hasClass("collapsed") ? .6 : 1.0;
		others.not(self).fadeTo(200, opacity);
	});

	if(! $(".location-container input[value='Grupprummet']").is(":checked") ) {
		$(".hide").hide();
	}

	// Toggle repeat checkbox when room is 'Grupprummet'
	$(".location-container input").on("change", function(evt) {
		$(".booking-repeat-container").toggle();

		if($(this).val() !== "Grupprummet") {
			$("#booking-repeat-check").attr("checked", false);
			$(".booking-repeat-info").toggle();
		}
	});

	/*
		Format the dates correctly (Ex: YYYY-mmdd => YYYY-mm-dd)
	 */
	$(".booking-dates-container input").on("blur", function(evt) {
		var date = $(this).val();
		if(!date.match(/^\d{4}-\d{1,2}-\d{1,2}$/)) {
			$(this).val(formatDateFromString(date));
		}
	});

	$("#booking-repeat-check").on("change", function(evt) {
		$(".booking-repeat-info").slideToggle(200);
	});

	$("#is-party-booking").on("change", function(evt) {

	});

	/*
		Prevent overlapping dates. I.e. don't let users input
		start: 2013-02-23 and end: 2013-02-20 and vice versa.
	 */
	$(".booking-dates-container input").on("change", function(evt) {
		var $this = $(this),
			$other = $(".booking-dates-container").find("input").not($this),
			newDate, start_date, end_date, date_src;

		if($this.is("#start-date")) {
			start_date = parseDateFromString($this.val());
			end_date = parseDateFromString($other.val());
			date_src = start_date;
		}
		else {
			start_date = parseDateFromString($other.val());
			end_date = parseDateFromString($this.val());
			date_src = end_date;
		}

		if(start_date > end_date) {
			newDate = formatDate(date_src);
			$other.val(newDate);
		}
	});

});<commit_msg>Fix date JS not formatting dates correctly<commit_after>/*
	Simple jQuery tabs plugin
*/
(function($){

	$.fn.bookingtabs = function(options){
		if(options.tabContainer === undefined){
			return false;
		}

		var nav = $(this),
			settings = {
				activeClass: "current",
				useHash: true,
				hashPrefix: "tab-",
				el: "a"
			};

		settings = $.extend({}, settings, options);

		return this.each(function(){
			var $tabContainers = $(settings.tabContainer),
				hash = location.hash && ("#"+ settings.hashPrefix + location.hash.replace("#","")),
				which = (settings.useHash && hash) || ":first";

			$tabContainers.hide().filter(which).show();

			$(this).find(settings.el).on("click", function(evt){
				evt.preventDefault();
				var tab = $tabContainers.filter(this.hash);

				$tabContainers.hide();
				tab.show();

				nav.find(settings.el).removeClass(settings.activeClass);
				$(this).addClass(settings.activeClass);
				location.hash = tab.attr("id").replace(settings.hashPrefix, "");

			});

			if(which == ":first")
				$(this).find(settings.el).filter(which).click();
			else
				$(this).find(settings.el).filter('[href="'+which+'"]').click();

		});
	};

})(jQuery);

/*
	Javascript functions for the Bookings plugin
 */

/**
 * Correct date parsing
 *
 * @param Date on the format YYYY-mm-dd
 * @return Date object from param
 */
function parseDateFromString(input) {
	var parts = input.match(/(\d+)/g);
	return new Date(parts[0], parts[1]-1, parts[2]);
}

function formatDate(date) {
	var month = date.getMonth() + 1,
		day = date.getDate();
	if(month < 10) {
		month = "0"+month;
	}
	if(day < 10) {
		day = "0"+day;
	}

	return date.getFullYear()+"-"+ month +"-"+day;
}

function formatDateFromString(date) {
	// Strip non-numeric stuff and build new string (YYYY-mm-dd)
	var d = date.replace(/[^0-9]/g, ""),
		year = d.substr(0, 4),
		month = d.substr(4, 2),
		day = d.substr(6, 2);

	return year+"-"+month+"-"+day;
}

$(function() {

	// Set up tabs
	$(".bookingtabs").tabs({
		tabContainer: ".tab-container > div",
		activeClass: "tab-current"
	});

	$(".booking-list > li").on("click", function() {
		var self = $(this),
			others = $(".booking-list > li");

		others.fadeTo(0, 1.0);

		self.toggleClass("collapsed").find(".booking-details").slideToggle(200);

		var opacity = self.hasClass("collapsed") ? .6 : 1.0;
		others.not(self).fadeTo(200, opacity);
	});

	if(! $(".location-container input[value='Grupprummet']").is(":checked") ) {
		$(".hide").hide();
	}

	// Toggle repeat checkbox when room is 'Grupprummet'
	$(".location-container input").on("change", function(evt) {
		$(".booking-repeat-container").toggle();

		if($(this).val() !== "Grupprummet") {
			$("#booking-repeat-check").attr("checked", false);
			$(".booking-repeat-info").toggle();
		}
	});

	/*
		Format the dates correctly (Ex: YYYY-mmdd => YYYY-mm-dd)
	 */
	$(".booking-dates-container input").on("blur", function(evt) {
		var date = $(this).val();
		if(date.match(/^\d{4}-\d{2}-\d{2}$/) === null) {
			$(this).val(formatDate(parseDateFromString(formatDateFromString(date))));
		}
	});

	$("#booking-repeat-check").on("change", function(evt) {
		$(".booking-repeat-info").slideToggle(200);
	});

	$("#is-party-booking").on("change", function(evt) {

	});

	/*
		Prevent overlapping dates. I.e. don't let users input
		start: 2013-02-23 and end: 2013-02-20 and vice versa.
	 */
	$(".booking-dates-container input").on("change", function(evt) {
		var $this = $(this),
			$other = $(".booking-dates-container").find("input").not($this),
			newDate, start_date, end_date, date_src;

		if($this.is("#start-date")) {
			start_date = parseDateFromString($this.val());
			end_date = parseDateFromString($other.val());
			date_src = start_date;
		}
		else {
			start_date = parseDateFromString($other.val());
			end_date = parseDateFromString($this.val());
			date_src = end_date;
		}

		if(start_date > end_date) {
			newDate = formatDate(date_src);
			$other.val(newDate);
		}
	});

});<|endoftext|>


<commit_before><commit_msg>Fix a crash loading state at the end of all lands.<commit_after><|endoftext|>


<commit_before>// The completion substrings, used for showing the longest common match
var g_substrings = [];

/*
 * returns the longest common substring
 * used for the 'longest' setting for wildmode
 *
 */
function get_longest_substring()/*{{{*/
{
    if (g_substrings.length == 0)
        return '';
    var longest = g_substrings[0];
    for (var i = 1; i < g_substrings.length; i++)
    {
        if (g_substrings[i].length > longest.length)
            longest = g_substrings[i];
    }
    //alert(longest);
    return longest;
}/*}}}*/

// function uses smartcase
// list = [ [['com1', 'com2'], 'text'], [['com3', 'com4'], 'text'] ]
function build_longest_common_substring(list, filter)/*{{{*/
{
    var filtered = [];
    //var filter_length = filter.length;
    //filter = filter.toLowerCase();
    var ignorecase = false;
    if(filter == filter.toLowerCase())
        ignorecase = true;

    for (var i = 0; i < list.length; i++)
    {
        for (var j = 0; j < list[i][0].length; j++)
        {
            var item = list[i][0][j];
            if(ignorecase)
                item = item.toLowerCase();

            if (item.indexOf(filter) == -1)
                continue;

            if (g_substrings.length == 0)
            {
                //alert('if: ' + item);
                var last_index = item.lastIndexOf(filter);
                var length = item.length;
                for (var k = item.indexOf(filter); k != -1 && k <= last_index; k = item.indexOf(filter, k + 1))
                {
                    for (var l = k + filter.length; l <= length; l++)
                        g_substrings.push(list[i][0][j].substring(k, l));
                }
            }
            else
            {
                //alert('else: ' + item);
                g_substrings = g_substrings.filter(function($_) {
                    return list[i][0][j].indexOf($_) >= 0;
                });
            }
            filtered.push([list[i][0][j], list[i][1]]);
            break;
        }
    }
    return filtered;
}/*}}}*/

/* this function is case sensitive */
function build_longest_starting_substring(list, filter)/*{{{*/
{
    var filtered = [];
    //var filter_length = filter.length;
    for (var i = 0; i < list.length; i++)
    {
        for (var j = 0; j < list[i][0].length; j++)
        {
            if (list[i][0][j].indexOf(filter) != 0)
                continue;
            if (g_substrings.length == 0)
            {
                var length = list[i][0][j].length;
                for (var k = filter.length; k <= length; k++)
                    g_substrings.push(list[i][0][j].substring(0, k));
            }
            else
            {
                g_substrings = g_substrings.filter(function($_) {
                    return list[i][0][j].indexOf($_) == 0;
                });
            }
            filtered.push([list[i][0][j], list[i][1]]);
            break;
        }
    }
    return filtered;
}/*}}}*/

/*
 * filter a list of urls
 *
 * may consist of searchengines, filenames, bookmarks and history,
 * depending on the 'complete' option
 * if the 'complete' argument is passed like "h", it temproarily overrides the complete option
 */
function get_url_completions(filter, complete)/*{{{*/
{
    var completions = new Array();
    g_substrings = [];

    var cpt = complete || vimperator.options["complete"];
    // join all completion arrays together
    for (var i = 0; i < cpt.length; i++)
    {
        if (cpt[i] == 's')
            completions = completions.concat(get_search_completions(filter));
        else if (cpt[i] == 'b')
            completions = completions.concat(get_bookmark_completions(filter));
        else if (cpt[i] == 'h')
            completions = completions.concat(get_history_completions(filter));
        else if (cpt[i] == 'f')
            completions = completions.concat(get_file_completions(filter, true));
    }

    return completions;
}/*}}}*/

/* discard all entries in the 'urls' array, which don't match 'filter */
function filter_url_array(urls, filter)/*{{{*/
{
    var filtered = [];
    // completions which don't match the url but just the description
    // list them add the end of the array
    var additional_completions = [];

    if (!filter) return urls.map(function($_) {
        return [$_[0], $_[1]]
    });

    //var filter_length = filter.length;
    var ignorecase = false;
    if(filter == filter.toLowerCase())
        ignorecase = true;

    /*
     * Longest Common Subsequence
     * This shouldn't use build_longest_common_substring
     * for performance reasons, so as not to cycle through the urls twice
     */
    for (var i = 0; i < urls.length; i++)
    {
        var url = urls[i][0] || "";
        var title = urls[i][1] || "";
        if(ignorecase)
        {
            url = url.toLowerCase();
            title = title.toLowerCase();
        }

        if (url.indexOf(filter) == -1)
        {
            if (title.indexOf(filter) != -1)
                additional_completions.push([ urls[i][0], urls[i][1] ]);
            continue;
        }
        if (g_substrings.length == 0)   // Build the substrings
        {
            var last_index = url.lastIndexOf(filter);
            var url_length = url.length;
            for (var k = url.indexOf(filter); k != -1 && k <= last_index; k = url.indexOf(filter, k + 1))
            {
                for (var l = k + filter.length; l <= url_length; l++)
                    g_substrings.push(url.substring(k, l));
            }
        }
        else
        {
            g_substrings = g_substrings.filter(function($_) {
                return url.indexOf($_) >= 0;
            });
        }
        filtered.push([urls[i][0], urls[i][1]]);
    }

    return filtered.concat(additional_completions);
}/*}}}*/

function get_search_completions(filter)/*{{{*/
{
    var engines = vimperator.bookmarks.getSearchEngines().concat(vimperator.bookmarks.getKeywords());

    if (!filter) return engines.map(function($_) {
        return [$_[0], $_[1]];
    });
    var mapped = engines.map(function($_) {
        return [[$_[0]], $_[1]];
    });
    return build_longest_common_substring(mapped, filter);
}/*}}}*/

function get_history_completions(filter)
{
    var items = vimperator.history.get();
    return filter_url_array(items, filter);
}

function get_bookmark_completions(filter)
{
    var bookmarks = vimperator.bookmarks.get();
    return filter_url_array(bookmarks, filter);
}

function get_file_completions(filter)/*{{{*/
{
    //var completions = new Array();
    /* This is now also used as part of the url completion, so the substrings shouldn't be cleared for that case */
    if (!arguments[1])
        g_substrings = [];
    var match = filter.match(/^(.*[\/\\])(.*?)$/);
    var dir;

    if (!match || !(dir = match[1]))
        return [];

    var compl = match[2] || '';
    try {
        var fd = fopen(dir, "<");
    } catch(e) {
        // thrown if file does not exist
        return [ ];
    }

    if (!fd)
        return [];

    var entries = fd.read();
    var delim = fd.path.length == 1 ? '' : (fd.path.search(/\\/) != -1) ? "\\" : "/";
    var new_filter = fd.path + delim + compl;
    if (!filter) return entries.map(function($_) {
        var path = $_.path;
        if ($_.isDirectory()) path += '/';
        return [path, ''];
    });
    var mapped = entries.map(function($_) {
        var path = $_.path;
        if ($_.isDirectory()) path += '/';
        return [[path], ''];
    });

    return build_longest_starting_substring(mapped, new_filter);
}/*}}}*/

function get_help_completions(filter)/*{{{*/
{
    var help_array = [[["introduction"], "Introductory text"],
                      [["mappings"], "Normal mode commands"],
                      [["commands"], "Ex commands"],
                      [["options"], "Configuration options"]]; // TODO: hardcoded until we have proper 'pages'
    g_substrings = [];
    for (var command in vimperator.commands)
    {
        help_array.push([command.long_names.map(function($_) {
                                                    return ":" + $_;
                                                }),
                        command.short_help])
    }
    options = get_options_completions(filter, true);
    help_array = help_array.concat(options.map(function($_) {
        return [
                $_[0].map(function($_) { return "'" + $_ + "'"; }),
                $_[1]
            ];
    }));
    for (var map in vimperator.mappings)
        help_array.push([map.names, map.short_help])

    if (!filter) return help_array.map(function($_) {
        return [$_[0][0], $_[1]]; // unfiltered, use the first command
    });

    return build_longest_common_substring(help_array, filter);
}/*}}}*/

function get_command_completions(filter)/*{{{*/
{
    //g_completions = [];
    g_substrings = [];
    var completions = []
    if (!filter)
    {
        for (var command in vimperator.commands)
            completions.push([command.name, command.short_help]);
        return completions;
    }

    for (var command in vimperator.commands)
        completions.push([command.long_names, command.short_help]); // # FIXME: just return it in the format expected by blss() for now -- djk
    return build_longest_starting_substring(completions, filter);
}/*}}}*/

function get_options_completions(filter, unfiltered)/*{{{*/
{
    g_substrings = [];
    var options_completions = [];
    var no_mode = false;
    if (filter.indexOf("no") == 0) // boolean option
    {
        no_mode = true;
        filter = filter.substr(2);
    }

    if (unfiltered)
    {
        var options = [];
        for (var option in vimperator.options)
        {
            if (no_mode && option.type != "boolean")
                continue;
            options.push([option.names, option.short_help])
        }
        return options;
    }

    if (!filter)
    {
        var options = [];
        for (var option in vimperator.options)
        {
            if (no_mode && option.type != "boolean")
                continue;
            var prefix = no_mode ? 'no' : '';
            options.push([prefix + option.name, option.short_help])
        }
        return options;
    }

    // check if filter ends with =, then complete current value
    else if(filter.length > 0 && filter.lastIndexOf("=") == filter.length -1)
    {
        filter = filter.substr(0, filter.length-1);
        for (var option in vimperator.options)
        {
            if (option.hasName(filter))
            {
                    options_completions.push([filter + "=" + option.value, ""]);
                    return options_completions;
            }
        }
        return options_completions;
    }

    // can't use b_l_s_s, since this has special requirements (the prefix)
    var filter_length = filter.length;
    for (var option in vimperator.options)
    {
        if (no_mode && option.type != "boolean")
            continue;
        var prefix = no_mode ? 'no' : '';
        for (var j = 0; j < option.names.length; j++)
        {
            if (option.names[j].indexOf(filter) != 0)
                continue;
            if (g_substrings.length == 0)
            {
                var length = option.names[j].length;
                for (var k = filter_length; k <= length; k++)
                    g_substrings.push(prefix + option.names[j].substring(0, k));
            }
            else
            {
                g_substrings = g_substrings.filter(function($_) {
                    return option.names[j].indexOf($_) == 0;
                });
            }
            options_completions.push([prefix + option.names[j], option.short_help]);
            break;
        }
    }

    return options_completions;
}/*}}}*/

function get_buffer_completions(filter)/*{{{*/
{
    g_substrings = [];
    var items = [];
    var num = getBrowser().browsers.length;
    var title, url;

    for (var i = 0; i < num; i++)
    {
        try
        {
            title = getBrowser().getBrowserAtIndex(i).contentDocument.getElementsByTagName('title')[0].text;
        }
        catch (e)
        {
            title = "";
        }

        url = getBrowser().getBrowserAtIndex(i).contentDocument.location.href;

        if (title.indexOf(filter) == -1 && url.indexOf(filter) == -1)
            continue;

        if (title.indexOf(filter) != -1 || url.indexOf(filter) != -1)
        {
            if (title == "")
                title = "(Untitled)";
            items.push([[(i + 1) + ": " + title, (i + 1) + ": " + url], url]);
        }
    }
    if (!filter) return items.map(function($_) {
        return [$_[0][0], $_[1]];
    });
    return build_longest_common_substring(items, filter);
}/*}}}*/

function exTabCompletion(str)
{
	var [count, cmd, special, args] = tokenize_ex(str);
	var completions = new Array;
	var start = 0;
	var s = 0; //FIXME, command specific start setting

	// if there is no space between the command name and the cursor
	// then get completions of the command name
	var matches = str.match(/^(:*\d*)\w*$/);
	if(matches)
	{
		completions = get_command_completions(cmd);
		start = matches[1].length;
	}
	else // dynamically get completions as specified with the command's completer function
	{
        var command = vimperator.commands.get(cmd);
		if (command && command.completer)
		{
			completions = command.completer.call(this, args);
//			if (command[0][0] == "open" ||
//					command[0][0] == "tabopen" ||
//					command[0][0] == "winopen")
//				start = str.search(/^:*\d*\w+(\s+|.*\|)/); // up to the last | or the first space
//			else
			matches = str.match(/^:*\d*\w+\s+/); // up to the first spaces only
			start = matches[0].length;
		}
	}
	return [start, completions];
}

// vim: set fdm=marker sw=4 ts=4 et:
<commit_msg>remove FIXME comment<commit_after>// The completion substrings, used for showing the longest common match
var g_substrings = [];

/*
 * returns the longest common substring
 * used for the 'longest' setting for wildmode
 *
 */
function get_longest_substring()/*{{{*/
{
    if (g_substrings.length == 0)
        return '';
    var longest = g_substrings[0];
    for (var i = 1; i < g_substrings.length; i++)
    {
        if (g_substrings[i].length > longest.length)
            longest = g_substrings[i];
    }
    //alert(longest);
    return longest;
}/*}}}*/

// function uses smartcase
// list = [ [['com1', 'com2'], 'text'], [['com3', 'com4'], 'text'] ]
function build_longest_common_substring(list, filter)/*{{{*/
{
    var filtered = [];
    //var filter_length = filter.length;
    //filter = filter.toLowerCase();
    var ignorecase = false;
    if(filter == filter.toLowerCase())
        ignorecase = true;

    for (var i = 0; i < list.length; i++)
    {
        for (var j = 0; j < list[i][0].length; j++)
        {
            var item = list[i][0][j];
            if(ignorecase)
                item = item.toLowerCase();

            if (item.indexOf(filter) == -1)
                continue;

            if (g_substrings.length == 0)
            {
                //alert('if: ' + item);
                var last_index = item.lastIndexOf(filter);
                var length = item.length;
                for (var k = item.indexOf(filter); k != -1 && k <= last_index; k = item.indexOf(filter, k + 1))
                {
                    for (var l = k + filter.length; l <= length; l++)
                        g_substrings.push(list[i][0][j].substring(k, l));
                }
            }
            else
            {
                //alert('else: ' + item);
                g_substrings = g_substrings.filter(function($_) {
                    return list[i][0][j].indexOf($_) >= 0;
                });
            }
            filtered.push([list[i][0][j], list[i][1]]);
            break;
        }
    }
    return filtered;
}/*}}}*/

/* this function is case sensitive */
function build_longest_starting_substring(list, filter)/*{{{*/
{
    var filtered = [];
    //var filter_length = filter.length;
    for (var i = 0; i < list.length; i++)
    {
        for (var j = 0; j < list[i][0].length; j++)
        {
            if (list[i][0][j].indexOf(filter) != 0)
                continue;
            if (g_substrings.length == 0)
            {
                var length = list[i][0][j].length;
                for (var k = filter.length; k <= length; k++)
                    g_substrings.push(list[i][0][j].substring(0, k));
            }
            else
            {
                g_substrings = g_substrings.filter(function($_) {
                    return list[i][0][j].indexOf($_) == 0;
                });
            }
            filtered.push([list[i][0][j], list[i][1]]);
            break;
        }
    }
    return filtered;
}/*}}}*/

/*
 * filter a list of urls
 *
 * may consist of searchengines, filenames, bookmarks and history,
 * depending on the 'complete' option
 * if the 'complete' argument is passed like "h", it temproarily overrides the complete option
 */
function get_url_completions(filter, complete)/*{{{*/
{
    var completions = new Array();
    g_substrings = [];

    var cpt = complete || vimperator.options["complete"];
    // join all completion arrays together
    for (var i = 0; i < cpt.length; i++)
    {
        if (cpt[i] == 's')
            completions = completions.concat(get_search_completions(filter));
        else if (cpt[i] == 'b')
            completions = completions.concat(get_bookmark_completions(filter));
        else if (cpt[i] == 'h')
            completions = completions.concat(get_history_completions(filter));
        else if (cpt[i] == 'f')
            completions = completions.concat(get_file_completions(filter, true));
    }

    return completions;
}/*}}}*/

/* discard all entries in the 'urls' array, which don't match 'filter */
function filter_url_array(urls, filter)/*{{{*/
{
    var filtered = [];
    // completions which don't match the url but just the description
    // list them add the end of the array
    var additional_completions = [];

    if (!filter) return urls.map(function($_) {
        return [$_[0], $_[1]]
    });

    //var filter_length = filter.length;
    var ignorecase = false;
    if(filter == filter.toLowerCase())
        ignorecase = true;

    /*
     * Longest Common Subsequence
     * This shouldn't use build_longest_common_substring
     * for performance reasons, so as not to cycle through the urls twice
     */
    for (var i = 0; i < urls.length; i++)
    {
        var url = urls[i][0] || "";
        var title = urls[i][1] || "";
        if(ignorecase)
        {
            url = url.toLowerCase();
            title = title.toLowerCase();
        }

        if (url.indexOf(filter) == -1)
        {
            if (title.indexOf(filter) != -1)
                additional_completions.push([ urls[i][0], urls[i][1] ]);
            continue;
        }
        if (g_substrings.length == 0)   // Build the substrings
        {
            var last_index = url.lastIndexOf(filter);
            var url_length = url.length;
            for (var k = url.indexOf(filter); k != -1 && k <= last_index; k = url.indexOf(filter, k + 1))
            {
                for (var l = k + filter.length; l <= url_length; l++)
                    g_substrings.push(url.substring(k, l));
            }
        }
        else
        {
            g_substrings = g_substrings.filter(function($_) {
                return url.indexOf($_) >= 0;
            });
        }
        filtered.push([urls[i][0], urls[i][1]]);
    }

    return filtered.concat(additional_completions);
}/*}}}*/

function get_search_completions(filter)/*{{{*/
{
    var engines = vimperator.bookmarks.getSearchEngines().concat(vimperator.bookmarks.getKeywords());

    if (!filter) return engines.map(function($_) {
        return [$_[0], $_[1]];
    });
    var mapped = engines.map(function($_) {
        return [[$_[0]], $_[1]];
    });
    return build_longest_common_substring(mapped, filter);
}/*}}}*/

function get_history_completions(filter)
{
    var items = vimperator.history.get();
    return filter_url_array(items, filter);
}

function get_bookmark_completions(filter)
{
    var bookmarks = vimperator.bookmarks.get();
    return filter_url_array(bookmarks, filter);
}

function get_file_completions(filter)/*{{{*/
{
    //var completions = new Array();
    /* This is now also used as part of the url completion, so the substrings shouldn't be cleared for that case */
    if (!arguments[1])
        g_substrings = [];
    var match = filter.match(/^(.*[\/\\])(.*?)$/);
    var dir;

    if (!match || !(dir = match[1]))
        return [];

    var compl = match[2] || '';
    try {
        var fd = fopen(dir, "<");
    } catch(e) {
        // thrown if file does not exist
        return [ ];
    }

    if (!fd)
        return [];

    var entries = fd.read();
    var delim = fd.path.length == 1 ? '' : (fd.path.search(/\\/) != -1) ? "\\" : "/";
    var new_filter = fd.path + delim + compl;
    if (!filter) return entries.map(function($_) {
        var path = $_.path;
        if ($_.isDirectory()) path += '/';
        return [path, ''];
    });
    var mapped = entries.map(function($_) {
        var path = $_.path;
        if ($_.isDirectory()) path += '/';
        return [[path], ''];
    });

    return build_longest_starting_substring(mapped, new_filter);
}/*}}}*/

function get_help_completions(filter)/*{{{*/
{
    var help_array = [[["introduction"], "Introductory text"],
                      [["mappings"], "Normal mode commands"],
                      [["commands"], "Ex commands"],
                      [["options"], "Configuration options"]]; // TODO: hardcoded until we have proper 'pages'
    g_substrings = [];
    for (var command in vimperator.commands)
    {
        help_array.push([command.long_names.map(function($_) {
                                                    return ":" + $_;
                                                }),
                        command.short_help])
    }
    options = get_options_completions(filter, true);
    help_array = help_array.concat(options.map(function($_) {
        return [
                $_[0].map(function($_) { return "'" + $_ + "'"; }),
                $_[1]
            ];
    }));
    for (var map in vimperator.mappings)
        help_array.push([map.names, map.short_help])

    if (!filter) return help_array.map(function($_) {
        return [$_[0][0], $_[1]]; // unfiltered, use the first command
    });

    return build_longest_common_substring(help_array, filter);
}/*}}}*/

function get_command_completions(filter)/*{{{*/
{
    //g_completions = [];
    g_substrings = [];
    var completions = []
    if (!filter)
    {
        for (var command in vimperator.commands)
            completions.push([command.name, command.short_help]);
        return completions;
    }

    for (var command in vimperator.commands)
        completions.push([command.long_names, command.short_help]);
    return build_longest_starting_substring(completions, filter);
}/*}}}*/

function get_options_completions(filter, unfiltered)/*{{{*/
{
    g_substrings = [];
    var options_completions = [];
    var no_mode = false;
    if (filter.indexOf("no") == 0) // boolean option
    {
        no_mode = true;
        filter = filter.substr(2);
    }

    if (unfiltered)
    {
        var options = [];
        for (var option in vimperator.options)
        {
            if (no_mode && option.type != "boolean")
                continue;
            options.push([option.names, option.short_help])
        }
        return options;
    }

    if (!filter)
    {
        var options = [];
        for (var option in vimperator.options)
        {
            if (no_mode && option.type != "boolean")
                continue;
            var prefix = no_mode ? 'no' : '';
            options.push([prefix + option.name, option.short_help])
        }
        return options;
    }

    // check if filter ends with =, then complete current value
    else if(filter.length > 0 && filter.lastIndexOf("=") == filter.length -1)
    {
        filter = filter.substr(0, filter.length-1);
        for (var option in vimperator.options)
        {
            if (option.hasName(filter))
            {
                    options_completions.push([filter + "=" + option.value, ""]);
                    return options_completions;
            }
        }
        return options_completions;
    }

    // can't use b_l_s_s, since this has special requirements (the prefix)
    var filter_length = filter.length;
    for (var option in vimperator.options)
    {
        if (no_mode && option.type != "boolean")
            continue;
        var prefix = no_mode ? 'no' : '';
        for (var j = 0; j < option.names.length; j++)
        {
            if (option.names[j].indexOf(filter) != 0)
                continue;
            if (g_substrings.length == 0)
            {
                var length = option.names[j].length;
                for (var k = filter_length; k <= length; k++)
                    g_substrings.push(prefix + option.names[j].substring(0, k));
            }
            else
            {
                g_substrings = g_substrings.filter(function($_) {
                    return option.names[j].indexOf($_) == 0;
                });
            }
            options_completions.push([prefix + option.names[j], option.short_help]);
            break;
        }
    }

    return options_completions;
}/*}}}*/

function get_buffer_completions(filter)/*{{{*/
{
    g_substrings = [];
    var items = [];
    var num = getBrowser().browsers.length;
    var title, url;

    for (var i = 0; i < num; i++)
    {
        try
        {
            title = getBrowser().getBrowserAtIndex(i).contentDocument.getElementsByTagName('title')[0].text;
        }
        catch (e)
        {
            title = "";
        }

        url = getBrowser().getBrowserAtIndex(i).contentDocument.location.href;

        if (title.indexOf(filter) == -1 && url.indexOf(filter) == -1)
            continue;

        if (title.indexOf(filter) != -1 || url.indexOf(filter) != -1)
        {
            if (title == "")
                title = "(Untitled)";
            items.push([[(i + 1) + ": " + title, (i + 1) + ": " + url], url]);
        }
    }
    if (!filter) return items.map(function($_) {
        return [$_[0][0], $_[1]];
    });
    return build_longest_common_substring(items, filter);
}/*}}}*/

function exTabCompletion(str)
{
	var [count, cmd, special, args] = tokenize_ex(str);
	var completions = new Array;
	var start = 0;
	var s = 0; //FIXME, command specific start setting

	// if there is no space between the command name and the cursor
	// then get completions of the command name
	var matches = str.match(/^(:*\d*)\w*$/);
	if(matches)
	{
		completions = get_command_completions(cmd);
		start = matches[1].length;
	}
	else // dynamically get completions as specified with the command's completer function
	{
        var command = vimperator.commands.get(cmd);
		if (command && command.completer)
		{
			completions = command.completer.call(this, args);
//			if (command[0][0] == "open" ||
//					command[0][0] == "tabopen" ||
//					command[0][0] == "winopen")
//				start = str.search(/^:*\d*\w+(\s+|.*\|)/); // up to the last | or the first space
//			else
			matches = str.match(/^:*\d*\w+\s+/); // up to the first spaces only
			start = matches[0].length;
		}
	}
	return [start, completions];
}

// vim: set fdm=marker sw=4 ts=4 et:
<|endoftext|>


<commit_before>;(function($) {
    $(function() {
        $.entwine('ss', function($) {

            $('.cms-edit-form .btn-toolbar #ActionMenus_WorkflowOptions .action').entwine({
                onclick: function(e) {
                    var transitionId = $(this).attr('data-transitionid');
                    var buttonName = $(this).attr('name');

                    buttonName = buttonName.replace(/-\d+/, '');
                    $(this).attr('name', buttonName);

                    $('input[name=TransitionID]').val(transitionId);

                    this._super(e);
                }
            });

            $('.cms-edit-form .btn-toolbar .action.start-workflow').entwine({
                onmouseup: function(e) {

                    // Populate the hidden form field with the selected workflow definition.

                    var action = $(this);
                    $('input[name=TriggeredWorkflowID]').val(action.data('workflow'));

                    // Update the element name to exclude the ID, therefore submitting correctly.

                    var name = action.attr('name');
                    action.attr('name', name.replace(/-\d+/, ''));
                    this._super(e);
                }
            });
        });
    });
})(jQuery);
<commit_msg>Added backwards compatibility for the two different classes<commit_after>;(function($) {
    $(function() {
        $.entwine('ss', function($) {

            $('.cms-edit-form').find('.Actions, .btn-toolbar').find('#ActionMenus_WorkflowOptions .action').entwine({
                onclick: function(e) {
                    var transitionId = $(this).attr('data-transitionid');
                    var buttonName = $(this).attr('name');

                    buttonName = buttonName.replace(/-\d+/, '');
                    $(this).attr('name', buttonName);

                    $('input[name=TransitionID]').val(transitionId);

                    this._super(e);
                }
            });

            $('.cms-edit-form').find('.Actions, .btn-toolbar').find('.action.start-workflow').entwine({
                onmouseup: function(e) {

                    // Populate the hidden form field with the selected workflow definition.

                    var action = $(this);
                    $('input[name=TriggeredWorkflowID]').val(action.data('workflow'));

                    // Update the element name to exclude the ID, therefore submitting correctly.

                    var name = action.attr('name');
                    action.attr('name', name.replace(/-\d+/, ''));
                    this._super(e);
                }
            });
        });
    });
})(jQuery);
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Box, withAxs } from 'axs';
import { ViewPager, Frame, Track, View, AnimatedView } from 'react-view-pager';
import { Image } from '../base';

const StyledViewPager = withAxs(ViewPager);
const StyledFrame = withAxs(Frame);
const StyledTrack = withAxs(Track);
const StyledView = withAxs(View);
const StyledAnimatedView = withAxs(AnimatedView);

const thumb = image => image.replace('.jpg', '-s.jpg');

const styles = {
  viewport: {
    maxWidth: 800,
    margin: '0 auto',
  },
  frame: {
    maxWidth: 800,
    margin: '0 auto',
  },
  view: {
    userSelect: 'none',
  },
  progressContainer: {
    height: 3,
    position: 'relative',
  },
  progressBar: {
    height: '100%',
    transformOrigin: 'left center',
    position: 'absolute',
  },
  page: {
    height: 50,
    cursor: 'pointer',
  },
};

class ProgressView extends Component {
  render() {
    return (
      <StyledView flexAuto css={styles.view} {...this.props}>
        <AnimatedView
          animations={[
            {
              prop: 'opacity',
              stops: [
                [ -200, 0 ],
                [ 0, 1 ],
                [ 200, 0 ],
              ],
            }, {
              prop: 'translateY',
              stops: [
                [ -200, 50 ],
                [ 0, 0 ],
                [ 200, 50 ],
              ],
            },
          ]}
        >
          {this.props.children}
        </AnimatedView>
      </StyledView>
    );
  }
}

ProgressView.propTypes = {
  children: PropTypes.node,
};

ProgressView.displayName = 'ProgressView';

const ProgressBar = ({ progress }) => (
  <Box bgGray3 width={1} css={styles.progressContainer}>
    <Box
      bgGray9
      width={1}
      css={{
        ...styles.progressBar,
        transform: `scaleX(${Math.max(0, Math.min(1, progress))})`,
      }}
    />
  </Box>
);

ProgressBar.propTypes = {
  progress: PropTypes.number,
};

ProgressBar.displayName = 'ProgressBar';

const ProgressPage = ({ index, children, onClick }) => (
  <StyledAnimatedView
    mr2
    key={index}
    index={index}
    animations={[
      {
        prop: 'scale',
        stops: [
          [ -300, 0.75 ],
          [ 0, 1 ],
          [ 300, 0.75 ],
        ],
      }, {
        prop: 'opacity',
        stops: [
          [ -300, 0.5 ],
          [ 0, 1 ],
          [ 300, 0.5 ],
        ],
      },
    ]}
    width={70}
    css={styles.page}
    onClick={(e) => {
      onClick(e);
    }}
  >
    {children}
  </StyledAnimatedView>
);

ProgressPage.propTypes = {
  index: PropTypes.number,
  children: PropTypes.node,
  onClick: PropTypes.func,
};

ProgressPage.displayName = 'ProgressPage';

class Carousel extends Component {
  constructor(props) {
    super(props);
    this.state = {
      currentView: 0,
      progress: 0,
    };

    this._handleScroll = this._handleScroll.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.productId !== nextProps.productId) {
      this.setState({ currentView: 0, progress: 0 });
    }
  }

  _handleScroll(progress) {
    this.setState({ progress });
  }

  render() {
    const { currentView, progress } = this.state;
    return (
      <StyledViewPager
        width={1}
        display="flex"
        flexDirection="column"
        css={styles.viewport}
      >
        <StyledFrame
          width={1}
          // eslint-disable-next-line no-return-assign
          ref={c => this.frame = c}
          css={styles.frame}
        >
          <StyledTrack
            display="flex"
            currentView={currentView}
            onScroll={this._handleScroll}
            onViewChange={(currentIndicies) => {
              this.setState({ currentView: currentIndicies[0] });
            }}
          >
            {this.props.images.map((image, i) => (
              <ProgressView key={i}>
                <Image src={`/static/images/product/${image}`} />
              </ProgressView>
            ))}
          </StyledTrack>
          <ProgressBar progress={progress} />
        </StyledFrame>
        <Box
          my1
          mx0
          display="flex"
          flexDirection="row"
          justifyContent="flex-start"
          alignItems="center"
          is="nav"
        >
          {this.props.images.map((image, i) =>
            <ProgressPage
              key={i}
              index={i}
              onClick={() => this.setState({ currentView: i })}
            >
              <Image src={`/static/images/product/${thumb(image)}`} />
            </ProgressPage>
          )}
        </Box>
      </StyledViewPager>
    );
  }
}

Carousel.propTypes = {
  images: PropTypes.arrayOf(PropTypes.string),
  productId: PropTypes.string,
};

Carousel.displayName = 'Carousel';

export default Carousel;
<commit_msg>maxwidths per breakpoints<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Box, withAxs, config } from 'axs';
import { ViewPager, Frame, Track, View, AnimatedView } from 'react-view-pager';
import { Image } from '../base';

const StyledViewPager = withAxs(ViewPager);
const StyledFrame = withAxs(Frame);
const StyledTrack = withAxs(Track);
const StyledView = withAxs(View);
const StyledAnimatedView = withAxs(AnimatedView);

const { breakpoints } = config.get();

const thumb = image => image.replace('.jpg', '-s.jpg');

const styles = {
  viewport: {
    maxWidth: 600,
    margin: '0 auto',
    flexDirection: 'column',
    [breakpoints[0]]: {
      maxWidth: 800,
      flexDirection: 'row',
    },
    [breakpoints[1]]: {
      maxWidth: 684,
      flexDirection: 'column !important',
    },
    [breakpoints[2]]: {
      maxWidth: 706,
      flexDirection: 'row !important',
    },
  },
  frame: {
    maxWidth: 800,
    margin: '0 auto',
  },
  view: {
    userSelect: 'none',
  },
  progressContainer: {
    height: 3,
    position: 'relative',
  },
  progressBar: {
    height: '100%',
    transformOrigin: 'left center',
    position: 'absolute',
  },
  pageNav: {
    flexDirection: 'row',
    [breakpoints[0]]: {
      flexDirection: 'column',
    },
    [breakpoints[1]]: {
      flexDirection: 'row !important',
    },
    [breakpoints[2]]: {
      flexDirection: 'column !important',
    },
  },
  page: {
    height: 50,
    cursor: 'pointer',
  },
};

class ProgressView extends Component {
  render() {
    return (
      <StyledView flexAuto css={styles.view} {...this.props}>
        <AnimatedView
          animations={[
            {
              prop: 'opacity',
              stops: [
                [ -200, 0 ],
                [ 0, 1 ],
                [ 200, 0 ],
              ],
            }, {
              prop: 'translateY',
              stops: [
                [ -200, 50 ],
                [ 0, 0 ],
                [ 200, 50 ],
              ],
            },
          ]}
        >
          {this.props.children}
        </AnimatedView>
      </StyledView>
    );
  }
}

ProgressView.propTypes = {
  children: PropTypes.node,
};

ProgressView.displayName = 'ProgressView';

const ProgressBar = ({ progress }) => (
  <Box bgGray3 width={1} css={styles.progressContainer}>
    <Box
      bgGray9
      width={1}
      css={{
        ...styles.progressBar,
        transform: `scaleX(${Math.max(0, Math.min(1, progress))})`,
      }}
    />
  </Box>
);

ProgressBar.propTypes = {
  progress: PropTypes.number,
};

ProgressBar.displayName = 'ProgressBar';

const ProgressPage = ({ index, children, onClick }) => (
  <StyledAnimatedView
    mr={[ 2, 0, 2, 0 ]}
    ml={[ 0, 2, 0, 3 ]}
    key={index}
    index={index}
    animations={[
      {
        prop: 'scale',
        stops: [
          [ -300, 0.75 ],
          [ 0, 1 ],
          [ 300, 0.75 ],
        ],
      }, {
        prop: 'opacity',
        stops: [
          [ -300, 0.5 ],
          [ 0, 1 ],
          [ 300, 0.5 ],
        ],
      },
    ]}
    width={70}
    css={styles.page}
    onClick={(e) => {
      onClick(e);
    }}
  >
    {children}
  </StyledAnimatedView>
);

ProgressPage.propTypes = {
  index: PropTypes.number,
  children: PropTypes.node,
  onClick: PropTypes.func,
};

ProgressPage.displayName = 'ProgressPage';

class Carousel extends Component {
  constructor(props) {
    super(props);
    this.state = {
      currentView: 0,
      progress: 0,
    };

    this._handleScroll = this._handleScroll.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.productId !== nextProps.productId) {
      this.setState({ currentView: 0, progress: 0 });
    }
  }

  _handleScroll(progress) {
    this.setState({ progress });
  }

  render() {
    const { currentView, progress } = this.state;
    return (
      <StyledViewPager
        width={1}
        display="flex"
        css={styles.viewport}
      >
        <StyledFrame
          width={1}
          // eslint-disable-next-line no-return-assign
          ref={c => this.frame = c}
          css={styles.frame}
        >
          <StyledTrack
            display="flex"
            currentView={currentView}
            onScroll={this._handleScroll}
            onViewChange={(currentIndicies) => {
              this.setState({ currentView: currentIndicies[0] });
            }}
          >
            {this.props.images.map((image, i) => (
              <ProgressView key={i}>
                <Image src={`/static/images/product/${image}`} />
              </ProgressView>
            ))}
          </StyledTrack>
          <ProgressBar progress={progress} />
        </StyledFrame>
        <Box
          my1
          mx0
          display="flex"
          justifyContent="flex-start"
          alignItems="center"
          is="nav"
          css={styles.pageNav}
        >
          {this.props.images.map((image, i) =>
            <ProgressPage
              key={i}
              index={i}
              onClick={() => this.setState({ currentView: i })}
            >
              <Image src={`/static/images/product/${thumb(image)}`} />
            </ProgressPage>
          )}
        </Box>
      </StyledViewPager>
    );
  }
}

Carousel.propTypes = {
  images: PropTypes.arrayOf(PropTypes.string),
  productId: PropTypes.string,
};

Carousel.displayName = 'Carousel';

export default Carousel;
<|endoftext|>


<commit_before>/*
 *
 * Mongo-Hacker
 * MongoDB Shell Enhancements for Hackers
 *
 * Tyler J. Brock - 2013
 *
 * http://tylerbrock.github.com/mongo-hacker
 *
 */

if (_isWindows()) {
    print("\nSorry! MongoDB Shell Enhancements for Hackers isn't compatible with Windows.\n");
}

var current_version = parseFloat(db.serverBuildInfo().version).toFixed(2)

if (current_version < 2.2) {
    print("Sorry! MongoDB Shell Enhancements for Hackers is only compatible with Mongo 2.2+\n");
}

<commit_msg>allow --nodb to work with version check<commit_after>/*
 *
 * Mongo-Hacker
 * MongoDB Shell Enhancements for Hackers
 *
 * Tyler J. Brock - 2013
 *
 * http://tylerbrock.github.com/mongo-hacker
 *
 */

if (_isWindows()) {
    print("\nSorry! MongoDB Shell Enhancements for Hackers isn't compatible with Windows.\n");
}

if (typeof db !== 'undefined') {
    var current_version = parseFloat(db.serverBuildInfo().version).toFixed(2)

    if (current_version < 2.2) {
        print("Sorry! MongoDB Shell Enhancements for Hackers is only compatible with Mongo 2.2+\n");
    }
}

<|endoftext|>


<commit_before>angular.module('Aggie')

.controller('NavbarController', [
  '$scope',
  '$rootScope',
  '$location',
  'AuthService',
  'FlashService',
  'Socket',
  function($scope, $rootScope, $location, AuthService, flash, Socket) {
    $scope.unreadErrorCount = '0';

    var init = function() {
      if ($rootScope.currentUser) {
        Socket.on('sourceErrorCountUpdated', sourceErrorCountUpdated);
      } else {
        Socket.off('sourceErrorCountUpdated');
      }
    };

    var sourceErrorCountUpdated = function(response) {
      $scope.unreadErrorCount = response.unreadErrorCount;
    };

    $scope.logout = function() {
      AuthService.logout(function(err) {
        if (!err) {
          if ($location.path() == '/login') {
            flash.setNoticeNow('You have been successfully logged out.');
          } else {
            flash.setNotice('You have been successfully logged out.');
            $location.path('/login');
          }
        } else {
          console.log('Error', err);
        }
      });
    };

    $rootScope.$watch('currentUser', init);

    init();
  }
]);
<commit_msg>fixed qs params on logout (closes #1297)<commit_after>angular.module('Aggie')

.controller('NavbarController', [
  '$scope',
  '$rootScope',
  '$location',
  'AuthService',
  'FlashService',
  'Socket',
  function($scope, $rootScope, $location, AuthService, flash, Socket) {
    $scope.unreadErrorCount = '0';

    var init = function() {
      if ($rootScope.currentUser) {
        Socket.on('sourceErrorCountUpdated', sourceErrorCountUpdated);
      } else {
        Socket.off('sourceErrorCountUpdated');
      }
    };

    var sourceErrorCountUpdated = function(response) {
      $scope.unreadErrorCount = response.unreadErrorCount;
    };

    $scope.logout = function() {
      AuthService.logout(function(err) {
        if (!err) {
          if ($location.path() == '/login') {
            flash.setNoticeNow('You have been successfully logged out.');
          } else {
            flash.setNotice('You have been successfully logged out.');
            $location.url('/login');
          }
        } else {
          console.log('Error', err);
        }
      });
    };

    $rootScope.$watch('currentUser', init);

    init();
  }
]);
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * Test fixture for print preview WebUI testing.
 * @extends {testing.Test}
 * @constructor
 **/
function PrintPreviewWebUITest() {}

PrintPreviewWebUITest.prototype = {
  __proto__: testing.Test.prototype,

  /**
   * Browse to the sample page, cause print preview & call PreLoad().
   * @type {string}
   * @override
   **/
  browsePrintPreload: 'print_preview_hello_world_test.html',

  /**
   * Register a mock handler to ensure expectations are met and print preview
   * behaves correctly.
   * @type {Function}
   * @override
   **/
  PreLoad: function() {
    // TODO(scr) remove this after tests pass consistently.
    console.info('PreLoad');

    /**
     * Create a handler class with empty methods to allow mocking to register
     * expectations and for registration of handlers with chrome.send.
     **/
    function MockPrintPreviewHandler() {}

    MockPrintPreviewHandler.prototype = {
      getDefaultPrinter: function() {},
      getPrinters: function() {},
      getPreview: function(settings) {},
      print: function(settings) {},
      getPrinterCapabilities: function(printerName) {},
      showSystemDialog: function() {},
      managePrinters: function() {},
      closePrintPreviewTab: function() {},
      hidePreview: function() {},
    };

    // Create the actual mock and register stubs for methods expected to be
    // called before tests run.  Specific expectations can be made in the
    // tests themselves.
    var mockHandler = this.mockHandler = mock(MockPrintPreviewHandler);
    mockHandler.stubs().getDefaultPrinter().
        will(callFunction(function() {
          setDefaultPrinter('FooDevice');
        }));
    mockHandler.stubs().getPrinterCapabilities(NOT_NULL).
        will(callFunction(function() {
          updateWithPrinterCapabilities({
            disableColorOption: true,
            setColorAsDefault: true,
            disableCopiesOption: true,
          });
        }));
    mockHandler.stubs().getPreview(NOT_NULL).
        will(callFunction(function() {
          updatePrintPreview('title', true, 1, 1);
        }));

    mockHandler.stubs().getPrinters().
        will(callFunction(function() {
          setPrinters([{
              printerName: 'FooName',
              deviceName: 'FooDevice',
            }, {
              printerName: 'BarName',
              deviceName: 'BarDevice',
            },
          ]);
        }));

    // Register mock as a handler of the chrome.send messages.
    registerMockMessageCallbacks(mockHandler, MockPrintPreviewHandler);

    // Override checkCompatiblePluginExists to return a value consistent with
    // the state being tested and stub out the pdf viewer if it doesn't exist,
    // such as on non-official builds. When the plugin exists, use the real
    // thing.
    var self = this;
    window.addEventListener('DOMContentLoaded', function() {
      if (!this.checkCompatiblePluginExists()) {
        // TODO(scr) remove this after tests pass consistently.
        console.info('no PDF Plugin; providing fake methods.');
        this.createPDFPlugin = self.createPDFPlugin;
      }

      this.checkCompatiblePluginExists =
          self.checkCompatiblePluginExists;
    });
  },

  /**
   * Generate a real C++ class; don't typedef.
   * @type {?string}
   * @override
   **/
  typedefCppFixture: null,

  /**
   * Create the PDF plugin or reload the existing one. This function replaces
   * createPDFPlugin defined in
   * chrome/browser/resources/print_preview/print_preview.js when there is no
   * official pdf plugin so that the WebUI logic can be tested. It creates and
   * attaches an HTMLDivElement to the |mainview| element with attributes and
   * empty methods, which are used by testing and that would be provided by the
   * HTMLEmbedElement when the PDF plugin exists.
   * @param {string} previewUid Preview unique identifier.
   */
  createPDFPlugin: function(previewUid) {
    var pdfViewer = $('pdf-viewer');
    if (pdfViewer)
      return;

    pdfViewer = document.createElement('div');
    pdfViewer.setAttribute('id', 'pdf-viewer');
    pdfViewer.setAttribute('type',
                           'application/x-google-chrome-print-preview-pdf');
    pdfViewer.setAttribute(
        'src', 'chrome://print/' + previewUid + '/print.pdf');
    pdfViewer.setAttribute('aria-live', 'polite');
    pdfViewer.setAttribute('aria-atomic', 'true');
    function fakeFunction() {}
    pdfViewer.onload = fakeFunction;
    pdfViewer.goToPage = fakeFunction;
    pdfViewer.removePrintButton = fakeFunction;
    pdfViewer.fitToHeight = fakeFunction;
    pdfViewer.grayscale = fakeFunction;
    $('mainview').appendChild(pdfViewer);
    onPDFLoad();
  },

  /**
   * Always return true so tests run on systems without plugin available.
   * @return {boolean} Always true.
   **/
  checkCompatiblePluginExists: function() {
    return true;
  },
};

GEN('#include "base/command_line.h"');
GEN('#include "chrome/browser/ui/webui/web_ui_browsertest.h"');
GEN('#include "chrome/common/chrome_switches.h"');
GEN('');
GEN('class PrintPreviewWebUITest');
GEN('    : public WebUIBrowserTest {');
GEN(' protected:');
GEN('  // WebUIBrowserTest override.');
GEN('  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {');
GEN('    WebUIBrowserTest::SetUpCommandLine(command_line);');
GEN('#if !defined(GOOGLE_CHROME_BUILD) || defined(OS_CHROMEOS)');
GEN('    // Don\'t enable the flag for chrome builds, which should be on by ' +
    'default.');
GEN('    command_line->AppendSwitch(switches::kEnablePrintPreview);');
GEN('#else');
GEN('    ASSERT_TRUE(switches::IsPrintPreviewEnabled());');
GEN('#endif');
GEN('  }');
GEN('');
GEN('};');
GEN('');

/**
 * The expected length of the |printer-list| element.
 * @type {number}
 * @const
 **/
var printerListMinLength = 2;

/**
 * The expected index of the "foo" printer returned by the stubbed handler.
 * @type {number}
 * @const
 **/
var fooIndex = 0;

/**
 * The expected index of the "bar" printer returned by the stubbed handler.
 * @type {number}
 * @const
 **/
var barIndex = 1;

// Test some basic assumptions about the print preview WebUI.
TEST_F('PrintPreviewWebUITest', 'FLAKY_TestPrinterList', function() {
  var printerList = $('printer-list');
  assertNotEquals(null, printerList);
  assertGE(printerList.options.length, printerListMinLength);
  expectEquals(fooIndex, printerList.selectedIndex);
  expectEquals('FooName', printerList.options[fooIndex].text,
               'fooIndex=' + fooIndex);
  expectEquals('FooDevice', printerList.options[fooIndex].value,
               'fooIndex=' + fooIndex);
  expectEquals('BarName', printerList.options[barIndex].text,
               'barIndex=' + barIndex);
  expectEquals('BarDevice', printerList.options[barIndex].value,
               'barIndex=' + barIndex);
});

/**
 * Verify that the section |sectionId| visibility matches |visible|.
 * @param {string} sectionId The id of the section to check.
 * @param {boolean} visible The expected state of visibility.
 **/
function checkSectionVisible(sectionId, visible) {
  var section = $(sectionId);
  assertNotEquals(null, section);
  expectEquals(section.classList.contains('visible'), visible,
               'sectionId=' + sectionId);
}

// Test that disabled settings hide the disabled sections.
// crbug.com/90476
TEST_F('PrintPreviewWebUITest', 'FLAKY_TestSectionsDisabled', function() {
  this.mockHandler.expects(once()).getPrinterCapabilities('FooDevice').
      will(callFunction(function() {
        updateWithPrinterCapabilities({
          disableColorOption: true,
          setColorAsDefault: true,
          disableCopiesOption: true,
          disableLandscapeOption: true,
        });
      }));

  updateControlsWithSelectedPrinterCapabilities();

  checkSectionVisible('layout-option', false);
  checkSectionVisible('color-options', false);
  checkSectionVisible('copies-option', false);
});

// Test that changing the selected printer updates the preview.
// crbug.com/90476
TEST_F('PrintPreviewWebUITest', 'FLAKY_TestPrinterChangeUpdatesPreview',
       function() {
  var matchAnythingSave = new SaveArgumentsMatcher(ANYTHING);

  this.mockHandler.expects(once()).getPreview(matchAnythingSave).
      will(callFunction(function() {
        updatePrintPreview('title', true, 2,
                           matchAnythingSave.argument.requestID);
      }));

  var printerList = $('printer-list');
  assertNotEquals(null, printerList, 'printerList');
  assertGE(printerList.options.length, printerListMinLength);
  expectEquals(fooIndex, printerList.selectedIndex,
               'fooIndex=' + fooIndex);
  var oldLastPreviewRequestID = lastPreviewRequestID;
  ++printerList.selectedIndex;
  updateControlsWithSelectedPrinterCapabilities();
  expectNotEquals(oldLastPreviewRequestID, lastPreviewRequestID);
});

/**
 * Test fixture to test case when no PDF plugin exists.
 * @extends {PrintPreviewWebUITest}
 * @constructor
 **/
function PrintPreviewNoPDFWebUITest() {}

PrintPreviewNoPDFWebUITest.prototype = {
  __proto__: PrintPreviewWebUITest.prototype,

  /**
   * Provide a typedef for C++ to correspond to JS subclass.
   * @type {?string}
   * @override
   */
  typedefCppFixture: 'PrintPreviewWebUITest',

  /**
   * Always return false to simulate failure and check expected error condition.
   * @return {boolean} Always false.
   * @override
   */
  checkCompatiblePluginExists: function() {
    return false;
  },
};

// Test that error message is displayed when plugin doesn't exist.
TEST_F('PrintPreviewNoPDFWebUITest', 'TestErrorMessage', function() {
  var errorButton = $('error-button');
  assertNotEquals(null, errorButton);
  expectFalse(errorButton.disabled);
  var errorText = $('error-text');
  assertNotEquals(null, errorText);
  expectFalse(errorText.classList.contains('hidden'));
});
<commit_msg>Address continuous build for mac flakiness.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * Test fixture for print preview WebUI testing.
 * @extends {testing.Test}
 * @constructor
 **/
function PrintPreviewWebUITest() {}

PrintPreviewWebUITest.prototype = {
  __proto__: testing.Test.prototype,

  /**
   * Browse to the sample page, cause print preview & call PreLoad().
   * @type {string}
   * @override
   **/
  browsePrintPreload: 'print_preview_hello_world_test.html',

  /**
   * Register a mock handler to ensure expectations are met and print preview
   * behaves correctly.
   * @type {Function}
   * @override
   **/
  PreLoad: function() {
    // TODO(scr) remove this after tests pass consistently.
    console.info('PreLoad');

    /**
     * Create a handler class with empty methods to allow mocking to register
     * expectations and for registration of handlers with chrome.send.
     **/
    function MockPrintPreviewHandler() {}

    MockPrintPreviewHandler.prototype = {
      getDefaultPrinter: function() {},
      getPrinters: function() {},
      getPreview: function(settings) {},
      print: function(settings) {},
      getPrinterCapabilities: function(printerName) {},
      showSystemDialog: function() {},
      managePrinters: function() {},
      closePrintPreviewTab: function() {},
      hidePreview: function() {},
    };

    // Create the actual mock and register stubs for methods expected to be
    // called before tests run.  Specific expectations can be made in the
    // tests themselves.
    var mockHandler = this.mockHandler = mock(MockPrintPreviewHandler);
    mockHandler.stubs().getDefaultPrinter().
        will(callFunction(function() {
          setDefaultPrinter('FooDevice');
        }));
    mockHandler.stubs().getPrinterCapabilities(NOT_NULL).
        will(callFunction(function() {
          updateWithPrinterCapabilities({
            disableColorOption: true,
            setColorAsDefault: true,
            disableCopiesOption: true,
          });
        }));
    mockHandler.stubs().getPreview(NOT_NULL).
        will(callFunction(function() {
          updatePrintPreview('title', true, 1, 1);
        }));

    mockHandler.stubs().getPrinters().
        will(callFunction(function() {
          setPrinters([{
              printerName: 'FooName',
              deviceName: 'FooDevice',
            }, {
              printerName: 'BarName',
              deviceName: 'BarDevice',
            },
          ]);
        }));

    // Register mock as a handler of the chrome.send messages.
    registerMockMessageCallbacks(mockHandler, MockPrintPreviewHandler);

    // Override checkCompatiblePluginExists to return a value consistent with
    // the state being tested and stub out the pdf viewer if it doesn't exist,
    // such as on non-official builds. When the plugin exists, use the real
    // thing.
    var self = this;
    window.addEventListener('DOMContentLoaded', function() {
      if (!this.checkCompatiblePluginExists()) {
        // TODO(scr) remove this after tests pass consistently.
        console.info('no PDF Plugin; providing fake methods.');
        this.createPDFPlugin = self.createPDFPlugin;
      }

      this.checkCompatiblePluginExists =
          self.checkCompatiblePluginExists;
    });
  },

  /**
   * Generate a real C++ class; don't typedef.
   * @type {?string}
   * @override
   **/
  typedefCppFixture: null,

  /**
   * Create the PDF plugin or reload the existing one. This function replaces
   * createPDFPlugin defined in
   * chrome/browser/resources/print_preview/print_preview.js when there is no
   * official pdf plugin so that the WebUI logic can be tested. It creates and
   * attaches an HTMLDivElement to the |mainview| element with attributes and
   * empty methods, which are used by testing and that would be provided by the
   * HTMLEmbedElement when the PDF plugin exists.
   * @param {string} previewUid Preview unique identifier.
   */
  createPDFPlugin: function(previewUid) {
    var pdfViewer = $('pdf-viewer');
    if (pdfViewer)
      return;

    pdfViewer = document.createElement('div');
    pdfViewer.setAttribute('id', 'pdf-viewer');
    pdfViewer.setAttribute('type',
                           'application/x-google-chrome-print-preview-pdf');
    pdfViewer.setAttribute(
        'src', 'chrome://print/' + previewUid + '/print.pdf');
    pdfViewer.setAttribute('aria-live', 'polite');
    pdfViewer.setAttribute('aria-atomic', 'true');
    function fakeFunction() {}
    pdfViewer.onload = fakeFunction;
    pdfViewer.goToPage = fakeFunction;
    pdfViewer.removePrintButton = fakeFunction;
    pdfViewer.fitToHeight = fakeFunction;
    pdfViewer.grayscale = fakeFunction;
    $('mainview').appendChild(pdfViewer);
    onPDFLoad();
  },

  /**
   * Always return true so tests run on systems without plugin available.
   * @return {boolean} Always true.
   **/
  checkCompatiblePluginExists: function() {
    return true;
  },
};

GEN('#include "base/command_line.h"');
GEN('#include "chrome/browser/ui/webui/web_ui_browsertest.h"');
GEN('#include "chrome/common/chrome_switches.h"');
GEN('');
GEN('class PrintPreviewWebUITest');
GEN('    : public WebUIBrowserTest {');
GEN(' protected:');
GEN('  // WebUIBrowserTest override.');
GEN('  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {');
GEN('    WebUIBrowserTest::SetUpCommandLine(command_line);');
GEN('#if !defined(GOOGLE_CHROME_BUILD) || defined(OS_CHROMEOS)');
GEN('    // Don\'t enable the flag for chrome builds, which should be on by ' +
    'default.');
GEN('    command_line->AppendSwitch(switches::kEnablePrintPreview);');
GEN('#else');
GEN('    ASSERT_TRUE(switches::IsPrintPreviewEnabled());');
GEN('#endif');
GEN('  }');
GEN('');
GEN('};');
GEN('');

/**
 * The expected length of the |printer-list| element.
 * @type {number}
 * @const
 **/
var printerListMinLength = 2;

/**
 * The expected index of the "foo" printer returned by the stubbed handler.
 * @type {number}
 * @const
 **/
var fooIndex = 0;

/**
 * The expected index of the "bar" printer returned by the stubbed handler.
 * @type {number}
 * @const
 **/
var barIndex = 1;

// Test some basic assumptions about the print preview WebUI.
// crbug.com/88282
TEST_F('PrintPreviewWebUITest', 'FLAKY_TestPrinterList', function() {
  var printerList = $('printer-list');
  assertNotEquals(null, printerList);
  assertGE(printerList.options.length, printerListMinLength);
  expectEquals(fooIndex, printerList.selectedIndex);
  expectEquals('FooName', printerList.options[fooIndex].text,
               'fooIndex=' + fooIndex);
  expectEquals('FooDevice', printerList.options[fooIndex].value,
               'fooIndex=' + fooIndex);
  expectEquals('BarName', printerList.options[barIndex].text,
               'barIndex=' + barIndex);
  expectEquals('BarDevice', printerList.options[barIndex].value,
               'barIndex=' + barIndex);
});

/**
 * Verify that the section |sectionId| visibility matches |visible|.
 * @param {string} sectionId The id of the section to check.
 * @param {boolean} visible The expected state of visibility.
 **/
function checkSectionVisible(sectionId, visible) {
  var section = $(sectionId);
  assertNotEquals(null, section);
  expectEquals(section.classList.contains('visible'), visible,
               'sectionId=' + sectionId);
}

// Test that disabled settings hide the disabled sections.
// crbug.com/90476
TEST_F('PrintPreviewWebUITest', 'FLAKY_TestSectionsDisabled', function() {
  this.mockHandler.expects(once()).getPrinterCapabilities('FooDevice').
      will(callFunction(function() {
        updateWithPrinterCapabilities({
          disableColorOption: true,
          setColorAsDefault: true,
          disableCopiesOption: true,
          disableLandscapeOption: true,
        });
      }));

  updateControlsWithSelectedPrinterCapabilities();

  checkSectionVisible('layout-option', false);
  checkSectionVisible('color-options', false);
  checkSectionVisible('copies-option', false);
});

// Test that changing the selected printer updates the preview.
// crbug.com/90476
TEST_F('PrintPreviewWebUITest', 'FLAKY_TestPrinterChangeUpdatesPreview',
       function() {
  var matchAnythingSave = new SaveArgumentsMatcher(ANYTHING);

  this.mockHandler.expects(once()).getPreview(matchAnythingSave).
      will(callFunction(function() {
        updatePrintPreview('title', true, 2,
                           matchAnythingSave.argument.requestID);
      }));

  var printerList = $('printer-list');
  assertNotEquals(null, printerList, 'printerList');
  assertGE(printerList.options.length, printerListMinLength);
  expectEquals(fooIndex, printerList.selectedIndex,
               'fooIndex=' + fooIndex);
  var oldLastPreviewRequestID = lastPreviewRequestID;
  ++printerList.selectedIndex;
  updateControlsWithSelectedPrinterCapabilities();
  expectNotEquals(oldLastPreviewRequestID, lastPreviewRequestID);
});

/**
 * Test fixture to test case when no PDF plugin exists.
 * @extends {PrintPreviewWebUITest}
 * @constructor
 **/
function PrintPreviewNoPDFWebUITest() {}

PrintPreviewNoPDFWebUITest.prototype = {
  __proto__: PrintPreviewWebUITest.prototype,

  /**
   * Provide a typedef for C++ to correspond to JS subclass.
   * @type {?string}
   * @override
   */
  typedefCppFixture: 'PrintPreviewWebUITest',

  /**
   * Always return false to simulate failure and check expected error condition.
   * @return {boolean} Always false.
   * @override
   */
  checkCompatiblePluginExists: function() {
    return false;
  },
};

// Test that error message is displayed when plugin doesn't exist.
// crbug.com/90476
TEST_F('PrintPreviewNoPDFWebUITest', 'FLAKY_TestErrorMessage', function() {
  var errorButton = $('error-button');
  assertNotEquals(null, errorButton);
  expectFalse(errorButton.disabled);
  var errorText = $('error-text');
  assertNotEquals(null, errorText);
  expectFalse(errorText.classList.contains('hidden'));
});
<|endoftext|>


<commit_before>window.requestAnimationFrame = window.requestAnimationFrame ||(
function() {
	return  window.webkitRequestAnimationFrame ||
			window.mozRequestAnimationFrame ||
			window.oRequestAnimationFrame ||
			window.msRequestAnimationFrame ||
			function( callback, element) {
				window.setTimeout(callback, 1000 / 60);
			};
})();

var canvas,
		gl,
		width, height, numFrames, full_game,
		turn_number, counter, play,
		vertex_buffer, color_buffer,
		blankColor, player1Color, player2Color, dimFactor,
		vertex_locations, player1Color, player2Color,
		vertex_shader, fragment_shader,
		currentProgram,
		vertex_position, color_position,
		parameters = {  start_time  : new Date().getTime(),
						time        : 0,
						screenWidth : 0,
						screenHeight: 0 };

function begin(data) {
	var meta = data.split("\n")[0].split(" ")
	var restOfFile = data.substring(data.indexOf("\n") + 1).replace(/[^0-9]/g, "");
	var w = meta[0]
	var h = meta[1]
	var nf = meta[2]
	var fc = restOfFile

	vertex_shader = document.getElementById('vs').textContent;
	fragment_shader = document.getElementById('fs').textContent;

	canvas = document.querySelector('canvas');

	//Get width, height, and number of frames from file. Note that those are already declared as global variables.
	width = w;
	height = h;
	numFrames = nf;

	//Parse 1D array:
	full_game = [];
	var loc = 0;
	for(var a = 0; a < numFrames; a++) {
		var frame = [];
		for(var b = 0; b < height * width; b++) {
			frame.push(fc[loc]);
			loc++;
		}
		full_game.push(frame);
	}

	//Add canvas listener:
	play = true;
	document.addEventListener("keydown", keyFunc);

	//Set turn number to be 0;
	turn_number = 0;
	counter = 0;

	//Initialise WebGL
	try {
		gl = canvas.getContext('experimental-webgl');
	} catch(error) { }

	if(!gl) {
		throw "cannot create webgl context";
	}

	vl = [];
	var dx = 2.0 / width, dy = 2.0 / height, xSize = 0.4 * dx, ySize = 0.4 * dy;
	for(var yPos = -1 +(dy / 2); yPos < 1; yPos += dy) {
		for(var xPos = -1 +(dx / 2); xPos < 1; xPos += dx) {
			vl.push(xPos - xSize);
			vl.push(yPos - ySize);
			vl.push(xPos + xSize);
			vl.push(yPos + ySize);
			vl.push(xPos + xSize);
			vl.push(yPos - ySize);
			vl.push(xPos - xSize);
			vl.push(yPos - ySize);
			vl.push(xPos + xSize);
			vl.push(yPos + ySize);
			vl.push(xPos - xSize);
			vl.push(yPos + ySize);
		}
	}
	var vertex_locations = new Float32Array(vl);

	//Get player colors from file.
	player1Color = new Float32Array([ 1.0, 0.0, 0.0 ]);
	player2Color = new Float32Array([ 0.0, 0.0, 1.0 ]);
	blankColor = new Float32Array([ 0.5, 0.5, 0.5 ]);
	dimFactor = 0.3;

	//Create Vertex buffer
	vertex_buffer = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
	gl.bufferData(gl.ARRAY_BUFFER, vertex_locations, gl.STATIC_DRAW);
	//Create Color buffer
	color_buffer = gl.createBuffer();

	//Create Program
	currentProgram = createProgram(vertex_shader, fragment_shader);

	//Find vertex and color positions.
	vertex_position = gl.getAttribLocation(currentProgram, "position");
	color_position = gl.getAttribLocation(currentProgram, "vcolor");

	onWindowResize();
	window.addEventListener('resize', onWindowResize, false);

	animate();
}

function keyFunc(e) {
	console.log(e.keyCode);
	if(e.keyCode == 37) {
		if(turn_number > 0) turn_number--;
		play = false;
	}
	else if(e.keyCode == 39) {
		if(turn_number < numFrames - 1) turn_number++;
		play = false;
	}
	else if(e.keyCode == 32) {
		play = !play;
	}
}

function createProgram(vertex, fragment) {

	var program = gl.createProgram();

	var vs = createShader(vertex, gl.VERTEX_SHADER);
	var fs = createShader('#ifdef GL_ES\nprecision highp float;\n#endif\n\n' + fragment, gl.FRAGMENT_SHADER);

	if(vs == null || fs == null) return null;

	gl.attachShader(program, vs);
	gl.attachShader(program, fs);

	gl.deleteShader(vs);
	gl.deleteShader(fs);

	gl.linkProgram(program);

	if(!gl.getProgramParameter(program, gl.LINK_STATUS)) {

		alert("ERROR:\n" +
		"VALIDATE_STATUS: " + gl.getProgramParameter(program, gl.VALIDATE_STATUS) + "\n" +
		"ERROR: " + gl.getError() + "\n\n" +
		"- Vertex Shader -\n" + vertex + "\n\n" +
		"- Fragment Shader -\n" + fragment);

		return null;

	}

	return program;

}

function createShader(src, type) {

	var shader = gl.createShader(type);

	gl.shaderSource(shader, src);
	gl.compileShader(shader);

	if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {

		alert((type == gl.VERTEX_SHADER ? "VERTEX" : "FRAGMENT") + " SHADER:\n" + gl.getShaderInfoLog(shader));
		return null;

	}

	return shader;
}

function onWindowResize(event) {
	canvas.width = 400;
	canvas.height = 400;

	parameters.screenWidth = canvas.width;
	parameters.screenHeight = canvas.height;

	gl.viewport(0, 0, canvas.width, canvas.height);
}

function animate() {
	if(turn_number < numFrames - 1) requestAnimationFrame(animate);
	counter++;
	if(play && turn_number < numFrames - 1 && counter % 12 == 0) turn_number++;
	nextFrame();
	render();
}

function nextFrame() {
	var map = full_game[turn_number];

	var colors = [];
	for(var a = 0; a < map.length; a++) {
		for(var b = 0; b < 6; b++) { //Fill in for each vertex:
			if(map[a] == 1) {
				colors.push(player1Color[0]);
				colors.push(player1Color[1]);
				colors.push(player1Color[2]);
			}
			else if(map[a] == 3) {
				colors.push(player1Color[0] * dimFactor);
				colors.push(player1Color[1] * dimFactor);
				colors.push(player1Color[2] * dimFactor);
			}
			else if(map[a] == 2) {
				colors.push(player2Color[0]);
				colors.push(player2Color[1]);
				colors.push(player2Color[2]);
			}
			else if(map[a] == 4) {
				colors.push(player2Color[0] * dimFactor);
				colors.push(player2Color[1] * dimFactor);
				colors.push(player2Color[2] * dimFactor);
			}
			else {
				colors.push(blankColor[0]);
				colors.push(blankColor[1]);
				colors.push(blankColor[2]);
			}
		}
	}

	gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.DYNAMIC_DRAW);
}

function render() {

	if(!currentProgram) return;

	parameters.time = new Date().getTime() - parameters.start_time;

	gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

	//Load program into GPU

	gl.useProgram(currentProgram);

	//Set values to program variables

	//Render geometry
	gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
	gl.vertexAttribPointer(vertex_position, 2, gl.FLOAT, false, 0, 0);
	gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
	gl.vertexAttribPointer(color_position, 3, gl.FLOAT, false, 0, 0);
	gl.enableVertexAttribArray(vertex_position);
	gl.enableVertexAttribArray(color_position);
	gl.drawArrays(gl.TRIANGLES, 0, 1536); //256 * 6
	gl.disableVertexAttribArray(vertex_position);
	gl.disableVertexAttribArray(color_position);
}<commit_msg>Keep Rendering<commit_after>window.requestAnimationFrame = window.requestAnimationFrame ||(
function() {
	return  window.webkitRequestAnimationFrame ||
			window.mozRequestAnimationFrame ||
			window.oRequestAnimationFrame ||
			window.msRequestAnimationFrame ||
			function( callback, element) {
				window.setTimeout(callback, 1000 / 60);
			};
})();

var canvas,
		gl,
		width, height, numFrames, full_game,
		turn_number, counter, play,
		vertex_buffer, color_buffer,
		blankColor, player1Color, player2Color, dimFactor,
		vertex_locations, player1Color, player2Color,
		vertex_shader, fragment_shader,
		currentProgram,
		vertex_position, color_position,
		parameters = {  start_time  : new Date().getTime(),
						time        : 0,
						screenWidth : 0,
						screenHeight: 0 };

function begin(data) {
	var meta = data.split("\n")[0].split(" ")
	var restOfFile = data.substring(data.indexOf("\n") + 1).replace(/[^0-9]/g, "");
	var w = meta[0]
	var h = meta[1]
	var nf = meta[2]
	var fc = restOfFile

	vertex_shader = document.getElementById('vs').textContent;
	fragment_shader = document.getElementById('fs').textContent;

	canvas = document.querySelector('canvas');

	//Get width, height, and number of frames from file. Note that those are already declared as global variables.
	width = w;
	height = h;
	numFrames = nf;

	//Parse 1D array:
	full_game = [];
	var loc = 0;
	for(var a = 0; a < numFrames; a++) {
		var frame = [];
		for(var b = 0; b < height * width; b++) {
			frame.push(fc[loc]);
			loc++;
		}
		full_game.push(frame);
	}

	//Add canvas listener:
	play = true;
	document.addEventListener("keydown", keyFunc);

	//Set turn number to be 0;
	turn_number = 0;
	counter = 0;

	//Initialise WebGL
	try {
		gl = canvas.getContext('experimental-webgl');
	} catch(error) { }

	if(!gl) {
		throw "cannot create webgl context";
	}

	vl = [];
	var dx = 2.0 / width, dy = 2.0 / height, xSize = 0.4 * dx, ySize = 0.4 * dy;
	for(var yPos = -1 +(dy / 2); yPos < 1; yPos += dy) {
		for(var xPos = -1 +(dx / 2); xPos < 1; xPos += dx) {
			vl.push(xPos - xSize);
			vl.push(yPos - ySize);
			vl.push(xPos + xSize);
			vl.push(yPos + ySize);
			vl.push(xPos + xSize);
			vl.push(yPos - ySize);
			vl.push(xPos - xSize);
			vl.push(yPos - ySize);
			vl.push(xPos + xSize);
			vl.push(yPos + ySize);
			vl.push(xPos - xSize);
			vl.push(yPos + ySize);
		}
	}
	var vertex_locations = new Float32Array(vl);

	//Get player colors from file.
	player1Color = new Float32Array([ 1.0, 0.0, 0.0 ]);
	player2Color = new Float32Array([ 0.0, 0.0, 1.0 ]);
	blankColor = new Float32Array([ 0.5, 0.5, 0.5 ]);
	dimFactor = 0.3;

	//Create Vertex buffer
	vertex_buffer = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
	gl.bufferData(gl.ARRAY_BUFFER, vertex_locations, gl.STATIC_DRAW);
	//Create Color buffer
	color_buffer = gl.createBuffer();

	//Create Program
	currentProgram = createProgram(vertex_shader, fragment_shader);

	//Find vertex and color positions.
	vertex_position = gl.getAttribLocation(currentProgram, "position");
	color_position = gl.getAttribLocation(currentProgram, "vcolor");

	onWindowResize();
	window.addEventListener('resize', onWindowResize, false);

	animate();
}

function keyFunc(e) {
	console.log(e.keyCode);
	if(e.keyCode == 37) {
		if(turn_number > 0) turn_number--;
		play = false;
	}
	else if(e.keyCode == 39) {
		if(turn_number < numFrames - 1) turn_number++;
		play = false;
	}
	else if(e.keyCode == 32) {
		play = !play;
	}
}

function createProgram(vertex, fragment) {

	var program = gl.createProgram();

	var vs = createShader(vertex, gl.VERTEX_SHADER);
	var fs = createShader('#ifdef GL_ES\nprecision highp float;\n#endif\n\n' + fragment, gl.FRAGMENT_SHADER);

	if(vs == null || fs == null) return null;

	gl.attachShader(program, vs);
	gl.attachShader(program, fs);

	gl.deleteShader(vs);
	gl.deleteShader(fs);

	gl.linkProgram(program);

	if(!gl.getProgramParameter(program, gl.LINK_STATUS)) {

		alert("ERROR:\n" +
		"VALIDATE_STATUS: " + gl.getProgramParameter(program, gl.VALIDATE_STATUS) + "\n" +
		"ERROR: " + gl.getError() + "\n\n" +
		"- Vertex Shader -\n" + vertex + "\n\n" +
		"- Fragment Shader -\n" + fragment);

		return null;

	}

	return program;

}

function createShader(src, type) {

	var shader = gl.createShader(type);

	gl.shaderSource(shader, src);
	gl.compileShader(shader);

	if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {

		alert((type == gl.VERTEX_SHADER ? "VERTEX" : "FRAGMENT") + " SHADER:\n" + gl.getShaderInfoLog(shader));
		return null;

	}

	return shader;
}

function onWindowResize(event) {
	canvas.width = 400;
	canvas.height = 400;

	parameters.screenWidth = canvas.width;
	parameters.screenHeight = canvas.height;

	gl.viewport(0, 0, canvas.width, canvas.height);
}

function animate() {
	requestAnimationFrame(animate);
	counter++;
	if(play && turn_number < numFrames - 1 && counter % 12 == 0) turn_number++;
	nextFrame();
	render();
}

function nextFrame() {
	var map = full_game[turn_number];

	var colors = [];
	for(var a = 0; a < map.length; a++) {
		for(var b = 0; b < 6; b++) { //Fill in for each vertex:
			if(map[a] == 1) {
				colors.push(player1Color[0]);
				colors.push(player1Color[1]);
				colors.push(player1Color[2]);
			}
			else if(map[a] == 3) {
				colors.push(player1Color[0] * dimFactor);
				colors.push(player1Color[1] * dimFactor);
				colors.push(player1Color[2] * dimFactor);
			}
			else if(map[a] == 2) {
				colors.push(player2Color[0]);
				colors.push(player2Color[1]);
				colors.push(player2Color[2]);
			}
			else if(map[a] == 4) {
				colors.push(player2Color[0] * dimFactor);
				colors.push(player2Color[1] * dimFactor);
				colors.push(player2Color[2] * dimFactor);
			}
			else {
				colors.push(blankColor[0]);
				colors.push(blankColor[1]);
				colors.push(blankColor[2]);
			}
		}
	}

	gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.DYNAMIC_DRAW);
}

function render() {

	if(!currentProgram) return;

	parameters.time = new Date().getTime() - parameters.start_time;

	gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

	//Load program into GPU

	gl.useProgram(currentProgram);

	//Set values to program variables

	//Render geometry
	gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
	gl.vertexAttribPointer(vertex_position, 2, gl.FLOAT, false, 0, 0);
	gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
	gl.vertexAttribPointer(color_position, 3, gl.FLOAT, false, 0, 0);
	gl.enableVertexAttribArray(vertex_position);
	gl.enableVertexAttribArray(color_position);
	gl.drawArrays(gl.TRIANGLES, 0, 1536); //256 * 6
	gl.disableVertexAttribArray(vertex_position);
	gl.disableVertexAttribArray(color_position);
}<|endoftext|>


<commit_before>/**
 * Panel layout UI element
 *
 * @class panel
 * @augments elation.ui.base
 * @memberof elation.ui
 *
 * @param {object} args
 * @param {string} args.classname
 * @param {string} args.orientation
 */
elation.require(["ui.base", "ui.content"], function() {
  elation.requireCSS("ui.panel");

  elation.component.add("ui.panel", function() {
    this.defaultcontainer = {tag: 'div', classname: 'ui_panel'};

    this.init = function() {
      this.items = [];
      this.orientation = this.args.orientation || 'vertical';

      this.addclass('ui_panel');
      this.addclass('orientation_' + this.orientation);
      if (this.args.classname) {
        this.addclass(this.args.classname);
      }
    }
    /**
     * Append a new component to this panel
     * @function add
     * @memberof elation.ui.panel#
     * @param {elation.component.base} component
     */
    this.add = function(component) {
      if (component) {
        if (elation.utils.isString(component)) {
          var panel = elation.ui.content({content: component, append: this});
          component = panel;
        } else {
          this.container.appendChild(component.container);
        }
        this.items.push(component);
        return component;
      } else {
        console.log('Error: invalid component passed in to ui.panel.add');
      }
      return false;
    }
    /**
     * Remove the specified component from this panel
     * @function remove
     * @memberof elation.ui.panel#
     * @param {elation.component.base} component
     */
    this.remove = function(component) {
      if (component.container && component.container.parentNode == this.container) {
        this.container.removeChild(component.container);
        var idx = this.items.indexOf(component);
        if (idx != -1) this.items.splice(idx, 1);
      }
    }
    /**
     * Clear all items from this panel
     * @function clear
     * @memberof elation.ui.panel#
     */
    this.clear = function() {
      while (this.items.length > 0) {
        this.remove(this.items[0]);
      }
    }
  }, elation.ui.base);
});
<commit_msg>Added ui.panel_vertical ui.panel_horizontal ui.panel_inline ui.panel_float<commit_after>/**
 * Panel layout UI element
 *
 * @class panel
 * @augments elation.ui.base
 * @memberof elation.ui
 *
 * @param {object} args
 * @param {string} args.classname
 * @param {string} args.orientation
 */
elation.require(["ui.base", "ui.content"], function() {
  elation.requireCSS("ui.panel");

  elation.component.add("ui.panel", function() {
    this.defaultcontainer = {tag: 'div', classname: 'ui_panel'};

    this.init = function() {
      this.items = [];
      this.orientation = this.args.orientation || 'vertical';

      this.addclass('ui_panel');
      this.addclass('orientation_' + this.orientation);
      if (this.args.classname) {
        this.addclass(this.args.classname);
      }
    }
    /**
     * Append a new component to this panel
     * @function add
     * @memberof elation.ui.panel#
     * @param {elation.component.base} component
     */
    this.add = function(component) {
      if (component) {
        if (elation.utils.isString(component)) {
          var panel = elation.ui.content({content: component, append: this});
          component = panel;
        } else {
          this.container.appendChild(component.container);
        }
        this.items.push(component);
        return component;
      } else {
        console.log('Error: invalid component passed in to ui.panel.add');
      }
      return false;
    }
    /**
     * Remove the specified component from this panel
     * @function remove
     * @memberof elation.ui.panel#
     * @param {elation.component.base} component
     */
    this.remove = function(component) {
      if (component.container && component.container.parentNode == this.container) {
        this.container.removeChild(component.container);
        var idx = this.items.indexOf(component);
        if (idx != -1) this.items.splice(idx, 1);
      }
    }
    /**
     * Clear all items from this panel
     * @function clear
     * @memberof elation.ui.panel#
     */
    this.clear = function() {
      while (this.items.length > 0) {
        this.remove(this.items[0]);
      }
    }
  }, elation.ui.base);

  elation.component.add("ui.panel_horizontal", function() {
    this.init = function() {
      this.args.orientation = 'horizontal';
      elation.ui.panel_horizontal.extendclass.init.call(this);
    }
  }, elation.ui.panel);
  elation.component.add("ui.panel_vertical", function() {
    this.init = function() {
      this.args.orientation = 'vertical';
      elation.ui.panel_vertical.extendclass.init.call(this);
    }
  }, elation.ui.panel);
  elation.component.add("ui.panel_float", function() {
    this.init = function() {
      this.args.orientation = 'float';
      elation.ui.panel_float.extendclass.init.call(this);
    }
  }, elation.ui.panel);
  elation.component.add("ui.panel_inline", function() {
    this.init = function() {
      this.args.orientation = 'inline';
      elation.ui.panel_inline.extendclass.init.call(this);
    }
  }, elation.ui.panel);
});
<|endoftext|>


<commit_before>let globals = require('globals')

let jest = { }
for (let i in globals.jest) {
  if (i !== 'test' && i !== 'xtest') jest[i] = globals.jest[i]
}

module.exports = {
  extends: 'standard',
  plugins: [
    'jest',
    'security',
    'node',
    'unicorn'
  ],
  rules: {
    'standard/no-callback-literal': 'off',

    'security/detect-possible-timing-attacks': 'error',
    'security/detect-eval-with-expression': 'error',
    'security/detect-non-literal-require': 'error',
    'security/detect-non-literal-regexp': 'error',
    'security/detect-pseudoRandomBytes': 'error',
    'security/detect-buffer-noassert': 'error',
    'security/detect-unsafe-regex': 'error',
    'security/detect-new-buffer': 'error',

    'node/no-unpublished-require': 'error',
    'node/no-extraneous-require': 'error',
    'node/no-missing-require': 'error',

    'unicorn/custom-error-definition': 'error',
    'unicorn/no-unused-properties': 'error',
    'unicorn/no-array-instanceof': 'error',
    'unicorn/prefer-event-key': 'error',
    'unicorn/regex-shorthand': 'error',

    'import/order': ['error', {
      'groups': [
        ['builtin', 'external'],
        ['internal', 'parent', 'sibling', 'index']
      ],
      'newlines-between': 'always'
    }],

    'nonblock-statement-body-position': 'error',
    'no-misleading-character-class': 'error',
    'computed-property-spacing': ['error', 'never'],
    'array-bracket-spacing': ['error', 'never'],
    'func-name-matching': 'error',
    'no-useless-return': 'error',
    'consistent-return': 'error',
    'multiline-ternary': ['error', 'never'],
    'no-nested-ternary': 'error',
    'block-scoped-var': 'error',
    'no-invalid-this': 'error',
    'global-require': 'error',
    'no-unused-vars': ['error', {
      args: 'after-used',
      vars: 'all'
    }],
    'no-new-symbol': 'error',
    'getter-return': 'error',
    'for-direction': 'error',
    'no-lonely-if': 'error',
    'prefer-const': 'off',
    'quote-props': ['error', 'consistent-as-needed'],
    'func-style': ['error', 'declaration'],
    'no-shadow': 'error',
    'max-len': ['error', 80],
    'no-new': 'off'
  },
  env: {
    browser: true,
    node: true
  },
  overrides: [
    {
      files: ['test/*', 'test/**/*', '*.test.js'],
      rules: {
        'node/no-unpublished-require': 'off',
        'node/no-missing-require': ['error', {
          allowModules: ['worker_threads']
        }]
      },
      globals: jest
    },
    {
      files: ['*.test.js'],
      rules: {
        'jest/require-to-throw-message': 'error',
        'jest/prefer-to-be-undefined': 'error',
        'jest/prefer-to-have-length': 'error',
        'jest/no-standalone-expect': 'error',
        'jest/prefer-hooks-on-top': 'error',
        'jest/no-identical-title': 'error',
        'jest/consistent-test-it': ['error', { fn: 'it' }],
        'jest/no-disabled-tests': 'error',
        'jest/prefer-to-be-null': 'error',
        'jest/prefer-to-contain': 'error',
        'jest/no-focused-tests': 'error',
        'jest/prefer-spy-on': 'error',
        'jest/no-try-expect': 'error',
        'jest/valid-expect': 'error',
        'jest/valid-title': 'error',
        'global-require': 'off'
      },
      globals: jest
    }
  ]
}
<commit_msg>Add more Jest rules<commit_after>let globals = require('globals')

let jest = { }
for (let i in globals.jest) {
  if (i !== 'test' && i !== 'xtest') jest[i] = globals.jest[i]
}

module.exports = {
  extends: 'standard',
  plugins: [
    'jest',
    'security',
    'node',
    'unicorn'
  ],
  rules: {
    'standard/no-callback-literal': 'off',

    'security/detect-possible-timing-attacks': 'error',
    'security/detect-eval-with-expression': 'error',
    'security/detect-non-literal-require': 'error',
    'security/detect-non-literal-regexp': 'error',
    'security/detect-pseudoRandomBytes': 'error',
    'security/detect-buffer-noassert': 'error',
    'security/detect-unsafe-regex': 'error',
    'security/detect-new-buffer': 'error',

    'node/no-unpublished-require': 'error',
    'node/no-extraneous-require': 'error',
    'node/no-missing-require': 'error',

    'unicorn/custom-error-definition': 'error',
    'unicorn/no-unused-properties': 'error',
    'unicorn/no-array-instanceof': 'error',
    'unicorn/prefer-event-key': 'error',
    'unicorn/regex-shorthand': 'error',

    'import/order': ['error', {
      'groups': [
        ['builtin', 'external'],
        ['internal', 'parent', 'sibling', 'index']
      ],
      'newlines-between': 'always'
    }],

    'nonblock-statement-body-position': 'error',
    'no-misleading-character-class': 'error',
    'computed-property-spacing': ['error', 'never'],
    'array-bracket-spacing': ['error', 'never'],
    'func-name-matching': 'error',
    'no-useless-return': 'error',
    'consistent-return': 'error',
    'multiline-ternary': ['error', 'never'],
    'no-nested-ternary': 'error',
    'block-scoped-var': 'error',
    'no-invalid-this': 'error',
    'global-require': 'error',
    'no-unused-vars': ['error', {
      args: 'after-used',
      vars: 'all'
    }],
    'no-new-symbol': 'error',
    'getter-return': 'error',
    'for-direction': 'error',
    'no-lonely-if': 'error',
    'prefer-const': 'off',
    'quote-props': ['error', 'consistent-as-needed'],
    'func-style': ['error', 'declaration'],
    'no-shadow': 'error',
    'max-len': ['error', 80],
    'no-new': 'off'
  },
  env: {
    browser: true,
    node: true
  },
  overrides: [
    {
      files: ['test/*', 'test/**/*', '*.test.js'],
      rules: {
        'node/no-unpublished-require': 'off',
        'node/no-missing-require': ['error', {
          allowModules: ['worker_threads']
        }]
      },
      globals: jest
    },
    {
      files: ['*.test.js'],
      rules: {
        'jest/require-to-throw-message': 'error',
        'jest/prefer-to-be-undefined': 'error',
        'jest/no-commented-out-tests': 'error',
        'jest/prefer-to-have-length': 'error',
        'jest/no-standalone-expect': 'error',
        'jest/prefer-hooks-on-top': 'error',
        'jest/no-jasmine-globals': 'error',
        'jest/no-identical-title': 'error',
        'jest/no-duplicate-hooks': 'error',
        'jest/consistent-test-it': ['error', { fn: 'it' }],
        'jest/prefer-called-with': 'error',
        'jest/no-disabled-tests': 'error',
        'jest/prefer-to-be-null': 'error',
        'jest/prefer-to-contain': 'error',
        'jest/no-test-prefixes': 'error',
        'jest/no-test-callback': 'error',
        'jest/no-focused-tests': 'error',
        'jest/no-truthy-falsy': 'error',
        'jest/lowercase-name': 'error',
        'jest/valid-describe': 'error',
        'jest/no-try-expect': 'error',
        'jest/prefer-spy-on': 'error',
        'jest/valid-expect': 'error',
        'jest/valid-title': 'error',
        'jest/prefer-todo': 'error',
        'global-require': 'off'
      },
      globals: jest
    }
  ]
}
<|endoftext|>