<commit_before>
// create our angular app and inject ngAnimate and ui-router
// =============================================================================
angular.module('formApp', ['ngAnimate', 'ui.router'])

// configuring our routes
// =============================================================================
.config(function($stateProvider, $urlRouterProvider) {

    $stateProvider

        // route to show our basic form (/form)
        .state('form', {
            url: '/form',
            templateUrl: 'form.html',
            controller: 'formController'
        })

        // nested states
        // each of these sections will have their own view
        // url will be nested (/form/target)
        .state('form.target', {
            url: '/target',
            templateUrl: 'form-target.html'
        })

        // url will be /form/category
        .state('form.category', {
            url: '/category',
            templateUrl: 'form-category.html'
        })

        // url will be /form/keywords
        .state('form.keywords', {
            url: '/keywords',
            templateUrl: 'form-keywords.html'
        })

        // url will be /form/comments
        .state('form.comments', {
            url: '/comments',
            templateUrl: 'form-comments.html'
        })

        // url will be /form/logo
        .state('form.logo', {
            url: '/logo',
            templateUrl: 'form-logo.html'
        })

        // url will be /form/comments
        .state('form.summary', {
            url: '/summary',
            templateUrl: 'form-summary.html'
        });

    // catch all route
    // send users to the form page
    $urlRouterProvider.otherwise('/form/target');
})

// our controller for the form
// =============================================================================
.controller('formController', function($scope, $http, $state) {

    var default_audience = {"kids":false,"teens":false,"adults":false,"elderly":false};
    var default_category = {"travel":false,"fitness":false,"social":false,"productivity":false,"media":false,"finance":false,"shopping":false,"education":false};
    var default_keywords = {"transportation":false,"lodging":false,"attractions":false,"running":false,"diet":false,"workout":false,"chat":false,"professional":false,"dating":false,"note":false,"list":false,"calendar":false,"banking":false,"investments":false,"budget":false,"clothing":false,"home":false,"electronics":false,"music":false,"video":false,"photo":false,"study":false,"learn":false,"reference":false};

    // we will store all of our form data in this object
    $scope.audience = angular.copy(default_audience);
    $scope.category = angular.copy(default_category);
    $scope.keywords = angular.copy(default_keywords);
    $scope.comments = "";
    $scope.SelectedLogo = -1;

    $scope.completed = function (obj) {
        var keys = Object.keys(obj);
        return keys.map(function (key) {
            return obj[key];
        }).filter(function (value) {
            return value;
        }).length > 0;
    };

    $scope.startOver = function() {
        $scope.audience = angular.copy(default_audience);
        $scope.category = angular.copy(default_category);
        $scope.keywords = angular.copy(default_keywords);
        $scope.comments = "";
    }

    $scope.getLogo = function() {
        $http({
            method  : 'POST',
            url     : 'http://startr.mybluemix.net/processData',
            data    : {
                "target"   : $scope.audience,
                "category" : $scope.category,
                "keywords" : $scope.keywords,
                "comments" : $scope.comments }
        })
        .success(function(data) {
            console.log(data);

            // if (!data.success) {
            //     $scope.errorlogo = data.errors.logo;
            // }
            // else {
                $scope.serverResponse = data;

                $scope.styles = $scope.serverResponse.map(function (value) {
                    var sizes = {
                        "small": 30,
                        "normal": 40,
                        "big": 60
                    };

                    return {
                        "font-family" : value._font,
                        "font-size" : sizes[value._size] + "px"
                    };
                });

                $state.go('form.logo')

            // }
        });
    }

    //function to process the form
    $scope.processForm = function() {

    };

});

<commit_msg>Modified response receipt<commit_after>
// create our angular app and inject ngAnimate and ui-router
// =============================================================================
angular.module('formApp', ['ngAnimate', 'ui.router'])

// configuring our routes
// =============================================================================
.config(function($stateProvider, $urlRouterProvider) {

    $stateProvider

        // route to show our basic form (/form)
        .state('form', {
            url: '/form',
            templateUrl: 'form.html',
            controller: 'formController'
        })

        // nested states
        // each of these sections will have their own view
        // url will be nested (/form/target)
        .state('form.target', {
            url: '/target',
            templateUrl: 'form-target.html'
        })

        // url will be /form/category
        .state('form.category', {
            url: '/category',
            templateUrl: 'form-category.html'
        })

        // url will be /form/keywords
        .state('form.keywords', {
            url: '/keywords',
            templateUrl: 'form-keywords.html'
        })

        // url will be /form/comments
        .state('form.comments', {
            url: '/comments',
            templateUrl: 'form-comments.html'
        })

        // url will be /form/logo
        .state('form.logo', {
            url: '/logo',
            templateUrl: 'form-logo.html'
        })

        // url will be /form/comments
        .state('form.summary', {
            url: '/summary',
            templateUrl: 'form-summary.html'
        });

    // catch all route
    // send users to the form page
    $urlRouterProvider.otherwise('/form/target');
})

// our controller for the form
// =============================================================================
.controller('formController', function($scope, $http, $state) {

    var default_audience = {"kids":false,"teens":false,"adults":false,"elderly":false};
    var default_category = {"travel":false,"fitness":false,"social":false,"productivity":false,"media":false,"finance":false,"shopping":false,"education":false};
    var default_keywords = {"transportation":false,"lodging":false,"attractions":false,"running":false,"diet":false,"workout":false,"chat":false,"professional":false,"dating":false,"note":false,"list":false,"calendar":false,"banking":false,"investments":false,"budget":false,"clothing":false,"home":false,"electronics":false,"music":false,"video":false,"photo":false,"study":false,"learn":false,"reference":false};

    // we will store all of our form data in this object
    $scope.audience = angular.copy(default_audience);
    $scope.category = angular.copy(default_category);
    $scope.keywords = angular.copy(default_keywords);
    $scope.comments = "";
    $scope.SelectedLogo = -1;

    $scope.completed = function (obj) {
        var keys = Object.keys(obj);
        return keys.map(function (key) {
            return obj[key];
        }).filter(function (value) {
            return value;
        }).length > 0;
    };

    $scope.startOver = function() {
        $scope.audience = angular.copy(default_audience);
        $scope.category = angular.copy(default_category);
        $scope.keywords = angular.copy(default_keywords);
        $scope.comments = "";
    }

    $scope.getLogo = function() {
        $http({
            method  : 'POST',
            url     : 'http://startr.mybluemix.net/processData',
            data    : {
                "target"   : $scope.audience,
                "category" : $scope.category,
                "keywords" : $scope.keywords,
                "comments" : $scope.comments }
        })
        .success(function(data) {
            console.log(data);

            // if (!data.success) {
            //     $scope.errorlogo = data.errors.logo;
            // }
            // else {
                $scope.serverResponse = data.results;
                $scope.serverAnalysis = data.analysis;

                $scope.styles = $scope.serverResponse.map(function (value) {
                    var sizes = {
                        "small": 30,
                        "normal": 40,
                        "big": 60
                    };

                    return {
                        "font-family" : value._font,
                        "font-size" : sizes[value._size] + "px"
                    };
                });

                $state.go('form.logo')

            // }
        });
    }

    //function to process the form
    $scope.processForm = function() {

    };

});

<|endoftext|>


