Modules (181)

ViewCommandHandlers

Description

The ViewCommandHandlers object dispatches the following event(s):

  • fontSizeChange -- Triggered when the font size is changed via the Increase Font Size, Decrease Font Size, or Restore Font Size commands. The 2nd arg to the listener is the amount of the change. The 3rd arg is a string containing the new font size after applying the change.

Dependencies

Variables

Private

DEFAULT_FONT_FAMILY

Type
string
Private
    var DEFAULT_FONT_FAMILY = "'SourceCodePro-Medium', MS ゴシック, 'MS Gothic', monospace";
Private

DEFAULT_FONT_SIZE

Type
number
Private
    var DEFAULT_FONT_SIZE = 12;

DYNAMIC_FONT_FAMILY_ID

Type
string
    var DYNAMIC_FONT_FAMILY_ID = "codemirror-dynamic-font-family";

DYNAMIC_FONT_STYLE_ID

Type
string
    var DYNAMIC_FONT_STYLE_ID = "codemirror-dynamic-fonts";
Private

MAX_FONT_SIZE

Type
number
Private
    var MAX_FONT_SIZE = 72;
Private

MIN_FONT_SIZE

Type
number
Private
    var MIN_FONT_SIZE = 1;
Private

currFontFamily

Type
string
Private
    var currFontFamily;
Private

currFontSize

Type
string
Private
    var currFontSize;

validFontSizeRegExpStr

Font sizes should be validated by this regexp

    var validFontSizeRegExpStr = "^([0-9]+)?(\\.)?([0-9]+)(px|em)$";
    // Need RegExp as a string to be exported for use with HTML5 pattern attribute

Functions

Private

_addDynamicFontFamily

fontFamily
string
A string with the font family
    function _addDynamicFontFamily(fontFamily) {
        _addDynamicProperty(DYNAMIC_FONT_FAMILY_ID, {
            propName: "font-family",
            propValue: fontFamily
        });
    }
Private

_addDynamicFontSize

fontSize
string
A string with the font size and the size unit
    function _addDynamicFontSize(fontSize) {
        var template = FontRuleTemplate.split("{font-size-param}").join(fontSize);
        less.render(template, null, function onParse(err, tree) {
            if (err) {
                console.error(err);
            } else {
                _addDynamicProperty(DYNAMIC_FONT_STYLE_ID, {
                    ruleText: tree.css
                });
            }
        });
    }
Private

_addDynamicProperty

propertyID
string
Is the property ID to be added
ruleCfg
object
Is the CSS Rule configuration object
ruleCfg.propName
string
Is the name of the style property
ruleCfg.propValue
string
Is the value of the style property
ruleCfg.priorityFlag
boolean
Is a flag to make the style property !important
ruleCfg.ruleName
string
Optional Selctor name to be used for the rule
ruleCfg.ruleText
string
Optional selector definition text
    function _addDynamicProperty(propertyID, ruleCfg) {
        var $style   = $("<style type='text/css'></style>").attr("id", propertyID);
        if (ruleCfg.ruleText) {
            $style.html(ruleCfg.ruleText);
        } else {
            var cssRule = ruleCfg.ruleName || ".CodeMirror";
            var styleStr = ruleCfg.ruleText || StringUtils.format("{0}: {1} {2}", ruleCfg.propName, ruleCfg.propValue, ruleCfg.priorityFlag ? "!important" : "");
            $style.html(cssRule + "{ " + styleStr + " }");
        }

        // Let's make sure we remove the already existing item from the DOM.
        _removeDynamicProperty(propertyID);
        $("head").append($style);
    }
Private

_adjustFontSize

adjustment
number
Negative number to make the font smaller; positive number to make it bigger
Returns:
boolean
true if adjustment occurred, false if it did not occur
     function _adjustFontSize(adjustment) {
        var fsStyle    = prefs.get("fontSize");
        var validFontSizeRegExp = new RegExp(validFontSizeRegExpStr);
        
        // Make sure that the font size is expressed in terms we can
        // handle (px or em). If not, simply bail.
        
         if (fsStyle.search(validFontSizeRegExp) === -1) {
            return false;
        }

        // Guaranteed to work by validation above.
        var fsUnits = fsStyle.substring(fsStyle.length - 2, fsStyle.length),
            delta   = fsUnits === "px" ? 1 : 0.1,
            fsOld   = parseFloat(fsStyle.substring(0, fsStyle.length - 2)),
            fsNew   = fsOld + (delta * adjustment),
            fsStr   = fsNew + fsUnits;

        // Don't let the font size get too small or too large. The minimum font size is 1px or 0.1em
        // and the maximum font size is 72px or 7.2em depending on the unit used
        if (fsNew < MIN_FONT_SIZE * delta || fsNew > MAX_FONT_SIZE * delta) {
            return false;
        }

        setFontSize(fsStr);
        return true;
    }
