<commit_before>/*
 * Copyright 2014 WebFilings, 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
 *
 *     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.
 */

define(function(require) {
    'use strict';

    var requestAnimFrame = require('wf-js-common/requestAnimationFrame');

    /**
     * Creates a new ScrollBar with the given ScrollList and options.
     *
     * @classdesc
     *
     * A ScrollBar provides a UI based on the traditional browser scrollbar
     * for users to scroll the ScrollList.
     *
     * @name ScrollBar
     * @constructor
     *
     * @param {ScrollList} scrollList
     *        The ScrollList that the ScrollBar is constructed for
     *
     * @param {HTMLElement} parent
     *        The parent element for the ScrollBar to be created within
     *
     * @param {Object} options
     *        An object with optional classes and ids to be placed on the
     *        scrollbarEL and scrollbarContainerEL.
     *
     * @param {number} options.min_height
     *        The minimum height, in pixes, of the ScrollBar
     *        If not provided, the min_height will default to 16px
     *
     */

    var ScrollBar = function (scrollList, parent, options) {
        var offset;
        var that = this;

        // Set the scrollList
        if (scrollList === undefined) {
            throw new Error('ScrollBar#ScrollBar: scrollList is required');
        }
        else {
            this._scrollList = scrollList;
        }

        // Set the parent
        if (parent === undefined) {
            throw new Error('ScrollBar#ScrollBar: parent is required.');
        }
        else {
            this._parent = parent;
        }

        // Set the options
        this._options = options;

        // Set the layout
        this._layout = scrollList.getLayout();

        // Set the number of items
        this._TOTAL_ITEMS = scrollList._items.length;

        // Set the viewportHeight
        this._viewportHeight = this._layout.getViewportSize().height;

        // Set the virtualHeight
        this._virtualHeight = this._layout.getSize().height;

        // Set up the DOM and set the scrollbar and scrollbarContainer elements
        this._elements = this.setUpDOM();

        // Set the average object height
        this._avgObjHeight = this._virtualHeight/this._TOTAL_ITEMS;

        // Set scrollbarScrolling to initially false
        this._scrollbarScrolling = false;

        // Set clickOffset to null
        this._clickOffset = null;

        // Set the initial scale
        this._scale = this._scrollList._scaleTranslator._map.getCurrentTransformState().scale;

        // Set the effective virtual height.
        this._effectiveVirtualHeight = this._virtualHeight * (1 / this._scale);

        // Set the initial scrollbar height
        this._scrollbarHeight = this.calculateScrollBarHeight(that);

        // Get the initial position, in case it's not at 0, and set the scrollbar position and page number
        requestAnimFrame(function() {
            that.placeScrollBar(that, that._elements.scrollbar);
        });

        // Match the scroll bar positioning to the users scrolling
        this._scrollList.getListMap().onTranslationChanged(function() {
            if (that._scrollbarScrolling) {
                return;
            }
            requestAnimFrame(function() {
                that.placeScrollBar(that, that._elements.scrollbar);
            });
        });

        // Make necessary adjustments when the users zooms in or out
        this._scrollList.getListMap().onScaleChanged(function() {
            that._scale = that._scrollList._scaleTranslator._map.getCurrentTransformState().scale;
            that._effectiveVirtualHeight = that._layout.getSize().height * that._scale;
            that._scrollbarHeight = that.calculateScrollBarHeight(that);
            that._elements.scrollbar.style.height = that._scrollbarHeight + 'px';
        });

        // Attach handlers for scrolling the ScrollBar
        this._elements.scrollbar.addEventListener('mousedown', function(event) {
            offset = that._elements.scrollbar.offsetTop + that._elements.scrollbarContainer.offsetTop;
            that._clickOffset = event.clientY - offset + that._elements.scrollbarContainer.offsetTop;
            that._scrollbarScrolling = true;

            that._mouseupHandler = function () {
                that.stopUpdatingScrollbar(that);
            };

            that._mousemoveHandler = function (e) {
                that.updateScrollBar(e, that, that._clickOffset);
            };

            document.addEventListener('mousemove', that._mousemoveHandler);

            document.addEventListener('mouseup', that._mouseupHandler);
        });

    };

    ScrollBar.prototype = {
        setUpDOM: function () {
            // Create the scrollbar's container
            var scrollbarContainerEL = document.createElement('div');
            var scrollbarEL = document.createElement('div');

            // Set the given classes and ids scrollbar and it's container
            if ( this._options.scrollbarId ) {
                scrollbarEL.setAttribute('id', this._options.scrollbarId);
            }
            if ( this._options.scrollbarClass ) {
                scrollbarEL.classNames += this._options.scrollbarClass;
            }
            if ( this._options.scrollbarContainerId ) {
                scrollbarContainerEL.setAttribute('id', this._options.scrollbarContainerId);
            }
            if ( this._options.scrollbarContainerClass) {
                scrollbarContainerEL.classnames += this._options.scrollbarContainerClass;
            }

            // Append the scrollbar and it's parent container to the given parent element
            scrollbarContainerEL.appendChild(scrollbarEL);
            this._parent.appendChild(scrollbarContainerEL);

            // Set the container height to the viewport height
            scrollbarContainerEL.style.height = this._viewportHeight + 'px';
            // Set the scrollbar height
            scrollbarEL.style.height = this._scrollbarHeight + 'px';

            return {scrollbar: scrollbarEL, scrollbarContainer: scrollbarContainerEL};
        },

        // Position the scrollbar based on the current position of the ScrollList
        placeScrollBar: function (that) {
            var currentPosition = that._layout.getVisiblePosition().top;
            var availableScrollbarHeight = that._viewportHeight - that._scrollbarHeight;
            var scrollableVirtualHeight = that._virtualHeight - (that._layout.getVisiblePosition().bottom - that._layout.getVisiblePosition().top);
            var translatedPosition = availableScrollbarHeight / scrollableVirtualHeight * currentPosition;
            that._elements.scrollbar.style.top = translatedPosition + 'px';
        },

        updateScrollBar: function (event, that, clickOffset) {
            // Don't go past the window bounds
            var scrollbarPos = Math.max(0, event.clientY - clickOffset);
            scrollbarPos = Math.min(scrollbarPos, that._viewportHeight - that._scrollbarHeight);
            that._elements.scrollbar.style.top = scrollbarPos + 'px';
            var offset = (that._viewportHeight/that._avgObjHeight)/2;

            // Use the ratio of scrollbar position inside the scrolling area to calculate
            // the current item we should be interested in.
            var positionOfInterest = ((scrollbarPos) / (that._viewportHeight - that._scrollbarHeight)) * (that._virtualHeight);

            // Ensure that positionOfInterest isn't undefined.
            if (!positionOfInterest) {
                positionOfInterest = 0;
            }

            that._scrollList.scrollToPosition({
                y: positionOfInterest
            });
        },

        stopUpdatingScrollbar: function (that) {
            that._clickOffset = undefined;
            document.removeEventListener('mousemove', that._mousemoveHandler);
            that._scrollbarScrolling = false;
            that.removeDocumentEventWatching(that);
        },

        removeDocumentEventWatching: function (that) {
            document.removeEventListener('mouseup', that._mouseupHandler);
        },

        calculateScrollBarHeight: function (that) {
            // Calculate the size of the scrollbar depending on the virtual height
            // The scrollbar shouldn't be shorter than MIN_HEIGHT
            var MIN_HEIGHT = that._options.min_height || 16;
            var height =  Math.max(MIN_HEIGHT, (that._viewportHeight / that._effectiveVirtualHeight) * that._viewportHeight);
            return height;
        }
    };

    return ScrollBar;

});
<commit_msg>Move scale change handler outside of the constructor<commit_after>/*
 * Copyright 2014 WebFilings, 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
 *
 *     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.
 */

define(function(require) {
    'use strict';

    var requestAnimFrame = require('wf-js-common/requestAnimationFrame');

    /**
     * Creates a new ScrollBar with the given ScrollList and options.
     *
     * @classdesc
     *
     * A ScrollBar provides a UI based on the traditional browser scrollbar
     * for users to scroll the ScrollList.
     *
     * @name ScrollBar
     * @constructor
     *
     * @param {ScrollList} scrollList
     *        The ScrollList that the ScrollBar is constructed for
     *
     * @param {HTMLElement} parent
     *        The parent element for the ScrollBar to be created within
     *
     * @param {Object} options
     *        An object with optional classes and ids to be placed on the
     *        scrollbarEL and scrollbarContainerEL.
     *
     * @param {number} options.minHeight
     *        The minimum height, in pixes, of the ScrollBar
     *        If not provided, the minHeight will default to 16px
     *
     */

    var ScrollBar = function (scrollList, parent, options) {
        var offset;
        var that = this;

        // Set the scrollList
        if (scrollList === undefined) {
            throw new Error('ScrollBar#ScrollBar: scrollList is required');
        }
        else {
            this._scrollList = scrollList;
        }

        // Set the parent
        if (parent === undefined) {
            throw new Error('ScrollBar#ScrollBar: parent is required.');
        }
        else {
            this._parent = parent;
        }

        // Set the options
        this._options = options;

        // Set the layout
        this._layout = scrollList.getLayout();

        // Set the number of items
        this._TOTAL_ITEMS = scrollList._items.length;

        // Set the viewportHeight
        this._viewportHeight = this._layout.getViewportSize().height;

        // Set the virtualHeight
        this._virtualHeight = this._layout.getSize().height;

        // Set up the DOM and set the scrollbar and scrollbarContainer elements
        this._elements = this.setUpDOM();

        // Set the average object height
        this._avgObjHeight = this._virtualHeight/this._TOTAL_ITEMS;

        // Set scrollbarScrolling to initially false
        this._scrollbarScrolling = false;

        // Set clickOffset to null
        this._clickOffset = null;

        // Set the initial scale
        this._scale = this._scrollList._scaleTranslator._map.getCurrentTransformState().scale;

        // Set the effective virtual height.
        this._effectiveVirtualHeight = this._virtualHeight * (1 / this._scale);

        // Set the initial scrollbar height
        this._scrollbarHeight = this.calculateScrollBarHeight(that);

        // Get the initial position, in case it's not at 0, and set the scrollbar position and page number
        requestAnimFrame(function() {
            that.placeScrollBar(that, that._elements.scrollbar);
        });

        // Match the scroll bar positioning to the users scrolling
        this._scrollList.getListMap().onTranslationChanged(function() {
            if (that._scrollbarScrolling) {
                return;
            }
            requestAnimFrame(function() {
                that.placeScrollBar(that, that._elements.scrollbar);
            });
        });

        // Make necessary adjustments when the users zooms in or out
        this._scrollList.getListMap().onScaleChanged(function() {
            that.adjustScale(that);
        });

        // Attach handlers for scrolling the ScrollBar
        this._elements.scrollbar.addEventListener('mousedown', function(event) {
            offset = that._elements.scrollbar.offsetTop + that._elements.scrollbarContainer.offsetTop;
            that._clickOffset = event.clientY - offset + that._elements.scrollbarContainer.offsetTop;
            that._scrollbarScrolling = true;

            that._mouseupHandler = function () {
                that.stopUpdatingScrollbar(that);
            };

            that._mousemoveHandler = function (e) {
                that.updateScrollBar(e, that, that._clickOffset);
            };

            document.addEventListener('mousemove', that._mousemoveHandler);

            document.addEventListener('mouseup', that._mouseupHandler);
        });

    };

    ScrollBar.prototype = {
        setUpDOM: function () {
            // Create the scrollbar's container
            var scrollbarContainerEL = document.createElement('div');
            var scrollbarEL = document.createElement('div');

            // Set the given classes and ids scrollbar and it's container
            if ( this._options.scrollbarId ) {
                scrollbarEL.setAttribute('id', this._options.scrollbarId);
            }
            if ( this._options.scrollbarClass ) {
                scrollbarEL.classNames += this._options.scrollbarClass;
            }
            if ( this._options.scrollbarContainerId ) {
                scrollbarContainerEL.setAttribute('id', this._options.scrollbarContainerId);
            }
            if ( this._options.scrollbarContainerClass) {
                scrollbarContainerEL.classnames += this._options.scrollbarContainerClass;
            }

            // Append the scrollbar and it's parent container to the given parent element
            scrollbarContainerEL.appendChild(scrollbarEL);
            this._parent.appendChild(scrollbarContainerEL);

            // Set the container height to the viewport height
            scrollbarContainerEL.style.height = this._viewportHeight + 'px';
            // Set the scrollbar height
            scrollbarEL.style.height = this._scrollbarHeight + 'px';

            return {scrollbar: scrollbarEL, scrollbarContainer: scrollbarContainerEL};
        },

        // Position the scrollbar based on the current position of the ScrollList
        placeScrollBar: function (that) {
            var currentPosition = that._layout.getVisiblePosition().top;
            var availableScrollbarHeight = that._viewportHeight - that._scrollbarHeight;
            var scrollableVirtualHeight = that._virtualHeight - (that._layout.getVisiblePosition().bottom - that._layout.getVisiblePosition().top);
            var translatedPosition = availableScrollbarHeight / scrollableVirtualHeight * currentPosition;
            that._elements.scrollbar.style.top = translatedPosition + 'px';
        },

        updateScrollBar: function (event, that, clickOffset) {
            // Don't go past the window bounds
            var scrollbarPos = Math.max(0, event.clientY - clickOffset);
            scrollbarPos = Math.min(scrollbarPos, that._viewportHeight - that._scrollbarHeight);
            that._elements.scrollbar.style.top = scrollbarPos + 'px';

            // Use the ratio of scrollbar position inside the scrolling area to calculate
            // the current item we should be interested in.
            var positionOfInterest = ((scrollbarPos) / (that._viewportHeight - that._scrollbarHeight)) * (that._virtualHeight);

            // Ensure that positionOfInterest isn't undefined.
            if (!positionOfInterest) {
                positionOfInterest = 0;
            }

            that._scrollList.scrollToPosition({
                y: positionOfInterest
            });
        },

        stopUpdatingScrollbar: function (that) {
            that._clickOffset = undefined;
            document.removeEventListener('mousemove', that._mousemoveHandler);
            that._scrollbarScrolling = false;
            that.removeDocumentEventWatching(that);
        },

        removeDocumentEventWatching: function (that) {
            document.removeEventListener('mouseup', that._mouseupHandler);
        },

        calculateScrollBarHeight: function (that) {
            // Calculate the size of the scrollbar depending on the virtual height
            // The scrollbar shouldn't be shorter than MIN_HEIGHT
            var MIN_HEIGHT = that._options.minHeight || 16;
            var height =  Math.max(MIN_HEIGHT, (that._viewportHeight / that._effectiveVirtualHeight) * that._viewportHeight);
            return height;
        },

        adjustScale: function (that) {
            that._scale = that._scrollList._scaleTranslator._map.getCurrentTransformState().scale;
            that._effectiveVirtualHeight = that._layout.getSize().height * that._scale;
            that._scrollbarHeight = that.calculateScrollBarHeight(that);
            that._elements.scrollbar.style.height = that._scrollbarHeight + 'px';
        }
    };

    return ScrollBar;

});
<|endoftext|>