<commit_before>	var WHOLE_LIST;   // boolean if long or short list
    var SHORT_LIST;   // array of max 31. results
    var LONG_LIST;    // array of all results if spezific request
    var PREFIX;       // string of input before request for more results
    var CUT_LIST;     // cutted results list of Long List
    var INDEX;        // which topic is marked
    var IE;			  // boolean if Internet Explorer
    var MOUSE_OVER;   // if the mouse is over the input or list area
    var FIELD;		  // field name from the table vor the lucene search
    var CLASS_NAME;   // class name (table in the database) for lucene search
    var INPUT;		  // input field id in the jsp file
  	var DISPLAY;      // id of the div for the the list
  	var ERROR;        // id of the div for the error message
  	var FRAME;        // a frame which is displayed under the result list to fix bugs in IE

  	setWholeList(false);
    setPrefix("");
    SHORT_LIST = new Array();
    LONG_LIST = new Array();
    CUT_LIST = new Array();
    setIndex(-1);
    IE = false;
    MOUSE_OVER = 0;

  	function setMouseOver(mouseOver) {
  		MOUSE_OVER = mouseOver;
  	}

  	function setWholeList(wholeList) {
  		WHOLE_LIST = wholeList;
  	}

  	function getWholeList() {
  		return WHOLE_LIST;
  	}

  	function setCutList( cutList) {
  		CUT_LIST = cutList;
  	}

  	function setShortList( list) {
  		SHORT_LIST = list;
  	}

  	function setLongList( longList) {
  		LONG_LIST = longList;
  	}

  	function setPrefix( prefix) {
  		PREFIX = prefix;
  	}

  	function setIndex( index) {
  		INDEX = index;
  	}

  	function getId(input) {
  		INPUT = input;
  		DISPLAY = input + "_display";
  		ERROR = input + "_error";
  		FRAME = input + "_IEbugFixFrame";
  	}

	// AJAX request to load a long or short array
  	function loadList() {
      AjaxServices.getContent( document.getElementById(INPUT).value,
                                     getWholeList(),
                                     FIELD,
                                     CLASS_NAME,
                                     function (array) {
                                     		$(INPUT).focus();
                                        	if (array[0] == "true") {
                                        		if (getWholeList()) {
                                          			setCutList(getElementList(array));
                                          			setLongList(CUT_LIST);
                                        		} else {
                                         			setShortList(getElementList(array));
                                        		}
                                        		setPrefix(document.getElementById(INPUT).value);
                                       	 		printList(getElementList(array));
                                        	} else if (array[0] != '') {
                                        		printError(array[0]);
                                        	}
                                      }
                                 );
    }

    // output if an error appears
    function printError(error) {
    	removeList();
    	$(ERROR).style.visibility = "visible";
    	getCoordinates($(ERROR), $(INPUT));
    	$(ERROR).appendChild(document.createTextNode(error));
    }

    // cut off the first element which could containts error messages
    function getElementList(array) {
        var elemList = new Array(array.length - 1);

        for (var i = 0; i < elemList.length; i++) {
                elemList[i] = array[i+1];
        }
        return elemList;
	}

    // after every Keyboard hit
    function readInput(e, className, field) {
    	CLASS_NAME = className;
    	FIELD = field;
    	var curKey;
    	if (e.which) {   			// FF
        	curKey = e.which;
        	IE = false;
      	} else if (e.keyCode) {     // IE
      		curKey = e.keyCode;
      		IE = true;
      	}

        // ascii code from "a" till  "z" or
        // ascii code from "0" till "9"
        // backspace
        // delete
		if ((curKey >= 65 && curKey <= 90) ||        // load list
            (curKey >= 48 && curKey <= 57) ||
        	(curKey >= 96 && curKey <= 105) ||
        	curKey == 8 || curKey == 46) {
        	setIndex(-1);
        	if (WHOLE_LIST && $(INPUT).value.indexOf(PREFIX) != 0) {
            	setWholeList(false);
       			loadList();
        	} else if (WHOLE_LIST) {
        		cutLongList();
        		printList(CUT_LIST);
        	} else if (!WHOLE_LIST) {
          		loadList();
        	}
        } else if (curKey == 38) {                    // up arrow

        	var len;
        	if (WHOLE_LIST) {
        		len = CUT_LIST.length -1;
        	} else {
        		len = SHORT_LIST.length -1;
        	}

        	remarkIndex();

        	if (INDEX > -1) {
            	setIndex(INDEX - 1);
          	} else {
          		setIndex(len);
          	}
          	scrollUp(len);
          	markIndex();
        } else if (curKey == 40) {                     // down arrow

        	var len;
        	if (WHOLE_LIST) {
        		len = CUT_LIST.length -1;
        	} else {
           		len = SHORT_LIST.length -1;
        	}

        	remarkIndex();

        	if (INDEX < len) {
        		setIndex(INDEX + 1);
        	} else {
           		setIndex(-1);
        	}

        	scrollDown(len);
        	markIndex();
        } else {
        	setIndex(-1);
        }
	}

    // spezific function for Querybuilder
    function isSubmit(e) {
    	// enter
    	if (e.which == 13 && INDEX > -1) {
        	if (WHOLE_LIST) {
          		$(INPUT).value = CUT_LIST[INDEX];
        	} else {
          		$(INPUT).value = SHORT_LIST[INDEX];
        	}
        	removeList();
        	$('attribute').click(); // submit the constraint
      	}
    }

    // spezific function for submit in template
    function isEnter(e) {
        var curKey;
    	if (e.which) {   			// FF
        	curKey = e.which;
      	} else if (e.keyCode) {     // IE
      		curKey = e.keyCode;
      	}
    	//enter
    	if (curKey == 13) {
            Event.stop(e);
    		if (INDEX > -1) {
    			if (WHOLE_LIST) {
          			$(INPUT).value = CUT_LIST[INDEX];
        		} else {
          			$(INPUT).value = SHORT_LIST[INDEX];
        		}
        	}
        	removeList();
        }
        // tabstop
        if (curKey == 9) {
        	removeList();
        }
    }

    // highlight the actual topic
    function markIndex() {
    	if (INDEX != -1) {
    		$('li' + INDEX.toString()).style.background = '#8AECFF';
    	}
    }

    // remove the higlight of the actual topic
    function remarkIndex() {
    	if (INDEX != -1) {
    		$('li' + INDEX.toString()).style.background = 'none';
    	}
    }

    // paint a spezific list
	function printList(array) {
		removeList();
		if ($(INPUT).value != "" && array.length > 0) {
	    	getCoordinates($(DISPLAY), $(INPUT));

	    	if (IE) {
				getCoordinates($(FRAME), $(INPUT));
				$(FRAME).height = "150";
	    	}

	    	var ul = document.createElement('ul');
	    	ul.setAttribute("id", "ulList");
			var li;

			for (var i = 0; i < array.length; i++) {
				// IE & FF
				li = document.createElement('li');
			    li.setAttribute("val", array[i].toString());
				li.setAttribute("id", "li" + i.toString());
				if (IE) {
					li.setAttribute("onmousedown", function() { $(INPUT).value = this.getAttribute('val'); removeList();});
					li.setAttribute("onmouseover", function() {  remarkIndex();
																 setIndex(parseInt(this.getAttribute('id').replace("li","")));
																 markIndex();
															   });
					li.setAttribute("onmouseout", function() { remarkIndex(); setIndex(-1); } );
				} else { // FF
					li.setAttribute("onMouseDown", "$(INPUT).value = this.getAttribute('val'); removeList();" );
					li.setAttribute("onMouseOver", "remarkIndex(); setIndex(" + i + "); markIndex();" );
					li.setAttribute("onMouseOut", "remarkIndex(); setIndex(-1);" );
				}
				// IE & FF
				$(DISPLAY).style.visibility = "visible";
				li.appendChild(document.createTextNode(array[i]));
				ul.appendChild(li);
			}

			// should the link for more results shown
			if (!WHOLE_LIST && array.length == 31 && $(INPUT).value.length > 3) {
				// IE & FF
                var input = document.createElement('input');
                input.setAttribute("type", "button");
                if (IE) {
                	input.setAttribute("onmousedown", function() { setWholeList(true); loadList(); });
                	input.setAttribute("onmouseout", function() { this.style.background = '#b2cdbf'; });
                	input.setAttribute("onmouseover", function() { this.style.background = '#8AECFF'; });
                	input.style.background = "#b2cdbf";
    				input.style.color = "#4c4d6b";
    				input.style.border = "none";
                	input.style.width = "100%";
                } else { // FF
                	input.setAttribute("class", "more_results");
                	input.setAttribute("onMouseDown", "setWholeList(true); loadList();");
                	input.setAttribute("onMouseOver", "this.style.background = '#8AECFF';");
                	input.setAttribute("onMouseOut", "this.style.background = '#b2cdbf';");
                }
     			// IE & FF
                input.setAttribute("value", "MORE RESULTS...");
                input.setAttribute("TABINDEX","0");
                ul.appendChild(input);
			}
			$(DISPLAY).appendChild(ul);
		} else {
	    	$(FRAME).height = "0"; // IE
	    }
	}

	// remove the list
	function removeList () {
		setIndex(-1);
		for (var i = 0; i < 2; i++) {
			if ($(DISPLAY).hasChildNodes()) {
  				$(DISPLAY).removeChild($(DISPLAY).firstChild);
  			}
  		}
  		if ($(ERROR).hasChildNodes()) {
  			$(ERROR).removeChild($(ERROR).firstChild);
  		}
  		if (IE) {
  			$(FRAME).height = "0";
  			$(DISPLAY).style.visibility = "hidden";
  			$(ERROR).style.visibility = "hidden";
  		}
	}

	// search and store the position from source element to the
	// target element
	function getCoordinates(target, source) {
        target.clonePosition( source, {
          setHeight:false,
          offsetTop: source.offsetHeight
        });
    }

	// created a spezific cutted list of the long list
	// and store it to CUT_LIST
    function cutLongList() {
    	var tmp = new Array();
    	var wordList = new Array();
    	var input =  $(INPUT).value;

    	tmp = input.split(' ');
    	// all other searchwords added to the wordList
    	for (var i = 0; i < tmp.length; i++) {
  			if (tmp[i].length > 0 ) {
  				wordList.push(tmp[i]);
    		}
    	}

    	// create the short list which is displayed
    	CUT_LIST = new Array();
    	for (var i = 0; i < LONG_LIST.length; i++) {
    		var isContent = true;
    		for (var j = 0; j < wordList.length; j++) {
    			if ( LONG_LIST[i].toLowerCase().indexOf(wordList[j].toLowerCase()) == -1) {
    				isContent = false;
  				}
    		}
    		if (isContent) {
    			CUT_LIST.push(LONG_LIST[i]);
    		}
    	}
    }

    function scrollDown( max) {
    	if ($(DISPLAY).hasChildNodes()){
			if (INDEX <= 2) {
				$('ulList').scrollTop = 0;
			} else if(INDEX > 2 && INDEX < (max - 2)) {
				var now = 0;
				var after  = $('li'+ (INDEX + 2).toString()).offsetHeight;

				for ( var i = 1; i <= (INDEX + 1); i++) {
					now += $('li'+ i.toString()).offsetHeight;
				}

				after += now;

				if ((now % 150) > (after % 150)) {
					$('ulList').scrollTop = now - $('li'+ (INDEX + 1).toString()).offsetHeight;
				}
			} else if (INDEX >= (max-2)) {
				var jumpDown = 0;
				for ( var i = 1; i < max; i++) {
					jumpDown += $('li'+ i.toString()).offsetHeight;
				}
				$('ulList').scrollTop = jumpDown;
			}
		}
	}

	function scrollUp( max) {
		if ($(DISPLAY).hasChildNodes()){
			if (INDEX == max) {
				var jumpDown = 0;
				for ( var i = 1; i < max; i++) {
					jumpDown += $('li'+ i.toString()).offsetHeight;
				}
				$('ulList').scrollTop = jumpDown;
			} else if ( INDEX > -1) {
				var now = 0;
				var after  = $('li'+ INDEX.toString()).offsetHeight;
				for (var i = max; i > INDEX; i--) {
					now += $('li'+ i.toString()).offsetHeight;
				}
				after += now;
				if ((now % 150) > (after % 150)) {
					var jumpUp = 1;
					var before = 0;
					var i = INDEX;
					while (i > 0 && ((before % 150) < (jumpUp % 150))) {
					 	before += $('li'+ i.toString()).offsetHeight;
					 	i--;
					 	jumpUp = before + $('li'+ i.toString()).offsetHeight;
					}
					var top = 0;
					for ( var i = 1; i <= (INDEX + 1); i++) {
						top += $('li'+ i.toString()).offsetHeight;
					}
					$('ulList').scrollTop = top - jumpUp;
				}
			}
		}
	}