Private

_getLinesInView

textHeight
number
scrollTop
number
editorHeight
number
Returns:
{first: number,last: number}
    function _getLinesInView(textHeight, scrollTop, editorHeight) {
        var scrolledTop    = scrollTop / textHeight,
            scrolledBottom = (scrollTop + editorHeight) / textHeight;

        // Adjust the last line to round inward to show a whole lines.
        var firstLine      = Math.ceil(scrolledTop),
            lastLine       = Math.floor(scrolledBottom) - 1;

        return { first: firstLine, last: lastLine };
    }
Private

_handleDecreaseFontSize

Decreases the font size by 1

    function _handleDecreaseFontSize() {
        _adjustFontSize(-1);
    }
Private

_handleIncreaseFontSize

Increases the font size by 1

    function _handleIncreaseFontSize() {
        _adjustFontSize(1);
    }
Private

_handleRestoreFontSize

Restores the font size to the original size

    function _handleRestoreFontSize() {
        setFontSize(DEFAULT_FONT_SIZE + "px");
    }
Private

_handleScrollLineDown

Scrolls one line down

    function _handleScrollLineDown() {
        _scrollLine(1);
    }
Private

_handleScrollLineUp

Scrolls one line up

    function _handleScrollLineUp() {
        _scrollLine(-1);
    }
Private

_handleThemeSettings

Open theme settings dialog

    function _handleThemeSettings() {
        ThemeSettings.showDialog();
    }

    // Register command handlers
    CommandManager.register(Strings.CMD_INCREASE_FONT_SIZE, Commands.VIEW_INCREASE_FONT_SIZE,  _handleIncreaseFontSize);
    CommandManager.register(Strings.CMD_DECREASE_FONT_SIZE, Commands.VIEW_DECREASE_FONT_SIZE,  _handleDecreaseFontSize);
    CommandManager.register(Strings.CMD_RESTORE_FONT_SIZE,  Commands.VIEW_RESTORE_FONT_SIZE,   _handleRestoreFontSize);
    CommandManager.register(Strings.CMD_SCROLL_LINE_UP,     Commands.VIEW_SCROLL_LINE_UP,      _handleScrollLineUp);
    CommandManager.register(Strings.CMD_SCROLL_LINE_DOWN,   Commands.VIEW_SCROLL_LINE_DOWN,    _handleScrollLineDown);
    CommandManager.register(Strings.CMD_THEMES,             Commands.CMD_THEMES_OPEN_SETTINGS, _handleThemeSettings);

    prefs.definePreference("fontSize",   "string", DEFAULT_FONT_SIZE + "px", {
        description: Strings.DESCRIPTION_FONT_SIZE
    }).on("change", function () {
        setFontSize(prefs.get("fontSize"));
    });
    prefs.definePreference("fontFamily", "string", DEFAULT_FONT_FAMILY, {
        description: Strings.DESCRIPTION_FONT_FAMILY
    }).on("change", function () {
        setFontFamily(prefs.get("fontFamily"));
    });

    // Define a preference for font smoothing mode on Mac.
    // By default fontSmoothing is set to "subpixel-antialiased"
    // for the text inside code editor. It can be overridden
    // to "antialiased", that would set text rendering AA to use
    // gray scale antialiasing.
    if (brackets.platform === "mac") {
        prefs.definePreference("fontSmoothing", "string", "subpixel-antialiased", {
            description: Strings.DESCRIPTION_FONT_SMOOTHING,
            values: ["subpixel-antialiased", "antialiased"]
        }).on("change", function () {
            setMacFontSmoothingType(prefs.get("fontSmoothing"));
        });
    }

    // Update UI when opening or closing a document
    MainViewManager.on("currentFileChange", _updateUI);

    // Update UI when Brackets finishes loading
    AppInit.appReady(init);

    EventDispatcher.makeEventDispatcher(exports);

    exports.restoreFontSize = restoreFontSize;
    exports.restoreFonts    = restoreFonts;
    exports.getFontSize     = getFontSize;
    exports.setFontSize     = setFontSize;
    exports.getFontFamily   = getFontFamily;
    exports.setFontFamily   = setFontFamily;
    exports.validFontSizeRegExp = validFontSizeRegExpStr;
});
Private