<commit_before>$(function(){
	/*/////////////////////////
	// 60fps scroll paints
	/////////////////////////*/
	var body = $('body');
	var timer;
	$(window).on("scroll", function(){
		if(! body.hasClass('disable-hover')){
			body.addClass('disable-hover');
		}
		timer = setTimeout(function(){
			body.removeClass('disable-hover');
		}, 250);
	}, false);

	/*/////////////////////////
	// Split up query strings
	/////////////////////////*/
	var getQueryVariable = function(variable){
		var query = window.location.search.substring(1);
		var vars = query.split("&");
		for (var i=0;i<vars.length;i++) {
			var pair = vars[i].split("=");
			if(pair[0] === variable){
				return pair[1];
			}
		}

		return(false);
	};

	/*/////////////////////////
	// open data-target in new tabs
	/////////////////////////*/
	var popupWindow = function(){
		$("a[data-popup]").on("click", function(event){
			event.preventDefault():
			window.open($(this)[0].href);
		});
	};
	popupWindow();
});
<commit_msg>fixing typo in main.js<commit_after>$(function(){
	/*/////////////////////////
	// 60fps scroll paints
	/////////////////////////*/
	var body = $('body');
	var timer;
	$(window).on("scroll", function(){
		if(! body.hasClass('disable-hover')){
			body.addClass('disable-hover');
		}
		timer = setTimeout(function(){
			body.removeClass('disable-hover');
		}, 250);
	}, false);

	/*/////////////////////////
	// Split up query strings
	/////////////////////////*/
	var getQueryVariable = function(variable){
		var query = window.location.search.substring(1);
		var vars = query.split("&");
		for (var i=0;i<vars.length;i++) {
			var pair = vars[i].split("=");
			if(pair[0] === variable){
				return pair[1];
			}
		}

		return(false);
	};

	/*/////////////////////////
	// open data-target in new tabs
	/////////////////////////*/
	var popupWindow = function(){
		$("a[data-popup]").on("click", function(event){
			event.preventDefault();
			window.open($(this)[0].href);
		});
	};
	popupWindow();
});
<|endoftext|>


<commit_before>////////////////////////////////////////////////
/*   Provided Code - Please Don't Edit   */
////////////////////////////////////////////////
'use strict';

function getInput() {
    console.log("Please choose either 'rock', 'paper', or 'scissors'.")
    return prompt();
}
function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber < 0.33) {
        return "rock";
    } else if (randomNumber < 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
}
////////////////////////////////////////////////
/*           Write Your Code Below            */
////////////////////////////////////////////////

function getPlayerMove(move) {
    if (move === null || move == '') {
        return getInput();
    } else {
        return move;
    }
}

function getComputerMove(move) {
    if (move === null || move == '') {
        return randomPlay();
    } else {
        return move;
    }
}

function getWinner(playerMove,computerMove) {
    var winner;
    if (playerMove === computerMove) {
        // Tie condition
        winner = 'tie';
    } else if (playerMove === 'rock') {
        if (computerMove === 'paper') {
            winner = 'computer';
        } else {
            winner = 'player';
        }
    } else if (playerMove === 'paper') {
        if (computerMove === 'scissors') {
            winner = 'computer';
        } else {
            winner = 'player';
        }
    } else { //playerMove === 'scissor'
        if (computerMove === 'rock') {
            winner = 'computer';
        } else {
            winner = 'player';
        }
    }
    return winner;
}

function playToFive() {
    console.log("Let's play Rock, Paper, Scissors");
    var playerWins = 0;
    var computerWins = 0;
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    return [playerWins, computerWins];
}

<commit_msg>replaced if statements with ternary operators<commit_after>////////////////////////////////////////////////
/*   Provided Code - Please Don't Edit   */
////////////////////////////////////////////////
'use strict';

function getInput() {
    console.log("Please choose either 'rock', 'paper', or 'scissors'.")
    return prompt();
}
function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber < 0.33) {
        return "rock";
    } else if (randomNumber < 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
}

function getPlayerMove(move) {
    (move === null || move === '') ? getInput() : move;
}

function getComputerMove(move) {
    (move === null || move === '') ? randomPlay() : move;
}

function getWinner(playerMove,computerMove) {
    var winner;
    if (playerMove === computerMove) {
        // Tie condition
        winner = 'tie';
    } else if (playerMove === 'rock') {
        if (computerMove === 'paper') {
            winner = 'computer';
        } else {
            winner = 'player';
        }
    } else if (playerMove === 'paper') {
        if (computerMove === 'scissors') {
            winner = 'computer';
        } else {
            winner = 'player';
        }
    } else { //playerMove === 'scissor'
        if (computerMove === 'rock') {
            winner = 'computer';
        } else {
            winner = 'player';
        }
    }
    return winner;
}

function playToFive() {
    console.log("Let's play Rock, Paper, Scissors");
    var playerWins = 0;
    var computerWins = 0;
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    return [playerWins, computerWins];
}

<|endoftext|>


