<commit_before>function load_balls() {
	var ballsInPlay = {
		"placeholder" : false,
		"ball-one" : false,
		"ball-two" : false,
		"ball-three" : false,
		"ball-four" : false,
		"ball-five" : false,
		"ball-six" : false,
		"ball-seven" : false,
		"ball-eight" : false,
		"ball-nine" : false,
		"ball-ten" : false,
		"ball-eleven" : false,
		"ball-twelve" : false,
		"ball-thirteen" : false,
		"ball-fourteen" : false,
		"ball-fifteen" : false
	};

	var indexToId = [
		"placeholder",
		"ball-one",
		"ball-two",
		"ball-three",
		"ball-four",
		"ball-five",
		"ball-six",
		"ball-seven",
		"ball-eight",
		"ball-nine",
		"ball-ten",
		"ball-eleven",
		"ball-twelve",
		"ball-thirteen",
		"ball-fourteen",
		"ball-fifteen"
	];

	$.ajax({
        url: "/api/game/ballsontable",
        success: function(data) {
            $.each(data["data"], function(index, value) {
            	ballsInPlay[indexToId[value]] = true;
            });
	        $.each(ballsInPlay, function(index, value) {
		   		if(value) {
		   			$("#" + index).css("opacity", 1);
		   		}
		   		else {
		   			$("#" + index).css("opacity", 0.3);
		   		}
	   		});
    	}
	});

   setTimeout(load_balls, 5000);
   return ballsInPlay;
}

function toggle_ball(id) {
	var idToBall = {
		"ball-one" : 1,
		"ball-two" : 2,
		"ball-three" : 3,
		"ball-four" : 4,
		"ball-five" : 5,
		"ball-six" : 6,
		"ball-seven" : 7,
		"ball-eight" : 8,
		"ball-nine" : 9,
		"ball-ten" : 10,
		"ball-eleven" : 11,
		"ball-twelve" : 12,
		"ball-thirteen" : 13,
		"ball-fourteen" : 14,
		"ball-fifteen" : 15
	};

	var num = idToBall[id];

	$.ajax({
		type: "POST",
		url: "/api/game/toggleball",
		data: JSON.stringify({ball: num}),
		success: function() {
			console.log("Successful POST: ball #" + num);
		}
	});
}

function on_click_ball(ballsInPlay) {
	$('div.poolball').click(function() {
		var id = $(this).attr('id');
		if(ballsInPlay[id]) {
			$(this).fadeTo(700, 0.3);
			ballsInPlay[id] = false;
			toggle_ball(id);
		}
		else {
			$(this).fadeTo(700, 1);
			ballsInPlay[id] = true;
			toggle_ball(id);
		}
	});
}

