<commit_before>function startswith (str, prefix) {
  return str.substring(0,prefix.length) == prefix;
}

function endswith (str, suffix) {
  return str.substring(this.length - suffix.length) == suffix;
}

function replaceIdsInDOM(id, templateId, dom) {
    $.each(dom, function () {
	if (this.nodeType == 1) {  // Node.ELEMENT_TYPE
	    if (   this.hasAttribute('id')
		&& startswith(this.getAttribute('id'), templateId))
		this.setAttribute('id', id + this.getAttribute('id').substring(templateId.length))
	    if (   this.hasAttribute('name')
		&& startswith(this.getAttribute('name'), templateId))
		this.setAttribute('name', id + this.getAttribute('name').substring(templateId.length))
	}
    })
    if (dom.children().length > 0)
        replaceIdsInDOM(id, templateId, dom.children());
}

function makeTemplateInstance(id, templateId) {
    var res = $('#' + templateId).clone(true);
    replaceIdsInDOM(id, templateId, res);
    res[0].style.display = 'inherit';
    return res[0];
}

function parseFloatNazi(str)
{
    if (str == null || str == "") {
	return 0;
    }

    var str2 = str.replace(/,/g,'.');

    if (str2.match(/^[0-9]*\.?[0-9]+$/))
	return parseFloat(str2);
    return NaN;
}

function toMoney (val) {
    if (isNaN(val)) {
	return '?';
    }
    return val.toFixed(2).replace(/\./g,',');
}

// this function is needed to work around
// a bug in IE related to element attributes
function hasClass(obj) {
    var result = false;
    if (obj.getAttributeNode("class") != null) {
	result = obj.getAttributeNode("class").value;
    }
    return result;
}

function stripe(id) {

    // the flag we'll use to keep track of
    // whether the current row is odd or even
    var even = false;

    // obtain a reference to the desired tables
    // ... and iterate through them
    var table_list;
    if (id != null) {
	table_list = $(id);
    } else {
	table_list = $('.striped');
    }

    for(var tab=0; tab<table_list.length;tab++) {

	var table = table_list[tab];
	if (! table) { continue; }

	// by definition, tables can have more than one tbody
	// element, so we'll have to get the list of child
	// <tbody>s
	var tbodies = table.getElementsByTagName("tbody");

	// and iterate through them...
	for (var h = 0; h < tbodies.length; h++) {

	    // find all the <tr> elements...
	    var trs = tbodies[h].getElementsByTagName("tr");

	    // ... and iterate through them
	    for (var i = 0; i < trs.length; i++) {

		var parent = trs[i].parentNode;
		while(parent && parent.nodeName.toLowerCase() != 'tbody')
		    {
			parent = parent.parentNode;
		    }

		if( parent != tbodies[h] )
		    {
			continue;
		    }

		// avoid rows that have a class attribute
		// or backgroundColor style
		if (! hasClass(trs[i]) &&
		    ! trs[i].style.backgroundColor) {

		    // get all the cells in this row...
		    var tds = trs[i].getElementsByTagName("td");
		    var ths = trs[i].getElementsByTagName("th");

		    // and iterate through them...
		    for (var j = 0; j < tds.length; j++) {

			var mytd = tds[j];

			mytd.className = even?'even':'odd';
		    }
		    for (var j = 0; j < ths.length; j++) {

			var myth = ths[j];

			myth.className = even?'even':'odd';
		    }
		}
		// flip from odd to even, or vice-versa
		even =  ! even;
	    }
	}
    }
}
<commit_msg>Added a few utility functions<commit_after>function startswith (str, prefix) {
  return str.substring(0,prefix.length) == prefix;
}

function endswith (str, suffix) {
  return str.substring(this.length - suffix.length) == suffix;
}

function map(fn, seq) {
  var res = new Array();

  seq.each(function (x) { res.push(fn(x)); })
  return res;
}

function reduce (fn, seq) {
  var pos = 1;
  var res = seq[0];

  for (; pos < seq.length; pos++)
    res = fn(res, seq[pos]);
  return res;
}

function add (x, y) { return x + y; }
function sub (x, y) { return x - y; }
function mul (x, y) { return x * y; }
function div (x, y) { return x / y; }

function sum (seq) { return reduce(add, seq); }
function avg (seq) { return sum(seq) / seq.length; }

function replaceIdsInDOM(id, templateId, dom) {
    $.each(dom, function () {
	if (this.nodeType == 1) {  // Node.ELEMENT_TYPE
	    if (   this.hasAttribute('id')
		&& startswith(this.getAttribute('id'), templateId))
		this.setAttribute('id', id + this.getAttribute('id').substring(templateId.length))
	    if (   this.hasAttribute('name')
		&& startswith(this.getAttribute('name'), templateId))
		this.setAttribute('name', id + this.getAttribute('name').substring(templateId.length))
	}
    })
    if (dom.children().length > 0)
        replaceIdsInDOM(id, templateId, dom.children());
}

function makeTemplateInstance(id, templateId) {
    var res = $('#' + templateId).clone(true);
    replaceIdsInDOM(id, templateId, res);
    res[0].style.display = 'inherit';
    return res[0];
}

function decorateDOM(dom, decoration) {
    var value;
    for (member in decoration) {
	value = decoration[member];
        if (value.argumentNames === undefined) {
            $.each(dom, function (domitem) { domitem[member] = value; });
        } else {
            decorateDOM($('#' + member, dom), value);
        }
    }
}

function parseFloatNazi(str)
{
    if (str == null || str == "") {
	return 0;
    }

    var str2 = str.replace(/,/g,'.');

    if (str2.match(/^[0-9]*\.?[0-9]+$/))
	return parseFloat(str2);
    return NaN;
}

function toMoney (val) {
    if (isNaN(val)) {
	return '?';
    }
    return val.toFixed(2).replace(/\./g,',');
}

// this function is needed to work around
// a bug in IE related to element attributes
function hasClass(obj) {
    var result = false;
    if (obj.getAttributeNode("class") != null) {
	result = obj.getAttributeNode("class").value;
    }
    return result;
}

function stripe(id) {

    // the flag we'll use to keep track of
    // whether the current row is odd or even
    var even = false;

    // obtain a reference to the desired tables
    // ... and iterate through them
    var table_list;
    if (id != null) {
	table_list = $(id);
    } else {
	table_list = $('.striped');
    }

    for(var tab=0; tab<table_list.length;tab++) {

	var table = table_list[tab];
	if (! table) { continue; }

	// by definition, tables can have more than one tbody
	// element, so we'll have to get the list of child
	// <tbody>s
	var tbodies = table.getElementsByTagName("tbody");

	// and iterate through them...
	for (var h = 0; h < tbodies.length; h++) {

	    // find all the <tr> elements...
	    var trs = tbodies[h].getElementsByTagName("tr");

	    // ... and iterate through them
	    for (var i = 0; i < trs.length; i++) {

		var parent = trs[i].parentNode;
		while(parent && parent.nodeName.toLowerCase() != 'tbody')
		    {
			parent = parent.parentNode;
		    }

		if( parent != tbodies[h] )
		    {
			continue;
		    }

		// avoid rows that have a class attribute
		// or backgroundColor style
		if (! hasClass(trs[i]) &&
		    ! trs[i].style.backgroundColor) {

		    // get all the cells in this row...
		    var tds = trs[i].getElementsByTagName("td");
		    var ths = trs[i].getElementsByTagName("th");

		    // and iterate through them...
		    for (var j = 0; j < tds.length; j++) {

			var mytd = tds[j];

			mytd.className = even?'even':'odd';
		    }
		    for (var j = 0; j < ths.length; j++) {

			var myth = ths[j];

			myth.className = even?'even':'odd';
		    }
		}
		// flip from odd to even, or vice-versa
		even =  ! even;
	    }
	}
    }
}
<|endoftext|>


<commit_before>$("#nameInput").submit(function (event) {
    $("#nameInput").blur(); // unselects form
    $('#information').hide()

    // stop form from submitting normally
    event.preventDefault();

    var inputtedName = $('#userName').val();
	  console.log('beginning request for: ' + inputtedName)

    //Form validation
    if (checkUserName(inputtedName)) {
        $('#loading').show();

        $.ajax({
            type: 'GET',
            url: '/user/' + inputtedName,
            success: function (data) { successOccurs(inputtedName, data) } ,
            error: function (data) { errorOccurs(inputtedName, data) }
        })
    } else {
        //this should be added to an 'error' para instead.
        $('#information').show().text("The inputted name must conform to reddit's naming standards");
    }
})

//what runs upon successful ajax request
function successOccurs(inputtedName, data) {
    $('#loading').hide();

    if (data.error) {
        $('#information').show().text('Error occurred: ' + data.info)
    } else {
        console.log('success: ' + inputtedName);
        $('.JSON').text(JSON.stringify(data));

        var comms = data.comments;
        var subs = data.submissions;

        $('#information').show().text('Successfully gathered ' + comms.length + ' comments and ' + subs.length + ' submissions from /u/' + inputtedName)
    }
}

//catches ajax errors
function errorOccurs(inputtedName, data) {
    $('#loading').hide();
    $('#information').show().text('Unsuccessfully gathered ' + inputtedName + '\'s content for reasons: ' + data)
    console.log(data)
}

//checks user name against reddit's specs
function checkUserName(name) {

    var flag;
    var myRegex = /^([a-zA-Z0-9_-]){3,20}$/;

    if (myRegex.test(name)) {
        flag = true;
    } else {
        flag = false;
    }

    return flag;
}<commit_msg>Update main.js<commit_after>$("#nameInput").submit(function(event) {
    $("#nameInput").blur(); // unselects form
    $('#information').hide();

    // stop form from submitting normally
    event.preventDefault();

    var inputtedName = $('#userName').val();
    console.log('beginning request for: ' + inputtedName);

    //Form validation
    if (checkUserName(inputtedName)) {
        $('#loading').show();

        $.ajax({
            type: 'GET',
            url: '/user/' + inputtedName,
            success: function(data) {
                successOccurs(inputtedName, data)
            },
            error: function(data) {
                errorOccurs(inputtedName, data)
            }
        })
    } else {
        //this should be added to an 'error' para instead.
        $('#information').show().text("The inputted name must conform to reddit's naming standards");
    }
})

//what runs upon successful ajax request
function successOccurs(inputtedName, data) {
    $('#loading').hide();

    if (data.error) {
        $('#information').show().text('Error occurred: ' + data.info);
    } else {
        console.log('success: ' + inputtedName);
        $('.JSON').text(JSON.stringify(data));

        var comms = data.comments;
        var subs = data.submissions;

        $('#information').show().text('Successfully gathered ' + comms.length + ' comments and ' + subs.length + ' submissions from /u/' + inputtedName);
    }
}