<commit_msg>fixed IE explorer bug<commit_after>	var WHOLE_LIST;   // boolean if long or short list
    var SHORT_LIST;   // array of max 31. results
    var LONG_LIST;    // array of all results if spezific request
    var PREFIX;       // string of input before request for more results
    var CUT_LIST;     // cutted results list of Long List
    var INDEX;        // which topic is marked
    var IE;			  // boolean if Internet Explorer
    var MOUSE_OVER;   // if the mouse is over the input or list area
    var FIELD;		  // field name from the table vor the lucene search
    var CLASS_NAME;   // class name (table in the database) for lucene search
    var INPUT;		  // input field id in the jsp file
  	var DISPLAY;      // id of the div for the the list
  	var ERROR;        // id of the div for the error message
  	var FRAME;        // a frame which is displayed under the result list to fix bugs in IE

  	setWholeList(false);
    setPrefix("");
    SHORT_LIST = new Array();
    LONG_LIST = new Array();
    CUT_LIST = new Array();
    setIndex(-1);
    IE = false;
    MOUSE_OVER = 0;

  	function setMouseOver(mouseOver) {
  		MOUSE_OVER = mouseOver;
  	}

  	function setWholeList(wholeList) {
  		WHOLE_LIST = wholeList;
  	}

  	function getWholeList() {
  		return WHOLE_LIST;
  	}

  	function setCutList( cutList) {
  		CUT_LIST = cutList;
  	}

  	function setShortList( list) {
  		SHORT_LIST = list;
  	}

  	function setLongList( longList) {
  		LONG_LIST = longList;
  	}

  	function setPrefix( prefix) {
  		PREFIX = prefix;
  	}

  	function setIndex( index) {
  		INDEX = index;
  	}

  	function getId(input) {
  		INPUT = input;
  		DISPLAY = input + "_display";
  		ERROR = input + "_error";
  		FRAME = input + "_IEbugFixFrame";
  	}

	// AJAX request to load a long or short array
  	function loadList() {
      AjaxServices.getContent( document.getElementById(INPUT).value,
                                     getWholeList(),
                                     FIELD,
                                     CLASS_NAME,
                                     function (array) {
                                     		$(INPUT).focus();
                                        	if (array[0] == "true") {
                                        		if (getWholeList()) {
                                          			setCutList(getElementList(array));
                                          			setLongList(CUT_LIST);
                                        		} else {
                                         			setShortList(getElementList(array));
                                        		}
                                        		setPrefix(document.getElementById(INPUT).value);
                                       	 		printList(getElementList(array));
                                        	} else if (array[0] != '') {
                                        		printError(array[0]);
                                        	}
                                      }
                                 );
    }

    // output if an error appears
    function printError(error) {
    	removeList();
    	$(ERROR).style.visibility = "visible";
    	getCoordinates($(ERROR), $(INPUT));
    	$(ERROR).appendChild(document.createTextNode(error));
    }

    // cut off the first element which could containts error messages
    function getElementList(array) {
        var elemList = new Array(array.length - 1);

        for (var i = 0; i < elemList.length; i++) {
                elemList[i] = array[i+1];
        }
        return elemList;
	}

    // after every Keyboard hit
    function readInput(e, className, field) {
    	CLASS_NAME = className;
    	FIELD = field;
    	var curKey;
    	if (e.which) {   			// FF
        	curKey = e.which;
        	IE = false;
      	} else if (e.keyCode) {     // IE
      		curKey = e.keyCode;
      		IE = true;
      	}

        // ascii code from "a" till  "z" or
        // ascii code from "0" till "9"
        // backspace
        // delete
		if ((curKey >= 65 && curKey <= 90) ||        // load list
            (curKey >= 48 && curKey <= 57) ||
        	(curKey >= 96 && curKey <= 105) ||
        	curKey == 8 || curKey == 46) {
        	setIndex(-1);
        	if (WHOLE_LIST && $(INPUT).value.indexOf(PREFIX) != 0) {
            	setWholeList(false);
       			loadList();
        	} else if (WHOLE_LIST) {
        		cutLongList();
        		printList(CUT_LIST);
        	} else if (!WHOLE_LIST) {
          		loadList();
        	}
        } else if (curKey == 38) {                    // up arrow

        	var len;
        	if (WHOLE_LIST) {
        		len = CUT_LIST.length -1;
        	} else {
        		len = SHORT_LIST.length -1;
        	}

        	remarkIndex();

        	if (INDEX > -1) {
            	setIndex(INDEX - 1);
          	} else {
          		setIndex(len);
          	}
          	scrollUp(len);
          	markIndex();
        } else if (curKey == 40) {                     // down arrow

        	var len;
        	if (WHOLE_LIST) {
        		len = CUT_LIST.length -1;
        	} else {
           		len = SHORT_LIST.length -1;
        	}

        	remarkIndex();

        	if (INDEX < len) {
        		setIndex(INDEX + 1);
        	} else {
           		setIndex(-1);
        	}

        	scrollDown(len);
        	markIndex();
        } else {
        	setIndex(-1);
        }
	}

    // spezific function for Querybuilder
    function isSubmit(e) {
    	// enter
    	if ((e.which == 13 && INDEX > -1) || (e.keyCode == 13 && INDEX > -1)) {

    		Event.stop(e);
        	if (WHOLE_LIST) {
          		$(INPUT).value = CUT_LIST[INDEX];
        	} else {
          		$(INPUT).value = SHORT_LIST[INDEX];
        	}
        	removeList();
        	$('attribute').click(); // submit the constraint
      	}
    }

    // spezific function for submit in template
    function isEnter(e) {
        var curKey;
    	if (e.which) {   			// FF
        	curKey = e.which;
      	} else if (e.keyCode) {     // IE
      		curKey = e.keyCode;
      	}
    	//enter
    	if (curKey == 13) {
            Event.stop(e);
    		if (INDEX > -1) {
    			if (WHOLE_LIST) {
          			$(INPUT).value = CUT_LIST[INDEX];
        		} else {
          			$(INPUT).value = SHORT_LIST[INDEX];
        		}
        	}
        	removeList();
        }
        // tabstop
        if (curKey == 9) {
        	removeList();
        }
    }

    // highlight the actual topic
    function markIndex() {
    	if (INDEX != -1) {
    		$('li' + INDEX.toString()).style.background = '#8AECFF';
    	}
    }

    // remove the higlight of the actual topic
    function remarkIndex() {
    	if (INDEX != -1) {
    		$('li' + INDEX.toString()).style.background = 'none';
    	}
    }

    // paint a spezific list
	function printList(array) {
		removeList();
		if ($(INPUT).value != "" && array.length > 0) {
	    	getCoordinates($(DISPLAY), $(INPUT));

	    	if (IE) {
				getCoordinates($(FRAME), $(INPUT));
				$(FRAME).height = "150";
	    	}

	    	var ul = document.createElement('ul');
	    	ul.setAttribute("id", "ulList");
			var li;

			for (var i = 0; i < array.length; i++) {
				// IE & FF
				li = document.createElement('li');
			    li.setAttribute("val", array[i].toString());
				li.setAttribute("id", "li" + i.toString());
				if (IE) {
					li.setAttribute("onmousedown", function() { $(INPUT).value = this.getAttribute('val'); removeList();});
					li.setAttribute("onmouseover", function() {  remarkIndex();
																 setIndex(parseInt(this.getAttribute('id').replace("li","")));
																 markIndex();
															   });
					li.setAttribute("onmouseout", function() { remarkIndex(); setIndex(-1); } );
				} else { // FF
					li.setAttribute("onMouseDown", "$(INPUT).value = this.getAttribute('val'); removeList();" );
					li.setAttribute("onMouseOver", "remarkIndex(); setIndex(" + i + "); markIndex();" );
					li.setAttribute("onMouseOut", "remarkIndex(); setIndex(-1);" );
				}
				// IE & FF
				$(DISPLAY).style.visibility = "visible";
				li.appendChild(document.createTextNode(array[i]));
				ul.appendChild(li);
			}

			// should the link for more results shown
			if (!WHOLE_LIST && array.length == 31 && $(INPUT).value.length > 3) {
				// IE & FF
                var input = document.createElement('input');
                input.setAttribute("type", "button");
                if (IE) {
                	input.setAttribute("onmousedown", function() { setWholeList(true); loadList(); });
                	input.setAttribute("onmouseout", function() { this.style.background = '#b2cdbf'; });
                	input.setAttribute("onmouseover", function() { this.style.background = '#8AECFF'; });
                	input.style.background = "#b2cdbf";
    				input.style.color = "#4c4d6b";
    				input.style.border = "none";
                	input.style.width = "100%";
                } else { // FF
                	input.setAttribute("class", "more_results");
                	input.setAttribute("onMouseDown", "setWholeList(true); loadList();");
                	input.setAttribute("onMouseOver", "this.style.background = '#8AECFF';");
                	input.setAttribute("onMouseOut", "this.style.background = '#b2cdbf';");
                }
     			// IE & FF
                input.setAttribute("value", "MORE RESULTS...");
                input.setAttribute("TABINDEX","0");
                ul.appendChild(input);
			}
			$(DISPLAY).appendChild(ul);
		} else {
	    	$(FRAME).height = "0"; // IE
	    }
	}

	// remove the list
	function removeList () {
		setIndex(-1);
		for (var i = 0; i < 2; i++) {
			if ($(DISPLAY).hasChildNodes()) {
  				$(DISPLAY).removeChild($(DISPLAY).firstChild);
  			}
  		}
  		if ($(ERROR).hasChildNodes()) {
  			$(ERROR).removeChild($(ERROR).firstChild);
  		}
  		if (IE) {
  			$(FRAME).height = "0";
  			$(DISPLAY).style.visibility = "hidden";
  			$(ERROR).style.visibility = "hidden";
  		}
	}

	// search and store the position from source element to the
	// target element
	function getCoordinates(target, source) {
        target.clonePosition( source, {
          setHeight:false,
          offsetTop: source.offsetHeight
        });
    }

	// created a spezific cutted list of the long list
	// and store it to CUT_LIST
    function cutLongList() {
    	var tmp = new Array();
    	var wordList = new Array();
    	var input =  $(INPUT).value;

    	tmp = input.split(' ');
    	// all other searchwords added to the wordList
    	for (var i = 0; i < tmp.length; i++) {
  			if (tmp[i].length > 0 ) {
  				wordList.push(tmp[i]);
    		}
    	}

    	// create the short list which is displayed
    	CUT_LIST = new Array();
    	for (var i = 0; i < LONG_LIST.length; i++) {
    		var isContent = true;
    		for (var j = 0; j < wordList.length; j++) {
    			if ( LONG_LIST[i].toLowerCase().indexOf(wordList[j].toLowerCase()) == -1) {
    				isContent = false;
  				}
    		}
    		if (isContent) {
    			CUT_LIST.push(LONG_LIST[i]);
    		}
    	}
    }

    function scrollDown( max) {
    	if ($(DISPLAY).hasChildNodes()){
			if (INDEX <= 2) {
				$('ulList').scrollTop = 0;
			} else if(INDEX > 2 && INDEX < (max - 2)) {
				var now = 0;
				var after  = $('li'+ (INDEX + 2).toString()).offsetHeight;

				for ( var i = 1; i <= (INDEX + 1); i++) {
					now += $('li'+ i.toString()).offsetHeight;
				}

				after += now;

				if ((now % 150) > (after % 150)) {
					$('ulList').scrollTop = now - $('li'+ (INDEX + 1).toString()).offsetHeight;
				}
			} else if (INDEX >= (max-2)) {
				var jumpDown = 0;
				for ( var i = 1; i < max; i++) {
					jumpDown += $('li'+ i.toString()).offsetHeight;
				}
				$('ulList').scrollTop = jumpDown;
			}
		}
	}

	function scrollUp( max) {
		if ($(DISPLAY).hasChildNodes()){
			if (INDEX == max) {
				var jumpDown = 0;
				for ( var i = 1; i < max; i++) {
					jumpDown += $('li'+ i.toString()).offsetHeight;
				}
				$('ulList').scrollTop = jumpDown;
			} else if ( INDEX > -1) {
				var now = 0;
				var after  = $('li'+ INDEX.toString()).offsetHeight;
				for (var i = max; i > INDEX; i--) {
					now += $('li'+ i.toString()).offsetHeight;
				}
				after += now;
				if ((now % 150) > (after % 150)) {
					var jumpUp = 1;
					var before = 0;
					var i = INDEX;
					while (i > 0 && ((before % 150) < (jumpUp % 150))) {
					 	before += $('li'+ i.toString()).offsetHeight;
					 	i--;
					 	jumpUp = before + $('li'+ i.toString()).offsetHeight;
					}
					var top = 0;
					for ( var i = 1; i <= (INDEX + 1); i++) {
						top += $('li'+ i.toString()).offsetHeight;
					}
					$('ulList').scrollTop = top - jumpUp;
				}
			}
		}
	}

