<commit_before>    ////////////////////////////////////////////////
    // remove temporary photo files in iOS
    // code from:
    // https://software.intel.com/en-us/articles/phonegap-camera-api-capture-a-photo-using-a-device-camera-and-edit-zoom-and-crop-the
    /////////////////////////////////////////////////

    // Removes all temporary files created by application. Is to be used when temporary files are not intended to be operated with further
function removeTemporaryFiles() {
    if (isIOS()) {
        navigator.camera.cleanup(onSuccess, onError);
    }
    function onSuccess() {  }
    function onError(message) {  }
}
// Determines whether the current device is running iOS
function isIOS() {
    var iDevices = ["iPad", "iPhone", "iPod"];
    for (var i = 0; i < iDevices.length ; i++ ) {
        if( navigator.platform.indexOf(iDevices[i]) !== -1){
            return true;
        }
    }
    return false;
}
    // Get current position
	//
	function currentPosition(){
		var flag = new Boolean();

		if(navigator.geolocation){
			flag = true;

			//get current location
			navigator.geolocation.getCurrentPosition(function(pos){
				return pos;
			}, function(){
				//has GPS but not working...
				errorGeolocation(flag);
			});
		}
		else {
			//device has no GPS
			flag = false;
			errorGeolocation(flag);
		}

		function errorGeolocation(errFlag){
			if (errFlag == true)
			{
				alert("Geolocation service failed.");
			}
			else
			{
				alert("Your device does not support geolocation.");
			}
		}
		alert('return null');
		return '';
	}

    ////////////////////////////////////////////////
    // phonegap camera code template from
    // http://docs.phonegap.com/en/2.5.0/cordova_camera_camera.md.html
    // API: https://github.com/apache/cordova-plugin-camera/blob/master/doc/index.md
    ////////////////////////////////////////////////

    // Wait for Cordova to connect with the device
    //
    document.addEventListener("deviceready",onDeviceReady,false);

	var photoURI;
    var options;
    // Cordova is ready to be used!
    //
    function onDeviceReady() {
        options = { quality: 50,
			destinationType : Camera.DestinationType.NATIVE_URI,
			sourceType : Camera.PictureSourceType.CAMERA,
			targetWidth: 500,
			targetHeight: 500,
			allowEdit: true,
			correctOrientation: true,
			encodingType: Camera.EncodingType.JPG,
			saveToPhotoAlbum: true };

		photoURI = null;
	//capturePhoto();

    }

	// display photo on the page
	function showPhoto(imageURI){

      // Get image handle
      //
      var largeImage = document.getElementById('largeImage');

      // Unhide image elements
      //
      largeImage.style.display = 'block';

      // Show the captured photo
      // The inline CSS rules are used to resize the image
      //
      largeImage.src = imageURI;

	}

	// Retrieve and save current GPS location to the given photo
	//
	function savePhotoData(imageURI,shared){
		//retrieve saved photo coords
		var photos = window.localStorage.getItem("photos");
		if(photos!=''){
			photos = JSON.parse(photos);
		}
		else{
			photos = {};
		}

		//get current GPS location
		var pos = currentPosition();
		if(pos!=''){
			photos[imageURI].coords = pos;
		}
		else{
			photos[imageURI].coords = '';
		}

		photos[imageURI].URI = imageURI;
		photos[imageURI].shared = shared;
		window.localStorage.setItem("photos",JSON.stringify(photos));
	}

    // Called when a photo is successfully retrieved
    //
    function onTakePhotoSuccess(imageURI) {
		alert('GET!! '+imageURI);
		photoURI = imageURI;

		//display photo
		showPhoto(imageURI);

		//save photo coords
		savePhotoData(imageURI,false);

    }

	function onGetPhotoSuccess(imageURI){
		alert('Get!!! '+imageURI);
		photoURI = imageURI;

		//display photo
		showPhoto(imageURI);

	}
    // A button will call this function
    //
    function capturePhoto() {
      // Take picture using device camera and retrieve image as base64-encoded string
      options.sourceType = Camera.PictureSourceType.CAMERA;
	  options.saveToPhotoAlbum = true;
	  options.allowEdit=true;
	  options.targetWidth = 500;
	  options.targetHeight = 500;
      navigator.camera.getPicture(onTakePhotoSuccess, onFail, options);
    }

    // A button will call this function
    //
    function getPhoto() {
      // Retrieve image file location from specified source
      options.sourceType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
	  options.saveToPhotoAlbum = false;
	  options.allowEdit = false;
	  delete options.targetWidth;
	  delete options.targetHeight;
      navigator.camera.getPicture(onGetPhotoSuccess, onFail, options);
    }

    // Called if something bad happens.
    //
    function onFail(message) {
      alert('Failed because: ' + message);
	  delete photoURI;
    }

	//delete image
	function deletePhoto(){
		if(photoURI != '' && photoURI != null){
			alert('deleting photo '+photoURI);
			window.resolveLocalFileSystemURI(photoURI, function (fileEntry) {
				alert('deleting file '+fileEntry.fullPath);
				alert('file url '+fileEntry.toURL);
				fileEntry.remove(function (entry) {
					alert('image deleted');
				  //remove photo coords from localStorage
				  var photos = window.localStorage.getItem("photos");
				  if(photos!=''){
					photos = JSON.parse(photos);
					if(photos[photoURI]!=''){
						delete photos[photoURI];
						window.localStorage.setItem("photos",JSON.stringify(photos));
					}
				  }
				},function(message){
					alert('image delete failed: '+getFileErrMsg(message.code));
				});
				delete photoURI;
			}, function (message){
				console.log('resolveFileSystemURI failed: '+getFileErrMsg(message.code));
			});
		}
	}

	function resSuccess(fileEntry){
		alert('deleting file '+fileEntry.fullPath);
		fileEntry.remove(rmSuccess,rmFail);
		delete photoURI;
	}

	function resFail(message){
		console.log('resolveFileSystemURI failed: '+getFileErrMsg(message.code));
	}

	function rmSuccess(){
		  alert('image deleted');
		  //remove photo coords from localStorage
		  var photos = window.localStorage.getItem("photos");
		  if(photos!=''){
			photos = JSON.parse(photos);
			if(photos[photoURI]!=''){
				delete photos[photoURI];
				window.localStorage.setItem("photos",JSON.stringify(photos));
			}
		  }

		  // Get image handle
		  //
		  // var largeImage = document.getElementById('largeImage');

		  // hide image elements
		  //
		  // largeImage.style.display = 'none';
			$('#largeImage').hide();
		  //reset values
		  // largeImage.src = '';
		  //photoURI = null;
	}

	function rmFail(message){
		alert('image delete failed: '+getFileErrMsg(message.code));
		//photoURI=null;
	}

	function getFileErrMsg(code){
		var msg = '';
		switch (e.code)
		{
		case FileError.QUOTA_EXCEEDED_ERR:
		msg = 'QUOTA_EXCEEDED_ERR';
		break;
        case FileError.NOT_FOUND_ERR:
		msg = 'NOT_FOUND_ERR';
		break;
        case FileError.SECURITY_ERR:
		msg = 'SECURITY_ERR';
		break;
        case FileError.INVALID_MODIFICATION_ERR:
		msg = 'INVALID_MODIFICATION_ERR';
		break;
        case FileError.INVALID_STATE_ERR:
		msg = 'INVALID_STATE_ERR';
		break;
		case FileError.ABORT_ERR:
		msg = 'ABORT_ERR';
		break;
		case FileError.NOT_READABLE_ERR:
		msg = 'NOT_READABLE_ERR';
		break;
		case FileError.ENCODING_ERR:
		msg = 'ENCODING_ERR';
		break;
        case FileError.SYNTAX_ERR:
		msg = 'SYNTAX_ERR';
		break;
		case FileError.TYPE_MISMATCH_ERR:
		msg = 'TYPE_MISMATCH_ERR';
		break;
        case FileError.PATH_EXISTS_ERR:
		msg = 'PATH_EXISTS_ERR';
		break;
        default:
		msg = e.code;
        break;
		};
	}
	/////////////////////////////////////////////////////
	// upload photo code template from:
	// http://docs.phonegap.com/en/3.1.0/cordova_file_file.md.html#FileTransfer
	/////////////////////////////////////////////////////
	function uploadPhoto(){
		if(photoURI!='' && photoURI!=null){
			//get photoURI's photo coords, if any
			var photos = window.localStorage.getItem("photos");
			photos = JSON.parse(photos);

			var pos = photos[photoURI];
			if(pos == ''){
				//try to get current position
				pos = currentPosition();
				if(pos!=''){
					//save photo coords
					savePhotoData(photoURI,true);
				}
				else{
					alert('upload photo error, no geolocation available!');
					return;
				}
			}
			//set upload options
			var uploadOptions = new FileUploadOptions();
			uploadOptions.fileKey="file";
			uploadOptions.fileName=photoURI.substr(photoURI.lastIndexOf('/')+1);
			uploadOptions.mimeType="image/jpeg";
			var params = {};
			params.coords = pos;
			//params.value2 = "param";
			uploadOptions.params = params;
			var ft = new FileTransfer();
			ft.upload(photoURI, encodeURI("http://some.server.com/upload.php"), win, fail, uploadOptions);

		}
	}
	function win(r) {
	console.log("Code = " + r.responseCode);
	console.log("Response = " + r.response);
	console.log("Sent = " + r.bytesSent);
	}
	function fail(error) {
	alert("An error has occurred: Code = " + error.code);
	console.log("upload error source " + error.source);
	console.log("upload error target " + error.target);
	}

	//delete from server
	function deleteFromServer(){

	}
<commit_msg>fix delete picture<commit_after>    ////////////////////////////////////////////////
    // remove temporary photo files in iOS
    // code from:
    // https://software.intel.com/en-us/articles/phonegap-camera-api-capture-a-photo-using-a-device-camera-and-edit-zoom-and-crop-the
    /////////////////////////////////////////////////

    // Removes all temporary files created by application. Is to be used when temporary files are not intended to be operated with further
