<commit_before>$(function(){
	window.viewport = {
		width  : $(window).width(),
		height : $(window).height()
	};
	window.pageNavigatorTouch = {
		start		: {},
		end			: {},
		startTimer	: null
	};
	//$("#pagenavigator").on("touchstart", touchDownHandle)
	var pagenavigator = document.getElementById("pagenavigator");
	pagenavigator.addEventListener("touchstart",touchDownHandle,false);
	pagenavigator.addEventListener("click",function(e){
		e.stopPropagation();
		e.preventDefault();
	},true);
	$("body").on("scroll",function(e){
		e.stopPropagation();
		e.preventDefault();
	});
	//document.addEventListener("touchstart",touchDownHandle,false);
	window.transitionEnd = whichTransitionEvent(document.getElementById('pagenavigator'));
	loadCards();
});

function whichTransitionEvent(el){
    var t;
    var transitions = {
      'transition':'transitionend',
      'OTransition':'oTransitionEnd',
      'MozTransition':'transitionend',
      'WebkitTransition':'webkitTransitionEnd'
    }

    for(t in transitions){
        if( el.style[t] !== undefined ){
            return transitions[t];
        }
    }
}

function touchDownHandle(event){
	event.stopPropagation();
	event.preventDefault();

	//document.removeEventListener("touchstart",touchDownHandle);

	//console.log("touch start :" + event.touches[0].pageX);
	pageNavigatorTouch.startTimer = Date.now();
	$("#pagenavigator").removeClass("slide-animation");
	//pageNavigatorTouch.start = event.originalEvent.touches[0];
	//$("#pagenavigator").on("touchmove", touchMoveHandle);
	//$("#pagenavigator").one("touchend", touchUpHandle);

	pageNavigatorTouch.start = jQuery.extend({}, event.touches[0]);
	var pagenavigator = document.getElementById("pagenavigator");
	pagenavigator.addEventListener("touchmove",touchMoveHandle,false);
	pagenavigator.addEventListener("touchend",touchUpHandle,false);
};

function touchMoveHandle(event){
	event.stopPropagation();
	event.preventDefault();
	//console.log("touch move");
	//pageNavigatorTouch.end = event.originalEvent.touches[0];
	pageNavigatorTouch.end = event.touches[0];
	movePercent = ((pageNavigatorTouch.end.pageX - pageNavigatorTouch.start.pageX) / viewport.width) * 100;
	//console.log("distance : " +pageNavigatorTouch.start.pageX);
	////console.log("=> movePercent : ", movePercent);
	$("#pagenavigator").css({
		"-webkit-transform": "translate3d("+ (movePercent/3) +"% ,0 ,0)",
		"transform": "translate3d("+ (movePercent/3) +"% ,0 ,0)"
		//left : -100 + movePercent +"%"
	});
};

function touchUpHandle(event){
	event.stopPropagation();
	event.preventDefault();
	//console.log("touch end")
	//$("#pagenavigator").off("touchmove", touchMoveHandle);
	var pagenavigator = document.getElementById("pagenavigator");
	pagenavigator.removeEventListener("touchmove",touchMoveHandle);
	pagenavigator.removeEventListener("touchend",touchUpHandle);

	var distance = (pageNavigatorTouch.end.pageX - pageNavigatorTouch.start.pageX);
	//console.log("distance : " + distance);
	movePercent = (distance / viewport.width) * 100;
	//swipe or slide
	isSwipe = ((Date.now() - pageNavigatorTouch.startTimer) < 250) && (Math.abs(distance) > 75) ? true : false;
	////console.log("=> movePercent : ", movePercent);
	$("#pagenavigator").addClass("slide-animation");
	if (Math.abs(movePercent) < 40){
		if(isSwipe){
			preformPageSlide(movePercent);
		}else{
			pageSlideReset();
		}
	} else {
		preformPageSlide(movePercent);
	};
};

function preformPageSlide(movePercent){
	//console.log("pageSlide");
	if(movePercent < 0){
		pageSlideLeft();
	} else {
		pageSlideRight();
	}
};

function pageSlideReset(){
	$("#pagenavigator").css({
		"transform": "translate3d(0,0,0)",
		"-webkit-transform": "translate3d(0,0,0)"
	});
}
function pageSlideLeft(){
	$("#pagenavigator").css({
		"transform": "translate3d(-33.3%,0,0)",
		"-webkit-transform": "translate3d(-33.3%,0,0)"
	}).one(window.transitionEnd, function(event){
		event.stopPropagation();
		event.preventDefault();
		//console.log("transition ended");
		var nextCard = $("#nextCardHolder div").data("cardInfo");
		showCard(nextCard);
	});
	//console.log('slideLeft: end');
}
function pageSlideRight(){
	//console.log('slideRight');
	$("#pagenavigator").one(window.transitionEnd, function(event){
		event.stopPropagation();
		event.preventDefault();
		//console.log("transition ended");
		var previousCard = $("#previousCardHolder div").data("cardInfo");
		showCard(previousCard);
	}).css({
		"transform": "translate3d(33.3%,0,0)",
		"-webkit-transform": "translate3d(33.3%,0,0)"
	});
}
function loadCards(){
	$.getJSON("data/data.json",function(data){
		//console.log("success loading data")
		try{
			//console.log(data.kaarten.length + "cards loaded");
			cards = data.kaarten;
			//setupNavigation();
			processCardData();
		} catch(err){
			//console.error(err);
		}
		//app.setupNavigation();
	})
	.fail(function() {
		console.error( "error loading data" );
	})
}

function showCard(cardInfo){
	//console.log("showCard");
	var mainCardIndex		= cards.indexOf(cardInfo),
		nextCardIndex 		= mainCardIndex+1 > cards.length ? -1 : mainCardIndex+1,
		previousCardIndex 	= mainCardIndex-1;

	$("#pagenavigator").removeClass("slide-animation"); //disable animation
	////console.log("showCards : ", previousIndex, mainIndex, nextIndex);
	$("#menu .pure-menu-selected").removeClass("pure-menu-selected");

	$('[href="#'+cardInfo.id+'"]').parent().addClass("pure-menu-selected");

	switch (cardInfo){
		case $("#nextCardHolder").data("cardInfo"):		//next card is selected
				$("#preloader").append($("#previous div"));	//store in carddeck
				$("#previousCardHolder").append($("#mainCardHolder div"));
				$("#mainCardHolder").append($("#nextCardHolder div"));
				pageSlideReset();
				$("#nextCardHolder").append($("#"+cards[nextCardIndex].id));
			break;
		case $("#previousCardHolder").data("cardInfo"):	// previous card is selected
				$("#preloader").append($("#nextCardHolder div"));	//store in carddeck
				$("#nextCardHolder").append($("#mainCardHolder div"));
				$("#mainCardHolder").append($("#previousCardHolder div"));
				pageSlideReset();
				$("#previousCardHolder").append($("#"+cards[nextCardIndex].id));
			break;
		default:							// no card selected
				$("#preloader").append($("#nextCardHolder div, #mainCardHolder div, #previousCardHolder div"));	//store in carddeck
				$("#mainCardHolder").append($("#"+cards[mainCardIndex].id));
				pageSlideReset();
				try{
					$("#previousCardHolder").append($("#"+cards[previousCardIndex].id));
				} catch(err) {
				}
				try{
					$("#nextCardHolder").append($("#"+cards[nextCardIndex].id));
				} catch(err) {
				}

			break;
	}

}