<|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

const alertMessage = 'Sorry! We cannot geolocate you. Please enter a zipcode';
let map;
let locationQuery = '';
let product = '';

function getGeolocation() {
  hideEntryContainer();
  displayInformationDiv();
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(displayLocation, displayError);
  }
  else {
    console.log('Browser does not support geolocation');
    alert(alertMessage);
  }
}

function displayLocation(position) {
  let lat = position.coords.latitude;
  let lng = position.coords.longitude;
  reverseGeocodeGeolocation(lat, lng);
  locationQuery = '/data?lat=' + lat + '&lng=' + lng;
  fetchByQueryString();
}

function displayError() {
  console.log('Geolocation not enabled');
  alert(alertMessage);
}

function getZipCode() {
  hideEntryContainer();
  displayInformationDiv();
  zip = document.getElementById('entryZipCode').value;
  if (isValidInput(zip)) {
    document.getElementById('zipCode').innerText = zip;
    locationQuery = '/data?zipCode=' + zip;
    fetchByQueryString();
  }
  else {
    window.alert('Invalid input. Try again.');
  }
}

function getProduct() {
  initiateLoaderCircle();
  fetchByQueryString();
}

function fetchByQueryString() {
product = document.getElementById('product').value;
  if (product === '') {
    fetchList(locationQuery + '&product=');
  }
  else {
    fetchList(locationQuery + '&product=' + product);
  }
}

/* Background blur, loader, information div, and popup control */

let backgroundBlurDiv = document.getElementById('background-blur-div');
let popupFormCenterWrapper = document.getElementById('popup-form-center-wrapper');
let informationDivCenterWrapper = document.getElementById('information-div-center-wrapper');
let loaderCircleElement = document.getElementById('loader-circle-center-wrapper');
let mapElement = document.getElementById('map');

function displayEntryContainer() {
  backgroundBlurDiv.className = 'blurred-element-display';
  popupFormCenterWrapper.className = 'centered-element-display';
  mapElement.className = 'map-to-back';
  document.getElementById('entryZipCode').value
        = document.getElementById('zipCode').innerText;
}

function hideEntryContainer() {
  backgroundBlurDiv.className = 'element-hide';
  popupFormCenterWrapper.className = 'element-hide';
  mapElement.className = 'map-to-front';
}

function initiateLoaderCircle() {
  backgroundBlurDiv.className = 'blurred-element-display';
  loaderCircleElement.className = 'centered-element-display';
  mapElement.className = 'map-to-back';
}

function removeLoaderCircle() {
  backgroundBlurDiv.className = 'element-hide';
  loaderCircleElement.className = 'element-hide';
  mapElement.className = 'map-to-front';
}

function displayInformationDiv() {
  backgroundBlurDiv.className = 'blurred-element-display';
  informationDivCenterWrapper.className = 'centered-element-display';
  mapElement.className = 'map-to-back';
}

function hideInformationDiv() {
  backgroundBlurDiv.className = 'element-hide';
  informationDivCenterWrapper.className = 'element-hide';
  mapElement.className = 'map-to-front';
}

function isValidInput(zip) {
  let len = zip.length;
  if (len === 0) {
    return false;
  }

  for (let i=0; i<len; i++) {
    let charCode = zip.charCodeAt(i);
    if (!(charCode >= 48 && charCode <= 57) &&      // digits
          !(charCode >= 65 && charCode <= 90) &&    // uppercase letters
          !(charCode >= 97 && charCode <= 122) &&   // lowercase letters
          !(charCode === 44) &&                     // comma
          !(charCode === 32)) {                     // space
      return false;
    }
  }

  return true;
}

//Array of the (currently 6 for this demo build) 15 listings gathered from the fetch request
let resultsCardsArray = [];

//Count of the total businesses in the fetch request, used to set a unique id for each card
let totalCardCount = 0;
let bounds = 0;

// Storing the most recent listings from the latest fetch to get the list of businesses
let listingsLocalStorage = [];

function fetchList(queryString) {
  bounds = new google.maps.LatLngBounds();
  fetch(queryString).then(response => response.json()).then((listings) => {
    resultsCardsArray = [];
    totalCardCount = 0;
    listingsLocalStorage = listings;
    addResultCardsAndMapToTheScreen(listings);
    hideInformationDiv();
    removeLoaderCircle();
  });
}

function addResultCardsAndMapToTheScreen(listings){
  initMap(listings[0].mapLocation);
    listings.forEach((listing) => {
      resultsCardsArray.push(createResultCard(listing.name, listing.formattedAddress,
            listing.photos, listing.rating, listing.placeId, totalCardCount));

      if (totalCardCount < 15) createMarker(listing, totalCardCount);
      totalCardCount++;
    });
    initialDisplay();
    map.fitBounds(bounds);
}

/**
 * @param {string} name The name of the business
 * @param {string} address The address of the business
 * @param {string} image The url of the business image
 * @param {double} rating The numerical rating of the business, passed to the createRating() function
 * @param {string} websiteUrl The url of the business' website
 * @param {int} totalCardCount The number of businesses in the list, used to set a specific id to each card
 */
function createResultCard(name, address, photos, rating, passedPlaceId, totalCardCount) {

  const resultsCard = document.createElement('div');
  resultsCard.className = 'results-card';
  resultsCard.id = totalCardCount;

  const resultsCardRight = document.createElement('div');
  resultsCardRight.className = 'results-card-right';

  const imageDiv = document.createElement('div');
  imageDiv.className = 'results-image';

  const imageElement = document.createElement('img');
  imageElement.id = 'results-image-element';
  imageElement.src = '/images/image_not_found_two.png';

  let resultPhotoReference = '';
  if ((photos != null) && (photos.length > 0)) {
    resultPhotoReference = photos[0].photoReference;
  }
  else {
    resultPhotoReference = 'none';
  }

  imageDiv.appendChild(imageElement);

  const nameHeader = document.createElement('h2');
  nameHeader.innerText = name;

  const addressParagraph = document.createElement('p');
  addressParagraph.innerText = address;

  const nameAndAddressDiv = document.createElement('div');
  nameAndAddressDiv.className = 'results-business-description';
  nameAndAddressDiv.appendChild(nameHeader);
  nameAndAddressDiv.appendChild(addressParagraph);

  const ratingDiv = createRating(rating);

  const websiteButton = document.createElement('button');
  websiteButton.className = 'results-website-button';

  resultsCardRight.appendChild(nameAndAddressDiv);
  resultsCardRight.appendChild(ratingDiv);
  resultsCardRight.appendChild(websiteButton);

  resultsCard.appendChild(imageDiv);
  resultsCard.appendChild(resultsCardRight);

  //Creates object that contains the resultCard and photoReference to append to array
  let resultsCardObject = {
    card: resultsCard,
    photoReference: resultPhotoReference,
    placeId: passedPlaceId
  };

  return resultsCardObject;
}