//catches ajax errors
function errorOccurs(inputtedName, data) {
    $('#loading').hide();
    $('#information').show().text('Unsuccessfully gathered ' + inputtedName + '\'s content for reasons: ' + data);
    console.log(data);
}

//checks user name against reddit's specs
function checkUserName(name) {

    var flag;
    var myRegex = /^([a-zA-Z0-9_-]){3,20}$/;

    if (myRegex.test(name)) {
        flag = true;
    } else {
        flag = false;
    }

    return flag;
}
<|endoftext|>


<commit_before>
'use strict';

//Look after different browser vendors' ways of calling the getUserMedia() API method:
//Opera --> getUserMedia
//Chrome --> webkitGetUserMedia
//Firefox --> mozGetUserMedia
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

// Clean-up function:
// collect garbage before unloading browser's window
window.onbeforeunload = function(e){
    hangup();
}

// Data channel information
var sendChannel, receiveChannel;

// HTML5 <video> elements
var localVideo = document.querySelector('#localVideo');
var remoteVideo = document.querySelector('#remoteVideo');

// Flags...
var isChannelReady;
var isInitiator;
var isStarted;

// WebRTC data structures
// Streams
var localStream;
var remoteStream;
// Peer Connection
var pc;

var socket = null;

// Peer Connection ICE protocol configuration (either Firefox or Chrome)
var pc_config = webrtcDetectedBrowser === 'firefox' ?
    {'iceServers':[{'urls':'stun:23.21.150.121'}]} : // IP address
    {'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}]};

function createCORSRequest(method, url) {
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr) {
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest != "undefined") {
        xhr = new XDomainRequest();
        xhr.open(method, url);
    } else {
        xhr = null;
    }
    return xhr;
}

// Peer Connection contraints: (i) use DTLS;
var pc_constraints = webrtcDetectedBrowser === 'firefox' ?
 {
    'optional': [
      {'DtlsSrtpKeyAgreement': true},
      {'RtpDataChannels': true}
]} :
{
    'optional' : [

]};

// Session Description Protocol constraints:
// - use both audio and video regardless of what devices are available
//var sdpConstraints = {'mandatory': {
//  'OfferToReceiveAudio':true,
//  'OfferToReceiveVideo':true }};

var sdpConstraints = webrtcDetectedBrowser === 'firefox' ?
  {'offerToReceiveAudio':true,'offerToReceiveVideo':true } :
  {'mandatory': {'OfferToReceiveAudio':true, 'OfferToReceiveVideo':true }};

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

// Let's get started: prompt user for input (room name)
// var default_name = randomId();
var href = location.pathname;

var room =  href.substr(href.lastIndexOf('/') + 1);//prompt('Enter room name:', default_name);

// Connect to signalling server
var socket = io.connect();

// Send 'Create or join' message to singnalling server
if (room !== '') {
    console.log('Create or join room', room);
    socket.emit('create or join', room);
    socket.emit('getCred');
}

// Set getUserMedia constraints
var constraints = {video: true,
                   audio: true };

// Call getUserMedia()
navigator.getUserMedia(constraints, handleUserMedia, handleUserMediaError);
console.log('Getting user media with constraints', constraints);

// From this point on, execution proceeds based on asynchronous events...

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

// getUserMedia() handlers...
/////////////////////////////////////////////
function handleUserMedia(stream) {
    localStream = stream;
    attachMediaStream(localVideo, stream);
    console.log('Adding local stream.');
    sendMessage('got user media');
    if (isInitiator) {
        checkAndStart();
    }
}

function handleUserMediaError(error){
    console.log('navigator.getUserMedia error: ', error);
}
/////////////////////////////////////////////
// Server-mediated message exchanging...
/////////////////////////////////////////////

/////////////////////////////////////////////
// 1. Server-->Client...
/////////////////////////////////////////////

// Handle 'created' message coming back from server:
// this peer is the initiator
socket.on('created', function (room){
    console.log('Created room ' + room);
    isInitiator = true;
});

// Handle 'full' message coming back from server:
// this peer arrived too late :-(
socket.on('full', function (room){
    console.log('Room ' + room + ' is full');
});

// Handle 'join' message coming back from server:
// another peer is joining the channel
socket.on('join', function (room){
    console.log('Another peer made a request to join room ' + room);
    //console.log('This peer is the initiator of room ' + room + '!');
    isChannelReady = true;
});

// Handle 'joined' message coming back from server:
// this is the second peer joining the channel
socket.on('joined', function (room){
    console.log('This peer has joined room ' + room);
    isChannelReady = true;
});

// Server-sent log message...
socket.on('log', function (array){
    console.log.apply(console, array);
});

// Receive message from the other peer via the signalling server
socket.on('message', function (message){
    //console.log('Received message:', message);
    if (message === 'got user media') {
        checkAndStart();
    } else if (message.type === 'offer') {
        if (!isInitiator && !isStarted) {
            checkAndStart();
        }
        pc.setRemoteDescription(new RTCSessionDescription(message));
        doAnswer();
    } else if (message.type === 'answer' && isStarted) {
        pc.setRemoteDescription(new RTCSessionDescription(message));
    } else if (message.type === 'candidate' && isStarted) {
        var candidate = new RTCIceCandidate({sdpMLineIndex:message.label,
        candidate:message.candidate});
        pc.addIceCandidate(candidate);
    } else if (message === 'bye' && isStarted) {
        handleRemoteHangup();
    }
});

socket.on('ICE Candidates', function(cred){
    var url = 'https://service.xirsys.com/ice';
    var xhr = createCORSRequest('POST', url);
    xhr.onload = function() {
        var iceServers = JSON.parse(xhr.responseText).d.iceServers;
        pc_config.iceServers = iceServers;
    };
    xhr.onerror = function() {
        console.error('Woops, there was an error making xhr request.');
    };
    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

    xhr.send(cred);

});
////////////////////////////////////////////////

// 2. Client-->Server
////////////////////////////////////////////////
// Send message to the other peer via the signalling server
function sendMessage(message){
    //console.log('Sending message: ', message);
    socket.emit('message', message);
}
////////////////////////////////////////////////////

////////////////////////////////////////////////////
// Channel negotiation trigger function
function checkAndStart() {
    if (!isStarted && typeof localStream != 'undefined' && isChannelReady) {
        createPeerConnection();
        pc.addStream(localStream);
        isStarted = true;
        if (isInitiator) {
            doCall();
        }
    }
}

/////////////////////////////////////////////////////////
// Peer Connection management...
function createPeerConnection() {
    try {
        pc = new RTCPeerConnection(pc_config, pc_constraints);
        pc.onicecandidate = handleIceCandidate;
        // console.log('Created RTCPeerConnnection with:\n' +
        //     '  config: \'' + JSON.stringify(pc_config) + '\';\n' +
        //     '  constraints: \'' + JSON.stringify(pc_constraints) + '\'.');
    } catch (e) {
        console.log('Failed to create PeerConnection, exception: ' + e.message);
        alert('Cannot create RTCPeerConnection object.');
        return;
    }
    pc.onaddstream = handleRemoteStreamAdded;
    pc.onremovestream = handleRemoteStreamRemoved;

    if (isInitiator) {
        try {
            // Create a reliable data channel
            sendChannel = pc.createDataChannel("sendDataChannel",
              {reliable: true});
            //console.log('Created sendChannel' , sendChannel);
            trace('Created send data channel');
        } catch (e) {
            alert('Failed to create data channel. ');
            trace('createDataChannel() failed with exception: ' + e.message);
        }
        sendChannel.onopen = handleSendChannelStateChange;
        sendChannel.onmessage = handleMessage;
        sendChannel.onclose = handleSendChannelStateChange;
    } else { // Joiner
        pc.ondatachannel = gotReceiveChannel;
    }

    game.startCommunication();
}

// Data channel management
function sendData(data) {
    if(isInitiator) sendChannel.send(data);
    else receiveChannel.send(data);
    trace('Sent data: ' + data);
    //console.log('data:', data, typeof(data));
}

// Handlers...

function gotReceiveChannel(event) {
    trace('Receive Channel Callback');
    receiveChannel = event.channel;
    receiveChannel.onmessage = handleMessage;
    receiveChannel.onopen = handleReceiveChannelStateChange;
    receiveChannel.onclose = handleReceiveChannelStateChange;
}

function handleMessage(event) {
    trace('Received message: ' + event.data);
    game.receiveFromOpponent(event.data);
}

function handleSendChannelStateChange() {
    var readyState = sendChannel.readyState;
    trace('Send channel state is: ' + readyState);
    // If channel ready, enable user's input
    if (readyState == "open") {
        // dataChannelSend.disabled = false;
        // dataChannelSend.focus();
        // dataChannelSend.placeholder = "";
    } else {
        //dataChannelSend.disabled = true;
    }
}

function handleReceiveChannelStateChange() {
    var readyState = receiveChannel.readyState;
    trace('Receive channel state is: ' + readyState);
    // If channel ready, enable user's input
    if (readyState == "open") {
        // dataChannelSend.disabled = false;
        // dataChannelSend.focus();
        // dataChannelSend.placeholder = "";
    } else {
        // dataChannelSend.disabled = true;
    }
}

// ICE candidates management
function handleIceCandidate(event) {
    //console.log('handleIceCandidate event: ', event);
    if (event.candidate) {
        sendMessage({
            type: 'candidate',
            label: event.candidate.sdpMLineIndex,
            id: event.candidate.sdpMid,
            candidate: event.candidate.candidate});
    } else {
        //console.log('End of candidates.');
    }
}

// Create Offer
function doCall() {
    console.log('Creating Offer...');
    pc.createOffer(setLocalAndSendMessage, onSignalingError, sdpConstraints);
}

// Signalling error handler
function onSignalingError(error) {
    console.log('Failed to create signaling message : ' + error.name);
}

// Create Answer
function doAnswer() {
    console.log('Sending answer to peer.');
    pc.createAnswer(setLocalAndSendMessage, onSignalingError, sdpConstraints);
}

// Success handler for both createOffer()
// and createAnswer()
function setLocalAndSendMessage(sessionDescription) {
    pc.setLocalDescription(sessionDescription);
    sendMessage(sessionDescription);
}

/////////////////////////////////////////////////////////
// Remote stream handlers...

function handleRemoteStreamAdded(event) {
    console.log('Remote stream added.');
    attachMediaStream(remoteVideo, event.stream);
    remoteStream = event.stream;
}

function handleRemoteStreamRemoved(event) {
    console.log('Remote stream removed. Event: ', event);
}
/////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////
// Clean-up functions...