function processCardData(){
	//console.log('processCardData')
	var prevCardId = "", nextCardId = "";
	$.each(cards, function(index, value){
		if(index != cards.length-1){
			nextCardId = cards[index+1].naam;
		} else {
			nextCardId = "";
		}
		//addCardPage(value, {prev : prevCardId, next : nextCardId});
		addCardlinkToNavigation(value);
		prevCardId = value.naam;
	});
	//setTimeout( function(){$.mobile.changePage( "#"+cards[0].naam );}, 2500);
	showCard(cards[0]);
};
function addCardlinkToNavigation(card){
	//console.log('addCardlinkToNavigation')

	$( "
"+card.titel+"
" ).appendTo( "#cardsnavigation ul" ).on("click", loadCard);
	$("
").appendTo("#preloader");
	$("#"+card.id).data("cardInfo",card);

};

function loadCard(event){
	event.preventDefault();
	event.stopPropagation();
	//console.log('click', event);
	if($('#layout').hasClass('active')){
		showCard($($(event.target).attr('href')).data("cardInfo"));
		$('#layout, #menu, #menulink').toggleClass('active');
	}
}

<commit_msg>alpha2<commit_after>$(function(){
	window.viewport = {
		width  : $(window).width(),
		height : $(window).height()
	};
	window.pageNavigatorTouch = {
		start		: {},
		end			: {},
		startTimer	: null
	};
	//$("#pagenavigator").on("touchstart", touchDownHandle)
	var pagenavigator = document.getElementById("pagenavigator");
	pagenavigator.addEventListener("touchstart",touchDownHandle,false);
	pagenavigator.addEventListener("click",function(e){
		e.stopPropagation();
		e.preventDefault();
	},true);
	$("body").on("scroll",function(e){
		e.stopPropagation();
		e.preventDefault();
	});
	//document.addEventListener("touchstart",touchDownHandle,false);
	window.transitionEnd = whichTransitionEvent(document.getElementById('pagenavigator'));
	loadCards();
});

function whichTransitionEvent(el){
    var t;
    var transitions = {
      'transition':'transitionend',
      'OTransition':'oTransitionEnd',
      'MozTransition':'transitionend',
      'WebkitTransition':'webkitTransitionEnd'
    }

    for(t in transitions){
        if( el.style[t] !== undefined ){
            return transitions[t];
        }
    }
}

function touchDownHandle(event){
	event.stopPropagation();
	event.preventDefault();

	//document.removeEventListener("touchstart",touchDownHandle);

	//console.log("touch start :" + event.touches[0].pageX);
	pageNavigatorTouch.startTimer = Date.now();
	$("#pagenavigator").removeClass("slide-animation");
	//pageNavigatorTouch.start = event.originalEvent.touches[0];
	//$("#pagenavigator").on("touchmove", touchMoveHandle);
	//$("#pagenavigator").one("touchend", touchUpHandle);

	pageNavigatorTouch.start = jQuery.extend({}, event.touches[0]);
	var pagenavigator = document.getElementById("pagenavigator");
	pagenavigator.addEventListener("touchmove",touchMoveHandle,false);
	pagenavigator.addEventListener("touchend",touchUpHandle,false);
};

function touchMoveHandle(event){
	event.stopPropagation();
	event.preventDefault();
	//console.log("touch move");
	//pageNavigatorTouch.end = event.originalEvent.touches[0];
	pageNavigatorTouch.end = event.touches[0];
	movePercent = ((pageNavigatorTouch.end.pageX - pageNavigatorTouch.start.pageX) / viewport.width) * 100;
	//console.log("distance : " +pageNavigatorTouch.start.pageX);
	////console.log("=> movePercent : ", movePercent);
	$("#pagenavigator").css({
		"-webkit-transform": "translate3d("+ (movePercent/3) +"% ,0 ,0)",
		"transform": "translate3d("+ (movePercent/3) +"% ,0 ,0)"
		//left : -100 + movePercent +"%"
	});
};

function touchUpHandle(event){
	event.stopPropagation();
	event.preventDefault();
	//console.log("touch end")
	//$("#pagenavigator").off("touchmove", touchMoveHandle);
	var pagenavigator = document.getElementById("pagenavigator");
	pagenavigator.removeEventListener("touchmove",touchMoveHandle);
	pagenavigator.removeEventListener("touchend",touchUpHandle);

	try{
		var distance = (pageNavigatorTouch.end.pageX - pageNavigatorTouch.start.pageX);
		//console.log("distance : " + distance);
		movePercent = (distance / viewport.width) * 100;
		//swipe or slide
		isSwipe = ((Date.now() - pageNavigatorTouch.startTimer) < 250) && (Math.abs(distance) > 75) ? true : false;
		////console.log("=> movePercent : ", movePercent);
		$("#pagenavigator").addClass("slide-animation");
		if (Math.abs(movePercent) < 40){
			if(isSwipe){
				preformPageSlide(movePercent);
			}else{
				pageSlideReset();
			}
		} else {
			preformPageSlide(movePercent);
		};
		pageNavigatorTouch.end = pageNavigatorTouch.start = null;
	} catch(e){

	}
};

function preformPageSlide(movePercent){
	//console.log("pageSlide");
	if(movePercent < 0){
		pageSlideLeft();
	} else {
		pageSlideRight();
	}
};

function pageSlideReset(){
	$("#pagenavigator").css({
		"transform": "translate3d(0,0,0)",
		"-webkit-transform": "translate3d(0,0,0)"
	});
}
function pageSlideLeft(){
	$("#pagenavigator").css({
		"transform": "translate3d(-33.3%,0,0)",
		"-webkit-transform": "translate3d(-33.3%,0,0)"
	}).one(window.transitionEnd, function(event){
		event.stopPropagation();
		event.preventDefault();
		//console.log("transition ended");
		var nextCard = $("#nextCardHolder div").data("cardInfo");
		showCard(nextCard);
	});
	//console.log('slideLeft: end');
}
function pageSlideRight(){
	//console.log('slideRight');
	$("#pagenavigator").one(window.transitionEnd, function(event){
		event.stopPropagation();
		event.preventDefault();
		//console.log("transition ended");
		var previousCard = $("#previousCardHolder div").data("cardInfo");
		showCard(previousCard);
	}).css({
		"transform": "translate3d(33.3%,0,0)",
		"-webkit-transform": "translate3d(33.3%,0,0)"
	});
}
function loadCards(){
	$.getJSON("data/data.json",function(data){
		//console.log("success loading data")
		try{
			//console.log(data.kaarten.length + "cards loaded");
			cards = data.kaarten;
			//setupNavigation();
			processCardData();
		} catch(err){
			//console.error(err);
		}
		//app.setupNavigation();
	})
	.fail(function() {
		console.error( "error loading data" );
	})
}

function showCard(cardInfo){
	//console.log("showCard");
	var mainCardIndex		= cards.indexOf(cardInfo),
		nextCardIndex 		= mainCardIndex+1 > cards.length ? -1 : mainCardIndex+1,
		previousCardIndex 	= mainCardIndex-1;

	$("#pagenavigator").removeClass("slide-animation"); //disable animation
	////console.log("showCards : ", previousIndex, mainIndex, nextIndex);
	$("#menu .pure-menu-selected").removeClass("pure-menu-selected");

	$('[href="#'+cardInfo.id+'"]').parent().addClass("pure-menu-selected");

	switch (cardInfo){
		case $("#nextCardHolder").data("cardInfo"):		//next card is selected
				$("#preloader").append($("#previous div"));	//store in carddeck
				$("#previousCardHolder").append($("#mainCardHolder div"));
				$("#mainCardHolder").append($("#nextCardHolder div"));
				pageSlideReset();
				$("#nextCardHolder").append($("#"+cards[nextCardIndex].id));
			break;
		case $("#previousCardHolder").data("cardInfo"):	// previous card is selected
				$("#preloader").append($("#nextCardHolder div"));	//store in carddeck
				$("#nextCardHolder").append($("#mainCardHolder div"));
				$("#mainCardHolder").append($("#previousCardHolder div"));
				pageSlideReset();
				$("#previousCardHolder").append($("#"+cards[nextCardIndex].id));
			break;
		default:							// no card selected
				$("#preloader").append($("#nextCardHolder div, #mainCardHolder div, #previousCardHolder div"));	//store in carddeck
				$("#mainCardHolder").append($("#"+cards[mainCardIndex].id));
				pageSlideReset();
				try{
					$("#previousCardHolder").append($("#"+cards[previousCardIndex].id));
				} catch(err) {
				}
				try{
					$("#nextCardHolder").append($("#"+cards[nextCardIndex].id));
				} catch(err) {
				}

			break;
	}

}

function processCardData(){
	//console.log('processCardData')
	var prevCardId = "", nextCardId = "";
	$.each(cards, function(index, value){
		if(index != cards.length-1){
			nextCardId = cards[index+1].naam;
		} else {
			nextCardId = "";
		}
		//addCardPage(value, {prev : prevCardId, next : nextCardId});
		addCardlinkToNavigation(value);
		prevCardId = value.naam;
	});
	//setTimeout( function(){$.mobile.changePage( "#"+cards[0].naam );}, 2500);
	showCard(cards[0]);
};
function addCardlinkToNavigation(card){
	//console.log('addCardlinkToNavigation')

	$( "
"+card.titel+"
" ).appendTo( "#cardsnavigation ul" ).on("click", loadCard);
	$("
").appendTo("#preloader");
	$("#"+card.id).data("cardInfo",card);

};

function loadCard(event){
	event.preventDefault();
	event.stopPropagation();
	//console.log('click', event);
	if($('#layout').hasClass('active')){
		showCard($($(event.target).attr('href')).data("cardInfo"));
		$('#layout, #menu, #menulink').toggleClass('active');
	}
}

<|endoftext|>


<commit_before>/* coding: utf-8
 *
 * maposmatic, the web front-end of the MapOSMatic city map generation system
 * Copyright (C) 2009 David Decotigny
 * Copyright (C) 2009 Frédéric Lehobey
 * Copyright (C) 2009 David Mentré
 * Copyright (C) 2009 Maxime Petazzoni
 * Copyright (C) 2009 Thomas Petazzoni
 * Copyright (C) 2009 Gaël Utard
 * Copyright (C) 2009 Étienne Loks
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * See the file COPYING for details.
 */

/* OSM slippy map management. */

var map = null;
var update_lock = 0;
var epsg_display_projection = new OpenLayers.Projection('EPSG:4326');
var epsg_projection = new OpenLayers.Projection('EPSG:900913');

function getUpperLeftLat() { return document.getElementById('lat_upper_left'); }
function getUpperLeftLon() { return document.getElementById('lon_upper_left'); }
function getBottomRightLat() { return document.getElementById('lat_bottom_right'); }
function getBottomRightLon() { return document.getElementById('lon_bottom_right'); }

/** Map Zoom/Move events callback: update form fields on zoom action. */
function updateForm()
{
    if (update_lock)
      return;

    var bounds = map.getExtent();

    var topleft = new OpenLayers.LonLat(bounds.left, bounds.top);
    topleft = topleft.transform(epsg_projection, epsg_display_projection);

    var bottomright = new OpenLayers.LonLat(bounds.right, bounds.bottom);
    bottomright = bottomright.transform(epsg_projection, epsg_display_projection);

    getUpperLeftLat().value = topleft.lat.toFixed(4);
    getUpperLeftLon().value = topleft.lon.toFixed(4);
    getBottomRightLat().value = bottomright.lat.toFixed(4);
    getBottomRightLon().value = bottomright.lon.toFixed(4);
}

/* Update the map on form field modification. */
function updateMap()
{
    var bounds = new OpenLayers.Bounds(getUpperLeftLon().value,
                                       getUpperLeftLat().value,
                                       getBottomRightLon().value,
                                       getBottomRightLat().value);
    bounds.transform(epsg_display_projection, epsg_projection);

    update_lock = 1;
    map.zoomToExtent(bounds);
    update_lock = 0;
}

/* Main initialisation function. Must be called before the map is manipulated. */
function mapInit()
{
    map = new OpenLayers.Map ('map', {
        controls:[new OpenLayers.Control.Navigation(),
                  new OpenLayers.Control.PanZoomBar(),
                  new OpenLayers.Control.Attribution()],
        maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
        numZoomLevels: 18,
        maxResolution: 156543.0399,
        projection: epsg_projection,
        displayProjection: epsg_display_projection
    } );

    layerTilesMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
    map.addLayer(layerTilesMapnik);

    map.events.register('zoomend', map, updateForm);
    map.events.register('moveend', map, updateForm);
    updateMap();
}

function setFormActivation(active) {
  if (active) {
    $('#map_language').show();
    $('#id_go_next_btn').show()
      .removeAttr('disabled');
  } else {
    $('#map_language').hide();
    $('#id_go_next_btn').hide()
      .attr('disabled', 'disabled');
  }
}

/** Language list management. */
var languages;

function resetLanguages() {
  $('#id_map_language').html(languages);
  $('#id_map_language').children('option').each(function() {
    if ($(this).val() == 'C')
      $(this).attr('selected', 'selected');
  });
}

function preselectLanguage(country) {
  var seen = false;

  $('#id_map_language').html(languages);
  $('#id_map_language').children('option').each(function() {
    if (! ($(this).val().match('.._' + country.toUpperCase() + '\..*') != null
           || $(this).val() == 'C'))
      $(this).remove();
    else if (!seen) {
      $(this).attr('selected', 'selected');
      seen = true;
    }
  });
}

/** Auto-suggest feature. */
function suggest(input, results, osm_id, button, options) {
  var $input = $(input).attr('autocomplete', 'off');
  var $results = $(results);
  var $osm_id = $(osm_id);
  var $button = $(button);
  var timeout = false;
  var shown = false;

  closeSuggest();

  // Setup the keyup event.
  $input.keyup(processKey);

  // Disable form validation via the Enter key
  $input.keypress(function(e) { if (e.keyCode == 13) return false; });

  function appendValidResult(item) {
    var id = 'rad_' + item.country_code + '_' + item.ocitysmap_params['id'];
    $results.append('
'
       + item.display_name + '
');

    var e = $('#' + id)
    e.bind('click', function(e) { setResult($(this)); });
    e.bind('mouseover', function(e) { setSelectedResultTo($(this)); });
  }

  /* Empty and close the suggestion box. */
  function closeSuggest() {
    $results.empty();
    $results.hide();
    shown = false;
  }

  /* Handle the JSON result. */
  function handleNominatimResults(data, textResult) {
    var unusable_token = false;
    $(input).css('cursor', 'text');
    closeSuggest();

    if (data.length) {
      $results.show();
      shown = true;
    }

    $.each(data, function(i, item) {
      if (typeof item.ocitysmap_params != 'undefined' &&
          item.ocitysmap_params['admin_level'] == 8) {
        appendValidResult(item);
      } else {
        $results.append('
'
          + item.display_name + '
');
        unusable_token = true;
      }
    });

    if (unusable_token)
      $results.append('
' + $('#noadminlimitinfo').html() + '
');
  }

  function doQuery() {
    if (!$input.val().length)
      return;
    $(input).css('cursor', 'wait');
    $.getJSON("/nominatim/", { q: $input.val() }, handleNominatimResults);
  }

  function processKey(e) {
    clearResult();

    switch (e.keyCode) {
      case 27:  // ESC
        closeSuggest();
        break;
      case 9:   // TAB
      case 13:  // OK
        var elt = getCurrentResult();
        if (elt)
          setResult(elt);
        return false;
        break;
      case 38:  // UP
        if (!shown)
          doQuery();
        prevResult();
        break;
      case 40:  // DOWN
        if (!shown)
          doQuery();
        nextResult();
        break;
      default:
        if (timeout)
          clearTimeout(timeout);
        timeout = setTimeout(doQuery, options.timeout);
      }
  }

  /* Returns the currently selected result. */
  function getCurrentResult() {
    var children = $results.children('li.' + options.selectedClass);
    if (children.length)
      return children;
    return false;
  }

  /* Set the form to the given result. */
  function setResult(elt) {
    var temp = elt.attr('id').split('_');

    preselectLanguage(temp[1]);
    $osm_id.val(temp[2]);
    $input.val(elt.html());

    closeSuggest();
    setFormActivation(true);
  }

  function clearResult() {
    $osm_id.val('');
    setFormActivation(false);
  }

  /** Functions to manipulate the current selection. */

  /* Set the currently selected item in the drop-down list. */
  function setSelectedResultTo(elt) {
    $results.children('li').removeClass(options.selectedClass);
    if (elt)
      elt.addClass(options.selectedClass);
  }

  /* Move to the previous valid result. */
  function prevResult() {
    var current = getCurrentResult();
    var new_result;

    if (current) {
      var prev_valid = current.siblings('li.suggestok');
      if (prev_valid.length)
        new_result = prev_valid;
    } else {
      new_result = $results.children('li.suggestok:last');
    }

    setSelectedResultTo(new_result);
  }

  /* Move to the next valid result. */
  function nextResult() {
    var current = getCurrentResult();
    var new_result;

    if (current) {
      var next_valid = current.siblings('li.suggestok');
      if (next_valid.length)
        new_result = next_valid;
    } else {
      new_result = $results.children('li.suggestok:first');
    }

    setSelectedResultTo(new_result);
  }
}

/** Page initialization. */
$(document).ready(function() {
  function switchToAdminMode() {
    $('#mapform tbody').children('tr.bybbox').hide();
    $('#mapform tbody').children('tr.byadmin').show();
    setFormActivation(false);
  }

  function switchToBBoxMode() {
    $('#mapform tbody').children('tr.byadmin').hide();
    $('#mapform tbody').children('tr.bybbox').show();
    setFormActivation(true);
    if (map == null)
      mapInit();
    resetLanguages();
  }

  if ($('#id_mode_1').is(':checked'))
    switchToBBoxMode();
  else
    switchToAdminMode();

  $('#id_mode_0').bind('click', function(e) { switchToAdminMode(); });
  $('#id_mode_1').bind('click', function(e) { switchToBBoxMode(); });

  suggest('#id_administrative_city', '#suggest',
          '#id_administrative_osmid', '#id_go_next_btn',
          { selectedClass: 'selected',
            timeout: 150
          });

  languages = $('#id_map_language').html();
});
<commit_msg>Avoid resetting the language selector with empty contents<commit_after>/* coding: utf-8
 *
 * maposmatic, the web front-end of the MapOSMatic city map generation system
 * Copyright (C) 2009 David Decotigny
 * Copyright (C) 2009 Frédéric Lehobey
 * Copyright (C) 2009 David Mentré
 * Copyright (C) 2009 Maxime Petazzoni
 * Copyright (C) 2009 Thomas Petazzoni
 * Copyright (C) 2009 Gaël Utard
 * Copyright (C) 2009 Étienne Loks
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * See the file COPYING for details.
 */

/* OSM slippy map management. */

var map = null;
var update_lock = 0;
var epsg_display_projection = new OpenLayers.Projection('EPSG:4326');
var epsg_projection = new OpenLayers.Projection('EPSG:900913');

function getUpperLeftLat() { return document.getElementById('lat_upper_left'); }
function getUpperLeftLon() { return document.getElementById('lon_upper_left'); }
function getBottomRightLat() { return document.getElementById('lat_bottom_right'); }
function getBottomRightLon() { return document.getElementById('lon_bottom_right'); }

/** Map Zoom/Move events callback: update form fields on zoom action. */
function updateForm()
{
    if (update_lock)
      return;

    var bounds = map.getExtent();

    var topleft = new OpenLayers.LonLat(bounds.left, bounds.top);
    topleft = topleft.transform(epsg_projection, epsg_display_projection);

    var bottomright = new OpenLayers.LonLat(bounds.right, bounds.bottom);
    bottomright = bottomright.transform(epsg_projection, epsg_display_projection);

    getUpperLeftLat().value = topleft.lat.toFixed(4);
    getUpperLeftLon().value = topleft.lon.toFixed(4);
    getBottomRightLat().value = bottomright.lat.toFixed(4);
    getBottomRightLon().value = bottomright.lon.toFixed(4);
}

/* Update the map on form field modification. */
function updateMap()
{
    var bounds = new OpenLayers.Bounds(getUpperLeftLon().value,
                                       getUpperLeftLat().value,
                                       getBottomRightLon().value,
                                       getBottomRightLat().value);
    bounds.transform(epsg_display_projection, epsg_projection);

    update_lock = 1;
    map.zoomToExtent(bounds);
    update_lock = 0;
}

/* Main initialisation function. Must be called before the map is manipulated. */
function mapInit()
{
    map = new OpenLayers.Map ('map', {
        controls:[new OpenLayers.Control.Navigation(),
                  new OpenLayers.Control.PanZoomBar(),
                  new OpenLayers.Control.Attribution()],
        maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
        numZoomLevels: 18,
        maxResolution: 156543.0399,
        projection: epsg_projection,
        displayProjection: epsg_display_projection
    } );

    layerTilesMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
    map.addLayer(layerTilesMapnik);

    map.events.register('zoomend', map, updateForm);
    map.events.register('moveend', map, updateForm);
    updateMap();
}

function setFormActivation(active) {
  if (active) {
    $('#map_language').show();
    $('#id_go_next_btn').show()
      .removeAttr('disabled');
  } else {
    $('#map_language').hide();
    $('#id_go_next_btn').hide()
      .attr('disabled', 'disabled');
  }
}

/** Language list management. */
var languages;

function resetLanguages() {
  $('#id_map_language').html(languages);
  $('#id_map_language').children('option').each(function() {
    if ($(this).val() == 'C')
      $(this).attr('selected', 'selected');
  });
}

function preselectLanguage(country) {
  var seen = false;

  $('#id_map_language').html(languages);
  $('#id_map_language').children('option').each(function() {
    if (! ($(this).val().match('.._' + country.toUpperCase() + '\..*') != null
           || $(this).val() == 'C'))
      $(this).remove();
    else if (!seen) {
      $(this).attr('selected', 'selected');
      seen = true;
    }
  });
}

/** Auto-suggest feature. */
function suggest(input, results, osm_id, button, options) {
  var $input = $(input).attr('autocomplete', 'off');
  var $results = $(results);
  var $osm_id = $(osm_id);
  var $button = $(button);
  var timeout = false;
  var shown = false;

  closeSuggest();

  // Setup the keyup event.
  $input.keyup(processKey);

  // Disable form validation via the Enter key
  $input.keypress(function(e) { if (e.keyCode == 13) return false; });

  function appendValidResult(item) {
    var id = 'rad_' + item.country_code + '_' + item.ocitysmap_params['id'];
    $results.append('
'
       + item.display_name + '
');

    var e = $('#' + id)
    e.bind('click', function(e) { setResult($(this)); });
    e.bind('mouseover', function(e) { setSelectedResultTo($(this)); });
  }

  /* Empty and close the suggestion box. */
  function closeSuggest() {
    $results.empty();
    $results.hide();
    shown = false;
  }

  /* Handle the JSON result. */
  function handleNominatimResults(data, textResult) {
    var unusable_token = false;
    $(input).css('cursor', 'text');
    closeSuggest();

    if (data.length) {
      $results.show();
      shown = true;
    }

    $.each(data, function(i, item) {
      if (typeof item.ocitysmap_params != 'undefined' &&
          item.ocitysmap_params['admin_level'] == 8) {
        appendValidResult(item);
      } else {
        $results.append('
'
          + item.display_name + '
');
        unusable_token = true;
      }
    });

    if (unusable_token)
      $results.append('
' + $('#noadminlimitinfo').html() + '
');
  }

  function doQuery() {
    if (!$input.val().length)
      return;
    $(input).css('cursor', 'wait');
    $.getJSON("/nominatim/", { q: $input.val() }, handleNominatimResults);
  }

  function processKey(e) {
    clearResult();

    switch (e.keyCode) {
      case 27:  // ESC
        closeSuggest();
        break;
      case 9:   // TAB
      case 13:  // OK
        var elt = getCurrentResult();
        if (elt)
          setResult(elt);
        return false;
        break;
      case 38:  // UP
        if (!shown)
          doQuery();
        prevResult();
        break;
      case 40:  // DOWN
        if (!shown)
          doQuery();
        nextResult();
        break;
      default:
        if (timeout)
          clearTimeout(timeout);
        timeout = setTimeout(doQuery, options.timeout);
      }
  }

  /* Returns the currently selected result. */
  function getCurrentResult() {
    var children = $results.children('li.' + options.selectedClass);
    if (children.length)
      return children;
    return false;
  }

  /* Set the form to the given result. */
  function setResult(elt) {
    var temp = elt.attr('id').split('_');

    preselectLanguage(temp[1]);
    $osm_id.val(temp[2]);
    $input.val(elt.html());

    closeSuggest();
    setFormActivation(true);
  }

  function clearResult() {
    $osm_id.val('');
    setFormActivation(false);
  }

  /** Functions to manipulate the current selection. */

  /* Set the currently selected item in the drop-down list. */
  function setSelectedResultTo(elt) {
    $results.children('li').removeClass(options.selectedClass);
    if (elt)
      elt.addClass(options.selectedClass);
  }

  /* Move to the previous valid result. */
  function prevResult() {
    var current = getCurrentResult();
    var new_result;

    if (current) {
      var prev_valid = current.siblings('li.suggestok');
      if (prev_valid.length)
        new_result = prev_valid;
    } else {
      new_result = $results.children('li.suggestok:last');
    }

    setSelectedResultTo(new_result);
  }

  /* Move to the next valid result. */
  function nextResult() {
    var current = getCurrentResult();
    var new_result;

    if (current) {
      var next_valid = current.siblings('li.suggestok');
      if (next_valid.length)
        new_result = next_valid;
    } else {
      new_result = $results.children('li.suggestok:first');
    }

    setSelectedResultTo(new_result);
  }
}

/** Page initialization. */
$(document).ready(function() {
  languages = $('#id_map_language').html();

  function switchToAdminMode() {
    $('#mapform tbody').children('tr.bybbox').hide();
    $('#mapform tbody').children('tr.byadmin').show();
    setFormActivation(false);
  }

  function switchToBBoxMode() {
    $('#mapform tbody').children('tr.byadmin').hide();
    $('#mapform tbody').children('tr.bybbox').show();
    setFormActivation(true);
    if (map == null)
      mapInit();
    resetLanguages();
  }

  if ($('#id_mode_1').is(':checked'))
    switchToBBoxMode();
  else
    switchToAdminMode();

  $('#id_mode_0').bind('click', function(e) { switchToAdminMode(); });
  $('#id_mode_1').bind('click', function(e) { switchToBBoxMode(); });

  suggest('#id_administrative_city', '#suggest',
          '#id_administrative_osmid', '#id_go_next_btn',
          { selectedClass: 'selected',
            timeout: 150
          });
});
<|endoftext|>


<commit_before>define([
    'jquery',
    '/common/login.js',
    '/common/cryptpad-common.js',
    '/common/credential.js' // preloaded for login.js
], function ($, Login, Cryptpad) {
    var Messages = Cryptpad.Messages;

    $(function () {
        var $main = $('#mainBlock');

        // Language selector
        var $sel = $('#language-selector');
        Cryptpad.createLanguageSelector(undefined, $sel);
        $sel.find('button').addClass('btn').addClass('btn-secondary');
        $sel.show();

        // User admin menu
        var $userMenu = $('#user-menu');
        var userMenuCfg = {
            $initBlock: $userMenu
        };
        var $userAdmin = Cryptpad.createUserAdminMenu(userMenuCfg);
        $userAdmin.find('button').addClass('btn').addClass('btn-secondary');

        $(window).click(function () {
            $('.cryptpad-dropdown').hide();
        });

        // main block is hidden in case javascript is disabled
        $main.removeClass('hidden');

        // Make sure we don't display non-translated content (empty button)
        $main.find('#data').removeClass('hidden');

        if (Cryptpad.isLoggedIn()) {
            // already logged in, redirect to drive
            document.location.href = '/drive/';
            return;
        } else {
            $main.find('#userForm').removeClass('hidden');
        }

        // text and password input fields
        var $uname = $('#username');
        var $passwd = $('#password');
        var $confirm = $('#password-confirm');

        if (sessionStorage.login_user) {
            $uname.val(sessionStorage.login_user);
        }
        if (sessionStorage.login_pass) {
            $passwd.val(sessionStorage.login_pass);
        }

        [ $uname, $passwd, $confirm]
        .some(function ($el) { if (!$el.val()) { $el.focus(); return true; } });

        // checkboxes
        var $checkImport = $('#import-recent');
        var $checkAcceptTerms = $('#accept-terms');

        var $register = $('button#register');

        var logMeIn = function (result) {
            localStorage.User_hash = result.userHash;

            var proxy = result.proxy;
            proxy.edPublic = result.edPublic;
            proxy.edPrivate = result.edPrivate;

            Cryptpad.feedback('REGISTRATION', true);

            Cryptpad.whenRealtimeSyncs(result.realtime, function () {
                Cryptpad.login(result.userHash, result.userName, function () {
                    if (sessionStorage.redirectTo) {
                        var h = sessionStorage.redirectTo;
                        var parser = document.createElement('a');
                        parser.href = h;
                        if (parser.origin === window.location.origin) {
                            delete sessionStorage.redirectTo;
                            window.location.href = h;
                            return;
                        }
                    }
                    window.location.href = '/drive/';
                });
            });
        };

        $register.click(function () {
            var uname = $uname.val();
            var passwd = $passwd.val();
            var confirmPassword = $confirm.val();

            var shouldImport = $checkImport[0].checked;
            var doesAccept = $checkAcceptTerms[0].checked;

            /* basic validation */
            if (passwd !== confirmPassword) { // do their passwords match?
                return void Cryptpad.alert(Messages.register_passwordsDontMatch);
            }

            if (!doesAccept) { // do they accept the terms of service?
                return void Cryptpad.alert(Messages.register_mustAcceptTerms);
            }

            Cryptpad.confirm("
" + Messages.register_warning + "
",
            function (yes) {
                if (!yes) { return; }

                // setTimeout 100ms to remove the keyboard on mobile devices before the loading screen pops up
                window.setTimeout(function () {
                    Cryptpad.addLoadingScreen(Messages.login_hashing);
                    // We need a setTimeout(cb, 0) otherwise the loading screen is only displayed after hashing the password
                    window.setTimeout(function () {
                        Login.loginOrRegister(uname, passwd, true, function (err, result) {
                            var proxy = result.proxy;

                            if (err) {
                                switch (err) {
                                    case 'NO_SUCH_USER':
                                        Cryptpad.removeLoadingScreen(function () {
                                            Cryptpad.alert(Messages.login_noSuchUser);
                                        });
                                        break;
                                    case 'INVAL_USER':
                                        Cryptpad.removeLoadingScreen(function () {
                                            Cryptpad.alert(Messages.login_invalUser);
                                        });
                                        break;
                                    case 'INVAL_PASS':
                                        Cryptpad.removeLoadingScreen(function () {
                                            Cryptpad.alert(Messages.login_invalPass);
                                        });
                                        break;
                                    case 'ALREADY_REGISTERED':
                                        Cryptpad.removeLoadingScreen(function () {
                                            Cryptpad.confirm(Messages.register_alreadyRegistered, function (yes) {
                                                if (!yes) { return; }
                                                proxy.login_name = uname;

                                                if (!proxy[Cryptpad.displayNameKey]) {
                                                    proxy[Cryptpad.displayNameKey] = uname;
                                                }
                                                Cryptpad.eraseTempSessionValues();
                                                logMeIn(result);
                                            });
                                        });
                                        break;
                                    default: // UNHANDLED ERROR
                                        Cryptpad.errorLoadingScreen(Messages.login_unhandledError);
                                }
                                return;
                            }
                            Cryptpad.eraseTempSessionValues();
                            if (shouldImport) {
                                sessionStorage.migrateAnonDrive = 1;
                            }

                            proxy.login_name = uname;
                            proxy[Cryptpad.displayNameKey] = uname;
                            sessionStorage.createReadme = 1;

                            logMeIn(result);
                        });
                    }, 0);
                }, 100);
            }, {
                ok: Messages.register_writtenPassword,
                cancel: Messages.register_cancel,
                cancelClass: 'safe',
                okClass: 'danger',
                reverseOrder: true,
            }, true, function ($dialog) {
                $dialog.find('> div').addClass('half');
            });
        });
    });
});
<commit_msg>add automated registration test<commit_after>define([
    'jquery',
    '/common/login.js',
    '/common/cryptpad-common.js',
    '/common/test.js',
    '/common/credential.js', // preloaded for login.js
], function ($, Login, Cryptpad, Test) {
    var Messages = Cryptpad.Messages;

    $(function () {
        var $main = $('#mainBlock');

        // Language selector
        var $sel = $('#language-selector');
        Cryptpad.createLanguageSelector(undefined, $sel);
        $sel.find('button').addClass('btn').addClass('btn-secondary');
        $sel.show();

        // User admin menu
        var $userMenu = $('#user-menu');
        var userMenuCfg = {
            $initBlock: $userMenu
        };
        var $userAdmin = Cryptpad.createUserAdminMenu(userMenuCfg);
        $userAdmin.find('button').addClass('btn').addClass('btn-secondary');

        $(window).click(function () {
            $('.cryptpad-dropdown').hide();
        });

        // main block is hidden in case javascript is disabled
        $main.removeClass('hidden');

        // Make sure we don't display non-translated content (empty button)
        $main.find('#data').removeClass('hidden');

        if (Cryptpad.isLoggedIn()) {
            // already logged in, redirect to drive
            document.location.href = '/drive/';
            return;
        } else {
            $main.find('#userForm').removeClass('hidden');
        }

        // text and password input fields
        var $uname = $('#username');
        var $passwd = $('#password');
        var $confirm = $('#password-confirm');

        if (sessionStorage.login_user) {
            $uname.val(sessionStorage.login_user);
        }
        if (sessionStorage.login_pass) {
            $passwd.val(sessionStorage.login_pass);
        }

        [ $uname, $passwd, $confirm]
        .some(function ($el) { if (!$el.val()) { $el.focus(); return true; } });

        // checkboxes
        var $checkImport = $('#import-recent');
        var $checkAcceptTerms = $('#accept-terms');

        var $register = $('button#register');

        var logMeIn = function (result) {
            if (Test.testing) {
                Test.passed();
                window.alert("Test passed!");
                return;
            }
            localStorage.User_hash = result.userHash;

            var proxy = result.proxy;
            proxy.edPublic = result.edPublic;
            proxy.edPrivate = result.edPrivate;

            Cryptpad.feedback('REGISTRATION', true);

            Cryptpad.whenRealtimeSyncs(result.realtime, function () {
                Cryptpad.login(result.userHash, result.userName, function () {
                    if (sessionStorage.redirectTo) {
                        var h = sessionStorage.redirectTo;
                        var parser = document.createElement('a');
                        parser.href = h;
                        if (parser.origin === window.location.origin) {
                            delete sessionStorage.redirectTo;
                            window.location.href = h;
                            return;
                        }
                    }
                    window.location.href = '/drive/';
                });
            });
        };

        $register.click(function () {
            var uname = $uname.val();
            var passwd = $passwd.val();
            var confirmPassword = $confirm.val();

            var shouldImport = $checkImport[0].checked;
            var doesAccept = $checkAcceptTerms[0].checked;

            /* basic validation */
            if (passwd !== confirmPassword) { // do their passwords match?
                return void Cryptpad.alert(Messages.register_passwordsDontMatch);
            }

            if (!doesAccept) { // do they accept the terms of service?
                return void Cryptpad.alert(Messages.register_mustAcceptTerms);
            }

            Cryptpad.confirm("
" + Messages.register_warning + "
",
            function (yes) {
                if (!yes) { return; }

                // setTimeout 100ms to remove the keyboard on mobile devices before the loading screen pops up
                window.setTimeout(function () {
                    Cryptpad.addLoadingScreen(Messages.login_hashing);
                    // We need a setTimeout(cb, 0) otherwise the loading screen is only displayed after hashing the password
                    window.setTimeout(function () {
                        Login.loginOrRegister(uname, passwd, true, function (err, result) {
                            var proxy = result.proxy;

                            if (err) {
                                switch (err) {
                                    case 'NO_SUCH_USER':
                                        Cryptpad.removeLoadingScreen(function () {
                                            Cryptpad.alert(Messages.login_noSuchUser);
                                        });
                                        break;
                                    case 'INVAL_USER':
                                        Cryptpad.removeLoadingScreen(function () {
                                            Cryptpad.alert(Messages.login_invalUser);
                                        });
                                        break;
                                    case 'INVAL_PASS':
                                        Cryptpad.removeLoadingScreen(function () {
                                            Cryptpad.alert(Messages.login_invalPass);
                                        });
                                        break;
                                    case 'ALREADY_REGISTERED':
                                        Cryptpad.removeLoadingScreen(function () {
                                            Cryptpad.confirm(Messages.register_alreadyRegistered, function (yes) {
                                                proxy.login_name = uname;

                                                if (!proxy[Cryptpad.displayNameKey]) {
                                                    proxy[Cryptpad.displayNameKey] = uname;
                                                }
                                                Cryptpad.eraseTempSessionValues();
                                                logMeIn(result);
                                            });
                                        });
                                        break;
                                    default: // UNHANDLED ERROR
                                        Cryptpad.errorLoadingScreen(Messages.login_unhandledError);
                                }
                                return;
                            }

                            if (Test.testing) { return void logMeIn(result); }

                            Cryptpad.eraseTempSessionValues();
                            if (shouldImport) {
                                sessionStorage.migrateAnonDrive = 1;
                            }

                            proxy.login_name = uname;
                            proxy[Cryptpad.displayNameKey] = uname;
                            sessionStorage.createReadme = 1;

                            logMeIn(result);
                        });
                    }, 0);
                }, 100);
            }, {
                ok: Messages.register_writtenPassword,
                cancel: Messages.register_cancel,
                cancelClass: 'safe',
                okClass: 'danger',
                reverseOrder: true,
            }, true, function ($dialog) {
                $dialog.find('> div').addClass('half');
            });
        });

        Test(function () {
            $uname.val('test' + Math.random());
            $passwd.val('test');
            $confirm.val('test');
            $checkImport[0].checked = true;
            $checkAcceptTerms[0].checked = true;
            $register.click();

            window.setTimeout(function () {
                Cryptpad.findOKButton().click()
            }, 1000);
        });
    });
});
<|endoftext|>


<commit_before>/*global it:true */

/* EXAMPLE APPIUM + SAUCE LABS INTEGRATION
   First: npm install mocha -g; npm install wd
   Usage: SAUCE_USERNAME=xxx SAUCE_ACCESS_KEY=yyy mocha sauce-android.js */

"use strict";

var should = require("should")
  , appUrl = 'http://appium.s3.amazonaws.com/NotesList.apk'
  , dbPath = "../../../test/helpers/driverblock.js"
  , describeSauce = require(dbPath).describeForSauce(appUrl, 'Android')
  , extraCaps = {
      "app-activity": ".NotesList"
      , "app-package": "com.example.android.notepad"
    };

describeSauce('notes app', function(h) {
  it('should save a note', function(done) {
    h.driver.elementByName("New note", function(err, el) {
      el.click(function() {
        h.driver.elementByTagName("textfield", function(err, el) {
          el.sendKeys("This is a new note!", function() {
            h.driver.elementByName("Save", function(err, el) {
              el.click(function() {
                h.driver.elementsByTagName("text", function(err, els) {
                  els[2].text(function(err, text) {
                    text.should.equal("This is a new note!");
                    els[2].click(function() {
                      h.driver.quit(done);
                    });
                  });
                });
              });
            });
          });
        });
      });
    });
  });
}, extraCaps);
<commit_msg>update sauce android example to not be dependent on driverblock<commit_after>/*global it:true, describe:true, beforeEach:true, afterEach:true */

/* EXAMPLE APPIUM + SAUCE LABS INTEGRATION
   First: npm install mocha -g; npm install wd
   Usage: SAUCE_USERNAME=xxx SAUCE_ACCESS_KEY=yyy mocha -t 300000 sauce-android.js */

"use strict";

var should = require("should")
  , wd = require("wd")
  , appUrl = 'http://appium.s3.amazonaws.com/NotesList.apk';

describe('notes app', function() {
  var driver = null;

  beforeEach(function(done) {
    driver = wd.remote("ondemand.saucelabs.com", 80,
      process.env.SAUCE_USERNAME, process.env.SAUCE_ACCESS_KEY);
    driver.init({
      device: 'Android',
      version: '4.2',
      app: appUrl,
      name: 'Sauce Android test',
      'app-activity': '.NotesList',
      'app-package': 'com.example.android.notepad'
    }, function(err) {
      should.not.exist(err);
      done();
    });
  });

  afterEach(function(done) {
    driver.quit(function(err) {
      should.not.exist(err);
      done();
    });
  });

  it('should save a note', function(done) {
    driver.elementByName("New note", function(err, el) {
      el.click(function() {
        driver.elementByTagName("textfield", function(err, el) {
          el.sendKeys("This is a new note!", function() {
            driver.elementByName("Save", function(err, el) {
              el.click(function() {
                driver.elementsByTagName("text", function(err, els) {
                  els[2].text(function(err, text) {
                    text.should.equal("This is a new note!");
                    els[2].click(function(err) {
                      should.not.exist(err);
                      done();
                    });
                  });
                });
              });
            });
          });
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>if(chrome.tabs.onMouseScroll){
  chrome.tabs.onMouseScroll.addListener(function(e){
    console.info(e);
  });
}
chrome.tabs.onCreated.addListener(function(e){
  // Boost new tab creation (literally, but you lost top sites).
  console.info(e);
  chrome.tabs.update(e.id, {url: 'about:blank'});
});
<commit_msg>Limit tab creation interrupt<commit_after>if(chrome.tabs.onMouseScroll){
  chrome.tabs.onMouseScroll.addListener(function(e){
    console.info(e);
  });
}
chrome.tabs.onCreated.addListener(function(tab){
  // Boost new tab creation (literally, but you lost top sites).
  if(tab.url === 'chrome://newtab/'){
    chrome.tabs.update(tab.id, {url: 'about:blank'});
  }
});
<|endoftext|>


<commit_before>var buildQuery = function(queryString) {
	var splitString = queryString.split(" ");
	var query = "";
	for (var i = 0; i < splitString.length; i++) {
		if (i < splitString.length-1)
			seperator = "+";
		else
			seperator = "";

		query+=(splitString[i]+seperator);
	};
	return query;
};

var parseNouns = function(string) {
	var cap = 4;
	var init = 0;
	var nouns = "";
	var unTaggedWords = new Lexer().lex(string);
	var taggedWords = new POSTagger().tag(unTaggedWords);

	for (var i = 0; i < taggedWords.length; i++) {
		var word = taggedWords[i];
		console.log(word)
		//["DT", "EX", "VBP", ":", ",", "TO", "WP"]
		if (word[1].slice(0,2) == "NN") {
			init++;
			nouns += word[0];
			if (init == cap) break;
			if (i < taggedWords.length-1) nouns+=" ";
		}
	}

	return (nouns.length > 0) ? nouns : null;
};

var getJstorResults = function(DOM) {
	console.log(DOM);
	var document = $(DOM);
	var resultRows = document.find(".row.result-item");
	var slicedResultsRows = resultRows.slice(0,3);

	var results = [];

	for (var i = 0; i < slicedResultsRows.length; i++) {
		var result = {};
		var snippet = $(slicedResultsRows[i]).find(".snippetText");
		snippet.remove();
		var list = $(slicedResultsRows[i]).find(".format.inline-list");
		list.remove();
		result["html"] = $(slicedResultsRows[i]).html();
		results.push(result);
	}

	return results;
};

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
	if (request.DOM) {
		var HTMLString = request.DOM;
		var dom = document.implementation.createHTMLDocument('newDOM');
		dom.documentElement.innerHTML = HTMLString;

		var title = dom.title;
		var parsedTitle = parseNouns(title);
		var query = buildQuery(parsedTitle);
		console.log(query);
		$.ajax({
            type: "GET", //or GET
            url: "http://www.jstor.org/action/doBasicSearch?Query="+query+"&acc=on&wc=on&fc=off&group=none",
            success: function(data){
            	// console.log(data);
            	var container = document.createElement("div");
            	container.innerHTML = data;

				var results = getJstorResults(container);
				console.log(results);
				chrome.runtime.sendMessage({results: results}, function(response){
					if (response.success) {
						console.log("SUCCESS");
					}
				});
			},
			error: function(jxhr){
				console.log(jxhr.responseText);
				sendResponse({success: false});
			}
        });
    }
});
<commit_msg>remove crappy content<commit_after>var buildQuery = function(queryString) {
	var splitString = queryString.split(" ");
	var query = "";
	for (var i = 0; i < splitString.length; i++) {
		if (i < splitString.length-1)
			seperator = "+";
		else
			seperator = "";

		query+=(splitString[i]+seperator);
	};
	return query;
};

var parseNouns = function(string) {
	var cap = 4;
	var init = 0;
	var nouns = "";
	var unTaggedWords = new Lexer().lex(string);
	var taggedWords = new POSTagger().tag(unTaggedWords);
	var badWords = ["|"];

	for (var i = 0; i < taggedWords.length; i++) {
		var word = taggedWords[i];
		console.log(word)
		//["DT", "EX", "VBP", ":", ",", "TO", "WP"]

		if (word[1].slice(0,2) == "NN" && badWords.indexOf(word[0]) == -1) {
			init++;
			nouns += word[0];
			if (init == cap) break;
			if (i < taggedWords.length-1) nouns+=" ";
		}
	}

	return (nouns.length > 0) ? nouns : null;
};

var getJstorResults = function(DOM) {
	console.log(DOM);
	var document = $(DOM);
	var resultRows = document.find(".row.result-item");
	var slicedResultsRows = resultRows.slice(0,3);

	var results = [];

	for (var i = 0; i < slicedResultsRows.length; i++) {
		var result = {};
		var snippet = $(slicedResultsRows[i]).find(".snippetText, .snippets.mlm");
		snippet.remove();
		var list = $(slicedResultsRows[i]).find(".format.inline-list");
		list.remove();
		var hidden = $(slicedResultsRows[i]).find(".visuallyhidden");
		hidden.remove();
		var inputs = $(slicedResultsRows[i]).find("input");
		inputs.remove();
		var imgs = $(slicedResultsRows[i]).find("img");
		imgs.remove();
		result["html"] = $(slicedResultsRows[i]).html();
		results.push(result);
	}

	return results;
};

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
	if (request.DOM) {
		var HTMLString = request.DOM;
		var dom = document.implementation.createHTMLDocument('newDOM');
		dom.documentElement.innerHTML = HTMLString;

		var title = dom.title;
		var parsedTitle = parseNouns(title);
		var query = buildQuery(parsedTitle);
		console.log(query);
		$.ajax({
            type: "GET", //or GET
            url: "http://www.jstor.org/action/doBasicSearch?Query="+query+"&acc=on&wc=on&fc=off&group=none",
            success: function(data){
            	// console.log(data);
            	var container = document.createElement("div");
            	container.innerHTML = data;

				var results = getJstorResults(container);
				console.log(results);
				chrome.runtime.sendMessage({results: results}, function(response){
					if (response.success) {
						console.log("SUCCESS");
					}
				});
			},
			error: function(jxhr){
				console.log(jxhr.responseText);
				sendResponse({success: false});
			}
        });
    }
});
<|endoftext|>


<commit_before>/*
 * grunt-mutation-testing
 *
 *
 * Copyright (c) 2014 Marco Stahl
 * Licensed under the MIT license.
 *
 * TODO (Martin Koster): split up this file and refactor to effect better separation of concerns. That should also improve legibility
 */

'use strict';
var esprima = require('esprima');
var fs = require('fs');
var exec = require('sync-exec');
var path = require('path');
var QPromise = require('q');
var mutate = require('./mutations');
var _ = require('lodash');
var mutationTestingKarma = require('./mutation-testing-karma');
var mutationTestingMocha = require('./mutation-testing-mocha');
var notFailingMutations = [];

function ensureRegExpArray(value) {
    var array = _.isArray(value) ? value : [value];
    return array.map(function (stringOrRegExp) {
        return _.isString(stringOrRegExp) ? new RegExp('^' + stringOrRegExp + '$') : stringOrRegExp;
    });
}

function canBeIgnored(opts, src, mutation) {
    if (!opts.ignore) {
        return false;
    }
    var ignorePatterns = ensureRegExpArray(opts.ignore);
    var affectedSrcPart = src.substring(mutation.begin, mutation.end);
    return _.any(ignorePatterns, function (ignorePattern) {
        return ignorePattern.test(affectedSrcPart);
    });
}

function canBeDiscarded(opts, mutation) {
    if (!opts.discardReplacements) {
        return false;
    }
    var discardPatterns = ensureRegExpArray(opts.discardReplacements);
    return _.any(discardPatterns, function (discardPattern) {
        return discardPattern.test(mutation.replacement);
    });
}

function createStats() {
    return {
        all: 0,
        ignored: 0,
        untested: 0 // if a test succeeds for mutated code, it's an untested mutation
    };
}

function addStats(stats1, stats2) {
    return _.mapValues(stats1, function (value, key) {
        return value + stats2[key];
    });
}

function createStatsMessage(stats) {
    var ignoredMessage = stats.ignored ? ' ' + stats.ignored + ' mutations were ignored.' : '';
    var allUnIgnored = stats.all - stats.ignored;
    var testedMutations = allUnIgnored - stats.untested;
    var percentTested = Math.floor((testedMutations / allUnIgnored) * 100);
    return testedMutations +
        ' of ' + allUnIgnored + ' unignored mutations are tested (' + percentTested + '%).' + ignoredMessage;
}

function truncateReplacement(opts, replacementArg) {
    var maxLength = opts.maxReplacementLength !== undefined ? opts.maxReplacementLength : 20;
    var replacement = replacementArg.replace(/\s+/g, ' ');
    if (maxLength > 0 && replacement.length > maxLength) {
        return replacement.slice(0, maxLength / 2) + ' ... ' + replacement.slice(-maxLength / 2);
    }
    return replacement;
}

function createMutationLogMessage(opts, srcFilePath, mutation, src) {
    var srcFileName = opts.basePath ? srcFilePath.substr(srcFilePath.indexOf(opts.basePath)) : srcFilePath;
    var currentMutationPosition = srcFileName + ':' + mutation.line + ':' + (mutation.col + 1);
    var mutatedCode = src.substr(mutation.begin, mutation.end - mutation.begin);
    return currentMutationPosition + (
            mutation.replacement ?
            ' ' + truncateReplacement(opts, mutatedCode) + ' can be replaced with: ' + truncateReplacement(opts, mutation.replacement) :
            ' ' + truncateReplacement(opts, mutatedCode) + ' can be removed');
}

function createNotTestedBecauseInsideUntestedMutationLogMessage(opts, srcFilePath, mutation) {
    var srcFileName = opts.basePath ? srcFilePath.substr(srcFilePath.indexOf(opts.basePath)) : srcFilePath;
    var currentMutationPosition = srcFileName + ':' + mutation.line + ':' + (mutation.col + 1);
    return currentMutationPosition + ' is inside a surviving mutation';
}

function isInsideNotFailingMutation(innerMutation) {
    return _.indexOf(notFailingMutations, innerMutation.parentMutationId) > -1;
}

/**
 * @param {string} srcFilename
 * @param {function} runTests
 * @param {function} logMutation
 * @param {function} log the logger
 * @param {object} opts the config options
 */
function mutationTestFile(srcFilename, runTests, logMutation, log, opts) {
    var src = fs.readFileSync(srcFilename, 'UTF8');
    var mutations = mutate.findMutations(src, opts.excludeMutations);
    var mutationPromise = new QPromise({});

    var stats = createStats();

    log('\nMutating file ' + srcFilename + '\n');

    mutations.forEach(function (mutation) {
        stats.all += 1;
        if (canBeDiscarded(opts, mutation)) {
            return;
        }
        if (canBeIgnored(opts, src, mutation)) {
            stats.ignored += 1;
            return;
        }
        var perc = Math.round((stats.all / mutations.length) * 100);
        mutationPromise = mutationPromise.then(function () {
            log('Line ' + mutation.line + ' (' + perc + '%), ');
            if (opts.dontTestInsideNotFailingMutations && isInsideNotFailingMutation(mutation)) {
                stats.untested += 1;
                logMutation(createNotTestedBecauseInsideUntestedMutationLogMessage(opts, srcFilename, mutation));
                return;
            }
            fs.writeFileSync(srcFilename, mutate.applyMutation(src, mutation));
            return runTests().then(function (testSuccess) {
                if (testSuccess) {
                    logMutation(createMutationLogMessage(opts, srcFilename, mutation, src));
                    stats.untested += 1;
                    notFailingMutations.push(mutation.mutationId);
                }
            });
        });
    });

    mutationPromise = mutationPromise.then(function () {
        return stats;
    });

    return mutationPromise.fin(function () {
        console.log('\nRestore ', srcFilename);
        fs.writeFileSync(srcFilename, src);
    });
}

function mutationTest(grunt, task, opts) {
    var done = task.async();
    var mutationTestPromise = new QPromise();

    function logToMutationReport(fileDest, msg) {
        if (fileDest === 'LOG') {
            grunt.log.writeln('\n' + msg);
            return;
        }
        if (!grunt.file.exists(fileDest)) {
            grunt.file.write(fileDest, '');
        }
        fs.appendFileSync(fileDest, msg + '\n');
    }

    function runTests() {
        var deferred = QPromise.defer();
        if (typeof opts.test === 'string') {
            var execResult = exec(opts.test);
            deferred.resolve(execResult.status === 0);
        } else {
            opts.test(function (ok) {
                deferred.resolve(ok);
            });
        }
        return deferred.promise;
    }

    var files = task.files;

    opts.before(function () {
        // run first without mutations
        runTests().done(function (testOk) {
            if (!testOk) {
                files.forEach(function (file) {
                    logToMutationReport(file.dest, 'Tests fail without mutations.');
                });
            } else {
                files.forEach(function (file) {
                    mutationTestPromise = mutationTestPromise.then(function () {
                        var validFiles = file.src.filter(function (filepath) {
                            if (!grunt.file.exists(filepath)) {
                                grunt.log.warn('Source file "' + filepath + '" not found.');
                                return false;
                            } else {
                                return true;
                            }
                        });

                        if (validFiles.length === 0) {
                            grunt.log.warn('Found no valid files in ' + JSON.stringify(file.orig.src));
                            return false;
                        }

                        function log(msg) {
                            grunt.log.write(msg);
                        }

                        var logMutationToFileDest = _.partial(logToMutationReport, file.dest);
                        var statsSummary = createStats();

                        var mutationFilesPromise = new QPromise();
                        validFiles.forEach(function (srcFile) {
                            mutationFilesPromise = mutationFilesPromise.then(function () {
                                return mutationTestFile(path.resolve(srcFile), runTests, logMutationToFileDest, log, opts).then(function (stats) {
                                    statsSummary = addStats(statsSummary, stats);
                                });
                            });
                        });

                        mutationFilesPromise = mutationFilesPromise.then(function () {
                            logMutationToFileDest(createStatsMessage(statsSummary));
                        });

                        return mutationFilesPromise;
                    });
                });
            }

            mutationTestPromise.then(function () {
                var dfd = QPromise.defer();
                opts.after(function () {
                    dfd.resolve();
                });
                return dfd.promise;
            });
            mutationTestPromise.done(done);
        });
    });
}

function callDone(done) {
    done(true);
}

var DEFAULT_OPTIONS = {
    test: callDone,
    before: callDone,
    after: callDone
};

module.exports = function (grunt) {
    grunt.registerMultiTask('mutationTest', 'Test your tests by mutating the production code.', function () {
        var opts = this.options(DEFAULT_OPTIONS);
        mutationTestingKarma.init(grunt, opts);
        mutationTestingMocha.init(grunt, opts);
        mutationTest(grunt, this, opts);
    });
};
<commit_msg>Now normalizing Windows paths in output (fixes unit tests on Windows)<commit_after>/*
 * grunt-mutation-testing
 *
 *
 * Copyright (c) 2014 Marco Stahl
 * Licensed under the MIT license.
 *
 * TODO (Martin Koster): split up this file and refactor to effect better separation of concerns. That should also improve legibility
 */

'use strict';
var esprima = require('esprima');
var fs = require('fs');
var exec = require('sync-exec');
var path = require('path');
var QPromise = require('q');
var _ = require('lodash');
var os = require('os');

var mutate = require('./mutations');
var mutationTestingKarma = require('./mutation-testing-karma');
var mutationTestingMocha = require('./mutation-testing-mocha');

var notFailingMutations = [];

function ensureRegExpArray(value) {
    var array = _.isArray(value) ? value : [value];
    return array.map(function (stringOrRegExp) {
        return _.isString(stringOrRegExp) ? new RegExp('^' + stringOrRegExp + '$') : stringOrRegExp;
    });
}

function canBeIgnored(opts, src, mutation) {
    if (!opts.ignore) {
        return false;
    }
    var ignorePatterns = ensureRegExpArray(opts.ignore);
    var affectedSrcPart = src.substring(mutation.begin, mutation.end);
    return _.any(ignorePatterns, function (ignorePattern) {
        return ignorePattern.test(affectedSrcPart);
    });
}

function canBeDiscarded(opts, mutation) {
    if (!opts.discardReplacements) {
        return false;
    }
    var discardPatterns = ensureRegExpArray(opts.discardReplacements);
    return _.any(discardPatterns, function (discardPattern) {
        return discardPattern.test(mutation.replacement);
    });
}

function createStats() {
    return {
        all: 0,
        ignored: 0,
        untested: 0 // if a test succeeds for mutated code, it's an untested mutation
    };
}

function addStats(stats1, stats2) {
    return _.mapValues(stats1, function (value, key) {
        return value + stats2[key];
    });
}

function createStatsMessage(stats) {
    var ignoredMessage = stats.ignored ? ' ' + stats.ignored + ' mutations were ignored.' : '';
    var allUnIgnored = stats.all - stats.ignored;
    var testedMutations = allUnIgnored - stats.untested;
    var percentTested = Math.floor((testedMutations / allUnIgnored) * 100);
    return testedMutations +
        ' of ' + allUnIgnored + ' unignored mutations are tested (' + percentTested + '%).' + ignoredMessage;
}

function truncateReplacement(opts, replacementArg) {
    var maxLength = opts.maxReplacementLength !== undefined ? opts.maxReplacementLength : 20;
    var replacement = replacementArg.replace(/\s+/g, ' ');
    if (maxLength > 0 && replacement.length > maxLength) {
        return replacement.slice(0, maxLength / 2) + ' ... ' + replacement.slice(-maxLength / 2);
    }
    return replacement;
}

function createMutationFileMessage(opts, srcFile) {
    // Normalize Windows paths to use '/' instead of '\\'
    if(os.platform() === 'win32') {
        srcFile = srcFile.replace(/\\/g, '/');
    }

    // Strip off anything before the basePath when present
    if(opts.basePath && srcFile.indexOf(opts.basePath) !== -1) {
        srcFile = srcFile.substr(srcFile.indexOf(opts.basePath));
    }

    return srcFile;
}

function createMutationLogMessage(opts, srcFilePath, mutation, src) {
    var srcFileName = createMutationFileMessage(opts, srcFilePath);
    var currentMutationPosition = srcFileName + ':' + mutation.line + ':' + (mutation.col + 1);
    var mutatedCode = src.substr(mutation.begin, mutation.end - mutation.begin);
    return currentMutationPosition + (
            mutation.replacement ?
            ' ' + truncateReplacement(opts, mutatedCode) + ' can be replaced with: ' + truncateReplacement(opts, mutation.replacement) :
            ' ' + truncateReplacement(opts, mutatedCode) + ' can be removed');
}

function createNotTestedBecauseInsideUntestedMutationLogMessage(opts, srcFilePath, mutation) {
    var srcFileName = createMutationFileMessage(opts, srcFilePath);
    var currentMutationPosition = srcFileName + ':' + mutation.line + ':' + (mutation.col + 1);
    return currentMutationPosition + ' is inside a surviving mutation';
}

function isInsideNotFailingMutation(innerMutation) {
    return _.indexOf(notFailingMutations, innerMutation.parentMutationId) > -1;
}

/**
 * @param {string} srcFilename
 * @param {function} runTests
 * @param {function} logMutation
 * @param {function} log the logger
 * @param {object} opts the config options
 */
function mutationTestFile(srcFilename, runTests, logMutation, log, opts) {
    var src = fs.readFileSync(srcFilename, 'UTF8');
    var mutations = mutate.findMutations(src, opts.excludeMutations);
    var mutationPromise = new QPromise({});

    var stats = createStats();

    log('\nMutating file ' + srcFilename + '\n');

    mutations.forEach(function (mutation) {
        stats.all += 1;
        if (canBeDiscarded(opts, mutation)) {
            return;
        }
        if (canBeIgnored(opts, src, mutation)) {
            stats.ignored += 1;
            return;
        }
        var perc = Math.round((stats.all / mutations.length) * 100);
        mutationPromise = mutationPromise.then(function () {
            log('Line ' + mutation.line + ' (' + perc + '%), ');
            if (opts.dontTestInsideNotFailingMutations && isInsideNotFailingMutation(mutation)) {
                stats.untested += 1;
                logMutation(createNotTestedBecauseInsideUntestedMutationLogMessage(opts, srcFilename, mutation));
                return;
            }
            fs.writeFileSync(srcFilename, mutate.applyMutation(src, mutation));
            return runTests().then(function (testSuccess) {
                if (testSuccess) {
                    logMutation(createMutationLogMessage(opts, srcFilename, mutation, src));
                    stats.untested += 1;
                    notFailingMutations.push(mutation.mutationId);
                }
            });
        });
    });

    mutationPromise = mutationPromise.then(function () {
        return stats;
    });

    return mutationPromise.fin(function () {
        console.log('\nRestore ', srcFilename);
        fs.writeFileSync(srcFilename, src);
    });
}

function mutationTest(grunt, task, opts) {
    var done = task.async();
    var mutationTestPromise = new QPromise();

    function logToMutationReport(fileDest, msg) {
        if (fileDest === 'LOG') {
            grunt.log.writeln('\n' + msg);
            return;
        }
        if (!grunt.file.exists(fileDest)) {
            grunt.file.write(fileDest, '');
        }
        fs.appendFileSync(fileDest, msg + '\n');
    }

    function runTests() {
        var deferred = QPromise.defer();
        if (typeof opts.test === 'string') {
            var execResult = exec(opts.test);
            deferred.resolve(execResult.status === 0);
        } else {
            opts.test(function (ok) {
                deferred.resolve(ok);
            });
        }
        return deferred.promise;
    }

    var files = task.files;

    opts.before(function () {
        // run first without mutations
        runTests().done(function (testOk) {
            if (!testOk) {
                files.forEach(function (file) {
                    logToMutationReport(file.dest, 'Tests fail without mutations.');
                });
            } else {
                files.forEach(function (file) {
                    mutationTestPromise = mutationTestPromise.then(function () {
                        var validFiles = file.src.filter(function (filepath) {
                            if (!grunt.file.exists(filepath)) {
                                grunt.log.warn('Source file "' + filepath + '" not found.');
                                return false;
                            } else {
                                return true;
                            }
                        });

                        if (validFiles.length === 0) {
                            grunt.log.warn('Found no valid files in ' + JSON.stringify(file.orig.src));
                            return false;
                        }

                        function log(msg) {
                            grunt.log.write(msg);
                        }

                        var logMutationToFileDest = _.partial(logToMutationReport, file.dest);
                        var statsSummary = createStats();

                        var mutationFilesPromise = new QPromise();
                        validFiles.forEach(function (srcFile) {
                            mutationFilesPromise = mutationFilesPromise.then(function () {
                                return mutationTestFile(path.resolve(srcFile), runTests, logMutationToFileDest, log, opts).then(function (stats) {
                                    statsSummary = addStats(statsSummary, stats);
                                });
                            });
                        });

                        mutationFilesPromise = mutationFilesPromise.then(function () {
                            logMutationToFileDest(createStatsMessage(statsSummary));
                        });

                        return mutationFilesPromise;
                    });
                });
            }

            mutationTestPromise.then(function () {
                var dfd = QPromise.defer();
                opts.after(function () {
                    dfd.resolve();
                });
                return dfd.promise;
            });
            mutationTestPromise.done(done);
        });
    });
}

function callDone(done) {
    done(true);
}

var DEFAULT_OPTIONS = {
    test: callDone,
    before: callDone,
    after: callDone
};

module.exports = function (grunt) {
    grunt.registerMultiTask('mutationTest', 'Test your tests by mutating the production code.', function () {
        var opts = this.options(DEFAULT_OPTIONS);
        mutationTestingKarma.init(grunt, opts);
        mutationTestingMocha.init(grunt, opts);
        mutationTest(grunt, this, opts);
    });
};
<|endoftext|>


<commit_before>/*
 * grunt-mutation-testing
 *
 *
 * Copyright (c) 2014 Marco Stahl
 * Licensed under the MIT license.
 *
 * TODO (Martin Koster): split up this file and refactor to effect better separation of concerns. That should also improve legibility
 */

'use strict';
var esprima = require('esprima');
var fs = require('fs');
var exec = require('sync-exec');
var path = require('path');
var Q = require('q');
var _ = require('lodash');

var Mutator = require('../lib/Mutator');
var mutationTestingKarma = require('./mutation-testing-karma');
var mutationTestingMocha = require('./mutation-testing-mocha');
var OptionUtils = require('../utils/OptionUtils');

var IOUtils = require('../utils/IOUtils');
var reportGenerator = require('../lib/reporting/ReportGenerator');
var notFailingMutations = [];

function ensureRegExpArray(value) {
    var array = _.isArray(value) ? value : [value];
    return array.map(function (stringOrRegExp) {
        return _.isString(stringOrRegExp) ? new RegExp('^' + stringOrRegExp + '$') : stringOrRegExp;
    });
}

function canBeIgnored(opts, src, mutation) {
    if (!opts.ignore) {
        return false;
    }
    var ignorePatterns = ensureRegExpArray(opts.ignore);
    var affectedSrcPart = src.substring(mutation.begin, mutation.end);
    return _.any(ignorePatterns, function (ignorePattern) {
        return ignorePattern.test(affectedSrcPart);
    });
}

function canBeDiscarded(opts, mutation) {
    if (!opts.discardReplacements) {
        return false;
    }
    var discardPatterns = ensureRegExpArray(opts.discardReplacements);
    return _.any(discardPatterns, function (discardPattern) {
        return discardPattern.test(mutation.replacement);
    });
}

function createStats() {
    return {
        all: 0,
        ignored: 0,
        untested: 0,
        survived: 0
    };
}

function addStats(stats1, stats2) {
    return _.mapValues(stats1, function (value, key) {
        return value + stats2[key];
    });
}

function createStatsMessage(stats) {
    var ignoredMessage = stats.ignored ? ' ' + stats.ignored + ' mutations were ignored.' : '';
    var allUnIgnored = stats.all - stats.ignored;
    var testedMutations = allUnIgnored - stats.untested - stats.survived;
    var percentTested = Math.floor((testedMutations / allUnIgnored) * 100);
    return testedMutations +
        ' of ' + allUnIgnored + ' unignored mutations are tested (' + percentTested + '%).' + ignoredMessage;
}

function truncateReplacement(opts, replacementArg) {
    var maxLength = opts.maxReportedMutationLength !== undefined ? opts.maxReportedMutationLength : 80;
    var replacement = replacementArg.replace(/\s+/g, ' ');
    if (maxLength > 0 && replacement.length > maxLength) {
        return replacement.slice(0, maxLength / 2) + ' ... ' + replacement.slice(-maxLength / 2);
    }
    return replacement;
}

function createMutationFileMessage(opts, srcFile) {
    return IOUtils.normalizeWindowsPath(_.last(srcFile.split(opts.basePath)));
}

function createMutationLogMessage(opts, srcFilePath, mutation, src, testSurvived) {
    var srcFileName = createMutationFileMessage(opts, srcFilePath),
        result = testSurvived ? "SURVIVED" : "KILLED",
        currentMutationPosition = srcFileName + ':' + mutation.line + ':' + (mutation.col + 1),
        mutatedCode = src.substr(mutation.begin, mutation.end - mutation.begin),
        message = currentMutationPosition + (
            mutation.replacement ?
            ' Replaced ' + truncateReplacement(opts, mutatedCode) + ' with ' + truncateReplacement(opts, mutation.replacement) + ' -> ' + result :
            ' Removed ' + truncateReplacement(opts, mutatedCode) + ' -> ' + result
            );

    return {
        mutation: mutation,
        survived: testSurvived,
        message: message
    };
}

function createTestsFailWithoutMutationsLogMessage(opts, srcFilePath) {
    var srcFileName = createMutationFileMessage(opts, srcFilePath);
    return srcFileName + ' tests fail without mutations';
}

function createNotTestedBecauseInsideUntestedMutationLogMessage(opts, srcFilePath, mutation) {
    var srcFileName = createMutationFileMessage(opts, srcFilePath);
    var currentMutationPosition = srcFileName + ':' + mutation.line + ':' + (mutation.col + 1);
    return currentMutationPosition + ' is inside a surviving mutation';
}

function isInsideNotFailingMutation(innerMutation) {
    return _.indexOf(notFailingMutations, innerMutation.parentMutationId) > -1;
}

/**
 * @param {string} srcFilename
 * @param {function} runTests
 * @param {function} logMutation
 * @param {function} log the logger
 * @param {object} opts the config options
 */
function mutationTestFile(srcFilename, runTests, logMutation, log, opts) {
    var src = fs.readFileSync(path.resolve(srcFilename), 'UTF8');
    var mutator = new Mutator(src);
    var mutations = mutator.collectMutations(opts.excludeMutations);
    var mutationPromise = new Q({});

    var stats = createStats();
    var fileMutationResult = {
        stats: stats,
        src: src,
        fileName: createMutationFileMessage(opts, srcFilename),
        mutationResults: []
    };

    log('\nMutating file ' + srcFilename + '\n');

    mutations.forEach(function (mutation) {
        stats.all += 1;
        if (canBeDiscarded(opts, mutation)) {
            return;
        }
        if (canBeIgnored(opts, src, mutation)) {
            stats.ignored += 1;
            return;
        }
        var perc = Math.round((stats.all / mutations.length) * 100);
        mutationPromise = mutationPromise.then(function () {
            log('Line ' + mutation.line + ' (' + perc + '%), ');
            if (opts.dontTestInsideNotFailingMutations && isInsideNotFailingMutation(mutation)) {
                stats.untested += 1;
                logMutation(createNotTestedBecauseInsideUntestedMutationLogMessage(opts, srcFilename, mutation));
                return;
            }
            fs.writeFileSync(srcFilename, mutator.applyMutation(mutation));
            return runTests().then(function (testSurvived) {
				var mutationResult = createMutationLogMessage(opts, srcFilename, mutation, src, testSurvived);
                fileMutationResult.mutationResults.push(mutationResult);
                if (testSurvived) {
                    stats.survived += 1;
                    logMutation(mutationResult.message);
                    notFailingMutations.push(mutation.mutationId);
                }
            });
        });
    });

    mutationPromise = mutationPromise.then(function () {
        return {stats: stats, fileMutationResult: fileMutationResult};
    });

    return mutationPromise.fin(function () {
        console.log('\nRestore ', srcFilename);
        fs.writeFileSync(srcFilename, src);
    });
}

function mutationTest(grunt, task, opts) {
    var done = task.async(),
        mutationTestPromise = new Q(),
        totalResults = [];

    function logToMutationReport(fileDest, msg) {
        if (fileDest === 'LOG') {
            grunt.log.writeln('\n' + msg);
            return;
        }
        if (!grunt.file.exists(fileDest)) {
            grunt.file.write(fileDest, '');
        }
        fs.appendFileSync(fileDest, msg + '\n');
    }

    function createMutationCoverageReport(results){
        if(opts.mutationCoverageReporter) {
            grunt.log.writeln('Generating the mutation coverage report in directory: ' + opts.mutationCoverageReporter.dir);
            reportGenerator.generate(opts.mutationCoverageReporter, results);
        }
    }

    function runTests() {
        var deferred = Q.defer();
        if (typeof opts.test === 'string') {
            var execResult = exec(opts.test);
            deferred.resolve(execResult.status === 0);
        } else {
            opts.test(function (ok) {
                deferred.resolve(ok);
            });
        }
        return deferred.promise;
    }

    opts.before(function () {
        var logFile = 'LOG',
            logMutationToFileDest;
        if(opts.reporters.text) {
            logFile = path.join(opts.reporters.text.dir, opts.reporters.text.file || 'grunt-mutation-testing.txt');
        }
        logMutationToFileDest = _.partial(logToMutationReport, logFile);

        // run first without mutations
        runTests().done(function (testOk) {
            if (!testOk) {
                opts.mutate.forEach(function(file) {
                    logMutationToFileDest(createTestsFailWithoutMutationsLogMessage(opts, file));
                });
            } else {
                var statsSummary = createStats();
                opts.mutate.forEach(function(file) {
                    mutationTestPromise = mutationTestPromise.then(function () {
                        if(!grunt.file.exists(file)) {
                            grunt.log.warn('Source file "' + file + '" not found.');
                            return false;
                        }

                        function log(msg) {
                            grunt.log.write(msg);
                        }

                        return mutationTestFile(path.resolve(file), runTests, logMutationToFileDest, log, opts).then(function(opts) {
                            statsSummary = addStats(statsSummary, opts.stats);
                            totalResults.push(opts.fileMutationResult);
                        });
                    });
                });
                mutationTestPromise = mutationTestPromise.then(function() {
                    logMutationToFileDest(createStatsMessage(statsSummary));
                });
            }

            mutationTestPromise.then(function () {
                createMutationCoverageReport(totalResults);
                var dfd = Q.defer();
                opts.after(function () {
                    dfd.resolve();
                });
                return dfd.promise;
            });
            mutationTestPromise.done(done);
        });
    });
}

module.exports = function (grunt) {
    grunt.registerMultiTask('mutationTest', 'Test your tests by mutating the code.', function() {
        var opts = OptionUtils.getOptions(grunt, this);
        mutationTestingKarma.init(grunt, opts);
        mutationTestingMocha.init(grunt, opts);
        mutationTest(grunt, this, opts);
    });
};
<commit_msg>Fixed createMutationFileMessage not working properly on Windows.<commit_after>/*
 * grunt-mutation-testing
 *
 *
 * Copyright (c) 2014 Marco Stahl
 * Licensed under the MIT license.
 *
 * TODO (Martin Koster): split up this file and refactor to effect better separation of concerns. That should also improve legibility
 */

'use strict';
var esprima = require('esprima');
var fs = require('fs');
var exec = require('sync-exec');
var path = require('path');
var Q = require('q');
var _ = require('lodash');

var Mutator = require('../lib/Mutator');
var mutationTestingKarma = require('./mutation-testing-karma');
var mutationTestingMocha = require('./mutation-testing-mocha');
var OptionUtils = require('../utils/OptionUtils');

var IOUtils = require('../utils/IOUtils');
var reportGenerator = require('../lib/reporting/ReportGenerator');
var notFailingMutations = [];

function ensureRegExpArray(value) {
    var array = _.isArray(value) ? value : [value];
    return array.map(function (stringOrRegExp) {
        return _.isString(stringOrRegExp) ? new RegExp('^' + stringOrRegExp + '$') : stringOrRegExp;
    });
}

function canBeIgnored(opts, src, mutation) {
    if (!opts.ignore) {
        return false;
    }
    var ignorePatterns = ensureRegExpArray(opts.ignore);
    var affectedSrcPart = src.substring(mutation.begin, mutation.end);
    return _.any(ignorePatterns, function (ignorePattern) {
        return ignorePattern.test(affectedSrcPart);
    });
}

function canBeDiscarded(opts, mutation) {
    if (!opts.discardReplacements) {
        return false;
    }
    var discardPatterns = ensureRegExpArray(opts.discardReplacements);
    return _.any(discardPatterns, function (discardPattern) {
        return discardPattern.test(mutation.replacement);
    });
}

function createStats() {
    return {
        all: 0,
        ignored: 0,
        untested: 0,
        survived: 0
    };
}

function addStats(stats1, stats2) {
    return _.mapValues(stats1, function (value, key) {
        return value + stats2[key];
    });
}

function createStatsMessage(stats) {
    var ignoredMessage = stats.ignored ? ' ' + stats.ignored + ' mutations were ignored.' : '';
    var allUnIgnored = stats.all - stats.ignored;
    var testedMutations = allUnIgnored - stats.untested - stats.survived;
    var percentTested = Math.floor((testedMutations / allUnIgnored) * 100);
    return testedMutations +
        ' of ' + allUnIgnored + ' unignored mutations are tested (' + percentTested + '%).' + ignoredMessage;
}

function truncateReplacement(opts, replacementArg) {
    var maxLength = opts.maxReportedMutationLength !== undefined ? opts.maxReportedMutationLength : 80;
    var replacement = replacementArg.replace(/\s+/g, ' ');
    if (maxLength > 0 && replacement.length > maxLength) {
        return replacement.slice(0, maxLength / 2) + ' ... ' + replacement.slice(-maxLength / 2);
    }
    return replacement;
}

function createMutationFileMessage(opts, srcFile) {
    var normalizedBasePath = IOUtils.normalizeWindowsPath(opts.basePath),
        normalizedSrcFile = IOUtils.normalizeWindowsPath(srcFile);
    return _.last(normalizedSrcFile.split(normalizedBasePath));
}

function createMutationLogMessage(opts, srcFilePath, mutation, src, testSurvived) {
    var srcFileName = createMutationFileMessage(opts, srcFilePath),
        result = testSurvived ? "SURVIVED" : "KILLED",
        currentMutationPosition = srcFileName + ':' + mutation.line + ':' + (mutation.col + 1),
        mutatedCode = src.substr(mutation.begin, mutation.end - mutation.begin),
        message = currentMutationPosition + (
            mutation.replacement ?
            ' Replaced ' + truncateReplacement(opts, mutatedCode) + ' with ' + truncateReplacement(opts, mutation.replacement) + ' -> ' + result :
            ' Removed ' + truncateReplacement(opts, mutatedCode) + ' -> ' + result
            );

    return {
        mutation: mutation,
        survived: testSurvived,
        message: message
    };
}

function createTestsFailWithoutMutationsLogMessage(opts, srcFilePath) {
    var srcFileName = createMutationFileMessage(opts, srcFilePath);
    return srcFileName + ' tests fail without mutations';
}

function createNotTestedBecauseInsideUntestedMutationLogMessage(opts, srcFilePath, mutation) {
    var srcFileName = createMutationFileMessage(opts, srcFilePath);
    var currentMutationPosition = srcFileName + ':' + mutation.line + ':' + (mutation.col + 1);
    return currentMutationPosition + ' is inside a surviving mutation';
}

function isInsideNotFailingMutation(innerMutation) {
    return _.indexOf(notFailingMutations, innerMutation.parentMutationId) > -1;
}

/**
 * @param {string} srcFilename
 * @param {function} runTests
 * @param {function} logMutation
 * @param {function} log the logger
 * @param {object} opts the config options
 */
function mutationTestFile(srcFilename, runTests, logMutation, log, opts) {
    var src = fs.readFileSync(path.resolve(srcFilename), 'UTF8');
    var mutator = new Mutator(src);
    var mutations = mutator.collectMutations(opts.excludeMutations);
    var mutationPromise = new Q({});

    var stats = createStats();
    var fileMutationResult = {
        stats: stats,
        src: src,
        fileName: createMutationFileMessage(opts, srcFilename),
        mutationResults: []
    };

    log('\nMutating file ' + srcFilename + '\n');

    mutations.forEach(function (mutation) {
        stats.all += 1;
        if (canBeDiscarded(opts, mutation)) {
            return;
        }
        if (canBeIgnored(opts, src, mutation)) {
            stats.ignored += 1;
            return;
        }
        var perc = Math.round((stats.all / mutations.length) * 100);
        mutationPromise = mutationPromise.then(function () {
            log('Line ' + mutation.line + ' (' + perc + '%), ');
            if (opts.dontTestInsideNotFailingMutations && isInsideNotFailingMutation(mutation)) {
                stats.untested += 1;
                logMutation(createNotTestedBecauseInsideUntestedMutationLogMessage(opts, srcFilename, mutation));
                return;
            }
            fs.writeFileSync(srcFilename, mutator.applyMutation(mutation));
            return runTests().then(function (testSurvived) {
				var mutationResult = createMutationLogMessage(opts, srcFilename, mutation, src, testSurvived);
                fileMutationResult.mutationResults.push(mutationResult);
                if (testSurvived) {
                    stats.survived += 1;
                    logMutation(mutationResult.message);
                    notFailingMutations.push(mutation.mutationId);
                }
            });
        });
    });

    mutationPromise = mutationPromise.then(function () {
        return {stats: stats, fileMutationResult: fileMutationResult};
    });

    return mutationPromise.fin(function () {
        console.log('\nRestore ', srcFilename);
        fs.writeFileSync(srcFilename, src);
    });
}

function mutationTest(grunt, task, opts) {
    var done = task.async(),
        mutationTestPromise = new Q(),
        totalResults = [];

    function logToMutationReport(fileDest, msg) {
        if (fileDest === 'LOG') {
            grunt.log.writeln('\n' + msg);
            return;
        }
        if (!grunt.file.exists(fileDest)) {
            grunt.file.write(fileDest, '');
        }
        fs.appendFileSync(fileDest, msg + '\n');
    }

    function createMutationCoverageReport(results){
        if(opts.mutationCoverageReporter) {
            grunt.log.writeln('Generating the mutation coverage report in directory: ' + opts.mutationCoverageReporter.dir);
            reportGenerator.generate(opts.mutationCoverageReporter, results);
        }
    }

    function runTests() {
        var deferred = Q.defer();
        if (typeof opts.test === 'string') {
            var execResult = exec(opts.test);
            deferred.resolve(execResult.status === 0);
        } else {
            opts.test(function (ok) {
                deferred.resolve(ok);
            });
        }
        return deferred.promise;
    }

    opts.before(function () {
        var logFile = 'LOG',
            logMutationToFileDest;
        if(opts.reporters.text) {
            logFile = path.join(opts.reporters.text.dir, opts.reporters.text.file || 'grunt-mutation-testing.txt');
        }
        logMutationToFileDest = _.partial(logToMutationReport, logFile);

        // run first without mutations
        runTests().done(function (testOk) {
            if (!testOk) {
                opts.mutate.forEach(function(file) {
                    logMutationToFileDest(createTestsFailWithoutMutationsLogMessage(opts, file));
                });
            } else {
                var statsSummary = createStats();
                opts.mutate.forEach(function(file) {
                    mutationTestPromise = mutationTestPromise.then(function () {
                        if(!grunt.file.exists(file)) {
                            grunt.log.warn('Source file "' + file + '" not found.');
                            return false;
                        }

                        function log(msg) {
                            grunt.log.write(msg);
                        }

                        return mutationTestFile(path.resolve(file), runTests, logMutationToFileDest, log, opts).then(function(opts) {
                            statsSummary = addStats(statsSummary, opts.stats);
                            totalResults.push(opts.fileMutationResult);
                        });
                    });
                });
                mutationTestPromise = mutationTestPromise.then(function() {
                    logMutationToFileDest(createStatsMessage(statsSummary));
                });
            }

            mutationTestPromise.then(function () {
                createMutationCoverageReport(totalResults);
                var dfd = Q.defer();
                opts.after(function () {
                    dfd.resolve();
                });
                return dfd.promise;
            });
            mutationTestPromise.done(done);
        });
    });
}

module.exports = function (grunt) {
    grunt.registerMultiTask('mutationTest', 'Test your tests by mutating the code.', function() {
        var opts = OptionUtils.getOptions(grunt, this);
        mutationTestingKarma.init(grunt, opts);
        mutationTestingMocha.init(grunt, opts);
        mutationTest(grunt, this, opts);
    });
};
<|endoftext|>