/**
 * @param {double} rating The numerical rating for the business, determins the number of stars
 */
function createRating(rating) {
  const ratingDiv = document.createElement('div');
  ratingDiv.className = 'results-rating';

  let roundedRating = Math.round(rating);

  for(i = 0; i < roundedRating; i++) {
    ratingDiv.innerText += '★';
  }

  for (i = roundedRating; i < 5; i++) {
    ratingDiv.innerText += '☆';
  }

  ratingDiv.innerText += (' ' + rating.toFixed(1));

  return ratingDiv;
}

window.onbeforeunload = function() {
  localStorage.setItem("listings", JSON.stringify(listingsLocalStorage));
  localStorage.setItem("location", locationQuery);
  localStorage.setItem("zipcode", document.getElementById('zipCode').innerText);
  localStorage.setItem("product", document.getElementById('product').value);
}

window.onload = function() {
  listingsLocalStorage = JSON.parse(localStorage.getItem("listings"));
  locationQuery = localStorage.getItem("location");
  bounds = new google.maps.LatLngBounds();
  let zipcode = localStorage.getItem("zipcode");
  let product = localStorage.getItem("product");

  if (listingsLocalStorage != null && locationQuery != null && zipcode != null) {
    hideEntryContainer();
    document.getElementById('zipCode').innerText = zipcode;
    addResultCardsAndMapToTheScreen(listingsLocalStorage);

    if (product !== "") {
      document.getElementById('product').value = product;
    }
  }
}
<commit_msg>Fix bug if not able to geolocate user<commit_after>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

const alertMessage = 'Sorry! We cannot geolocate you. Please enter a zipcode';
let map;
let locationQuery = '';
let product = '';

function getGeolocation() {
  hideEntryContainer();
  displayInformationDiv();
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(displayLocation, displayError);
  }
  else {
    console.log('Browser does not support geolocation');
    hideInformationDiv();
    displayEntryContainer();
    alert(alertMessage);

  }
}

function displayLocation(position) {
  let lat = position.coords.latitude;
  let lng = position.coords.longitude;
  reverseGeocodeGeolocation(lat, lng);
  locationQuery = '/data?lat=' + lat + '&lng=' + lng;
  fetchByQueryString();
}

function displayError() {
  console.log('Geolocation not enabled');
  hideInformationDiv();
  displayEntryContainer();
  alert(alertMessage);
}

function getZipCode() {
  hideEntryContainer();
  displayInformationDiv();
  zip = document.getElementById('entryZipCode').value;
  if (isValidInput(zip)) {
    document.getElementById('zipCode').innerText = zip;
    locationQuery = '/data?zipCode=' + zip;
    fetchByQueryString();
  }
  else {
    window.alert('Invalid input. Try again.');
  }
}

function getProduct() {
  initiateLoaderCircle();
  fetchByQueryString();
}

function fetchByQueryString() {
product = document.getElementById('product').value;
  if (product === '') {
    fetchList(locationQuery + '&product=');
  }
  else {
    fetchList(locationQuery + '&product=' + product);
  }
}

/* Background blur, loader, information div, and popup control */

let backgroundBlurDiv = document.getElementById('background-blur-div');
let popupFormCenterWrapper = document.getElementById('popup-form-center-wrapper');
let informationDivCenterWrapper = document.getElementById('information-div-center-wrapper');
let loaderCircleElement = document.getElementById('loader-circle-center-wrapper');
let mapElement = document.getElementById('map');

function displayEntryContainer() {
  backgroundBlurDiv.className = 'blurred-element-display';
  popupFormCenterWrapper.className = 'centered-element-display';
  mapElement.className = 'map-to-back';
  document.getElementById('entryZipCode').value
        = document.getElementById('zipCode').innerText;
}

function hideEntryContainer() {
  backgroundBlurDiv.className = 'element-hide';
  popupFormCenterWrapper.className = 'element-hide';
  mapElement.className = 'map-to-front';
}

function initiateLoaderCircle() {
  backgroundBlurDiv.className = 'blurred-element-display';
  loaderCircleElement.className = 'centered-element-display';
  mapElement.className = 'map-to-back';
}

function removeLoaderCircle() {
  backgroundBlurDiv.className = 'element-hide';
  loaderCircleElement.className = 'element-hide';
  mapElement.className = 'map-to-front';
}

function displayInformationDiv() {
  backgroundBlurDiv.className = 'blurred-element-display';
  informationDivCenterWrapper.className = 'centered-element-display';
  mapElement.className = 'map-to-back';
}

function hideInformationDiv() {
  backgroundBlurDiv.className = 'element-hide';
  informationDivCenterWrapper.className = 'element-hide';
  mapElement.className = 'map-to-front';
}

function isValidInput(zip) {
  let len = zip.length;
  if (len === 0) {
    return false;
  }

  for (let i=0; i<len; i++) {
    let charCode = zip.charCodeAt(i);
    if (!(charCode >= 48 && charCode <= 57) &&      // digits
          !(charCode >= 65 && charCode <= 90) &&    // uppercase letters
          !(charCode >= 97 && charCode <= 122) &&   // lowercase letters
          !(charCode === 44) &&                     // comma
          !(charCode === 32)) {                     // space
      return false;
    }
  }

  return true;
}

//Array of the (currently 6 for this demo build) 15 listings gathered from the fetch request
let resultsCardsArray = [];

//Count of the total businesses in the fetch request, used to set a unique id for each card
let totalCardCount = 0;
let bounds = 0;

// Storing the most recent listings from the latest fetch to get the list of businesses
let listingsLocalStorage = [];

function fetchList(queryString) {
  bounds = new google.maps.LatLngBounds();
  fetch(queryString).then(response => response.json()).then((listings) => {
    resultsCardsArray = [];
    totalCardCount = 0;
    listingsLocalStorage = listings;
    addResultCardsAndMapToTheScreen(listings);
    hideInformationDiv();
    removeLoaderCircle();
  });
}

function addResultCardsAndMapToTheScreen(listings){
  initMap(listings[0].mapLocation);
    listings.forEach((listing) => {
      resultsCardsArray.push(createResultCard(listing.name, listing.formattedAddress,
            listing.photos, listing.rating, listing.placeId, totalCardCount));

      if (totalCardCount < 15) createMarker(listing, totalCardCount);
      totalCardCount++;
    });
    initialDisplay();
    map.fitBounds(bounds);
}

/**
 * @param {string} name The name of the business
 * @param {string} address The address of the business
 * @param {string} image The url of the business image
 * @param {double} rating The numerical rating of the business, passed to the createRating() function
 * @param {string} websiteUrl The url of the business' website
 * @param {int} totalCardCount The number of businesses in the list, used to set a specific id to each card
 */
function createResultCard(name, address, photos, rating, passedPlaceId, totalCardCount) {

  const resultsCard = document.createElement('div');
  resultsCard.className = 'results-card';
  resultsCard.id = totalCardCount;

  const resultsCardRight = document.createElement('div');
  resultsCardRight.className = 'results-card-right';

  const imageDiv = document.createElement('div');
  imageDiv.className = 'results-image';

  const imageElement = document.createElement('img');
  imageElement.id = 'results-image-element';
  imageElement.src = '/images/image_not_found_two.png';

  let resultPhotoReference = '';
  if ((photos != null) && (photos.length > 0)) {
    resultPhotoReference = photos[0].photoReference;
  }
  else {
    resultPhotoReference = 'none';
  }

  imageDiv.appendChild(imageElement);

  const nameHeader = document.createElement('h2');
  nameHeader.innerText = name;

  const addressParagraph = document.createElement('p');
  addressParagraph.innerText = address;

  const nameAndAddressDiv = document.createElement('div');
  nameAndAddressDiv.className = 'results-business-description';
  nameAndAddressDiv.appendChild(nameHeader);
  nameAndAddressDiv.appendChild(addressParagraph);

  const ratingDiv = createRating(rating);

  const websiteButton = document.createElement('button');
  websiteButton.className = 'results-website-button';

  resultsCardRight.appendChild(nameAndAddressDiv);
  resultsCardRight.appendChild(ratingDiv);
  resultsCardRight.appendChild(websiteButton);

  resultsCard.appendChild(imageDiv);
  resultsCard.appendChild(resultsCardRight);

  //Creates object that contains the resultCard and photoReference to append to array
  let resultsCardObject = {
    card: resultsCard,
    photoReference: resultPhotoReference,
    placeId: passedPlaceId
  };

  return resultsCardObject;
}

/**
 * @param {double} rating The numerical rating for the business, determins the number of stars
 */
function createRating(rating) {
  const ratingDiv = document.createElement('div');
  ratingDiv.className = 'results-rating';

  let roundedRating = Math.round(rating);

  for(i = 0; i < roundedRating; i++) {
    ratingDiv.innerText += '★';
  }

  for (i = roundedRating; i < 5; i++) {
    ratingDiv.innerText += '☆';
  }

  ratingDiv.innerText += (' ' + rating.toFixed(1));

  return ratingDiv;
}

window.onbeforeunload = function() {
  localStorage.setItem("listings", JSON.stringify(listingsLocalStorage));
  localStorage.setItem("location", locationQuery);
  localStorage.setItem("zipcode", document.getElementById('zipCode').innerText);
  localStorage.setItem("product", document.getElementById('product').value);
}