function hangup() {
    console.log('Hanging up.');
    stop();
    sendMessage('bye');
}

function handleRemoteHangup() {
    console.log('Session terminated.');
    stop();
    isInitiator = false;
    remoteVideo.src = "";
}

function stop() {
    isStarted = false;
    if (pc) pc.close();
    pc = null;
}

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

<commit_msg>game start communication on datachannel ready<commit_after>
'use strict';

//Look after different browser vendors' ways of calling the getUserMedia() API method:
//Opera --> getUserMedia
//Chrome --> webkitGetUserMedia
//Firefox --> mozGetUserMedia
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

// Clean-up function:
// collect garbage before unloading browser's window
window.onbeforeunload = function(e){
    hangup();
}

// Data channel information
var sendChannel, receiveChannel;

// HTML5 <video> elements
var localVideo = document.querySelector('#localVideo');
var remoteVideo = document.querySelector('#remoteVideo');

// Flags...
var isChannelReady;
var isInitiator;
var isStarted;

// WebRTC data structures
// Streams
var localStream;
var remoteStream;
// Peer Connection
var pc;

var socket = null;

// Peer Connection ICE protocol configuration (either Firefox or Chrome)
var pc_config = webrtcDetectedBrowser === 'firefox' ?
    {'iceServers':[{'urls':'stun:23.21.150.121'}]} : // IP address
    {'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}]};

function createCORSRequest(method, url) {
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr) {
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest != "undefined") {
        xhr = new XDomainRequest();
        xhr.open(method, url);
    } else {
        xhr = null;
    }
    return xhr;
}

// Peer Connection contraints: (i) use DTLS;
var pc_constraints = webrtcDetectedBrowser === 'firefox' ?
 {
    'optional': [
      {'DtlsSrtpKeyAgreement': true},
      {'RtpDataChannels': true}
]} :
{
    'optional' : [

]};

// Session Description Protocol constraints:
// - use both audio and video regardless of what devices are available
//var sdpConstraints = {'mandatory': {
//  'OfferToReceiveAudio':true,
//  'OfferToReceiveVideo':true }};

var sdpConstraints = webrtcDetectedBrowser === 'firefox' ?
  {'offerToReceiveAudio':true,'offerToReceiveVideo':true } :
  {'mandatory': {'OfferToReceiveAudio':true, 'OfferToReceiveVideo':true }};

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

// Let's get started: prompt user for input (room name)
// var default_name = randomId();
var href = location.pathname;

var room =  href.substr(href.lastIndexOf('/') + 1);//prompt('Enter room name:', default_name);

// Connect to signalling server
var socket = io.connect();

// Send 'Create or join' message to singnalling server
if (room !== '') {
    console.log('Create or join room', room);
    socket.emit('create or join', room);
    socket.emit('getCred');
}

// Set getUserMedia constraints
var constraints = {video: true,
                   audio: true };

// Call getUserMedia()
navigator.getUserMedia(constraints, handleUserMedia, handleUserMediaError);
console.log('Getting user media with constraints', constraints);

// From this point on, execution proceeds based on asynchronous events...

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

// getUserMedia() handlers...
/////////////////////////////////////////////
function handleUserMedia(stream) {
    localStream = stream;
    attachMediaStream(localVideo, stream);
    console.log('Adding local stream.');
    sendMessage('got user media');
    if (isInitiator) {
        checkAndStart();
    }
}

function handleUserMediaError(error){
    console.log('navigator.getUserMedia error: ', error);
}
/////////////////////////////////////////////
// Server-mediated message exchanging...
/////////////////////////////////////////////

/////////////////////////////////////////////
// 1. Server-->Client...
/////////////////////////////////////////////

// Handle 'created' message coming back from server:
// this peer is the initiator
socket.on('created', function (room){
    console.log('Created room ' + room);
    isInitiator = true;
});

// Handle 'full' message coming back from server:
// this peer arrived too late :-(
socket.on('full', function (room){
    console.log('Room ' + room + ' is full');
});

// Handle 'join' message coming back from server:
// another peer is joining the channel
socket.on('join', function (room){
    console.log('Another peer made a request to join room ' + room);
    //console.log('This peer is the initiator of room ' + room + '!');
    isChannelReady = true;
});

// Handle 'joined' message coming back from server:
// this is the second peer joining the channel
socket.on('joined', function (room){
    console.log('This peer has joined room ' + room);
    isChannelReady = true;
});

// Server-sent log message...
socket.on('log', function (array){
    console.log.apply(console, array);
});

// Receive message from the other peer via the signalling server
socket.on('message', function (message){
    //console.log('Received message:', message);
    if (message === 'got user media') {
        checkAndStart();
    } else if (message.type === 'offer') {
        if (!isInitiator && !isStarted) {
            checkAndStart();
        }
        pc.setRemoteDescription(new RTCSessionDescription(message));
        doAnswer();
    } else if (message.type === 'answer' && isStarted) {
        pc.setRemoteDescription(new RTCSessionDescription(message));
    } else if (message.type === 'candidate' && isStarted) {
        var candidate = new RTCIceCandidate({sdpMLineIndex:message.label,
        candidate:message.candidate});
        pc.addIceCandidate(candidate);
    } else if (message === 'bye' && isStarted) {
        handleRemoteHangup();
    }
});

socket.on('ICE Candidates', function(cred){
    var url = 'https://service.xirsys.com/ice';
    var xhr = createCORSRequest('POST', url);
    xhr.onload = function() {
        var iceServers = JSON.parse(xhr.responseText).d.iceServers;
        pc_config.iceServers = iceServers;
    };
    xhr.onerror = function() {
        console.error('Woops, there was an error making xhr request.');
    };
    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

    xhr.send(cred);

});
////////////////////////////////////////////////

// 2. Client-->Server
////////////////////////////////////////////////
// Send message to the other peer via the signalling server
function sendMessage(message){
    //console.log('Sending message: ', message);
    socket.emit('message', message);
}
////////////////////////////////////////////////////

////////////////////////////////////////////////////
// Channel negotiation trigger function
function checkAndStart() {
    if (!isStarted && typeof localStream != 'undefined' && isChannelReady) {
        createPeerConnection();
        pc.addStream(localStream);
        isStarted = true;
        if (isInitiator) {
            doCall();
        }
    }
}

/////////////////////////////////////////////////////////
// Peer Connection management...
function createPeerConnection() {
    try {
        pc = new RTCPeerConnection(pc_config, pc_constraints);
        pc.onicecandidate = handleIceCandidate;
        // console.log('Created RTCPeerConnnection with:\n' +
        //     '  config: \'' + JSON.stringify(pc_config) + '\';\n' +
        //     '  constraints: \'' + JSON.stringify(pc_constraints) + '\'.');
    } catch (e) {
        console.log('Failed to create PeerConnection, exception: ' + e.message);
        alert('Cannot create RTCPeerConnection object.');
        return;
    }
    pc.onaddstream = handleRemoteStreamAdded;
    pc.onremovestream = handleRemoteStreamRemoved;

    if (isInitiator) {
        try {
            // Create a reliable data channel
            sendChannel = pc.createDataChannel("sendDataChannel",
              {reliable: true});
            //console.log('Created sendChannel' , sendChannel);
            trace('Created send data channel');
        } catch (e) {
            alert('Failed to create data channel. ');
            trace('createDataChannel() failed with exception: ' + e.message);
        }
        sendChannel.onopen = handleSendChannelStateChange;
        sendChannel.onmessage = handleMessage;
        sendChannel.onclose = handleSendChannelStateChange;
    } else { // Joiner
        pc.ondatachannel = gotReceiveChannel;
    }

   // game.startCommunication();
}

// Data channel management
function sendData(data) {
    if(isInitiator) sendChannel.send(data);
    else receiveChannel.send(data);
    trace('Sent data: ' + data);
    //console.log('data:', data, typeof(data));
}

// Handlers...

function gotReceiveChannel(event) {
    trace('Receive Channel Callback');
    receiveChannel = event.channel;
    receiveChannel.onmessage = handleMessage;
    receiveChannel.onopen = handleReceiveChannelStateChange;
    receiveChannel.onclose = handleReceiveChannelStateChange;
}

function handleMessage(event) {
    trace('Received message: ' + event.data);
    game.receiveFromOpponent(event.data);
}

function handleSendChannelStateChange() {
    var readyState = sendChannel.readyState;
    trace('Send channel state is: ' + readyState);
    // If channel ready, enable user's input
    if (readyState == "open") {
        game.startCommunication();
        // dataChannelSend.disabled = false;
        // dataChannelSend.focus();
        // dataChannelSend.placeholder = "";
    } else {
        //dataChannelSend.disabled = true;
    }
}

function handleReceiveChannelStateChange() {
    var readyState = receiveChannel.readyState;
    trace('Receive channel state is: ' + readyState);
    // If channel ready, enable user's input
    if (readyState == "open") {
        game.startCommunication();
        // dataChannelSend.disabled = false;
        // dataChannelSend.focus();
        // dataChannelSend.placeholder = "";
    } else {
        // dataChannelSend.disabled = true;
    }
}

// ICE candidates management
function handleIceCandidate(event) {
    //console.log('handleIceCandidate event: ', event);
    if (event.candidate) {
        sendMessage({
            type: 'candidate',
            label: event.candidate.sdpMLineIndex,
            id: event.candidate.sdpMid,
            candidate: event.candidate.candidate});
    } else {
        //console.log('End of candidates.');
    }
}

// Create Offer
function doCall() {
    console.log('Creating Offer...');
    pc.createOffer(setLocalAndSendMessage, onSignalingError, sdpConstraints);
}

// Signalling error handler
function onSignalingError(error) {
    console.log('Failed to create signaling message : ' + error.name);
}

// Create Answer
function doAnswer() {
    console.log('Sending answer to peer.');
    pc.createAnswer(setLocalAndSendMessage, onSignalingError, sdpConstraints);
}

// Success handler for both createOffer()
// and createAnswer()
function setLocalAndSendMessage(sessionDescription) {
    pc.setLocalDescription(sessionDescription);
    sendMessage(sessionDescription);
}

/////////////////////////////////////////////////////////
// Remote stream handlers...

function handleRemoteStreamAdded(event) {
    console.log('Remote stream added.');
    attachMediaStream(remoteVideo, event.stream);
    remoteStream = event.stream;
}

function handleRemoteStreamRemoved(event) {
    console.log('Remote stream removed. Event: ', event);
}
/////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////
// Clean-up functions...

function hangup() {
    console.log('Hanging up.');
    stop();
    sendMessage('bye');
}

function handleRemoteHangup() {
    console.log('Session terminated.');
    stop();
    isInitiator = false;
    remoteVideo.src = "";
}

