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

Fixing the adjust font restore scroll and adding unit tests #3300

Merged
merged 5 commits into from
Apr 4, 2013
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
63 changes: 41 additions & 22 deletions src/view/ViewCommandHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,24 +76,53 @@ define(function (require, exports, module) {
* @type {boolean}
*/
var _fontSizePrefsLoaded = false;



/**
* @private
* Refreshes the editor and restores the scroll position
*/
function _refreshAndRestoreScroll() {
var editor = EditorManager.getCurrentFullEditor(),
oldHeight = editor.getTextHeight(),
oldWidth = editor._codeMirror.defaultCharWidth();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This time I didn't add this function as an Editor method, since for now it just used here, but let me know if should just make it a method of Editor.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is ok here for now since this is the only place scroll is affected. We should consider moving this into Editor whenever this is required from someplace else


editor.refreshAll();

// Since the height isnt updated after the font-size is changed, we just consider the rendered lines
// to calulate the new scroll position
Copy link
Contributor

Choose a reason for hiding this comment

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

typos isn't and calculate

var scrollPos = editor.getScrollPos(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Even though jslint won't ask you to, merge this var block with the one above now that there aren't comments in between

viewportTop = $(".CodeMirror-lines", editor.getRootElement()).parent().position().top,
scrollTop = scrollPos.y - viewportTop;
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this values be retrieved before refreshing the editor? It certainly seems to produce a better behavior...


// Calcualte the new scroll based on the old font sizes and scroll position
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo Calculate

var newWidth = editor._codeMirror.defaultCharWidth(),
newHeight = editor.getTextHeight(),
deltaX = Math.round(scrollPos.x / oldWidth),
deltaY = Math.round(scrollTop / oldHeight),
scrollPosX = scrollPos.x + deltaX * (newWidth - oldWidth),
scrollPosY = scrollPos.y + deltaY * (newHeight - oldHeight);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should move the rounding methods down from delta to scrollPos to reduce rounding errors.


// Scroll the document back to its original position
editor.setScrollPos(scrollPosX, scrollPosY);
}

/**
* @private
* Removes the styles used to update the font size and updates the editor if refresh is true
* @param {boolean} refresh - True to refresh the current full editor
* @param {!boolean} refresh - true to refresh the current full editor
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be just {boolean}. ! indicates that the parameter is non-nullable, but Functions and all value types (boolean, number, and string) are non-nullable by default. Just clarifying as we've been confusing this operator with mandatory parameters for some time :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Also minor nit, no need to use - to separate the parameter name from the definition

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I kind of like the dash here, since it better separates the argument from the description, and is used a lot too all over the code.

Copy link
Contributor

Choose a reason for hiding this comment

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

There certainly are a lot of them. (Precisely 334 from over 1700 param tags). We may want to change those too over time ;)

The problem with the dash is that once we use a doc generator, it will probably become part of the description as the pattern separates the fields with spaces and will consider the dash as the first character.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should be easy enough to cover both cases, but for consistency we need to use one. It would also look better if the description starts on a capital letter, without the dash it can intensify the separation and in the Docs it will surely look better, althought there it would be easy to capitalize the first letter. I'll start changing this file :)

*/
function _removeDynamicFontSize(refresh) {
$("#" + DYNAMIC_FONT_STYLE_ID).remove();
if (refresh) {
EditorManager.getCurrentFullEditor().refreshAll();
_refreshAndRestoreScroll();
}
}

/**
* @private
* Increases or decreases the editor's font size.
* @param {number} negative number to make the font smaller; positive number to make it bigger.
* @param {!number} adjustment - negative number to make the font smaller; positive number to make it bigger
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comments as with the previous jdoc

* @return {boolean} true if adjustment occurred, false if it did not occur
*/
function _adjustFontSize(adjustment) {
Expand Down Expand Up @@ -144,38 +173,26 @@ define(function (require, exports, module) {
"line-height: " + lhStr + " !important;}");
$("head").append(style);

var editor = EditorManager.getCurrentFullEditor();
editor.refreshAll();

// Scroll the document back to its original position. This can only happen
// if the font size is specified in pixels (which it currently is).
if (fsUnits === "px") {
var scrollPos = editor.getScrollPos();
var scrollDeltaX = Math.round(scrollPos.x / lhOld);
var scrollDeltaY = Math.round(scrollPos.y / lhOld);

scrollDeltaX = (adjustment >= 0 ? scrollDeltaX : -scrollDeltaX);
scrollDeltaY = (adjustment >= 0 ? scrollDeltaY : -scrollDeltaY);

editor.setScrollPos((scrollPos.x + scrollDeltaX),
(scrollPos.y + scrollDeltaY));
}
_refreshAndRestoreScroll();

return true;
}

/** Increses the font size by 1 */
function _handleIncreaseFontSize() {
if (_adjustFontSize(1)) {
_prefs.setValue("fontSizeAdjustment", _prefs.getValue("fontSizeAdjustment") + 1);
}
}


/** Decreases the font size by 1 */
function _handleDecreaseFontSize() {
if (_adjustFontSize(-1)) {
_prefs.setValue("fontSizeAdjustment", _prefs.getValue("fontSizeAdjustment") - 1);
}
}

/** Restores the font size to the original size */
function _handleRestoreFontSize() {
_removeDynamicFontSize(true);
_prefs.setValue("fontSizeAdjustment", 0);
Expand Down Expand Up @@ -237,7 +254,7 @@ define(function (require, exports, module) {
/**
* @private
* Scroll the viewport one line up or down.
* @param {number} -1 to scroll one line up; 1 to scroll one line down.
* @param {!number} -1 to scroll one line up; 1 to scroll one line down.
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comments for !

*/
function _scrollLine(direction) {
var editor = EditorManager.getCurrentFullEditor(),
Expand Down Expand Up @@ -306,10 +323,12 @@ define(function (require, exports, module) {
}
}

/** Scrolls one line up */
function _handleScrollLineUp() {
_scrollLine(-1);
}

/** Scrolls one line down */
function _handleScrollLineDown() {
_scrollLine(1);
}
Expand Down
3 changes: 2 additions & 1 deletion test/UnitTestSuite.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define */
define(function (require, exports, module) {
'use strict';
"use strict";

require("spec/CodeHint-test");
require("spec/CodeHintUtils-test");
Expand Down Expand Up @@ -57,6 +57,7 @@ define(function (require, exports, module) {
require("spec/QuickOpen-test");
require("spec/StringMatch-test");
require("spec/UpdateNotification-test");
require("spec/ViewCommandHandlers-test");
require("spec/ViewUtils-test");
require("spec/WorkingSetView-test");
});
3 changes: 3 additions & 0 deletions test/spec/ViewCommandHandlers-test-files/test.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.testClass {
color: red;
}
11 changes: 11 additions & 0 deletions test/spec/ViewCommandHandlers-test-files/test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!doctype html>
<html>
<head>
<title>Simple Test</title>
<link rel="stylesheet" href="test.css">
</head>

<body>
<p class="testClass">Brackets is awesome!</p>
</body>
</html>
158 changes: 158 additions & 0 deletions test/spec/ViewCommandHandlers-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be 2013 ;)

*
* 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, $, describe, beforeEach, afterEach, it, runs, waitsFor, expect, brackets, waitsForDone, document */
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove unused globals $, afterEach, waitsFor, brackets and document


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

var CommandManager, // loaded from brackets.test
Commands, // loaded from brackets.test
EditorManager, // loaded from brackets.test
DocumentManager, // loaded from brackets.test
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove unused DocumentManager. Maybe from the mousewheel tests?

FileViewController,
SpecRunnerUtils = require("spec/SpecRunnerUtils");

describe("ViewCommandHandlers", function () {
this.category = "integration";

var testPath = SpecRunnerUtils.getTestPath("/spec/ViewCommandHandlers-test-files"),
testWindow;

var CSS_FILE = testPath + "/test.css",
HTML_FILE = testPath + "/test.html";

beforeEach(function () {
var promise;

// Create a new window that will be shared by ALL tests in this spec.
if (!testWindow) {
SpecRunnerUtils.createTestWindowAndRun(this, function (w) {
testWindow = w;

// Load module instances from brackets.test
CommandManager = testWindow.brackets.test.CommandManager;
Commands = testWindow.brackets.test.Commands;
EditorManager = testWindow.brackets.test.EditorManager;
DocumentManager = testWindow.brackets.test.DocumentManager;
Copy link
Contributor

Choose a reason for hiding this comment

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

DocumentManager not required for now

FileViewController = testWindow.brackets.test.FileViewController;

SpecRunnerUtils.loadProjectInTestWindow(testPath);
});

runs(function () {
promise = CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: HTML_FILE});
waitsForDone(promise, "Open into working set");
});

runs(function () {
// Open inline editor onto test.css's ".testClass" rule
promise = SpecRunnerUtils.toggleQuickEditAtOffset(EditorManager.getCurrentFullEditor(), {line: 8, ch: 11});
waitsForDone(promise, "Open inline editor");
});
}
});

function getEditors() {
var editor = EditorManager.getCurrentFullEditor();
return {
editor: editor,
inline: editor.getInlineWidgets()[0].editors[0]
};
}


describe("Adjust the Font Size", function () {
it("should increase the font size in both editor and inline editor", function () {
runs(function () {
var editors = getEditors();
var expectedSize = editors.editor.getTextHeight() + 2;

CommandManager.execute(Commands.VIEW_INCREASE_FONT_SIZE);
CommandManager.execute(Commands.VIEW_INCREASE_FONT_SIZE);

expect(editors.editor.getTextHeight()).toBe(expectedSize);
expect(editors.inline.getTextHeight()).toBe(expectedSize);
});
});

it("should decrease the font size in both editor and inline editor", function () {
runs(function () {
var editors = getEditors();
var expectedSize = editors.editor.getTextHeight() - 2;

CommandManager.execute(Commands.VIEW_DECREASE_FONT_SIZE);
CommandManager.execute(Commands.VIEW_DECREASE_FONT_SIZE);

expect(editors.editor.getTextHeight()).toBe(expectedSize);
expect(editors.inline.getTextHeight()).toBe(expectedSize);
});
});

it("should restore the font size in both editor and inline editor", function () {
runs(function () {
var editors = getEditors();
var expectedSize = editors.editor.getTextHeight();

CommandManager.execute(Commands.VIEW_INCREASE_FONT_SIZE);
CommandManager.execute(Commands.VIEW_INCREASE_FONT_SIZE);
CommandManager.execute(Commands.VIEW_RESTORE_FONT_SIZE);

expect(editors.editor.getTextHeight()).toBe(expectedSize);
expect(editors.inline.getTextHeight()).toBe(expectedSize);
});
});

it("should keep the same font size when opening another document", function () {
var promise, expectedSize, editor;

runs(function () {
editor = EditorManager.getCurrentFullEditor();
expectedSize = editor.getTextHeight() + 1;

promise = CommandManager.execute(Commands.VIEW_INCREASE_FONT_SIZE);
waitsForDone(promise, "Increase font size");
});

runs(function () {
// Open another document and bring it to the front
waitsForDone(FileViewController.openAndSelectDocument(CSS_FILE, FileViewController.PROJECT_MANAGER),
"FILE_OPEN on file timeout", 1000);
});

runs(function () {
editor = EditorManager.getCurrentFullEditor();
expect(editor.getTextHeight()).toBe(expectedSize);
});

// This must be in the last spec in the suite.
runs(function () {
this.after(function () {
SpecRunnerUtils.closeTestWindow();
});
});
});
});
});
});