window.onload = function() {
  listingsLocalStorage = JSON.parse(localStorage.getItem("listings"));
  locationQuery = localStorage.getItem("location");
  bounds = new google.maps.LatLngBounds();
  let zipcode = localStorage.getItem("zipcode");
  let product = localStorage.getItem("product");

  if (listingsLocalStorage != null && locationQuery != null && zipcode != null) {
    hideEntryContainer();
    document.getElementById('zipCode').innerText = zipcode;
    addResultCardsAndMapToTheScreen(listingsLocalStorage);

    if (product !== "") {
      document.getElementById('product').value = product;
    }
  }
}
<|endoftext|>


<commit_before>import {FlyControls} from 'https://threejs.org/examples/jsm/controls/FlyControls.js';
import {GUI} from 'https://threejs.org/examples/jsm/libs/dat.gui.module.js';

// Initialization of global objects.
let scene;
let camera;
let renderer;
let clock;
let controls;
const rotationData = new Map();
const points = [];
const numOfPoints = 15; // Arbitrary test number
/**
 * Initializes the scene, camera, renderer, and clock.
 */
function init() {
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(
      /* fov =*/ 75,
      /* aspectRatio =*/ window.innerWidth / window.innerHeight,
      /* nearFrustum =*/.1,
      /* farFrustum =*/ 1000);
  camera.position.set(0, 1, 1);
  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);
  clock = new THREE.Clock();

  // The camera controls allows the user to fly with the camera.
  controls = new FlyControls(camera, renderer.domElement);
  controls.movementSpeed = 1;
  controls.rollSpeed = Math.PI / 10;
  controls.autoForward = false;
  controls.dragToLook = true;

  addObjects();
  gui();
}

/**
 * Creates all the objects and adds them to the scene.
*/
function addObjects() {
  const geometry = new THREE.PlaneGeometry(5, 25, 1);
  const material =
      new THREE.MeshBasicMaterial({color: 'pink', side: THREE.DoubleSide});
  // The plane is a place holder for the 2D localized map image
  const plane = new THREE.Mesh(geometry, material);
  plane.rotation.x = Math.PI / 2;
  plane.position.z = -10;
  scene.add(plane);
  addPoseData();
}

/**
 * Creates fake pose data and adds them as objects to the scene
 */
function addPoseData() {
  let material = new THREE.LineBasicMaterial({color: 'red'});
  for (let increment = 0; increment < numOfPoints; increment++) {
    points.push(new THREE.Vector3(
        Math.pow(-1, increment), .20, -increment)); // GPS points

    const geometry = new THREE.CylinderGeometry(.02, .02, .5);

    // The cylinder represents the orientation of each data point
    const cylinder = new THREE.Mesh(geometry, material);
    cylinder.rotateX(THREE.Math.degToRad(-90));
    cylinder.position.set(0, 0, -.25);
    scene.add(cylinder); // Orientation indicator

    // The pivot sphere represents the position of each data point
    const pivot = new THREE.Group();
    pivot.position.set(Math.pow(-1, increment), .25, -increment);
    scene.add(pivot);
    pivot.add(cylinder);
    const pivotSphereGeo =
      new THREE.SphereGeometry(.03); // Small sphere indicating pivot point
    const pivotSphere = new THREE.Mesh(pivotSphereGeo);
    pivotSphere.position.set(Math.pow(-1, increment), .25, -increment);
    scene.add(pivotSphere);

    rotationData.set(increment, {origin: pivot, mesh: cylinder});
  }
  const geometry = new THREE.BufferGeometry().setFromPoints(points);
  material = new THREE.LineBasicMaterial({color: 'blue'});
  const line = new THREE.Line(geometry, material);
  scene.add(line);
}

/**
 * Creates a GUI for manipulating the orientation of each data point
 */
function gui() {
  const gui = new GUI();
  let params = {clipIntersection: true, Yaw: 0, showHelpers: false};
  gui.add(params, 'Yaw', -360, 360)
      .name('Yaw (degrees)')
      .onChange(function(radians) {
        rotateAxis(radians, 'z');
      });

  params = {clipIntersection: true, Pitch: 0, showHelpers: false};
  gui.add(params, 'Pitch', -360, 360)
      .name('Pitch (degrees)')
      .onChange(function(radians) {
        rotateAxis(radians, 'x');
      });

  params = {clipIntersection: true, Roll: 0, showHelpers: false};
  gui.add(params, 'Roll', -360, 360)
      .name('Roll (degrees)')
      .onChange(function(radians) {
        rotateAxis(radians, 'y');
      });
}
/**
 * This is the animation loop which continually updates the scene.
 * It allows the movement of objects to be seen on screen and the camera
 * to be moved in accordance to the controls.
 */
function animate() {
  requestAnimationFrame(animate);
  const delta = clock.getDelta();
  controls.update(delta);
  renderer.render(scene, camera);
};

/**
 * This function rotates the data points about given axis using radians.
 * @param {int} radians This how many radians to rotate along an axis.
 * @param {string} axis This is identifying which axis to rotate around.
 */
function rotateAxis(radians, axis) {
  for (let i = 0; i < rotationData.size; i++) {
    if (axis == 'z') {
      rotationData.get(i).origin.rotation.z = THREE.Math.degToRad(radians);
    }
    if (axis == 'y') {
      rotationData.get(i).origin.rotation.y = THREE.Math.degToRad(radians);
    }
    if (axis == 'x') {
      rotationData.get(i).origin.rotation.x = THREE.Math.degToRad(radians);
    }
  }
}

init();
animate();
<commit_msg>Changed mislabeled variable<commit_after>import {FlyControls} from 'https://threejs.org/examples/jsm/controls/FlyControls.js';
import {GUI} from 'https://threejs.org/examples/jsm/libs/dat.gui.module.js';

// Initialization of global objects.
let scene;
let camera;
let renderer;
let clock;
let controls;
const rotationData = new Map();
const points = [];
const numOfPoints = 15; // Arbitrary test number
/**
 * Initializes the scene, camera, renderer, and clock.
 */
function init() {
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(
      /* fov =*/ 75,
      /* aspectRatio =*/ window.innerWidth / window.innerHeight,
      /* nearFrustum =*/.1,
      /* farFrustum =*/ 1000);
  camera.position.set(0, 1, 1);
  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);
  clock = new THREE.Clock();

  // The camera controls allows the user to fly with the camera.
  controls = new FlyControls(camera, renderer.domElement);
  controls.movementSpeed = 1;
  controls.rollSpeed = Math.PI / 10;
  controls.autoForward = false;
  controls.dragToLook = true;

  addObjects();
  gui();
}

/**
 * Creates all the objects and adds them to the scene.
*/
function addObjects() {
  const geometry = new THREE.PlaneGeometry(5, 25, 1);
  const material =
      new THREE.MeshBasicMaterial({color: 'pink', side: THREE.DoubleSide});
  // The plane is a place holder for the 2D localized map image
  const plane = new THREE.Mesh(geometry, material);
  plane.rotation.x = Math.PI / 2;
  plane.position.z = -10;
  scene.add(plane);
  addPoseData();
}

/**
 * Creates fake pose data and adds them as objects to the scene
 */
function addPoseData() {
  let material = new THREE.LineBasicMaterial({color: 'red'});
  for (let increment = 0; increment < numOfPoints; increment++) {
    points.push(new THREE.Vector3(
        Math.pow(-1, increment), .20, -increment)); // GPS points

    const geometry = new THREE.CylinderGeometry(.02, .02, .5);

    // The cylinder represents the orientation of each data point
    const cylinder = new THREE.Mesh(geometry, material);
    cylinder.rotateX(THREE.Math.degToRad(-90));
    cylinder.position.set(0, 0, -.25);
    scene.add(cylinder); // Orientation indicator

    // The pivot sphere represents the position of each data point
    const pivot = new THREE.Group();
    pivot.position.set(Math.pow(-1, increment), .25, -increment);
    scene.add(pivot);
    pivot.add(cylinder);
    const pivotSphereGeo =
      new THREE.SphereGeometry(.03); // Small sphere indicating pivot point
    const pivotSphere = new THREE.Mesh(pivotSphereGeo);
    pivotSphere.position.set(Math.pow(-1, increment), .25, -increment);
    scene.add(pivotSphere);

    rotationData.set(increment, {origin: pivot, mesh: cylinder});
  }
  const geometry = new THREE.BufferGeometry().setFromPoints(points);
  material = new THREE.LineBasicMaterial({color: 'blue'});
  const line = new THREE.Line(geometry, material);
  scene.add(line);
}

/**
 * Creates a GUI for manipulating the orientation of each data point
 */
function gui() {
  const gui = new GUI();
  let params = {clipIntersection: true, Yaw: 0, showHelpers: false};
  gui.add(params, 'Yaw', -360, 360)
      .name('Yaw (degrees)')
      .onChange(function(degrees) {
        rotateAxis(degrees, 'z');
      });

  params = {clipIntersection: true, Pitch: 0, showHelpers: false};
  gui.add(params, 'Pitch', -360, 360)
      .name('Pitch (degrees)')
      .onChange(function(degrees) {
        rotateAxis(degrees, 'x');
      });

  params = {clipIntersection: true, Roll: 0, showHelpers: false};
  gui.add(params, 'Roll', -360, 360)
      .name('Roll (degrees)')
      .onChange(function(degrees) {
        rotateAxis(degrees, 'y');
      });
}
/**
 * This is the animation loop which continually updates the scene.
 * It allows the movement of objects to be seen on screen and the camera
 * to be moved in accordance to the controls.
 */
function animate() {
  requestAnimationFrame(animate);
  const delta = clock.getDelta();
  controls.update(delta);
  renderer.render(scene, camera);
};

/**
 * This function rotates the data points about given axis using degrees.
 * @param {int} degrees This how many degrees to rotate along an axis.
 * @param {string} axis This is identifying which axis to rotate around.
 */