function stop() {
    isStarted = false;
    if (pc) pc.close();
    pc = null;
}

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

<|endoftext|>


<commit_before>
"use strict";

var todosList;
var oldList;
var sleepycounter = 0;
var justChanged;
var fading;
var backgroundImage, backgroundOpacity;

$(document).ready(function () {

	if ($('#inputDeadline').length) {
		$.datetimepicker.setLocale('en');
		$('#inputDeadline').datetimepicker();
	}

	if ($("#tasksTable").length) {
		getTasks();
		sortTable();
	}

	getPrefs();

	$('#btnSubmit').click(function () {
		justChanged = $('#inputCourseCode').val() + " " + $('#inputTask').val();
		addTask($('#inputCourseCode').val(), $('#inputTask').val(), $('#inputDeadline').val(), $('#inputWeight').val() / 100);
	});

	$('#prefslink').click(function () {
		$('#prefs').show();
		$('#bigbkgdiv').show();
		$('#inputBkgURL').val(backgroundImage);
		$('#inputOpacity').val(backgroundOpacity);
	});

	$('#btnPrefSubmit').click(function () {
		$('#prefs').hide();
		$('#bigbkgdiv').hide();
		$.ajax({
			url: 'setPrefs',
			type: 'POST',
			data: {
				BkgURL: $('#inputBkgURL').val(),
				inputOpacity: $('#inputOpacity').val()
			},
			success: function (result) {
				if (result) {
					getPrefs();
				}
			},
			timeout: function () {
				console.log("setPrefs: timeout");
			},
			error: function (error) {
				console.log("setPrefs: error", error);
			}
		});
	});

	// Updates
	var updateLoop = setInterval(function () {
		if (todosList) {
			oldList = todosList;
			if (todosList === oldList && sleepycounter < 6) {
				// Every five minutes, update the table order and the priorities
				console.log("Just updating the numbers");
				updateTables(todosList);
				sleepycounter++;
			} else {
				// Every half hour, poll the server
				console.log("Updating the list");
				sleepycounter = 0;
				getTasks();
			}
		}
	}, 300000);
});

function jsDateToExcelDate(inDate) {
	var returnDateTime = 25569.0 + ((inDate.getTime() - (inDate.getTimezoneOffset() * 60 * 1000)) / (1000 * 60 * 60 * 24));
	return returnDateTime.toString().substr(0, 20);
}

function getTasks() {
	$.ajax({
		url: 'getTasks',
		type: 'POST',
		data: {
			gettasks: "get tasks"
		},
		success: function (result) {
			if (result) {
				todosList = result;
				updateTables(todosList);
			}
		},
		timeout: function () {
			console.log("Timeout");
			updateTables(todosList);
		},
		error: function (error) {
			console.log("Error", error);
			updateTables(todosList);
		}
	});
}

function getPrefs() {
	$.ajax({
		url: 'getPrefs',
		type: 'POST',
		data: {
			gettasks: "get prefs"
		},
		success: function (result) {
			if (result) {
				backgroundImage = result[0].backgroundURL;
				backgroundOpacity = result[0].backgroundOpacity;
				$('body').css('background', 'url('+backgroundImage+') no-repeat left top');
				$('body').css('background-size', 'cover');
				$('#content').css('background-color', 'rgba(255, 255, 255, '+backgroundOpacity+')');
				console.log(result);
			}
		},
		timeout: function () {
			console.log("getPrefs: timeout");
		},
		error: function (error) {
			console.log("getPrefs: error", error);
		}
	});
}

function updateTables(result) {
	var len = result.length;
	var currentText, completedText, priority, style, weight, dueDate, isCompleted, completedButton, priorityColumn, string;
	var rightNow = new Date();
	var rightNowPlusSeven = rightNow.addDays(7);
	var rightNowPlusFourteen = rightNow.addDays(14);
	if (len > 0) {
		for (var i = 0; i < len; i++) {
			if (result[i].coursecode && result[i].task && result[i].deadline && result[i].weight) {
				result[i].deadline = new Date(result[i].deadline);
				dueDate = new Date(result[i].deadline);
				weight = parseFloat(result[i].weight * 100).toFixed(1);
				priority = (result[i].weight / (jsDateToExcelDate(result[i].deadline) - jsDateToExcelDate(rightNow))) * 100;
				priority = parseFloat(priority).toFixed(2);
				if (priority < 0 || result[i].completed) {
					isCompleted = true;
				} else {
					isCompleted = false;
				}
				if (isCompleted === false) {
					completedButton = '';
					priorityColumn = '' + priority + '	'
					if (dueDate && dueDate < rightNowPlusSeven) {
						style = ' style="background-color: red;"';
					} else if (dueDate && dueDate < rightNowPlusFourteen) {
						style = ' style="background-color: yellow;"';
					} else {
						style = "";
					}
				} else { // If the task is completed
					completedButton = '';
					priorityColumn = '';
					style = "";
				}
				string = '
' + completedButton + '	' + result[i].coursecode + '	' + result[i].task + '	' + moment(dueDate).format("ddd") + '	' + moment(dueDate).format("D") + '	' + moment(dueDate).format("MMM,") + '	' + moment(dueDate).format("h:mm A") + '	' + weight + '%	' + priorityColumn + '
';

				if (isCompleted === false) {
					currentText += string;
				} else {
					completedText += string;
				}
			}
		}
		if (currentText !== "") {
			$("#tasksTable").find("tr:gt(0)").remove();
			$("#tasksTable").append(currentText);
			sortTable();
		}
		if (completedText !== "") {
			$("#completedTable").find("tr:gt(0)").remove();
			$("#completedTable").append(completedText);
		}
	}
}

function sortTable() {
	var tbl = document.getElementById("tasksTable").tBodies[0];
	var store = [],
		len;
	for (var i = 0, len = tbl.rows.length; i < len; i++) {
		var row = tbl.rows[i];
		var sortnr = parseFloat(row.cells[8].textContent || row.cells[8].innerText);
		if (!isNaN(sortnr)) store.push([sortnr, row]);
	}
	store.sort(function (y, x) {
		return x[0] - y[0];
	});
	for (var j = 0, len = store.length; j < len; j++) {
		tbl.appendChild(store[j][1]);
	}
	store = null;
	var tableWidth = $("#tasksTable").width;
	$("#content").width(tableWidth);
}

function addTask(coursecode, task, deadline, weight) {
	$.ajax({
		url: 'addTask',
		type: 'POST',
		data: {
			'coursecode': coursecode,
			'task': task,
			'deadline': deadline,
			'weight': weight
		},
		success: function (result) {
			getTasks();
			showToast("Task " + justChanged + " added.");
		},
		timeout: function () {
			showToast("Task could not be added. Server did not respond.");
		},
		error: function (error) {
			console.log(error);
			showToast("Task could not be added. Server gave an error.");
		}
	});
}

function deleteItem(id) {
	var t = $("#" + id);
	var undo = ' Undo';
	justChanged = t.next().text() + " " + t.next().next().text();
	$.ajax({
		url: 'deleteTask',
		type: 'POST',
		data: {
			'delID': id
		},
		success: function (result) {
			if (result) {
				getTasks();
				showToast("Task " + justChanged + " deleted.", undo);
			}
		},
		timeout: function () {
			showToast("Task could not be deleted. Server did not respond.");
		},
		error: function (error) {
			console.log(error);
			showToast("Task could not be deleted. Server gave an error.");
		}
	});
}

function completeItem(id) {
	$.ajax({
		url: 'completeTask',
		type: 'POST',
		data: {
			'complID': id
		},
		success: function (result) {
			if (result) {
				getTasks();
			}
		},
		timeout: function () {
			showToast("Task could not be marked as complete. Server did not respond.");
		},
		error: function (error) {
			console.log(error);
			showToast("Task could not be marked as complete. Server gave an error.");
		}
	});
}

Date.prototype.addDays = function (days) {
	var dat = new Date(this.valueOf());
	dat.setDate(dat.getDate() + days);
	return dat;
};

var fadeToast = function () {
	$("#toast").empty();
	$("#toast").hide();
};

function showToast(text, action) {
	clearTimeout(fading);
	$("#toast").text(text);
	if (action) {
		var oldHTML = $("#toast").html();
		$("#toast").html(oldHTML + action);
	}
	$("#toast").show();
	$("#toast").css('background-color', 'pink');
	fading = setTimeout(fadeToast, 8000);
}<commit_msg>Also poll the server for preferences updates<commit_after><|endoftext|>


<commit_before>var sourceURLctr = 1;

