/
githubmirror
/
brackets
Обзор
Документация
Войти
/
githubmirror
/
brackets
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
release-1.7
src/view/ViewCommandHandlers.js
564 строки
20 KB
Prayag Verma
Make src folder files evergreen
27 янв 2016, 13:58
27 янв 2016, 13:58
0e99e63
Код
Авторство
О чём код?
/* * Copyright (c) 2012 - present 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, brackets: false, $ */ /** * 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. */ define(function (require, exports, module) { "use strict"; var Commands = require("command/Commands"), EventDispatcher = require("utils/EventDispatcher"), CommandManager = require("command/CommandManager"), Strings = require("strings"), StringUtils = require("utils/StringUtils"), EditorManager = require("editor/EditorManager"), PreferencesManager = require("preferences/PreferencesManager"), DocumentManager = require("document/DocumentManager"), ThemeSettings = require("view/ThemeSettings"), MainViewManager = require("view/MainViewManager"), AppInit = require("utils/AppInit"), _ = require("thirdparty/lodash"); var prefs = PreferencesManager.getExtensionPrefs("fonts"); /** * @private * The currently present font size. Used to detect no-op changes. * @type {string} */ var currFontSize; /** * @private * The currently present font family. Used to detect no-op changes. * @type {string} */ var currFontFamily; /** * @const * @type {string} */ var DYNAMIC_FONT_STYLE_ID = "codemirror-dynamic-fonts"; /** * @const * @type {string} */ var DYNAMIC_FONT_FAMILY_ID = "codemirror-dynamic-font-family"; /** * @const * @private * The smallest font size in pixels * @type {number} */ var MIN_FONT_SIZE = 1; /** * @const * @private * The largest font size in pixels * @type {number} */ var MAX_FONT_SIZE = 72; /** * @const * @private * The default font size used only to convert the old fontSizeAdjustment view state to the new fontSize * @type {number} */ var DEFAULT_FONT_SIZE = 12; /** * @const * @private * The default font family * @type {string} */ var DEFAULT_FONT_FAMILY = "'SourceCodePro-Medium', MS ゴシック, 'MS Gothic', monospace"; /** * @private * Removes style property from the DOM * @param {string} propertyID is the id of the property to be removed */ function _removeDynamicProperty(propertyID) { $("#" + propertyID).remove(); } /** * @private * Add the style property to the DOM * @param {string} propertyID Is the property ID to be added * @param {string} name Is the name of the style property * @param {string} value Is the value of the style * @param {boolean} important Is a flag to make the style property !important */ function _addDynamicProperty(propertyID, name, value, important, cssRule) { cssRule = cssRule || ".CodeMirror"; var $style = $("<style type='text/css'></style>").attr("id", propertyID); var styleStr = StringUtils.format("{0}: {1}{2}", name, value, important ? " !important" : ""); $style.html(cssRule + "{ " + styleStr + " }"); // Let's make sure we remove the already existing item from the DOM. _removeDynamicProperty(propertyID); $("head").append($style); } /** * @private * Removes the styles used to update the font size */ function _removeDynamicFontSize() { _removeDynamicProperty(DYNAMIC_FONT_STYLE_ID); } /** * @private * Add the styles used to update the font size * @param {string} fontSize A string with the font size and the size unit */ function _addDynamicFontSize(fontSize) { _addDynamicProperty(DYNAMIC_FONT_STYLE_ID, "font-size", fontSize, true); } /** * @private * Removes the styles used to update the font family */ function _removeDynamicFontFamily() { _removeDynamicProperty(DYNAMIC_FONT_FAMILY_ID); } /** * @private * Add the styles used to update the font family * @param {string} fontFamily A string with the font family */ function _addDynamicFontFamily(fontFamily) { _addDynamicProperty(DYNAMIC_FONT_FAMILY_ID, "font-family", fontFamily); } /** * @private * Sets the font size and restores the scroll position as best as possible. * @param {!Editor} editor Editor to update. * @param {string=} fontSize 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); } /** * Font size setter to set the font size for the document editor * @param {string} fontSize 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); } /** * Font size getter to get the current font size for the document editor * @return {string} Font size with size unit as 'px' or 'em' */ function getFontSize() { return prefs.get("fontSize"); } /** * Font family setter to set the font family for the document editor * @param {string} fontFamily 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(); } } /** * Font smoothing setter to set the anti-aliasing type for the code area on Mac. * @param {string} aaType 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"); } } /** * Font family getter to get the currently configured font family for the document editor * @return {string} The font family for the document editor */ function getFontFamily() { return prefs.get("fontFamily"); } /** * @private * Increases or decreases the editor's font size. * @param {number} adjustment Negative number to make the font smaller; positive number to make it bigger * @return {boolean} true if adjustment occurred, false if it did not occur */ function _adjustFontSize(adjustment) { var fsStyle = prefs.get("fontSize"), validFont = /^[\d\.]+(px|em)$/; // Make sure that the font size is expressed in terms we can handle (px or em). If not, simply bail. if (fsStyle.search(validFont) === -1) { return false; } // Guaranteed to work by the 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; } /** Increases the font size by 1 */ function _handleIncreaseFontSize() { _adjustFontSize(1); } /** Decreases the font size by 1 */ function _handleDecreaseFontSize() { _adjustFontSize(-1); } /** Restores the font size to the original size */ function _handleRestoreFontSize() { setFontSize(DEFAULT_FONT_SIZE + "px"); } /** * @private * Updates the user interface appropriately based on whether or not a document is * currently open in the editor. */ 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); } } /** * Initializes the different settings that need to loaded */ function init() { currFontFamily = prefs.get("fontFamily"); _addDynamicFontFamily(currFontFamily); currFontSize = prefs.get("fontSize"); _addDynamicFontSize(currFontSize); _updateUI(); } /** * 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); } } /** * Restores the font size and font family back to factory settings. */ function restoreFonts() { setFontFamily(DEFAULT_FONT_FAMILY); setFontSize(DEFAULT_FONT_SIZE + "px"); } /** * @private * Calculates the first and last visible lines of the focused editor * @param {number} textHeight * @param {number} scrollTop * @param {number} editorHeight * @return {{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 * Scroll the viewport one line up or down. * @param {number} direction -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); } /** Scrolls one line up */ function _handleScrollLineUp() { _scrollLine(-1); } /** Scrolls one line down */ function _handleScrollLineDown() { _scrollLine(1); } /** Open theme settings dialog */ function _handleThemeSettings() { ThemeSettings.showDialog(); } /** * @private * Convert the old "fontSizeAdjustment" preference to the new view state. * * @param {string} key The key of the preference to be examined for migration * of old preferences. Not used since we only have one in this module. * @param {string} value The value of "fontSizeAdjustment" preference * @return {Object} JSON object for the new view state equivalent to * the old "fontSizeAdjustment" preference. */ function _convertToNewViewState(key, value) { return { "fontSizeStyle": (DEFAULT_FONT_SIZE + value) + "px" }; } // 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); PreferencesManager.convertPreferences(module, {"fontSizeAdjustment": "user"}, true, _convertToNewViewState); 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; });