<commit_before>/*
jquery.animate-enhanced plugin v1.02
---
http://github.com/benbarnett/jQuery-Animate-Enhanced
http://benbarnett.net
@benpbarnett
*/
(function(d,J,K){function P(a,b,d,l,j,h,c,n,q){var t=!1;c=!0===c&&!0===n;b=b||{};b.original||(b.original={},t=!0);b.properties=b.properties||{};b.secondary=b.secondary||{};n=b.meta;for(var k=b.original,x=b.properties,Q=b.secondary,D=r.length-1;0<=D;D--){var F=r[D]+"transition-property",y=r[D]+"transition-duration",e=r[D]+"transition-timing-function";d=c?r[D]+"transform":d;t&&(k[F]=a.css(F)||"",k[y]=a.css(y)||"",k[e]=a.css(e)||"");Q[d]=c?!0===q||!0===G&&!1!==q&&L?"translate3d("+n.left+"px, "+n.top+
"px, 0)":"translate("+n.left+"px,"+n.top+"px)":h;x[F]=(x[F]?x[F]+",":"")+d;x[y]=(x[y]?x[y]+",":"")+l+"ms";x[e]=(x[e]?x[e]+",":"")+j}return b}function B(a){for(var b in a)return!1;return!0}function R(a){a=a.toUpperCase();var b={LI:"list-item",TR:"table-row",TD:"table-cell",TH:"table-cell",CAPTION:"table-caption",COL:"table-column",COLGROUP:"table-column-group",TFOOT:"table-footer-group",THEAD:"table-header-group",TBODY:"table-row-group"};return"string"==typeof b[a]?b[a]:"block"}function H(a){return parseFloat(a.replace(a.match(/\D+$/),
""))}function M(a){var b=!0;a.each(function(a,d){return b=b&&d.ownerDocument});return b}var S="top right bottom left opacity height width".split(" "),I=["top","right","bottom","left"],r=["-webkit-","-moz-","-o-",""],T=["avoidTransforms","useTranslate3d","leaveTransforms"],U=/^([+-]=)?([\d+-.]+)(.*)$/,V=/([A-Z])/g,W={secondary:{},meta:{top:0,right:0,bottom:0,left:0}},N=null,C=!1,z=(document.body||document.documentElement).style,O=void 0!==z.WebkitTransition||void 0!==z.MozTransition||void 0!==z.OTransition||
void 0!==z.transition,L="WebKitCSSMatrix"in window&&"m11"in new WebKitCSSMatrix,G=L;d.expr&&d.expr.filters&&(N=d.expr.filters.animated,d.expr.filters.animated=function(a){return d(a).data("events")&&d(a).data("events")["webkitTransitionEnd oTransitionEnd transitionend"]?!0:N.call(this,a)});d.extend({toggle3DByDefault:function(){return G=!G},toggleDisabledByDefault:function(){return C=!C},setDisabledByDefault:function(a){return C=a}});d.fn.translation=function(){if(!this[0])return null;var a=window.getComputedStyle(this[0],
null),d={x:0,y:0};if(a)for(var p=r.length-1;0<=p;p--){var l=a.getPropertyValue(r[p]+"transform");if(l&&/matrix/i.test(l)){a=l.replace(/^matrix\(/i,"").split(/, |\)$/g);d={x:parseInt(a[4],10),y:parseInt(a[5],10)};break}}return d};d.fn.animate=function(a,b,p,l){a=a||{};var j=!("undefined"!==typeof a.bottom||"undefined"!==typeof a.right),h=d.speed(b,p,l),c=this,n=0,q=function(){n--;0===n&&"function"===typeof h.complete&&h.complete.apply(c,arguments)},t;if(!(t=!0===("undefined"!==typeof a.avoidCSSTransitions?
a.avoidCSSTransitions:C)))if(!(t=!O))if(!(t=B(a))){var k;a:{for(k in a)if(("width"==k||"height"==k)&&("show"==a[k]||"hide"==a[k]||"toggle"==a[k])){k=!0;break a}k=!1}t=k||0>=h.duration}return t?J.apply(this,arguments):this[!0===h.queue?"queue":"each"](function(){var b=d(this),c=d.extend({},h),l=function(c){var g=b.data("jQe")||{original:{}},f={};if(2==c.eventPhase){if(!0!==a.leaveTransforms){for(c=r.length-1;0<=c;c--)f[r[c]+"transform"]="";if(j&&"undefined"!==typeof g.meta){c=0;for(var e;e=I[c];++c)f[e]=
g.meta[e+"_o"]+"px",d(this).css(e,f[e])}}b.unbind("webkitTransitionEnd oTransitionEnd transitionend").css(g.original).css(f).data("jQe",null);"hide"===a.opacity&&b.css({display:"none",opacity:""});q.call(this)}},k={bounce:"cubic-bezier(0.0, 0.35, .5, 1.3)",linear:"linear",swing:"ease-in-out",easeInQuad:"cubic-bezier(0.550, 0.085, 0.680, 0.530)",easeInCubic:"cubic-bezier(0.550, 0.055, 0.675, 0.190)",easeInQuart:"cubic-bezier(0.895, 0.030, 0.685, 0.220)",easeInQuint:"cubic-bezier(0.755, 0.050, 0.855, 0.060)",
easeInSine:"cubic-bezier(0.470, 0.000, 0.745, 0.715)",easeInExpo:"cubic-bezier(0.950, 0.050, 0.795, 0.035)",easeInCirc:"cubic-bezier(0.600, 0.040, 0.980, 0.335)",easeInBack:"cubic-bezier(0.600, -0.280, 0.735, 0.045)",easeOutQuad:"cubic-bezier(0.250, 0.460, 0.450, 0.940)",easeOutCubic:"cubic-bezier(0.215, 0.610, 0.355, 1.000)",easeOutQuart:"cubic-bezier(0.165, 0.840, 0.440, 1.000)",easeOutQuint:"cubic-bezier(0.230, 1.000, 0.320, 1.000)",easeOutSine:"cubic-bezier(0.390, 0.575, 0.565, 1.000)",easeOutExpo:"cubic-bezier(0.190, 1.000, 0.220, 1.000)",
easeOutCirc:"cubic-bezier(0.075, 0.820, 0.165, 1.000)",easeOutBack:"cubic-bezier(0.175, 0.885, 0.320, 1.275)",easeInOutQuad:"cubic-bezier(0.455, 0.030, 0.515, 0.955)",easeInOutCubic:"cubic-bezier(0.645, 0.045, 0.355, 1.000)",easeInOutQuart:"cubic-bezier(0.770, 0.000, 0.175, 1.000)",easeInOutQuint:"cubic-bezier(0.860, 0.000, 0.070, 1.000)",easeInOutSine:"cubic-bezier(0.445, 0.050, 0.550, 0.950)",easeInOutExpo:"cubic-bezier(1.000, 0.000, 0.000, 1.000)",easeInOutCirc:"cubic-bezier(0.785, 0.135, 0.150, 0.860)",
easeInOutBack:"cubic-bezier(0.680, -0.550, 0.265, 1.550)"},y={},k=k[c.easing||"swing"]?k[c.easing||"swing"]:c.easing||"swing",e;for(e in a)if(-1===d.inArray(e,T)){var p=-1<d.inArray(e,I),m;var g=b,w=a[e],u=e,s=p&&!0!==a.avoidTransforms;if("d"==u)m=void 0;else if(M(g)){var f=U.exec(w);m="auto"===g.css(u)?0:g.css(u);m="string"==typeof m?H(m):m;"string"==typeof w&&H(w);var s=!0===s?0:m,t=g.is(":hidden"),v=g.translation();"left"==u&&(s=parseInt(m,10)+v.x);"right"==u&&(s=parseInt(m,10)+v.x);"top"==u&&
(s=parseInt(m,10)+v.y);"bottom"==u&&(s=parseInt(m,10)+v.y);!f&&"show"==w?(s=1,t&&g.css({display:R(g.context.tagName),opacity:0})):!f&&"hide"==w&&(s=0);f?(g=parseFloat(f[2]),f[1]&&(g=("-="===f[1]?-1:1)*g+parseInt(s,10)),m=g):m=s}else m=void 0;f=e;g=m;w=b;if(M(w)){u=-1<d.inArray(f,S);if(("width"==f||"height"==f||"opacity"==f)&&parseFloat(g)===parseFloat(w.css(f)))u=!1;f=u}else f=!1;if(f){var f=b,g=e,w=c.duration,u=k,p=p&&!0!==a.avoidTransforms,s=j,t=a.useTranslate3d,v=(v=f.data("jQe"))&&!B(v)?v:d.extend(!0,
{},W),A=m;if(-1<d.inArray(g,I)){var E=v.meta,C=H(f.css(g))||0,z=g+"_o",A=m-C;E[g]=A;E[z]="auto"==f.css(g)?0+A:C+A||0;v.meta=E;s&&0===A&&(A=0-E[z],E[g]=A,E[z]=0)}f.data("jQe",P(f,v,g,w,u,A,p,s,t))}else y[e]=a[e]}b.unbind("webkitTransitionEnd oTransitionEnd transitionend");if((e=b.data("jQe"))&&!B(e)&&!B(e.secondary)){n++;b.css(e.properties);var G=e.secondary;setTimeout(function(){b.bind("webkitTransitionEnd oTransitionEnd transitionend",l).css(G)})}else c.queue=!1;B(y)||(n++,J.apply(b,[y,{duration:c.duration,
easing:d.easing[c.easing]?c.easing:d.easing.swing?"swing":"linear",complete:q,queue:c.queue}]));return!0})};d.fn.animate.defaults={};d.fn.stop=function(a,b,p){if(!O)return K.apply(this,[a,b]);a&&this.queue([]);this.each(function(){var l=d(this),j=l.data("jQe");if(j&&!B(j)){var h,c={};if(b){if(c=j.secondary,!p&&void 0!==typeof j.meta.left_o||void 0!==typeof j.meta.top_o){c.left=void 0!==typeof j.meta.left_o?j.meta.left_o:"auto";c.top=void 0!==typeof j.meta.top_o?j.meta.top_o:"auto";for(h=r.length-
1;0<=h;h--)c[r[h]+"transform"]=""}}else if(!B(j.secondary)){var n=window.getComputedStyle(l[0],null);if(n)for(var q in j.secondary)if(j.secondary.hasOwnProperty(q)&&(q=q.replace(V,"-$1").toLowerCase(),c[q]=n.getPropertyValue(q),!p&&/matrix/i.test(c[q]))){h=c[q].replace(/^matrix\(/i,"").split(/, |\)$/g);c.left=parseFloat(h[4])+parseFloat(l.css("left"))+"px"||"auto";c.top=parseFloat(h[5])+parseFloat(l.css("top"))+"px"||"auto";for(h=r.length-1;0<=h;h--)c[r[h]+"transform"]=""}}l.unbind("webkitTransitionEnd oTransitionEnd transitionend");
l.css(j.original).css(c).data("jQe",null)}else K.apply(l,[a,b])});return this}})(jQuery,jQuery.fn.animate,jQuery.fn.stop);<commit_msg>Updated version of the animate enhanced plugin.<commit_after>/*
jquery.animate-enhanced plugin v1.08
---
http://github.com/benbarnett/jQuery-Animate-Enhanced
http://benbarnett.net
@benpbarnett
*/
(function(d,C,D){function J(a,b,l,c){if("d"!=l&&E(a)){var f=K.exec(b),e="auto"===a.css(l)?0:a.css(l),e="string"==typeof e?z(e):e;"string"==typeof b&&z(b);c=!0===c?0:e;var g=a.is(":hidden"),n=a.translation();"left"==l&&(c=parseInt(e,10)+n.x);"right"==l&&(c=parseInt(e,10)+n.x);"top"==l&&(c=parseInt(e,10)+n.y);"bottom"==l&&(c=parseInt(e,10)+n.y);if(f||"show"!=b)f||"hide"!=b||(c=0);else if(c=1,g)elem=a[0],elem.style&&(display=elem.style.display,d._data(elem,"olddisplay")||"none"!==display||(display=elem.style.display=
""),""===display&&"none"===d.css(elem,"display")&&d._data(elem,"olddisplay",L(elem.tagName)),""===display||"none"===display)&&(elem.style.display=d._data(elem,"olddisplay")||""),a.css("opacity",0);return f?(a=parseFloat(f[2]),f[1]&&(a=("-="===f[1]?-1:1)*a+parseInt(c,10)),f[3]&&"px"!=f[3]&&(a+=f[3]),a):c}}function M(a,b,l,c,f,e,g,n){var m=a.data(r),m=m&&!q(m)?m:d.extend(!0,{},N),s=f;if(-1<d.inArray(b,A)){var k=m.meta,p=z(a.css(b))||0,t=b+"_o",s=f-p;k[b]=s;k[t]="auto"==a.css(b)?0+s:p+s||0;m.meta=k;
g&&0===s&&(s=0-k[t],k[b]=s,k[t]=0)}return a.data(r,O(a,m,b,l,c,s,e,g,n))}function O(a,b,d,c,f,e,g,n,m){var s=!1;g=!0===g&&!0===n;b=b||{};b.original||(b.original={},s=!0);b.properties=b.properties||{};b.secondary=b.secondary||{};n=b.meta;for(var r=b.original,p=b.properties,t=b.secondary,h=k.length-1;0<=h;h--){var u=k[h]+"transition-property",v=k[h]+"transition-duration",q=k[h]+"transition-timing-function";d=g?k[h]+"transform":d;s&&(r[u]=a.css(u)||"",r[v]=a.css(v)||"",r[q]=a.css(q)||"");var P=t,Q=d,
w;if(g){w=n.left;var F=n.top;w=!0===m||!0===B&&!1!==m&&G?"translate3d("+w+"px, "+F+"px, 0)":"translate("+w+"px,"+F+"px)"}else w=e;P[Q]=w;p[u]=(p[u]?p[u]+",":"")+d;p[v]=(p[v]?p[v]+",":"")+c+"ms";p[q]=(p[q]?p[q]+",":"")+f}return b}function R(a){for(var b in a)if(!("width"!=b&&"height"!=b||"show"!=a[b]&&"hide"!=a[b]&&"toggle"!=a[b]))return!0;return!1}function q(a){for(var b in a)return!1;return!0}function L(a){a=a.toUpperCase();var b={LI:"list-item",TR:"table-row",TD:"table-cell",TH:"table-cell",CAPTION:"table-caption",
COL:"table-column",COLGROUP:"table-column-group",TFOOT:"table-footer-group",THEAD:"table-header-group",TBODY:"table-row-group"};return"string"==typeof b[a]?b[a]:"block"}function z(a){return parseFloat(a.replace(a.match(/\D+$/),""))}function E(a){var b=!0;a.each(function(a,d){return b=b&&d.ownerDocument});return b}function S(a,b,l){if(!E(l))return!1;var c=-1<d.inArray(a,T);"width"!=a&&"height"!=a&&"opacity"!=a||parseFloat(b)!==parseFloat(l.css(a))||(c=!1);return c}var T="top right bottom left opacity height width".split(" "),
A=["top","right","bottom","left"],k=["-webkit-","-moz-","-o-",""],U=["avoidTransforms","useTranslate3d","leaveTransforms"],K=/^([+-]=)?([\d+-.]+)(.*)$/,V=/([A-Z])/g,N={secondary:{},meta:{top:0,right:0,bottom:0,left:0}},r="jQe",H=null,x=!1,y=(document.body||document.documentElement).style,I=void 0!==y.WebkitTransition||void 0!==y.MozTransition||void 0!==y.OTransition||void 0!==y.transition,G="WebKitCSSMatrix"in window&&"m11"in new WebKitCSSMatrix,B=G;d.expr&&d.expr.filters&&(H=d.expr.filters.animated,
d.expr.filters.animated=function(a){return d(a).data("events")&&d(a).data("events")["webkitTransitionEnd oTransitionEnd transitionend"]?!0:H.call(this,a)});d.extend({toggle3DByDefault:function(){return B=!B},toggleDisabledByDefault:function(){return x=!x},setDisabledByDefault:function(a){return x=a}});d.fn.translation=function(){if(!this[0])return null;var a=window.getComputedStyle(this[0],null),b={x:0,y:0};if(a)for(var d=k.length-1;0<=d;d--){var c=a.getPropertyValue(k[d]+"transform");if(c&&/matrix/i.test(c)){a=
c.replace(/^matrix\(/i,"").split(/, |\)$/g);b={x:parseInt(a[4],10),y:parseInt(a[5],10)};break}}return b};d.fn.animate=function(a,b,l,c){a=a||{};var f=!("undefined"!==typeof a.bottom||"undefined"!==typeof a.right),e=d.speed(b,l,c),g=0,n=function(){g--;0===g&&"function"===typeof e.complete&&e.complete.apply(this,arguments)};return!0===("undefined"!==typeof a.avoidCSSTransitions?a.avoidCSSTransitions:x)||!I||q(a)||R(a)||0>=e.duration||e.step?C.apply(this,arguments):this[!0===e.queue?"queue":"each"](function(){var b=
d(this),c=d.extend({},e),l=function(c){var e=b.data(r)||{original:{}},g={};if(2==c.eventPhase){if(!0!==a.leaveTransforms){for(c=k.length-1;0<=c;c--)g[k[c]+"transform"]="";if(f&&"undefined"!==typeof e.meta){c=0;for(var h;h=A[c];++c)g[h]=e.meta[h+"_o"]+"px",d(this).css(h,g[h])}}b.unbind("webkitTransitionEnd oTransitionEnd transitionend").css(e.original).css(g).data(r,null);"hide"===a.opacity&&(elem=b[0],elem.style&&(display=d.css(elem,"display"),"none"===display||d._data(elem,"olddisplay")||d._data(elem,
"olddisplay",display),elem.style.display="none"),b.css("opacity",""));n.call(this)}},p={bounce:"cubic-bezier(0.0, 0.35, .5, 1.3)",linear:"linear",swing:"ease-in-out",easeInQuad:"cubic-bezier(0.550, 0.085, 0.680, 0.530)",easeInCubic:"cubic-bezier(0.550, 0.055, 0.675, 0.190)",easeInQuart:"cubic-bezier(0.895, 0.030, 0.685, 0.220)",easeInQuint:"cubic-bezier(0.755, 0.050, 0.855, 0.060)",easeInSine:"cubic-bezier(0.470, 0.000, 0.745, 0.715)",easeInExpo:"cubic-bezier(0.950, 0.050, 0.795, 0.035)",easeInCirc:"cubic-bezier(0.600, 0.040, 0.980, 0.335)",
easeInBack:"cubic-bezier(0.600, -0.280, 0.735, 0.045)",easeOutQuad:"cubic-bezier(0.250, 0.460, 0.450, 0.940)",easeOutCubic:"cubic-bezier(0.215, 0.610, 0.355, 1.000)",easeOutQuart:"cubic-bezier(0.165, 0.840, 0.440, 1.000)",easeOutQuint:"cubic-bezier(0.230, 1.000, 0.320, 1.000)",easeOutSine:"cubic-bezier(0.390, 0.575, 0.565, 1.000)",easeOutExpo:"cubic-bezier(0.190, 1.000, 0.220, 1.000)",easeOutCirc:"cubic-bezier(0.075, 0.820, 0.165, 1.000)",easeOutBack:"cubic-bezier(0.175, 0.885, 0.320, 1.275)",easeInOutQuad:"cubic-bezier(0.455, 0.030, 0.515, 0.955)",
easeInOutCubic:"cubic-bezier(0.645, 0.045, 0.355, 1.000)",easeInOutQuart:"cubic-bezier(0.770, 0.000, 0.175, 1.000)",easeInOutQuint:"cubic-bezier(0.860, 0.000, 0.070, 1.000)",easeInOutSine:"cubic-bezier(0.445, 0.050, 0.550, 0.950)",easeInOutExpo:"cubic-bezier(1.000, 0.000, 0.000, 1.000)",easeInOutCirc:"cubic-bezier(0.785, 0.135, 0.150, 0.860)",easeInOutBack:"cubic-bezier(0.680, -0.550, 0.265, 1.550)"},t={},p=p[c.easing||"swing"]?p[c.easing||"swing"]:c.easing||"swing",h;for(h in a)if(-1===d.inArray(h,
U)){var u=-1<d.inArray(h,A),v=J(b,a[h],h,u&&!0!==a.avoidTransforms);S(h,v,b)?M(b,h,c.duration,p,v,u&&!0!==a.avoidTransforms,f,a.useTranslate3d):t[h]=a[h]}b.unbind("webkitTransitionEnd oTransitionEnd transitionend");h=b.data(r);if(!h||q(h)||q(h.secondary))c.queue=!1;else{g++;b.css(h.properties);var x=h.secondary;setTimeout(function(){b.bind("webkitTransitionEnd oTransitionEnd transitionend",l).css(x)})}q(t)||(g++,C.apply(b,[t,{duration:c.duration,easing:d.easing[c.easing]?c.easing:d.easing.swing?"swing":
"linear",complete:n,queue:c.queue}]));return!0})};d.fn.animate.defaults={};d.fn.stop=function(a,b,l){if(!I)return D.apply(this,[a,b]);a&&this.queue([]);this.each(function(){var c=d(this),f=c.data(r);if(f&&!q(f)){var e,g={};if(b){if(g=f.secondary,!l&&void 0!==typeof f.meta.left_o||void 0!==typeof f.meta.top_o)for(g.left=void 0!==typeof f.meta.left_o?f.meta.left_o:"auto",g.top=void 0!==typeof f.meta.top_o?f.meta.top_o:"auto",e=k.length-1;0<=e;e--)g[k[e]+"transform"]=""}else if(!q(f.secondary)){var n=
window.getComputedStyle(c[0],null);if(n)for(var m in f.secondary)if(f.secondary.hasOwnProperty(m)&&(m=m.replace(V,"-$1").toLowerCase(),g[m]=n.getPropertyValue(m),!l&&/matrix/i.test(g[m])))for(e=g[m].replace(/^matrix\(/i,"").split(/, |\)$/g),g.left=parseFloat(e[4])+parseFloat(c.css("left"))+"px"||"auto",g.top=parseFloat(e[5])+parseFloat(c.css("top"))+"px"||"auto",e=k.length-1;0<=e;e--)g[k[e]+"transform"]=""}c.unbind("webkitTransitionEnd oTransitionEnd transitionend");c.css(f.original).css(g).data(r,
null)}else D.apply(c,[a,b])});return this}})(jQuery,jQuery.fn.animate,jQuery.fn.stop);<|endoftext|>