function load_players() {
	$.ajax({
		url: "/api/game/listplayers",
		success: function(data) {
			$("#game_list").empty();
			$("#game_list").append('

');

			var firstItem = true;
            $.each(data["data"]["players"], function(key, value) {

            	if(firstItem) {
        			$("ul#playerlist").append('
' + value + '
');
            		firstItem = false;
            	}
            	else {
            		$("ul#playerlist").append('
' + value + '
');
            	}
            });
		}
	});
}

function leave_game() {
	$('#leavegamebutton').click(function() {
		$.ajax({
			url: "/api/game/leavegame",
			type: "DELETE",
			success: function() {
				window.location.href = "/room/join";
			}
		});
	});
}

$(document).ready(function() {
	var ballsInPlay = load_balls();
	on_click_ball(ballsInPlay);
	load_players(); 	// TODO: fix player list layout
	leave_game();
});
<commit_msg>updated game.js to use new /api/game/gamestate endpoint<commit_after>function load_balls() {
	var ballsInPlay = {
		"placeholder" : false,
		"ball-one" : false,
		"ball-two" : false,
		"ball-three" : false,
		"ball-four" : false,
		"ball-five" : false,
		"ball-six" : false,
		"ball-seven" : false,
		"ball-eight" : false,
		"ball-nine" : false,
		"ball-ten" : false,
		"ball-eleven" : false,
		"ball-twelve" : false,
		"ball-thirteen" : false,
		"ball-fourteen" : false,
		"ball-fifteen" : false
	};

	var indexToId = [
		"placeholder",
		"ball-one",
		"ball-two",
		"ball-three",
		"ball-four",
		"ball-five",
		"ball-six",
		"ball-seven",
		"ball-eight",
		"ball-nine",
		"ball-ten",
		"ball-eleven",
		"ball-twelve",
		"ball-thirteen",
		"ball-fourteen",
		"ball-fifteen"
	];

	$.ajax({
        url: "/api/game/gamestate",
        success: function(data) {
            $.each(data["data"]["balls_on_table"], function(index, value) {
            	ballsInPlay[indexToId[value]] = true;
            });
	        $.each(ballsInPlay, function(index, value) {
		   		if(value) {
		   			$("#" + index).css("opacity", 1);
		   		}
		   		else {
		   			$("#" + index).css("opacity", 0.3);
		   		}
	   		});
    	}
	});

   setTimeout(load_balls, 5000);
   return ballsInPlay;
}

function toggle_ball(id) {
	var idToBall = {
		"ball-one" : 1,
		"ball-two" : 2,
		"ball-three" : 3,
		"ball-four" : 4,
		"ball-five" : 5,
		"ball-six" : 6,
		"ball-seven" : 7,
		"ball-eight" : 8,
		"ball-nine" : 9,
		"ball-ten" : 10,
		"ball-eleven" : 11,
		"ball-twelve" : 12,
		"ball-thirteen" : 13,
		"ball-fourteen" : 14,
		"ball-fifteen" : 15
	};

	var num = idToBall[id];

	$.ajax({
		type: "POST",
		url: "/api/game/toggleball",
		data: JSON.stringify({ball: num}),
		success: function() {
			console.log("Successful POST: ball #" + num);
		}
	});
}

function on_click_ball(ballsInPlay) {
	$('div.poolball').click(function() {
		var id = $(this).attr('id');
		if(ballsInPlay[id]) {
			$(this).fadeTo(700, 0.3);
			ballsInPlay[id] = false;
			toggle_ball(id);
		}
		else {
			$(this).fadeTo(700, 1);
			ballsInPlay[id] = true;
			toggle_ball(id);
		}
	});
}

function load_players() {
	$.ajax({
		url: "/api/game/listplayers",
		success: function(data) {
			$("#game_list").empty();
			$("#game_list").append('

');

			var firstItem = true;
            $.each(data["data"]["players"], function(key, value) {

            	if(firstItem) {
        			$("ul#playerlist").append('
' + value + '
');
            		firstItem = false;
            	}
            	else {
            		$("ul#playerlist").append('
' + value + '
');
            	}
            });
		}
	});
}

function leave_game() {
	$('#leavegamebutton').click(function() {
		$.ajax({
			url: "/api/game/leavegame",
			type: "DELETE",
			success: function() {
				window.location.href = "/room/join";
			}
		});
	});
}

$(document).ready(function() {
	var ballsInPlay = load_balls();
	on_click_ball(ballsInPlay);
	load_players(); 	// TODO: fix player list layout
	leave_game();
});
<|endoftext|>


<commit_before>'use strict';

var Axes = require('../cartesian/axes');

var str2RGBArray = require('../../lib/str2rgbarray');

function Axes2DOptions(scene) {
    this.scene = scene;
    this.gl = scene.gl;
    this.pixelRatio = scene.pixelRatio;

    this.screenBox = [0, 0, 1, 1];
    this.viewBox = [0, 0, 1, 1];
    this.dataBox = [-1, -1, 1, 1];

    this.borderLineEnable = [false, false, false, false];
    this.borderLineWidth = [1, 1, 1, 1];
    this.borderLineColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.ticks = [[], []];
    this.tickEnable = [true, true, false, false];
    this.tickPad = [15, 15, 15, 15];
    this.tickAngle = [0, 0, 0, 0];
    this.tickColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];
    this.tickMarkLength = [0, 0, 0, 0];
    this.tickMarkWidth = [0, 0, 0, 0];
    this.tickMarkColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.labels = ['x', 'y'];
    this.labelEnable = [true, true, false, false];
    this.labelAngle = [0, Math.PI / 2, 0, 3.0 * Math.PI / 2];
    this.labelPad = [15, 15, 15, 15];
    this.labelSize = [12, 12];
    this.labelFont = ['sans-serif', 'sans-serif'];
    this.labelColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.title = '';
    this.titleEnable = true;
    this.titleCenter = [0, 0, 0, 0];
    this.titleAngle = 0;
    this.titleColor = [0, 0, 0, 1];
    this.titleFont = 'sans-serif';
    this.titleSize = 18;

    this.gridLineEnable = [true, true];
    this.gridLineColor = [
        [0, 0, 0, 0.5],
        [0, 0, 0, 0.5]
    ];
    this.gridLineWidth = [1, 1];
    this.gridLineDash = ['', ''];

    this.zeroLineEnable = [true, true];
    this.zeroLineWidth = [1, 1];
    this.zeroLineColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.borderColor = [0, 0, 0, 0];
    this.backgroundColor = [0, 0, 0, 0];

    this.static = this.scene.staticPlot;
}

var proto = Axes2DOptions.prototype;

var AXES = ['xaxis', 'yaxis'];

proto.merge = function(options) {
    // titles are rendered in SVG
    this.titleEnable = false;
    this.backgroundColor = str2RGBArray(options.plot_bgcolor);

    var axisName, ax, axTitle, axMirror;
    var hasAxisInDfltPos, hasAxisInAltrPos, hasSharedAxis, mirrorLines, mirrorTicks;
    var i, j;

    for(i = 0; i < 2; ++i) {
        axisName = AXES[i];
        var axisLetter = axisName.charAt(0);

        // get options relevant to this subplot,
        // '_name' is e.g. xaxis, xaxis2, yaxis, yaxis4 ...
        ax = options[this.scene[axisName]._name];

        axTitle = ax.title.text === this.scene.fullLayout._dfltTitle[axisLetter] ? '' : ax.title.text;

        for(j = 0; j <= 2; j += 2) {
            this.labelEnable[i + j] = false;
            this.labels[i + j] = axTitle;
            this.labelColor[i + j] = str2RGBArray(ax.title.font.color);
            this.labelFont[i + j] = ax.title.font.family;
            this.labelSize[i + j] = ax.title.font.size;
            this.labelPad[i + j] = this.getLabelPad(axisName, ax);

            this.tickEnable[i + j] = false;
            this.tickColor[i + j] = str2RGBArray((ax.tickfont || {}).color);
            this.tickAngle[i + j] = (ax.tickangle === 'auto') ?
                0 :
                Math.PI * -ax.tickangle / 180;
            this.tickPad[i + j] = this.getTickPad(ax);

            this.tickMarkLength[i + j] = 0;
            this.tickMarkWidth[i + j] = ax.tickwidth || 0;
            this.tickMarkColor[i + j] = str2RGBArray(ax.tickcolor);

            this.borderLineEnable[i + j] = false;
            this.borderLineColor[i + j] = str2RGBArray(ax.linecolor);
            this.borderLineWidth[i + j] = ax.linewidth || 0;
        }

        hasSharedAxis = this.hasSharedAxis(ax);
        hasAxisInDfltPos = this.hasAxisInDfltPos(axisName, ax) && !hasSharedAxis;
        hasAxisInAltrPos = this.hasAxisInAltrPos(axisName, ax) && !hasSharedAxis;

        axMirror = ax.mirror || false;
        mirrorLines = hasSharedAxis ?
            (String(axMirror).indexOf('all') !== -1) :  // 'all' or 'allticks'
            !!axMirror;                                 // all but false
        mirrorTicks = hasSharedAxis ?
            (axMirror === 'allticks') :
            (String(axMirror).indexOf('ticks') !== -1); // 'ticks' or 'allticks'

        // Axis titles and tick labels can only appear of one side of the scene
        //  and are never show on subplots that share existing axes.

        if(hasAxisInDfltPos) this.labelEnable[i] = true;
        else if(hasAxisInAltrPos) this.labelEnable[i + 2] = true;

        if(hasAxisInDfltPos) this.tickEnable[i] = ax.showticklabels;
        else if(hasAxisInAltrPos) this.tickEnable[i + 2] = ax.showticklabels;

        // Grid lines and ticks can appear on both sides of the scene
        //  and can appear on subplot that share existing axes via `ax.mirror`.

        if(hasAxisInDfltPos || mirrorLines) this.borderLineEnable[i] = ax.showline;
        if(hasAxisInAltrPos || mirrorLines) this.borderLineEnable[i + 2] = ax.showline;

        if(hasAxisInDfltPos || mirrorTicks) this.tickMarkLength[i] = this.getTickMarkLength(ax);
        if(hasAxisInAltrPos || mirrorTicks) this.tickMarkLength[i + 2] = this.getTickMarkLength(ax);

        this.gridLineEnable[i] = ax.showgrid;
        this.gridLineColor[i] = str2RGBArray(ax.gridcolor);
        this.gridLineWidth[i] = ax.gridwidth;
        this.gridLineDash[i] = ax.griddash;

        this.zeroLineEnable[i] = ax.zeroline;
        this.zeroLineColor[i] = str2RGBArray(ax.zerolinecolor);
        this.zeroLineWidth[i] = ax.zerolinewidth;
    }
};

// is an axis shared with an already-drawn subplot ?
proto.hasSharedAxis = function(ax) {
    var scene = this.scene;
    var subplotIds = scene.fullLayout._subplots.gl2d;
    var list = Axes.findSubplotsWithAxis(subplotIds, ax);

    // if index === 0, then the subplot is already drawn as subplots
    // are drawn in order.
    return (list.indexOf(scene.id) !== 0);
};

// has an axis in default position (i.e. bottom/left) ?
proto.hasAxisInDfltPos = function(axisName, ax) {
    var axSide = ax.side;

    if(axisName === 'xaxis') return (axSide === 'bottom');
    else if(axisName === 'yaxis') return (axSide === 'left');
};

// has an axis in alternate position (i.e. top/right) ?
proto.hasAxisInAltrPos = function(axisName, ax) {
    var axSide = ax.side;

    if(axisName === 'xaxis') return (axSide === 'top');
    else if(axisName === 'yaxis') return (axSide === 'right');
};

proto.getLabelPad = function(axisName, ax) {
    var offsetBase = 1.5;
    var fontSize = ax.title.font.size;
    var showticklabels = ax.showticklabels;

    if(axisName === 'xaxis') {
        return (ax.side === 'top') ?
            -10 + fontSize * (offsetBase + (showticklabels ? 1 : 0)) :
            -10 + fontSize * (offsetBase + (showticklabels ? 0.5 : 0));
    } else if(axisName === 'yaxis') {
        return (ax.side === 'right') ?
            10 + fontSize * (offsetBase + (showticklabels ? 1 : 0.5)) :
            10 + fontSize * (offsetBase + (showticklabels ? 0.5 : 0));
    }
};

proto.getTickPad = function(ax) {
    return (ax.ticks === 'outside') ? 10 + ax.ticklen : 15;
};

proto.getTickMarkLength = function(ax) {
    if(!ax.ticks) return 0;

    var ticklen = ax.ticklen;

    return (ax.ticks === 'inside') ? -ticklen : ticklen;
};

function createAxes2D(scene) {
    return new Axes2DOptions(scene);
}

module.exports = createAxes2D;
<commit_msg>no gl2d<commit_after>'use strict';

var Axes = require('../cartesian/axes');

var str2RGBArray = require('../../lib/str2rgbarray');

function Axes2DOptions(scene) {
    this.scene = scene;
    this.gl = scene.gl;
    this.pixelRatio = scene.pixelRatio;

    this.screenBox = [0, 0, 1, 1];
    this.viewBox = [0, 0, 1, 1];
    this.dataBox = [-1, -1, 1, 1];

    this.borderLineEnable = [false, false, false, false];
    this.borderLineWidth = [1, 1, 1, 1];
    this.borderLineColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.ticks = [[], []];
    this.tickEnable = [true, true, false, false];
    this.tickPad = [15, 15, 15, 15];
    this.tickAngle = [0, 0, 0, 0];
    this.tickColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];
    this.tickMarkLength = [0, 0, 0, 0];
    this.tickMarkWidth = [0, 0, 0, 0];
    this.tickMarkColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.labels = ['x', 'y'];
    this.labelEnable = [true, true, false, false];
    this.labelAngle = [0, Math.PI / 2, 0, 3.0 * Math.PI / 2];
    this.labelPad = [15, 15, 15, 15];
    this.labelSize = [12, 12];
    this.labelFont = ['sans-serif', 'sans-serif'];
    this.labelColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.title = '';
    this.titleEnable = true;
    this.titleCenter = [0, 0, 0, 0];
    this.titleAngle = 0;
    this.titleColor = [0, 0, 0, 1];
    this.titleFont = 'sans-serif';
    this.titleSize = 18;

    this.gridLineEnable = [true, true];
    this.gridLineColor = [
        [0, 0, 0, 0.5],
        [0, 0, 0, 0.5]
    ];
    this.gridLineWidth = [1, 1];

    this.zeroLineEnable = [true, true];
    this.zeroLineWidth = [1, 1];
    this.zeroLineColor = [
        [0, 0, 0, 1],
        [0, 0, 0, 1]
    ];

    this.borderColor = [0, 0, 0, 0];
    this.backgroundColor = [0, 0, 0, 0];

    this.static = this.scene.staticPlot;
}

var proto = Axes2DOptions.prototype;

var AXES = ['xaxis', 'yaxis'];

proto.merge = function(options) {
    // titles are rendered in SVG
    this.titleEnable = false;
    this.backgroundColor = str2RGBArray(options.plot_bgcolor);

    var axisName, ax, axTitle, axMirror;
    var hasAxisInDfltPos, hasAxisInAltrPos, hasSharedAxis, mirrorLines, mirrorTicks;
    var i, j;

    for(i = 0; i < 2; ++i) {
        axisName = AXES[i];
        var axisLetter = axisName.charAt(0);

        // get options relevant to this subplot,
        // '_name' is e.g. xaxis, xaxis2, yaxis, yaxis4 ...
        ax = options[this.scene[axisName]._name];

        axTitle = ax.title.text === this.scene.fullLayout._dfltTitle[axisLetter] ? '' : ax.title.text;

        for(j = 0; j <= 2; j += 2) {
            this.labelEnable[i + j] = false;
            this.labels[i + j] = axTitle;
            this.labelColor[i + j] = str2RGBArray(ax.title.font.color);
            this.labelFont[i + j] = ax.title.font.family;
            this.labelSize[i + j] = ax.title.font.size;
            this.labelPad[i + j] = this.getLabelPad(axisName, ax);

            this.tickEnable[i + j] = false;
            this.tickColor[i + j] = str2RGBArray((ax.tickfont || {}).color);
            this.tickAngle[i + j] = (ax.tickangle === 'auto') ?
                0 :
                Math.PI * -ax.tickangle / 180;
            this.tickPad[i + j] = this.getTickPad(ax);

            this.tickMarkLength[i + j] = 0;
            this.tickMarkWidth[i + j] = ax.tickwidth || 0;
            this.tickMarkColor[i + j] = str2RGBArray(ax.tickcolor);

            this.borderLineEnable[i + j] = false;
            this.borderLineColor[i + j] = str2RGBArray(ax.linecolor);
            this.borderLineWidth[i + j] = ax.linewidth || 0;
        }

        hasSharedAxis = this.hasSharedAxis(ax);
        hasAxisInDfltPos = this.hasAxisInDfltPos(axisName, ax) && !hasSharedAxis;
        hasAxisInAltrPos = this.hasAxisInAltrPos(axisName, ax) && !hasSharedAxis;

        axMirror = ax.mirror || false;
        mirrorLines = hasSharedAxis ?
            (String(axMirror).indexOf('all') !== -1) :  // 'all' or 'allticks'
            !!axMirror;                                 // all but false
        mirrorTicks = hasSharedAxis ?
            (axMirror === 'allticks') :
            (String(axMirror).indexOf('ticks') !== -1); // 'ticks' or 'allticks'

        // Axis titles and tick labels can only appear of one side of the scene
        //  and are never show on subplots that share existing axes.

        if(hasAxisInDfltPos) this.labelEnable[i] = true;
        else if(hasAxisInAltrPos) this.labelEnable[i + 2] = true;

        if(hasAxisInDfltPos) this.tickEnable[i] = ax.showticklabels;
        else if(hasAxisInAltrPos) this.tickEnable[i + 2] = ax.showticklabels;

        // Grid lines and ticks can appear on both sides of the scene
        //  and can appear on subplot that share existing axes via `ax.mirror`.

        if(hasAxisInDfltPos || mirrorLines) this.borderLineEnable[i] = ax.showline;
        if(hasAxisInAltrPos || mirrorLines) this.borderLineEnable[i + 2] = ax.showline;

        if(hasAxisInDfltPos || mirrorTicks) this.tickMarkLength[i] = this.getTickMarkLength(ax);
        if(hasAxisInAltrPos || mirrorTicks) this.tickMarkLength[i + 2] = this.getTickMarkLength(ax);

        this.gridLineEnable[i] = ax.showgrid;
        this.gridLineColor[i] = str2RGBArray(ax.gridcolor);
        this.gridLineWidth[i] = ax.gridwidth;
        this.gridLineDash[i] = ax.griddash;

        this.zeroLineEnable[i] = ax.zeroline;
        this.zeroLineColor[i] = str2RGBArray(ax.zerolinecolor);
        this.zeroLineWidth[i] = ax.zerolinewidth;
    }
};

// is an axis shared with an already-drawn subplot ?
proto.hasSharedAxis = function(ax) {
    var scene = this.scene;
    var subplotIds = scene.fullLayout._subplots.gl2d;
    var list = Axes.findSubplotsWithAxis(subplotIds, ax);

    // if index === 0, then the subplot is already drawn as subplots
    // are drawn in order.
    return (list.indexOf(scene.id) !== 0);
};

// has an axis in default position (i.e. bottom/left) ?
proto.hasAxisInDfltPos = function(axisName, ax) {
    var axSide = ax.side;

    if(axisName === 'xaxis') return (axSide === 'bottom');
    else if(axisName === 'yaxis') return (axSide === 'left');
};

// has an axis in alternate position (i.e. top/right) ?
proto.hasAxisInAltrPos = function(axisName, ax) {
    var axSide = ax.side;

    if(axisName === 'xaxis') return (axSide === 'top');
    else if(axisName === 'yaxis') return (axSide === 'right');
};

proto.getLabelPad = function(axisName, ax) {
    var offsetBase = 1.5;
    var fontSize = ax.title.font.size;
    var showticklabels = ax.showticklabels;

    if(axisName === 'xaxis') {
        return (ax.side === 'top') ?
            -10 + fontSize * (offsetBase + (showticklabels ? 1 : 0)) :
            -10 + fontSize * (offsetBase + (showticklabels ? 0.5 : 0));
    } else if(axisName === 'yaxis') {
        return (ax.side === 'right') ?
            10 + fontSize * (offsetBase + (showticklabels ? 1 : 0.5)) :
            10 + fontSize * (offsetBase + (showticklabels ? 0.5 : 0));
    }
};

proto.getTickPad = function(ax) {
    return (ax.ticks === 'outside') ? 10 + ax.ticklen : 15;
};

proto.getTickMarkLength = function(ax) {
    if(!ax.ticks) return 0;

    var ticklen = ax.ticklen;

    return (ax.ticks === 'inside') ? -ticklen : ticklen;
};

function createAxes2D(scene) {
    return new Axes2DOptions(scene);
}

module.exports = createAxes2D;
<|endoftext|>


<commit_before>module.exports = function (context, message) {

    var id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });

    context.bindings.out = {
        id: id,
        raw: message
    };

    context.done();
};<commit_msg>closer to API<commit_after>module.exports = function (context, message) {

    var id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });

    var content = {
        id: message.tweetid,
        social_site: "Twitter",
        content: message.tweettext
    };

    var data = {
        id: id,
        registered_account_id: message.userid,
        is_archived: false,
        archived_by: 1,
        last_update: "10/10/2016",
        created_date: "10/10/2016",
        log: 41.94000,
        lat: -115.00002,
        profilepic: message.profileimageurl,
        photos: [],
        social_content: [content]
    };

    context.bindings.out = data;

    context.done();
};<|endoftext|>