function rotateAxis(degrees, axis) {
  for (let i = 0; i < rotationData.size; i++) {
    if (axis == 'z') {
      rotationData.get(i).origin.rotation.z = THREE.Math.degToRad(degrees);
    }
    if (axis == 'y') {
      rotationData.get(i).origin.rotation.y = THREE.Math.degToRad(degrees);
    }
    if (axis == 'x') {
      rotationData.get(i).origin.rotation.x = THREE.Math.degToRad(degrees);
    }
  }
}

init();
animate();
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Foreground page
"use strict";

// To communicate back to the host (handler site).
var hostPort = null;

// Details about the handler being registered.
var handler = null;

function arraysEqual(x, y) {
  if (x.length != y.length)
    return false;

  for (var i = 0; i < x.length; i++) {
    if (x[i] != y[i])
      return false;
  }

  return true;
}

// Takes an object with the fields of a handler, and converts it into a new
// Handler object. This sanitizes the object received from the host (which is
// untrusted). Throws an error if the object contains missing or invalid fields.
function processHandler(handler) {
  if (typeof handler != 'object')
    throw new Error('handler is not an object');

  if (typeof handler.name != 'string' || handler.name == '')
    throw new Error('handler.name is missing or invalid');

  if (typeof handler.url != 'string' || handler.url.indexOf('://') < 0)
    throw new Error('handler.url is missing or invalid');

  if (typeof handler.verbs != 'object' || handler.verbs.length == undefined ||
      handler.verbs.length == 0)
    throw new Error('handler.verbs is missing or invalid');

  var verbs = [];
  for (var i = 0; i < handler.verbs.length; i++) {
    var verb = handler.verbs[i];
    if (typeof verb != 'string' || verb == '')
      throw new Error('handler.verbs is missing or invalid');

    verbs.push(verb);
  }

  return new Handler(handler.name, handler.url, verbs);
}

// Determines whether a handler is already registered in the database. This does
// an exact match -- doesn't just check the URL. If any details have changed,
// returns false (because the handler needs to be re-registered). Returns a
// promise that is resolved with a Boolean.
function alreadyRegistered(handler) {
  return new Promise((resolve, reject) => {
    openRegistryDatabase().then(db => {
      getHandlerForUrl(db, handler.url).then(existing => {
        if (existing == undefined) {
          resolve(false);
          return;
        }

        resolve(existing.name == handler.name &&
                arraysEqual(existing.verbs, handler.verbs));
      }, error => reject(error));
    }, error => reject(error));
  });
}

// Creates a human-readable (English) string from a list of strings. Inserts
// commas between items, with "and" between the last two items.
function listToFriendlyString(items) {
  if (items.length >= 2) {
    var last = items[items.length - 1];
    var secondLast = items[items.length - 2];
    items = items.slice(0, items.length - 2);
    items.push(`${secondLast} and ${last}`);
  }
  return items.join(', ');
}

// Fills in the text fields.
function populateUI() {
  var siteName = document.getElementById('site_name');
  var siteUrl = document.getElementById('site_url');
  var verb = document.getElementById('verb');

  siteName.textContent = handler.name;
  siteUrl.textContent = handler.url;
  verb.textContent = listToFriendlyString(handler.verbs);

  document.getElementById('registrar').style.display = 'block';
}

// Registers this handler in the database.
function register() {
  openRegistryDatabase().then(db => {
    registerHandler(db, handler)
        .then(
            () => {
              db.close();
              closeDialog();
            },
            error => {
              db.close();
              closeDialog();
              throw error;
            });
  });
}

window.onmessage = function(e) {
  hostPort = e.data.port;
  var unsanitizedHandler = e.data.handler;
  try {
    handler = processHandler(unsanitizedHandler);
  } catch (error) {
    closeDialog();
    throw error;
  }

  alreadyRegistered(handler).then(isRegistered => {
    if (isRegistered) {
      console.debug(
          `Ballista proxy: Not registering handler for ${handler.url}; ` +
          'already registered.');
      closeDialog();
      return;
    }

    populateUI();
  });
};

function closeDialog() {
  if (hostPort == null)
    throw Error('Cannot close dialog; never received a port from host.');

  hostPort.postMessage({close: true});
}

function registerButtonClick() {
  register();
}

function cancelButtonClick() {
  closeDialog();
}

function onLoad() {
  document.getElementById('register')
      .addEventListener('click', registerButtonClick);
  document.getElementById('cancel')
      .addEventListener('click', cancelButtonClick);
}

window.addEventListener('load', onLoad, false);
<commit_msg>register: Abstract handler equality into handlersEqual function.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Foreground page
"use strict";

// To communicate back to the host (handler site).
var hostPort = null;

// Details about the handler being registered.
var handler = null;

function arraysEqual(x, y) {
  if (x.length != y.length)
    return false;

  for (var i = 0; i < x.length; i++) {
    if (x[i] != y[i])
      return false;
  }

  return true;
}

// Determines if two handlers are "equal" (for the purpose of re-registering a
// handler).
function handlersEqual(x, y) {
  return x.name == y.name && arraysEqual(x.verbs, y.verbs);
}

// Takes an object with the fields of a handler, and converts it into a new
// Handler object. This sanitizes the object received from the host (which is
// untrusted). Throws an error if the object contains missing or invalid fields.
function processHandler(handler) {
  if (typeof handler != 'object')
    throw new Error('handler is not an object');

  if (typeof handler.name != 'string' || handler.name == '')
    throw new Error('handler.name is missing or invalid');

  if (typeof handler.url != 'string' || handler.url.indexOf('://') < 0)
    throw new Error('handler.url is missing or invalid');

  if (typeof handler.verbs != 'object' || handler.verbs.length == undefined ||
      handler.verbs.length == 0)
    throw new Error('handler.verbs is missing or invalid');

  var verbs = [];
  for (var i = 0; i < handler.verbs.length; i++) {
    var verb = handler.verbs[i];
    if (typeof verb != 'string' || verb == '')
      throw new Error('handler.verbs is missing or invalid');

    verbs.push(verb);
  }

  return new Handler(handler.name, handler.url, verbs);
}

// Determines whether a handler is already registered in the database. This does
// an exact match -- doesn't just check the URL. If any details have changed,
// returns false (because the handler needs to be re-registered). Returns a
// promise that is resolved with a Boolean.
function alreadyRegistered(handler) {
  return new Promise((resolve, reject) => {
    openRegistryDatabase().then(db => {
      getHandlerForUrl(db, handler.url).then(existing => {
        if (existing == undefined) {
          resolve(false);
          return;
        }

        resolve(handlersEqual(existing, handler));
      }, error => reject(error));
    }, error => reject(error));
  });
}

// Creates a human-readable (English) string from a list of strings. Inserts
// commas between items, with "and" between the last two items.
function listToFriendlyString(items) {
  if (items.length >= 2) {
    var last = items[items.length - 1];
    var secondLast = items[items.length - 2];
    items = items.slice(0, items.length - 2);
    items.push(`${secondLast} and ${last}`);
  }
  return items.join(', ');
}

// Fills in the text fields.
function populateUI() {
  var siteName = document.getElementById('site_name');
  var siteUrl = document.getElementById('site_url');
  var verb = document.getElementById('verb');

  siteName.textContent = handler.name;
  siteUrl.textContent = handler.url;
  verb.textContent = listToFriendlyString(handler.verbs);

  document.getElementById('registrar').style.display = 'block';
}

// Registers this handler in the database.
function register() {
  openRegistryDatabase().then(db => {
    registerHandler(db, handler)
        .then(
            () => {
              db.close();
              closeDialog();
            },
            error => {
              db.close();
              closeDialog();
              throw error;
            });
  });
}

window.onmessage = function(e) {
  hostPort = e.data.port;
  var unsanitizedHandler = e.data.handler;
  try {
    handler = processHandler(unsanitizedHandler);
  } catch (error) {
    closeDialog();
    throw error;
  }

  alreadyRegistered(handler).then(isRegistered => {
    if (isRegistered) {
      console.debug(
          `Ballista proxy: Not registering handler for ${handler.url}; ` +
          'already registered.');
      closeDialog();
      return;
    }

    populateUI();
  });
};

function closeDialog() {
  if (hostPort == null)
    throw Error('Cannot close dialog; never received a port from host.');

  hostPort.postMessage({close: true});
}

function registerButtonClick() {
  register();
}

function cancelButtonClick() {
  closeDialog();
}

function onLoad() {
  document.getElementById('register')
      .addEventListener('click', registerButtonClick);
  document.getElementById('cancel')
      .addEventListener('click', cancelButtonClick);
}

window.addEventListener('load', onLoad, false);
<|endoftext|>


<commit_before>/*
 * Qt+WebKit powered headless test runner using Phantomjs
 *
 * Phantomjs installation: http://code.google.com/p/phantomjs/wiki/BuildInstructions
 *
 * Run with:
 *  phantomjs runner.js [url-of-your-qunit-testsuite]
 *
 * E.g.
 *      phantomjs runner.js http://localhost/qunit/test
 */

var url = phantom.args[0];

var page = require('webpage').create();

// Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this")
page.onConsoleMessage = function(msg) {
	console.log(msg);
};

page.onInitialized = function() {
	page.evaluate(addLogging);
};
page.open(url, function(status){
	if (status !== "success") {
		console.log("Unable to access network: " + status);
		phantom.exit(1);
	} else {
		// page.evaluate(addLogging);
		var interval = setInterval(function() {
			if (finished()) {
				clearInterval(interval);
				onfinishedTests();
			}
		}, 500);
	}
});

function finished() {
	return page.evaluate(function(){
		return !!window.qunitDone;
	});
}

function onfinishedTests() {
	var output = page.evaluate(function() {
			return JSON.stringify(window.qunitDone);
	});
	phantom.exit(JSON.parse(output).failed > 0 ? 1 : 0);
}