function removeTemporaryFiles() {
    if (isIOS()) {
        navigator.camera.cleanup(onSuccess, onError);
    }
    function onSuccess() {  }
    function onError(message) {  }
}
// Determines whether the current device is running iOS
function isIOS() {
    var iDevices = ["iPad", "iPhone", "iPod"];
    for (var i = 0; i < iDevices.length ; i++ ) {
        if( navigator.platform.indexOf(iDevices[i]) !== -1){
            return true;
        }
    }
    return false;
}
    // Get current position
	//
	function currentPosition(){
		var flag = new Boolean();

		if(navigator.geolocation){
			flag = true;

			//get current location
			navigator.geolocation.getCurrentPosition(function(pos){
				return pos;
			}, function(){
				//has GPS but not working...
				errorGeolocation(flag);
			});
		}
		else {
			//device has no GPS
			flag = false;
			errorGeolocation(flag);
		}

		function errorGeolocation(errFlag){
			if (errFlag == true)
			{
				alert("Geolocation service failed.");
			}
			else
			{
				alert("Your device does not support geolocation.");
			}
		}
		alert('return null');
		return '';
	}

    ////////////////////////////////////////////////
    // phonegap camera code template from
    // http://docs.phonegap.com/en/2.5.0/cordova_camera_camera.md.html
    // API: https://github.com/apache/cordova-plugin-camera/blob/master/doc/index.md
    ////////////////////////////////////////////////

    // Wait for Cordova to connect with the device
    //
    document.addEventListener("deviceready",onDeviceReady,false);

	var photoURI;
    var options;
    // Cordova is ready to be used!
    //
    function onDeviceReady() {
        options = { quality: 50,
			destinationType : Camera.DestinationType.NATIVE_URI,
			sourceType : Camera.PictureSourceType.CAMERA,
			targetWidth: 500,
			targetHeight: 500,
			allowEdit: true,
			correctOrientation: true,
			encodingType: Camera.EncodingType.JPG,
			saveToPhotoAlbum: true };

		photoURI = null;
	//capturePhoto();

    }

	// display photo on the page
	function showPhoto(imageURI){

      // Get image handle
      //
      var largeImage = document.getElementById('largeImage');

      // Unhide image elements
      //
      largeImage.style.display = 'block';

      // Show the captured photo
      // The inline CSS rules are used to resize the image
      //
      largeImage.src = imageURI;

	}

	// Retrieve and save current GPS location to the given photo
	//
	function savePhotoData(imageURI,shared){
		//retrieve saved photo coords
		var photos = window.localStorage.getItem("photos");
		if(photos!=''){
			photos = JSON.parse(photos);
		}
		else{
			photos = {};
		}

		//get current GPS location
		var pos = currentPosition();
		if(pos!=''){
			photos[imageURI].coords = pos;
		}
		else{
			photos[imageURI].coords = '';
		}

		photos[imageURI].URI = imageURI;
		photos[imageURI].shared = shared;
		window.localStorage.setItem("photos",JSON.stringify(photos));
	}

    // Called when a photo is successfully retrieved
    //
    function onTakePhotoSuccess(imageURI) {
		alert('GET!! '+imageURI);
		photoURI = imageURI;

		//display photo
		showPhoto(imageURI);

		//save photo coords
		savePhotoData(imageURI,false);

    }

	function onGetPhotoSuccess(imageURI){
		alert('Get!!! '+imageURI);
		photoURI = imageURI;

		//display photo
		showPhoto(imageURI);

	}
    // A button will call this function
    //
    function capturePhoto() {
      // Take picture using device camera and retrieve image as base64-encoded string
      options.sourceType = Camera.PictureSourceType.CAMERA;
	  options.saveToPhotoAlbum = true;
	  options.allowEdit=true;
	  options.targetWidth = 500;
	  options.targetHeight = 500;
      navigator.camera.getPicture(onTakePhotoSuccess, onFail, options);
    }

    // A button will call this function
    //
    function getPhoto() {
      // Retrieve image file location from specified source
      options.sourceType = Camera.PictureSourceType.SAVEDPHOTOALBUM;
	  options.saveToPhotoAlbum = false;
	  options.allowEdit = false;
	  delete options.targetWidth;
	  delete options.targetHeight;
      navigator.camera.getPicture(onGetPhotoSuccess, onFail, options);
    }

    // Called if something bad happens.
    //
    function onFail(message) {
      alert('Failed because: ' + message);
	  delete photoURI;
    }

	//delete image
	function deletePhoto(){
		if(photoURI != '' && photoURI != null){
			alert('deleting photo '+photoURI);
			window.resolveLocalFileSystemURI(photoURI, function (fileEntry) {
				alert('deleting file '+fileEntry.fullPath);
				alert('file url '+fileEntry.toURL());
				fileEntry.remove(function (entry) {
					alert('image deleted');
				  //remove photo coords from localStorage
				  var photos = window.localStorage.getItem("photos");
				  if(photos!=''){
					photos = JSON.parse(photos);
					if(photos[photoURI]!=''){
						delete photos[photoURI];
						window.localStorage.setItem("photos",JSON.stringify(photos));
					}
				  }
				},function(message){
					alert('image delete failed: '+getFileErrMsg(message.code));
				});
				delete photoURI;
			}, function (message){
				console.log('resolveFileSystemURI failed: '+getFileErrMsg(message.code));
			});
		}
	}

	function resSuccess(fileEntry){
		alert('deleting file '+fileEntry.fullPath);
		fileEntry.remove(rmSuccess,rmFail);
		delete photoURI;
	}

	function resFail(message){
		console.log('resolveFileSystemURI failed: '+getFileErrMsg(message.code));
	}

	function rmSuccess(){
		  alert('image deleted');
		  //remove photo coords from localStorage
		  var photos = window.localStorage.getItem("photos");
		  if(photos!=''){
			photos = JSON.parse(photos);
			if(photos[photoURI]!=''){
				delete photos[photoURI];
				window.localStorage.setItem("photos",JSON.stringify(photos));
			}
		  }

		  // Get image handle
		  //
		  // var largeImage = document.getElementById('largeImage');

		  // hide image elements
		  //
		  // largeImage.style.display = 'none';
			$('#largeImage').hide();
		  //reset values
		  // largeImage.src = '';
		  //photoURI = null;
	}

	function rmFail(message){
		alert('image delete failed: '+getFileErrMsg(message.code));
		//photoURI=null;
	}

	function getFileErrMsg(code){
		var msg = '';
		switch (e.code)
		{
		case FileError.QUOTA_EXCEEDED_ERR:
		msg = 'QUOTA_EXCEEDED_ERR';
		break;
        case FileError.NOT_FOUND_ERR:
		msg = 'NOT_FOUND_ERR';
		break;
        case FileError.SECURITY_ERR:
		msg = 'SECURITY_ERR';
		break;
        case FileError.INVALID_MODIFICATION_ERR:
		msg = 'INVALID_MODIFICATION_ERR';
		break;
        case FileError.INVALID_STATE_ERR:
		msg = 'INVALID_STATE_ERR';
		break;
		case FileError.ABORT_ERR:
		msg = 'ABORT_ERR';
		break;
		case FileError.NOT_READABLE_ERR:
		msg = 'NOT_READABLE_ERR';
		break;
		case FileError.ENCODING_ERR:
		msg = 'ENCODING_ERR';
		break;
        case FileError.SYNTAX_ERR:
		msg = 'SYNTAX_ERR';
		break;
		case FileError.TYPE_MISMATCH_ERR:
		msg = 'TYPE_MISMATCH_ERR';
		break;
        case FileError.PATH_EXISTS_ERR:
		msg = 'PATH_EXISTS_ERR';
		break;
        default:
		msg = e.code;
        break;
		};
	}
	/////////////////////////////////////////////////////
	// upload photo code template from:
	// http://docs.phonegap.com/en/3.1.0/cordova_file_file.md.html#FileTransfer
	/////////////////////////////////////////////////////
	function uploadPhoto(){
		if(photoURI!='' && photoURI!=null){
			//get photoURI's photo coords, if any
			var photos = window.localStorage.getItem("photos");
			photos = JSON.parse(photos);

			var pos = photos[photoURI];
			if(pos == ''){
				//try to get current position
				pos = currentPosition();
				if(pos!=''){
					//save photo coords
					savePhotoData(photoURI,true);
				}
				else{
					alert('upload photo error, no geolocation available!');
					return;
				}
			}
			//set upload options
			var uploadOptions = new FileUploadOptions();
			uploadOptions.fileKey="file";
			uploadOptions.fileName=photoURI.substr(photoURI.lastIndexOf('/')+1);
			uploadOptions.mimeType="image/jpeg";
			var params = {};
			params.coords = pos;
			//params.value2 = "param";
			uploadOptions.params = params;
			var ft = new FileTransfer();
			ft.upload(photoURI, encodeURI("http://some.server.com/upload.php"), win, fail, uploadOptions);

		}
	}
	function win(r) {
	console.log("Code = " + r.responseCode);
	console.log("Response = " + r.response);
	console.log("Sent = " + r.bytesSent);
	}
	function fail(error) {
	alert("An error has occurred: Code = " + error.code);
	console.log("upload error source " + error.source);
	console.log("upload error target " + error.target);
	}

	//delete from server
	function deleteFromServer(){

	}