<commit_before>
import { observable, computed, toJS } from 'mobx';

// TODO
import fakeFetch from 'utils/fakeFetch';

class DataStore {
	@observable total = 0;
	@observable isFetching = false;
	@observable page = 1;

	@computed get dataSource() {
		return toJS(this.collections.get(this.page));
	}

	collections = observable.map();

	size = 20;

	constructor(schema) {
		this._schema = schema;
		this.columns = schema.map(({ title, key, render }) => ({
			title,
			key,
			render,
			dataIndex: key,
		}));
	}

	async fetch(query = {}) {
		const page = (function () {
			const p = query.page || 1;
			return p < 1 ? 1 : p;
		}());

		if (this.collections.has(page)) { return this; }

		this.isFetching = true;

		const { total, list } = await fakeFetch({
			count: this.size,
			page,
		});

		// console.log('list', list);

		const collection = list.map((data, index) => {

			// TODO: should depend on `schema.unique`
			data.key = data.key || index;

			return data;
		});

		this.page = page;
		this.isFetching = false;
		this.total = total;
		this.collections.set(page, collection);
		return this;
	}
}

const caches = new WeakMap();

export default function getDataStore(schema) {
	if (caches.has(schema)) { return caches.get(schema); }

	const store = new DataStore(schema);
	caches.set(schema, store);
	return store;
}
<commit_msg>fix Data bug<commit_after>
import { observable, computed, toJS } from 'mobx';

// TODO
import fakeFetch from 'utils/fakeFetch';

class DataStore {
	@observable total = 0;
	@observable isFetching = false;
	@observable page = 1;

	@computed get dataSource() {
		return toJS(this.collections.get(this.page));
	}

	collections = observable.map();

	size = 20;

	constructor(schema) {
		this._schema = schema;
		this.columns = schema.map(({ title, key, render }) => ({
			title,
			key,
			render,
			dataIndex: key,
		}));
	}

	async fetch(query = {}) {
		const page = (function () {
			const p = query.page || 1;
			return p < 1 ? 1 : p;
		}());

		if (this.collections.has(page)) {
			this.page = page;
			return this;
		}

		this.isFetching = true;

		const { total, list } = await fakeFetch({
			count: this.size,
			page,
		});

		// console.log('list', list);

		const collection = list.map((data, index) => {

			// TODO: should depend on `schema.unique`
			data.key = data.key || index;

			return data;
		});

		this.page = page;
		this.isFetching = false;
		this.total = total;
		this.collections.set(page, collection);
		return this;
	}
}

const caches = new WeakMap();

export default function getDataStore(schema) {
	if (caches.has(schema)) { return caches.get(schema); }

	const store = new DataStore(schema);
	caches.set(schema, store);
	return store;
}
<|endoftext|>


<commit_before>import colors from './colors';
import darken from '../internal/darken';

const styleSheet = {
  list: {
    background: colors.white,
    boxSizing: 'border-box',
    margin: '0',
    paddingLeft: '0',
  },
  listItem: {
    backgroundColor: colors.white,
    boxSizing: 'border-box',
    borderBottom: `1px solid ${colors.white}`,
    cursor: 'pointer',
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    height: '54px',
    listStyle: 'none',
    padding: '10px',
    position: 'relative',
    transition: 'background-color .3s ease-in-out',
    '&:first-of-type': {
      borderTop: `1px solid ${colors.white}`
    },
    '&:hover': {
      backgroundColor: darken(colors.white, 0.05)
    },
    '&:active': {
      backgroundColor: darken(colors.white, 0.15)
    }
  },
  active: {
    backgroundColor: colors.theme,
    color: colors.white,
    '&:hover': {
      backgroundColor: darken(colors.theme, 0.05)
    },
    '&:active': {
      backgroundColor: darken(colors.theme, 0.15)
    },
    '& $primaryText': {
      color: colors.white
    },
    '& $secondaryText': {
      color: colors.white
    }
  },
  rightButton: {
    paddingRight: '52px'
  },
  button: {
    position: 'absolute',
    right: '6px',
    top: '6px'
  },
  primaryText: {
    color: colors.primaryText,
    fontSize: '16px',
    margin: 0,
    lineHeight: '16px'
  },
  secondaryText: {
    color: colors.secondaryText,
    fontSize: '14px',
    fontWeight: 'normal',
    margin: 0,
    marginTop: '2.4px',
    lineHeight: '14px'
  },
  leftAvatar: {
    paddingLeft: '56px'
  },
  avatar: {
    position: 'absolute',
    left: '8px',
    top: '6px'
  }
};

export default styleSheet;
<commit_msg>:lipstick: Added user select<commit_after>import colors from './colors';
import darken from '../internal/darken';