<commit_before>////////////////////////////////////////////////
/*   Provided Code - Please Don't Edit   */
////////////////////////////////////////////////
'use strict';

function getInput() {
    console.log("Please choose either 'rock', 'paper', or 'scissors'.")
    return prompt();
}
function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber < 0.33) {
        return "rock";
    } else if (randomNumber < 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
}
////////////////////////////////////////////////
/*           Write Your Code Below            */
////////////////////////////////////////////////

function getPlayerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `getInput()`.
    return /* Your Expression */;
}

function getComputerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `randomPlay()`.
    return /* Your Expression */;
}

function getWinner(playerMove,computerMove) {
    var winner;
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    // Assume that the only values playerMove and computerMove can have are 'rock', 'paper', and 'scissors'.
    // The rules of the game are that 'rock' beats 'scissors', 'scissors' beats 'paper', and 'paper' beats 'rock'.
    /* YOUR CODE HERE */
    return winner;
}

function playToFive() {
    console.log("Let's play Rock, Paper, Scissors");
    var playerWins = 0;
    var computerWins = 0;
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    return [playerWins, computerWins];
}

<commit_msg>Completed Unit 3 homework: added expressions to function getPlayerMove and function getComputermove.<commit_after>
////////////////////////////////////////////////
/*   Provided Code - Please Don't Edit   */
////////////////////////////////////////////////
'use strict';

function getInput() {
    console.log("Please choose either 'rock', 'paper', or 'scissors'.")
    return prompt();
}
function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber < 0.33) {
        return "rock";
    } else if (randomNumber < 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
}
////////////////////////////////////////////////
/*           Write Your Code Below            */
////////////////////////////////////////////////

function getPlayerMove(move) {
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `getInput()`.
    return move = move || getInput();
}

function getComputerMove(move) {
    // Write an expression that operates on a variable called `move`
    // If a `move` has a value, your expression should evaluate to that value.
    // However, if `move` is not specified / is null, your expression should equal `randomPlay()`.
    return move = move || getInput();
}

function getWinner(playerMove,computerMove) {
    var winner;
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    // Assume that the only values playerMove and computerMove can have are 'rock', 'paper', and 'scissors'.
    // The rules of the game are that 'rock' beats 'scissors', 'scissors' beats 'paper', and 'paper' beats 'rock'.
    /* YOUR CODE HERE */
    return winner;
}

function playToFive() {
    console.log("Let's play Rock, Paper, Scissors");
    var playerWins = 0;
    var computerWins = 0;
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    return [playerWins, computerWins];
}

<|endoftext|>


<commit_before>/*
 * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, $ */

/*
* Displays an auto suggest popup list of files to allow the user to quickly navigate to a file and lines
* within a file.
* Uses FileIndexManger to supply the file list.
*
* TODO (issue 333) - currently jquery smart auto complete is used for the popup list. While it mostly works
* it has several issues, so it should be replace with an alternative. Issues:
* - only accepts an array of strings. A list of objects is preferred to avoid some work arounds to display
*   both the path and filename.
* - the popup position logic has flaws that require css work-arounds
* - the popup properties cannot be modified once the object is constructed
*/