_removeDynamicFontFamily

    function _removeDynamicFontFamily() {
        _removeDynamicProperty(DYNAMIC_FONT_FAMILY_ID);
    }
Private

_removeDynamicFontSize

    function _removeDynamicFontSize() {
        _removeDynamicProperty(DYNAMIC_FONT_STYLE_ID);
    }
Private

_removeDynamicProperty

propertyID
string
is the id of the property to be removed
    function _removeDynamicProperty(propertyID) {
        $("#" + propertyID).remove();
    }
Private

_scrollLine

direction
number
-1 to scroll one line up; 1 to scroll one line down.
    function _scrollLine(direction) {
        var editor        = EditorManager.getCurrentFullEditor(),
            textHeight    = editor.getTextHeight(),
            cursorPos     = editor.getCursorPos(),
            hasSelecction = editor.hasSelection(),
            inlineEditors = editor.getInlineWidgets(),
            scrollInfo    = editor._codeMirror.getScrollInfo(),
            paddingTop    = editor._getLineSpaceElement().offsetTop,
            editorHeight  = scrollInfo.clientHeight,
            scrollTop     = scrollInfo.top - paddingTop,
            removedScroll = paddingTop;

        // Go through all the editors and reduce the scroll top and editor height to properly calculate the lines in view
        var line, coords;
        inlineEditors.forEach(function (inlineEditor) {
            line   = editor._getInlineWidgetLineNumber(inlineEditor);
            coords = editor._codeMirror.charCoords({line: line, ch: 0}, "local");

            if (coords.top < scrollInfo.top) {
                scrollTop     -= inlineEditor.info.height;
                removedScroll += inlineEditor.info.height;

            } else if (coords.top + inlineEditor.info.height < scrollInfo.top + editorHeight) {
                editorHeight -= inlineEditor.info.height;
            }
        });

        // Calculate the lines in view
        var linesInView = _getLinesInView(textHeight, scrollTop, editorHeight);

        // If there is no selection move the cursor so that is always visible.
        if (!hasSelecction) {
            // Move the cursor to the first visible line.
            if (cursorPos.line < linesInView.first) {
                editor.setCursorPos({line: linesInView.first + direction, ch: cursorPos.ch});

            // Move the cursor to the last visible line.
            } else if (cursorPos.line > linesInView.last) {
                editor.setCursorPos({line: linesInView.last + direction, ch: cursorPos.ch});

            // Move the cursor up or down using moveV to keep the goal column intact, since setCursorPos deletes it.
            } else if ((direction > 0 && cursorPos.line === linesInView.first) ||
                    (direction < 0 && cursorPos.line === linesInView.last)) {
                editor._codeMirror.moveV(direction, "line");
            }
        }

        // Scroll and make it snap to lines
        var lines = linesInView.first + direction;
        editor.setScrollPos(scrollInfo.left, (textHeight * lines) + removedScroll);
    }
Private

_updateScroll

editor
non-nullable
Editor
Editor to update.
fontSize
optional
string
A string with the font size and the size unit
    function _updateScroll(editor, fontSize) {
        var oldWidth    = editor._codeMirror.defaultCharWidth(),
            oldFontSize = prefs.get("fontSize"),
            newFontSize = fontSize,
            delta       = 0,
            adjustment  = 0,
            scrollPos   = editor.getScrollPos(),
            line        = editor._codeMirror.lineAtHeight(scrollPos.y, "local");

        delta = /em$/.test(oldFontSize) ? 10 : 1;
        adjustment = parseInt((parseFloat(newFontSize) - parseFloat(oldFontSize)) * delta, 10);

        // Only adjust the scroll position if there was any adjustments to the font size.
        // Otherwise there will be unintended scrolling.
        //
        if (adjustment) {
            editor.refreshAll();
        }

        // Calculate the new scroll based on the old font sizes and scroll position
        var newWidth   = editor._codeMirror.defaultCharWidth(),
            deltaX     = scrollPos.x / oldWidth,
            scrollPosX = scrollPos.x + Math.round(deltaX * (newWidth  - oldWidth)),
            scrollPosY = editor._codeMirror.heightAtLine(line, "local");

        editor.setScrollPos(scrollPosX, scrollPosY);
    }
Private