function addLogging() {
	window.document.addEventListener( "DOMContentLoaded", function() {
		var current_test_assertions = [];
		var module;

		QUnit.moduleStart(function(context) {
			module = context.name;
		});

		QUnit.testDone(function(result) {
			var name = module + ': ' + result.name;
			var i;

			if (result.failed) {
				console.log('Assertion Failed: ' + name);

				for (i = 0; i < current_test_assertions.length; i++) {
					console.log('    ' + current_test_assertions[i]);
				}
			}

			current_test_assertions = [];
		});

		QUnit.log(function(details) {
			var response;

			if (details.result) {
				return;
			}

			response = details.message || '';

			if (typeof details.expected !== 'undefined') {
				if (response) {
					response += ', ';
				}

				response += 'expected: ' + details.expected + ', but was: ' + details.actual;
			}

			current_test_assertions.push('Failed assertion: ' + response);
		});

		QUnit.done(function(result){
			console.log('Took ' + result.runtime +  'ms to run ' + result.total + ' tests. ' + result.passed + ' passed, ' + result.failed + ' failed.');
			window.qunitDone = result;
		});
	}, false );
}
<commit_msg>Simplify phantomjs runner to use module property in testDone callback<commit_after>/*
 * Qt+WebKit powered headless test runner using Phantomjs
 *
 * Phantomjs installation: http://code.google.com/p/phantomjs/wiki/BuildInstructions
 *
 * Run with:
 *  phantomjs runner.js [url-of-your-qunit-testsuite]
 *
 * E.g.
 *      phantomjs runner.js http://localhost/qunit/test
 */

var url = phantom.args[0];

var page = require('webpage').create();

// Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this")
page.onConsoleMessage = function(msg) {
	console.log(msg);
};

page.onInitialized = function() {
	page.evaluate(addLogging);
};
page.open(url, function(status){
	if (status !== "success") {
		console.log("Unable to access network: " + status);
		phantom.exit(1);
	} else {
		// page.evaluate(addLogging);
		var interval = setInterval(function() {
			if (finished()) {
				clearInterval(interval);
				onfinishedTests();
			}
		}, 500);
	}
});

function finished() {
	return page.evaluate(function(){
		return !!window.qunitDone;
	});
}

function onfinishedTests() {
	var output = page.evaluate(function() {
			return JSON.stringify(window.qunitDone);
	});
	phantom.exit(JSON.parse(output).failed > 0 ? 1 : 0);
}

function addLogging() {
	window.document.addEventListener( "DOMContentLoaded", function() {
		var current_test_assertions = [];

		QUnit.testDone(function(result) {
			var name = result.module + ': ' + result.name;
			var i;

			if (result.failed) {
				console.log('Assertion Failed: ' + name);

				for (i = 0; i < current_test_assertions.length; i++) {
					console.log('    ' + current_test_assertions[i]);
				}
			}

			current_test_assertions = [];
		});

		QUnit.log(function(details) {
			var response;

			if (details.result) {
				return;
			}

			response = details.message || '';

			if (typeof details.expected !== 'undefined') {
				if (response) {
					response += ', ';
				}

				response += 'expected: ' + details.expected + ', but was: ' + details.actual;
			}

			current_test_assertions.push('Failed assertion: ' + response);
		});

		QUnit.done(function(result){
			console.log('Took ' + result.runtime +  'ms to run ' + result.total + ' tests. ' + result.passed + ' passed, ' + result.failed + ' failed.');
			window.qunitDone = result;
		});
	}, false );
}
<|endoftext|>


<commit_before>/*
 * QtWebKit-powered headless test runner using PhantomJS
 *
 * PhantomJS binaries: http://phantomjs.org/download.html
 * Requires PhantomJS 1.6+ (1.7+ recommended)
 *
 * Run with:
 *   phantomjs runner.js [url-of-your-qunit-testsuite]
 *
 * e.g.
 *   phantomjs runner.js http://localhost/qunit/test/index.html
 */

/*jshint latedef:false */
/*global phantom:false, require:false, console:false, window:false, QUnit:false */

(function() {
	'use strict';

	var url, page,
		args = require('system').args;

	// arg[0]: scriptName, args[1...]: arguments
	if (args.length !== 2) {
		console.error('Usage:\n  phantomjs runner.js [url-of-your-qunit-testsuite]');
		phantom.exit(1);
	}

	url = args[1];
	page = require('webpage').create();

	// Route `console.log()` calls from within the Page context to the main Phantom context (i.e. current `this`)
	page.onConsoleMessage = function(msg) {
		console.log(msg);
	};

	page.onInitialized = function() {
		page.evaluate(addLogging);
	};

	page.onCallback = function(message) {
		var result,
			failed;

		if (message) {
			if (message.name === 'QUnit.done') {
				result = message.data;
				failed = !result || result.failed;

				phantom.exit(failed ? 1 : 0);
			}
		}
	};

	page.open(url, function(status) {
		if (status !== 'success') {
			console.error('Unable to access network: ' + status);
			phantom.exit(1);
		} else {
			// Cannot do this verification with the 'DOMContentLoaded' handler because it
			// will be too late to attach it if a page does not have any script tags.
			var qunitMissing = page.evaluate(function() { return (typeof QUnit === 'undefined' || !QUnit); });
			if (qunitMissing) {
				console.error('The `QUnit` object is not present on this page.');
				phantom.exit(1);
			}

			// Do nothing... the callback mechanism will handle everything!
		}
	});

	function addLogging() {
		window.document.addEventListener('DOMContentLoaded', function() {
			var current_test_assertions = [];

			QUnit.log(function(details) {
				var response;

				// Ignore passing assertions
				if (details.result) {
					return;
				}

				response = details.message || '';

				if (typeof details.expected !== 'undefined') {
					if (response) {
						response += ', ';
					}

					response += 'expected: ' + details.expected + ', but was: ' + details.actual;
					if (details.source) {
						response += "\n" + details.source;
					}
				}

				current_test_assertions.push('Failed assertion: ' + response);
			});

			QUnit.testDone(function(result) {
				var i,
					len,
					name = result.module + ': ' + result.name;

				if (result.failed) {
					console.log('Test failed: ' + name);

					for (i = 0, len = current_test_assertions.length; i < len; i++) {
						console.log('    ' + current_test_assertions[i]);
					}
				}

				current_test_assertions.length = 0;
			});

			QUnit.done(function(result) {
				console.log('Took ' + result.runtime +  'ms to run ' + result.total + ' tests. ' + result.passed + ' passed, ' + result.failed + ' failed.');

				if (typeof window.callPhantom === 'function') {
					window.callPhantom({
						'name': 'QUnit.done',
						'data': result
					});
				}
			});
		}, false);
	}
})();
<commit_msg>PhantomJS plugin: Include stack trace for all failed tests. Closes #416.<commit_after>/*
 * QtWebKit-powered headless test runner using PhantomJS
 *
 * PhantomJS binaries: http://phantomjs.org/download.html
 * Requires PhantomJS 1.6+ (1.7+ recommended)
 *
 * Run with:
 *   phantomjs runner.js [url-of-your-qunit-testsuite]
 *
 * e.g.
 *   phantomjs runner.js http://localhost/qunit/test/index.html
 */

/*jshint latedef:false */
/*global phantom:false, require:false, console:false, window:false, QUnit:false */

(function() {
	'use strict';

	var url, page,
		args = require('system').args;

	// arg[0]: scriptName, args[1...]: arguments
	if (args.length !== 2) {
		console.error('Usage:\n  phantomjs runner.js [url-of-your-qunit-testsuite]');
		phantom.exit(1);
	}

	url = args[1];
	page = require('webpage').create();

	// Route `console.log()` calls from within the Page context to the main Phantom context (i.e. current `this`)
	page.onConsoleMessage = function(msg) {
		console.log(msg);
	};

	page.onInitialized = function() {
		page.evaluate(addLogging);
	};

	page.onCallback = function(message) {
		var result,
			failed;

		if (message) {
			if (message.name === 'QUnit.done') {
				result = message.data;
				failed = !result || result.failed;

				phantom.exit(failed ? 1 : 0);
			}
		}
	};

	page.open(url, function(status) {
		if (status !== 'success') {
			console.error('Unable to access network: ' + status);
			phantom.exit(1);
		} else {
			// Cannot do this verification with the 'DOMContentLoaded' handler because it
			// will be too late to attach it if a page does not have any script tags.
			var qunitMissing = page.evaluate(function() { return (typeof QUnit === 'undefined' || !QUnit); });
			if (qunitMissing) {
				console.error('The `QUnit` object is not present on this page.');
				phantom.exit(1);
			}

			// Do nothing... the callback mechanism will handle everything!
		}
	});

	function addLogging() {
		window.document.addEventListener('DOMContentLoaded', function() {
			var current_test_assertions = [];

			QUnit.log(function(details) {
				var response;

				// Ignore passing assertions
				if (details.result) {
					return;
				}

				response = details.message || '';

				if (typeof details.expected !== 'undefined') {
					if (response) {
						response += ', ';
					}

					response += 'expected: ' + details.expected + ', but was: ' + details.actual;
				}

				if (details.source) {
					response += "\n" + details.source;
				}

				current_test_assertions.push('Failed assertion: ' + response);
			});

			QUnit.testDone(function(result) {
				var i,
					len,
					name = result.module + ': ' + result.name;

				if (result.failed) {
					console.log('Test failed: ' + name);

					for (i = 0, len = current_test_assertions.length; i < len; i++) {
						console.log('    ' + current_test_assertions[i]);
					}
				}

				current_test_assertions.length = 0;
			});

			QUnit.done(function(result) {
				console.log('Took ' + result.runtime +  'ms to run ' + result.total + ' tests. ' + result.passed + ' passed, ' + result.failed + ' failed.');

				if (typeof window.callPhantom === 'function') {
					window.callPhantom({
						'name': 'QUnit.done',
						'data': result
					});
				}
			});
		}, false);
	}
})();
<|endoftext|>