define(function (require, exports, module) {
    'use strict';

    var FileIndexManager    = require("project/FileIndexManager"),
        JSLintUtils         = require("language/JSLintUtils"),
        DocumentManager     = require("document/DocumentManager"),
        EditorManager       = require("editor/EditorManager"),
        CommandManager      = require("command/CommandManager"),
        Commands            = require("command/Commands"),
        QuickOpenJSSymbol   = require("search/QuickOpenJavaScript"),
        QuickOpenCSS        = require("search/QuickOpenCSS"),
        QuickOpenHTML       = require("search/QuickOpenHTML"),
        ProjectManager      = require("project/ProjectManager");

    /** @type Array.<QuickOpenPlugin> */
    var plugins = [];

    /** @type {QuickOpenPlugin} */
    var currentPlugin = null;
    var fileList;

    /**
     * Rembers the current document that was displayed when showDialog() was called
     * The current document is restored if the user presses escape
     * @type {string} fullpath
     */
    var origDocPath;

    /**
     * Rembers the current cursor location that was present when showDialog() was called
     * The cursor position s restored if the user presses escape
     * @type {!{line:number, ch:number}}
     */
    var origCursorPos;

    var dialogOpen = false;

    /**
     * Defines API for new QuickOpen plguins
     * @param {string} plugin name
     * @param {Array.<string>} filetypes array. Example: ["js", "css", "txt"]
     * @param {Function} filter takes a query string and returns an array of strings that match the query
     * @param {?Functon} match takes a query string and returns true if this plugin wants to provide results for this query
     * @param {Functon} itemFocus performs an action when a result has focus
     * @param {Functon} itemSelect performs an action when a result is choosen
     * @param {?Functon} resultFormatter takes a query string and an item string and returns a
 item to insert into the displayed search resuklts
     */
    function QuickOpenPlugin(name, fileTypes, filter, match, itemFocus, itemSelect, resultsFormatter) {

        this.name = name;
        this.fileTypes = fileTypes; // empty array indicates all
        this.filter = filter;
        this.match = match;
        this.itemFocus = itemFocus;
        this.itemSelect = itemSelect;
        this.resultsFormatter = resultsFormatter;
    }

    /**
     * Registers new QuickOpenPlugin
     * @param {QuickOpenPlugin} plugin
     */
    function addQuickOpenPlugin(plugin) {
        plugins.push(new QuickOpenPlugin(
            plugin.name,
            plugin.fileTypes,
            plugin.filter,
            plugin.match,
            plugin.itemFocus,
            plugin.itemSelect,
            plugin.resultsFormatter
        ));
    }

    /**
    * QuickNavigateDialog class
    * @constructor
    */
    function QuickNavigateDialog() {
        this.searchField = undefined; // defined when showDialog() is called
    }

    /**
     * Creates a dialog div floating on top of the current code mirror editor
     */
    QuickNavigateDialog.prototype._createDialogDiv = function (template) {
        var wrap = $("#editorHolder")[0];
        this.dialog = wrap.insertBefore(document.createElement("div"), wrap.firstChild);
        this.dialog.className = "CodeMirror-dialog";
        this.dialog.innerHTML = '
' + template + '
';
    };

    function _filenameFromPath(path, includeExtension) {
        var end;
        if (includeExtension) {
            end = path.length;
        } else {
            end = path.lastIndexOf(".");
        }
        return path.slice(path.lastIndexOf("/") + 1, end);
    }

    function extractLineNumber(query) {
        var result;
        var regInfo = query.match(/(!?:)(\d+)/); // colon followed by a digit
        if (regInfo) {
            result = regInfo[2] - 1;
        }

        return result;
    }

    /**
     * Closes the search dialog and resolves the promise that showDialog returned
     */
    QuickNavigateDialog.prototype._handleItemSelect = function (selectedItem) {
        if (currentPlugin) {
            currentPlugin.itemSelect(selectedItem);
        } else {
            var query = this.searchField.val();
            var fullPath = $(selectedItem).attr("data-fullpath");

            // extract line number
            var cursor;
            var gotoLine = extractLineNumber(query);
            if (gotoLine) {
                cursor = {line: gotoLine, ch: 0};
            }

            // Do navigation
            if (fullPath) {
                CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: fullPath})
                    .done(function () {
                        if (gotoLine) {
                            EditorManager.getCurrentFullEditor().setCursorPos(cursor);
                        }
                    });
            } else if (gotoLine) {
                EditorManager.getCurrentFullEditor().setCursorPos(cursor);
            }
        }

        this._close();
        EditorManager.focusEditor();
    };

    /**
     * Opens the file specified by selected item if there is no current plugin, otherwise defers handling
     * to the currentPlugin
     */
    QuickNavigateDialog.prototype._handleItemFocus = function (selectedItem) {
        if (currentPlugin) {
            currentPlugin.itemFocus(selectedItem);
        } else {
            var fullPath = $(selectedItem).attr("data-fullpath");
            if (fullPath) {
                fullPath = decodeURIComponent(fullPath);
                CommandManager.execute(Commands.FILE_OPEN, {fullPath: fullPath, focusEditor: false});
            }
        }
    };

    QuickNavigateDialog.prototype._handleKeyIn = function (e, query) {
        // extract line number
        var gotoLine = extractLineNumber(query);
        if (gotoLine) {
            var from = {line: gotoLine, ch: 0};
            var to = {line: gotoLine, ch: 99999};
            EditorManager.getCurrentFullEditor().setSelection(from, to);
        }

        // Remove current plugin if the query stops matching
        if (currentPlugin && !currentPlugin.match(query)) {
            currentPlugin = null;
        }

        if ($(".smart_autocomplete_highlight").length === 0) {
            this._handleItemFocus($(".smart_autocomplete_container > li:first-child"));
        }
    };

    /**
     * Close the dialog when the ENTER (13) or ESC (27) key is pressed
     */
    QuickNavigateDialog.prototype._handleKeyDown = function (e) {
        if (e.keyCode === 13 || e.keyCode === 27) {
            e.stopPropagation();
            e.preventDefault();

            // clear the query on ESC key and restore document and cursor poisition
            if (e.keyCode === 27) {

                // restore document and cursor position
                if (origDocPath) {
                    CommandManager.execute(Commands.FILE_OPEN, {fullPath: origDocPath})
                        .done(function () {
                            EditorManager.getCurrentFullEditor().setCursorPos(origCursorPos);
                        });
                }
            } else if (e.keyCode === 13) {
                // Select current item on ENTER key
                this._handleItemSelect();
            }

            this._close();
        }
    };

    /**
    * Closes the search dialog and resolves the promise that showDialog returned
    */
    QuickNavigateDialog.prototype._close = function (value) {

        if (!dialogOpen) {
            return;
        }
        dialogOpen = false;

        JSLintUtils.setEnabled(true);

        // for some odd reason I need to remove the dialog like this through the parent
        // If I do it more directly listeners are not removed by the smart auto complete plugin
        this.dialog.parentNode.removeChild(this.dialog);
        $(".smart_autocomplete_container").remove();
    };

    function filterFileList(query) {
        var filteredList = $.map(fileList, function (itemInfo) {
            // match query against filename only (not the full path)
            var path = itemInfo.fullPath;
            var filename = _filenameFromPath(path, true);
            if (filename.toLowerCase().indexOf(query.toLowerCase()) !== -1) {
                return path;
            } else {
                return null;
            }
        }).sort(function (a, b) {
            a = a.toLowerCase();
            b = b.toLowerCase();
            //first,  sort by filename without extension
            var filenameA = _filenameFromPath(a, false);
            var filenameB = _filenameFromPath(b, false);
            if (filenameA < filenameB) {
                return -1;
            } else if (filenameA > filenameB) {
                return 1;
            } else {
                // filename is the same, compare including extension
                filenameA = _filenameFromPath(a, true);
                filenameB = _filenameFromPath(b, true);
                if (filenameA < filenameB) {
                    return -1;
                } else if (filenameA > filenameB) {
                    return 1;
                } else {
                    return 0;
                }
            }
        });

        return filteredList;
    }

    function _handleFilter(query) {
        var curDoc = DocumentManager.getCurrentDocument();
        if (!curDoc) {
            return [];
        }

        var filename = _filenameFromPath(curDoc.file.fullPath, true);
        var extension = filename.slice(filename.lastIndexOf(".") + 1, filename.length);

        var i;
        for (i = 0; i < plugins.length; i++) {
            var plugin = plugins[i];
            var extensionMatch = plugin.fileTypes.indexOf(extension) !== -1 || plugin.fileTypes.length === 0;
            if (extensionMatch &&  plugin.match && plugin.match(query)) {
                currentPlugin = plugin;
                return plugin.filter(query);
            }
        }

        currentPlugin = null;
        return filterFileList(query);
    }

    function defaultResultsFormatter(item, query) {
        query = query.slice(query.indexOf("@") + 1, query.length);
        var boldName = item.replace(new RegExp(query, "gi"), "$&");
        return "
" + boldName + "
";
    }

    function _handleResultsFormatter(item) {
        var query = $('input#quickFileOpenSearch').val();

        if (currentPlugin) {
            var formatter = currentPlugin.resultsFormatter || defaultResultsFormatter;
            return formatter(item, query);
        } else {
            // Format filename result
            var filename = _filenameFromPath(item, true);
            var rPath = ProjectManager.makeProjectRelativeIfPossible(item);
            var boldName = filename.replace(new RegExp(query, "gi"), "$&");
            return "
" + boldName +
                "
" + rPath + "
";
        }
    }

    function setCaretPosition(elem, caretPos) {
        if(elem != null) {
            if(elem.createTextRange) {
                var range = elem.createTextRange();
                range.move('character', caretPos);
                range.select();
            }
            else {
                if(elem.selectionStart) {
                    elem.focus();
                    elem.setSelectionRange(caretPos, caretPos);
                }
                else
                    elem.focus();
            }
        }
    }

    function setSearchFieldValue(initialValue) {
        initialValue = initialValue || "";
        var $field = $('input#quickFileOpenSearch');
        if ($field) {
            $field.val(initialValue);
            $field.focus();
            setCaretPosition($field.get(0), initialValue.length);
        }
    }

    /**
    * Shows the search dialog and initializes the auto suggestion list with filenames from the current project
    */
    QuickNavigateDialog.prototype.showDialog = function (initialValue) {
        var that = this;
        dialogOpen = true;

        // To improve performance during list selection disable JSLint until a document is choosen or dialog is closed
        JSLintUtils.setEnabled(false);

        var curDoc = DocumentManager.getCurrentDocument();
        origDocPath = curDoc ? curDoc.file.fullPath : null;
        if (curDoc) {
            origCursorPos = EditorManager.getCurrentFullEditor().getCursorPos();
        } else {
            origCursorPos = null;
        }

        // Move file list getting code so all this code isn't wrapped in it
        FileIndexManager.getFileInfoList("all")
            .done(function (files) {
                fileList = files;
                var dialogHTML = 'Quick Open: <input type="text" autocomplete="off" id="quickFileOpenSearch" style="width: 30em">';
                that._createDialogDiv(dialogHTML);
                that.searchField = $('input#quickFileOpenSearch');

                that.searchField.smartAutoComplete({
                    source: files,
                    maxResults: 20,
                    forceSelect: false,
                    typeAhead: false,   // won't work right now because smart auto complete
                                        // using internal raw results instead of filtered results for matching
                    filter: _handleFilter,
                    resultFormatter: _handleResultsFormatter
                });

                that.searchField.bind({
                    itemSelect: function (e, selectedItem) { that._handleItemSelect(selectedItem); },
                    itemFocus: function (e, selectedItem) { that._handleItemFocus(selectedItem); },
                    keydown: function (e) { that._handleKeyDown(e); },
                    keyIn: function (e, query) { that._handleKeyIn(e, query); }
                });

                setSearchFieldValue(initialValue);
            });
    };

    function doSearch(prefix) {
        prefix = prefix || "";
        var currentEditor = EditorManager.getFocusedEditor();
        var initialString = currentEditor && currentEditor.getSelectedText() || "";
        initialString = prefix + initialString;

        if (dialogOpen) {
            setSearchFieldValue(initialString);
        } else {
            var dialog = new QuickNavigateDialog();
            dialog.showDialog(initialString);
        }
    }

    function doFileSearch() {
        doSearch();
    }

    function doGotoLine() {
        doSearch(":");
    }

    // TODO: should provide a way for QuickOpenJSSymbol to create this function as a plugin
    function doDefinitionSearch() {
        doSearch("@");
    }

    // TODO: in future we would dynamally discover quick open plugins and get their plugins
    var jsFuncPlugin = QuickOpenJSSymbol.getPlugin();
    addQuickOpenPlugin(jsFuncPlugin);

    var cssSelectorsPlugin = QuickOpenCSS.getPlugin();
    addQuickOpenPlugin(cssSelectorsPlugin);

    var htmlIDPlugin = QuickOpenHTML.getPlugin();
    addQuickOpenPlugin(htmlIDPlugin);

    // TODO: allow QuickOpenJS to register it's own commands and keybindings
    CommandManager.register(Commands.NAVIGATE_QUICK_OPEN, doFileSearch);
    CommandManager.register(Commands.NAVIGATE_GOTO_DEFINITION, doDefinitionSearch);
    CommandManager.register(Commands.NAVIGATE_GOTO_LINE, doGotoLine);

    exports.addQuickOpenPlugin = addQuickOpenPlugin;
});
<commit_msg>Remember original selection instead of cursor position<commit_after>/*
 * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, $ */

