diff --git a/src/styles/brackets_codemirror_override.less b/src/styles/brackets_codemirror_override.less index e44d31c20a0..f75b7912b2f 100644 --- a/src/styles/brackets_codemirror_override.less +++ b/src/styles/brackets_codemirror_override.less @@ -76,108 +76,118 @@ } -span.cm-keyword {color: @accent-keyword;} -span.cm-atom {color: @accent-atom;} -span.cm-number {color: @accent-number;} -span.cm-def {color: @accent-def;} -span.cm-variable {color: @accent-variable;} -span.cm-variable-2 {color: @accent-variable-2;} -span.cm-variable-3 {color: @accent-variable-3;} -span.cm-property {color: @accent-property;} -span.cm-operator {color: @accent-operator;} -span.cm-comment {color: @accent-comment;} -span.cm-string {color: @accent-string;} -span.cm-string-2 {color: @accent-string-2;} -span.cm-meta {color: @accent-meta;} -span.cm-error {color: @accent-error;} -span.cm-qualifier {color: @accent-qualifier;} -span.cm-builtin {color: @accent-builtin;} -span.cm-bracket {color: @accent-bracket;} -span.cm-tag {color: @accent-tag;} -span.cm-attribute {color: @accent-attribute;} -span.cm-header {color: @accent-header;} -span.cm-quote {color: @accent-quote;} -span.cm-hr {color: @accent-hr;} -span.cm-link {color: @accent-link; text-decoration: none;} -span.cm-rangeinfo {color: @accent-rangeinfo;} -span.cm-minus {color: @accent-minus;} -span.cm-plus {color: @accent-plus;} + span.cm-keyword {color: @accent-keyword;} + span.cm-atom {color: @accent-atom;} + span.cm-number {color: @accent-number;} + span.cm-def {color: @accent-def;} + span.cm-variable {color: @accent-variable;} + span.cm-variable-2 {color: @accent-variable-2;} + span.cm-variable-3 {color: @accent-variable-3;} + span.cm-property {color: @accent-property;} + span.cm-operator {color: @accent-operator;} + span.cm-comment {color: @accent-comment;} + span.cm-string {color: @accent-string;} + span.cm-string-2 {color: @accent-string-2;} + span.cm-meta {color: @accent-meta;} + span.cm-error {color: @accent-error;} + span.cm-qualifier {color: @accent-qualifier;} + span.cm-builtin {color: @accent-builtin;} + span.cm-bracket {color: @accent-bracket;} + span.cm-tag {color: @accent-tag;} + span.cm-attribute {color: @accent-attribute;} + span.cm-header {color: @accent-header;} + span.cm-quote {color: @accent-quote;} + span.cm-hr {color: @accent-hr;} + span.cm-link {color: @accent-link; text-decoration: none;} + span.cm-rangeinfo {color: @accent-rangeinfo;} + span.cm-minus {color: @accent-minus;} + span.cm-plus {color: @accent-plus;} + + span.CodeMirror-matchingbracket {color: @accent-bracket !important; background-color: @matching-bracket;} + span.CodeMirror-nonmatchingbracket {color: @accent-bracket !important;} -span.CodeMirror-matchingbracket {color: @accent-bracket !important; background-color: @matching-bracket;} -span.CodeMirror-nonmatchingbracket {color: @accent-bracket !important;} + .CodeMirror-cursors { + .CodeMirror-cursor { + .code-cursor(); + } -.CodeMirror-cursors { - .CodeMirror-cursor { - .code-cursor(); + /* Ensure the cursor shows up in front of code spans with a background color + * (e.g. matchingbracket). + */ + z-index: 3; } - /* Ensure the cursor shows up in front of code spans with a background color - * (e.g. matchingbracket). - */ - z-index: 3; -} - -.CodeMirror-lines { - padding: @code-padding 0; - - /* This is necessary for issue #2780. The logic for closing dropdowns depends on "click" events. Now - * that each line has a separate div element, there is a good chance that mouseDown and mouseUp events - * occur on different elements, which means a click event will not be sent. By disabling pointer events here, - * we are guaranteed that the mouse event will be captured by our parent div, and click events will - * be dispatched. - */ - pointer-events: none; -} - -.CodeMirror-linewidget { - /* Re-enable pointer events for line widget. Pointer events are disabled for "CodeMirror-lines", which is the - * parent of line widgets, so they need to be explicitly re-enabled here in order for selection to work. */ - pointer-events: auto; -} + .CodeMirror-lines { + padding: @code-padding 0; + + /* This is necessary for issue #2780. The logic for closing dropdowns depends on "click" events. Now + * that each line has a separate div element, there is a good chance that mouseDown and mouseUp events + * occur on different elements, which means a click event will not be sent. By disabling pointer events here, + * we are guaranteed that the mouse event will be captured by our parent div, and click events will + * be dispatched. + */ + pointer-events: none; + } -.CodeMirror-gutters { - background-color: @background-color-3; - border-right: none; -} + /** + * These classes are set to inline-block because they are spans and they need block dimension properties when + * when calculation height and width. + */ + .CodeMirror-searching, + .CodeMirror-matchingtag, + .CodeMirror-matchingbracket { + display: inline-block; + } -.platform-mac { - .CodeMirror-scrollbar-filler { - background-image: url(images/scrollbar-mac-corner.png); + .CodeMirror-linewidget { + /* Re-enable pointer events for line widget. Pointer events are disabled for "CodeMirror-lines", which is the + * parent of line widgets, so they need to be explicitly re-enabled here in order for selection to work. */ + pointer-events: auto; } - .CodeMirror-gutter-filler { - background-image: url(images/scrollbar-mac-bg.png); + + .CodeMirror-gutters { + background-color: @background-color-3; + border-right: none; } -} -.platform-win { - .CodeMirror-scrollbar-filler, - .CodeMirror-gutter-filler { - background-color: @win-scrollbar-track; - height: 12px !important; + +.platform-mac { + .CodeMirror-scrollbar-filler { + background-image: url(images/scrollbar-mac-corner.png); + } + .CodeMirror-gutter-filler { + background-image: url(images/scrollbar-mac-bg.png); + } } - .CodeMirror-scrollbar-filler { - width: 12px !important; +.platform-win { + .CodeMirror-scrollbar-filler, + .CodeMirror-gutter-filler { + background-color: @win-scrollbar-track; + height: 12px !important; + } + .CodeMirror-scrollbar-filler { + width: 12px !important; + } } -} .platform-linux { - .CodeMirror-scrollbar-filler, - .CodeMirror-gutter-filler { - background-color: @background-color-3; - height: 12px !important; + .CodeMirror-scrollbar-filler, + .CodeMirror-gutter-filler { + background-color: @background-color-3; + height: 12px !important; + } + .CodeMirror-scrollbar-filler { + width: 12px !important; + } } - .CodeMirror-scrollbar-filler { - width: 12px !important; + + .CodeMirror-linenumber { + color: @accent-comment; + min-width: 2.5em; + /*font-size: 0.9em;*/ /* restore after SourceCodePro font fix? */ + padding: 0 @code-padding 0 10px; /* left padding for project panel selection triangle */ } -} - -.CodeMirror-linenumber { - color: @accent-comment; - min-width: 2.5em; - /*font-size: 0.9em;*/ /* restore after SourceCodePro font fix? */ - padding: 0 @code-padding 0 10px; /* left padding for project panel selection triangle */ -} .CodeMirror-focused .CodeMirror-selected { - background: @selection-color-focused; -} + background: @selection-color-focused; + } /* CodeMirror's use of descendant selectors for certain styling causes problems when editors are diff --git a/src/styles/brackets_codemirror_override.less.orig b/src/styles/brackets_codemirror_override.less.orig new file mode 100644 index 00000000000..dbf8f72fc73 --- /dev/null +++ b/src/styles/brackets_codemirror_override.less.orig @@ -0,0 +1,318 @@ +// Copyright (c) 2012 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. + +/* Brackets / CodeMirror Code Formatting */ + +.CodeMirror pre { + padding: 0 @code-padding 0 0; +} + +.show-line-padding .CodeMirror pre { + padding-left: @code-padding; +} + +.CodeMirror-scroll { + background-color: @background-color-3; +} + +.CodeMirror { + .code-font(); +} + +.platform-mac .CodeMirror { + .code-font-mac(); +} + +.platform-win .CodeMirror { + .code-font-win(); +} + +@code-padding: 15px; + +.CodeMirror-activeline-background { + background: transparent; +} + +.CodeMirror-focused .CodeMirror-activeline-background { + background: @activeline-bgcolor; +} + +.show-line-padding .CodeMirror-focused .CodeMirror-activeline-background { + box-shadow: inset @code-padding 0 0 0 @activeline-number-bgcolor; +} + +.CodeMirror-focused .CodeMirror-activeline { + & > div, .CodeMirror-gutter-elt { + height: 100%; + } + .CodeMirror-gutter-elt { + background: @activeline-number-bgcolor; + color: @bc-black; + } + .inline-widget .CodeMirror-gutter-elt { + color: @accent-comment; + } +} + +.CodeMirror-focused .cm-matchhighlight { + border-bottom: 2px solid #78B2F2; +} + + +span.cm-keyword {color: @accent-keyword;} +span.cm-atom {color: @accent-atom;} +span.cm-number {color: @accent-number;} +span.cm-def {color: @accent-def;} +span.cm-variable {color: @accent-variable;} +span.cm-variable-2 {color: @accent-variable-2;} +span.cm-variable-3 {color: @accent-variable-3;} +span.cm-property {color: @accent-property;} +span.cm-operator {color: @accent-operator;} +span.cm-comment {color: @accent-comment;} +span.cm-string {color: @accent-string;} +span.cm-string-2 {color: @accent-string-2;} +span.cm-meta {color: @accent-meta;} +span.cm-error {color: @accent-error;} +span.cm-qualifier {color: @accent-qualifier;} +span.cm-builtin {color: @accent-builtin;} +span.cm-bracket {color: @accent-bracket;} +span.cm-tag {color: @accent-tag;} +span.cm-attribute {color: @accent-attribute;} +span.cm-header {color: @accent-header;} +span.cm-quote {color: @accent-quote;} +span.cm-hr {color: @accent-hr;} +span.cm-link {color: @accent-link; text-decoration: none;} +span.cm-rangeinfo {color: @accent-rangeinfo;} +span.cm-minus {color: @accent-minus;} +span.cm-plus {color: @accent-plus;} + +span.CodeMirror-matchingbracket {color: @accent-bracket !important; background-color: @matching-bracket;} +span.CodeMirror-nonmatchingbracket {color: @accent-bracket !important;} + +.CodeMirror-cursors { + .CodeMirror-cursor { + .code-cursor(); + } + +<<<<<<< HEAD + .CodeMirror-lines { + padding: @code-padding 0; + + /* This is necessary for issue #2780. The logic for closing dropdowns depends on "click" events. Now + * that each line has a separate div element, there is a good chance that mouseDown and mouseUp events + * occur on different elements, which means a click event will not be sent. By disabling pointer events here, + * we are guaranteed that the mouse event will be captured by our parent div, and click events will + * be dispatched. + */ + pointer-events: none; + } + + /** + * These classes are set to inline-block because they are spans and they need block dimension properties when + * when calculation height and width. + */ + .CodeMirror-searching, + .CodeMirror-matchingtag, + .CodeMirror-matchingbracket { + display: inline-block; + } + + .CodeMirror-linewidget { + /* Re-enable pointer events for line widget. Pointer events are disabled for "CodeMirror-lines", which is the + * parent of line widgets, so they need to be explicitly re-enabled here in order for selection to work. */ + pointer-events: auto; + } + + .CodeMirror-gutters { + background-color: @background-color-3; + border-right: none; +======= + /* Ensure the cursor shows up in front of code spans with a background color + * (e.g. matchingbracket). + */ + z-index: 3; +} + +.CodeMirror-lines { + padding: @code-padding 0; + + /* This is necessary for issue #2780. The logic for closing dropdowns depends on "click" events. Now + * that each line has a separate div element, there is a good chance that mouseDown and mouseUp events + * occur on different elements, which means a click event will not be sent. By disabling pointer events here, + * we are guaranteed that the mouse event will be captured by our parent div, and click events will + * be dispatched. + */ + pointer-events: none; +} + +.CodeMirror-linewidget { + /* Re-enable pointer events for line widget. Pointer events are disabled for "CodeMirror-lines", which is the + * parent of line widgets, so they need to be explicitly re-enabled here in order for selection to work. */ + pointer-events: auto; +} + +.CodeMirror-gutters { + background-color: @background-color-3; + border-right: none; +} + +.platform-mac { + .CodeMirror-scrollbar-filler { + background-image: url(images/scrollbar-mac-corner.png); +>>>>>>> master + } + .CodeMirror-gutter-filler { + background-image: url(images/scrollbar-mac-bg.png); + } +} +.platform-win { + .CodeMirror-scrollbar-filler, + .CodeMirror-gutter-filler { + background-color: @win-scrollbar-track; + height: 12px !important; + } + .CodeMirror-scrollbar-filler { + width: 12px !important; + } +} +.platform-linux { + .CodeMirror-scrollbar-filler, + .CodeMirror-gutter-filler { + background-color: @background-color-3; + height: 12px !important; + } + .CodeMirror-scrollbar-filler { + width: 12px !important; + } +} + +.CodeMirror-linenumber { + color: @accent-comment; + min-width: 2.5em; + /*font-size: 0.9em;*/ /* restore after SourceCodePro font fix? */ + padding: 0 @code-padding 0 10px; /* left padding for project panel selection triangle */ +} +.CodeMirror-focused .CodeMirror-selected { + background: @selection-color-focused; +} + +/* + CodeMirror's use of descendant selectors for certain styling causes problems when editors are + nested because, for items in the inner editor, the left-hand clause in the selector will now + match either the actual containing CodeMirror instance *OR* the outer "host" CodeMirror instance. + + TODO (issue #324): We'll still have problems if editors can be nested more than one level deep, + or if any other descendant-selector-driven CM styles can differ between inner & outer editors + (potential problem areas include line wrap and coloring theme: basically, anything in codemirror.css + that uses a descandant selector where the CSS class name to the left of the space is something + other than a vanilla .CodeMirror) + */ +.CodeMirror { + div.CodeMirror-overwrite div.CodeMirror-cursor { + border-left: none !important; + border-bottom: 1px solid black !important; + width: 1.2ex; + } + + .CodeMirror { + background: transparent; + } + + .CodeMirror span.CodeMirror-matchingbracket { + /* Ensure visibility against gray inline editor background */ + background-color: @matching-bracket; + color: @accent-bracket !important; + } + + .CodeMirror .CodeMirror-cursors { + visibility: hidden; + } + .CodeMirror.CodeMirror-focused .CodeMirror-cursors { + visibility: visible; + } + + .CodeMirror .CodeMirror-selected { + background: @selection-color-unfocused; + } + .CodeMirror.CodeMirror-focused .CodeMirror-selected { + background: @selection-color-focused; + } + .CodeMirror .CodeMirror-gutters { + background: transparent; + border-right: none; + } + + .CodeMirror-scroll { + outline: none; + } + + .CodeMirror-sizer { + cursor: text; + } + + .CodeMirror .CodeMirror-vscrollbar, .CodeMirror .CodeMirror-hscrollbar { + cursor: default; + } + + .CodeMirror .CodeMirror-activeline-background { + background: transparent; + } + + .show-line-padding & .CodeMirror .CodeMirror-activeline-background { + box-shadow: none; + } + + .CodeMirror .CodeMirror-activeline .CodeMirror-gutter-elt { + background: transparent; + color: @accent-comment; + } + + .CodeMirror-focused .CodeMirror-activeline-background { + background: @activeline-bgcolor; + } + + .show-line-padding & .CodeMirror-focused .CodeMirror-activeline-background { + box-shadow: inset @code-padding 0 0 0 @tc-gray-panel-top-bar; + } + + .CodeMirror-focused .CodeMirror-activeline { + .CodeMirror-gutter-elt { + background: @tc-gray-panel-top-bar; + color: @bc-black; + } + } + + .CodeMirror-matchingtag { background: @matching-bracket; } +} + +/* + * Temporarily override bold and italic syntax highlighting until + * SourceCodePro supports them in a fixed pitch + */ +span.cm-em { + font-style: normal; +} +span.cm-header, span.cm-strong { + font-weight: normal; +} +span.cm-emstrong { + font-style: normal; + font-weight: normal; +} diff --git a/src/thirdparty/CodeMirror2 b/src/thirdparty/CodeMirror2 index 6c0cd2b56b5..64bee5830b6 160000 --- a/src/thirdparty/CodeMirror2 +++ b/src/thirdparty/CodeMirror2 @@ -1 +1 @@ -Subproject commit 6c0cd2b56b50837a010bd27f322a57edfbe9fee9 +Subproject commit 64bee5830b6f838c2c9be6dded98a5dac794dbcd diff --git a/src/view/ViewCommandHandlers.js b/src/view/ViewCommandHandlers.js index d36cbff4642..95f3511c63b 100644 --- a/src/view/ViewCommandHandlers.js +++ b/src/view/ViewCommandHandlers.js @@ -1,28 +1,28 @@ /* * Copyright (c) 2012 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 + * 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, + * 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 + * 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, window, $ */ +/*global define, $ */ /** * The ViewCommandHandlers object dispatches the following event(s): @@ -33,18 +33,18 @@ */ define(function (require, exports, module) { "use strict"; - + var Commands = require("command/Commands"), CommandManager = require("command/CommandManager"), - KeyBindingManager = require("command/KeyBindingManager"), Strings = require("strings"), - ProjectManager = require("project/ProjectManager"), + StringUtils = require("utils/StringUtils"), EditorManager = require("editor/EditorManager"), PreferencesManager = require("preferences/PreferencesManager"), DocumentManager = require("document/DocumentManager"), ThemeSettings = require("view/ThemeSettings"), AppInit = require("utils/AppInit"); + var prefs = PreferencesManager.getExtensionPrefs("brackets-fonts"); /** * @const @@ -52,6 +52,18 @@ define(function (require, exports, module) { */ var DYNAMIC_FONT_STYLE_ID = "codemirror-dynamic-fonts"; + /** + * @const + * @type {string} + */ + var DYNAMIC_FONT_FAMILY_ID = "codemirror-dynamic-font-family"; + + /** + * @const + * @type {string} + */ + var DYNAMIC_LINE_HEIGHT_ID = "codemirror-dynamic-line-height"; + /** * @const * @private @@ -59,7 +71,7 @@ define(function (require, exports, module) { * @type {number} */ var MIN_FONT_SIZE = 1; - + /** * @const * @private @@ -67,88 +79,160 @@ define(function (require, exports, module) { * @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 fontSizeStyle + * 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 line height + * @type {number} + */ + var DEFAULT_LINE_HEIGHT = 1.4; + + /** + * @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 = $("").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() { - $("#" + DYNAMIC_FONT_STYLE_ID).remove(); + _removeDynamicProperty(DYNAMIC_FONT_STYLE_ID); } - + /** * @private * Add the styles used to update the font size - * @param {string} fontSizeStyle A string with the font size and the size unit + * @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 _addDynamicFontSize(fontSizeStyle) { - var style = $("").attr("id", DYNAMIC_FONT_STYLE_ID); - style.html(".CodeMirror { font-size: " + fontSizeStyle + " !important; }"); - $("head").append(style); + function _addDynamicFontFamily(fontFamily) { + _addDynamicProperty(DYNAMIC_FONT_FAMILY_ID, "font-family", fontFamily); + } + + /** + * @private + * Removes the styles used to update the font family + */ + function _removeDynamicLineHeight() { + _removeDynamicProperty(DYNAMIC_LINE_HEIGHT_ID); + } + + /** + * @private + * Add the styles used to update the line height + * @param {string} lineHeight A string with the line height with size unit + */ + function _addDynamicLineHeight(lineHeight) { + _addDynamicProperty(DYNAMIC_LINE_HEIGHT_ID, "line-height", lineHeight, true, ".CodeMirror-lines > div"); } /** * @private * Sets the font size and restores the scroll position as best as possible. - * @param {string=} fontSizeStyle A string with the font size and the size unit + * @param {string=} fontSize A string with the font size and the size unit */ - function _setSizeAndRestoreScroll(fontSizeStyle) { + function _updateScroll(fontSize) { var editor = EditorManager.getCurrentFullEditor(), oldWidth = editor._codeMirror.defaultCharWidth(), - oldFontSize = $(".CodeMirror").css("font-size"), - newFontSize = "", + oldFontSize = prefs.get("fontSize"), + newFontSize = fontSize, delta = 0, adjustment = 0, scrollPos = editor.getScrollPos(), line = editor._codeMirror.lineAtHeight(scrollPos.y, "local"); - - _removeDynamicFontSize(); - if (fontSizeStyle) { - _addDynamicFontSize(fontSizeStyle); - } - editor.refreshAll(); - + delta = /em$/.test(oldFontSize) ? 10 : 1; - newFontSize = $(".CodeMirror").css("font-size"); 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) { - $(exports).triggerHandler("fontSizeChange", [adjustment, newFontSize]); - } + 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"); + // 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); + editor.setScrollPos(scrollPosX, scrollPosY); + } } - + /** * @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 + * @return {boolean} true if adjustment occurred, false if it did not occur */ function _adjustFontSize(adjustment) { - var fsStyle = $(".CodeMirror").css("font-size"), + 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, @@ -162,29 +246,35 @@ define(function (require, exports, module) { return false; } - _setSizeAndRestoreScroll(fsStr); - PreferencesManager.setViewState("fontSizeStyle", fsStr); - + 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() { - _setSizeAndRestoreScroll(); - PreferencesManager.setViewState("fontSizeStyle"); + setFontSize(DEFAULT_FONT_SIZE); } - - + + /** + * Initializes the different settings that need to loaded + */ + function init() { + _addDynamicFontFamily(prefs.get("fontFamily")); + _addDynamicFontSize(prefs.get("fontSize")); + _addDynamicLineHeight(prefs.get("lineHeight")); + _updateUI(); + } + /** * @private * Updates the user interface appropriately based on whether or not a document is @@ -205,13 +295,13 @@ define(function (require, exports, module) { CommandManager.get(Commands.VIEW_RESTORE_FONT_SIZE).setEnabled(false); } } - + /** * Restores the font size using the saved style and migrates the old fontSizeAdjustment - * view state to the new fontSizeStyle, when required + * view state to the new fontSize, when required */ function restoreFontSize() { - var fsStyle = PreferencesManager.getViewState("fontSizeStyle"), + var fsStyle = prefs.get("fontSize"), fsAdjustment = PreferencesManager.getViewState("fontSizeAdjustment"); if (fsAdjustment) { @@ -221,7 +311,7 @@ define(function (require, exports, module) { if (!fsStyle) { // Migrate the old view state to the new one. fsStyle = (DEFAULT_FONT_SIZE + fsAdjustment) + "px"; - PreferencesManager.setViewState("fontSizeStyle", fsStyle); + prefs.set("fontSize", fsStyle); } } @@ -231,6 +321,14 @@ define(function (require, exports, module) { } } + /** + * Restores the font size, font family, and line height back to factory settings. + */ + function restoreFonts() { + setFontFamily(DEFAULT_FONT_FAMILY); + setFontSize(DEFAULT_FONT_SIZE + "px"); + setLineHeight(DEFAULT_LINE_HEIGHT); + } /** @@ -244,14 +342,14 @@ define(function (require, exports, module) { 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. @@ -268,62 +366,162 @@ define(function (require, exports, module) { 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 + + // 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(); + /** + * 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) { + var oldValue = prefs.get("fontSize"); + + if (oldValue === fontSize) { + return; + } + + _removeDynamicFontSize(); + if (fontSize) { + _addDynamicFontSize(fontSize); + } + + if (EditorManager.getCurrentFullEditor()) { + _updateScroll(fontSize); + } + + $(exports).triggerHandler("fontSizeChange", [fontSize, oldValue]); + 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(), + oldValue = prefs.get("fontFamily"); + + if (oldValue === fontFamily) { + return; + } + + _removeDynamicFontFamily(); + if (fontFamily) { + _addDynamicFontFamily(fontFamily); + } + + $(exports).triggerHandler("fontFamilyChange", [fontFamily, oldValue]); + prefs.set("fontFamily", fontFamily); + + if (editor) { + editor.refreshAll(); + } } + /** + * 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"); + } + + + /** + * Line height setter to set the line height of the document editor + * @param {string} lineHeight The line height. The value is in 'em'. + */ + function setLineHeight(lineHeight) { + var editor = EditorManager.getCurrentFullEditor(), + oldValue = prefs.get("lineHeight"); + + // Make sure the incoming value is a number... Strip off any size units + lineHeight = parseFloat(lineHeight); + + if (oldValue === lineHeight) { + return; + } + + _removeDynamicLineHeight(); + if (lineHeight) { + _addDynamicLineHeight(lineHeight); + } + + $(exports).triggerHandler("lineHeightChange", [lineHeight, oldValue]); + prefs.set("lineHeight", lineHeight); + + if (editor) { + editor.refreshAll(); + } + } + + /** + * Line height getter to get the line height for the document editor + * @return {string} The line height with size unit as 'em' for the document editor + */ + function getLineHeight() { + return prefs.get("lineHeight"); + } + + + // TODO: remove /** * @private * Convert the old "fontSizeAdjustment" preference to the new view state. @@ -334,9 +532,9 @@ define(function (require, exports, module) { * @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" }; - } + //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); @@ -346,13 +544,26 @@ define(function (require, exports, module) { 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); + // TODO: remove + //PreferencesManager.convertPreferences(module, {"fontSizeAdjustment": "user"}, true, _convertToNewViewState); + + + prefs.definePreference("fontSize", "string", DEFAULT_FONT_SIZE + "px"); + prefs.definePreference("lineHeight", "number", DEFAULT_LINE_HEIGHT); + prefs.definePreference("fontFamily", "string", DEFAULT_FONT_FAMILY); // Update UI when opening or closing a document $(DocumentManager).on("currentDocumentChange", _updateUI); // Update UI when Brackets finishes loading - AppInit.appReady(_updateUI); - + AppInit.appReady(init); + exports.restoreFontSize = restoreFontSize; + exports.restoreFonts = restoreFonts; + exports.getFontSize = getFontSize; + exports.setFontSize = setFontSize; + exports.getFontFamily = getFontFamily; + exports.setFontFamily = setFontFamily; + exports.getLineHeight = getLineHeight; + exports.setLineHeight = setLineHeight; }); diff --git a/src/view/ViewCommandHandlers.js.orig b/src/view/ViewCommandHandlers.js.orig new file mode 100644 index 00000000000..a77bce0e5a3 --- /dev/null +++ b/src/view/ViewCommandHandlers.js.orig @@ -0,0 +1,635 @@ +/* + * Copyright (c) 2012 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, $ */ + +/** + * 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"), + 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"), + AppInit = require("utils/AppInit"); + +<<<<<<< HEAD + var prefs = PreferencesManager.getExtensionPrefs("brackets-fonts"); +======= +>>>>>>> master + + /** + * @const + * @type {string} + */ + var DYNAMIC_FONT_STYLE_ID = "codemirror-dynamic-fonts"; + + /** + * @const + * @type {string} + */ + var DYNAMIC_FONT_FAMILY_ID = "codemirror-dynamic-font-family"; + + /** + * @const + * @type {string} + */ + var DYNAMIC_LINE_HEIGHT_ID = "codemirror-dynamic-line-height"; + + /** + * @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; + +<<<<<<< HEAD + /** + * @const + * @private + * The default line height + * @type {number} + */ + var DEFAULT_LINE_HEIGHT = 1.4; + + /** + * @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 = $("").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); + } +======= +>>>>>>> master + + /** + * @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); + } + +<<<<<<< HEAD + /** + * @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 + * Removes the styles used to update the font family + */ + function _removeDynamicLineHeight() { + _removeDynamicProperty(DYNAMIC_LINE_HEIGHT_ID); + } + + /** + * @private + * Add the styles used to update the line height + * @param {string} lineHeight A string with the line height with size unit + */ + function _addDynamicLineHeight(lineHeight) { + _addDynamicProperty(DYNAMIC_LINE_HEIGHT_ID, "line-height", lineHeight, true, ".CodeMirror-lines > div"); + } + +======= +>>>>>>> master + /** + * @private + * Sets the font size and restores the scroll position as best as possible. + * @param {string=} fontSize A string with the font size and the size unit + */ + function _updateScroll(fontSize) { + var editor = EditorManager.getCurrentFullEditor(), + oldWidth = editor._codeMirror.defaultCharWidth(), + oldFontSize = prefs.get("fontSize"), + newFontSize = fontSize, + delta = 0, + adjustment = 0, + scrollPos = editor.getScrollPos(), + line = editor._codeMirror.lineAtHeight(scrollPos.y, "local"); +<<<<<<< HEAD + +======= + + _removeDynamicFontSize(); + if (fontSizeStyle) { + _addDynamicFontSize(fontSizeStyle); + } + editor.refreshAll(); + +>>>>>>> master + delta = /em$/.test(oldFontSize) ? 10 : 1; + adjustment = parseInt((parseFloat(newFontSize) - parseFloat(oldFontSize)) * delta, 10); + +<<<<<<< HEAD + // Only adjust the scroll position if there was any adjustments to the font size. + // Otherwise there will be unintended scrolling. + // +======= +>>>>>>> master + 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); + } +<<<<<<< HEAD +======= + + // 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); +>>>>>>> master + } + + /** + * @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; + } + +<<<<<<< HEAD + setFontSize(fsStr); +======= + _setSizeAndRestoreScroll(fsStr); + PreferencesManager.setViewState("fontSizeStyle", fsStr); + +>>>>>>> master + 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); + } +<<<<<<< HEAD + + /** + * Initializes the different settings that need to loaded + */ + function init() { + _addDynamicFontFamily(prefs.get("fontFamily")); + _addDynamicFontSize(prefs.get("fontSize")); + _addDynamicLineHeight(prefs.get("lineHeight")); + _updateUI(); + } + +======= + + +>>>>>>> master + /** + * @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); + } + } + + /** + * 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); + } + } + +<<<<<<< HEAD + /** + * Restores the font size, font family, and line height back to factory settings. + */ + function restoreFonts() { + setFontFamily(DEFAULT_FONT_FAMILY); + setFontSize(DEFAULT_FONT_SIZE + "px"); + setLineHeight(DEFAULT_LINE_HEIGHT); + } +======= +>>>>>>> master + + + /** + * @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); + } + +<<<<<<< HEAD + /** + * 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) { + var oldValue = prefs.get("fontSize"); + + if (oldValue === fontSize) { + return; + } + + _removeDynamicFontSize(); + if (fontSize) { + _addDynamicFontSize(fontSize); + } + + if (EditorManager.getCurrentFullEditor()) { + _updateScroll(fontSize); + } + + $(exports).triggerHandler("fontSizeChange", [fontSize, oldValue]); + 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(), + oldValue = prefs.get("fontFamily"); + + if (oldValue === fontFamily) { + return; + } + + _removeDynamicFontFamily(); + if (fontFamily) { + _addDynamicFontFamily(fontFamily); + } + + $(exports).triggerHandler("fontFamilyChange", [fontFamily, oldValue]); + prefs.set("fontFamily", fontFamily); + + if (editor) { + editor.refreshAll(); + } + } + + /** + * 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"); + } + + + /** + * Line height setter to set the line height of the document editor + * @param {string} lineHeight The line height. The value is in 'em'. + */ + function setLineHeight(lineHeight) { + var editor = EditorManager.getCurrentFullEditor(), + oldValue = prefs.get("lineHeight"); + + // Make sure the incoming value is a number... Strip off any size units + lineHeight = parseFloat(lineHeight); + + if (oldValue === lineHeight) { + return; + } + + _removeDynamicLineHeight(); + if (lineHeight) { + _addDynamicLineHeight(lineHeight); + } + + $(exports).triggerHandler("lineHeightChange", [lineHeight, oldValue]); + prefs.set("lineHeight", lineHeight); + + if (editor) { + editor.refreshAll(); + } + } + + /** + * Line height getter to get the line height for the document editor + * @return {string} The line height with size unit as 'em' for the document editor + */ + function getLineHeight() { + return prefs.get("lineHeight"); + } + + + // TODO: remove +======= + /** Open theme settings dialog */ + function _handleThemeSettings() { + ThemeSettings.showDialog(); + } + +>>>>>>> master + /** + * @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. + */ +<<<<<<< HEAD + //function _convertToNewViewState(key, value) { + // return { "fontSizeStyle": (DEFAULT_FONT_SIZE + value) + "px" }; + //} +======= + function _convertToNewViewState(key, value) { + return { "fontSizeStyle": (DEFAULT_FONT_SIZE + value) + "px" }; + } +>>>>>>> master + + // 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); + + // TODO: remove + //PreferencesManager.convertPreferences(module, {"fontSizeAdjustment": "user"}, true, _convertToNewViewState); + + + prefs.definePreference("fontSize", "string", DEFAULT_FONT_SIZE + "px"); + prefs.definePreference("lineHeight", "number", DEFAULT_LINE_HEIGHT); + prefs.definePreference("fontFamily", "string", DEFAULT_FONT_FAMILY); + + // Update UI when opening or closing a document + $(DocumentManager).on("currentDocumentChange", _updateUI); + + // Update UI when Brackets finishes loading +<<<<<<< HEAD + AppInit.appReady(init); + +======= + AppInit.appReady(_updateUI); + +>>>>>>> master + exports.restoreFontSize = restoreFontSize; + exports.restoreFonts = restoreFonts; + exports.getFontSize = getFontSize; + exports.setFontSize = setFontSize; + exports.getFontFamily = getFontFamily; + exports.setFontFamily = setFontFamily; + exports.getLineHeight = getLineHeight; + exports.setLineHeight = setLineHeight; +});