_updateUI

    function _updateUI() {
        if (DocumentManager.getCurrentDocument() !== null) {
            if (!CommandManager.get(Commands.VIEW_INCREASE_FONT_SIZE).getEnabled()) {
                // If one is disabled then they all are disabled, so enable them all
                CommandManager.get(Commands.VIEW_INCREASE_FONT_SIZE).setEnabled(true);
                CommandManager.get(Commands.VIEW_DECREASE_FONT_SIZE).setEnabled(true);
                CommandManager.get(Commands.VIEW_RESTORE_FONT_SIZE).setEnabled(true);
            }
        } else {
            // No current document so disable all of the Font Size commands
            CommandManager.get(Commands.VIEW_INCREASE_FONT_SIZE).setEnabled(false);
            CommandManager.get(Commands.VIEW_DECREASE_FONT_SIZE).setEnabled(false);
            CommandManager.get(Commands.VIEW_RESTORE_FONT_SIZE).setEnabled(false);
        }
    }
Public API

getFontFamily

Font family getter to get the currently configured font family for the document editor

Returns:
string
The font family for the document editor
    function getFontFamily() {
        return prefs.get("fontFamily");
    }
Public API

getFontSize

Font size getter to get the current font size for the document editor

Returns:
string
Font size with size unit as 'px' or 'em'
    function getFontSize() {
        return prefs.get("fontSize");
    }

init

Initializes the different settings that need to loaded

    function init() {
        currFontFamily = prefs.get("fontFamily");
        _addDynamicFontFamily(currFontFamily);
        currFontSize = prefs.get("fontSize");
        _addDynamicFontSize(currFontSize);
        _updateUI();
    }
Public API

restoreFontSize

Restores the font size using the saved style and migrates the old fontSizeAdjustment view state to the new fontSize, when required

    function restoreFontSize() {
        var fsStyle      = prefs.get("fontSize"),
            fsAdjustment = PreferencesManager.getViewState("fontSizeAdjustment");

        if (fsAdjustment) {
            // Always remove the old view state even if we also have the new view state.
            PreferencesManager.setViewState("fontSizeAdjustment");

            if (!fsStyle) {
                // Migrate the old view state to the new one.
                fsStyle = (DEFAULT_FONT_SIZE + fsAdjustment) + "px";
                prefs.set("fontSize", fsStyle);
            }
        }

        if (fsStyle) {
            _removeDynamicFontSize();
            _addDynamicFontSize(fsStyle);
        }
    }
Public API

restoreFonts

Restores the font size and font family back to factory settings.

    function restoreFonts() {
        setFontFamily(DEFAULT_FONT_FAMILY);
        setFontSize(DEFAULT_FONT_SIZE + "px");
    }
Public API

setFontFamily

Font family setter to set the font family for the document editor

fontFamily
string
The font family to be set. It can be a string with multiple comma separated fonts
    function setFontFamily(fontFamily) {
        var editor = EditorManager.getCurrentFullEditor();

        if (currFontFamily === fontFamily) {
            return;
        }

        _removeDynamicFontFamily();
        if (fontFamily) {
            _addDynamicFontFamily(fontFamily);
        }

        exports.trigger("fontFamilyChange", fontFamily, currFontFamily);
        currFontFamily = fontFamily;
        prefs.set("fontFamily", fontFamily);

        if (editor) {
            editor.refreshAll();
        }
    }
Public API

setFontSize

Font size setter to set the font size for the document editor

fontSize
string
The font size with size unit as 'px' or 'em'
    function setFontSize(fontSize) {
        if (currFontSize === fontSize) {
            return;
        }

        _removeDynamicFontSize();
        if (fontSize) {
            _addDynamicFontSize(fontSize);
        }

        // Update scroll metrics in viewed editors
        _.forEach(MainViewManager.getPaneIdList(), function (paneId) {
            var currentPath = MainViewManager.getCurrentlyViewedPath(paneId),
                doc = currentPath && DocumentManager.getOpenDocumentForPath(currentPath);
            if (doc && doc._masterEditor) {
                _updateScroll(doc._masterEditor, fontSize);
            }
        });

        exports.trigger("fontSizeChange", fontSize, currFontSize);
        currFontSize = fontSize;
        prefs.set("fontSize", fontSize);
    }

setMacFontSmoothingType

Font smoothing setter to set the anti-aliasing type for the code area on Mac.

aaType
string
The antialiasing type to be set. It can take either "subpixel-antialiased" or "antialiased"
    function setMacFontSmoothingType(aaType) {
        var $editor_holder  = $("#editor-holder");

        // Add/Remove the class based on the preference. Also
        // default to subpixel AA in case of invalid entries.
        if (aaType === "antialiased") {
            $editor_holder.removeClass("subpixel-aa");
        } else {
            $editor_holder.addClass("subpixel-aa");
        }
    }