/*
* Displays an auto suggest popup list of files to allow the user to quickly navigate to a file and lines
* within a file.
* Uses FileIndexManger to supply the file list.
*
* TODO (issue 333) - currently jquery smart auto complete is used for the popup list. While it mostly works
* it has several issues, so it should be replace with an alternative. Issues:
* - only accepts an array of strings. A list of objects is preferred to avoid some work arounds to display
*   both the path and filename.
* - the popup position logic has flaws that require css work-arounds
* - the popup properties cannot be modified once the object is constructed
*/

define(function (require, exports, module) {
    'use strict';

    var FileIndexManager    = require("project/FileIndexManager"),
        JSLintUtils         = require("language/JSLintUtils"),
        DocumentManager     = require("document/DocumentManager"),
        EditorManager       = require("editor/EditorManager"),
        CommandManager      = require("command/CommandManager"),
        Commands            = require("command/Commands"),
        QuickOpenJSSymbol   = require("search/QuickOpenJavaScript"),
        QuickOpenCSS        = require("search/QuickOpenCSS"),
        QuickOpenHTML       = require("search/QuickOpenHTML"),
        ProjectManager      = require("project/ProjectManager");

    /** @type Array.<QuickOpenPlugin> */
    var plugins = [];

    /** @type {QuickOpenPlugin} */
    var currentPlugin = null;
    var fileList;

    /**
     * Rembers the current document that was displayed when showDialog() was called
     * The current document is restored if the user presses escape
     * @type {string} fullpath
     */
    var origDocPath;

    /**
     * Rembers the current cursor location that was present when showDialog() was called
     * The cursor position s restored if the user presses escape
     * @type ?{start:{line:number, ch:number}, end:{line:number, ch:number}}
     */
    var origSelection;

    var dialogOpen = false;

    /**
     * Defines API for new QuickOpen plguins
     * @param {string} plugin name
     * @param {Array.<string>} filetypes array. Example: ["js", "css", "txt"]
     * @param {Function} filter takes a query string and returns an array of strings that match the query
     * @param {?Functon} match takes a query string and returns true if this plugin wants to provide results for this query
     * @param {Functon} itemFocus performs an action when a result has focus
     * @param {Functon} itemSelect performs an action when a result is choosen
     * @param {?Functon} resultFormatter takes a query string and an item string and returns a
 item to insert into the displayed search resuklts
     */
    function QuickOpenPlugin(name, fileTypes, filter, match, itemFocus, itemSelect, resultsFormatter) {

        this.name = name;
        this.fileTypes = fileTypes; // empty array indicates all
        this.filter = filter;
        this.match = match;
        this.itemFocus = itemFocus;
        this.itemSelect = itemSelect;
        this.resultsFormatter = resultsFormatter;
    }

    /**
     * Registers new QuickOpenPlugin
     * @param {QuickOpenPlugin} plugin
     */
    function addQuickOpenPlugin(plugin) {
        plugins.push(new QuickOpenPlugin(
            plugin.name,
            plugin.fileTypes,
            plugin.filter,
            plugin.match,
            plugin.itemFocus,
            plugin.itemSelect,
            plugin.resultsFormatter
        ));
    }

    /**
    * QuickNavigateDialog class
    * @constructor
    */
    function QuickNavigateDialog() {
        this.searchField = undefined; // defined when showDialog() is called
    }

    /**
     * Creates a dialog div floating on top of the current code mirror editor
     */
    QuickNavigateDialog.prototype._createDialogDiv = function (template) {
        var wrap = $("#editorHolder")[0];
        this.dialog = wrap.insertBefore(document.createElement("div"), wrap.firstChild);
        this.dialog.className = "CodeMirror-dialog";
        this.dialog.innerHTML = '
' + template + '
';
    };

    function _filenameFromPath(path, includeExtension) {
        var end;
        if (includeExtension) {
            end = path.length;
        } else {
            end = path.lastIndexOf(".");
        }
        return path.slice(path.lastIndexOf("/") + 1, end);
    }

    function extractLineNumber(query) {
        var result;
        var regInfo = query.match(/(!?:)(\d+)/); // colon followed by a digit
        if (regInfo) {
            result = regInfo[2] - 1;
        }

        return result;
    }

    /**
     * Closes the search dialog and resolves the promise that showDialog returned
     */
    QuickNavigateDialog.prototype._handleItemSelect = function (selectedItem) {
        if (currentPlugin) {
            currentPlugin.itemSelect(selectedItem);
        } else {
            var query = this.searchField.val();
            var fullPath = $(selectedItem).attr("data-fullpath");

            // extract line number
            var cursor;
            var gotoLine = extractLineNumber(query);
            if (gotoLine) {
                cursor = {line: gotoLine, ch: 0};
            }

            // Do navigation
            if (fullPath) {
                CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: fullPath})
                    .done(function () {
                        if (gotoLine) {
                            EditorManager.getCurrentFullEditor().setCursorPos(cursor);
                        }
                    });
            } else if (gotoLine) {
                EditorManager.getCurrentFullEditor().setCursorPos(cursor);
            }
        }

        this._close();
        EditorManager.focusEditor();
    };

    /**
     * Opens the file specified by selected item if there is no current plugin, otherwise defers handling
     * to the currentPlugin
     */
    QuickNavigateDialog.prototype._handleItemFocus = function (selectedItem) {
        if (currentPlugin) {
            currentPlugin.itemFocus(selectedItem);
        } else {
            var fullPath = $(selectedItem).attr("data-fullpath");
            if (fullPath) {
                fullPath = decodeURIComponent(fullPath);
                CommandManager.execute(Commands.FILE_OPEN, {fullPath: fullPath, focusEditor: false});
            }
        }
    };

    QuickNavigateDialog.prototype._handleKeyIn = function (e, query) {
        // extract line number
        var gotoLine = extractLineNumber(query);
        if (gotoLine) {
            var from = {line: gotoLine, ch: 0};
            var to = {line: gotoLine, ch: 99999};

            EditorManager.getCurrentFullEditor().setSelection(from, to);
        }

        // Remove current plugin if the query stops matching
        if (currentPlugin && !currentPlugin.match(query)) {
            currentPlugin = null;
        }

        if ($(".smart_autocomplete_highlight").length === 0) {
            this._handleItemFocus($(".smart_autocomplete_container > li:first-child"));
        }
    };

    /**
     * Close the dialog when the ENTER (13) or ESC (27) key is pressed
     */
    QuickNavigateDialog.prototype._handleKeyDown = function (e) {
        if (e.keyCode === 13 || e.keyCode === 27) {
            e.stopPropagation();
            e.preventDefault();

            // clear the query on ESC key and restore document and cursor poisition
            if (e.keyCode === 27) {

                // restore document and cursor position
                if (origDocPath) {
                    CommandManager.execute(Commands.FILE_OPEN, {fullPath: origDocPath})
                        .done(function () {
                            EditorManager.getCurrentFullEditor().setSelection(origSelection.start, origSelection.end);
                        });
                }
            } else if (e.keyCode === 13) {
                // Select current item on ENTER key
                this._handleItemSelect();
            }

            this._close();
        }
    };

    /**
    * Closes the search dialog and resolves the promise that showDialog returned
    */
    QuickNavigateDialog.prototype._close = function (value) {

        if (!dialogOpen) {
            return;
        }
        dialogOpen = false;

        JSLintUtils.setEnabled(true);

        // for some odd reason I need to remove the dialog like this through the parent
        // If I do it more directly listeners are not removed by the smart auto complete plugin
        this.dialog.parentNode.removeChild(this.dialog);
        $(".smart_autocomplete_container").remove();

        var editor = EditorManager.getCurrentFullEditor();
        editor.focus();
        editor.getCurrentFullEditor().setSelection(origSelection.start, origSelection.end);
    };

    function filterFileList(query) {
        var filteredList = $.map(fileList, function (itemInfo) {
            // match query against filename only (not the full path)
            var path = itemInfo.fullPath;
            var filename = _filenameFromPath(path, true);
            if (filename.toLowerCase().indexOf(query.toLowerCase()) !== -1) {
                return path;
            } else {
                return null;
            }
        }).sort(function (a, b) {
            a = a.toLowerCase();
            b = b.toLowerCase();
            //first,  sort by filename without extension
            var filenameA = _filenameFromPath(a, false);
            var filenameB = _filenameFromPath(b, false);
            if (filenameA < filenameB) {
                return -1;
            } else if (filenameA > filenameB) {
                return 1;
            } else {
                // filename is the same, compare including extension
                filenameA = _filenameFromPath(a, true);
                filenameB = _filenameFromPath(b, true);
                if (filenameA < filenameB) {
                    return -1;
                } else if (filenameA > filenameB) {
                    return 1;
                } else {
                    return 0;
                }
            }
        });

        return filteredList;
    }

    function _handleFilter(query) {
        var curDoc = DocumentManager.getCurrentDocument();
        if (curDoc) {
            var filename = _filenameFromPath(curDoc.file.fullPath, true);
            var extension = filename.slice(filename.lastIndexOf(".") + 1, filename.length);

            var i;
            for (i = 0; i < plugins.length; i++) {
                var plugin = plugins[i];
                var extensionMatch = plugin.fileTypes.indexOf(extension) !== -1 || plugin.fileTypes.length === 0;
                if (extensionMatch &&  plugin.match && plugin.match(query)) {
                    currentPlugin = plugin;
                    return plugin.filter(query);
                }
            }
        }

        currentPlugin = null;
        return filterFileList(query);
    }

    function defaultResultsFormatter(item, query) {
        query = query.slice(query.indexOf("@") + 1, query.length);
        var boldName = item.replace(new RegExp(query, "gi"), "$&");
        return "
" + boldName + "
";
    }

    function _handleResultsFormatter(item) {
        var query = $('input#quickFileOpenSearch').val();

        if (currentPlugin) {
            var formatter = currentPlugin.resultsFormatter || defaultResultsFormatter;
            return formatter(item, query);
        } else {
            // Format filename result
            var filename = _filenameFromPath(item, true);
            var rPath = ProjectManager.makeProjectRelativeIfPossible(item);
            var boldName = filename.replace(new RegExp(query, "gi"), "$&");
            return "
" + boldName +
                "
" + rPath + "
";
        }
    }

    function setCaretPosition(elem, caretPos) {
        if(elem != null) {
            if(elem.createTextRange) {
                var range = elem.createTextRange();
                range.move('character', caretPos);
                range.select();
            }
            else {
                if(elem.selectionStart) {
                    elem.focus();
                    elem.setSelectionRange(caretPos, caretPos);
                }
                else
                    elem.focus();
            }
        }
    }

    function setSearchFieldValue(initialValue) {
        initialValue = initialValue || "";
        var $field = $('input#quickFileOpenSearch');
        if ($field) {
            $field.val(initialValue);
            $field.focus();
            setCaretPosition($field.get(0), initialValue.length);
        }
    }

    /**
    * Shows the search dialog and initializes the auto suggestion list with filenames from the current project
    */
    QuickNavigateDialog.prototype.showDialog = function (initialValue) {
        var that = this;
        dialogOpen = true;

        // To improve performance during list selection disable JSLint until a document is choosen or dialog is closed
        JSLintUtils.setEnabled(false);

        var curDoc = DocumentManager.getCurrentDocument();
        origDocPath = curDoc ? curDoc.file.fullPath : null;
        if (curDoc) {
            origSelection = EditorManager.getCurrentFullEditor().getSelection();
        } else {
            origSelection = null;
        }

        // Move file list getting code so all this code isn't wrapped in it
        FileIndexManager.getFileInfoList("all")
            .done(function (files) {
                fileList = files;
                var dialogHTML = 'Quick Open: <input type="text" autocomplete="off" id="quickFileOpenSearch" style="width: 30em">';
                that._createDialogDiv(dialogHTML);
                that.searchField = $('input#quickFileOpenSearch');

                that.searchField.smartAutoComplete({
                    source: files,
                    maxResults: 20,
                    forceSelect: false,
                    typeAhead: false,   // won't work right now because smart auto complete
                                        // using internal raw results instead of filtered results for matching
                    filter: _handleFilter,
                    resultFormatter: _handleResultsFormatter
                });

                that.searchField.bind({
                    itemSelect: function (e, selectedItem) { that._handleItemSelect(selectedItem); },
                    /* Disabling open on rollover right now because it causes bugs
                    itemFocus: function (e, selectedItem) { that._handleItemFocus(selectedItem); },*/
                    keydown: function (e) { that._handleKeyDown(e); },
                    keyIn: function (e, query) { that._handleKeyIn(e, query); }
                });

                setSearchFieldValue(initialValue);
            });
    };

    function doSearch(prefix) {
        prefix = prefix || "";
        var currentEditor = EditorManager.getFocusedEditor();
        var initialString = currentEditor && currentEditor.getSelectedText() || "";
        initialString = prefix + initialString;

        if (dialogOpen) {
            setSearchFieldValue(initialString);
        } else {
            var dialog = new QuickNavigateDialog();
            dialog.showDialog(initialString);
        }
    }

    function doFileSearch() {
        doSearch();
    }

    function doGotoLine() {
        doSearch(":");
    }

    // TODO: should provide a way for QuickOpenJSSymbol to create this function as a plugin
    function doDefinitionSearch() {
        doSearch("@");
    }

    // TODO: in future we would dynamally discover quick open plugins and get their plugins
    var jsFuncPlugin = QuickOpenJSSymbol.getPlugin();
    addQuickOpenPlugin(jsFuncPlugin);

    var cssSelectorsPlugin = QuickOpenCSS.getPlugin();
    addQuickOpenPlugin(cssSelectorsPlugin);

    var htmlIDPlugin = QuickOpenHTML.getPlugin();
    addQuickOpenPlugin(htmlIDPlugin);

    // TODO: allow QuickOpenJS to register it's own commands and keybindings
    CommandManager.register(Commands.NAVIGATE_QUICK_OPEN, doFileSearch);
    CommandManager.register(Commands.NAVIGATE_GOTO_DEFINITION, doDefinitionSearch);
    CommandManager.register(Commands.NAVIGATE_GOTO_LINE, doGotoLine);

    exports.addQuickOpenPlugin = addQuickOpenPlugin;
});
<|endoftext|>