<|endoftext|>


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

    var viewing_id = -1;

    /* FIXME: this stuff shouldn't run if no newsgroup is displayed */

    /* Expanding and collapsing posts in the list */
    $( '.expander' ).click(expanderClick);
    $( '.expander' ).dblclick(expanderClick);

    function expanderClick(e) {
        if ($.trim($(this).text()) === '+') {
            $(this).parents('.post').next().show();
            $(this).html('–');
        } else {
            $(this).parents('.post').next().hide();
            $(this).html('+');
        }
        /* don't trigger the post view click event */
        e.stopPropagation();
    }

    /* Clicking posts in the list */
    $( '.post' ).click(postItemClick);

    function postItemClick() {
        /* get the id of the post that was just clicked */
        var id = $(this).children('.postid').attr('value');
        /* un-highlight all the other posts */
        $('.post').css('background-color', 'inherit');
        /* highlight the one that was just clicked */
        $(this).css('background-color', '#00FFFF');

        /* if this is a top-level post, and there are unread sub-posts... */
        if ($(this).next('.hiddenposts').find('.unread').length > 0) {
            $(this).find('.unread').removeClass('unread').addClass('subunread');
        } else {
            $(this).find('.unread').removeClass('unread').addClass('read');
        }

        var reply_container = $(this).parents('.hiddenposts');
        /* if this is a reply post */
        if (reply_container.length > 0) {
            root_post = reply_container.prev('.post');
            /* if all other replies to the 'root' post are read */
            if (reply_container.find('.unread').length === 0) {
                root_post.find('.subunread').removeClass('subunread').addClass('read');
            }
        }
        showPost(id);
    }

    /* Double clicking posts in the list */
    $( '.post' ).dblclick(postItemDoubleClick);

    function postItemDoubleClick() {
        alert("Normally this would open the post in a new window, but isn't implemented.");
        return;
        var id = $(this).children('.postid').attr('value');
        var w = window.open(
            'viewpost.php?id=' + id,
            '_blank'
        );
        if (window.focus) {
            w.focus();
        }
    }

    /* Clicking 'Reply' */
    $( '.replybutton' ).click(function () {
        var w = window.open(
            'replypost.php?replyto=' + viewing_id,
            '_blank'
        );
        if (window.focus) {
            w.focus();
        }
    });

    /* Clicking 'New Post' */
    $( '.newpostbutton' ).click(function () {
        var w = window.open(
            'newpost.php?group=' + groupName(),
            '_blank'
        );
        if (window.focus) {
            w.focus();
        }
    });

    /* Auto updates */
    var last_update_time = $('#currenttime').attr('value');
    setInterval(function () {
        getNewPosts(function (posts) {
            if (posts.length === 0) {
                return;
            }
            /* Here we keep iterating over the list, trying to add posts into
             * the DOM. We finish when no change is made. We have to do this
             * because the 'posts' array might contain posts that are replies to
             * each other, and we can't add the reply without first adding the
             * post it is in reply to. */
            var changed = false;
            var unadded_posts;
            var post;
            do {
                changed = false;
                unadded_posts = [];
                for (var i = 0; i < posts.length; i++) {
                    post = posts[i];
                    if (post.parent_id === "") {
                        if (pageNumber() === 1) {
                            changed = true;
                            $('.post').first().parent().prepend('

');
                            $('.post').first().parent().prepend(createUnreadPost(post, 0));
                        } else {
                            /* We don't add it to unadded_posts when page != 1,
                            * since it's not in reply to anything, so we won't be
                            * able to add it later. */
                        }
                    } else {
                        /* find the post it's in reply to */
                        var p = $('.postid').filter("[value='" + post.parent_id + "']");
                        if (p.length > 0) {
                            changed = true;
                            p = p.parents('.post');
                            var indent = parseInt(p.find('.postindent').val());
                            var post_obj = createUnreadPost(post, indent + 1);
                            var toplevel;
                            if (indent === 0) {
                                p.next('.hiddenposts').append(post_obj);
                                p.next('.hiddenposts').append('

');
                                toplevel = p;
                            } else {
                                p.next('.childposts').append(post_obj);
                                p.next('.childposts').append('

');
                                toplevel = p.parents('.hiddenposts').prev('.post');
                            }
                            toplevel.find('.expander-dummy')
                                    .removeClass('expander-dummy')
                                    .addClass('expander')
                                    .text('+')
                                    .click(expanderClick)
                                    .dblclick(expanderClick);
                            toplevel.find('.read')
                                    .removeClass('read')
                                    .addClass('subunread');
                        } else {
                            /* might not have added the parent yet, try again */
                            unadded_posts.push(post);
                        }
                    }
                }
                posts = unadded_posts;
            } while (changed);
        });
    }, 30000);

    function pageNumber() {
        return parseInt($('#grouppagenumber').attr('value'));
    }

    function createUnreadPost(post, indent) {
        var html = '
' +
            '<input type="hidden" class="postid" value="XXX"/>' +   // id
            '<input type="hidden" class="postindent" value="XXX"/>' + // indent
            '
' +
                '
' +
                    '' +
                        ' ' +
                    '	' +
                    '' +               // indent
                        '' +
                            'XXX' +                                 // title
                        '' +
                    '	' +
                    '' +
                        '
' +
                            '
' +
                                '	' +
                                '' +
                                    'XXX' +                         // user
                                '	' +
                                '' +
                                    'XXX' +                         // time
                                '	' +
                            '
' +
                        '
' +
                    '	' +
                '
' +
            '
' +
        '
';
        var obj = $('

').html(html).children();
        /* data */
        obj.find('.postid').val(post.id);
        obj.find('.postindent').val(indent);
        obj.find('.titlecell').css('paddingLeft', 10 + 30*indent);
        obj.find('.posttitle').text(post.title);
        obj.find('.metadatauser').text(post.user);
        obj.find('.metadatatime').text(post.formatted_time);
        /* events */
        obj.click(postItemClick);
        obj.dblclick(postItemDoubleClick);
        return obj;
    }

    function groupName() {
        return $('#groupname').attr('value');
    }

    function getPost(id, f, mark_read) {
        var data = { };
        data.id = id;
        data.mark_read = mark_read ? "1" : "0";
        $.post("ajax.php", data, function (data) {
            var stat = $(data).find('status').text();
            if (stat === 'success') {
                f(getPostFromXML(data));
            } else {
                f(null);
            }
        }, "xml");
    }

    function getNewPosts(f) {
        var data = { };
        data.get_posts_after = last_update_time;
        data.newsgroup = groupName();
        $.post("ajax.php", data, function (data) {
            var stat = $(data).find('status').text();
            if (stat === 'success') {
                last_update_time = $(data).find('currenttime').text();
                var posts_xml = $(data).find('post')
                var posts = [];
                for (var i = 0; i < posts_xml.length; i++) {
                    posts.push(getPostFromXML(posts_xml[i]));
                }
                f(posts);
            } else {
                f(null);
            }
        }, "xml");
    }

    function getPostFromXML(xml) {
        var post = {};
        post.id = $(xml).find('id').text();
        post.parent_id = $(xml).find('parent').text();
        post.user = $(xml).find('user').text();
        post.time = $(xml).find('time').text();
        post.formatted_time = $(xml).find('formattedtime').text();
        post.title = $(xml).find('title').text();
        post.contents = $(xml).find('contents').text();
        return post;
    }

    function showPost(id) {
        getPost(id, function (post) {
            if (post !== null) {
                viewing_id = id;
                if (post.user === "") {
                    $(".vp_user").html('Anonymous');
                } else  {
                    $(".vp_user").text(post.user);
                }
                $(".vp_subject").text(post.title);
                $(".vp_date").text(post.time);
                $("#postcontents").html(post.contents);
                $("#postview").show();
            } else {
                alert('That post has been deleted.');
            }
        }, true);
    }

});
<commit_msg>Check for new posts  when the reply window closes.<commit_after>$( document ).ready(function () {

    var viewing_id = -1;

    /* FIXME: this stuff shouldn't run if no newsgroup is displayed */

    /* Expanding and collapsing posts in the list */
    $( '.expander' ).click(expanderClick);
    $( '.expander' ).dblclick(expanderClick);

    function expanderClick(e) {
        if ($.trim($(this).text()) === '+') {
            $(this).parents('.post').next().show();
            $(this).html('–');
        } else {
            $(this).parents('.post').next().hide();
            $(this).html('+');
        }
        /* don't trigger the post view click event */
        e.stopPropagation();
    }

    /* Clicking posts in the list */
    $( '.post' ).click(postItemClick);

    function postItemClick() {
        /* get the id of the post that was just clicked */
        var id = $(this).children('.postid').attr('value');
        /* un-highlight all the other posts */
        $('.post').css('background-color', 'inherit');
        /* highlight the one that was just clicked */
        $(this).css('background-color', '#00FFFF');

        /* if this is a top-level post, and there are unread sub-posts... */
        if ($(this).next('.hiddenposts').find('.unread').length > 0) {
            $(this).find('.unread').removeClass('unread').addClass('subunread');
        } else {
            $(this).find('.unread').removeClass('unread').addClass('read');
        }

        var reply_container = $(this).parents('.hiddenposts');
        /* if this is a reply post */
        if (reply_container.length > 0) {
            root_post = reply_container.prev('.post');
            /* if all other replies to the 'root' post are read */
            if (reply_container.find('.unread').length === 0) {
                root_post.find('.subunread').removeClass('subunread').addClass('read');
            }
        }
        showPost(id);
    }

    /* Double clicking posts in the list */
    $( '.post' ).dblclick(postItemDoubleClick);

    function postItemDoubleClick() {
        alert("Normally this would open the post in a new window, but isn't implemented.");
        return;
        var id = $(this).children('.postid').attr('value');
        var w = window.open(
            'viewpost.php?id=' + id,
            '_blank'
        );
        if (window.focus) {
            w.focus();
        }
    }

    /* Clicking 'Reply' */
    $( '.replybutton' ).click(function () {
        var w = window.open(
            'replypost.php?replyto=' + viewing_id,
            '_blank'
        );
        $(w).unload(function () {
            checkForNewPosts();
        });
        if (window.focus) {
            w.focus();
        }
    });

    /* Clicking 'New Post' */
    $( '.newpostbutton' ).click(function () {
        var w = window.open(
            'newpost.php?group=' + groupName(),
            '_blank'
        );
        $(w).unload(function () {
            checkForNewPosts();
        });
        if (window.focus) {
            w.focus();
        }
    });

    /* Auto updates */
    var last_update_time = $('#currenttime').attr('value');
    setInterval(checkForNewPosts, 30000);

    function checkForNewPosts() {
        getNewPosts(function (posts) {
            if (posts.length === 0) {
                return;
            }
            /* Here we keep iterating over the list, trying to add posts into
            * the DOM. We finish when no change is made. We have to do this
            * because the 'posts' array might contain posts that are replies to
            * each other, and we can't add the reply without first adding the
            * post it is in reply to. */
            var changed = false;
            var unadded_posts;
            var post;
            do {
                changed = false;
                unadded_posts = [];
                for (var i = 0; i < posts.length; i++) {
                    post = posts[i];
                    if (post.parent_id === "") {
                        if (pageNumber() === 1) {
                            changed = true;
                            $('.post').first().parent().prepend('

');
                            $('.post').first().parent().prepend(createUnreadPost(post, 0));
                        } else {
                            /* We don't add it to unadded_posts when page != 1,
                            * since it's not in reply to anything, so we won't be
                            * able to add it later. */
                        }
                    } else {
                        /* find the post it's in reply to */
                        var p = $('.postid').filter("[value='" + post.parent_id + "']");
                        if (p.length > 0) {
                            changed = true;
                            p = p.parents('.post');
                            var indent = parseInt(p.find('.postindent').val());
                            var post_obj = createUnreadPost(post, indent + 1);
                            var toplevel;
                            if (indent === 0) {
                                p.next('.hiddenposts').append(post_obj);
                                p.next('.hiddenposts').append('

');
                                toplevel = p;
                            } else {
                                p.next('.childposts').append(post_obj);
                                p.next('.childposts').append('

');
                                toplevel = p.parents('.hiddenposts').prev('.post');
                            }
                            toplevel.find('.expander-dummy')
                                    .removeClass('expander-dummy')
                                    .addClass('expander')
                                    .text('+')
                                    .click(expanderClick)
                                    .dblclick(expanderClick);
                            toplevel.find('.read')
                                    .removeClass('read')
                                    .addClass('subunread');
                        } else {
                            /* might not have added the parent yet, try again */
                            unadded_posts.push(post);
                        }
                    }
                }
                posts = unadded_posts;
            } while (changed);
        });
    }

    function pageNumber() {
        return parseInt($('#grouppagenumber').attr('value'));
    }

    function createUnreadPost(post, indent) {
        var html = '
' +
            '<input type="hidden" class="postid" value="XXX"/>' +   // id
            '<input type="hidden" class="postindent" value="XXX"/>' + // indent
            '
' +
                '
' +
                    '' +
                        ' ' +
                    '	' +
                    '' +               // indent
                        '' +
                            'XXX' +                                 // title
                        '' +
                    '	' +
                    '' +
                        '
' +
                            '
' +
                                '	' +
                                '' +
                                    'XXX' +                         // user
                                '	' +
                                '' +
                                    'XXX' +                         // time
                                '	' +
                            '
' +
                        '
' +
                    '	' +
                '
' +
            '
' +
        '
';
        var obj = $('

').html(html).children();
        /* data */
        obj.find('.postid').val(post.id);
        obj.find('.postindent').val(indent);
        obj.find('.titlecell').css('paddingLeft', 10 + 30*indent);
        obj.find('.posttitle').text(post.title);
        obj.find('.metadatauser').text(post.user);
        obj.find('.metadatatime').text(post.formatted_time);
        /* events */
        obj.click(postItemClick);
        obj.dblclick(postItemDoubleClick);
        return obj;
    }

    function groupName() {
        return $('#groupname').attr('value');
    }

    function getPost(id, f, mark_read) {
        var data = { };
        data.id = id;
        data.mark_read = mark_read ? "1" : "0";
        $.post("ajax.php", data, function (data) {
            var stat = $(data).find('status').text();
            if (stat === 'success') {
                f(getPostFromXML(data));
            } else {
                f(null);
            }
        }, "xml");
    }

    function getNewPosts(f) {
        var data = { };
        data.get_posts_after = last_update_time;
        data.newsgroup = groupName();
        $.post("ajax.php", data, function (data) {
            var stat = $(data).find('status').text();
            if (stat === 'success') {
                last_update_time = $(data).find('currenttime').text();
                var posts_xml = $(data).find('post')
                var posts = [];
                for (var i = 0; i < posts_xml.length; i++) {
                    posts.push(getPostFromXML(posts_xml[i]));
                }
                f(posts);
            } else {
                f(null);
            }
        }, "xml");
    }

    function getPostFromXML(xml) {
        var post = {};
        post.id = $(xml).find('id').text();
        post.parent_id = $(xml).find('parent').text();
        post.user = $(xml).find('user').text();
        post.time = $(xml).find('time').text();
        post.formatted_time = $(xml).find('formattedtime').text();
        post.title = $(xml).find('title').text();
        post.contents = $(xml).find('contents').text();
        return post;
    }

    function showPost(id) {
        getPost(id, function (post) {
            if (post !== null) {
                viewing_id = id;
                if (post.user === "") {
                    $(".vp_user").html('Anonymous');
                } else  {
                    $(".vp_user").text(post.user);
                }
                $(".vp_subject").text(post.title);
                $(".vp_date").text(post.time);
                $("#postcontents").html(post.contents);
                $("#postview").show();
            } else {
                alert('That post has been deleted.');
            }
        }, true);
    }

});
<|endoftext|>


<commit_before>define(['dojo/_base/array'], function(dojo){
dojo.getObject("xml", true, dojox);

dojox.xml.DomParser=new (function(){
	/**********************************************************
	 *	The DomParser is a close-to (but not entirely)
	 *	conforming XML parser based on regular
	 *	expressions.  It will take any XML fragment
	 *	and return a lightweight JS structure that is
	 *	similar to (but not exactly) the DOM specification.
	 *
	 *	Getter and setter methods are NOT available; the goal
	 *	was to keep the resulting object model entirely JS-like.
	 *
	 *	All node types but document fragments are supported;
	 *	all nodes support getElementsByTagName and
	 *	getElementsByTagNameNS (with short names byName and
	 *	byNameNS).  The document node supports getElementById
	 *	(byId), and all nodes support a supplimental
	 *	childrenByName/childrenByNameNS method as well.
	 *
	 *	The object model is intended to be a READONLY format;
	 *	mutation events are NOT supported, and though you
	 *	can change properties on a node-by-node basis, certain
	 *	operations are not supported (such as changing the ID
	 *	of an element).
	 **********************************************************/

	//	internal use only.
	var nodeTypes={ ELEMENT:1, ATTRIBUTE:2, TEXT:3, CDATA_SECTION:4, PROCESSING_INSTRUCTION:7, COMMENT:8, DOCUMENT:9 };

	//	compile the regular expressions once.
	var reTags=/<([^>\/\s+]*)([^>]*)>([^<]*)/g;
	var reAttr=/([^=]*)=(("([^"]*)")|('([^']*)'))/g;	//	patch from tdedischew AT gmail, with additional grouping
	var reEntity=/<!ENTITY\s+([^"]*)\s+"([^"]*)">/g;
	var reCData=/<!\[CDATA\[([\u0001-\uFFFF]*?)\]\]>/g;
	var reComments=/<!--([\u0001-\uFFFF]*?)-->/g;
	var trim=/^\s+|\s+$/g;
	var normalize=/\s+/g;
	var egt=/\>/g;
	var elt=/\</g;
	var equot=/\"/g;
	var eapos=/\'/g;
	var eamp=/\&/g;
	var dNs="_def_";

	//	create a root node.
	function _doc(){
		return new (function(){
			var all={};
			this.nodeType=nodeTypes.DOCUMENT;
			this.nodeName="#document";
			this.namespaces={};
			this._nsPaths={};
			this.childNodes=[];
			this.documentElement=null;

			//	any element with an ID attribute will be added to the internal hashtable.
			this._add=function(obj){
				if(typeof(obj.id)!="undefined"){ all[obj.id]=obj; }
			};
			this._remove=function(id){
				if(all[id]){ delete all[id]; }
			};

			this.byId=this.getElementById=function(id){ return all[id]; };
			this.byName=this.getElementsByTagName=byName;
			this.byNameNS=this.getElementsByTagNameNS=byNameNS;
			this.childrenByName=childrenByName;
			this.childrenByNameNS=childrenByNameNS;
		})();
	}

	//	functions attached to element nodes
	function byName(name){
		//	return all descendants with name.  Fully qualified (i.e. svg:svg)
		function __(node, name, arr){
			dojo.forEach(node.childNodes, function(c){
				if(c.nodeType==nodeTypes.ELEMENT){
					if(name=="*"){ arr.push(c); }
					else if(c.nodeName==name){ arr.push(c); }
					__(c, name, arr);
				}
			});
		}
		var a=[];
		__(this, name, a);
		return a;
	}
	function byNameNS(name, ns){
		//	return all descendants with name by namespace.  If no namespace passed, the default is used.
		function __(node, name, ns, arr){
			dojo.forEach(node.childNodes, function(c){
				if(c.nodeType==nodeTypes.ELEMENT){
					if(name=="*"&&c.ownerDocument._nsPaths[ns]==c.namespace){ arr.push(c); }
					else if(c.localName==name&&c.ownerDocument._nsPaths[ns]==c.namespace){ arr.push(c); }
					__(c, name, ns, arr);
				}
			});
		}
		if(!ns){ ns=dNs; }
		var a=[];
		__(this, name, ns, a);
		return a;
	}
	//	Only child nodes with name.
	function childrenByName(name){
		var a=[];
		dojo.forEach(this.childNodes, function(c){
			if(c.nodeType==nodeTypes.ELEMENT){
				if(name=="*"){ a.push(c); }
				else if(c.nodeName==name){ a.push(c); }
			}
		});
		return a;
	}

	function childrenByNameNS(name, ns){
		var a=[];
		dojo.forEach(this.childNodes, function(c){
			if(c.nodeType==nodeTypes.ELEMENT){
				if(name=="*"&&c.ownerDocument._nsPaths[ns]==c.namespace){ a.push(c); }
				else if(c.localName==name&&c.ownerDocument._nsPaths[ns]==c.namespace){ a.push(c); }
			}
		});
		return a;
	}

	function _createTextNode(v){
		return {
			nodeType:nodeTypes.TEXT,
			nodeName:"#text",
			nodeValue:v.replace(normalize," ").replace(egt,">").replace(elt,"<").replace(eapos,"'").replace(equot,'"').replace(eamp,"&")
		};
	}

	//	attribute functions
	function getAttr(name){
		for(var i=0; i<this.attributes.length; i++){
			if(this.attributes[i].nodeName==name){
				return this.attributes[i].nodeValue;
			}
		}
		return null;
	}
	function getAttrNS(name, ns){
		for(var i=0; i<this.attributes.length; i++){
			if(this.ownerDocument._nsPaths[ns]==this.attributes[i].namespace
				&&this.attributes[i].localName==name
			){
				return this.attributes[i].nodeValue;
			}
		}
		return null;
	}
	//	note that you can only swap IDs using setAttribute, NOT with setAttributeNS.
	function setAttr(name, val){
		var old=null;
		for(var i=0; i<this.attributes.length; i++){
			if(this.attributes[i].nodeName==name){
				old=this.attributes[i].nodeValue;
				this.attributes[i].nodeValue=val;
				break;
			}
		}
		if(name=="id"){
			if(old!=null){ this.ownerDocument._remove(old); }
			this.ownerDocument._add(this);
		}
	}
	function setAttrNS(name, val, ns){
		for(var i=0; i<this.attributes.length; i++){
			if(this.ownerDocument._nsPaths[ns]==this.attributes[i].namespace
				&&this.attributes[i].localName==name
			){
				this.attributes[i].nodeValue=val;
				return;
			}
		}
	}

	//	navigation
	function prev(){
		var p=this.parentNode;
		if(p){
			for(var i=0;i<p.childNodes.length;i++){
				if(p.childNodes[i]==this&&i>0){
					return p.childNodes[i-1];
				}
			}
		}
		return null;
	}
	function next(){
		var p=this.parentNode;
		if(p){
			for(var i=0;i<p.childNodes.length;i++){
				if(p.childNodes[i]==this&&(i+1)<p.childNodes.length){
					return p.childNodes[i+1];
				}
			}
		}
		return null;
	}

	//	the main method.
	this.parse=function(/* String */str){
		var root=_doc();
		if(str==null){ return root; }
		if(str.length==0){ return root; }

		//	preprocess custom entities
		if(str.indexOf("<!ENTITY")>0){
			var entity, eRe=[];
			if(reEntity.test(str)){
				reEntity.lastIndex=0;
				//	match entities
				while((entity=reEntity.exec(str))!=null){
					eRe.push({
						entity:"&"+entity[1].replace(trim,"")+";",
						expression:entity[2]
					});
				}
				//	replace instances in the document.
				for(var i=0; i<eRe.length; i++){
					str=str.replace(new RegExp(eRe[i].entity, "g"), eRe[i].expression);
				}
			}
		}

		//	pre-parse for CData, and tokenize.
		var cdSections=[], cdata;
		while((cdata=reCData.exec(str))!=null){ cdSections.push(cdata[1]); }
		for(var i=0; i<cdSections.length; i++){ str=str.replace(cdSections[i], i); }

		//	pre-parse for comments, and tokenize.
		var comments=[], comment;
		while((comment=reComments.exec(str))!=null){ comments.push(comment[1]); }
		for(i=0; i<comments.length; i++){ str=str.replace(comments[i], i); }

		//	parse the document
		var res, obj=root;
		while((res=reTags.exec(str))!=null){
			//	closing tags.
			if(res[2].charAt(0)=="/" && res[2].replace(trim, "").length>1){
				if(obj.parentNode){
					obj=obj.parentNode;
				}
				var text=(res[3]||"").replace(trim, "");
				if(text.length>0) {
					obj.childNodes.push(_createTextNode(text));
				}
			}

			//	open tags.
			else if(res[1].length>0){
				//	figure out the type of node.
				if(res[1].charAt(0)=="?"){
					//	processing instruction
					var name=res[1].substr(1);
					var target=res[2].substr(0,res[2].length-2);
					obj.childNodes.push({
						nodeType:nodeTypes.PROCESSING_INSTRUCTION,
						nodeName:name,
						nodeValue:target
					});
				}
				else if(res[1].charAt(0)=="!"){
					//	CDATA; skip over any declaration elements.
					if(res[1].indexOf("![CDATA[")==0){
						var val=parseInt(res[1].replace("![CDATA[","").replace("]]",""));
						obj.childNodes.push({
							nodeType:nodeTypes.CDATA_SECTION,
							nodeName:"#cdata-section",
							nodeValue:cdSections[val]
						});
					}
					//	Comments.
					else if(res[1].substr(0,3)=="!--"){
						var val=parseInt(res[1].replace("!--","").replace("--",""));
						obj.childNodes.push({
							nodeType:nodeTypes.COMMENT,
							nodeName:"#comment",
							nodeValue:comments[val]
						});
					}
				}
				else {
					//	Elements (with attribute and text)
					var name=res[1].replace(trim,"");
					var o={
						nodeType:nodeTypes.ELEMENT,
						nodeName:name,
						localName:name,
						namespace:dNs,
						ownerDocument:root,
						attributes:[],
						parentNode:null,
						childNodes:[]
					};

					//	check to see if it's namespaced.
					if(name.indexOf(":")>-1){
						var t=name.split(":");
						o.namespace=t[0];
						o.localName=t[1];
					}

					//	set the function references.
					o.byName=o.getElementsByTagName=byName;
					o.byNameNS=o.getElementsByTagNameNS=byNameNS;
					o.childrenByName=childrenByName;
					o.childrenByNameNS=childrenByNameNS;
					o.getAttribute=getAttr;
					o.getAttributeNS=getAttrNS;
					o.setAttribute=setAttr;
					o.setAttributeNS=setAttrNS;
					o.previous=o.previousSibling=prev;
					o.next=o.nextSibling=next;

					//	parse the attribute string.
					var attr;
					while((attr=reAttr.exec(res[2]))!=null){
						if(attr.length>0){
							var name=attr[1].replace(trim,"");
							var val=(attr[4]||attr[6]||"").replace(normalize," ")
								.replace(egt,">")
								.replace(elt,"<")
								.replace(eapos,"'")
								.replace(equot,'"')
								.replace(eamp,"&");
							if(name.indexOf("xmlns")==0){
								if(name.indexOf(":")>0){
									var ns=name.split(":");
									root.namespaces[ns[1]]=val;
									root._nsPaths[val]=ns[1];
								} else {
									root.namespaces[dNs]=val;
									root._nsPaths[val]=dNs;
								}
							} else {
								var ln=name;
								var ns=dNs;
								if(name.indexOf(":")>0){
									var t=name.split(":");
									ln=t[1];
									ns=t[0];
								}
								o.attributes.push({
									nodeType:nodeTypes.ATTRIBUTE,
									nodeName:name,
									localName:ln,
									namespace:ns,
									nodeValue:val
								});

								//	only add id as a property.
								if(ln=="id"){ o.id=val; }
							}
						}
					}
					root._add(o);

					if(obj){
						obj.childNodes.push(o);
						o.parentNode=obj;
						//	if it's not a self-closing node.
						if(res[2].charAt(res[2].length-1)!="/"){
							obj=o;
						}
					}
					var text=res[3];
					if(text.length>0){
						obj.childNodes.push(_createTextNode(text));
					}
				}
			}
		}

		//	set the document element
		for(var i=0; i<root.childNodes.length; i++){
			var e=root.childNodes[i];
			if(e.nodeType==nodeTypes.ELEMENT){
				root.documentElement=e;
				break;
			}
		}
		return root;
	};
})();
return dojox.xml.DomParser;
});
<commit_msg>fix missing dependency on dojo/_base/kernel, fixes #12850, refs #12863, #13208 !strict.<commit_after>define([
	"dojo/_base/kernel",// dojo.getObject
	"dojo/_base/array"	// dojo.forEach
], function(dojo){
dojo.getObject("xml", true, dojox);

dojox.xml.DomParser=new (function(){
	/**********************************************************
	 *	The DomParser is a close-to (but not entirely)
	 *	conforming XML parser based on regular
	 *	expressions.  It will take any XML fragment
	 *	and return a lightweight JS structure that is
	 *	similar to (but not exactly) the DOM specification.
	 *
	 *	Getter and setter methods are NOT available; the goal
	 *	was to keep the resulting object model entirely JS-like.
	 *
	 *	All node types but document fragments are supported;
	 *	all nodes support getElementsByTagName and
	 *	getElementsByTagNameNS (with short names byName and
	 *	byNameNS).  The document node supports getElementById
	 *	(byId), and all nodes support a supplimental
	 *	childrenByName/childrenByNameNS method as well.
	 *
	 *	The object model is intended to be a READONLY format;
	 *	mutation events are NOT supported, and though you
	 *	can change properties on a node-by-node basis, certain
	 *	operations are not supported (such as changing the ID
	 *	of an element).
	 **********************************************************/

	//	internal use only.
	var nodeTypes={ ELEMENT:1, ATTRIBUTE:2, TEXT:3, CDATA_SECTION:4, PROCESSING_INSTRUCTION:7, COMMENT:8, DOCUMENT:9 };

	//	compile the regular expressions once.
	var reTags=/<([^>\/\s+]*)([^>]*)>([^<]*)/g;
	var reAttr=/([^=]*)=(("([^"]*)")|('([^']*)'))/g;	//	patch from tdedischew AT gmail, with additional grouping
	var reEntity=/<!ENTITY\s+([^"]*)\s+"([^"]*)">/g;
	var reCData=/<!\[CDATA\[([\u0001-\uFFFF]*?)\]\]>/g;
	var reComments=/<!--([\u0001-\uFFFF]*?)-->/g;
	var trim=/^\s+|\s+$/g;
	var normalize=/\s+/g;
	var egt=/\>/g;
	var elt=/\</g;
	var equot=/\"/g;
	var eapos=/\'/g;
	var eamp=/\&/g;
	var dNs="_def_";

	//	create a root node.
	function _doc(){
		return new (function(){
			var all={};
			this.nodeType=nodeTypes.DOCUMENT;
			this.nodeName="#document";
			this.namespaces={};
			this._nsPaths={};
			this.childNodes=[];
			this.documentElement=null;

			//	any element with an ID attribute will be added to the internal hashtable.
			this._add=function(obj){
				if(typeof(obj.id)!="undefined"){ all[obj.id]=obj; }
			};
			this._remove=function(id){
				if(all[id]){ delete all[id]; }
			};

			this.byId=this.getElementById=function(id){ return all[id]; };
			this.byName=this.getElementsByTagName=byName;
			this.byNameNS=this.getElementsByTagNameNS=byNameNS;
			this.childrenByName=childrenByName;
			this.childrenByNameNS=childrenByNameNS;
		})();
	}

	//	functions attached to element nodes
	function byName(name){
		//	return all descendants with name.  Fully qualified (i.e. svg:svg)
		function __(node, name, arr){
			dojo.forEach(node.childNodes, function(c){
				if(c.nodeType==nodeTypes.ELEMENT){
					if(name=="*"){ arr.push(c); }
					else if(c.nodeName==name){ arr.push(c); }
					__(c, name, arr);
				}
			});
		}
		var a=[];
		__(this, name, a);
		return a;
	}
	function byNameNS(name, ns){
		//	return all descendants with name by namespace.  If no namespace passed, the default is used.
		function __(node, name, ns, arr){
			dojo.forEach(node.childNodes, function(c){
				if(c.nodeType==nodeTypes.ELEMENT){
					if(name=="*"&&c.ownerDocument._nsPaths[ns]==c.namespace){ arr.push(c); }
					else if(c.localName==name&&c.ownerDocument._nsPaths[ns]==c.namespace){ arr.push(c); }
					__(c, name, ns, arr);
				}
			});
		}
		if(!ns){ ns=dNs; }
		var a=[];
		__(this, name, ns, a);
		return a;
	}
	//	Only child nodes with name.
	function childrenByName(name){
		var a=[];
		dojo.forEach(this.childNodes, function(c){
			if(c.nodeType==nodeTypes.ELEMENT){
				if(name=="*"){ a.push(c); }
				else if(c.nodeName==name){ a.push(c); }
			}
		});
		return a;
	}

	function childrenByNameNS(name, ns){
		var a=[];
		dojo.forEach(this.childNodes, function(c){
			if(c.nodeType==nodeTypes.ELEMENT){
				if(name=="*"&&c.ownerDocument._nsPaths[ns]==c.namespace){ a.push(c); }
				else if(c.localName==name&&c.ownerDocument._nsPaths[ns]==c.namespace){ a.push(c); }
			}
		});
		return a;
	}

	function _createTextNode(v){
		return {
			nodeType:nodeTypes.TEXT,
			nodeName:"#text",
			nodeValue:v.replace(normalize," ").replace(egt,">").replace(elt,"<").replace(eapos,"'").replace(equot,'"').replace(eamp,"&")
		};
	}

	//	attribute functions
	function getAttr(name){
		for(var i=0; i<this.attributes.length; i++){
			if(this.attributes[i].nodeName==name){
				return this.attributes[i].nodeValue;
			}
		}
		return null;
	}
	function getAttrNS(name, ns){
		for(var i=0; i<this.attributes.length; i++){
			if(this.ownerDocument._nsPaths[ns]==this.attributes[i].namespace
				&&this.attributes[i].localName==name
			){
				return this.attributes[i].nodeValue;
			}
		}
		return null;
	}
	//	note that you can only swap IDs using setAttribute, NOT with setAttributeNS.
	function setAttr(name, val){
		var old=null;
		for(var i=0; i<this.attributes.length; i++){
			if(this.attributes[i].nodeName==name){
				old=this.attributes[i].nodeValue;
				this.attributes[i].nodeValue=val;
				break;
			}
		}
		if(name=="id"){
			if(old!=null){ this.ownerDocument._remove(old); }
			this.ownerDocument._add(this);
		}
	}
	function setAttrNS(name, val, ns){
		for(var i=0; i<this.attributes.length; i++){
			if(this.ownerDocument._nsPaths[ns]==this.attributes[i].namespace
				&&this.attributes[i].localName==name
			){
				this.attributes[i].nodeValue=val;
				return;
			}
		}
	}

	//	navigation
	function prev(){
		var p=this.parentNode;
		if(p){
			for(var i=0;i<p.childNodes.length;i++){
				if(p.childNodes[i]==this&&i>0){
					return p.childNodes[i-1];
				}
			}
		}
		return null;
	}
	function next(){
		var p=this.parentNode;
		if(p){
			for(var i=0;i<p.childNodes.length;i++){
				if(p.childNodes[i]==this&&(i+1)<p.childNodes.length){
					return p.childNodes[i+1];
				}
			}
		}
		return null;
	}

	//	the main method.
	this.parse=function(/* String */str){
		var root=_doc();
		if(str==null){ return root; }
		if(str.length==0){ return root; }

		//	preprocess custom entities
		if(str.indexOf("<!ENTITY")>0){
			var entity, eRe=[];
			if(reEntity.test(str)){
				reEntity.lastIndex=0;
				//	match entities
				while((entity=reEntity.exec(str))!=null){
					eRe.push({
						entity:"&"+entity[1].replace(trim,"")+";",
						expression:entity[2]
					});
				}
				//	replace instances in the document.
				for(var i=0; i<eRe.length; i++){
					str=str.replace(new RegExp(eRe[i].entity, "g"), eRe[i].expression);
				}
			}
		}

		//	pre-parse for CData, and tokenize.
		var cdSections=[], cdata;
		while((cdata=reCData.exec(str))!=null){ cdSections.push(cdata[1]); }
		for(var i=0; i<cdSections.length; i++){ str=str.replace(cdSections[i], i); }

		//	pre-parse for comments, and tokenize.
		var comments=[], comment;
		while((comment=reComments.exec(str))!=null){ comments.push(comment[1]); }
		for(i=0; i<comments.length; i++){ str=str.replace(comments[i], i); }

		//	parse the document
		var res, obj=root;
		while((res=reTags.exec(str))!=null){
			//	closing tags.
			if(res[2].charAt(0)=="/" && res[2].replace(trim, "").length>1){
				if(obj.parentNode){
					obj=obj.parentNode;
				}
				var text=(res[3]||"").replace(trim, "");
				if(text.length>0) {
					obj.childNodes.push(_createTextNode(text));
				}
			}

			//	open tags.
			else if(res[1].length>0){
				//	figure out the type of node.
				if(res[1].charAt(0)=="?"){
					//	processing instruction
					var name=res[1].substr(1);
					var target=res[2].substr(0,res[2].length-2);
					obj.childNodes.push({
						nodeType:nodeTypes.PROCESSING_INSTRUCTION,
						nodeName:name,
						nodeValue:target
					});
				}
				else if(res[1].charAt(0)=="!"){
					//	CDATA; skip over any declaration elements.
					if(res[1].indexOf("![CDATA[")==0){
						var val=parseInt(res[1].replace("![CDATA[","").replace("]]",""));
						obj.childNodes.push({
							nodeType:nodeTypes.CDATA_SECTION,
							nodeName:"#cdata-section",
							nodeValue:cdSections[val]
						});
					}
					//	Comments.
					else if(res[1].substr(0,3)=="!--"){
						var val=parseInt(res[1].replace("!--","").replace("--",""));
						obj.childNodes.push({
							nodeType:nodeTypes.COMMENT,
							nodeName:"#comment",
							nodeValue:comments[val]
						});
					}
				}
				else {
					//	Elements (with attribute and text)
					var name=res[1].replace(trim,"");
					var o={
						nodeType:nodeTypes.ELEMENT,
						nodeName:name,
						localName:name,
						namespace:dNs,
						ownerDocument:root,
						attributes:[],
						parentNode:null,
						childNodes:[]
					};

					//	check to see if it's namespaced.
					if(name.indexOf(":")>-1){
						var t=name.split(":");
						o.namespace=t[0];
						o.localName=t[1];
					}

					//	set the function references.
					o.byName=o.getElementsByTagName=byName;
					o.byNameNS=o.getElementsByTagNameNS=byNameNS;
					o.childrenByName=childrenByName;
					o.childrenByNameNS=childrenByNameNS;
					o.getAttribute=getAttr;
					o.getAttributeNS=getAttrNS;
					o.setAttribute=setAttr;
					o.setAttributeNS=setAttrNS;
					o.previous=o.previousSibling=prev;
					o.next=o.nextSibling=next;

					//	parse the attribute string.
					var attr;
					while((attr=reAttr.exec(res[2]))!=null){
						if(attr.length>0){
							var name=attr[1].replace(trim,"");
							var val=(attr[4]||attr[6]||"").replace(normalize," ")
								.replace(egt,">")
								.replace(elt,"<")
								.replace(eapos,"'")
								.replace(equot,'"')
								.replace(eamp,"&");
							if(name.indexOf("xmlns")==0){
								if(name.indexOf(":")>0){
									var ns=name.split(":");
									root.namespaces[ns[1]]=val;
									root._nsPaths[val]=ns[1];
								} else {
									root.namespaces[dNs]=val;
									root._nsPaths[val]=dNs;
								}
							} else {
								var ln=name;
								var ns=dNs;
								if(name.indexOf(":")>0){
									var t=name.split(":");
									ln=t[1];
									ns=t[0];
								}
								o.attributes.push({
									nodeType:nodeTypes.ATTRIBUTE,
									nodeName:name,
									localName:ln,
									namespace:ns,
									nodeValue:val
								});

								//	only add id as a property.
								if(ln=="id"){ o.id=val; }
							}
						}
					}
					root._add(o);

					if(obj){
						obj.childNodes.push(o);
						o.parentNode=obj;
						//	if it's not a self-closing node.
						if(res[2].charAt(res[2].length-1)!="/"){
							obj=o;
						}
					}
					var text=res[3];
					if(text.length>0){
						obj.childNodes.push(_createTextNode(text));
					}
				}
			}
		}

		//	set the document element
		for(var i=0; i<root.childNodes.length; i++){
			var e=root.childNodes[i];
			if(e.nodeType==nodeTypes.ELEMENT){
				root.documentElement=e;
				break;
			}
		}
		return root;
	};
})();
return dojox.xml.DomParser;
});
<|endoftext|>


<commit_before>/**
 * TODO ADD FB SOURCE LINK
 * @flow
 */

'use strict';

import React from 'react';
import {
    View,
    Text,
    StyleSheet,
    TouchableOpacity,
    Platform
} from 'react-native';
import Colors from './Colors';
import Icon from 'react-native-vector-icons/Ionicons';

export type Layout =
    'default'      // Use platform defaults (icon on Android, text on iOS)
  | 'icon'         // Always use icon
  | 'title';       // Always use title

export type Item = {
  title?: string;
  icon?: string;
  layout?: Layout;
  onPress?: () => void;
};

export type Props = {
  title: string;
  leftItem?: Item;
  rightItem?: Item;
  extraItems?: Array<Item>;
  //foreground?: Foreground;
  style?: any;
  children?: any;
};

class HeaderIOS extends React.Component {
    props: Props;

    render() {
        const {title, leftItem, rightItem} = this.props;
        const content = React.Children.count(this.props.children) === 0
          ? <Text style={styles.titleText}>
              {title}
            </Text>
          : this.props.children;

        return (
            <View>
                <View style={[styles.header, this.props.style]}>
                    <View style={styles.leftItem}>
                        <ItemWrapperIOS item={leftItem} />
                    </View>
                    <View
                      accessible={true}
                      accessibilityLabel={title}
                      accessibilityTraits="header"
                      style={styles.centerItem}>
                      {content}
                    </View>
                    <View style={styles.leftItem}>
                        <ItemWrapperIOS item={rightItem} />
                    </View>
                </View>
            </View>
        );
    }
}

class ItemWrapperIOS extends React.Component {
    props: {
        item: Item;
    };

    render() {
        const {item} = this.props;
        if (!item) {
            return null;
        }

        let content;
        const {title, icon, layout, onPress} = item;

        if (layout !== 'icon' && title) {
            content = (
                <Text style={styles.itemText}>
                    {title.toUpperCase()}
                </Text>
            );
        } else if (icon) { // TODO GH #8 let props pass any icon set
            content =
            <Icon style={styles.icon} name={icon} size={30} />
            ;
        }

        return (
            <TouchableOpacity
                accessibilityLabel={title}
                accessibilityTraits="button"
                onPress={onPress}
                style={styles.itemWrapper}>
                {content}
            </TouchableOpacity>
        );
    }
}

let STATUS_BAR_HEIGHT = Platform.OS === 'ios' ? 20 : 25;
let HEADER_HEIGHT = Platform.OS === 'ios' ? 44 + STATUS_BAR_HEIGHT : 56 + STATUS_BAR_HEIGHT;

var styles = StyleSheet.create({
    toolbarContainer: {
        paddingTop: STATUS_BAR_HEIGHT,
    },
    toolbar: {
        height: HEADER_HEIGHT - STATUS_BAR_HEIGHT,
    },
    header: {
        backgroundColor: Colors.darkBackground,
        paddingTop: STATUS_BAR_HEIGHT,
        height: HEADER_HEIGHT,
        flex: 1,
        flexDirection: 'row',
        //justifyContent: 'space-between',
        alignItems: 'center',
    },
    titleText: {
        color: Colors.softWhite,
        fontWeight: 'bold',
        fontSize: 20,
    },
    leftItem: {
        flex: 3,
        alignItems: 'center',
    },
    centerItem: {
        flex: 4,
        alignItems: 'center',
    },
    rightItem: {
        flex: 3,
        alignItems: 'center',
    },
    itemWrapper: {
        padding: 11,
    },
    itemText: {
        letterSpacing: 1,
        fontSize: 12,
        color: 'white',
    },
    icon: {
        color: Colors.softWhite,
    }
});

const Header = HeaderIOS; // Platform.OS === 'ios' ? HeaderIOS : null; // TODO GH issue #4
//Header.height = HEADER_HEIGHT;

module.exports = Header;
<commit_msg>Fixes incorrect style prop on `rightItem`<commit_after>/**
 * TODO ADD FB SOURCE LINK
 * @flow
 */

'use strict';

import React from 'react';
import {
    View,
    Text,
    StyleSheet,
    TouchableOpacity,
    Platform
} from 'react-native';
import Colors from './Colors';
import Icon from 'react-native-vector-icons/Ionicons';

export type Layout =
    'default'      // Use platform defaults (icon on Android, text on iOS)
  | 'icon'         // Always use icon
  | 'title';       // Always use title

export type Item = {
  title?: string;
  icon?: string;
  layout?: Layout;
  onPress?: () => void;
};

export type Props = {
  title: string;
  leftItem?: Item;
  rightItem?: Item;
  extraItems?: Array<Item>;
  //foreground?: Foreground;
  style?: any;
  children?: any;
};

class HeaderIOS extends React.Component {
    props: Props;

    render() {
        const {title, leftItem, rightItem} = this.props;
        const content = React.Children.count(this.props.children) === 0
          ? <Text style={styles.titleText}>
              {title}
            </Text>
          : this.props.children;

        return (
            <View>
                <View style={[styles.header, this.props.style]}>
                    <View style={styles.leftItem}>
                        <ItemWrapperIOS item={leftItem} />
                    </View>
                    <View
                      accessible={true}
                      accessibilityLabel={title}
                      accessibilityTraits="header"
                      style={styles.centerItem}>
                      {content}
                    </View>
                    <View style={styles.rightItem}>
                        <ItemWrapperIOS item={rightItem} />
                    </View>
                </View>
            </View>
        );
    }
}

class ItemWrapperIOS extends React.Component {
    props: {
        item: Item;
    };

    render() {
        const {item} = this.props;
        if (!item) {
            return null;
        }

        let content;
        const {title, icon, layout, onPress} = item;

        if (layout !== 'icon' && title) {
            content = (
                <Text style={styles.itemText}>
                    {title.toUpperCase()}
                </Text>
            );
        } else if (icon) { // TODO GH #8 let props pass any icon set
            content =
            <Icon style={styles.icon} name={icon} size={30} />
            ;
        }

        return (
            <TouchableOpacity
                accessibilityLabel={title}
                accessibilityTraits="button"
                onPress={onPress}
                style={styles.itemWrapper}>
                {content}
            </TouchableOpacity>
        );
    }
}

let STATUS_BAR_HEIGHT = Platform.OS === 'ios' ? 20 : 25;
let HEADER_HEIGHT = Platform.OS === 'ios' ? 44 + STATUS_BAR_HEIGHT : 56 + STATUS_BAR_HEIGHT;

var styles = StyleSheet.create({
    toolbarContainer: {
        paddingTop: STATUS_BAR_HEIGHT,
    },
    toolbar: {
        height: HEADER_HEIGHT - STATUS_BAR_HEIGHT,
    },
    header: {
        backgroundColor: Colors.darkBackground,
        paddingTop: STATUS_BAR_HEIGHT,
        height: HEADER_HEIGHT,
        flex: 1,
        flexDirection: 'row',
        //justifyContent: 'space-between',
        alignItems: 'center',
    },
    titleText: {
        color: Colors.softWhite,
        fontWeight: 'bold',
        fontSize: 20,
    },
    leftItem: {
        flex: 3,
        alignItems: 'flex-start',
    },
    centerItem: {
        flex: 4,
        alignItems: 'center',
    },
    rightItem: {
        flex: 3,
        alignItems: 'flex-end',
    },
    itemWrapper: {
        padding: 11,
    },
    itemText: {
        letterSpacing: 1,
        fontSize: 12,
        color: 'white',
    },
    icon: {
        color: Colors.softWhite,
    }
});

const Header = HeaderIOS; // Platform.OS === 'ios' ? HeaderIOS : null; // TODO GH issue #4
//Header.height = HEADER_HEIGHT;

module.exports = Header;
<|endoftext|>


<commit_before>define(['marionette', 'config','i18n'],
function(Marionette,config) {
  'use strict';

  return Marionette.LayoutView.extend({
    template: 'app/base/home/tpl/tpl-tile.html',
    className: 'tile small-tile',

    initialize: function(){
      if(this.model.get('TIns_Theme')){
        var tmp = this.model.get('TIns_Theme').split('-');
        switch(tmp[0]){
          case 'track':
            this.model.set({'icon' : 'reneco-trackbird'});
            break;
          case 'securite':
            this.model.set({'icon' : 'reneco-security'});
            break;
          case 'formbuilder':
            this.model.set({'icon' : 'reneco-releve'});
            break;
          case 'thesaurus':
            this.model.set({'icon' : 'reneco-thesaurus'});
            break;
          case 'ecoll':
            this.model.set({'icon' : 'reneco-ecollectionbig'});
            break;
          case 'position':
            this.model.set({'icon' : 'reneco-positions'});
            break;
          default:
            this.model.set({'icon' : 'reneco-releve'});
            break;
        }
      }else{
        this.model.set({'icon' : 'reneco-releve'});
      }
      // set hostname
      var hostname  = window.location.hostname ;
      var appliPath = this.model.get('TIns_ApplicationPath');
      var newPath = appliPath.replace("@@hostname@@", hostname);
      this.model.set('TIns_ApplicationPath','http://' + newPath);
    }
  });

});
<commit_msg>don't need config.js in lyt-tile.js<commit_after>define(['marionette', 'i18n'],
function(Marionette) {
  'use strict';

  return Marionette.LayoutView.extend({
    template: 'app/base/home/tpl/tpl-tile.html',
    className: 'tile small-tile',

    initialize: function(){
      if(this.model.get('TIns_Theme')){
        var tmp = this.model.get('TIns_Theme').split('-');
        switch(tmp[0]){
          case 'track':
            this.model.set({'icon' : 'reneco-trackbird'});
            break;
          case 'securite':
            this.model.set({'icon' : 'reneco-security'});
            break;
          case 'formbuilder':
            this.model.set({'icon' : 'reneco-releve'});
            break;
          case 'thesaurus':
            this.model.set({'icon' : 'reneco-thesaurus'});
            break;
          case 'ecoll':
            this.model.set({'icon' : 'reneco-ecollectionbig'});
            break;
          case 'position':
            this.model.set({'icon' : 'reneco-positions'});
            break;
          default:
            this.model.set({'icon' : 'reneco-releve'});
            break;
        }
      }else{
        this.model.set({'icon' : 'reneco-releve'});
      }
      // set hostname
      var hostname  = window.location.hostname ;
      var appliPath = this.model.get('TIns_ApplicationPath');
      var newPath = appliPath.replace("@@hostname@@", hostname);
      this.model.set('TIns_ApplicationPath','http://' + newPath);
    }
  });

});
<|endoftext|>


<commit_before>// @flow
import * as React from 'react'
import {Box, ClickableBox, Icon, List, Text} from '../../common-adapters'
import {globalStyles, globalMargins, globalColors} from '../../styles'
import {NativeImage} from '../../common-adapters/native-wrappers.native'
import * as Contacts from 'react-native-contacts'
import {isAndroid} from '../../constants/platform'

import {type TeamRoleType} from '../../constants/teams'

const AccessDenied = () => (
  <Text type="BodySemibold">
    We don't have permission to access your contacts! To fix this, please open Settings > Keybase and check off 'Allow Keybase to access Contacts'.
  </Text>
)

// Note: 'on Android the entire display name is passed in the givenName field. middleName and familyName will be empty strings.'
type ContactProps = {
  recordID: string,
  company: string,
  emailAddresses: Array<{label: string, email: string}>,
  familyName: string,
  givenName: string,
  middleName: string,
  phoneNumbers: Array<{label: string, number: string}>,
  hasThumbnail: boolean,
  thumbnailPath: string,
  // Postal addresses, etc. - unused
}

type ContactRowProps = {
  contact: ContactProps,
  id: string,
  onClick: () => void,
  selected: boolean,
}

const contactRow = (i: number, props: ContactRowProps) => {
  const contactName = isAndroid
    ? props.contact.givenName
    : props.contact.givenName + ' ' + props.contact.familyName
  const source = typeof props.contact.thumbnailPath === 'string'
    ? {uri: 'file://' + props.contact.thumbnailPath}
    : props.contact.thumbnailPath
  return (
    <ClickableBox
      style={{
        ...globalStyles.flexBoxRow,
        alignItems: 'center',
        height: 48,
        width: '100%',
        padding: globalMargins.small,
      }}
      onClick={props.onClick}
      key={props.contact.recordID}
    >
      <Box style={{...globalStyles.flexBoxRow, alignItems: 'center', flex: 1}}>
        <Box style={{...globalStyles.flexBoxRow, alignItems: 'center', flex: 1}}>
          {props.contact.hasThumbnail &&
            <NativeImage style={{width: 32, height: 32, borderRadius: 16, marginRight: 8}} source={source} />}
          {!props.contact.hasThumbnail && <Box style={{width: 40}} />}
          <Text type="BodySemibold">{contactName}</Text>
          {props.contact.emailAddresses.length === 0 &&
            <Icon
              type="iconfont-open-browser"
              style={{color: globalColors.black_20, fontSize: 16, marginLeft: globalMargins.small}}
            />}
        </Box>
        {props.selected &&
          <Icon
            type="iconfont-check"
            style={{color: globalColors.blue, fontSize: 24, marginRight: globalMargins.medium}}
          />}
      </Box>
    </ClickableBox>
  )
}

type Props = {
  invitees: string,
  name: string,
  onClose: () => void,
  onInvite: () => void,
  onInviteesChange: (invitees: string) => void,
  onOpenRolePicker: (currentSelectedRole: TeamRoleType, selectedRoleCallback: (TeamRoleType) => void) => void,
  onRoleChange: (role: TeamRoleType) => void,
  role: TeamRoleType,
}

// We need inviteeIDs separate from inviteeEmails to keep track of selected contacts that don't have an email address
type State = {
  invitees: Array<{contactID: string, address?: string}>,
  loading: boolean,
  hasPermission: boolean,
  contacts: Array<any>,
}

class InviteByEmail extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props)
    this.state = {
      invitees: [],
      loading: true,
      hasPermission: false,
      contacts: [],
    }
  }

  componentWillMount() {
    if (isAndroid) {
      Contacts.requestPermission((_, granted) => {
        this.setState({hasPermission: false})
        if (granted) {
          Contacts.getAll((err, contacts) => {
            if (err) {
              this.setState({hasPermission: false})
            } else {
              this.setState({hasPermission: true, contacts})
            }
          })
        }
      })
    } else {
      Contacts.getAll((err, contacts) => {
        if (err) {
          this.setState({hasPermission: false})
        } else {
          this.setState({hasPermission: true, contacts})
          console.log('CONTACTS: ', contacts)
        }
      })
    }
  }

  onSelectContact(contact: ContactProps) {
    console.log('clicked: ', contact)

    if (this.isSelected(contact)) {
      this._removeInvitee(contact)
    } else {
      this._addInvitee(contact)
    }
  }

  isSelected(contact: ContactProps): boolean {
    return this.state.invitees.findIndex(rec => rec.contactID === contact.recordID) >= 0
  }

  _addInvitee(contact: ContactProps) {
    if (contact.emailAddresses.length > 0) {
      this.setState({
        invitees: [
          ...this.state.invitees,
          {contactID: contact.recordID, address: contact.emailAddresses[0].email},
        ],
      })
    } else {
      this.setState({
        invitees: [...this.state.invitees, {contactID: contact.recordID}],
      })
    }
  }

  _removeInvitee(contact: ContactProps) {
    const idx = this.state.invitees.findIndex(rec => rec.contactID === contact.recordID)
    if (idx < 0) {
      console.warn('Warning: attempted to remove an invitee that was not in the list.')
    } else {
      this.setState({
        invitees: this.state.invitees.filter(rec => rec.contactID !== contact.recordID),
      })
    }
  }

  render() {
    const contactRowProps = this.state.contacts.map(contact => ({
      contact,
      id: contact.recordID,
      onClick: () => this.onSelectContact(contact),
      selected: this.isSelected(contact),
    }))
    return (
      <Box style={{...globalStyles.flexBoxColumn, flex: 1}}>
        <Box style={{...globalStyles.flexBoxRow, padding: globalMargins.small}}>
          <Text type="BodySemibold">
            Select contacts to invite to {this.props.name}
          </Text>
        </Box>
        {!this.state.hasPermission && <AccessDenied />}
        {this.state.hasPermission &&
          <List
            keyProperty="id"
            items={contactRowProps}
            fixedHeight={48}
            renderItem={contactRow}
            style={{alignSelf: 'stretch'}}
          />}
      </Box>
    )
  }
}

export default InviteByEmail
<commit_msg>Styling and add icon to access denied WIP<commit_after>// @flow
import * as React from 'react'
import {Box, ClickableBox, Icon, List, Text} from '../../common-adapters'
import {globalStyles, globalMargins, globalColors} from '../../styles'
import {NativeImage} from '../../common-adapters/native-wrappers.native'
import * as Contacts from 'react-native-contacts'
import {isAndroid} from '../../constants/platform'

import {type TeamRoleType} from '../../constants/teams'

const AccessDenied = () => (
  <Box
    style={{
      ...globalStyles.flexBoxColumn,
      padding: globalMargins.small,
      alignItems: 'center',
      justifyContent: 'center',
      flex: 1,
    }}
  >
    <Icon
      type="iconfont-close"
      style={{
        color: globalColors.red,
        fontSize: globalMargins.xlarge,
        marginBottom: globalMargins.large,
      }}
    />
    <Box>
      <Text type="Body" style={{marginBottom: globalMargins.small}}>
        We don't have permission to access your contacts!
      </Text>
      <Text type="Body">
        To fix this, please open Settings > Keybase and check off 'Allow Keybase to access Contacts'.
      </Text>
    </Box>
  </Box>
)

// Note: 'on Android the entire display name is passed in the givenName field. middleName and familyName will be empty strings.'
type ContactProps = {
  recordID: string,
  company: string,
  emailAddresses: Array<{label: string, email: string}>,
  familyName: string,
  givenName: string,
  middleName: string,
  phoneNumbers: Array<{label: string, number: string}>,
  hasThumbnail: boolean,
  thumbnailPath: string,
  // Postal addresses, etc. - unused
}

type ContactRowProps = {
  contact: ContactProps,
  id: string,
  onClick: () => void,
  selected: boolean,
}

const contactRow = (i: number, props: ContactRowProps) => {
  const contactName = isAndroid
    ? props.contact.givenName
    : props.contact.givenName + ' ' + props.contact.familyName
  const source = typeof props.contact.thumbnailPath === 'string'
    ? {uri: 'file://' + props.contact.thumbnailPath}
    : props.contact.thumbnailPath
  return (
    <ClickableBox
      style={{
        ...globalStyles.flexBoxRow,
        alignItems: 'center',
        height: 48,
        width: '100%',
        padding: globalMargins.small,
      }}
      onClick={props.onClick}
      key={props.contact.recordID}
    >
      <Box style={{...globalStyles.flexBoxRow, alignItems: 'center', flex: 1}}>
        <Box style={{...globalStyles.flexBoxRow, alignItems: 'center', flex: 1}}>
          {props.contact.hasThumbnail &&
            <NativeImage style={{width: 32, height: 32, borderRadius: 16, marginRight: 8}} source={source} />}
          {!props.contact.hasThumbnail && <Box style={{width: 40}} />}
          <Text type="Body">{contactName}</Text>
          {props.contact.emailAddresses.length === 0 &&
            <Icon
              type="iconfont-open-browser"
              style={{color: globalColors.black_20, fontSize: 16, marginLeft: globalMargins.small}}
            />}
        </Box>
        {props.selected &&
          <Icon
            type="iconfont-check"
            style={{color: globalColors.blue, fontSize: 24, marginRight: globalMargins.medium}}
          />}
      </Box>
    </ClickableBox>
  )
}

type Props = {
  invitees: string,
  name: string,
  onClose: () => void,
  onInvite: () => void,
  onInviteesChange: (invitees: string) => void,
  onOpenRolePicker: (currentSelectedRole: TeamRoleType, selectedRoleCallback: (TeamRoleType) => void) => void,
  onRoleChange: (role: TeamRoleType) => void,
  role: TeamRoleType,
}

// We need inviteeIDs separate from inviteeEmails to keep track of selected contacts that don't have an email address
type State = {
  invitees: Array<{contactID: string, address?: string}>,
  loading: boolean,
  hasPermission: boolean,
  contacts: Array<any>,
}

class InviteByEmail extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props)
    this.state = {
      invitees: [],
      loading: true,
      hasPermission: false,
      contacts: [],
    }
  }

  componentWillMount() {
    if (isAndroid) {
      Contacts.requestPermission((_, granted) => {
        this.setState({hasPermission: false})
        if (granted) {
          Contacts.getAll((err, contacts) => {
            if (err) {
              this.setState({hasPermission: false})
            } else {
              this.setState({hasPermission: true, contacts})
            }
          })
        }
      })
    } else {
      Contacts.getAll((err, contacts) => {
        if (err) {
          this.setState({hasPermission: false})
        } else {
          this.setState({hasPermission: true, contacts})
          console.log('CONTACTS: ', contacts)
        }
      })
    }
  }

  onSelectContact(contact: ContactProps) {
    console.log('clicked: ', contact)

    if (this.isSelected(contact)) {
      this._removeInvitee(contact)
    } else {
      this._addInvitee(contact)
    }
  }

  isSelected(contact: ContactProps): boolean {
    return this.state.invitees.findIndex(rec => rec.contactID === contact.recordID) >= 0
  }

  _addInvitee(contact: ContactProps) {
    if (contact.emailAddresses.length > 0) {
      this.setState({
        invitees: [
          ...this.state.invitees,
          {contactID: contact.recordID, address: contact.emailAddresses[0].email},
        ],
      })
    } else {
      this.setState({
        invitees: [...this.state.invitees, {contactID: contact.recordID}],
      })
    }
  }

  _removeInvitee(contact: ContactProps) {
    const idx = this.state.invitees.findIndex(rec => rec.contactID === contact.recordID)
    if (idx < 0) {
      console.warn('Warning: attempted to remove an invitee that was not in the list.')
    } else {
      this.setState({
        invitees: this.state.invitees.filter(rec => rec.contactID !== contact.recordID),
      })
    }
  }

  render() {
    const contactRowProps = this.state.contacts.map(contact => ({
      contact,
      id: contact.recordID,
      onClick: () => this.onSelectContact(contact),
      selected: this.isSelected(contact),
    }))
    return (
      <Box style={{...globalStyles.flexBoxColumn, flex: 1}}>
        {!this.state.hasPermission && <AccessDenied />}
        {this.state.hasPermission &&
          <Box style={{...globalStyles.flexBoxRow, padding: globalMargins.small}}>
            <Text type="Body">
              Select contacts to invite to {this.props.name}
            </Text>
          </Box>}
        {this.state.hasPermission &&
          <List
            keyProperty="id"
            items={contactRowProps}
            fixedHeight={48}
            renderItem={contactRow}
            style={{alignSelf: 'stretch'}}
          />}
      </Box>
    )
  }
}

export default InviteByEmail
<|endoftext|>


<commit_before>var Debug = require("debug");
var config = require("config");

// Export a version of this function which does nothing in production
if (config.environment !== "development") {
  module.exports = function () {
    return function (req, res, next) {
      req.trace = function () {};
      next();
    };
  };

  module.exports.init = function (req, res, next) {
    next();
  };

  return;
}

function prefix(req) {
  return "blot:trace:" + req.originalUrl;
}

module.exports = function (message) {
  return function (req, res, next) {
    req.trace(message);
    next();
  };
};

module.exports.init = function (req, res, next) {
  var start = Date.now();

  if (req.trace) {
    throw new Error('Already definied');
  }

  req.trace = Debug(prefix(req));
  req.trace("request recieved (init invoked)");

  res.on("finish", function () {
    var duration = Date.now() - start;
    req.trace("\x1b[32m%s\x1b[0m", duration + "ms", "taken to finish response");
  });

  next();
};
<commit_msg>Fixes trace in local mode<commit_after>var Debug = require("debug");
var config = require("config");

// Export a version of this function which does nothing in production
if (config.environment !== "development") {
  module.exports = function () {
    return function (req, res, next) {
      req.trace = function () {};
      next();
    };
  };

  module.exports.init = function (req, res, next) {
    next();
  };

  return;
}

function prefix(req) {
  return "blot:trace:" + req.originalUrl;
}

module.exports = function (message) {
  return function (req, res, next) {
    if (req.trace) req.trace(message);
    next();
  };
};

module.exports.init = function (req, res, next) {
  var start = Date.now();

  if (req.trace) {
    throw new Error('Already definied');
  }

  req.trace = Debug(prefix(req));
  req.trace("request recieved (init invoked)");

  res.on("finish", function () {
    var duration = Date.now() - start;
    req.trace("\x1b[32m%s\x1b[0m", duration + "ms", "taken to finish response");
  });

  next();
};
<|endoftext|>


<commit_before>var express = require('express'),
	router = express.Router(),
	net = require('net'),
	fs = require('fs'),
	socketPath = '/tmp/haproxy';

/* GET home page. */
router.post('/', function(req, res) {
	// console.log(req.body);
	// you can get commit information from request body

	var client = net.createConnection(socketPath);

	client.on('connect', function () {
		console.log('check connection');

		var writeResult = client.write('show health');

		console.log(writeResult);

		client.on('data', function (data) {
			console.log('read here');
			console.log('DATA: '+data);
		});
	});

	/*
	fs.stat(socketPath, function (err) {
		if (!err) {
			fs.unlinkSync(socketPath);
			return;
		}

		var unixServer = net.createServer(function (sock) {
			sock.write('show health');

			sock.on('data', function (data) {
				winston.debug('DATA: '+data);
				sock.destroy();
			});

		}).listen(socketPath);
	});
	*/

	res.send('complete');
});

module.exports = router;
<commit_msg>Add error checking method<commit_after>var express = require('express'),
	router = express.Router(),
	net = require('net'),
	fs = require('fs'),
	socketPath = '/tmp/haproxy';

/* GET home page. */
router.post('/', function(req, res) {
	// console.log(req.body);
	// you can get commit information from request body

	var client = net.createConnection(socketPath);

	client.on('connect', function () {
		console.log('check connection');

		var writeResult = client.write('show health');
		console.log(writeResult);
	});

	client.on('data', function (data) {
		console.log('read here');
		console.log('DATA: '+data);
	});

	client.on('error', function (error) {
		console.log('Error Connection: '+error);
	});

	res.send('complete');
});

module.exports = router;
<|endoftext|>


<commit_before>/**
 * Prism: Lightweight, robust, elegant syntax highlighting
 * MIT license http://www.opensource.org/licenses/mit-license.php/
 * @author Lea Verou http://lea.verou.me
 */(function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){var n=t.util.type(e);switch(n){case"Object":var r={};for(var i in e)e.hasOwnProperty(i)&&(r[i]=t.util.clone(e[i]));return r;case"Array":return e.slice()}return e}},languages:{extend:function(e,n){var r=t.util.clone(t.languages[e]);for(var i in n)r[i]=n[i];return r},insertBefore:function(e,n,r,i){i=i||t.languages;var s=i[e],o={};for(var u in s)if(s.hasOwnProperty(u)){if(u==n)for(var a in r)r.hasOwnProperty(a)&&(o[a]=r[a]);o[u]=s[u]}return i[e]=o},DFS:function(e,n){for(var r in e){n.call(e,r,e[r]);t.util.type(e)==="Object"&&t.languages.DFS(e[r],n)}}},highlightAll:function(e,n){var r=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');for(var i=0,s;s=r[i++];)t.highlightElement(s,e===!0,n)},highlightElement:function(r,i,s){var o,u,a=r;while(a&&!e.test(a.className))a=a.parentNode;if(a){o=(a.className.match(e)||[,""])[1];u=t.languages[o]}if(!u)return;r.className=r.className.replace(e,"").replace(/\s+/g," ")+" language-"+o;a=r.parentNode;/pre/i.test(a.nodeName)&&(a.className=a.className.replace(e,"").replace(/\s+/g," ")+" language-"+o);var f=r.textContent;if(!f)return;f=f.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ");var l={element:r,language:o,grammar:u,code:f};t.hooks.run("before-highlight",l);if(i&&self.Worker){var c=new Worker(t.filename);c.onmessage=function(e){l.highlightedCode=n.stringify(JSON.parse(e.data),o);t.hooks.run("before-insert",l);l.element.innerHTML=l.highlightedCode;s&&s.call(l.element);t.hooks.run("after-highlight",l)};c.postMessage(JSON.stringify({language:l.language,code:l.code}))}else{l.highlightedCode=t.highlight(l.code,l.grammar,l.language);t.hooks.run("before-insert",l);l.element.innerHTML=l.highlightedCode;s&&s.call(r);t.hooks.run("after-highlight",l)}},highlight:function(e,r,i){return n.stringify(t.tokenize(e,r),i)},tokenize:function(e,n,r){var i=t.Token,s=[e],o=n.rest;if(o){for(var u in o)n[u]=o[u];delete n.rest}e:for(var u in n){if(!n.hasOwnProperty(u)||!n[u])continue;var a=n[u],f=a.inside,l=!!a.lookbehind,c=0;a=a.pattern||a;for(var h=0;h<s.length;h++){var p=s[h];if(s.length>e.length)break e;if(p instanceof i)continue;a.lastIndex=0;var d=a.exec(p);if(d){l&&(c=d[1].length);var v=d.index-1+c,d=d[0].slice(c),m=d.length,g=v+m,y=p.slice(0,v+1),b=p.slice(g+1),w=[h,1];y&&w.push(y);var E=new i(u,f?t.tokenize(d,f):d);w.push(E);b&&w.push(b);Array.prototype.splice.apply(s,w)}}}return s},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[];r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(!r||!r.length)return;for(var i=0,s;s=r[i++];)s(n)}}},n=t.Token=function(e,t){this.type=e;this.content=t};n.stringify=function(e,r,i){if(typeof e=="string")return e;if(Object.prototype.toString.call(e)=="[object Array]")return e.map(function(t){return n.stringify(t,r,e)}).join("");var s={type:e.type,content:n.stringify(e.content,r,i),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:i};s.type=="comment"&&(s.attributes.spellcheck="true");t.hooks.run("wrap",s);var o="";for(var u in s.attributes)o+=u+'="'+(s.attributes[u]||"")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'" '+o+">"+s.content+"</"+s.tag+">"};if(!self.document){self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,i=n.code;self.postMessage(JSON.stringify(t.tokenize(i,t.languages[r])));self.close()},!1);return}var r=document.getElementsByTagName("script");r=r[r.length-1];if(r){t.filename=r.src;document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)}})();<commit_msg>Updated minified files<commit_after>var self=typeof window!="undefined"?window:{},Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){var n=t.util.type(e);switch(n){case"Object":var r={};for(var i in e)e.hasOwnProperty(i)&&(r[i]=t.util.clone(e[i]));return r;case"Array":return e.slice()}return e}},languages:{extend:function(e,n){var r=t.util.clone(t.languages[e]);for(var i in n)r[i]=n[i];return r},insertBefore:function(e,n,r,i){i=i||t.languages;var s=i[e],o={};for(var u in s)if(s.hasOwnProperty(u)){if(u==n)for(var a in r)r.hasOwnProperty(a)&&(o[a]=r[a]);o[u]=s[u]}return i[e]=o},DFS:function(e,n){for(var r in e){n.call(e,r,e[r]);t.util.type(e)==="Object"&&t.languages.DFS(e[r],n)}}},highlightAll:function(e,n){var r=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');for(var i=0,s;s=r[i++];)t.highlightElement(s,e===!0,n)},highlightElement:function(r,i,s){var o,u,a=r;while(a&&!e.test(a.className))a=a.parentNode;if(a){o=(a.className.match(e)||[,""])[1];u=t.languages[o]}if(!u)return;r.className=r.className.replace(e,"").replace(/\s+/g," ")+" language-"+o;a=r.parentNode;/pre/i.test(a.nodeName)&&(a.className=a.className.replace(e,"").replace(/\s+/g," ")+" language-"+o);var f=r.textContent;if(!f)return;f=f.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ");var l={element:r,language:o,grammar:u,code:f};t.hooks.run("before-highlight",l);if(i&&self.Worker){var c=new Worker(t.filename);c.onmessage=function(e){l.highlightedCode=n.stringify(JSON.parse(e.data),o);t.hooks.run("before-insert",l);l.element.innerHTML=l.highlightedCode;s&&s.call(l.element);t.hooks.run("after-highlight",l)};c.postMessage(JSON.stringify({language:l.language,code:l.code}))}else{l.highlightedCode=t.highlight(l.code,l.grammar,l.language);t.hooks.run("before-insert",l);l.element.innerHTML=l.highlightedCode;s&&s.call(r);t.hooks.run("after-highlight",l)}},highlight:function(e,r,i){return n.stringify(t.tokenize(e,r),i)},tokenize:function(e,n,r){var i=t.Token,s=[e],o=n.rest;if(o){for(var u in o)n[u]=o[u];delete n.rest}e:for(var u in n){if(!n.hasOwnProperty(u)||!n[u])continue;var a=n[u],f=a.inside,l=!!a.lookbehind,c=0;a=a.pattern||a;for(var h=0;h<s.length;h++){var p=s[h];if(s.length>e.length)break e;if(p instanceof i)continue;a.lastIndex=0;var d=a.exec(p);if(d){l&&(c=d[1].length);var v=d.index-1+c,d=d[0].slice(c),m=d.length,g=v+m,y=p.slice(0,v+1),b=p.slice(g+1),w=[h,1];y&&w.push(y);var E=new i(u,f?t.tokenize(d,f):d);w.push(E);b&&w.push(b);Array.prototype.splice.apply(s,w)}}}return s},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[];r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(!r||!r.length)return;for(var i=0,s;s=r[i++];)s(n)}}},n=t.Token=function(e,t){this.type=e;this.content=t};n.stringify=function(e,r,i){if(typeof e=="string")return e;if(Object.prototype.toString.call(e)=="[object Array]")return e.map(function(t){return n.stringify(t,r,e)}).join("");var s={type:e.type,content:n.stringify(e.content,r,i),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:i};s.type=="comment"&&(s.attributes.spellcheck="true");t.hooks.run("wrap",s);var o="";for(var u in s.attributes)o+=u+'="'+(s.attributes[u]||"")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'" '+o+">"+s.content+"</"+s.tag+">"};if(!self.document){if(!self.addEventListener)return self.Prism;self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,i=n.code;self.postMessage(JSON.stringify(t.tokenize(i,t.languages[r])));self.close()},!1);return self.Prism}var r=document.getElementsByTagName("script");r=r[r.length-1];if(r){t.filename=r.src;document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)}return self.Prism}();typeof module!="undefined"&&module.exports&&(module.exports=Prism);<|endoftext|>