const styleSheet = {
  list: {
    background: colors.white,
    boxSizing: 'border-box',
    margin: '0',
    paddingLeft: '0',
  },
  listItem: {
    backgroundColor: colors.white,
    boxSizing: 'border-box',
    borderBottom: `1px solid ${colors.white}`,
    cursor: 'pointer',
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    height: '54px',
    listStyle: 'none',
    padding: '10px',
    position: 'relative',
    transition: 'background-color .3s ease-in-out',
    '&:first-of-type': {
      borderTop: `1px solid ${colors.white}`
    },
    '&:hover': {
      backgroundColor: darken(colors.white, 0.05)
    },
    '&:active': {
      backgroundColor: darken(colors.white, 0.15)
    }
  },
  active: {
    backgroundColor: colors.theme,
    color: colors.white,
    '&:hover': {
      backgroundColor: darken(colors.theme, 0.05)
    },
    '&:active': {
      backgroundColor: darken(colors.theme, 0.15)
    },
    '& $primaryText': {
      color: colors.white
    },
    '& $secondaryText': {
      color: colors.white
    }
  },
  rightButton: {
    paddingRight: '52px'
  },
  button: {
    position: 'absolute',
    right: '6px',
    top: '6px'
  },
  primaryText: {
    color: colors.primaryText,
    fontSize: '16px',
    margin: 0,
    lineHeight: '16px',
    userSelect: 'none'
  },
  secondaryText: {
    color: colors.secondaryText,
    fontSize: '14px',
    fontWeight: 'normal',
    margin: 0,
    marginTop: '2.4px',
    lineHeight: '14px',
    userSelect: 'none'
  },
  leftAvatar: {
    paddingLeft: '56px'
  },
  avatar: {
    position: 'absolute',
    left: '8px',
    top: '6px'
  }
};

export default styleSheet;
<|endoftext|>


<commit_before>'use strict';

var extend = require('xtend');
var fuzzy = require('fuzzy');
var List = require('./list');

var Suggestions = function(el, data, options) {
  options = options || {};

  this.options = extend({
    minLength: 2,
    limit: 5,
    filter: true
  }, options);

  this.el = el;
  this.data = data || [];
  this.list = new List(this);

  this.query = '';
  this.selected = null;

  this.list.draw();

  this.el.addEventListener('keyup', function(e) {
    this.handleKeyUp(e.keyCode);
  }.bind(this), false);

  this.el.addEventListener('keydown', function(e) {
    this.handleKeyDown(e);
  }.bind(this));

  this.el.addEventListener('focus', function() {
    this.handleFocus();
  }.bind(this));

  this.el.addEventListener('blur', function() {
    this.handleBlur();
  }.bind(this));

  return this;
};

Suggestions.prototype.handleKeyUp = function(keyCode) {
  // 40 - DOWN
  // 38 - UP
  // 27 - ESC
  // 13 - ENTER
  // 9 - TAB

  if (keyCode === 40 ||
      keyCode === 38 ||
      keyCode === 27 ||
      keyCode === 13 ||
      keyCode === 9) return;

  this.query = this.normalize(this.el.value);

  this.list.clear();

  if (this.query.length < this.options.minLength) {
    this.list.draw();
    return;
  }

  this.getCandidates(function(data) {
    for (var i = 0; i < data.length; i++) {
      this.list.add(data[i]);
      if (i === (this.options.limit - 1)) break;
    }
    this.list.draw();
  }.bind(this));
};

Suggestions.prototype.handleKeyDown = function(e) {
  switch (e.keyCode) {
    case 13: // ENTER
    case 9:  // TAB
      e.preventDefault();
      if (!this.list.isEmpty()) {
        this.value(this.list.items[this.list.active].original);
        this.list.hide();
      }
    break;
    case 27: // ESC
      if (!this.list.isEmpty()) this.list.hide();
    break;
    case 38: // UP
      this.list.previous();
    break;
    case 40: // DOWN
      this.list.next();
    break;
  }
};

Suggestions.prototype.handleBlur = function() {
  this.list.hide();
};

Suggestions.prototype.handleFocus = function() {
  if (!this.list.isEmpty()) this.list.show();
};

/**
 * Update data previously passed
 *
 * @param {Array} revisedData
 */
Suggestions.prototype.update = function(revisedData) {
  this.data = revisedData;
  this.handleKeyUp();
};

/**
 * Clears data
 */
Suggestions.prototype.clear = function() {
  this.data = [];
  this.list.clear();
};

/**
 * Normalize the results list and input value for matching
 *
 * @param {String} value
 * @return {String}
 */
Suggestions.prototype.normalize = function(value) {
  value = value.toLowerCase();
  return value;
};

/**
 * Evaluates whether an array item qualifies as a match with the current query
 *
 * @param {String} candidate a possible item from the array passed
 * @param {String} query the current query
 * @return {Boolean}
 */
Suggestions.prototype.match = function(candidate, query) {
  return candidate.indexOf(query) > -1;
};

Suggestions.prototype.value = function(value) {
  this.selected = value;
  this.el.value = this.getItemValue(value);

  if (document.createEvent) {
    var e = document.createEvent('HTMLEvents');
    e.initEvent('change', true, false);
    this.el.dispatchEvent(e);
  } else {
    this.el.fireEvent('onchange');
  }
};

Suggestions.prototype.getCandidates = function(callback) {
  var options = {
    pre: '',
    post: '',
    extract: function(d) { return this.getItemValue(d); }.bind(this)
  };

  var results = this.options.filter ?
    fuzzy.filter(this.query, this.data, options) :
    this.data.map(function(d) {
      return {
        original: d,
        string: this.getItemValue(d).replace(new RegExp('(' + this.query + ')', 'ig'), function($1, match) {
          return '' + match + '';
        })
      };
    }.bind(this));

  callback(results);
};

/**
 * For a given item in the data array, return what should be used as the candidate string
 *
 * @param {Object|String} item an item from the data array
 * @return {String} item
 */
Suggestions.prototype.getItemValue = function(item) {
  return item;
};