<commit_before>import PropTypes from 'prop-types'
import React from 'react'

import styles from 'part:@sanity/components/dialogs/fullscreen-style'
import CloseIcon from 'part:@sanity/base/close-icon'
import Portal from 'react-portal'
import Button from 'part:@sanity/components/buttons/default'

export default class FullScreenDialog extends React.PureComponent {
  static propTypes = {
    color: PropTypes.oneOf(['default', 'warning', 'info', 'success', 'danger']),
    className: PropTypes.string,
    title: PropTypes.string,
    children: PropTypes.node,
    onClose: PropTypes.func,
    isOpen: PropTypes.bool,
    centered: PropTypes.bool,
    onAction: PropTypes.func,
    actions: PropTypes.arrayOf(PropTypes.shape({
      title: PropTypes.string.isRequired,
      index: PropTypes.string.isRequired,
      tooltip: PropTypes.string,
      kind: PropTypes.string,
      autoFocus: PropTypes.bool
    }))
  }

  static defaultProps = {
    color: 'default',
    isOpen: false,
    showHeader: false,
    onAction() {},
    onOpen() {},
    actions: []
  }

  componentDidMount() {
    window.addEventListener('keydown', this.handleKeyDown, false)
  }

  componentWillUnmount() {
    window.removeEventListener('keydown', this.handleKeyDown, false)
  }

  handleKeyDown = event => {
    if (event.key === 'Escape' && this.isClosable()) {
      this.props.onClose()
    }
  }

  handleActionClick = event => {
    const actionIndex = event.currentTarget.getAttribute('data-action-index')
    this.props.onAction(this.props.actions[actionIndex])
  }

  isClosable() {
    return typeof this.props.onClose === 'function'
  }

  render() {
    const {color, title, className, onClose, centered, isOpen, actions} = this.props

    const classNames = [
      styles[color] || styles.default,
      isOpen ? styles.isOpen : styles.isClosed,
      className,
      centered && styles.centered
    ]
      .filter(Boolean)
      .join(' ')

    return (
      <Portal closeOnEsc={this.isClosable()} isOpened={isOpen}>

          {
            onClose && (
              <button className={styles.closeButton} onClick={onClose}>
                <CloseIcon color="inherit" />
              </button>
            )
          }

{title}

              {this.props.children}

                {
                  actions.length > 0 &&

                    {
                      actions.map((action, i) => {
                        return (
                          <Button
                            key={i}
                            onClick={this.handleActionClick}
                            data-action-index={i}
                            color={color === 'default' ? action.color : 'white'}
                            disabled={action.disabled}
                            inverted={!action.secondary}
                            kind={action.kind}
                            autoFocus={action.autoFocus}
                            className={`
                              ${styles.button}
                              ${styles[`button_${action.kind}`] || styles.button}
                            `
                            }
                          >
                            {action.title}
                          </Button>
                        )
                      })
                    }

                }

      </Portal>
    )
  }
}
<commit_msg>[components] Remove another prop not in use<commit_after>import PropTypes from 'prop-types'
import React from 'react'

import styles from 'part:@sanity/components/dialogs/fullscreen-style'
import CloseIcon from 'part:@sanity/base/close-icon'
import Portal from 'react-portal'
import Button from 'part:@sanity/components/buttons/default'

export default class FullScreenDialog extends React.PureComponent {
  static propTypes = {
    color: PropTypes.oneOf(['default', 'warning', 'info', 'success', 'danger']),
    className: PropTypes.string,
    title: PropTypes.string,
    children: PropTypes.node,
    onClose: PropTypes.func,
    isOpen: PropTypes.bool,
    centered: PropTypes.bool,
    onAction: PropTypes.func,
    actions: PropTypes.arrayOf(PropTypes.shape({
      title: PropTypes.string.isRequired,
      tooltip: PropTypes.string,
      kind: PropTypes.string,
      autoFocus: PropTypes.bool
    }))
  }

  static defaultProps = {
    color: 'default',
    isOpen: false,
    showHeader: false,
    onAction() {},
    onOpen() {},
    actions: []
  }

  componentDidMount() {
    window.addEventListener('keydown', this.handleKeyDown, false)
  }

  componentWillUnmount() {
    window.removeEventListener('keydown', this.handleKeyDown, false)
  }

  handleKeyDown = event => {
    if (event.key === 'Escape' && this.isClosable()) {
      this.props.onClose()
    }
  }

  handleActionClick = event => {
    const actionIndex = event.currentTarget.getAttribute('data-action-index')
    this.props.onAction(this.props.actions[actionIndex])
  }

  isClosable() {
    return typeof this.props.onClose === 'function'
  }

  render() {
    const {color, title, className, onClose, centered, isOpen, actions} = this.props

    const classNames = [
      styles[color] || styles.default,
      isOpen ? styles.isOpen : styles.isClosed,
      className,
      centered && styles.centered
    ]
      .filter(Boolean)
      .join(' ')

    return (
      <Portal closeOnEsc={this.isClosable()} isOpened={isOpen}>

          {
            onClose && (
              <button className={styles.closeButton} onClick={onClose}>
                <CloseIcon color="inherit" />
              </button>
            )
          }

{title}

              {this.props.children}

                {
                  actions.length > 0 &&

                    {
                      actions.map((action, i) => {
                        return (
                          <Button
                            key={i}
                            onClick={this.handleActionClick}
                            data-action-index={i}
                            color={color === 'default' ? action.color : 'white'}
                            disabled={action.disabled}
                            inverted={!action.secondary}
                            kind={action.kind}
                            autoFocus={action.autoFocus}
                            className={`
                              ${styles.button}
                              ${styles[`button_${action.kind}`] || styles.button}
                            `
                            }
                          >
                            {action.title}
                          </Button>
                        )
                      })
                    }

                }

      </Portal>
    )
  }
}
<|endoftext|>


<commit_before>import React from "react";
import PropTypes from "prop-types";
import { InputCore } from "../Input";
import { TooltipCore } from "./../Tooltip";
import cx from "classnames";

class TextField extends React.PureComponent {
  constructor(props) {
    super(props);

    if (this.props.tooltip && !this.props.header) {
      throw "Tooltip requires Header";
    }

    // Initial state
    this.state = {
      "active": false
    };
  }

  componentDidMount() {
    this.setState({ "isValid": this.props.isValid });
  }

  componentWillReceiveProps(nextProps) {
    if (
      typeof nextProps.isValid !== "undefined" &&
      nextProps.isValid !== this.state.isValid
    ) {
      this.setState({ "isValid": nextProps.isValid });
    }
  }

