Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Fix Find/Replace unit tests and clean up event handling for animations #5213

Merged
merged 6 commits into from
Sep 17, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/document/DocumentCommandHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -798,13 +798,18 @@ define(function (require, exports, module) {
* promptOnly - If true, only displays the relevant confirmation UI and does NOT actually
* close the document. This is useful when chaining file-close together with other user
* prompts that may be cancelable.
* _forceClose - If true, closes the document without prompting even if there are unsaved
* changes. Only for use in unit tests.
* @return {$.Promise} a promise that is resolved when the file is closed, or if no file is open.
* FUTURE: should we reject the promise if no file is open?
*/
function handleFileClose(commandData) {
// If not specified, file defaults to null; promptOnly defaults to falsy
var file = commandData && commandData.file,
promptOnly = commandData && commandData.promptOnly;
var file, promptOnly, _forceClose;
if (commandData) {
file = commandData.file;
promptOnly = commandData.promptOnly;
_forceClose = commandData._forceClose;
}

// utility function for handleFileClose: closes document & removes from working set
function doClose(fileEntry) {
Expand Down Expand Up @@ -834,7 +839,7 @@ define(function (require, exports, module) {

var doc = DocumentManager.getOpenDocumentForPath(file.fullPath);

if (doc && doc.isDirty) {
if (doc && doc.isDirty && !_forceClose) {
// Document is dirty: prompt to save changes before closing
var filename = FileUtils.getBaseName(doc.file.fullPath);

Expand Down
36 changes: 20 additions & 16 deletions src/editor/Editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ define(function (require, exports, module) {
TextRange = require("document/TextRange").TextRange,
TokenUtils = require("utils/TokenUtils"),
ViewUtils = require("utils/ViewUtils"),
Async = require("utils/Async");
Async = require("utils/Async"),
AnimationUtils = require("utils/AnimationUtils");

var defaultPrefs = { useTabChar: false, tabSize: 4, spaceUnits: 4, closeBrackets: false,
showLineNumbers: true, styleActiveLine: false, wordWrap: true };
Expand Down Expand Up @@ -1101,11 +1102,9 @@ define(function (require, exports, module) {
self._inlineWidgets.push(inlineWidget);

// Set up the widget to start closed, then animate open when its initial height is set.
inlineWidget.$htmlContent
.height(0)
.addClass("animating")
.one("webkitTransitionEnd", function () {
inlineWidget.$htmlContent.removeClass("animating");
inlineWidget.$htmlContent.height(0);
AnimationUtils.animateUsingClass(inlineWidget.htmlContent, "animating")
.done(function () {
deferred.resolve();
});

Expand Down Expand Up @@ -1134,26 +1133,25 @@ define(function (require, exports, module) {
* @return {$.Promise} A promise that is resolved when the inline widget is fully closed and removed from the DOM.
*/
Editor.prototype.removeInlineWidget = function (inlineWidget) {
var deferred = new $.Deferred(),
self = this;

if (!inlineWidget.closePromise) {
var lineNum = this._getInlineWidgetLineNumber(inlineWidget),
deferred = new $.Deferred(),
self = this;
var lineNum = this._getInlineWidgetLineNumber(inlineWidget);

// Remove the inline widget from our internal list immediately, so
// everyone external to us knows it's essentially already gone. We
// don't want to wait until it's done animating closed (but we do want
// the other stuff in _removeInlineWidgetInternal to wait until then).
self._removeInlineWidgetFromList(inlineWidget);

inlineWidget.$htmlContent.addClass("animating")
.one("webkitTransitionEnd", function () {
inlineWidget.$htmlContent.removeClass("animating");
AnimationUtils.animateUsingClass(inlineWidget.htmlContent, "animating")
.done(function () {
self._codeMirror.removeLineWidget(inlineWidget.info);
self._removeInlineWidgetInternal(inlineWidget);
deferred.resolve();
})
.height(0);

});
inlineWidget.$htmlContent.height(0);
inlineWidget.closePromise = deferred.promise();
}
return inlineWidget.closePromise;
Expand Down Expand Up @@ -1264,9 +1262,15 @@ define(function (require, exports, module) {
}

function setOuterHeight() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that I didn't use AnimationUtils.animateUsingClass() here since in this case the class is being handled separately. It didn't seem worth generalizing that function to handle this case as well.

function finishAnimating(e) {
if (e.target === node) {
updateHeight();
$(node).off("webkitTransitionEnd", finishAnimating);
}
}
$(node).height(height);
if ($(node).hasClass("animating")) {
$(node).one("webkitTransitionEnd", updateHeight);
$(node).on("webkitTransitionEnd", finishAnimating);
} else {
updateHeight();
}
Expand Down
15 changes: 14 additions & 1 deletion src/search/FindReplace.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,19 @@ define(function (require, exports, module) {
}
$(currentDocument).off("change.replaceAll");
}

/**
* @private
* When the user switches documents (or closes the last document), ensure that the find bar
* closes, and also close the Replace All panel.
*/
function _handleDocumentChange() {
if (modalBar) {
modalBar.close();
modalBar = null;
}
_closeReplaceAllPanel();
}

/**
* @private
Expand Down Expand Up @@ -613,7 +626,7 @@ define(function (require, exports, module) {
});
});

$(DocumentManager).on("currentDocumentChange", _closeReplaceAllPanel);
$(DocumentManager).on("currentDocumentChange", _handleDocumentChange);

CommandManager.register(Strings.CMD_FIND, Commands.EDIT_FIND, _launchFind);
CommandManager.register(Strings.CMD_FIND_NEXT, Commands.EDIT_FIND_NEXT, _findNext);
Expand Down
66 changes: 66 additions & 0 deletions src/utils/AnimationUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/


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

/**
* Utilities for dealing with animations in the UI.
*/
define(function (require, exports, module) {
"use strict";

/**
* Start an animation by adding the given class to the given target. When the
* animation is complete, removes the class, clears the event handler we attach
* to watch for the animation to finish, and resolves the returned promise.
*
* @param {Element} target The DOM node to animate.
* @param {string} animClass The class that applies the animation/transition to the target.
* @return {$.Promise} A promise that is resolved when the animation completes. Never rejected.
*/
function animateUsingClass(target, animClass) {
var result = new $.Deferred();

function finish(e) {
if (e.target === target) {
$(target)
.removeClass(animClass)
.off("webkitTransitionEnd", finish);
result.resolve();
}
}

// Note that we can't just use $.one() here because we only want to remove
// the handler when we get the transition end event for the correct target (not
// a child).
$(target)
.addClass(animClass)
.on("webkitTransitionEnd", finish);

return result.promise();
}

exports.animateUsingClass = animateUsingClass;
});
14 changes: 8 additions & 6 deletions src/widgets/ModalBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@
define(function (require, exports, module) {
"use strict";

var EditorManager = require("editor/EditorManager"),
KeyEvent = require("utils/KeyEvent");
var EditorManager = require("editor/EditorManager"),
KeyEvent = require("utils/KeyEvent"),
AnimationUtils = require("utils/AnimationUtils");

/**
* @constructor
Expand Down Expand Up @@ -140,10 +141,11 @@ define(function (require, exports, module) {
}

var self = this;
this._$root.addClass("modal-bar-hide").one("webkitTransitionEnd", function () {
self._$root.remove();
result.resolve();
});
AnimationUtils.animateUsingClass(this._$root.get(0), "modal-bar-hide")
.done(function () {
self._$root.remove();
result.resolve();
});

// Preserve scroll position of the current full editor across the editor refresh, adjusting for the
// height of the modal bar so the code doesn't appear to shift if possible.
Expand Down
Loading