module.exports = Suggestions;
<commit_msg>ensure right click paste opens suggestions list (#17)<commit_after>'use strict';

var extend = require('xtend');
var fuzzy = require('fuzzy');
var List = require('./list');

var Suggestions = function(el, data, options) {
  options = options || {};

  this.options = extend({
    minLength: 2,
    limit: 5,
    filter: true
  }, options);

  this.el = el;
  this.data = data || [];
  this.list = new List(this);

  this.query = '';
  this.selected = null;

  this.list.draw();

  this.el.addEventListener('keyup', function(e) {
    this.handleKeyUp(e.keyCode);
  }.bind(this), false);

  this.el.addEventListener('keydown', function(e) {
    this.handleKeyDown(e);
  }.bind(this));

  this.el.addEventListener('focus', function() {
    this.handleFocus();
  }.bind(this));

  this.el.addEventListener('blur', function() {
    this.handleBlur();
  }.bind(this));

  this.el.addEventListener('paste', function(e) {
    this.handlePaste(e);
  }.bind(this));

  return this;
};

Suggestions.prototype.handleKeyUp = function(keyCode) {
  // 40 - DOWN
  // 38 - UP
  // 27 - ESC
  // 13 - ENTER
  // 9 - TAB

  if (keyCode === 40 ||
      keyCode === 38 ||
      keyCode === 27 ||
      keyCode === 13 ||
      keyCode === 9) return;

  this.handleInputChange(this.el.value);
};

Suggestions.prototype.handleKeyDown = function(e) {
  switch (e.keyCode) {
    case 13: // ENTER
    case 9:  // TAB
      e.preventDefault();
      if (!this.list.isEmpty()) {
        this.value(this.list.items[this.list.active].original);
        this.list.hide();
      }
    break;
    case 27: // ESC
      if (!this.list.isEmpty()) this.list.hide();
    break;
    case 38: // UP
      this.list.previous();
    break;
    case 40: // DOWN
      this.list.next();
    break;
  }
};

Suggestions.prototype.handleBlur = function() {
  this.list.hide();
};

Suggestions.prototype.handlePaste = function(e) {
  if (e.clipboardData) {
    this.handleInputChange(e.clipboardData.getData('Text'));
  } else {
    var self = this;
    setTimeout(function () {
      self.handleInputChange(e.target.value);
    }, 100);
  }
};

Suggestions.prototype.handleInputChange = function(query) {
  this.query = this.normalize(query);

  this.list.clear();

  if (this.query.length < this.options.minLength) {
    this.list.draw();
    return;
  }

  this.getCandidates(function(data) {
    for (var i = 0; i < data.length; i++) {
      this.list.add(data[i]);
      if (i === (this.options.limit - 1)) break;
    }
    this.list.draw();
  }.bind(this));
};

Suggestions.prototype.handleFocus = function() {
  if (!this.list.isEmpty()) this.list.show();
};

/**
 * Update data previously passed
 *
 * @param {Array} revisedData
 */
Suggestions.prototype.update = function(revisedData) {
  this.data = revisedData;
  this.handleKeyUp();
};

/**
 * Clears data
 */
Suggestions.prototype.clear = function() {
  this.data = [];
  this.list.clear();
};

/**
 * Normalize the results list and input value for matching
 *
 * @param {String} value
 * @return {String}
 */
Suggestions.prototype.normalize = function(value) {
  value = value.toLowerCase();
  return value;
};

/**
 * Evaluates whether an array item qualifies as a match with the current query
 *
 * @param {String} candidate a possible item from the array passed
 * @param {String} query the current query
 * @return {Boolean}
 */
Suggestions.prototype.match = function(candidate, query) {
  return candidate.indexOf(query) > -1;
};

Suggestions.prototype.value = function(value) {
  this.selected = value;
  this.el.value = this.getItemValue(value);

  if (document.createEvent) {
    var e = document.createEvent('HTMLEvents');
    e.initEvent('change', true, false);
    this.el.dispatchEvent(e);
  } else {
    this.el.fireEvent('onchange');
  }
};

Suggestions.prototype.getCandidates = function(callback) {
  var options = {
    pre: '',
    post: '',
    extract: function(d) { return this.getItemValue(d); }.bind(this)
  };

  var results = this.options.filter ?
    fuzzy.filter(this.query, this.data, options) :
    this.data.map(function(d) {
      return {
        original: d,
        string: this.getItemValue(d).replace(new RegExp('(' + this.query + ')', 'ig'), function($1, match) {
          return '' + match + '';
        })
      };
    }.bind(this));

  callback(results);
};

/**
 * For a given item in the data array, return what should be used as the candidate string
 *
 * @param {Object|String} item an item from the data array
 * @return {String} item
 */
Suggestions.prototype.getItemValue = function(item) {
  return item;
};

module.exports = Suggestions;
<|endoftext|>


<commit_before>SVG.MText = SVG.invent({
  create: function() {
    this.constructor.call(this, SVG.create('text'));
    this.dom.lineHeight = new SVG.Number(1.2);
    this.attr('font-family', SVG.defaults.attrs['font-family']);
    this.data('text-width', 200);

    var defaultSize = SVG.defaults.attrs['font-size'] ? SVG.defaults.attrs['font-size'] : '12px';
    this.attr('font-size', defaultSize);
    this.attr('multiline', true);
  },

  inherit: SVG.Shape,

  extend: {
    width: function(value) {
      if (typeof value === 'undefined') { return this.data('text-width'); }
      this.data('text-width', value);
      this.breakLines(this.width());
      return this;
    },

    align: function(value) {
      if (typeof value === 'undefined') { return this.attr('text-anchor'); }
      this.attr('text-anchor', value);
      this.adjustLines();
      return this;
    },

    clear: function() {
      while (this.node.hasChildNodes())
        this.node.removeChild(this.node.lastChild);

      return this;
    },

    text: function(text) {
      if (typeof text === 'undefined') {
        var t = "";
        this.lines().each(function() {
          t += this.node.textContent + "\n";
        });

        return t;
      }

      this.clear();

      var lines = text.split('\n');
      for (var i = 0, il = lines.length; i < il; i++)
        this.line(lines[i]);

      return this;
    },

    /**
     * Starts new text line. Creates new tspan marked as "newline"
     * @param  {String|Function} text
     * @return {SVG.Tspan}       tspan line instance
     */
    line: function(text) {
      var span = new SVG.Tspan();
      span.attr('newline', true);
      this.node.appendChild(span.node);

      if (typeof text === 'function') {
        text.call(this, span);
      } else if (typeof text !== 'undefined' && text.length > 0) {
        span.tspan(text);
      }

      this.breakLine(span, this.width());
      this.adjustLines();
      this.trimLines();

      return span;
    },

    trimLines: function() {
      this.lines().each(function() {
        var f = this.node.firstChild;
        if (f) {
          f.innerHTML = f.innerHTML.replace(/^\s+/, "");
        }

        var l = this.node.lastElementChild;
        if (l) {
          l.innerHTML = l.innerHTML.replace(/\s+$/, "");
        }
      });
    },

    adjustLines: function() {
      var lastDy = 0;
      var lastMargin = 0;
      var _self = this;
      var x = this.attr('x');
      if (this.attr('text-anchor') == 'middle')
        x = this.attr('x') + this.width()/2;
      else if(this.attr('text-anchor') == 'end')
        x = this.attr('x') + this.width();

      this.lines().each(function() {
        var fSize = _self.getBiggestFont(this);
        var marginBottom = (fSize * _self.dom.lineHeight - fSize)/2;
        var dy = lastMargin*2 + fSize;

        // console.log("Font size: %d, margin: %d", fSize, marginBottom);

        this.attr('dy', dy);
        this.attr('x', x);

        lastDy = dy;
        lastMargin = marginBottom;
      });
    },

    breakLines: function(width) {
      var _self = this;
      this.connectBrokenLines();
      this.lines().each(function() {
        _self.breakLine(this, width);
      });
      this.adjustLines();
      this.trimLines();
    },

    /**
     * Breaks given text line (wraps words)
     * Also wraps plain text into (tspan tags)
     * and removes everything else (@todo rethink this)
     *
     * @throws Exception if line node is not a SVGTSpanElement
     *
     * @param  {SVG.Tspan} line
     * @param  {Number}    width wrap length
     * @return {void}
     */
    breakLine: function(line, width) {
      if (!(line.node instanceof SVGTSpanElement)) {
        throw Exception('Given line is not SVG Tspan element!');
      }

      this.wrapPlainText(line);

      var lineLen = line.node.getComputedTextLength();
      if (lineLen <= width) { return; }

      // console.log("---- Starting breaking: %d > %d (width) ----", lineLen, width);

      var childs = line.node.childNodes;
      var tmpLen = 0;
      var watchdog = 0;
      var breakSpanIndex = -1;

      for (var i = 0; i < childs.length; i++) {

        watchdog++;
        if (watchdog > 100) {
          throw Exception('Watchdog limit reached! Something is wrong with break line "for" loop!');
        }

        var n = childs[i];
        if (n.nodeName !== 'tspan') { n.remove(); continue; } // @todo rethink

        tmpLen = tmpLen + n.getComputedTextLength();
        // console.log("Iterating %d from %d, checking if len: %d < %d", i+1, childs.length, tmpLen, width);
        if (tmpLen < width) { continue; }

        var span2 = this.breakSpanIntoTwo(n);
        if (span2 === null) {
          breakSpanIndex = (i < 1 && childs.length > 1) ? i+1 : i;
          break;
        }

        // reset loop
        childs = line.node.childNodes;
        i = -1;
        tmpLen = 0;
      }

      // if break index == 0 that means there is only one word in line and it cant be broken into smaller pieces!
      if (breakSpanIndex < 1) { return; }

      // console.log("Break on index %d which is: %s", breakSpanIndex, childs[breakSpanIndex].textContent);
      // create new line
      var newline = SVG.adopt(line.node.cloneNode());
      newline.data('connected-with-line', line.id());
      newline.id(SVG.eid(newline.node.nodeName));
      line.node.parentNode.insertBefore(newline.node, line.node);

      // put oter spans into new line
      var childsToMove = [];
      for (var y = 0; y < breakSpanIndex; y++) {
        childsToMove.push(childs[y]);
      }

      childsToMove.map(function(ch) { return newline.node.appendChild(ch); });

      // connect tspan in this line which can be connected
      // and recursive call same fun on new line
      this.connectBrokenWordsInLine(newline);
      this.breakLine(line, width);
      this.connectBrokenWordsInLine(line);
      this.adjustLines();

      // console.log("---- END breaking ----");
    },

    breakSpanIntoTwo: function(spanNode) {
      var parentNode = spanNode.parentNode;
      var words = spanNode.textContent.split(' ').filter(function (w){ return (w !== '' && w.length > 0); });

      // console.log(words);
      if (words.length < 2) {
        return null;
      }

      spanNode.innerHTML = "";
      // var span2 = childs[i].clone().node; @fixme: clone(). does not work on tspan elements (index() exactly)
      var span2 = spanNode.cloneNode(true);
      parentNode.insertBefore(span2, spanNode.nextSibling);
      SVG.adopt(span2).id(SVG.eid(span2.nodeName));
      SVG.adopt(span2).data('connect-prev', true);
      SVG.adopt(spanNode).data('connect-next', true);

      for (var j = 0; j < words.length; j++) {
        if (words[j] === '') { continue; }
        if (j+1 <= words.length/2 ) {
          spanNode.innerHTML = spanNode.innerHTML + words[j] + ' ';
        } else {
          span2.innerHTML = span2.innerHTML + words[j] + ' ';
        }
      }

      return span2;
    },

    /**
     * Connects spans created by breakSpanIntoTwo() method
     * Reduces unecessery tspans
     * @param  {SVG.Tspan} line
     * @return {void}
     */
    connectBrokenWordsInLine: function(line) {
      var childs = line.node.childNodes;
      for (var i = 0; i < childs.length; i++) {
        var span = SVG.adopt(childs[i]);
        var nextSpan = i < childs.length ? SVG.adopt(childs[i+1]) : null;
        if (span && span.data('connect-next') &&
            nextSpan && nextSpan.data('connect-prev')) {

          nextSpan.node.innerHTML = span.node.innerHTML + ' ' + nextSpan.node.innerHTML;
          span.node.remove();
          i--;
        }
      }
    },

    /**
     * Connects lines broken by word wrap method. Its required when we
     * want to changes width of textbox
     * @return {void}
     */
    connectBrokenLines: function() {
      var childs = this.node.childNodes;

      // reversed "for" loop
      for (var i = childs.length - 1; i >= 0; i--) {
        var span = SVG.adopt(childs[i]);
        if (!span || !span.data('connected-with-line')) { continue; }
        var targetSpan = SVG.get(span.data('connected-with-line'));
        if (!targetSpan) continue;

        targetSpan.node.innerHTML = span.node.innerHTML + ' ' + targetSpan.node.innerHTML;
        span.node.remove();
      }
    },

    /**
     * Wraps plain text into <tspan> tags
     * @param  {SVG.Tspan} tspanLine
     * @return {void}
     */
    wrapPlainText: function(tspanLine) {
      var childs = tspanLine.node.childNodes;
      if (!childs) { return; }

      for (var i = 0; i < childs.length; i++) {
        var n = childs[i];
        if (n.nodeName !== '#text') { continue; }
        var tmp = SVG.create('tspan');
        console.log('Text wprapped: ' + n.textContent);
        tmp.innerHTML = n.textContent;
        tspanLine.node.replaceChild(tmp, n);
      }
    },

    // search recursive through all child nodes and return biggest font size in px as number
    getBiggestFont: function(line) {
      var biggestFont = parseInt(getComputedStyle(line.node)['font-size']);
      var childs = SVG.utils.filterSVGElements(line.node.childNodes);

      for (var i = childs.length - 1; i >= 0; i--) {
        var f = this.getBiggestFont(SVG.adopt(childs[i]));
        biggestFont = f > biggestFont ? f : biggestFont;
      }

      return biggestFont;
    },

    lines: function() {
      // filter tspans and map them to SVG.js instances
      var lines = SVG.utils.map(SVG.utils.filterSVGElements(this.node.childNodes), function(el){
        return SVG.adopt(el);
      });

      // return an instance of SVG.set
      return new SVG.Set(lines);
    },

    lineHeight: function(value) {
      if (value === null) return this.dom.lineHeight;
      this.dom.lineHeight = new SVG.Number(value);
      this.adjustLines();
      return this;
    }
  },

  construct: {
    mtext: function() {
      return this.put(new SVG.MText());
    }
  }
});

SVG.extend(SVG.MText, {
  move: function(x, y) {
    return this.x(x).y(y);
  },

  x: function(x) {
    if (typeof x === 'undefined') return this.attr('x');
    this.attr('x', x);
    if (this.adjustLines) { this.adjustLines(); }
    return this;
  },

  y: function(y) {
    if (typeof y === 'undefined') return this.attr('y');
    this.attr('y', y);
    if (this.adjustLines) { this.adjustLines(); }
    return this;
  }
});

/**
 * Adopts SVG text element with multiline attr as
 * MText instance.
 * Normal <text> will not be adopted.
 *
 * @todo separate method to converts normal text to mtext
 *
 * @param {HTMLElement} node to adopt
 */
SVG.AdoptMText = function(node) {
  if (!node || node.nodeName != 'text') return null;

  // attr multiline means that <text> was mbox indeed
  if (!node.getAttribute("multiline")) return null;

  if (node.instance && node.instance instanceof SVG.MText) return node.instance;

  var element = new SVG.MText();

  element.type  = node.nodeName;
  element.node  = node;
  node.instance = element;

  console.log(element);

  element.setData(JSON.parse(node.getAttribute('svgjs:data')) || {});

  return element;
};
<commit_msg>bugfix in getBiggestFont<commit_after>SVG.MText = SVG.invent({
  create: function() {
    this.constructor.call(this, SVG.create('text'));
    this.dom.lineHeight = new SVG.Number(1.2);
    this.attr('font-family', SVG.defaults.attrs['font-family']);
    this.data('text-width', 200);

    var defaultSize = SVG.defaults.attrs['font-size'] ? SVG.defaults.attrs['font-size'] : '12px';
    this.attr('font-size', defaultSize);
    this.attr('multiline', true);
  },

  inherit: SVG.Shape,

  extend: {
    width: function(value) {
      if (typeof value === 'undefined') { return this.data('text-width'); }
      this.data('text-width', value);
      this.breakLines(this.width());
      return this;
    },

    align: function(value) {
      if (typeof value === 'undefined') { return this.attr('text-anchor'); }
      this.attr('text-anchor', value);
      this.adjustLines();
      return this;
    },

    clear: function() {
      while (this.node.hasChildNodes())
        this.node.removeChild(this.node.lastChild);

      return this;
    },

    text: function(text) {
      if (typeof text === 'undefined') {
        var t = "";
        this.lines().each(function() {
          t += this.node.textContent + "\n";
        });

        return t;
      }

      this.clear();

      var lines = text.split('\n');
      for (var i = 0, il = lines.length; i < il; i++)
        this.line(lines[i]);

      return this;
    },

    /**
     * Starts new text line. Creates new tspan marked as "newline"
     * @param  {String|Function} text
     * @return {SVG.Tspan}       tspan line instance
     */
    line: function(text) {
      var span = new SVG.Tspan();
      span.attr('newline', true);
      this.node.appendChild(span.node);

      if (typeof text === 'function') {
        text.call(this, span);
      } else if (typeof text !== 'undefined' && text.length > 0) {
        span.tspan(text);
      }

      this.breakLine(span, this.width());
      this.adjustLines();
      this.trimLines();

      return span;
    },

    trimLines: function() {
      this.lines().each(function() {
        var f = this.node.firstChild;
        if (f) {
          f.innerHTML = f.innerHTML.replace(/^\s+/, "");
        }

        var l = this.node.lastElementChild;
        if (l) {
          l.innerHTML = l.innerHTML.replace(/\s+$/, "");
        }
      });
    },

    adjustLines: function() {
      var lastDy = 0;
      var lastMargin = 0;
      var _self = this;
      var x = this.attr('x');
      if (this.attr('text-anchor') == 'middle')
        x = this.attr('x') + this.width()/2;
      else if(this.attr('text-anchor') == 'end')
        x = this.attr('x') + this.width();

      this.lines().each(function() {
        var fSize = _self.getBiggestFont(this);
        var marginBottom = (fSize * _self.dom.lineHeight - fSize)/2;
        var dy = lastMargin*2 + fSize;

        // console.log("Font size: %d, margin: %d", fSize, marginBottom);

        this.attr('dy', dy);
        this.attr('x', x);

        lastDy = dy;
        lastMargin = marginBottom;
      });
    },

    breakLines: function(width) {
      var _self = this;
      this.connectBrokenLines();
      this.lines().each(function() {
        _self.breakLine(this, width);
      });
      this.adjustLines();
      this.trimLines();
    },

    /**
     * Breaks given text line (wraps words)
     * Also wraps plain text into (tspan tags)
     * and removes everything else (@todo rethink this)
     *
     * @throws Exception if line node is not a SVGTSpanElement
     *
     * @param  {SVG.Tspan} line
     * @param  {Number}    width wrap length
     * @return {void}
     */
    breakLine: function(line, width) {
      if (!(line.node instanceof SVGTSpanElement)) {
        throw Exception('Given line is not SVG Tspan element!');
      }

      this.wrapPlainText(line);

      var lineLen = line.node.getComputedTextLength();
      if (lineLen <= width) { return; }

      // console.log("---- Starting breaking: %d > %d (width) ----", lineLen, width);

      var childs = line.node.childNodes;
      var tmpLen = 0;
      var watchdog = 0;
      var breakSpanIndex = -1;

      for (var i = 0; i < childs.length; i++) {

        watchdog++;
        if (watchdog > 100) {
          throw Exception('Watchdog limit reached! Something is wrong with break line "for" loop!');
        }

        var n = childs[i];
        if (n.nodeName !== 'tspan') { n.remove(); continue; } // @todo rethink

        tmpLen = tmpLen + n.getComputedTextLength();
        // console.log("Iterating %d from %d, checking if len: %d < %d", i+1, childs.length, tmpLen, width);
        if (tmpLen < width) { continue; }

        var span2 = this.breakSpanIntoTwo(n);
        if (span2 === null) {
          breakSpanIndex = (i < 1 && childs.length > 1) ? i+1 : i;
          break;
        }

        // reset loop
        childs = line.node.childNodes;
        i = -1;
        tmpLen = 0;
      }

      // if break index == 0 that means there is only one word in line and it cant be broken into smaller pieces!
      if (breakSpanIndex < 1) { return; }

      // console.log("Break on index %d which is: %s", breakSpanIndex, childs[breakSpanIndex].textContent);
      // create new line
      var newline = SVG.adopt(line.node.cloneNode());
      newline.data('connected-with-line', line.id());
      newline.id(SVG.eid(newline.node.nodeName));
      line.node.parentNode.insertBefore(newline.node, line.node);

      // put oter spans into new line
      var childsToMove = [];
      for (var y = 0; y < breakSpanIndex; y++) {
        childsToMove.push(childs[y]);
      }

      childsToMove.map(function(ch) { return newline.node.appendChild(ch); });

      // connect tspan in this line which can be connected
      // and recursive call same fun on new line
      this.connectBrokenWordsInLine(newline);
      this.breakLine(line, width);
      this.connectBrokenWordsInLine(line);
      this.adjustLines();

      // console.log("---- END breaking ----");
    },

    breakSpanIntoTwo: function(spanNode) {
      var parentNode = spanNode.parentNode;
      var words = spanNode.textContent.split(' ').filter(function (w){ return (w !== '' && w.length > 0); });

      // console.log(words);
      if (words.length < 2) {
        return null;
      }

      spanNode.innerHTML = "";
      // var span2 = childs[i].clone().node; @fixme: clone(). does not work on tspan elements (index() exactly)
      var span2 = spanNode.cloneNode(true);
      parentNode.insertBefore(span2, spanNode.nextSibling);
      SVG.adopt(span2).id(SVG.eid(span2.nodeName));
      SVG.adopt(span2).data('connect-prev', true);
      SVG.adopt(spanNode).data('connect-next', true);

      for (var j = 0; j < words.length; j++) {
        if (words[j] === '') { continue; }
        if (j+1 <= words.length/2 ) {
          spanNode.innerHTML = spanNode.innerHTML + words[j] + ' ';
        } else {
          span2.innerHTML = span2.innerHTML + words[j] + ' ';
        }
      }

      return span2;
    },

    /**
     * Connects spans created by breakSpanIntoTwo() method
     * Reduces unecessery tspans
     * @param  {SVG.Tspan} line
     * @return {void}
     */
    connectBrokenWordsInLine: function(line) {
      var childs = line.node.childNodes;
      for (var i = 0; i < childs.length; i++) {
        var span = SVG.adopt(childs[i]);
        var nextSpan = i < childs.length ? SVG.adopt(childs[i+1]) : null;
        if (span && span.data('connect-next') &&
            nextSpan && nextSpan.data('connect-prev')) {

          nextSpan.node.innerHTML = span.node.innerHTML + ' ' + nextSpan.node.innerHTML;
          span.node.remove();
          i--;
        }
      }
    },

    /**
     * Connects lines broken by word wrap method. Its required when we
     * want to changes width of textbox
     * @return {void}
     */
    connectBrokenLines: function() {
      var childs = this.node.childNodes;

      // reversed "for" loop
      for (var i = childs.length - 1; i >= 0; i--) {
        var span = SVG.adopt(childs[i]);
        if (!span || !span.data('connected-with-line')) { continue; }
        var targetSpan = SVG.get(span.data('connected-with-line'));
        if (!targetSpan) continue;

        targetSpan.node.innerHTML = span.node.innerHTML + ' ' + targetSpan.node.innerHTML;
        span.node.remove();
      }
    },

    /**
     * Wraps plain text into <tspan> tags
     * @param  {SVG.Tspan} tspanLine
     * @return {void}
     */
    wrapPlainText: function(tspanLine) {
      var childs = tspanLine.node.childNodes;
      if (!childs) { return; }

      for (var i = 0; i < childs.length; i++) {
        var n = childs[i];
        if (n.nodeName !== '#text') { continue; }
        var tmp = SVG.create('tspan');
        // console.log('Text wprapped: ' + n.textContent);
        tmp.innerHTML = n.textContent;
        tspanLine.node.replaceChild(tmp, n);
      }
    },

    // search recursive through all child nodes and return biggest font size in px as number
    getBiggestFont: function(line) {
      var biggestFont = 0;
      var childs = SVG.utils.filterSVGElements(line.node.childNodes);

      for (var i = childs.length - 1; i >= 0; i--) {
        if (childs[i].innerHTML.length < 1) continue;
        var fch = this.getBiggestFont(SVG.adopt(childs[i]));
        var fpa = parseInt(getComputedStyle(childs[i])['font-size']);
        var f = fpa > fch ? fpa : fch;
        biggestFont = f > biggestFont ? f : biggestFont;
      }

      return biggestFont;
    },

    lines: function() {
      // filter tspans and map them to SVG.js instances
      var lines = SVG.utils.map(SVG.utils.filterSVGElements(this.node.childNodes), function(el){
        return SVG.adopt(el);
      });

      // return an instance of SVG.set
      return new SVG.Set(lines);
    },

    lineHeight: function(value) {
      if (value === null) return this.dom.lineHeight;
      this.dom.lineHeight = new SVG.Number(value);
      this.adjustLines();
      return this;
    }
  },

  construct: {
    mtext: function() {
      return this.put(new SVG.MText());
    }
  }
});

SVG.extend(SVG.MText, {
  move: function(x, y) {
    return this.x(x).y(y);
  },

  x: function(x) {
    if (typeof x === 'undefined') return this.attr('x');
    this.attr('x', x);
    if (this.adjustLines) { this.adjustLines(); }
    return this;
  },

  y: function(y) {
    if (typeof y === 'undefined') return this.attr('y');
    this.attr('y', y);
    if (this.adjustLines) { this.adjustLines(); }
    return this;
  }
});

/**
 * Adopts SVG text element with multiline attr as
 * MText instance.
 * Normal <text> will not be adopted.
 *
 * @todo separate method to converts normal text to mtext
 *
 * @param {HTMLElement} node to adopt
 */
SVG.AdoptMText = function(node) {
  if (!node || node.nodeName != 'text') return null;

  // attr multiline means that <text> was mbox indeed
  if (!node.getAttribute("multiline")) return null;

  if (node.instance && node.instance instanceof SVG.MText) return node.instance;

  var element = new SVG.MText();

  element.type  = node.nodeName;
  element.node  = node;
  node.instance = element;

  // console.log(element);

  element.setData(JSON.parse(node.getAttribute('svgjs:data')) || {});

  return element;
};
<|endoftext|>


<commit_before>/**
 * Switch Plugin: fade
 * author  Kael Zhang
 */

KM.define(['./accordion'], function(K, require){

var

accordion = require('./accordion'),
fade = {},

STR_ATTRS = 'ATTRS',

ACCORDION_ATTRS = accordion[STR_ATTRS],

ATTRS = {
	property: {
		value: 'opacity'
	},

	activeValue: {
		value: 1
	},

	normalValue: {
		value: 0
	},

	fx: {
		value: {
			duration: 1000
		}
	}
};

fade[STR_ATTRS] = ATTRS;

// mix attributes
K.mix(ATTRS, ACCORDION_ATTRS, false);

// mix value of fx
K.mix(ATTRS.fx.value, ACCORDION_ATTRS.fx.value, false);

// mix plugin members
K.mix(fade, accordion, false);

return fade;

});<commit_msg>switch/fade: the 'property' attribute of fade plugin is readonly<commit_after>/**
 * Switch Plugin: fade
 * author  Kael Zhang
 */

KM.define(['./accordion'], function(K, require){

var

accordion = require('./accordion'),
fade = {},

STR_ATTRS = 'ATTRS',

ACCORDION_ATTRS = accordion[STR_ATTRS],

ATTRS = {
	property: {
		readOnly: true,
		value: 'opacity'
	},

	activeValue: {
		value: 1
	},

	normalValue: {
		value: 0
	},

	fx: {
		value: {
			duration: 1000
		}
	}
};

fade[STR_ATTRS] = ATTRS;

// mix attributes
K.mix(ATTRS, ACCORDION_ATTRS, false);

// mix value of fx
K.mix(ATTRS.fx.value, ACCORDION_ATTRS.fx.value, false);

// mix plugin members
K.mix(fade, accordion, false);

return fade;

});<|endoftext|>


<commit_before>/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
/*global easyTest, easyXDM, window*/
var _remoteUrl = location.href.substring(0, location.href.lastIndexOf("/") + 1);
if (_remoteUrl.indexOf("easyxdm.net") !== -1) {
    _remoteUrl = _remoteUrl.replace("easyxdm.net", "provider.easyxdm.net");
}
if (_remoteUrl.indexOf("xdm1") !== -1) {
    _remoteUrl = _remoteUrl.replace("xdm1", "xdm2");
}
var channelId = 0;
function runTests(){
    easyTest.test([/**Tests for the presence of namespaces and classes*/{
        name: "Check that the library is complete",
        steps: [{
            name: "check for the presence of easyXDM",
            run: function(){
                if (this.Assert.isObject(easyXDM) && this.Assert.isString(easyXDM.version)) {
                    this.log("found easyXDM, version=" + easyXDM.version);
                    return true;
                }
                return false;
            }
        }, {
            name: "check for the presence of easyXDM.transport",
            run: function(){
                return this.Assert.isObject(easyXDM.transport);
            }
        }, {
            name: "check for the presence of easyXDM.serializing",
            run: function(){
                return this.Assert.isObject(easyXDM.serializing);
            }
        }, {
            name: "check for the presence of easyXDM.configuration",
            run: function(){
                return this.Assert.isObject(easyXDM.configuration);
            }
        }, {
            name: "check for the presence of easyXDM.Channel",
            run: function(){
                return this.Assert.isFunction(easyXDM.Channel);
            }
        }, {
            name: "check for the presence of easyXDM.transport.HashTransport",
            run: function(){
                return this.Assert.isFunction(easyXDM.transport.HashTransport);
            }
        }, {
            name: "check for the presence of easyXDM.transport.PostMessageTransport",
            run: function(){
                return this.Assert.isFunction(easyXDM.transport.PostMessageTransport);
            }
        }, {
            name: "check for the presence of easyXDM.transport.NameTransport",
            run: function(){
                return this.Assert.isFunction(easyXDM.transport.NameTransport);
            }
        }, {
            name: "check for the presence of easyXDM.Debug",
            run: function(){
                return this.Assert.isObject(easyXDM.Debug);
            }
        }, {
            name: "check for the presence of easyXDM.DomHelper",
            run: function(){
                return this.Assert.isObject(easyXDM.DomHelper);
            }
        }, {
            name: "check for the presence of easyXDM.Url",
            run: function(){
                return this.Assert.isObject(easyXDM.Url);
            }
        }]
    }, {
        name: "test easyXDM.transport.NameTransport using queuing",
        runIf: function(){
            if (typeof window.postMessage !== "undefined") {
                return "This test will often fail in modern browser due to window.open() not always returning existing windows";
            }
        },
        setUp: function(){
            this.expectedMessage = "1abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                this.transport = new easyXDM.transport.NameTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html",
                    remoteHelper: _remoteUrl + "../hash.html",
                    onMessage: function(message, origin){
                        scope.notifyResult((scope.expectedMessage === message));
                    },
                    container: document.getElementById("embedded")
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 1000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.HashTransport using polling and queuing",
        setUp: function(){
            this.expectedMessage = "1abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                var messages = 0;
                this.transport = new easyXDM.transport.HashTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        if (scope.expectedMessage === message) {
                            if (++messages === 2) {
                                scope.notifyResult(true);
                            }
                        }
                    },
                    container: document.getElementById("embedded")
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 2000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.HashTransport using onresize and queuing",
        setUp: function(){
            this.expectedMessage = "2abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                var messages = 0;
                this.transport = new easyXDM.transport.HashTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        if (scope.expectedMessage === message) {
                            if (++messages === 2) {
                                scope.notifyResult(true);
                            }
                        }
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 2000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
                this.transport.postMessage(this.expectedMessage);

            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.HashTransport using parent and queuing",
        setUp: function(){
            this.expectedMessage = "2abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                var messages = 0;
                this.transport = new easyXDM.transport.HashTransport({
                    channel: "channel" + (channelId++),
                    local: window,
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        if (scope.expectedMessage === message) {
                            if (++messages === 2) {
                                scope.notifyResult(true);
                            }
                        }
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 1000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.HashTransport using readyAfter and queuing",
        runIf: function(){
            if (typeof window.postMessage !== "undefined") {
                return "This test will often fail in modern browser due to window.open() not always returning existing windows";
            }
        },
        setUp: function(){
            this.expectedMessage = "2abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                var messages = 0;
                this.transport = new easyXDM.transport.HashTransport({
                    channel: "channel" + (channelId++),
                    readyAfter: 1000,
                    local: "../changes.txt",
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        if (++messages === 2) {
                            scope.notifyResult(true);
                        }
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 1000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.HashTransport with fragmentation (8192)",
        setUp: function(){
            var i = 11;
            this.expectedMessage = "aaaa";
            while (i--) {
                this.expectedMessage += this.expectedMessage;
            }
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                this.transport = new easyXDM.transport.HashTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        scope.notifyResult(scope.expectedMessage === message);
                    },
                    container: document.getElementById("embedded")
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 5000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.PostMessageTransport",
        runIf: function(){
            if (typeof window.postMessage === "undefined") {
                return "This test requires the HTML5 postMessage interface.";
            }
        },

        setUp: function(){
            this.expectedMessage = "3abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                this.transport = new easyXDM.transport.PostMessageTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        scope.notifyResult((scope.expectedMessage === message));
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 1000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.BestAvailableTransport",
        setUp: function(){
            this.expectedMessage = "4abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                this.transport = new easyXDM.transport.BestAvailableTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        scope.notifyResult((scope.expectedMessage === message));
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 1000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.BestAvailableTransport with query parameters",
        setUp: function(){
            this.expectedMessage = "5abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                this.transport = new easyXDM.transport.BestAvailableTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html?a=b&c=d",
                    onMessage: function(message, origin){
                        scope.notifyResult((scope.expectedMessage === message));
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 1000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.Interface",
        setUp: function(){
            this.expectedMessage = "6abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                this.remote = new easyXDM.Interface({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_interface.html"
                }, {
                    remote: {
                        voidMethod: {
                            isVoid: true
                        },
                        asyncMethod: {},
                        method: {}
                    },
                    local: {
                        voidCallback: {
                            method: function(message){
                                scope.notifyResult((scope.expectedMessage === message));
                            },
                            isVoid: true
                        }
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "void method",
            timeout: 1000,
            run: function(){
                this.remote.voidMethod(this.expectedMessage);
            }
        }, {
            name: "async method",
            timeout: 1000,
            run: function(){
                var scope = this;
                this.remote.asyncMethod(this.expectedMessage, function(message){
                    scope.notifyResult((scope.expectedMessage === message));
                });
            }
        }, {
            name: "regular method",
            timeout: 1000,
            run: function(){
                var scope = this;
                this.remote.method(this.expectedMessage, function(message){
                    scope.notifyResult((scope.expectedMessage === message));
                });
            }
        }, {
            name: "destroy",
            run: function(){
                this.remote.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }]);
}
<commit_msg>Enhanced the tests<commit_after>/*jslint evil: true, browser: true, immed: true, passfail: true, undef: true, newcap: true*/
/*global easyTest, easyXDM, window*/
var _remoteUrl = location.href.substring(0, location.href.lastIndexOf("/") + 1);
if (_remoteUrl.indexOf("easyxdm.net") !== -1) {
    _remoteUrl = _remoteUrl.replace("easyxdm.net", "provider.easyxdm.net");
}
if (_remoteUrl.indexOf("xdm1") !== -1) {
    _remoteUrl = _remoteUrl.replace("xdm1", "xdm2");
}
var channelId = 0;
function runTests(){
    easyTest.test([/**Tests for the presence of namespaces and classes*/{
        name: "Check that the library is complete",
        steps: [{
            name: "check for the presence of easyXDM",
            run: function(){
                if (this.Assert.isObject(easyXDM) && this.Assert.isString(easyXDM.version)) {
                    this.log("found easyXDM, version=" + easyXDM.version);
                    return true;
                }
                return false;
            }
        }, {
            name: "check for the presence of easyXDM.transport",
            run: function(){
                return this.Assert.isObject(easyXDM.transport);
            }
        }, {
            name: "check for the presence of easyXDM.serializing",
            run: function(){
                return this.Assert.isObject(easyXDM.serializing);
            }
        }, {
            name: "check for the presence of easyXDM.configuration",
            run: function(){
                return this.Assert.isObject(easyXDM.configuration);
            }
        }, {
            name: "check for the presence of easyXDM.Channel",
            run: function(){
                return this.Assert.isFunction(easyXDM.Channel);
            }
        }, {
            name: "check for the presence of easyXDM.Channel",
            run: function(){
                return this.Assert.isFunction(easyXDM.Channel);
            }
        }, {
            name: "check for the presence of easyXDM.transport",
            run: function(){
                return this.Assert.isObject(easyXDM.transport);
            }
        }, {
            name: "check for the presence of easyXDM.transport.PostMessageTransport",
            run: function(){
                return this.Assert.isFunction(easyXDM.transport.PostMessageTransport);
            }
        }, {
            name: "check for the presence of easyXDM.transport.NameTransport",
            run: function(){
                return this.Assert.isFunction(easyXDM.transport.NameTransport);
            }
        }, {
            name: "check for the presence of easyXDM.transport.behaviors",
            run: function(){
                return this.Assert.isObject(easyXDM.transport.behaviors);
            }
        }, {
            name: "check for the presence of easyXDM.Debug",
            run: function(){
                return this.Assert.isObject(easyXDM.Debug);
            }
        }, {
            name: "check for the presence of easyXDM.DomHelper",
            run: function(){
                return this.Assert.isObject(easyXDM.DomHelper);
            }
        }, {
            name: "check for the presence of easyXDM.Url",
            run: function(){
                return this.Assert.isObject(easyXDM.Url);
            }
        }]
    }, {
        name: "test easyXDM.transport.NameTransport using queuing",
        runIf: function(){
            if (typeof window.postMessage !== "undefined") {
                return "This test will often fail in modern browser due to window.open() not always returning existing windows";
            }
        },
        setUp: function(){
            this.expectedMessage = "1abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                var messages = 0;
                this.transport = new easyXDM.transport.NameTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html",
                    remoteHelper: _remoteUrl + "../hash.html",
                    onMessage: function(message, origin){
                        if (scope.expectedMessage === message) {
                            if (++messages === 2) {
                                scope.notifyResult(true);
                            }
                        }
                    },
                    container: document.getElementById("embedded")
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 5000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.HashTransport using polling and queuing",
        setUp: function(){
            this.expectedMessage = "1abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                var messages = 0;
                this.transport = new easyXDM.transport.HashTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        if (scope.expectedMessage === message) {
                            if (++messages === 2) {
                                scope.notifyResult(true);
                            }
                        }
                    },
                    container: document.getElementById("embedded")
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 5000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.HashTransport using onresize and queuing",
        setUp: function(){
            this.expectedMessage = "2abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                var messages = 0;
                this.transport = new easyXDM.transport.HashTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        if (scope.expectedMessage === message) {
                            if (++messages === 2) {
                                scope.notifyResult(true);
                            }
                        }
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 5000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
                this.transport.postMessage(this.expectedMessage);

            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.HashTransport using parent and queuing",
        setUp: function(){
            this.expectedMessage = "2abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                var messages = 0;
                this.transport = new easyXDM.transport.HashTransport({
                    channel: "channel" + (channelId++),
                    local: window,
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        if (scope.expectedMessage === message) {
                            if (++messages === 2) {
                                scope.notifyResult(true);
                            }
                        }
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 5000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.HashTransport using readyAfter and queuing",
        runIf: function(){
            if (typeof window.postMessage !== "undefined") {
                return "This test will often fail in modern browser due to window.open() not always returning existing windows";
            }
        },
        setUp: function(){
            this.expectedMessage = "2abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                var messages = 0;
                this.transport = new easyXDM.transport.HashTransport({
                    channel: "channel" + (channelId++),
                    readyAfter: 1000,
                    local: "../changes.txt",
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        if (++messages === 2) {
                            scope.notifyResult(true);
                        }
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 5000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.HashTransport with fragmentation (8192)",
        setUp: function(){
            var i = 11;
            this.expectedMessage = "aaaa";
            while (i--) {
                this.expectedMessage += this.expectedMessage;
            }
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                this.transport = new easyXDM.transport.HashTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        scope.notifyResult(scope.expectedMessage === message);
                    },
                    container: document.getElementById("embedded")
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 5000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.PostMessageTransport",
        runIf: function(){
            if (typeof window.postMessage === "undefined") {
                return "This test requires the HTML5 postMessage interface.";
            }
        },

        setUp: function(){
            this.expectedMessage = "3abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                var messages = 0;
                this.transport = new easyXDM.transport.PostMessageTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        if (scope.expectedMessage === message) {
                            if (++messages === 2) {
                                scope.notifyResult(true);
                            }
                        }
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 5000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.BestAvailableTransport",
        setUp: function(){
            this.expectedMessage = "4abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                this.transport = new easyXDM.transport.BestAvailableTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html",
                    onMessage: function(message, origin){
                        scope.notifyResult((scope.expectedMessage === message));
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 5000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.transport.BestAvailableTransport with query parameters",
        setUp: function(){
            this.expectedMessage = "5abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                this.transport = new easyXDM.transport.BestAvailableTransport({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_transport.html?a=b&c=d",
                    onMessage: function(message, origin){
                        scope.notifyResult((scope.expectedMessage === message));
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "message is echoed back",
            timeout: 5000,
            run: function(){
                this.transport.postMessage(this.expectedMessage);
            }
        }, {
            name: "destroy",
            run: function(){
                this.transport.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }, {
        name: "test easyXDM.Interface",
        setUp: function(){
            this.expectedMessage = "6abcd1234";
        },
        steps: [{
            name: "onReady is fired",
            timeout: 5000,
            run: function(){
                var scope = this;
                this.remote = new easyXDM.Interface({
                    channel: "channel" + (channelId++),
                    local: "../hash.html",
                    remote: _remoteUrl + "test_interface.html"
                }, {
                    remote: {
                        voidMethod: {
                            isVoid: true
                        },
                        asyncMethod: {},
                        method: {}
                    },
                    local: {
                        voidCallback: {
                            method: function(message){
                                scope.notifyResult((scope.expectedMessage === message));
                            },
                            isVoid: true
                        }
                    }
                }, function(){
                    scope.notifyResult(true);
                });
            }
        }, {
            name: "void method",
            timeout: 5000,
            run: function(){
                this.remote.voidMethod(this.expectedMessage);
            }
        }, {
            name: "async method",
            timeout: 5000,
            run: function(){
                var scope = this;
                this.remote.asyncMethod(this.expectedMessage, function(message){
                    scope.notifyResult((scope.expectedMessage === message));
                });
            }
        }, {
            name: "regular method",
            timeout: 5000,
            run: function(){
                var scope = this;
                this.remote.method(this.expectedMessage, function(message){
                    scope.notifyResult((scope.expectedMessage === message));
                });
            }
        }, {
            name: "destroy",
            run: function(){
                this.remote.destroy();
                return ((document.getElementsByTagName("iframe").length === 0));
            }
        }]
    }]);
}
<|endoftext|>