var getPreparedCode = (function () {

  var consoleTest = /(^.|\b)console\./,
      re = {
        docReady: /\$\(document\)\.ready/,
        shortDocReady: /\$\(function/,
        console: /(^.|\b)console\.(\S+)/g,
        script: /<\/script/ig,
        code: /%code%/,
        csscode: /%css%/,
        title: /<title>(.*)<\/title>/i,
        winLoad: /window\.onload\s*=/,
        scriptopen: /\n" + close;
    }

    // reapply the same proxyConsole - but to all the source code, since
    if (re.console.test(source)) {
      var replaceWith = 'window.runnerWindow.proxyConsole.';
      // yes, this code looks stupid, but in fact what it does is look for
      // 'console.' and then checks the position of the code. If it's inside
      // an openning script tag, it'll change it to window.top._console,
      // otherwise it'll leave it.
      source = source.replace(re.console, function (all, str, arg, pos) {
        var open = source.lastIndexOf(' close) {
          return replaceWith + arg;
        } else {
          return all;
        }
      });
    }

    if (!hasHTML && !hasJS && hasCSS) {
      source = "
\n" + css.replace(/[<>&]/g, function (m) {
            if (m == '<') return '<';
            if (m == '>') return '>';
            if (m == '"') return '"';
          }) + "
";
    } else if (re.csscode.test(source)) {
      parts = source.split('%css%');
      source = parts[0] + css + parts[1];
    } else if (css && hasHTML) {
      parts = [];
      close = '';
      if (source.indexOf('') !== -1) {
        parts.push(source.substring(0, source.lastIndexOf('')));
        parts.push(source.substring(source.lastIndexOf('')));

        source = parts[0];
        close = parts.length == 2 && parts[1] ? parts[1] : '';
      }
      source += '\n' + close;
    }

    // Add defer to all inline script tags in IE.
    // This is because IE runs scripts as it loads them, so variables that
    // scripts like jQuery add to the global scope are undefined.
    // See http://jsbin.com/ijapom/5
    if (jsbin.ie && re.scriptopen.test(source)) {
      source = source.replace(/\n" + close;
    }

    // reapply the same proxyConsole - but to all the source code, since
    if (re.console.test(source)) {
      var replaceWith = 'window.runnerWindow.proxyConsole.';
      // yes, this code looks stupid, but in fact what it does is look for
      // 'console.' and then checks the position of the code. If it's inside
      // an openning script tag, it'll change it to window.top._console,
      // otherwise it'll leave it.
      source = source.replace(re.console, function (all, str, arg, pos) {
        var open = source.lastIndexOf(' close) {
          return replaceWith + arg;
        } else {
          return all;
        }
      });
    }

    if (!hasHTML && !hasJS && hasCSS) {
      source = "
\n" + css.replace(/[<>&]/g, function (m) {
            if (m == '<') return '<';
            if (m == '>') return '>';
            if (m == '"') return '"';
          }) + "
";
    } else if (re.csscode.test(source)) {
      parts = source.split('%css%');
      source = parts[0] + css + parts[1];
    } else if (css && hasHTML) {
      parts = [];
      close = '';
      if (source.indexOf('') !== -1) {
        parts.push(source.substring(0, source.lastIndexOf('')));
        parts.push(source.substring(source.lastIndexOf('')));

        source = parts[0];
        close = parts.length == 2 && parts[1] ? parts[1] : '';
      }
      source += '\n' + close;
    }

    // Add defer to all inline script tags in IE.
    // This is because IE runs scripts as it loads them, so variables that
    // scripts like jQuery add to the global scope are undefined.
    // See http://jsbin.com/ijapom/5
    if (jsbin.ie && re.scriptopen.test(source)) {
      source = source.replace(/


<commit_before>/** ============================================================================
 * JS Bin Runner
 * Accepts incoming postMessage events and updates a live iframe accordingly.
 * ========================================================================== */

var runner = (function () {

  var runner = {};

  /**
   * Store what parent origin *should* be
   */
  runner.parent = {};
  runner.parent.origin = '*';

  /**
   * Log error messages, indicating that it's from the runner.
   */
  runner.error = function () {
    var args = ['Runner:'].concat([].slice.call(arguments));
    if (!('console' in window)) return alert(args.join(' '));
    window.console.error.apply(console, args);
  };

  /**
   * Handle all incoming postMessages to the runner
   */
  runner.handleMessage = function (event) {
    if (!event.origin) return;
    var data = event.data;
    try {
      data = JSON.parse(event.data);
    } catch (e) {
      return runner.error('Error parsing event data:', e.message);
    }
    if (typeof runner[data.type] !== 'function') {
      return runner.error('No matching event handler:', data.type);
    }
    runner.parent.source = event.source;
    try {
      runner[data.type](data.data);
    } catch (e) {
      runner.error(e.message);
    }
  };

  /**
   * Send message to the parent window
   */
  runner.postMessage = function (type, data) {
    if (!runner.parent.source) {
      return runner.error('No postMessage connection to parent window.');
    }
    runner.parent.source.postMessage(JSON.stringify({
      type: type,
      data: data
    }), runner.parent.origin);
  };

  /**
   * Render a new preview iframe using the posted source
   */
  runner.render = function (data) {
    var iframe = sandbox.create(data.options);
    sandbox.use(iframe, function () {
      var childDoc = iframe.contentDocument,
          childWindow = getIframeWindow(iframe);
      if (!childDoc) childDoc = childWindow.document;

      // Process the source according to the options passed in
      var source = processor.render(data.source, data.options);

      // Start writing the page. This will clear any existing document.
      childDoc.open();

      // We need to write a blank line first – Firefox blows away things you add
      // to the child window when you do the fist document.write.
      // Note that each document.write fires a DOMContentLoaded in Firefox.
      // This method exhibits synchronous and asynchronous behavious, depending
      // on the browser. Urg.
      childDoc.write('');

      // Give the child a reference to things it needs. This has to go here so
      // that the user's code (that runs as a result of the following
      // childDoc.write) can access the objects.
      childWindow.runnerWindow = {
        proxyconsole: proxyconsole,
        protect: processor.protect
      };

      // Write the source out. IE crashes if you have lots of these, so that's
      // why the source is rendered above (processor.render) – it should be one
      // string. IE's a sensitive soul.
      childDoc.write(source);

      // Close the document. This will fire another DOMContentLoaded.
      childDoc.close();

      // Setup the new window
      sandbox.wrap(childWindow, data.options);
    });
  };

  /**
   * Run console commands against the iframe's scope
   */
  runner['console:run'] = function (cmd) {
    sandbox.eval(cmd);
  };

  /**
   * Load script into the apge
   */
  runner['console:load:script'] = function (url) {
    sandbox.injectScript(url, function (err) {
      if (err) return runner.postMessage('console:load:script:error', err);
      runner.postMessage('console:load:script:success', url);
    });
  };

  /**
   * Load DOM into the apge
   */
  runner['console:load:dom'] = function (html) {
    sandbox.injectDOM(html, function (err) {
      if (err) return runner.postMessage('console:load:dom:error', err);
      runner.postMessage('console:load:dom:success');
    });
  };

  return runner;

}());<commit_msg>Fix spelling.<commit_after>/** ============================================================================
 * JS Bin Runner
 * Accepts incoming postMessage events and updates a live iframe accordingly.
 * ========================================================================== */

var runner = (function () {

  var runner = {};

  /**
   * Store what parent origin *should* be
   */
  runner.parent = {};
  runner.parent.origin = '*';

  /**
   * Log error messages, indicating that it's from the runner.
   */
  runner.error = function () {
    var args = ['Runner:'].concat([].slice.call(arguments));
    if (!('console' in window)) return alert(args.join(' '));
    window.console.error.apply(console, args);
  };

  /**
   * Handle all incoming postMessages to the runner
   */
  runner.handleMessage = function (event) {
    if (!event.origin) return;
    var data = event.data;
    try {
      data = JSON.parse(event.data);
    } catch (e) {
      return runner.error('Error parsing event data:', e.message);
    }
    if (typeof runner[data.type] !== 'function') {
      return runner.error('No matching event handler:', data.type);
    }
    runner.parent.source = event.source;
    try {
      runner[data.type](data.data);
    } catch (e) {
      runner.error(e.message);
    }
  };

  /**
   * Send message to the parent window
   */
  runner.postMessage = function (type, data) {
    if (!runner.parent.source) {
      return runner.error('No postMessage connection to parent window.');
    }
    runner.parent.source.postMessage(JSON.stringify({
      type: type,
      data: data
    }), runner.parent.origin);
  };

  /**
   * Render a new preview iframe using the posted source
   */
  runner.render = function (data) {
    var iframe = sandbox.create(data.options);
    sandbox.use(iframe, function () {
      var childDoc = iframe.contentDocument,
          childWindow = getIframeWindow(iframe);
      if (!childDoc) childDoc = childWindow.document;

      // Process the source according to the options passed in
      var source = processor.render(data.source, data.options);

      // Start writing the page. This will clear any existing document.
      childDoc.open();

      // We need to write a blank line first – Firefox blows away things you add
      // to the child window when you do the fist document.write.
      // Note that each document.write fires a DOMContentLoaded in Firefox.
      // This method exhibits synchronous and asynchronous behaviour, depending
      // on the browser. Urg.
      childDoc.write('');

      // Give the child a reference to things it needs. This has to go here so
      // that the user's code (that runs as a result of the following
      // childDoc.write) can access the objects.
      childWindow.runnerWindow = {
        proxyconsole: proxyconsole,
        protect: processor.protect
      };

      // Write the source out. IE crashes if you have lots of these, so that's
      // why the source is rendered above (processor.render) – it should be one
      // string. IE's a sensitive soul.
      childDoc.write(source);

      // Close the document. This will fire another DOMContentLoaded.
      childDoc.close();

      // Setup the new window
      sandbox.wrap(childWindow, data.options);
    });
  };

  /**
   * Run console commands against the iframe's scope
   */
  runner['console:run'] = function (cmd) {
    sandbox.eval(cmd);
  };

  /**
   * Load script into the apge
   */
  runner['console:load:script'] = function (url) {
    sandbox.injectScript(url, function (err) {
      if (err) return runner.postMessage('console:load:script:error', err);
      runner.postMessage('console:load:script:success', url);
    });
  };

  /**
   * Load DOM into the apge
   */
  runner['console:load:dom'] = function (html) {
    sandbox.injectDOM(html, function (err) {
      if (err) return runner.postMessage('console:load:dom:error', err);
      runner.postMessage('console:load:dom:success');
    });
  };

  return runner;

}());<|endoftext|>


<commit_before>define(['./index', 'cryptoJS'], function (services) {
  'use strict';
  // expand input and show post button on focus
  services.service('authService', ['$q', '$http', '$firebase', function($q, $http, $firebase) {
    var ref = new Firebase('https://crackling-fire-2064.firebaseio.com/auth'),
        usersDB = $firebase(ref);

    return {
        register: function(user) {
            var deferred = $q.defer(),
                keys = usersDB.$getIndex();

            // first, make sure username is not taken
            for(var i = 0; i < keys.length; i++) {
                if(usersDB[keys[i]].username.toLowerCase() === user.username) {
                    deferred.reject("That username is already taken.");
                    return deferred.promise;
                }
            }

            // create salt, hash password, and create user object
            var salt = CryptoJS.lib.WordArray.random(128/8),
                passKeyHash = CryptoJS.PBKDF2(user.password, salt, { keySize: 512/32, iterations: 1000 }).toString(CryptoJS.enc.Base64),
                newUser = {
                    username: user.username,
                    salt: salt,
                    hash: passKeyHash
                };

            // save new user in database
            usersDB.$add(newUser).then(function() {
                deferred.resolve();
                return deferred.promise;
            })

            return deferred.promise;
        },
        login: function(user) {
            var deferred = $q.defer(),
                keys = usersDB.$getIndex();

            user.username = user.username.toLowerCase();

            for(var i = 0; i < keys.length; i++) {
                // find user with matching usename
                if(usersDB[keys[i]].username.toLowerCase() === user.username) {
                    var passKeyHash = CryptoJS.PBKDF2(user.password, usersDB[keys[i]].salt, { keySize: 512/32, iterations: 1000 }).toString(CryptoJS.enc.Base64);
                    // hash password and check for match
                    if(passKeyHash === usersDB[keys[i]].hash) {
                        var validUser = angular.copy(usersDB[keys[i]]);
                        delete validUser.salt;
                        delete validUser.hash;

                        deferred.resolve(validUser);
                        return deferred.promise;
                    }
                    else {
                        deferred.reject("That password is incorrect.");
                    }
                }
            }

            deferred.reject("That user does not exist.");
            return deferred.promise;
        }
    };
  }]);
});<commit_msg>index users in database by username<commit_after>define(['./index', 'cryptoJS'], function (services) {
  'use strict';
  // expand input and show post button on focus
  services.service('authService', ['$q', '$http', '$firebase', function($q, $http, $firebase) {
    var ref = new Firebase('https://crackling-fire-2064.firebaseio.com/auth'),
        usersDB = $firebase(ref);

    return {
        register: function(user) {
            var deferred = $q.defer(),
                keys = usersDB.$getIndex();

            // first, make sure username is not taken
            for(var i = 0; i < keys.length; i++) {
                if(usersDB[keys[i]].username.toLowerCase() === user.username) {
                    deferred.reject("That username is already taken.");
                    return deferred.promise;
                }
            }

            // create salt, hash password, and create user object
            var salt = CryptoJS.lib.WordArray.random(128/8),
                passKeyHash = CryptoJS.PBKDF2(user.password, salt, { keySize: 512/32, iterations: 1000 }).toString(CryptoJS.enc.Base64),
                newUser = {
                    username: user.username,
                    salt: salt,
                    hash: passKeyHash
                };

            // save new user in database
            usersDB[newUser.username] = newUser;
            usersDB.$save(newUser.username).then(function(ref) {
                deferred.resolve(ref);
            });

            return deferred.promise;
        },
        login: function(user) {
            var deferred = $q.defer(),
                keys = usersDB.$getIndex();

            user.username = user.username.toLowerCase();

            for(var i = 0; i < keys.length; i++) {
                // find user with matching usename
                if(usersDB[keys[i]].username.toLowerCase() === user.username) {
                    var passKeyHash = CryptoJS.PBKDF2(user.password, usersDB[keys[i]].salt, { keySize: 512/32, iterations: 1000 }).toString(CryptoJS.enc.Base64);
                    // hash password and check for match
                    if(passKeyHash === usersDB[keys[i]].hash) {
                        var validUser = angular.copy(usersDB[keys[i]]);
                        delete validUser.salt;
                        delete validUser.hash;

                        deferred.resolve(validUser);
                        return deferred.promise;
                    }
                    else {
                        deferred.reject("That password is incorrect.");
                    }
                }
            }

            deferred.reject("That user does not exist.");
            return deferred.promise;
        }
    };
  }]);
});<|endoftext|>


<commit_before>import sm from "sitemap";
import OperationConfig from "../../core/config/MetaConfig.js";

/**
 * Generates an XML sitemap for all CyberChef operations and a number of recipes.
 *
 * @author n1474335 [n1474335@gmail.com]
 * @copyright Crown Copyright 2018
 * @license Apache-2.0
 */

const sitemap = sm.createSitemap({
    hostname: "https://gchq.github.io/CyberChef",
});

sitemap.add({
    url: "/",
    changefreq: "weekly",
    priority: 1.0
});

for (let op in OperationConfig) {
    sitemap.add({
        url: `/#op=${encodeURIComponent(op)}`,
        changeFreq: "yearly",
        priority: 0.5
    });
}

const xml = sitemap.toString();

console.log(xml); // eslint-disable-line no-console
<commit_msg>Changed fragment to query in sitemap<commit_after>import sm from "sitemap";
import OperationConfig from "../../core/config/MetaConfig.js";

/**
 * Generates an XML sitemap for all CyberChef operations and a number of recipes.
 *
 * @author n1474335 [n1474335@gmail.com]
 * @copyright Crown Copyright 2018
 * @license Apache-2.0
 */

const sitemap = sm.createSitemap({
    hostname: "https://gchq.github.io/CyberChef",
});

sitemap.add({
    url: "/",
    changefreq: "weekly",
    priority: 1.0
});

for (let op in OperationConfig) {
    sitemap.add({
        url: `/?op=${encodeURIComponent(op)}`,
        changeFreq: "yearly",
        priority: 0.5
    });
}

const xml = sitemap.toString();

console.log(xml); // eslint-disable-line no-console
<|endoftext|>


<commit_before>$(function () {

  var sum = function () {
    var that = $(this),
        index = that.data("player-index"),
        row = that.parents("tr"),
        prev = parseInt(row.prev().find(".g2000n-player-" + index).val(), 10),
        preprev = parseInt(row.prev().prev().find(".g2000n-player-" + index).val(), 10);
    if (!isNaN(prev) && !isNaN(preprev)) {
      that.val(prev + preprev);
      that.parent().toggleClass("has-success", prev + preprev >= 2000);
    } else {
      that.val("");
    }
  };

  $(".g2000n-value").change(function () {
    $(".g2000n-sum.g2000n-player-" + $(this).data("player-index")).each(sum);
  }).trigger("change");

  /* Fixed headers in table; */
  $('table.table').floatThead({
    useAbsolutePositioning: false,
    scrollingTop: 50
  });

  /* Confirm leaving page; */
  function onbeforeunload() {
    return "You are about to navigate away from this page.\n\nIf you leave this page all scrores that you have entered will be lost!\n\nUse the save button to save all scores."
  }
  $(".g2000n-save").click(function () {
    window.onbeforeunload = null;
  });
  $(".g2000n-value").change(function () {
    window.onbeforeunload = onbeforeunload;
  });

});
<commit_msg>Fixed floating header after showing alert;<commit_after>$(function () {

  var sum = function () {
    var that = $(this),
        index = that.data("player-index"),
        row = that.parents("tr"),
        prev = parseInt(row.prev().find(".g2000n-player-" + index).val(), 10),
        preprev = parseInt(row.prev().prev().find(".g2000n-player-" + index).val(), 10);
    if (!isNaN(prev) && !isNaN(preprev)) {
      that.val(prev + preprev);
      that.parent().toggleClass("has-success", prev + preprev >= 2000);
    } else {
      that.val("");
    }
  };

  $(".g2000n-value").change(function () {
    $(".g2000n-sum.g2000n-player-" + $(this).data("player-index")).each(sum);
  }).trigger("change");

  /* Fixed headers in table; */
  var floatThead = $("table.table").floatThead({
    useAbsolutePositioning: false,
    scrollingTop: 50
  });
  $(".alert").on("closed.bs.alert", function () {
    floatThead.floatThead("reflow");
  });

  /* Confirm leaving page; */
  function onbeforeunload() {
    return "You are about to navigate away from this page.\n\nIf you leave this page all scrores that you have entered will be lost!\n\nUse the save button to save all scores."
  }
  $(".g2000n-save").click(function () {
    window.onbeforeunload = null;
  });
  $(".g2000n-value").change(function () {
    window.onbeforeunload = onbeforeunload;
  });

});
<|endoftext|>


<commit_before>(function() {

    /**
     * Backbone Forms File editor
     * @requires fancy-file
     */
    Backbone.Form.editors.File = Backbone.Form.editors.Base.extend({

        tagName: 'div',

        defaultValue: '',

        initialize: function(options) {
            this.$el.addClass('file');
            this.value = this.model.get(options.key);
            //this._dayLabels = options.schema.dayLabels;
            //this._dayPeriodLabels = options.schema.dayPeriodLabels;

            // taken from: https://developer.mozilla.org/en-US/docs/Web/API/FileReader?redirectlocale=en-US&redirectslug=DOM%2FFileReader#readAsDataURL%28%29
            this.oFReader = new FileReader();
            this.rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;
        },

        /**
         * Adds the editor to the DOM
         */
        render: function() {
            this.$el.html(
                '' +
                '<input name="upload" type="file" data-toggle="fancyfile" data-placeholder="Select a file..." data-text="Uplaod">'
            );
            $('[type="file"]', this.$el).fancyfile();
            if (this.value) {
                $('.image-preview', this.$el).attr('src', '/api/fs.file/' + this.value);
            }
            this.setValue(this.value);
            this._delegateEvents();

            return this;
        },

        _delegateEvents: function () {
            var editor = this;

            editor.oFReader.onload = function (oFREvent) {
                $('.image-preview', editor.$el).attr('src', oFREvent.target.result);
            };

            $('[type="file"]', editor.$el).on('change', function (event) {
                if (this.files.length === 0) { return; }
                var oFile = this.files[0];
                // only in the case of images... TODO
                if (!editor.rFilter.test(oFile.type)) { alert("You must select a valid image file!"); return; }

                editor.oFReader.readAsDataURL(oFile);

                //---
                var xhr = new XMLHttpRequest();
                xhr.open('POST', '/api/fs.file');

                xhr.upload.onprogress = function (e) {
                     console.log(e.loaded + ' of ' + e.total);
                };

                xhr.onload = function (xhr) {
                    var response = JSON.parse(arguments[0].currentTarget.response);
                    editor.setValue(response);
                };

                var form = new FormData();
                form.append('title', this.files[0].name);
                form.append('picture', this.files[0]);
                xhr.send(form);
                //---
            });

        },

        /**
         * Returns the current editor value
         * @return {String}
         */
        getValue: function() {
            // set the file object w/ObjectId
            return this.value;
        },

        /**
         * Sets the value of the form element
         * @param {String}
         */
        setValue: function(value) {
            // set the file object w/ObjectId
            this.value = value;
        }

    });

}());
<commit_msg>fixing file editor style issues<commit_after>(function() {

    /**
     * Backbone Forms File editor
     * @requires fancy-file
     */
    Backbone.Form.editors.File = Backbone.Form.editors.Base.extend({

        tagName: 'div',

        defaultValue: '',

        initialize: function(options) {
            this.$el.addClass('control-group');
            this.value = this.model.get(options.key);
            //this._dayLabels = options.schema.dayLabels;
            //this._dayPeriodLabels = options.schema.dayPeriodLabels;

            // taken from: https://developer.mozilla.org/en-US/docs/Web/API/FileReader?redirectlocale=en-US&redirectslug=DOM%2FFileReader#readAsDataURL%28%29
            this.oFReader = new FileReader();
            this.rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;
        },

        /**
         * Adds the editor to the DOM
         */
        render: function() {
            var editor = this;
            this.$el.html(
                '' +
                '<input name="upload" type="file" data-toggle="fancyfile" />'
            );
            setTimeout(function () { // once appended to the DOM
                $('[type="file"]', editor.$el).fancyfile({
                    text  : 'Uplaod',
                    icon  : '',
                    style : 'btn-info',
                    placeholder : 'Select File…'
                });
            }, 200)
            if (this.value) {
                $('.image-preview', this.$el).attr('src', '/api/fs.file/' + this.value);
            }
            this.setValue(this.value);
            this._delegateEvents();

            return this;
        },

        _delegateEvents: function () {
            var editor = this;

            editor.oFReader.onload = function (oFREvent) {
                $('.image-preview', editor.$el).attr('src', oFREvent.target.result);
            };

            $('[type="file"]', editor.$el).on('change', function (event) {
                if (this.files.length === 0) { return; }
                var oFile = this.files[0];
                // only in the case of images... TODO
                if (!editor.rFilter.test(oFile.type)) { alert("You must select a valid image file!"); return; }

                editor.oFReader.readAsDataURL(oFile);

                //---
                var xhr = new XMLHttpRequest();
                xhr.open('POST', '/api/fs.file');

                xhr.upload.onprogress = function (e) {
                     console.log(e.loaded + ' of ' + e.total);
                };

                xhr.onload = function (xhr) {
                    var response = JSON.parse(arguments[0].currentTarget.response);
                    editor.setValue(response);
                };

                var form = new FormData();
                form.append('title', this.files[0].name);
                form.append('picture', this.files[0]);
                xhr.send(form);
                //---
            });

        },

        /**
         * Returns the current editor value
         * @return {String}
         */
        getValue: function() {
            // set the file object w/ObjectId
            return this.value;
        },

        /**
         * Sets the value of the form element
         * @param {String}
         */
        setValue: function(value) {
            // set the file object w/ObjectId
            this.value = value;
        }

    });

}());
<|endoftext|>


<commit_before>'use strict';

describe('Action tests', function() {

  it('List action', function() {
    browser.get('#/action');

    var actions = element.all(by.repeater('action in actions'));
    expect(actions.count()).toEqual(3);
    expect(actions.get(0).getText()).toEqual('Sql-Fetch-Row');
    expect(actions.get(1).getText()).toEqual('Sql-Fetch-All');
    expect(actions.get(2).getText()).toEqual('Welcome');
  });

  it('Create action', function() {
    browser.get('#/action');

    var EC = protractor.ExpectedConditions;

    $('a.btn-primary').click();

    browser.wait(EC.visibilityOf($('div.modal-body')), 5000);

    element(by.model('action.name')).sendKeys('test-action');

    var actionOptions = element.all(by.options('action.class as action.name for action in actions'));
    expect(actionOptions.get(0).getText()).toEqual('Cache-Response');
    expect(actionOptions.get(1).getText()).toEqual('Composite');
    expect(actionOptions.get(2).getText()).toEqual('Condition');
    expect(actionOptions.get(3).getText()).toEqual('HTTP-Proxy');
    expect(actionOptions.get(4).getText()).toEqual('HTTP-Request');
    expect(actionOptions.get(5).getText()).toEqual('Mongo-Delete');
    expect(actionOptions.get(6).getText()).toEqual('Mongo-Fetch-All');
    expect(actionOptions.get(7).getText()).toEqual('Mongo-Fetch-Row');
    expect(actionOptions.get(8).getText()).toEqual('Mongo-Insert');
    expect(actionOptions.get(9).getText()).toEqual('Mongo-Update');
    expect(actionOptions.get(10).getText()).toEqual('MQ-Amqp');
    expect(actionOptions.get(11).getText()).toEqual('MQ-Beanstalk');
    expect(actionOptions.get(12).getText()).toEqual('Pipe');
    expect(actionOptions.get(13).getText()).toEqual('Processor');
    expect(actionOptions.get(14).getText()).toEqual('SQL-Builder');
    expect(actionOptions.get(15).getText()).toEqual('SQL-Execute');
    expect(actionOptions.get(16).getText()).toEqual('SQL-Fetch-All');
    expect(actionOptions.get(17).getText()).toEqual('SQL-Fetch-Row');
    expect(actionOptions.get(18).getText()).toEqual('Static-Response');
    expect(actionOptions.get(19).getText()).toEqual('Transform');
    expect(actionOptions.get(20).getText()).toEqual('Try-Catch');
    expect(actionOptions.get(21).getText()).toEqual('Validator');

    actionOptions.get(18).click();

    browser.wait(EC.visibilityOf($('#config-statusCode')), 5000);

    element(by.cssContainingText('#config-statusCode option', 'OK')).click();
    element(by.css('textarea.ace_text-input')).sendKeys('{"foo": "bar"}');

    $('button.btn-primary').click();

    browser.wait(EC.visibilityOf($('div.alert-success')), 5000);

    expect($('div.alert-success > div').getText()).toEqual('Action successful created');
  });

  it('Update action', function() {
    browser.get('#/action');

    var EC = protractor.ExpectedConditions;

    element.all(by.css('div.fusio-options a:nth-child(1)')).first().click();

    browser.wait(EC.visibilityOf($('div.modal-body')), 5000);

    expect(element(by.model('action.name')).getAttribute('value')).toEqual('test-action');
    expect(element(by.model('action.class')).getAttribute('value')).toEqual('Fusio\\Impl\\Action\\StaticResponse');

    browser.wait(EC.visibilityOf($('#config-statusCode')), 5000);

    expect(element(by.model('action.config.statusCode')).getAttribute('value')).toEqual('200');

    $('button.btn-primary').click();

    browser.wait(EC.visibilityOf($('div.alert-success')), 5000);

    expect($('div.alert-success > div').getText()).toEqual('Action successful updated');
  });

  it('Delete action', function() {
    browser.get('#/action');

    var EC = protractor.ExpectedConditions;

    element.all(by.css('div.fusio-options a:nth-child(2)')).first().click();

    browser.wait(EC.visibilityOf($('div.modal-body')), 5000);

    expect(element(by.model('action.name')).getAttribute('value')).toEqual('test-action');

    $('button.btn-primary').click();

    browser.wait(EC.visibilityOf($('div.alert-success')), 5000);

    expect($('div.alert-success > div').getText()).toEqual('Action successful deleted');
  });

});
<commit_msg>fix action test<commit_after>'use strict';

describe('Action tests', function() {

  it('List action', function() {
    browser.get('#/action');

    var actions = element.all(by.repeater('action in actions'));
    expect(actions.count()).toEqual(3);
    expect(actions.get(0).getText()).toEqual('Sql-Fetch-Row');
    expect(actions.get(1).getText()).toEqual('Sql-Fetch-All');
    expect(actions.get(2).getText()).toEqual('Welcome');
  });

  it('Create action', function() {
    browser.get('#/action');

    var EC = protractor.ExpectedConditions;

    $('a.btn-primary').click();

    browser.wait(EC.visibilityOf($('div.modal-body')), 5000);

    element(by.model('action.name')).sendKeys('test-action');

    var actionOptions = element.all(by.options('action.class as action.name for action in actions'));
    expect(actionOptions.get(0).getText()).toEqual('Cache-Response');
    expect(actionOptions.get(1).getText()).toEqual('Composite');
    expect(actionOptions.get(2).getText()).toEqual('Condition');
    expect(actionOptions.get(3).getText()).toEqual('HTTP-Proxy');
    expect(actionOptions.get(4).getText()).toEqual('HTTP-Request');
    expect(actionOptions.get(5).getText()).toEqual('Mongo-Delete');
    expect(actionOptions.get(6).getText()).toEqual('Mongo-Fetch-All');
    expect(actionOptions.get(7).getText()).toEqual('Mongo-Fetch-Row');
    expect(actionOptions.get(8).getText()).toEqual('Mongo-Insert');
    expect(actionOptions.get(9).getText()).toEqual('Mongo-Update');
    expect(actionOptions.get(10).getText()).toEqual('MQ-Amqp');
    expect(actionOptions.get(11).getText()).toEqual('MQ-Beanstalk');
    expect(actionOptions.get(12).getText()).toEqual('Pipe');
    expect(actionOptions.get(13).getText()).toEqual('Processor');
    expect(actionOptions.get(14).getText()).toEqual('SQL-Builder');
    expect(actionOptions.get(15).getText()).toEqual('SQL-Execute');
    expect(actionOptions.get(16).getText()).toEqual('SQL-Fetch-All');
    expect(actionOptions.get(17).getText()).toEqual('SQL-Fetch-Row');
    expect(actionOptions.get(17).getText()).toEqual('SQL-Table');
    expect(actionOptions.get(18).getText()).toEqual('Static-Response');
    expect(actionOptions.get(19).getText()).toEqual('Transform');
    expect(actionOptions.get(20).getText()).toEqual('Try-Catch');
    expect(actionOptions.get(21).getText()).toEqual('Validator');

    actionOptions.get(18).click();

    browser.wait(EC.visibilityOf($('#config-statusCode')), 5000);

    element(by.cssContainingText('#config-statusCode option', 'OK')).click();
    element(by.css('textarea.ace_text-input')).sendKeys('{"foo": "bar"}');

    $('button.btn-primary').click();

    browser.wait(EC.visibilityOf($('div.alert-success')), 5000);

    expect($('div.alert-success > div').getText()).toEqual('Action successful created');
  });

  it('Update action', function() {
    browser.get('#/action');

    var EC = protractor.ExpectedConditions;

    element.all(by.css('div.fusio-options a:nth-child(1)')).first().click();

    browser.wait(EC.visibilityOf($('div.modal-body')), 5000);

    expect(element(by.model('action.name')).getAttribute('value')).toEqual('test-action');
    expect(element(by.model('action.class')).getAttribute('value')).toEqual('Fusio\\Impl\\Action\\StaticResponse');

    browser.wait(EC.visibilityOf($('#config-statusCode')), 5000);

    expect(element(by.model('action.config.statusCode')).getAttribute('value')).toEqual('200');

    $('button.btn-primary').click();

    browser.wait(EC.visibilityOf($('div.alert-success')), 5000);

    expect($('div.alert-success > div').getText()).toEqual('Action successful updated');
  });

  it('Delete action', function() {
    browser.get('#/action');

    var EC = protractor.ExpectedConditions;

    element.all(by.css('div.fusio-options a:nth-child(2)')).first().click();

    browser.wait(EC.visibilityOf($('div.modal-body')), 5000);

    expect(element(by.model('action.name')).getAttribute('value')).toEqual('test-action');

    $('button.btn-primary').click();

    browser.wait(EC.visibilityOf($('div.alert-success')), 5000);

    expect($('div.alert-success > div').getText()).toEqual('Action successful deleted');
  });

});
<|endoftext|>


<commit_before>/**
 * 所有mixins需要在mounted之前创建Object3d对象
 */
export default {
    name: "Object3d",
    props: {
        inTree: {type: Boolean, default: true}, // 是否挂载在树节点上。当设置为false时直接挂载在scene根节点上
        position: {
            type: Object,
            default: () => {
                return {x: 0, y: 0, z: 0}
            }
        },
        rotation: {
            type: Object,
            default: () => {
                return {x: 0, y: 0, z: 0}
            }
        },
        scale: {
            type: Object,
            default: () => {
                return {x: 1, y: 1, z: 1}
            }
        },
        target: {
            type: Object,
            default: () => {
                return {x: 0, y: 0, z: 0}
            }
        },
        name: {
            type: String,
        }
    },
    data() {
        return {
            vue3d: null, // Vue3D component
            scene: null, // mounted scene
            object3d: null, // 当前三维对象
            parent: null, // 父级三维对象
            slot: false, // 是否挂载子节点
            visible: true, // 是否可见
        }
    },
    created() {
        if (!this.$parent) {
            console.error(this.$options.name + " must slot in Vue3D-Component");
            return;
        }
        // check Vue3D component parent
        if (!this.parent) {
            this._recursion(this.$parent)
        }
    },
    mounted() {
        this.vue3d.on("update", this.render);
        if (this.object3d) this.init();
    },
    updated() {
        this.render();
    },
    beforeDestroy() {
        this.onDestroy();
        this.slotOut();
        this._removeObject3d(this.object3d);
    },
    methods: {
        init() {
            this.object3d.vue3d = this;
            this.object3d.name = this.name || this.$options.name;
            this.setPosition();
            this.setRotation();
            this.setScale();
            this.setTarget();
            this._addObject3d(this.object3d);
            this.slotIn();
            this.onReady();
            this.render();
        },
        // 根据vue组件递归查询scene节点
        _recursion(parent) {
            if (parent.$options.name === 'Vue3d') { // 当前挂载于Vue3D 根节点
                this.scene = parent.scenes.activated();
                this.vue3d = parent;
                this.parent = parent;
            } else if (parent.$options.name === 'V3dScene') { // 当前挂载于 V3dScene 子节点
                this.scene = parent.scene;
                this.vue3d = parent.vue3d;
                this.parent = parent;
            } else if (parent.hasOwnProperty("scene") && parent.hasOwnProperty('object3d')) { // 当前挂载于 其他 子节点
                this.scene = parent.scene;
                this.vue3d = parent.vue3d;
                this.parent = parent;
            } else {
                this._recursion(parent.$parent);
            }
        },
        // 插槽中添加三维对象
        _addObject3d(object3d) {
            if (this.inTree) {
                this.addObject3d(object3d, true);
            } else {
                this.addObject3d(object3d, false);
            }
        },
        // 插槽中移除三位对象
        _removeObject3d(object3d) {
            this.removeObject3d(object3d, true);
        },
        setPosition() {
            this.object3d.position.set(this.position.x, this.position.y, this.position.z);
            this.render();
        },
        setRotation() {
            this.object3d.rotation.set(this.rotation.x, this.rotation.y, this.rotation.z);
            this.render();
        },
        setScale() {
            this.object3d.scale.set(this.scale.x, this.scale.y, this.scale.z);
            this.render();
        },
        setTarget() {
            this.object3d.lookAt(this.target.x, this.target.y, this.target.z);
        },
        addObject3d(object3d, inNode) {
            if (inNode && this.parent.hasOwnProperty('object3d')) {
                this.parent.object3d.add(object3d);
            } else {
                this.scene.add(object3d);
            }
        },
        removeObject3d(object3d, inNode) {
            if (inNode && this.parent.hasOwnProperty('object3d')) {
                this.parent.object3d.remove(object3d);
            } else {
                this.removeObject3d(object3d);
            }
            this.vue3d.off("update", this.onRender);
        },
        // 激活插槽
        slotIn() {
            this.slot = true;
        },
        // 屏蔽插槽
        slotOut() {
            this.slot = false;
        },
        // 渲染
        render() {
            this.vue3d.render();
        },
        onReady() {
            this.$emit('ready', this.object3d);
        },
        onRender() {
            this.$emit('update', this.object3d);
        },
        onDestroy() {
            this.$emit('remove', this.object3d);
        }
    },
    watch: {
        name(val, oldVal) {
            if (val === oldVal) return;
            this.object3d.name = val;
        },
        "position.x"(val, oldVal) {
            if (val === oldVal) return;
            this.setPosition();
        },
        "position.y"(val, oldVal) {
            if (val === oldVal) return;
            this.setPosition();
        },
        "position.z"(val, oldVal) {
            if (val === oldVal) return;
            this.setPosition();
        },
        "rotation.x"(val, oldVal) {
            if (val === oldVal) return;
            this.setRotation();
        },
        "rotation.y"(val, oldVal) {
            if (val === oldVal) return;
            this.setRotation();
        },
        "rotation.z"(val, oldVal) {
            if (val === oldVal) return;
            this.setRotation();
        },
        "scale.x"(val, oldVal) {
            if (val === oldVal) return;
            this.setScale();
        },
        "scale.y"(val, oldVal) {
            if (val === oldVal) return;
            this.setScale();
        },
        "scale.z"(val, oldVal) {
            if (val === oldVal) return;
            this.setScale();
        },
        "target.x"(val, oldVal) {
            if (val === oldVal) return;
            this.setTarget();
        },
        "target.y"(val, oldVal) {
            if (val === oldVal) return;
            this.setTarget();
        },
        "target.z"(val, oldVal) {
            if (val === oldVal) return;
            this.setTarget();
        },
    },
}
<commit_msg>0.7.8 修改键值<commit_after>/**
 * 所有mixins需要在mounted之前创建Object3d对象
 */
export default {
    name: "Object3d",
    props: {
        inTree: {type: Boolean, default: true}, // 是否挂载在树节点上。当设置为false时直接挂载在scene根节点上
        position: {
            type: Object,
            default: () => {
                return {x: 0, y: 0, z: 0}
            }
        },
        rotation: {
            type: Object,
            default: () => {
                return {x: 0, y: 0, z: 0}
            }
        },
        scale: {
            type: Object,
            default: () => {
                return {x: 1, y: 1, z: 1}
            }
        },
        target: {
            type: Object,
            default: () => {
                return {x: 0, y: 0, z: 0}
            }
        },
        name: {
            type: String,
        }
    },
    data() {
        return {
            vue3d: null, // Vue3D component
            scene: null, // mounted scene
            object3d: null, // 当前三维对象
            parent: null, // 父级三维对象
            slot: false, // 是否挂载子节点
            visible: true, // 是否可见
        }
    },
    created() {
        if (!this.$parent) {
            console.error(this.$options.name + " must slot in Vue3D-Component");
            return;
        }
        // check Vue3D component parent
        if (!this.parent) {
            this._recursion(this.$parent)
        }
    },
    mounted() {
        this.vue3d.on("update", this.render);
        if (this.object3d) this.init();
    },
    updated() {
        this.render();
    },
    beforeDestroy() {
        this.onDestroy();
        this.slotOut();
        this._removeObject3d(this.object3d);
    },
    methods: {
        init() {
            this.object3d.vComponent = this;
            this.object3d.name = this.name || this.$options.name;
            this.setPosition();
            this.setRotation();
            this.setScale();
            this.setTarget();
            this._addObject3d(this.object3d);
            this.slotIn();
            this.onReady();
            this.render();
        },
        // 根据vue组件递归查询scene节点
        _recursion(parent) {
            if (parent.$options.name === 'Vue3d') { // 当前挂载于Vue3D 根节点
                this.scene = parent.scenes.activated();
                this.vue3d = parent;
                this.parent = parent;
            } else if (parent.$options.name === 'V3dScene') { // 当前挂载于 V3dScene 子节点
                this.scene = parent.scene;
                this.vue3d = parent.vue3d;
                this.parent = parent;
            } else if (parent.hasOwnProperty("scene") && parent.hasOwnProperty('object3d')) { // 当前挂载于 其他 子节点
                this.scene = parent.scene;
                this.vue3d = parent.vue3d;
                this.parent = parent;
            } else {
                this._recursion(parent.$parent);
            }
        },
        // 插槽中添加三维对象
        _addObject3d(object3d) {
            if (this.inTree) {
                this.addObject3d(object3d, true);
            } else {
                this.addObject3d(object3d, false);
            }
        },
        // 插槽中移除三位对象
        _removeObject3d(object3d) {
            this.removeObject3d(object3d, true);
        },
        setPosition() {
            this.object3d.position.set(this.position.x, this.position.y, this.position.z);
            this.render();
        },
        setRotation() {
            this.object3d.rotation.set(this.rotation.x, this.rotation.y, this.rotation.z);
            this.render();
        },
        setScale() {
            this.object3d.scale.set(this.scale.x, this.scale.y, this.scale.z);
            this.render();
        },
        setTarget() {
            this.object3d.lookAt(this.target.x, this.target.y, this.target.z);
        },
        addObject3d(object3d, inNode) {
            if (inNode && this.parent.hasOwnProperty('object3d')) {
                this.parent.object3d.add(object3d);
            } else {
                this.scene.add(object3d);
            }
        },
        removeObject3d(object3d, inNode) {
            if (inNode && this.parent.hasOwnProperty('object3d')) {
                this.parent.object3d.remove(object3d);
            } else {
                this.removeObject3d(object3d);
            }
            this.vue3d.off("update", this.onRender);
        },
        // 激活插槽
        slotIn() {
            this.slot = true;
        },
        // 屏蔽插槽
        slotOut() {
            this.slot = false;
        },
        // 渲染
        render() {
            this.vue3d.render();
        },
        onReady() {
            this.$emit('ready', this.object3d);
        },
        onRender() {
            this.$emit('update', this.object3d);
        },
        onDestroy() {
            this.$emit('remove', this.object3d);
        }
    },
    watch: {
        name(val, oldVal) {
            if (val === oldVal) return;
            this.object3d.name = val;
        },
        "position.x"(val, oldVal) {
            if (val === oldVal) return;
            this.setPosition();
        },
        "position.y"(val, oldVal) {
            if (val === oldVal) return;
            this.setPosition();
        },
        "position.z"(val, oldVal) {
            if (val === oldVal) return;
            this.setPosition();
        },
        "rotation.x"(val, oldVal) {
            if (val === oldVal) return;
            this.setRotation();
        },
        "rotation.y"(val, oldVal) {
            if (val === oldVal) return;
            this.setRotation();
        },
        "rotation.z"(val, oldVal) {
            if (val === oldVal) return;
            this.setRotation();
        },
        "scale.x"(val, oldVal) {
            if (val === oldVal) return;
            this.setScale();
        },
        "scale.y"(val, oldVal) {
            if (val === oldVal) return;
            this.setScale();
        },
        "scale.z"(val, oldVal) {
            if (val === oldVal) return;
            this.setScale();
        },
        "target.x"(val, oldVal) {
            if (val === oldVal) return;
            this.setTarget();
        },
        "target.y"(val, oldVal) {
            if (val === oldVal) return;
            this.setTarget();
        },
        "target.z"(val, oldVal) {
            if (val === oldVal) return;
            this.setTarget();
        },
    },
}
<|endoftext|>