  _handleChange = (value, event, isValid) => {
    event.persist();

    if (this.props.maxLength) {
      // Keep difference between maxlength and input value in state for count
      this.setState({ "remaining": this.props.maxLength - value.length });
    }

    this.setState({
      "value": value,
      "isValid": isValid
    });

    if (this.props.onChange) {
      // Execute app code
      this.props.onChange(value, event, isValid);
    }
  };

  _handleFocus = () => {
    this.setState({ "active": true });
  };

  _handleBlur = () => {
    this.setState({ "active": false });
  };

  render() {
    const {
      name,
      type,
      header,
      placeholder,
      maxLength,
      small,
      medium,
      large,
      required,
      requiredText,
      validator,
      errorText,
      mask,
      disabled,
      hidden,
      className,
      inline,
      style,
      tooltip,
      tooltipRight
    } = this.props;

    let tooltipClasses = cx({
      "tooltipAlignment": true,
      "tooltipRight": tooltipRight
    });

    let tooltipInternalClasses = cx({
      "ra_Tooltip__tooltip": true,
      "ra_Tooltip__active": true,
      "ra_Tooltip__tooltip-right": true,
      "ra_Tooltip__tooltipContent": true,
      "ra_Tooltip__block": true
    });

    const reqText = (typeof requiredText !== "undefined") ? requiredText : "*";

    let textFieldHeader = header &&

        {header}
        {required &&
           {reqText}
        }
        {tooltip &&

            <TooltipCore
              className={tooltipInternalClasses}
              text={tooltip}
              position="top"
            />

        }

    ;

    let wrapperClasses = cx(
      {
        hidden,
        small,
        medium,
        large,
        inline
      },
      "textfieldWrapper"
    );

    let textFieldClasses = cx(
      {
        disabled,
        "active": this.state.active,
        "invalid": !this.state.isValid
      },
      "textfield"
    );

    return (

        {textFieldHeader}
        <InputCore
          type={type}
          name={name}
          placeholder={placeholder}
          value={this.state.value}
          maxLength={maxLength}
          styleName={textFieldClasses}
          onChange={(value, event, isValid) =>
            this._handleChange(value, event, isValid)
          }
          required={required}
          validator={validator}
          errorText={errorText}
          mask={mask}
          disabled={disabled}
          isValid={this.state.isValid}
          hidden={hidden}
        />

    );
  }
}

TextField.propTypes = {
  /**
   * Sets if the TextField is valid.
   */
  "isValid": PropTypes.bool,
  /** An Object, array, or string of CSS classes to apply to TextField.*/
  "className": PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.object,
    PropTypes.array
  ]),
  /**
   * Define a name for the text input.
   * @examples '<TextField name="test"/>'
   */
  "name": PropTypes.string,
  /**
   * Define a type for the text input. Default is "text".
   * @examples '<TextField type="password"/>'
   */
  "type": PropTypes.string,
  /**
   * Define a default value for the text input.
   * @examples '<TextField value="Textfield value here"/>'
   */
  "value": PropTypes.string,
  /**
   * Defines a small sized text input.
   * @examples '<TextField small/>'
   */
  "small": PropTypes.bool,
  /**
   * Define a title or header to be displayed above the textfield.
   * @examples '<TextField header="test"/>'
   */
  "header": PropTypes.string,
  /**
   * Defines a medium sized text input.
   * @examples '<TextField medium/>'
   */
  "medium": PropTypes.bool,
  /**
   * Defines a large sized text input.
   * @examples '<TextField large/>'
   */
  "large": PropTypes.bool,
  /**
   * Sets a maximum character length that will be validated onChange.
   * @examples '<TextField maxLenght={25}/>'
   */
  "maxLength": PropTypes.number,
  /**
   * Sets a handler function to be executed and validate against. If it returns any falsy value, validation error will trigger.
   * @examples '<TextField validator={this.customValidator}/>'
   */
  "validator": PropTypes.func,
  /**
   * Defines the error text to be shown when custom validation occurs.
   * @examples '<TextField errorText="Custom error message."/>'
   */
  "errorText": PropTypes.string,
  /**
   * Sets a mask for the input field.
   * @examples '<TextField mask="AAA 11111"/>'
   */
  "mask": PropTypes.string,
  /**
   * Defines placeholder text.
   * @examples '<TextField placeholder="test input"/>'
   */
  "placeholder": PropTypes.string,
  /**
   * Sets a handler function to be executed when onChange event occurs (at input element).
   * @examples <TextField onChange={this.customOnChangeFunc}/>
   */
  "onChange": PropTypes.func,
  /**
   * Sets the field as required. Will be validated onChange.
   * @examples '<TextField required/>'
   */
  "required": PropTypes.bool,
  /**
   * Determines if the text input is disabled.
   * @examples '<TextField disabled/>'
   */
  "disabled": PropTypes.bool,
  /**
   * Determines if the text input is hidden.
   * @examples '<TextField hidden/>'
   */
  "hidden": PropTypes.bool,

  /** Pass inline styling here. */
  "style": PropTypes.object,

  /** Sets whether or not TextField will display as inline */
  "inline": PropTypes.bool,

  /** passes tooltip as prop if added to textField */
  "tooltip": PropTypes.string,

  "tooltipRight": PropTypes.bool
};

TextField.defaultProps = {
  "type": "text",
  "isValid": true
};

export default TextField;
<commit_msg>Adding new prop to proptypes<commit_after>import React from "react";
import PropTypes from "prop-types";
import { InputCore } from "../Input";
import { TooltipCore } from "./../Tooltip";
import cx from "classnames";

class TextField extends React.PureComponent {
  constructor(props) {
    super(props);

    if (this.props.tooltip && !this.props.header) {
      throw "Tooltip requires Header";
    }

    // Initial state
    this.state = {
      "active": false
    };
  }

  componentDidMount() {
    this.setState({ "isValid": this.props.isValid });
  }

  componentWillReceiveProps(nextProps) {
    if (
      typeof nextProps.isValid !== "undefined" &&
      nextProps.isValid !== this.state.isValid
    ) {
      this.setState({ "isValid": nextProps.isValid });
    }
  }

  _handleChange = (value, event, isValid) => {
    event.persist();

    if (this.props.maxLength) {
      // Keep difference between maxlength and input value in state for count
      this.setState({ "remaining": this.props.maxLength - value.length });
    }

    this.setState({
      "value": value,
      "isValid": isValid
    });

    if (this.props.onChange) {
      // Execute app code
      this.props.onChange(value, event, isValid);
    }
  };

  _handleFocus = () => {
    this.setState({ "active": true });
  };

  _handleBlur = () => {
    this.setState({ "active": false });
  };

  render() {
    const {
      name,
      type,
      header,
      placeholder,
      maxLength,
      small,
      medium,
      large,
      required,
      requiredText,
      validator,
      errorText,
      mask,
      disabled,
      hidden,
      className,
      inline,
      style,
      tooltip,
      tooltipRight
    } = this.props;

    let tooltipClasses = cx({
      "tooltipAlignment": true,
      "tooltipRight": tooltipRight
    });

    let tooltipInternalClasses = cx({
      "ra_Tooltip__tooltip": true,
      "ra_Tooltip__active": true,
      "ra_Tooltip__tooltip-right": true,
      "ra_Tooltip__tooltipContent": true,
      "ra_Tooltip__block": true
    });

    const reqText = (typeof requiredText !== "undefined") ? requiredText : "*";

    let textFieldHeader = header &&

        {header}
        {required &&  {reqText} }
        {tooltip &&

            <TooltipCore
              className={tooltipInternalClasses}
              text={tooltip}
              position="top"
            />

        }

    ;

    let wrapperClasses = cx(
      {
        hidden,
        small,
        medium,
        large,
        inline
      },
      "textfieldWrapper"
    );

    let textFieldClasses = cx(
      {
        disabled,
        "active": this.state.active,
        "invalid": !this.state.isValid
      },
      "textfield"
    );

    return (

        {textFieldHeader}
        <InputCore
          type={type}
          name={name}
          placeholder={placeholder}
          value={this.state.value}
          maxLength={maxLength}
          styleName={textFieldClasses}
          onChange={(value, event, isValid) =>
            this._handleChange(value, event, isValid)
          }
          required={required}
          validator={validator}
          errorText={errorText}
          mask={mask}
          disabled={disabled}
          isValid={this.state.isValid}
          hidden={hidden}
        />

    );
  }
}

TextField.propTypes = {
  /**
   * Sets if the TextField is valid.
   */
  "isValid": PropTypes.bool,
  /** An Object, array, or string of CSS classes to apply to TextField.*/
  "className": PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.object,
    PropTypes.array
  ]),
  /**
   * Define a name for the text input.
   * @examples '<TextField name="test"/>'
   */
  "name": PropTypes.string,
  /**
   * Define a type for the text input. Default is "text".
   * @examples '<TextField type="password"/>'
   */
  "type": PropTypes.string,
  /**
   * Define a default value for the text input.
   * @examples '<TextField value="Textfield value here"/>'
   */
  "value": PropTypes.string,
  /**
   * Defines a small sized text input.
   * @examples '<TextField small/>'
   */
  "small": PropTypes.bool,
  /**
   * Define a title or header to be displayed above the textfield.
   * @examples '<TextField header="test"/>'
   */
  "header": PropTypes.string,
  /**
   * Defines a medium sized text input.
   * @examples '<TextField medium/>'
   */
  "medium": PropTypes.bool,
  /**
   * Defines a large sized text input.
   * @examples '<TextField large/>'
   */
  "large": PropTypes.bool,
  /**
   * Sets a maximum character length that will be validated onChange.
   * @examples '<TextField maxLenght={25}/>'
   */
  "maxLength": PropTypes.number,
  /**
   * Sets a handler function to be executed and validate against. If it returns any falsy value, validation error will trigger.
   * @examples '<TextField validator={this.customValidator}/>'
   */
  "validator": PropTypes.func,
  /**
   * Defines the error text to be shown when custom validation occurs.
   * @examples '<TextField errorText="Custom error message."/>'
   */
  "errorText": PropTypes.string,
  /**
   * Sets a mask for the input field.
   * @examples '<TextField mask="AAA 11111"/>'
   */
  "mask": PropTypes.string,
  /**
   * Defines placeholder text.
   * @examples '<TextField placeholder="test input"/>'
   */
  "placeholder": PropTypes.string,
  /**
   * Sets a handler function to be executed when onChange event occurs (at input element).
   * @examples <TextField onChange={this.customOnChangeFunc}/>
   */
  "onChange": PropTypes.func,
  /**
   * Sets the field as required. Will be validated onChange.
   * @examples '<TextField required/>'
   */
  "required": PropTypes.bool,
  /**
   * Sets the text to show next to the header for a required TextField. If omitted will default to *.
   * @examples '<TextField required requiredText="required"/>'
   */
  requiredText: PropTypes.string,
  /**
   * Determines if the text input is disabled.
   * @examples '<TextField disabled/>'
   */
  "disabled": PropTypes.bool,
  /**
   * Determines if the text input is hidden.
   * @examples '<TextField hidden/>'
   */
  "hidden": PropTypes.bool,

  /** Pass inline styling here. */
  "style": PropTypes.object,

  /** Sets whether or not TextField will display as inline */
  "inline": PropTypes.bool,

  /** passes tooltip as prop if added to textField */
  "tooltip": PropTypes.string,

  "tooltipRight": PropTypes.bool
};

TextField.defaultProps = {
  "type": "text",
  "isValid": true
};

export default TextField;
<|endoftext|>