From ef6048cfbb4358e7c2620a7afe0bae7a0c7e5223 Mon Sep 17 00:00:00 2001 From: ficristo Date: Fri, 11 Dec 2015 23:02:47 +0100 Subject: [PATCH] ESLint: enabled no-trailing-spaces and eol-last rules --- .eslintrc | 5 +- Gruntfile.js | 2 +- src/LiveDevelopment/Agents/CSSAgent.js | 46 +- src/LiveDevelopment/Agents/ConsoleAgent.js | 28 +- src/LiveDevelopment/Agents/DOMAgent.js | 28 +- src/LiveDevelopment/Agents/DOMHelpers.js | 24 +- src/LiveDevelopment/Agents/DOMNode.js | 26 +- src/LiveDevelopment/Agents/EditAgent.js | 26 +- src/LiveDevelopment/Agents/GotoAgent.js | 26 +- src/LiveDevelopment/Agents/HighlightAgent.js | 36 +- src/LiveDevelopment/Agents/NetworkAgent.js | 26 +- src/LiveDevelopment/Agents/RemoteAgent.js | 32 +- src/LiveDevelopment/Agents/RemoteFunctions.js | 146 +- src/LiveDevelopment/Agents/ScriptAgent.js | 24 +- src/LiveDevelopment/Documents/CSSDocument.js | 52 +- .../Documents/CSSPreprocessorDocument.js | 40 +- src/LiveDevelopment/Documents/HTMLDocument.js | 84 +- src/LiveDevelopment/Documents/JSDocument.js | 28 +- src/LiveDevelopment/Inspector/Inspector.js | 42 +- src/LiveDevelopment/LiveDevMultiBrowser.js | 172 +- src/LiveDevelopment/LiveDevServerManager.js | 8 +- src/LiveDevelopment/LiveDevelopment.js | 226 +-- .../documents/LiveCSSDocument.js | 48 +- .../documents/LiveDocument.js | 98 +- .../documents/LiveHTMLDocument.js | 82 +- .../language/HTMLInstrumentation.js | 226 +-- .../language/HTMLSimpleDOM.js | 112 +- .../MultiBrowserImpl/launchers/Launcher.js | 38 +- .../launchers/node/LauncherDomain.js | 34 +- .../protocol/LiveDevProtocol.js | 92 +- .../protocol/remote/DocumentObserver.js | 114 +- .../protocol/remote/LiveDevProtocolRemote.js | 112 +- .../transports/NodeSocketTransport.js | 46 +- .../node/NodeSocketTransportDomain.js | 52 +- .../remote/NodeSocketTransportRemote.js | 44 +- src/LiveDevelopment/Servers/BaseServer.js | 38 +- src/LiveDevelopment/Servers/FileServer.js | 28 +- src/LiveDevelopment/Servers/UserServer.js | 28 +- src/LiveDevelopment/main.js | 58 +- src/brackets.js | 80 +- src/command/CommandManager.js | 32 +- src/command/Commands.js | 50 +- src/command/DefaultMenus.js | 66 +- src/command/KeyBindingManager.js | 338 ++-- src/command/Menus.js | 18 +- src/dependencies.js | 34 +- src/document/ChangedDocumentTracker.js | 44 +- src/document/Document.js | 184 +- src/document/DocumentCommandHandlers.js | 16 +- src/document/DocumentManager.js | 176 +- src/document/InMemoryFile.js | 58 +- src/document/TextRange.js | 76 +- src/editor/CSSInlineEditor.js | 84 +- src/editor/CodeHintList.js | 94 +- src/editor/CodeHintManager.js | 8 +- src/editor/Editor.js | 462 ++--- src/editor/EditorCommandHandlers.js | 190 +- src/editor/EditorManager.js | 256 +-- src/editor/EditorOptionHandlers.js | 50 +- src/editor/EditorStatusBar.js | 110 +- src/editor/ImageViewer.js | 186 +- src/editor/InlineTextEditor.js | 84 +- src/editor/InlineWidget.js | 42 +- src/editor/MultiRangeInlineEditor.js | 240 +-- src/extensibility/ExtensionManager.js | 10 +- src/extensibility/ExtensionManagerDialog.js | 122 +- src/extensibility/ExtensionManagerView.js | 86 +- .../ExtensionManagerViewModel.js | 124 +- src/extensibility/InstallExtensionDialog.js | 112 +- src/extensibility/Package.js | 124 +- .../node/ExtensionManagerDomain.js | 78 +- src/extensibility/node/package-validator.js | 46 +- .../node/spec/Installation.spec.js | 78 +- .../node/spec/Validation.spec.js | 68 +- src/extensibility/registry_utils.js | 42 +- src/extensions/default/CSSCodeHints/main.js | 146 +- .../default/CSSCodeHints/unittests.js | 164 +- src/extensions/default/CloseOthers/main.js | 64 +- .../CloseOthers/unittest-files/dummy.js | 2 +- .../default/CloseOthers/unittests.js | 36 +- .../default/CommandLineTool/main.js | 46 +- .../default/DebugCommands/NodeDebugUtils.js | 48 +- src/extensions/default/DebugCommands/main.js | 94 +- src/extensions/default/HTMLCodeHints/main.js | 148 +- .../default/HTMLCodeHints/unittests.js | 198 +- .../default/HealthData/HealthDataManager.js | 12 +- .../HealthData/HealthDataNotification.js | 10 +- .../default/HealthData/HealthDataPopup.js | 4 +- .../default/HealthData/HealthDataPreview.js | 22 +- .../default/HealthData/HealthDataUtils.js | 22 +- src/extensions/default/HealthData/main.js | 42 +- .../default/HealthData/unittests.js | 24 +- .../default/HtmlEntityCodeHints/main.js | 98 +- .../default/HtmlEntityCodeHints/unittests.js | 62 +- .../default/InlineColorEditor/ColorEditor.js | 108 +- .../InlineColorEditor/InlineColorEditor.js | 90 +- .../default/InlineColorEditor/main.js | 62 +- .../default/InlineColorEditor/unittests.js | 200 +-- .../BezierCurveEditor.js | 42 +- .../InlineTimingFunctionEditor.js | 80 +- .../InlineTimingFunctionEditor/StepEditor.js | 42 +- .../TimingFunctionUtils.js | 38 +- .../InlineTimingFunctionEditor/main.js | 32 +- .../InlineTimingFunctionEditor/unittests.js | 88 +- src/extensions/default/JSLint/main.js | 60 +- src/extensions/default/JSLint/unittests.js | 50 +- .../default/JavaScriptCodeHints/HintUtils.js | 42 +- .../default/JavaScriptCodeHints/HintUtils2.js | 26 +- .../default/JavaScriptCodeHints/MessageIds.js | 24 +- .../ParameterHintManager.js | 12 +- .../JavaScriptCodeHints/Preferences.js | 24 +- .../JavaScriptCodeHints/ScopeManager.js | 196 +- .../default/JavaScriptCodeHints/Session.js | 94 +- .../default/JavaScriptCodeHints/main.js | 148 +- .../JavaScriptCodeHints/tern-worker.js | 96 +- .../default/JavaScriptCodeHints/unittests.js | 304 ++-- .../default/JavaScriptQuickEdit/main.js | 60 +- .../default/JavaScriptQuickEdit/unittests.js | 146 +- src/extensions/default/LESSSupport/main.js | 28 +- src/extensions/default/PrefsCodeHints/main.js | 112 +- .../default/PrefsCodeHints/unittests.js | 180 +- src/extensions/default/QuickOpenCSS/main.js | 28 +- src/extensions/default/QuickOpenHTML/main.js | 38 +- .../default/QuickOpenJavaScript/main.js | 34 +- src/extensions/default/QuickView/main.js | 180 +- src/extensions/default/QuickView/unittests.js | 14 +- src/extensions/default/RecentProjects/main.js | 8 +- .../default/RecentProjects/unittests.js | 16 +- src/extensions/default/SVGCodeHints/main.js | 80 +- .../default/SVGCodeHints/unittests.js | 180 +- .../default/StaticServer/StaticServer.js | 52 +- src/extensions/default/StaticServer/main.js | 32 +- .../StaticServer/node/StaticServerDomain.js | 78 +- .../default/StaticServer/unittests.js | 176 +- src/extensions/default/UrlCodeHints/main.js | 52 +- .../default/UrlCodeHints/unittests.js | 162 +- .../WebPlatformDocs/InlineDocsViewer.js | 78 +- .../default/WebPlatformDocs/main.js | 60 +- .../default/WebPlatformDocs/unittests.js | 96 +- .../samples/BracketsConfigCentral/main.js | 54 +- .../samples/ContextMenuTest/main.js | 32 +- .../InlineImageViewer/InlineImageViewer.js | 44 +- .../samples/InlineImageViewer/main.js | 66 +- .../samples/LocalizationExample/main.js | 28 +- .../LocalizationExample/nls/root/strings.js | 24 +- .../LocalizationExample/nls/strings.js | 30 +- .../samples/LocalizationExample/strings.js | 28 +- .../samples/TypingSpeedLogger/main.js | 48 +- .../samples/circular_dependency_test/main.js | 24 +- .../circular_dependency_test/secondary.js | 24 +- src/file/FileUtils.js | 114 +- src/filesystem/Directory.js | 84 +- src/filesystem/File.js | 72 +- src/filesystem/FileIndex.js | 66 +- src/filesystem/FileSystem.js | 286 +-- src/filesystem/FileSystemEntry.js | 166 +- src/filesystem/FileSystemError.js | 24 +- src/filesystem/FileSystemStats.js | 40 +- src/filesystem/WatchedRoot.js | 36 +- .../impls/appshell/AppshellFileSystem.js | 146 +- .../impls/appshell/node/FileWatcherDomain.js | 48 +- src/help/HelpCommandHandlers.js | 42 +- src/language/CSSUtils.js | 380 ++-- src/language/CodeInspection.js | 70 +- src/language/HTMLDOMDiff.js | 172 +- src/language/HTMLInstrumentation.js | 222 +-- src/language/HTMLSimpleDOM.js | 110 +- src/language/HTMLTokenizer.js | 102 +- src/language/HTMLUtils.js | 154 +- src/language/JSONUtils.js | 82 +- src/language/JSUtils.js | 126 +- src/language/LanguageManager.js | 302 ++-- src/language/XMLUtils.js | 84 +- src/nls/cs/strings.js | 2 +- src/nls/cs/urls.js | 26 +- src/nls/da/strings.js | 58 +- src/nls/da/urls.js | 24 +- src/nls/de/urls.js | 24 +- src/nls/el/strings.js | 46 +- src/nls/el/urls.js | 24 +- src/nls/es/strings.js | 120 +- src/nls/es/urls.js | 24 +- src/nls/fa-ir/strings.js | 2 +- src/nls/fa-ir/urls.js | 4 +- src/nls/fi/strings.js | 2 +- src/nls/fi/urls.js | 24 +- src/nls/fr/urls.js | 24 +- src/nls/gl/strings.js | 80 +- src/nls/hr/strings.js | 62 +- src/nls/hu/strings.js | 60 +- src/nls/id/strings.js | 28 +- src/nls/it/strings.js | 66 +- src/nls/it/urls.js | 24 +- src/nls/ja/urls.js | 24 +- src/nls/ko/strings.js | 54 +- src/nls/ko/urls.js | 24 +- src/nls/nb/strings.js | 6 +- src/nls/nb/urls.js | 26 +- src/nls/nl/urls.js | 24 +- src/nls/pl/urls.js | 24 +- src/nls/pt-pt/strings.js | 6 +- src/nls/root/strings-app.js | 24 +- src/nls/root/urls.js | 24 +- src/nls/ru/urls.js | 24 +- src/nls/sk/strings.js | 34 +- src/nls/sr/strings-app.js | 24 +- src/nls/strings-app.js | 24 +- src/nls/sv/strings.js | 54 +- src/nls/sv/urls.js | 24 +- src/nls/tr/strings.js | 48 +- src/nls/tr/urls.js | 24 +- src/nls/urls.js | 24 +- src/nls/zh-cn/strings.js | 36 +- src/nls/zh-cn/urls.js | 26 +- src/nls/zh-tw/urls.js | 24 +- src/preferences/PreferenceStorage.js | 88 +- src/preferences/PreferencesBase.js | 582 +++--- src/preferences/PreferencesDialogs.js | 34 +- src/preferences/PreferencesImpl.js | 24 +- src/preferences/PreferencesManager.js | 142 +- src/project/FileSyncManager.js | 138 +- src/project/FileTreeView.js | 4 +- src/project/FileTreeViewModel.js | 72 +- src/project/FileViewController.js | 86 +- src/project/ProjectManager.js | 72 +- src/project/ProjectModel.js | 68 +- src/project/SidebarView.js | 96 +- src/project/WorkingSetSort.js | 122 +- src/project/WorkingSetView.js | 334 ++-- src/search/FileFilters.js | 150 +- src/search/FindBar.js | 118 +- src/search/FindInFiles.js | 142 +- src/search/FindInFilesUI.js | 86 +- src/search/FindReplace.js | 158 +- src/search/FindUtils.js | 56 +- src/search/QuickOpen.js | 152 +- src/search/QuickSearchField.js | 104 +- src/search/ScrollTrackMarkers.js | 78 +- src/search/SearchModel.js | 60 +- src/search/SearchResultsView.js | 114 +- src/search/node/FindInFilesDomain.js | 58 +- src/strings.js | 34 +- src/utils/AnimationUtils.js | 48 +- src/utils/AppInit.js | 38 +- src/utils/Async.js | 158 +- src/utils/BuildInfoUtils.js | 44 +- src/utils/ColorUtils.js | 26 +- src/utils/DeprecationWarning.js | 74 +- src/utils/DragAndDrop.js | 76 +- src/utils/DropdownEventHandler.js | 74 +- src/utils/EventDispatcher.js | 74 +- src/utils/ExtensionLoader.js | 104 +- src/utils/ExtensionUtils.js | 72 +- src/utils/Global.js | 50 +- src/utils/KeyEvent.js | 26 +- src/utils/NativeApp.js | 48 +- src/utils/NodeConnection.js | 128 +- src/utils/NodeDomain.js | 96 +- src/utils/PerfUtils.js | 94 +- src/utils/Resizer.js | 148 +- src/utils/ShellAPI.js | 40 +- src/utils/StringMatch.js | 268 +-- src/utils/StringUtils.js | 40 +- src/utils/TokenUtils.js | 50 +- src/utils/UpdateNotification.js | 62 +- src/utils/UrlParams.js | 58 +- src/utils/ValidationUtils.js | 30 +- src/utils/ViewUtils.js | 138 +- src/view/MainViewFactory.js | 48 +- src/view/MainViewManager.js | 486 ++--- src/view/Pane.js | 432 ++--- src/view/PanelManager.js | 34 +- src/view/ThemeManager.js | 4 +- src/view/ThemeSettings.js | 2 +- src/view/ViewCommandHandlers.js | 6 +- src/view/ViewStateManager.js | 20 +- src/view/WorkspaceManager.js | 148 +- src/widgets/DefaultDialogs.js | 26 +- src/widgets/Dialogs.js | 74 +- src/widgets/DropdownButton.js | 92 +- src/widgets/ModalBar.js | 88 +- src/widgets/PopUpManager.js | 64 +- src/widgets/StatusBar.js | 86 +- src/xorigin.js | 2 +- tasks/build.js | 88 +- tasks/lib/common.js | 28 +- tasks/test.js | 28 +- tasks/write-config.js | 32 +- test/BootstrapReporterView.js | 156 +- test/PerformanceTestSuite.js | 28 +- test/SpecRunner.js | 98 +- test/TestPreferencesImpl.js | 18 +- test/UnitTestReporter.js | 144 +- test/node/TestingDomain.js | 26 +- test/perf/Performance-test.js | 46 +- test/spec/Async-test.js | 236 +-- test/spec/CSSInlineEdit-test.js | 64 +- test/spec/CSSUtils-test.js | 762 ++++---- test/spec/CodeHint-test.js | 112 +- test/spec/CodeHintUtils-test.js | 122 +- test/spec/CodeInspection-test.js | 162 +- test/spec/CommandManager-test.js | 30 +- test/spec/Document-test.js | 158 +- test/spec/DocumentCommandHandlers-test.js | 304 ++-- test/spec/DocumentManager-test.js | 50 +- test/spec/DragAndDrop-test.js | 50 +- test/spec/Editor-test.js | 332 ++-- test/spec/EditorCommandHandlers-test.js | 1586 ++++++++--------- test/spec/EditorManager-test.js | 30 +- test/spec/EditorOptionHandlers-test.js | 194 +- test/spec/EditorRedraw-test.js | 48 +- test/spec/EventDispatcher-test.js | 190 +- test/spec/ExtensionInstallation-test.js | 88 +- test/spec/ExtensionLoader-test.js | 2 +- test/spec/ExtensionManager-test.js | 326 ++-- test/spec/ExtensionUtils-test.js | 48 +- test/spec/FileFilters-test.js | 116 +- test/spec/FileSystem-test.js | 462 ++--- test/spec/FileTreeView-test.js | 78 +- test/spec/FileTreeViewModel-test.js | 36 +- test/spec/FileUtils-test.js | 6 +- test/spec/FindInFiles-test.js | 200 +-- test/spec/FindReplace-test.js | 514 +++--- test/spec/HTMLInstrumentation-test.js | 460 ++--- test/spec/HTMLSimpleDOM-test.js | 50 +- test/spec/HTMLTokenizer-test.js | 40 +- test/spec/InlineEditorProviders-test.js | 492 ++--- test/spec/InstallExtensionDialog-test.js | 138 +- test/spec/JSONUtils-test.js | 26 +- test/spec/JSUtils-test.js | 162 +- test/spec/KeyBindingManager-test.js | 296 +-- test/spec/LanguageManager-test.js | 378 ++-- test/spec/LiveDevelopment-test.js | 464 ++--- test/spec/LiveDevelopmentMultiBrowser-test.js | 86 +- test/spec/LowLevelFileIO-test.js | 526 +++--- test/spec/MainViewFactory-test.js | 34 +- test/spec/MainViewManager-test.js | 62 +- test/spec/Menu-test.js | 90 +- test/spec/MockFileSystemImpl.js | 88 +- test/spec/MockFileSystemModel.js | 56 +- test/spec/MultiRangeInlineEditor-test.js | 264 +-- test/spec/NativeMenu-test.js | 494 ++--- test/spec/NodeConnection-test.js | 72 +- test/spec/Pane-test.js | 162 +- test/spec/PhantomHelper.js | 32 +- test/spec/PreferencesBase-test.js | 472 ++--- test/spec/PreferencesManager-test.js | 72 +- test/spec/ProjectManager-test.js | 22 +- test/spec/ProjectModel-test.js | 198 +- test/spec/QuickOpen-test.js | 78 +- test/spec/QuickSearchField-test.js | 114 +- test/spec/RemoteFunctions-test.js | 188 +- test/spec/SpecRunnerUtils.js | 338 ++-- test/spec/StringMatch-test.js | 290 +-- test/spec/StringUtils-test.js | 42 +- test/spec/TextRange-test.js | 54 +- test/spec/UpdateNotification-test.js | 28 +- test/spec/UrlParams-test.js | 114 +- test/spec/ValidationUtils-test.js | 28 +- test/spec/ViewCommandHandlers-test.js | 78 +- test/spec/ViewFactory-test.js | 24 +- test/spec/ViewUtils-test.js | 66 +- test/spec/WorkingSetSort-test.js | 58 +- test/spec/WorkingSetView-test.js | 114 +- test/spec/XMLUtils-test.js | 126 +- 365 files changed, 18356 insertions(+), 18357 deletions(-) diff --git a/.eslintrc b/.eslintrc index cdb5257c694..0433f49400c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -48,14 +48,13 @@ "valid-jsdoc": 0, "valid-typeof": 2, - "no-trailing-spaces": 0, - "eol-last": 0 + "no-trailing-spaces": 2, + "eol-last": 2 }, "globals": { "brackets": false, "window": false, - // Resemble a browser environment. "alert": false, "document": false, "localStorage": false, diff --git a/Gruntfile.js b/Gruntfile.js index 883fd3a9a69..393ef3d629a 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -304,7 +304,7 @@ module.exports = function (grunt) { src: '<%= meta.src %>', test: '<%= meta.test %>', options: { - configFile: '.eslintrc' + quiet: true } }, shell: { diff --git a/src/LiveDevelopment/Agents/CSSAgent.js b/src/LiveDevelopment/Agents/CSSAgent.js index 12e2e38c981..88049aee349 100644 --- a/src/LiveDevelopment/Agents/CSSAgent.js +++ b/src/LiveDevelopment/Agents/CSSAgent.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -54,7 +54,7 @@ define(function CSSAgent(require, exports, module) { */ var _getAllStyleSheetsNotFound; - /** + /** * Create a canonicalized version of the given URL, stripping off query strings and hashes. * @param {string} url the URL to canonicalize * @return the canonicalized URL @@ -125,7 +125,7 @@ define(function CSSAgent(require, exports, module) { function clearCSSForDocument(doc) { return reloadCSSForDocument(doc, ""); } - + /** * @private * @param {jQuery.Event} event @@ -136,7 +136,7 @@ define(function CSSAgent(require, exports, module) { existing = styleForURL(res.header.sourceURL), styleSheetId = res.header.styleSheetId, duplicate; - + // detect duplicates duplicate = _.some(existing, function (styleSheet) { return styleSheet && styleSheet.styleSheetId === styleSheetId; @@ -144,13 +144,13 @@ define(function CSSAgent(require, exports, module) { if (duplicate) { return; } - + _styleSheetDetails[styleSheetId] = res.header; _styleSheetDetails[styleSheetId].canonicalizedURL = url; // canonicalized URL - + exports.trigger("styleSheetAdded", url, res.header); } - + /** * @private * @param {jQuery.Event} event @@ -158,12 +158,12 @@ define(function CSSAgent(require, exports, module) { */ function _styleSheetRemoved(event, res) { var header = _styleSheetDetails[res.styleSheetId]; - + delete _styleSheetDetails[res.styleSheetId]; - + exports.trigger("styleSheetRemoved", header.canonicalizedURL, header); } - + /** * @private * Attempt to use deleted API CSS.getAllStyleSheets @@ -226,8 +226,8 @@ define(function CSSAgent(require, exports, module) { Inspector.Page.off(".CSSAgent"); Inspector.CSS.off(".CSSAgent"); } - - + + EventDispatcher.makeEventDispatcher(exports); // Export public functions diff --git a/src/LiveDevelopment/Agents/ConsoleAgent.js b/src/LiveDevelopment/Agents/ConsoleAgent.js index 161d1030372..f667256718f 100644 --- a/src/LiveDevelopment/Agents/ConsoleAgent.js +++ b/src/LiveDevelopment/Agents/ConsoleAgent.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -74,7 +74,7 @@ define(function ConsoleAgent(require, exports, module) { function _onMessagesCleared(event, res) { // res = {} } - + /** * Enable the inspector Console domain * @return {jQuery.Promise} A promise resolved when the Console.enable() command is successful. @@ -100,4 +100,4 @@ define(function ConsoleAgent(require, exports, module) { exports.enable = enable; exports.load = load; exports.unload = unload; -}); \ No newline at end of file +}); diff --git a/src/LiveDevelopment/Agents/DOMAgent.js b/src/LiveDevelopment/Agents/DOMAgent.js index 8ea693bc11a..78eeecf2d76 100644 --- a/src/LiveDevelopment/Agents/DOMAgent.js +++ b/src/LiveDevelopment/Agents/DOMAgent.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -321,8 +321,8 @@ define(function DOMAgent(require, exports, module) { Inspector.Page.off(".DOMAgent"); Inspector.DOM.off(".DOMAgent"); } - - + + EventDispatcher.makeEventDispatcher(exports); // Export private functions diff --git a/src/LiveDevelopment/Agents/DOMHelpers.js b/src/LiveDevelopment/Agents/DOMHelpers.js index 96121762c93..a74b89762d0 100644 --- a/src/LiveDevelopment/Agents/DOMHelpers.js +++ b/src/LiveDevelopment/Agents/DOMHelpers.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ diff --git a/src/LiveDevelopment/Agents/DOMNode.js b/src/LiveDevelopment/Agents/DOMNode.js index 31927e6c135..0a63ea99dc2 100644 --- a/src/LiveDevelopment/Agents/DOMNode.js +++ b/src/LiveDevelopment/Agents/DOMNode.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -520,4 +520,4 @@ define(function DOMNodeModule(require, exports, module) { }; return DOMNode; -}); \ No newline at end of file +}); diff --git a/src/LiveDevelopment/Agents/EditAgent.js b/src/LiveDevelopment/Agents/EditAgent.js index fd73ff49cec..e839360935d 100644 --- a/src/LiveDevelopment/Agents/EditAgent.js +++ b/src/LiveDevelopment/Agents/EditAgent.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -134,4 +134,4 @@ define(function EditAgent(require, exports, module) { // Export public functions exports.load = load; exports.unload = unload; -}); \ No newline at end of file +}); diff --git a/src/LiveDevelopment/Agents/GotoAgent.js b/src/LiveDevelopment/Agents/GotoAgent.js index 59020aeeab9..5174f8d84a2 100644 --- a/src/LiveDevelopment/Agents/GotoAgent.js +++ b/src/LiveDevelopment/Agents/GotoAgent.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -40,7 +40,7 @@ define(function GotoAgent(require, exports, module) { EditorManager = require("editor/EditorManager"), CommandManager = require("command/CommandManager"), Commands = require("command/Commands"); - + /** Return the URL without the query string * @param {string} URL diff --git a/src/LiveDevelopment/Agents/HighlightAgent.js b/src/LiveDevelopment/Agents/HighlightAgent.js index 900461c033d..a9ec579f400 100644 --- a/src/LiveDevelopment/Agents/HighlightAgent.js +++ b/src/LiveDevelopment/Agents/HighlightAgent.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -72,7 +72,7 @@ define(function HighlightAgent(require, exports, module) { if (!LiveDevelopment.config.experimental) { return; } - + if (!Inspector.config.highlight) { return; } @@ -108,7 +108,7 @@ define(function HighlightAgent(require, exports, module) { _highlight = {type: "css", ref: name}; RemoteAgent.call("highlightRule", name); } - + /** Highlight all nodes with 'data-brackets-id' value * that matches id, or if id is an array, matches any of the given ids. * @param {string|Array} value of the 'data-brackets-id' to match, @@ -127,7 +127,7 @@ define(function HighlightAgent(require, exports, module) { }); rule(selector); } - + /** * Redraw active highlights */ @@ -148,8 +148,8 @@ define(function HighlightAgent(require, exports, module) { RemoteAgent.off(".HighlightAgent"); } } - - + + EventDispatcher.makeEventDispatcher(exports); // Export public functions @@ -160,4 +160,4 @@ define(function HighlightAgent(require, exports, module) { exports.redraw = redraw; exports.load = load; exports.unload = unload; -}); \ No newline at end of file +}); diff --git a/src/LiveDevelopment/Agents/NetworkAgent.js b/src/LiveDevelopment/Agents/NetworkAgent.js index b1f8c57b1ad..6d36d2d7288 100644 --- a/src/LiveDevelopment/Agents/NetworkAgent.js +++ b/src/LiveDevelopment/Agents/NetworkAgent.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -77,7 +77,7 @@ define(function NetworkAgent(require, exports, module) { } _logURL(res.frame.url); } - + /** * Enable the inspector Network domain * @return {jQuery.Promise} A promise resolved when the Network.enable() command is successful. diff --git a/src/LiveDevelopment/Agents/RemoteAgent.js b/src/LiveDevelopment/Agents/RemoteAgent.js index 6050b261bb0..01a97d1b88d 100644 --- a/src/LiveDevelopment/Agents/RemoteAgent.js +++ b/src/LiveDevelopment/Agents/RemoteAgent.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -120,7 +120,7 @@ define(function RemoteAgent(require, exports, module) { call("keepAlive"); }, 1000); } - + // WebInspector Event: Page.frameNavigated function _onFrameNavigated(event, res) { // res = {frame} @@ -162,10 +162,10 @@ define(function RemoteAgent(require, exports, module) { Inspector.DOM.off(".RemoteAgent"); _stopKeepAliveInterval(); } - - + + EventDispatcher.makeEventDispatcher(exports); - + // Export public functions exports.call = call; exports.load = load; diff --git a/src/LiveDevelopment/Agents/RemoteFunctions.js b/src/LiveDevelopment/Agents/RemoteFunctions.js index 43638ee74ad..41147c47ef0 100644 --- a/src/LiveDevelopment/Agents/RemoteFunctions.js +++ b/src/LiveDevelopment/Agents/RemoteFunctions.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -36,15 +36,15 @@ function RemoteFunctions(experimental) { "use strict"; var lastKeepAliveTime = Date.now(); - + /** * @type {DOMEditHandler} */ var _editHandler; - + var HIGHLIGHT_CLASSNAME = "__brackets-ld-highlight", KEEP_ALIVE_TIMEOUT = 3000; // Keep alive timeout value, in milliseconds - + // determine whether an event should be processed for Live Development function _validEvent(event) { if (navigator.platform.substr(0, 3) === "Mac") { @@ -240,14 +240,14 @@ function RemoteFunctions(experimental) { var elementBounds = element.getBoundingClientRect(), highlight = window.document.createElement("div"), styles = window.getComputedStyle(element); - + // Don't highlight elements with 0 width & height if (elementBounds.width === 0 && elementBounds.height === 0) { return; } - + highlight.className = HIGHLIGHT_CLASSNAME; - + var offset = _screenOffset(element); var stylesToSet = { @@ -270,27 +270,27 @@ function RemoteFunctions(experimental) { "box-shadow": "0 0 1px #fff", "box-sizing": "border-box" }; - + var animateStartValues = { "background-color": "rgba(0, 162, 255, 0.5)", "opacity": 0 }; - + var animateEndValues = { "background-color": "rgba(0, 162, 255, 0)", "opacity": 1 }; - + var transitionValues = { "-webkit-transition-property": "opacity, background-color", "-webkit-transition-duration": "300ms, 2.3s", "transition-property": "opacity, background-color", "transition-duration": "300ms, 2.3s" }; - + function _setStyleValues(styleValues, obj) { var prop; - + for (prop in styleValues) { obj.setProperty(prop, styleValues[prop]); } @@ -301,19 +301,19 @@ function RemoteFunctions(experimental) { doAnimation ? animateStartValues : animateEndValues, highlight.style ); - - + + if (doAnimation) { _setStyleValues(transitionValues, highlight.style); - + window.setTimeout(function () { _setStyleValues(animateEndValues, highlight.style); }, 20); } - + window.document.body.appendChild(highlight); }, - + add: function (element, doAnimation) { if (this._elementExists(element) || element === document) { return; @@ -322,14 +322,14 @@ function RemoteFunctions(experimental) { _trigger(element, "highlight", 1); } this.elements.push(element); - + this._makeHighlightDiv(element, doAnimation); }, clear: function () { var i, highlights = window.document.querySelectorAll("." + HIGHLIGHT_CLASSNAME), body = window.document.body; - + for (i = 0; i < highlights.length; i++) { body.removeChild(highlights[i]); } @@ -339,13 +339,13 @@ function RemoteFunctions(experimental) { _trigger(this.elements[i], "highlight", 0); } } - + this.elements = []; }, - + redraw: function () { var i, highlighted; - + // When redrawing a selector-based highlight, run a new selector // query to ensure we have the latest set of elements to highlight. if (this.selector) { @@ -353,7 +353,7 @@ function RemoteFunctions(experimental) { } else { highlighted = this.elements.slice(0); } - + this.clear(); for (i = 0; i < highlighted.length; i++) { this.add(highlighted[i], false); @@ -443,7 +443,7 @@ function RemoteFunctions(experimental) { function keepAlive() { lastKeepAliveTime = Date.now(); } - + // show goto function showGoto(targets) { if (!_currentMenu) { @@ -485,18 +485,18 @@ function RemoteFunctions(experimental) { } _remoteHighlight.selector = rule; } - + // redraw active highlights function redrawHighlights() { if (_remoteHighlight) { _remoteHighlight.redraw(); } } - + window.addEventListener("resize", redrawHighlights); // Add a capture-phase scroll listener to update highlights when // any element scrolls. - + function _scrollHandler(e) { // Document scrolls can be updated immediately. Any other scrolls // need to be updated on a timer to ensure the layout is correct. @@ -508,23 +508,23 @@ function RemoteFunctions(experimental) { } } } - + window.addEventListener("scroll", _scrollHandler, true); - + var aliveTest = window.setInterval(function () { if (Date.now() > lastKeepAliveTime + KEEP_ALIVE_TIMEOUT) { // Remove highlights hideHighlight(); - + // Remove listeners window.removeEventListener("resize", redrawHighlights); window.removeEventListener("scroll", _scrollHandler, true); - + // Clear this interval window.clearInterval(aliveTest); } }, 1000); - + /** * Constructor * @param {Document} htmlDocument @@ -545,15 +545,15 @@ function RemoteFunctions(experimental) { if (!id) { return null; } - + if (this.rememberedNodes && this.rememberedNodes[id]) { return this.rememberedNodes[id]; } - + var results = this.htmlDocument.querySelectorAll("[data-brackets-id='" + id + "']"); return results && results[0]; }; - + /** * @private * Insert a new child element @@ -564,13 +564,13 @@ function RemoteFunctions(experimental) { DOMEditHandler.prototype._insertChildNode = function (targetElement, childElement, edit) { var before = this._queryBracketsID(edit.beforeID), after = this._queryBracketsID(edit.afterID); - + if (edit.firstChild) { before = targetElement.firstChild; } else if (edit.lastChild) { after = targetElement.lastChild; } - + if (before) { targetElement.insertBefore(childElement, before); } else if (after && (after !== targetElement.lastChild)) { @@ -579,7 +579,7 @@ function RemoteFunctions(experimental) { targetElement.appendChild(childElement); } }; - + /** * @private * Given a string containing encoded entity references, returns the string with the entities decoded. @@ -595,7 +595,7 @@ function RemoteFunctions(experimental) { this.entityParseParent.textContent = ""; return result; }; - + /** * @private * @param {Node} node @@ -604,7 +604,7 @@ function RemoteFunctions(experimental) { function _isRawTextNode(node) { return (node.nodeType === Node.ELEMENT_NODE && /script|style|noscript|noframes|noembed|iframe|xmp/i.test(node.tagName)); } - + /** * @private * Replace a range of text and comment nodes with an optional new text node @@ -631,7 +631,7 @@ function RemoteFunctions(experimental) { } return node; } - + var start = (edit.afterID) ? this._queryBracketsID(edit.afterID) : null, startMissing = edit.afterID && !start, end = (edit.beforeID) ? this._queryBracketsID(edit.beforeID) : null, @@ -642,7 +642,7 @@ function RemoteFunctions(experimental) { textNode = (edit.content !== undefined) ? this.htmlDocument.createTextNode(_isRawTextNode(targetElement) ? edit.content : this._parseEntities(edit.content)) : null, lastRemovedWasText, isText; - + // remove all nodes inside the range while (current && (current !== end)) { isText = current.nodeType === Node.TEXT_NODE; @@ -668,7 +668,7 @@ function RemoteFunctions(experimental) { current = next; } } - + if (textNode) { // OK to use nextSibling here (not nextIgnoringHighlights) because we do literally // want to insert immediately after the start tag. @@ -681,7 +681,7 @@ function RemoteFunctions(experimental) { } } }; - + /** * @private * Apply an array of DOM edits to the document @@ -692,12 +692,12 @@ function RemoteFunctions(experimental) { targetElement, childElement, self = this; - + this.rememberedNodes = {}; - + edits.forEach(function (edit) { var editIsSpecialTag = edit.type === "elementInsert" && (edit.tag === "html" || edit.tag === "head" || edit.tag === "body"); - + if (edit.type === "rememberNodes") { edit.tagIDs.forEach(function (tagID) { var node = self._queryBracketsID(tagID); @@ -710,15 +710,15 @@ function RemoteFunctions(experimental) { }); return; } - + targetID = edit.type.match(/textReplace|textDelete|textInsert|elementInsert|elementMove/) ? edit.parentID : edit.tagID; targetElement = self._queryBracketsID(targetID); - + if (!targetElement && !editIsSpecialTag) { console.error("data-brackets-id=" + targetID + " not found"); return; } - + switch (edit.type) { case "attrChange": case "attrAdd": @@ -748,12 +748,12 @@ function RemoteFunctions(experimental) { if (!editIsSpecialTag) { childElement = self.htmlDocument.createElement(edit.tag); } - + Object.keys(edit.attributes).forEach(function (attr) { childElement.setAttribute(attr, self._parseEntities(edit.attributes[attr])); }); childElement.setAttribute("data-brackets-id", edit.tagID); - + if (!editIsSpecialTag) { self._insertChildNode(targetElement, childElement, edit); } @@ -772,17 +772,17 @@ function RemoteFunctions(experimental) { break; } }); - + this.rememberedNodes = {}; - + // update highlight after applying diffs redrawHighlights(); }; - + function applyDOMEdits(edits) { _editHandler.apply(edits); } - + /** * * @param {Element} elem @@ -793,18 +793,18 @@ function RemoteFunctions(experimental) { len, node, value; - + len = elem.attributes.length; for (i = 0; i < len; i++) { node = elem.attributes.item(i); value = (node.name === "data-brackets-id") ? parseInt(node.value, 10) : node.value; json.attributes[node.name] = value; } - + len = elem.childNodes.length; for (i = 0; i < len; i++) { node = elem.childNodes.item(i); - + // ignores comment nodes and visuals generated by live preview if (node.nodeType === Node.ELEMENT_NODE && node.className !== HIGHLIGHT_CLASSNAME) { json.children.push(_domElementToJSON(node)); @@ -812,17 +812,17 @@ function RemoteFunctions(experimental) { json.children.push({ content: node.nodeValue }); } } - + return json; } - + function getSimpleDOM() { return JSON.stringify(_domElementToJSON(document.documentElement)); } // init _editHandler = new DOMEditHandler(window.document); - + if (experimental) { window.document.addEventListener("keydown", onKeyDown); } diff --git a/src/LiveDevelopment/Agents/ScriptAgent.js b/src/LiveDevelopment/Agents/ScriptAgent.js index 4ec49304e3b..d785cfe0fae 100644 --- a/src/LiveDevelopment/Agents/ScriptAgent.js +++ b/src/LiveDevelopment/Agents/ScriptAgent.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ diff --git a/src/LiveDevelopment/Documents/CSSDocument.js b/src/LiveDevelopment/Documents/CSSDocument.js index 98c52d8df0e..d272f291714 100644 --- a/src/LiveDevelopment/Documents/CSSDocument.js +++ b/src/LiveDevelopment/Documents/CSSDocument.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -76,10 +76,10 @@ define(function CSSDocumentModule(require, exports, module) { this.doc.on("change.CSSDocument", this.onChange); this.doc.on("deleted.CSSDocument", this.onDeleted); - + this.onActiveEditorChange = this.onActiveEditorChange.bind(this); EditorManager.on("activeEditorChange", this.onActiveEditorChange); - + if (editor) { // Attach now this.attachToEditor(editor); @@ -113,7 +113,7 @@ define(function CSSDocumentModule(require, exports, module) { var deferred = new $.Deferred(), styleSheetHeader = this._getStyleSheetHeader(), styleSheet = getOnlyValue(styleSheetHeader); - + if (styleSheet) { Inspector.CSS.getStyleSheetText(styleSheet.styleSheetId).then(function (res) { deferred.resolve(res.text); @@ -121,10 +121,10 @@ define(function CSSDocumentModule(require, exports, module) { } else { deferred.reject(); } - + return deferred.promise(); }; - + /** Close the document */ CSSDocument.prototype.close = function close() { this.doc.off(".CSSDocument"); @@ -147,14 +147,14 @@ define(function CSSDocumentModule(require, exports, module) { CSSDocument.prototype.attachToEditor = function (editor) { this.editor = editor; - + if (this.editor) { HighlightAgent.on("highlight", this.onHighlight); this.editor.on("cursorActivity.CSSDocument", this.onCursorActivity); this.updateHighlight(); } }; - + CSSDocument.prototype.detachFromEditor = function () { if (this.editor) { HighlightAgent.hide(); @@ -182,24 +182,24 @@ define(function CSSDocumentModule(require, exports, module) { } } }; - + /** * Enable instrumented CSS - * @param enabled {boolean} + * @param enabled {boolean} */ CSSDocument.prototype.setInstrumentationEnabled = function setInstrumentationEnabled(enabled) { // no-op // "Instrumentation" is always enabled for CSS, we make no modifications }; - + /** * Returns true if document edits appear live in the connected browser - * @return {boolean} + * @return {boolean} */ CSSDocument.prototype.isLiveEditingEnabled = function () { return true; }; - + /** * Returns a JSON object with HTTP response overrides * @return {{body: string}} @@ -236,12 +236,12 @@ define(function CSSDocumentModule(require, exports, module) { /** Triggered when the active editor changes */ CSSDocument.prototype.onActiveEditorChange = function (event, newActive, oldActive) { this.detachFromEditor(); - + if (newActive && newActive.document === this.doc) { this.attachToEditor(newActive); } }; - + /** Triggered by the HighlightAgent to highlight a node in the editor */ CSSDocument.prototype.onHighlight = function onHighlight(event, node) { // clear an existing highlight diff --git a/src/LiveDevelopment/Documents/CSSPreprocessorDocument.js b/src/LiveDevelopment/Documents/CSSPreprocessorDocument.js index 67ac52860a6..8788b1fc045 100644 --- a/src/LiveDevelopment/Documents/CSSPreprocessorDocument.js +++ b/src/LiveDevelopment/Documents/CSSPreprocessorDocument.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2014 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. - * + * */ @@ -30,7 +30,7 @@ * * __HIGHLIGHTING__ * - * CSSPreprocessorDocument supports highlighting all DOMNode corresponding to the rule at + * CSSPreprocessorDocument supports highlighting all DOMNode corresponding to the rule at * the cursor position in the editor. * */ @@ -65,7 +65,7 @@ define(function CSSPreprocessorDocumentModule(require, exports, module) { // CSSPreprocessorDocument doesn't dispatch events, but the "live document" interface requires an on() API EventDispatcher.makeEventDispatcher(CSSPreprocessorDocument.prototype); - + /** Close the document */ CSSPreprocessorDocument.prototype.close = function close() { this.doc.off(".CSSPreprocessorDocument"); @@ -73,7 +73,7 @@ define(function CSSPreprocessorDocumentModule(require, exports, module) { this.doc.releaseRef(); this.detachFromEditor(); }; - + /** Return false so edits cause "out of sync" icon to appear */ CSSPreprocessorDocument.prototype.isLiveEditingEnabled = function () { // Normally this isn't called since wasURLRequested() returns false for us, but if user's @@ -83,13 +83,13 @@ define(function CSSPreprocessorDocumentModule(require, exports, module) { CSSPreprocessorDocument.prototype.attachToEditor = function (editor) { this.editor = editor; - + if (this.editor) { this.editor.on("cursorActivity.CSSPreprocessorDocument", this.onCursorActivity); this.updateHighlight(); } }; - + CSSPreprocessorDocument.prototype.detachFromEditor = function () { if (this.editor) { HighlightAgent.hide(); @@ -115,7 +115,7 @@ define(function CSSPreprocessorDocumentModule(require, exports, module) { } } }; - + /** Event Handlers *******************************************************/ /** Triggered on cursor activity of the editor */ @@ -126,12 +126,12 @@ define(function CSSPreprocessorDocumentModule(require, exports, module) { /** Triggered when the active editor changes */ CSSPreprocessorDocument.prototype.onActiveEditorChange = function (event, newActive, oldActive) { this.detachFromEditor(); - + if (newActive && newActive.document === this.doc) { this.attachToEditor(newActive); } }; - + // Export the class module.exports = CSSPreprocessorDocument; }); diff --git a/src/LiveDevelopment/Documents/HTMLDocument.js b/src/LiveDevelopment/Documents/HTMLDocument.js index f1a296a4294..7a572b461d7 100644 --- a/src/LiveDevelopment/Documents/HTMLDocument.js +++ b/src/LiveDevelopment/Documents/HTMLDocument.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -67,15 +67,15 @@ define(function HTMLDocumentModule(require, exports, module) { this.editor = editor; this._instrumentationEnabled = false; - + this._onActiveEditorChange = this._onActiveEditorChange.bind(this); EditorManager.on("activeEditorChange", this._onActiveEditorChange); - + // Attach now this.attachToEditor(editor); }; EventDispatcher.makeEventDispatcher(HTMLDocument.prototype); - + /** * Enable or disable instrumented HTML * @param {boolean} enabled Whether to enable or disable @@ -85,18 +85,18 @@ define(function HTMLDocumentModule(require, exports, module) { HTMLInstrumentation.scanDocument(this.doc); HTMLInstrumentation._markText(this.editor); } - + this._instrumentationEnabled = enabled; }; - + /** * Returns true if document edits appear live in the connected browser - * @return {boolean} + * @return {boolean} */ HTMLDocument.prototype.isLiveEditingEnabled = function () { return this._instrumentationEnabled; }; - + /** * Returns a JSON object with HTTP response overrides * @param {boolean} enabled (Unused) @@ -107,7 +107,7 @@ define(function HTMLDocumentModule(require, exports, module) { if (this._instrumentationEnabled && this.editor) { body = HTMLInstrumentation.generateInstrumentedHTML(this.editor); } - + return { body: body || this.doc.getText() }; @@ -133,7 +133,7 @@ define(function HTMLDocumentModule(require, exports, module) { this._onHighlight(); } }; - + /** * Attach new editor * @param {!Editor} editor The editor for this document @@ -141,7 +141,7 @@ define(function HTMLDocumentModule(require, exports, module) { HTMLDocument.prototype.attachToEditor = function (editor) { var self = this; this.editor = editor; - + // Performance optimization to use closures instead of Function.bind() // to improve responsiveness during cursor movement and keyboard events this.editor.on("cursorActivity.HTMLDocument", function (event, editor) { @@ -155,7 +155,7 @@ define(function HTMLDocumentModule(require, exports, module) { this.editor.on("beforeDestroy.HTMLDocument", function (event, editor) { self._onDestroy(event, editor); }); - + // Experimental code if (LiveDevelopment.config.experimental) { HighlightAgent.on("highlight.HTMLDocument", function (event, node) { @@ -168,7 +168,7 @@ define(function HTMLDocumentModule(require, exports, module) { HTMLInstrumentation._markText(this.editor); } }; - + /** * Detach current editor */ @@ -187,7 +187,7 @@ define(function HTMLDocumentModule(require, exports, module) { HTMLDocument.prototype.updateHighlight = function () { var editor = this.editor, ids = []; - + if (Inspector.config.highlight) { if (editor) { _.each(editor.getSelections(), function (sel) { @@ -200,7 +200,7 @@ define(function HTMLDocumentModule(require, exports, module) { } }); } - + if (!ids.length) { HighlightAgent.hide(); } else { @@ -222,7 +222,7 @@ define(function HTMLDocumentModule(require, exports, module) { } this.updateHighlight(); }; - + /** * @private * For the given editor change, compare the resulting browser DOM with the @@ -232,13 +232,13 @@ define(function HTMLDocumentModule(require, exports, module) { */ HTMLDocument.prototype._compareWithBrowser = function (change) { var self = this; - + RemoteAgent.call("getSimpleDOM").done(function (res) { var browserSimpleDOM = JSON.parse(res.result.value), edits, node, result; - + try { result = HTMLInstrumentation._getBrowserDiff(self.editor, browserSimpleDOM); } catch (err) { @@ -246,21 +246,21 @@ define(function HTMLDocumentModule(require, exports, module) { console.error(err.stack); return; } - + edits = result.diff.filter(function (delta) { // ignore textDelete in html root element node = result.browser.nodeMap[delta.parentID]; - + if (node && node.tag === "html" && delta.type === "textDelete") { return false; } - + return true; }); - + if (edits.length > 0) { console.warn("Browser DOM does not match after change: " + JSON.stringify(change)); - + edits.forEach(function (delta) { console.log(delta); }); @@ -278,8 +278,8 @@ define(function HTMLDocumentModule(require, exports, module) { this.detachFromEditor(); } }; - - + + /** * Triggered on change by the editor * @param {$.Event} event Event @@ -300,17 +300,17 @@ define(function HTMLDocumentModule(require, exports, module) { if (!isNestedTimer) { PerfUtils.markStart(perfTimerName); } - + // Only handles attribute changes currently. // TODO: text changes should be easy to add // TODO: if new tags are added, need to instrument them var self = this, result = HTMLInstrumentation.getUnappliedEditList(editor, change), applyEditsPromise; - + if (result.edits) { applyEditsPromise = RemoteAgent.call("applyDOMEdits", result.edits); - + applyEditsPromise.always(function () { if (!isNestedTimer) { PerfUtils.addMeasurement(perfTimerName); @@ -320,7 +320,7 @@ define(function HTMLDocumentModule(require, exports, module) { this.errors = result.errors || []; this.trigger("statusChanged", this); - + // Debug-only: compare in-memory vs. in-browser DOM // edit this file or set a conditional breakpoint at the top of this function: // "this._debug = true, false" @@ -331,7 +331,7 @@ define(function HTMLDocumentModule(require, exports, module) { self._compareWithBrowser(change); }); } - + // var marker = HTMLInstrumentation._getMarkerAtDocumentPos( // this.editor, // editor.getCursorPos() @@ -369,7 +369,7 @@ define(function HTMLDocumentModule(require, exports, module) { */ HTMLDocument.prototype._onActiveEditorChange = function (event, newActive, oldActive) { this.detachFromEditor(); - + if (newActive && newActive.document === this.doc) { this.attachToEditor(newActive); } diff --git a/src/LiveDevelopment/Documents/JSDocument.js b/src/LiveDevelopment/Documents/JSDocument.js index 57ac7791c66..6afca387cf5 100644 --- a/src/LiveDevelopment/Documents/JSDocument.js +++ b/src/LiveDevelopment/Documents/JSDocument.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -69,7 +69,7 @@ define(function JSDocumentModule(require, exports, module) { this.editor.on("cursorActivity", this.onCursorActivity); this.onCursorActivity(); }; - + // JSDocument doesn't dispatch events, but the "live document" interface requires having an on() API EventDispatcher.makeEventDispatcher(JSDocument.prototype); @@ -131,4 +131,4 @@ define(function JSDocumentModule(require, exports, module) { // Export the class module.exports = JSDocument; -}); \ No newline at end of file +}); diff --git a/src/LiveDevelopment/Inspector/Inspector.js b/src/LiveDevelopment/Inspector/Inspector.js index 5dfc5d9f858..795e10c03e9 100644 --- a/src/LiveDevelopment/Inspector/Inspector.js +++ b/src/LiveDevelopment/Inspector/Inspector.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -49,7 +49,7 @@ * * Inspector can connect directly to a web socket via `connect(socketURL)`, or * it can find the web socket that corresponds to the tab at the given URL and - * connect to it via `connectToURL(url)`. The later returns a promise. To + * connect to it via `connectToURL(url)`. The later returns a promise. To * disconnect use `disconnect()`. * * __EVENTS__ @@ -122,8 +122,8 @@ define(function Inspector(require, exports, module) { // FUTURE: Our current implementation closes and re-opens an inspector connection whenever // a new HTML file is selected. If done quickly enough, pending requests from the previous - // connection could come in before the new socket connection is established. For now we - // simply ignore this condition. + // connection could come in before the new socket connection is established. For now we + // simply ignore this condition. // This race condition will go away once we support multiple inspector connections and turn // off auto re-opening when a new HTML file is selected. return (new $.Deferred()).reject().promise(); @@ -295,13 +295,13 @@ define(function Inspector(require, exports, module) { _socket = undefined; } - + deferred.resolve(); } return promise; } - + /** * Connect to the remote debugger WebSocket at the given URL. * Clients must listen for the `connect` event. @@ -376,7 +376,7 @@ define(function Inspector(require, exports, module) { var InspectorText = require("text!LiveDevelopment/Inspector/Inspector.json"), InspectorJSON = JSON.parse(InspectorText); - + var i, j, domain, command; for (i in InspectorJSON.domains) { domain = InspectorJSON.domains[i]; @@ -389,10 +389,10 @@ define(function Inspector(require, exports, module) { } } } - - + + EventDispatcher.makeEventDispatcher(exports); - + // Export public functions exports.connect = connect; exports.connected = connected; diff --git a/src/LiveDevelopment/LiveDevMultiBrowser.js b/src/LiveDevelopment/LiveDevMultiBrowser.js index b12cb03f0fc..8c7fceb5af1 100644 --- a/src/LiveDevelopment/LiveDevMultiBrowser.js +++ b/src/LiveDevelopment/LiveDevMultiBrowser.js @@ -1,24 +1,24 @@ /* * 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, forin: true, maxerr: 50, regexp: true */ @@ -89,26 +89,26 @@ define(function (require, exports, module) { NodeSocketTransport = require("LiveDevelopment/MultiBrowserImpl/transports/NodeSocketTransport"), LiveDevProtocol = require("LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol"), DefaultLauncher = require("LiveDevelopment/MultiBrowserImpl/launchers/Launcher"); - + // Documents var LiveCSSDocument = require("LiveDevelopment/MultiBrowserImpl/documents/LiveCSSDocument"), LiveHTMLDocument = require("LiveDevelopment/MultiBrowserImpl/documents/LiveHTMLDocument"); - - /** + + /** * @private * The live HTML document for the currently active preview. - * @type {LiveHTMLDocument} + * @type {LiveHTMLDocument} */ var _liveDocument; - - /** + + /** * @private * Live documents related to the active HTML document - for example, CSS files * that are used by the document. * @type {Object.} */ var _relatedDocuments = {}; - + /** * @private * Protocol handler that provides the actual live development API on top of the current transport. @@ -120,7 +120,7 @@ define(function (require, exports, module) { * Current browser launcher for preview. */ var _launcher; - + /** * @private * Current live preview server @@ -128,7 +128,7 @@ define(function (require, exports, module) { */ var _server; - /** + /** * @private * Determine which live document class should be used for a given document * @param {Document} document The document we want to create a live document for. @@ -145,7 +145,7 @@ define(function (require, exports, module) { return null; } - + /** * Returns true if the global Live Development mode is on (might be in the middle of connecting). * @return {boolean} @@ -153,7 +153,7 @@ define(function (require, exports, module) { function isActive() { return exports.status > STATUS_INACTIVE; } - + /** * Returns the live document for a given path, or null if there is no live document for it. * @param {string} path @@ -163,7 +163,7 @@ define(function (require, exports, module) { if (!_server) { return null; } - + return _server.get(path); } @@ -176,7 +176,7 @@ define(function (require, exports, module) { liveDocument.off(".livedev"); liveDocument.close(); } - + /** * Removes the given CSS/JSDocument from _relatedDocuments. Signals that the * given file is no longer associated with the HTML document that is live (e.g. @@ -188,7 +188,7 @@ define(function (require, exports, module) { if (liveDoc) { delete _relatedDocuments[url]; } - + if (_server) { _server.remove(liveDoc); } @@ -206,9 +206,9 @@ define(function (require, exports, module) { if (status === exports.status) { return; } - + exports.status = status; - + var reason = status === STATUS_INACTIVE ? closeReason : null; exports.trigger("statusChange", status, reason); } @@ -222,18 +222,18 @@ define(function (require, exports, module) { _closeDocument(_liveDocument); _liveDocument = undefined; } - + Object.keys(_relatedDocuments).forEach(function (url) { _closeDocument(_relatedDocuments[url]); delete _relatedDocuments[url]; }); - + // Clear all documents from request filtering if (_server) { _server.clear(); } } - + /** * @private * Returns the URL that we would serve the given path at. @@ -256,11 +256,11 @@ define(function (require, exports, module) { function _createLiveDocument(doc, editor, roots) { var DocClass = _classForDocument(doc), liveDocument; - + if (!DocClass) { return null; } - + liveDocument = new DocClass(_protocol, _resolveUrl, doc, editor, roots); liveDocument.on("errorStatusChanged.livedev", function (event, hasErrors) { @@ -272,7 +272,7 @@ define(function (require, exports, module) { return liveDocument; } - /** + /** * Documents are considered to be out-of-sync if they are dirty and * do not have "update while editing" support * @param {Document} doc @@ -331,7 +331,7 @@ define(function (require, exports, module) { * available for currently opened document. We are searching for these files: * - index.html * - index.htm - * + * * If the project is configured with a custom base url for live development, then * the list of possible index files is extended to contain these index files too: * - index.php @@ -348,10 +348,10 @@ define(function (require, exports, module) { * - index.jspx * - index.shm * - index.shml - * + * * If a file was found, the promise will be resolved with the full path to this file. If no file * was found in the whole project tree, the promise will be resolved with null. - * + * * @return {jQuery.Promise} A promise that is resolved with a full path * to a file if one could been determined, or null if there was no suitable index * file. @@ -379,19 +379,19 @@ define(function (require, exports, module) { containingFolder, indexFileFound = false, stillInProjectTree = true; - + if (refPath) { containingFolder = FileUtils.getDirectoryPath(refPath); } else { containingFolder = projectRoot; } - + var filteredFiltered = allFiles.filter(function (item) { var parent = FileUtils.getParentPath(item.fullPath); - + return (containingFolder.indexOf(parent) === 0); }); - + var filterIndexFile = function (fileInfo) { if (fileInfo.fullPath.indexOf(containingFolder) === 0) { if (FileUtils.getFilenameWithoutExtension(fileInfo.name) === "index") { @@ -429,7 +429,7 @@ define(function (require, exports, module) { DocumentManager.getDocumentForPath(filteredFiltered[i].fullPath).then(result.resolve, result.resolve); return; } - + result.resolve(null); }); @@ -444,11 +444,11 @@ define(function (require, exports, module) { */ function _close(doCloseWindow, reason) { if (exports.status !== STATUS_INACTIVE) { - // Close live documents + // Close live documents _closeDocuments(); // Close all active connections _protocol.closeAllConnections(); - + if (_server) { // Stop listening for requests when disconnected _server.stop(); @@ -459,7 +459,7 @@ define(function (require, exports, module) { } //TODO: implement closeWindow together with launchers. // if (doCloseWindow) { -// +// // } _setStatus(STATUS_INACTIVE, reason || "explicit_close"); } @@ -473,7 +473,7 @@ define(function (require, exports, module) { _close(true); return new $.Deferred().resolve().promise(); } - + /** * @private * Displays an error when no HTML file can be found to preview. @@ -510,8 +510,8 @@ define(function (require, exports, module) { _liveDocument = _createLiveDocument(doc, doc._masterEditor); _server.add(_liveDocument); } - - + + /** * Launches the given URL in the default browser. * @param {string} url @@ -520,14 +520,14 @@ define(function (require, exports, module) { function _launch(url) { // open default browser // TODO: fail? - // + // _launcher.launch(url); } - + /** * @private * Launches the given document in the browser, given that a live document has already - * been created for it. + * been created for it. * @param {Document} doc */ function _open(doc) { @@ -591,13 +591,13 @@ define(function (require, exports, module) { close(); } } - + /** * @private - * Creates the live document in preparation for launching the - * preview of the given document, then launches it. (The live document + * Creates the live document in preparation for launching the + * preview of the given document, then launches it. (The live document * must already exist before we launch it so that the server can - * ask it for the instrumented version of the document when the browser + * ask it for the instrumented version of the document when the browser * requests it.) * TODO: could probably just consolidate this with _open() * @param {Document} doc @@ -612,7 +612,7 @@ define(function (require, exports, module) { // open browser to the url _open(initialDoc); } - + /** * @private * Create the server in preparation for opening a live preview. @@ -623,7 +623,7 @@ define(function (require, exports, module) { function _prepareServer(doc) { var deferred = new $.Deferred(), showBaseUrlPrompt = false; - + _server = LiveDevServerManager.getServer(doc.file.fullPath); // Optionally prompt for a base URL if no server was found but the @@ -657,7 +657,7 @@ define(function (require, exports, module) { // No server found deferred.reject(); } - + return deferred.promise(); } @@ -671,11 +671,11 @@ define(function (require, exports, module) { if (!isActive() || !doc) { return; } - + // close the current session and begin a new session var docUrl = _server && _server.pathToUrl(doc.file.fullPath), isViewable = _server && _server.canServe(doc.file.fullPath); - + if (_liveDocument.doc.url !== docUrl && isViewable) { // clear live doc and related docs _closeDocuments(); @@ -687,7 +687,7 @@ define(function (require, exports, module) { } } - + /** * Open a live preview on the current docuemnt. */ @@ -706,7 +706,7 @@ define(function (require, exports, module) { CommandManager.execute(Commands.CMD_OPEN, { fullPath: doc.file.fullPath }); } } - + // wait for server (StaticServer, Base URL or file:) prepareServerPromise .done(function () { @@ -718,7 +718,7 @@ define(function (require, exports, module) { }); }); } - + /** * For files that don't support as-you-type live editing, but are loaded by live HTML documents * (e.g. JS files), we want to reload the full document when they're saved. @@ -729,17 +729,17 @@ define(function (require, exports, module) { if (!isActive() || !_server) { return; } - + var absolutePath = doc.file.fullPath, liveDocument = absolutePath && _server.get(absolutePath), liveEditingEnabled = liveDocument && liveDocument.isLiveEditingEnabled && liveDocument.isLiveEditingEnabled(); - + // Skip reload if the saved document has live editing enabled if (liveEditingEnabled) { return; } - - // reload the page if the given document is a JS file related + + // reload the page if the given document is a JS file related // to the current live document. if (_liveDocument.isRelated(absolutePath)) { if (doc.getLanguage().getId() === "javascript") { @@ -749,7 +749,7 @@ define(function (require, exports, module) { } } - /** + /** * For files that don't support as-you-type live editing, but are loaded by live HTML documents * (e.g. JS files), we want to show a dirty indicator on the live development icon when they * have unsaved changes, so the user knows s/he needs to save in order to have the page reload. @@ -760,9 +760,9 @@ define(function (require, exports, module) { if (!isActive() || !_server) { return; } - + var absolutePath = doc.file.fullPath; - + if (_liveDocument.isRelated(absolutePath)) { // Set status to out of sync if dirty. Otherwise, set it to active status. _setStatus(_docIsOutOfSync(doc) ? STATUS_OUT_OF_SYNC : STATUS_ACTIVE); @@ -783,7 +783,7 @@ define(function (require, exports, module) { * * It must also dispatch the following jQuery events: * - * - "connect": When a target browser connects back to the transport. Must provide two parameters: + * - "connect": When a target browser connects back to the transport. Must provide two parameters: * - clientID - a unique number representing this connection * - url - the URL of the page in the target browser that's connecting to us * - "message": When a message is received by the transport. Must provide two parameters: @@ -791,7 +791,7 @@ define(function (require, exports, module) { * - message - the text of the message as a JSON string * - "close": When the remote browser closes the connection. Must provide one parameter: * - clientID - the ID of the client closing the connection - * + * * @param {{launch: function(string), send: function(number|Array., string), close: function(number), getRemoteScript: function(): ?string}} transport */ function setTransport(transport) { @@ -826,10 +826,10 @@ define(function (require, exports, module) { .on("dirtyFlagChange", _onDirtyFlagChange); ProjectManager .on("beforeProjectClose beforeAppClose", close); - + // Default transport for live connection messages - can be changed setTransport(NodeSocketTransport); - + // Default launcher for preview browser - can be changed setLauncher(DefaultLauncher); @@ -843,13 +843,13 @@ define(function (require, exports, module) { } return getLiveDocForPath(editor.document.file.fullPath); } - + /** - * Enable highlighting + * Enable highlighting */ function showHighlight() { var doc = getLiveDocForEditor(EditorManager.getActiveEditor()); - + if (doc && doc.updateHighlight) { doc.updateHighlight(); } @@ -863,16 +863,16 @@ define(function (require, exports, module) { _protocol.evaluate("_LD.hideHighlight()"); } } - + /** - * Redraw highlights + * Redraw highlights */ function redrawHighlight() { if (_protocol) { _protocol.evaluate("_LD.redrawHighlights()"); } } - + /** * Originally unload and reload agents. It doesn't apply for this new implementation. * @return {jQuery.Promise} Already resolved promise. @@ -880,7 +880,7 @@ define(function (require, exports, module) { function reconnect() { return $.Deferred().resolve(); } - + /** * Reload current page in all connected browsers. */ @@ -889,7 +889,7 @@ define(function (require, exports, module) { _protocol.reload(); } } - + /** * Returns current project server config. Copied from original LiveDevelopment. */ @@ -900,7 +900,7 @@ define(function (require, exports, module) { root: ProjectManager.getProjectRoot().fullPath }; } - + /** * @private * Returns the base URL of the current server serving the active live document, or null if @@ -910,14 +910,14 @@ define(function (require, exports, module) { function getServerBaseUrl() { return _server && _server.getBaseUrl(); } - + // for unit testing only function _getCurrentLiveDoc() { return _liveDocument; } - + EventDispatcher.makeEventDispatcher(exports); - + // For unit testing exports._server = _server; exports._getCurrentLiveDoc = _getCurrentLiveDoc; diff --git a/src/LiveDevelopment/LiveDevServerManager.js b/src/LiveDevelopment/LiveDevServerManager.js index 43f2d3db4b2..7baf24943e9 100644 --- a/src/LiveDevelopment/LiveDevServerManager.js +++ b/src/LiveDevelopment/LiveDevServerManager.js @@ -104,13 +104,13 @@ define(function (require, exports, module) { _serverProviders.push(providerObj); _serverProviders.sort(_providerSort); - + return providerObj; } - + /** * Remove a server from the list of the registered providers. - * + * * @param {{object}} provider The provider to be removed. */ function removeServer(provider) { @@ -121,7 +121,7 @@ define(function (require, exports, module) { } } } - + // Backwards compatibility exports.getProvider = getServer; exports.registerProvider = registerServer; diff --git a/src/LiveDevelopment/LiveDevelopment.js b/src/LiveDevelopment/LiveDevelopment.js index 4c40eb7f122..e0fa39fcbd8 100644 --- a/src/LiveDevelopment/LiveDevelopment.js +++ b/src/LiveDevelopment/LiveDevelopment.js @@ -1,24 +1,24 @@ /* * 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, forin: true, maxerr: 50, regexp: true */ @@ -105,13 +105,13 @@ define(function LiveDevelopment(require, exports, module) { CSSPreprocessorDocument = require("LiveDevelopment/Documents/CSSPreprocessorDocument"), HTMLDocument = require("LiveDevelopment/Documents/HTMLDocument"), JSDocument = require("LiveDevelopment/Documents/JSDocument"); - + // Document errors var SYNC_ERROR_CLASS = "live-preview-sync-error"; // Agents var CSSAgent = require("LiveDevelopment/Agents/CSSAgent"); - + var agents = { "console" : require("LiveDevelopment/Agents/ConsoleAgent"), "remote" : require("LiveDevelopment/Agents/RemoteAgent"), @@ -163,19 +163,19 @@ define(function LiveDevelopment(require, exports, module) { * @type {HTMLDocument} */ var _liveDocument; - + /** * Related Live Documents * @type {Object.} */ var _relatedDocuments = {}; - + /** * Promise returned for each call to open() * @type {jQuery.Deferred} */ var _openDeferred; - + /** * Promise returned for each call to close() * @type {jQuery.Deferred} @@ -184,13 +184,13 @@ define(function LiveDevelopment(require, exports, module) { // Disallow re-entrancy of loadAgents() var _loadAgentsPromise; - + /** * Current live preview server * @type {BaseServer} */ var _server; - + /** * @private * Handles of registered servers @@ -233,10 +233,10 @@ define(function LiveDevelopment(require, exports, module) { if (!_server) { return undefined; } - + return _server.get(path); } - + function getLiveDocForEditor(editor) { if (!editor) { return null; @@ -251,22 +251,22 @@ define(function LiveDevelopment(require, exports, module) { */ function _doClearErrors(liveDocument) { var lineHandle; - + if (!liveDocument.editor || !liveDocument._errorLineHandles || !liveDocument._errorLineHandles.length) { return; } - + liveDocument.editor._codeMirror.operation(function () { while (true) { // Iterate over all lines that were previously marked with an error lineHandle = liveDocument._errorLineHandles.pop(); - + if (!lineHandle) { break; } - + liveDocument.editor._codeMirror.removeLineClass(lineHandle, "wrap", SYNC_ERROR_CLASS); } }); @@ -289,14 +289,14 @@ define(function LiveDevelopment(require, exports, module) { function _closeDocument(liveDocument) { _doClearErrors(liveDocument); liveDocument.close(); - + if (liveDocument.editor) { liveDocument.editor.off(".livedev"); } - + liveDocument.off(".livedev"); } - + /** * Removes the given CSS/JSDocument from _relatedDocuments. Signals that the * given file is no longer associated with the HTML document that is live (e.g. @@ -306,14 +306,14 @@ define(function LiveDevelopment(require, exports, module) { if (_relatedDocuments[liveDoc.doc.url]) { delete _relatedDocuments[liveDoc.doc.url]; } - + if (_server) { _server.remove(liveDoc); } - + _closeDocument(liveDoc); } - + /** * Update the status. Triggers a statusChange event. * @param {number} status new status @@ -325,19 +325,19 @@ define(function LiveDevelopment(require, exports, module) { if (status === exports.status) { return; } - + exports.status = status; - + var reason = status === STATUS_INACTIVE ? closeReason : null; exports.trigger("statusChange", status, reason); } - + /** * @private * Event handler for live document errors. Displays error status in the editor gutter. * @param {$.Event} event * @param {HTMLDocument|CSSDocument} liveDocument - * @param {Array.<{token: SimpleNode, startPos: Pos, endPos: Pos}>} errors + * @param {Array.<{token: SimpleNode, startPos: Pos, endPos: Pos}>} errors */ function _handleLiveDocumentStatusChanged(liveDocument) { var startLine, @@ -347,7 +347,7 @@ define(function LiveDevelopment(require, exports, module) { status = (liveDocument.errors.length) ? STATUS_SYNC_ERROR : STATUS_ACTIVE; _setStatus(status); - + if (!liveDocument.editor) { return; } @@ -356,13 +356,13 @@ define(function LiveDevelopment(require, exports, module) { liveDocument.editor._codeMirror.operation(function () { // Remove existing errors before marking new ones _doClearErrors(liveDocument); - + liveDocument._errorLineHandles = liveDocument._errorLineHandles || []; - + liveDocument.errors.forEach(function (error) { startLine = error.startPos.line; endLine = error.endPos.line; - + for (i = startLine; i < endLine + 1; i++) { lineHandle = liveDocument.editor._codeMirror.addLineClass(i, "wrap", SYNC_ERROR_CLASS); liveDocument._errorLineHandles.push(lineHandle); @@ -380,12 +380,12 @@ define(function LiveDevelopment(require, exports, module) { _closeDocument(_liveDocument); _liveDocument = undefined; } - + Object.keys(_relatedDocuments).forEach(function (url) { _closeDocument(_relatedDocuments[url]); delete _relatedDocuments[url]; }); - + // Clear all documents from request filtering if (_server) { _server.clear(); @@ -425,7 +425,7 @@ define(function LiveDevelopment(require, exports, module) { _liveDocument = _createDocument(doc, doc._masterEditor); _server.add(_liveDocument); } - + /** Enable an agent. Takes effect next time a connection is made. Does not affect * current live development sessions. * @@ -458,11 +458,11 @@ define(function LiveDevelopment(require, exports, module) { return doc.isDirty && !isLiveEditingEnabled; } - + /** Triggered by Inspector.error */ function _onError(event, error, msgData) { var message; - + // Sometimes error.message is undefined if (!error.message) { console.warn("Expected a non-empty string in error.message, got this instead:", error.message); @@ -485,7 +485,7 @@ define(function LiveDevelopment(require, exports, module) { // Show the message, but include the error object for further information (e.g. error code) console.error(message, error, msgData); } - + function _styleSheetAdded(event, url) { var path = _server && _server.urlToPath(url), exists = !!_relatedDocuments[url]; @@ -526,7 +526,7 @@ define(function LiveDevelopment(require, exports, module) { }); _loadedAgentNames = []; } - + /** * @private * Invoke a no-arg method on an inspector agent @@ -562,10 +562,10 @@ define(function LiveDevelopment(require, exports, module) { // load only enabled agents enabledAgents = _enabledAgentNames; } - + return Object.keys(enabledAgents); } - + /** * @private * Setup agents that need inspector domains enabled before loading @@ -587,10 +587,10 @@ define(function LiveDevelopment(require, exports, module) { if (_loadAgentsPromise) { return _loadAgentsPromise; } - + var result = new $.Deferred(), allAgentsPromise; - + _loadAgentsPromise = result.promise(); _setStatus(STATUS_LOADING_AGENTS); @@ -618,7 +618,7 @@ define(function LiveDevelopment(require, exports, module) { if (_docIsOutOfSync(doc)) { status = STATUS_OUT_OF_SYNC; } - + _setStatus(status); result.resolve(); } else { @@ -627,7 +627,7 @@ define(function LiveDevelopment(require, exports, module) { }); allAgentsPromise.fail(result.reject); - + _loadAgentsPromise .fail(function () { // show error loading live dev dialog @@ -653,7 +653,7 @@ define(function LiveDevelopment(require, exports, module) { * available for currently opened document. We are searching for these files: * - index.html * - index.htm - * + * * If the project is configured with a custom base url for live development, then * the list of possible index files is extended to contain these index files too: * - index.php @@ -670,10 +670,10 @@ define(function LiveDevelopment(require, exports, module) { * - index.jspx * - index.shm * - index.shml - * + * * If a file was found, the promise will be resolved with the full path to this file. If no file * was found in the whole project tree, the promise will be resolved with null. - * + * * @return {jQuery.Promise} A promise that is resolved with a full path * to a file if one could been determined, or null if there was no suitable index * file. @@ -701,19 +701,19 @@ define(function LiveDevelopment(require, exports, module) { containingFolder, indexFileFound = false, stillInProjectTree = true; - + if (refPath) { containingFolder = FileUtils.getDirectoryPath(refPath); } else { containingFolder = projectRoot; } - + var filteredFiltered = allFiles.filter(function (item) { var parent = FileUtils.getParentPath(item.fullPath); - + return (containingFolder.indexOf(parent) === 0); }); - + var filterIndexFile = function (fileInfo) { if (fileInfo.fullPath.indexOf(containingFolder) === 0) { if (FileUtils.getFilenameWithoutExtension(fileInfo.name) === "index") { @@ -751,7 +751,7 @@ define(function LiveDevelopment(require, exports, module) { DocumentManager.getDocumentForPath(filteredFiltered[i].fullPath).then(result.resolve, result.resolve); return; } - + result.resolve(null); }); @@ -759,10 +759,10 @@ define(function LiveDevelopment(require, exports, module) { } /** - * If the current editor is for a CSS preprocessor file, then add it to the style sheet + * If the current editor is for a CSS preprocessor file, then add it to the style sheet * so that we can track cursor positions in the editor to show live preview highlighting. - * For normal CSS we only do highlighting from files we know for sure are referenced by the - * current live preview document, but for preprocessors we just assume that any preprocessor + * For normal CSS we only do highlighting from files we know for sure are referenced by the + * current live preview document, but for preprocessors we just assume that any preprocessor * file you edit is probably related to the live preview. * * @param {Event} event (unused) @@ -774,7 +774,7 @@ define(function LiveDevelopment(require, exports, module) { if (previous && previous.document && CSSUtils.isCSSPreprocessorFile(previous.document.file.fullPath)) { var prevDocUrl = _server && _server.pathToUrl(previous.document.file.fullPath); - + if (_relatedDocuments && _relatedDocuments[prevDocUrl]) { _closeRelatedDocument(_relatedDocuments[prevDocUrl]); } @@ -785,7 +785,7 @@ define(function LiveDevelopment(require, exports, module) { _styleSheetAdded(null, docUrl); } } - + /** * @private * While still connected to the Inspector, do cleanup for agents, @@ -799,7 +799,7 @@ define(function LiveDevelopment(require, exports, module) { connected = Inspector.connected(); EditorManager.off("activeEditorChange", onActiveEditorChange); - + Inspector.Page.off(".livedev"); Inspector.off(".livedev"); @@ -809,10 +809,10 @@ define(function LiveDevelopment(require, exports, module) { } else { unloadAgents(); } - - // Close live documents + + // Close live documents _closeDocuments(); - + if (_server) { // Stop listening for requests when disconnected _server.stop(); @@ -866,7 +866,7 @@ define(function LiveDevelopment(require, exports, module) { * the status accordingly. */ function cleanup() { - // Need to do this in order to trigger the corresponding CloseLiveBrowser cleanups required on + // Need to do this in order to trigger the corresponding CloseLiveBrowser cleanups required on // the native Mac side var closeDeferred = (brackets.platform === "mac") ? NativeApp.closeLiveBrowser() : $.Deferred().resolve(); closeDeferred.done(function () { @@ -885,7 +885,7 @@ define(function LiveDevelopment(require, exports, module) { _closeDeferred.resolve(); }); } - + if (_isPromisePending(_openDeferred)) { // Reject calls to open if requests are still pending _openDeferred.reject(); @@ -897,7 +897,7 @@ define(function LiveDevelopment(require, exports, module) { } else { _doInspectorDisconnect(doCloseWindow).always(cleanup); } - + return promise; } @@ -965,7 +965,7 @@ define(function LiveDevelopment(require, exports, module) { } unloadAgents(); - + // Clear any existing related documents before we reload the agents. // We need to recreate them for the reloaded document due to some // desirable side-effects (see #7606). Eventually, we should simplify @@ -997,12 +997,12 @@ define(function LiveDevelopment(require, exports, module) { function close() { return _close(true); } - + /** * @private * Create a promise that resolves when the interstitial page has * finished loading. - * + * * @return {jQuery.Promise} Resolves once page is loaded */ function _waitForInterstitialPageLoad() { @@ -1012,8 +1012,8 @@ define(function LiveDevelopment(require, exports, module) { keepPolling = false; deferred.reject(); }, 10000); // 10 seconds - - /* + + /* * Asynchronously check to see if the interstitial page has * finished loading; if not, check again until timing out. */ @@ -1021,7 +1021,7 @@ define(function LiveDevelopment(require, exports, module) { if (keepPolling && Inspector.connected()) { Inspector.Runtime.evaluate("window.isBracketsLiveDevelopmentInterstitialPageLoaded", function (response) { var result = response.result; - + if (result.type === "boolean" && result.value) { window.clearTimeout(timer); deferred.resolve(); @@ -1033,14 +1033,14 @@ define(function LiveDevelopment(require, exports, module) { deferred.reject(); } } - + pollInterstitialPage(); return deferred.promise(); } - + /** * @private - * Load agents and navigate to the target document once the + * Load agents and navigate to the target document once the * interstitial page has finished loading. */ function _onInterstitialPageLoad() { @@ -1053,7 +1053,7 @@ define(function LiveDevelopment(require, exports, module) { var enablePromise = Inspector.Page.enable().then(function () { return Inspector.DOM.enable().then(_enableAgents, _enableAgents); }); - + enablePromise.done(function () { // Some agents (e.g. DOMAgent and RemoteAgent) require us to // navigate to the page first before loading can complete. @@ -1085,7 +1085,7 @@ define(function LiveDevelopment(require, exports, module) { }); }); } - + /** Triggered by Inspector.connect */ function _onConnect(event) { // When the browser navigates away from the primary live document @@ -1093,7 +1093,7 @@ define(function LiveDevelopment(require, exports, module) { // When the Inspector WebSocket disconnects unexpectedely Inspector.on("disconnect.livedev", _onDisconnect); - + _waitForInterstitialPageLoad() .fail(function () { close(); @@ -1124,11 +1124,11 @@ define(function LiveDevelopment(require, exports, module) { ); _openDeferred.reject(); } - + function _openInterstitialPage() { var browserStarted = false, retryCount = 0; - + // Open the live browser if the connection fails, retry 3 times Inspector.connectToURL(launcherUrl).fail(function onConnectFail(err) { if (err === "CANCEL") { @@ -1209,7 +1209,7 @@ define(function LiveDevelopment(require, exports, module) { } else { message = StringUtils.format(Strings.ERROR_LAUNCHING_BROWSER, err); } - + Dialogs.showModalDialog( DefaultDialogs.DIALOG_ID_ERROR, Strings.ERROR_LAUNCHING_BROWSER_TITLE, @@ -1219,7 +1219,7 @@ define(function LiveDevelopment(require, exports, module) { _openDeferred.reject("OPEN_LIVE_BROWSER"); }); } - + if (exports.status !== STATUS_ERROR) { window.setTimeout(function retryConnect() { Inspector.connectToURL(launcherUrl).fail(onConnectFail); @@ -1240,10 +1240,10 @@ define(function LiveDevelopment(require, exports, module) { // Install a one-time event handler when connected to the launcher page Inspector.one("connect", _onConnect); - + // open browser to the interstitial page to prepare for loading agents _openInterstitialPage(); - + // Once all agents loaded (see _onInterstitialPageLoad()), begin Live Highlighting for preprocessor documents _openDeferred.done(function () { // Setup activeEditorChange event listener so that we can track cursor positions in @@ -1256,11 +1256,11 @@ define(function LiveDevelopment(require, exports, module) { onActiveEditorChange(null, EditorManager.getActiveEditor(), null); }); } - + function _prepareServer(doc) { var deferred = new $.Deferred(), showBaseUrlPrompt = false; - + _server = LiveDevServerManager.getServer(doc.file.fullPath); // Optionally prompt for a base URL if no server was found but the @@ -1295,7 +1295,7 @@ define(function LiveDevelopment(require, exports, module) { // No server found deferred.reject(); } - + return deferred.promise(); } @@ -1306,15 +1306,15 @@ define(function LiveDevelopment(require, exports, module) { root: ProjectManager.getProjectRoot().fullPath }; } - + function _createUserServer() { return new UserServer(getCurrentProjectServerConfig()); } - + function _createFileServer() { return new FileServer(getCurrentProjectServerConfig()); } - + /** * Open the Connection and go live * @@ -1340,11 +1340,11 @@ define(function LiveDevelopment(require, exports, module) { }); } } - + // Register user defined server provider and keep handlers for further clean-up _regServers.push(LiveDevServerManager.registerServer({ create: _createUserServer }, 99)); _regServers.push(LiveDevServerManager.registerServer({ create: _createFileServer }, 0)); - + // TODO: need to run _onFileChanged() after load if doc != currentDocument here? Maybe not, since activeEditorChange // doesn't trigger it, while inline editors can still cause edits in doc other than currentDoc... _getInitialDocFromCurrent().done(function (doc) { @@ -1372,11 +1372,11 @@ define(function LiveDevelopment(require, exports, module) { return _openDeferred.promise(); } - + /** Enable highlighting */ function showHighlight() { var doc = getLiveDocForEditor(EditorManager.getActiveEditor()); - + if (doc && doc.updateHighlight) { doc.updateHighlight(); } @@ -1388,7 +1388,7 @@ define(function LiveDevelopment(require, exports, module) { agents.highlight.hide(); } } - + /** Redraw highlights **/ function redrawHighlight() { if (Inspector.connected() && agents.highlight) { @@ -1398,21 +1398,21 @@ define(function LiveDevelopment(require, exports, module) { /** * @private - * MainViewManager.currentFileChange event handler. + * MainViewManager.currentFileChange event handler. */ function _onFileChanged() { var doc = _getCurrentDocument(); - + if (!doc || !Inspector.connected()) { return; } - + // close the current session and begin a new session if the current // document changes to an HTML document that was not loaded yet var docUrl = _server && _server.pathToUrl(doc.file.fullPath), wasRequested = agents.network && agents.network.wasURLRequested(docUrl), isViewable = exports.config.experimental || (_server && _server.canServe(doc.file.fullPath)); - + if (!wasRequested && isViewable) { // Update status _setStatus(STATUS_CONNECTING); @@ -1445,19 +1445,19 @@ define(function LiveDevelopment(require, exports, module) { if (!Inspector.connected() || !_server) { return; } - + var absolutePath = doc.file.fullPath, liveDocument = absolutePath && _server.get(absolutePath), liveEditingEnabled = liveDocument && liveDocument.isLiveEditingEnabled && liveDocument.isLiveEditingEnabled(); - + // Skip reload if the saved document has live editing enabled if (liveEditingEnabled) { return; } - + var documentUrl = _server.pathToUrl(absolutePath), wasRequested = agents.network && agents.network.wasURLRequested(documentUrl); - + if (wasRequested) { reload(); } @@ -1475,14 +1475,14 @@ define(function LiveDevelopment(require, exports, module) { /** Initialize the LiveDevelopment Session */ function init(theConfig) { exports.config = theConfig; - + Inspector.on("error", _onError); Inspector.Inspector.on("detached", _onDetached); // Only listen for styleSheetAdded // We may get interim added/removed events when pushing incremental updates CSSAgent.on("styleSheetAdded.livedev", _styleSheetAdded); - + MainViewManager .on("currentFileChange", _onFileChanged); DocumentManager @@ -1503,9 +1503,9 @@ define(function LiveDevelopment(require, exports, module) { return _server && _server.getBaseUrl(); } - + EventDispatcher.makeEventDispatcher(exports); - + // For unit testing exports.launcherUrl = launcherUrl; exports._getServer = _getServer; diff --git a/src/LiveDevelopment/MultiBrowserImpl/documents/LiveCSSDocument.js b/src/LiveDevelopment/MultiBrowserImpl/documents/LiveCSSDocument.js index 87cd58f400d..f4f2ed3b7b7 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/documents/LiveCSSDocument.js +++ b/src/LiveDevelopment/MultiBrowserImpl/documents/LiveCSSDocument.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -51,7 +51,7 @@ define(function LiveCSSDocumentModule(require, exports, module) { EventDispatcher = require("utils/EventDispatcher"), LiveDocument = require("LiveDevelopment/MultiBrowserImpl/documents/LiveDocument"); - /** + /** * @constructor * @see LiveDocument * @param {LiveDevProtocol} protocol The protocol to use for communicating with the browser. @@ -64,7 +64,7 @@ define(function LiveCSSDocumentModule(require, exports, module) { */ var LiveCSSDocument = function LiveCSSDocument(protocol, urlResolver, doc, editor, roots) { LiveDocument.apply(this, arguments); - + // Add a ref to the doc since we're listening for change events this.doc.addRef(); this.onChange = this.onChange.bind(this); @@ -73,13 +73,13 @@ define(function LiveCSSDocumentModule(require, exports, module) { this.doc.on("change.LiveCSSDocument", this.onChange); this.doc.on("deleted.LiveCSSDocument", this.onDeleted); }; - + LiveCSSDocument.prototype = Object.create(LiveDocument.prototype); LiveCSSDocument.prototype.constructor = LiveCSSDocument; LiveCSSDocument.prototype.parentClass = LiveDocument.prototype; - + EventDispatcher.makeEventDispatcher(LiveCSSDocument.prototype); - + /** * @override * Closes the live document, terminating its connection to the browser. @@ -128,16 +128,16 @@ define(function LiveCSSDocumentModule(require, exports, module) { } } }; - + /** * @override * Returns true if document edits appear live in the connected browser. - * @return {boolean} + * @return {boolean} */ LiveCSSDocument.prototype.isLiveEditingEnabled = function () { return true; }; - + /** Event Handlers *******************************************************/ /** @@ -151,7 +151,7 @@ define(function LiveCSSDocumentModule(require, exports, module) { this._updateBrowser(); }; - /** + /** * @private * Handles when the associated CSS document is deleted on disk. Removes the * stylesheet from the browser and shuts down the live document. @@ -169,15 +169,15 @@ define(function LiveCSSDocumentModule(require, exports, module) { // Only used for unit testing. LiveCSSDocument.prototype.getSourceFromBrowser = function () { var deferred = new $.Deferred(); - + this.protocol.getStylesheetText(this.doc.url) .then(function (res) { deferred.resolve(res.text); }, deferred.reject); - + return deferred.promise(); }; // Export the class module.exports = LiveCSSDocument; -}); \ No newline at end of file +}); diff --git a/src/LiveDevelopment/MultiBrowserImpl/documents/LiveDocument.js b/src/LiveDevelopment/MultiBrowserImpl/documents/LiveDocument.js index fafae596002..2c39f8def64 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/documents/LiveDocument.js +++ b/src/LiveDevelopment/MultiBrowserImpl/documents/LiveDocument.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2014 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. - * + * */ @@ -27,12 +27,12 @@ define(function (require, exports, module) { "use strict"; - + var EditorManager = require("editor/EditorManager"), EventDispatcher = require("utils/EventDispatcher"), PreferencesManager = require("preferences/PreferencesManager"), _ = require("thirdparty/lodash"); - + /** * @const * CSS class to use for live preview errors. @@ -65,7 +65,7 @@ define(function (require, exports, module) { this.urlResolver = urlResolver; this.doc = doc; this.roots = roots || []; - + this._onActiveEditorChange = this._onActiveEditorChange.bind(this); this._onCursorActivity = this._onCursorActivity.bind(this); this._onHighlightPrefChange = this._onHighlightPrefChange.bind(this); @@ -74,7 +74,7 @@ define(function (require, exports, module) { PreferencesManager.stateManager.getPreference("livedev.highlight") .on("change", this._onHighlightPrefChange); - + // Redraw highlights when window gets focus. This ensures that the highlights // will be in sync with any DOM changes that may have occurred. $(window).focus(this._onHighlightPrefChange); @@ -84,30 +84,30 @@ define(function (require, exports, module) { this._attachToEditor(editor); } } - + EventDispatcher.makeEventDispatcher(LiveDocument.prototype); - + /** * Closes the live document, terminating its connection to the browser. */ LiveDocument.prototype.close = function () { - + this._clearErrorDisplay(); this._detachFromEditor(); EditorManager.off("activeEditorChange", this._onActiveEditorChange); PreferencesManager.stateManager.getPreference("livedev.highlight") .off("change", this._onHighlightPrefChange); }; - + /** * Returns true if document edits appear live in the connected browser. * Should be overridden by subclasses. - * @return {boolean} + * @return {boolean} */ LiveDocument.prototype.isLiveEditingEnabled = function () { return false; }; - + /** * Called to turn instrumentation on or off for this file. Triggered by being * requested from the browser. Should be implemented by subclasses if instrumentation @@ -119,7 +119,7 @@ define(function (require, exports, module) { LiveDocument.prototype.setInstrumentationEnabled = function (enabled) { // Does nothing in base class. }; - + /** * Returns the instrumented version of the file. By default, just returns * the document text. Should be overridden by subclasses for cases if instrumentation @@ -131,7 +131,7 @@ define(function (require, exports, module) { body: this.doc.getText() }; }; - + /** * @private * Handles changes to the "Live Highlight" preference, switching it on/off in the browser as appropriate. @@ -143,7 +143,7 @@ define(function (require, exports, module) { this.hideHighlight(); } }; - + /** * @private * Handles when the active editor changes, attaching to the new editor if it's for the current document. @@ -152,16 +152,16 @@ define(function (require, exports, module) { * @param {?Editor} oldActive */ LiveDocument.prototype._onActiveEditorChange = function (event, newActive, oldActive) { - + //FIXME: #7 prevents the page to be reloaded when editing JS files. // Temporarily disabling this code to make JS editing work. // this._detachFromEditor(); - + if (newActive && newActive.document === this.doc) { this._attachToEditor(newActive); } }; - + /** * @private * Attaches to an editor for our associated document when it becomes active. @@ -169,13 +169,13 @@ define(function (require, exports, module) { */ LiveDocument.prototype._attachToEditor = function (editor) { this.editor = editor; - + if (this.editor) { this.editor.on("cursorActivity", this._onCursorActivity); this.updateHighlight(); } }; - + /** * @private * Detaches from the current editor. @@ -200,7 +200,7 @@ define(function (require, exports, module) { } this.updateHighlight(); }; - + /** * @private * Update errors shown by the live document in the editor. Should be called by subclasses @@ -212,7 +212,7 @@ define(function (require, exports, module) { endLine, i, lineHandle; - + if (!this.editor) { return; } @@ -221,23 +221,23 @@ define(function (require, exports, module) { this.editor._codeMirror.operation(function () { // Remove existing errors before marking new ones self._clearErrorDisplay(); - + self._errorLineHandles = self._errorLineHandles || []; - + self.errors.forEach(function (error) { startLine = error.startPos.line; endLine = error.endPos.line; - + for (i = startLine; i < endLine + 1; i++) { lineHandle = self.editor._codeMirror.addLineClass(i, "wrap", SYNC_ERROR_CLASS); self._errorLineHandles.push(lineHandle); } }); }); - + this.trigger("errorStatusChanged", !!this.errors.length); }; - + /** * @private * Clears the errors shown in the attached editor. @@ -245,27 +245,27 @@ define(function (require, exports, module) { LiveDocument.prototype._clearErrorDisplay = function () { var self = this, lineHandle; - + if (!this.editor || !this._errorLineHandles || !this._errorLineHandles.length) { return; } - + this.editor._codeMirror.operation(function () { while (true) { // Iterate over all lines that were previously marked with an error lineHandle = self._errorLineHandles.pop(); - + if (!lineHandle) { break; } - + self.editor._codeMirror.removeLineClass(lineHandle, "wrap", SYNC_ERROR_CLASS); } }); }; - + /** * Returns true if we should be highlighting. * @return {boolean} @@ -273,7 +273,7 @@ define(function (require, exports, module) { LiveDocument.prototype.isHighlightEnabled = function () { return PreferencesManager.getViewState("livedev.highlight"); }; - + /** * Called when the highlight in the browser should be updated because the user has * changed the selection. Does nothing in base class, should be implemented by subclasses @@ -282,7 +282,7 @@ define(function (require, exports, module) { LiveDocument.prototype.updateHighlight = function () { // Does nothing in base class }; - + /** * Hides the current highlight in the browser. * @param {boolean=} temporary If true, this isn't a change of state - we're just about @@ -307,8 +307,8 @@ define(function (require, exports, module) { this._lastHighlight = name; this.protocol.evaluate("_LD.highlightRule(" + JSON.stringify(name) + ")"); }; - - /** + + /** * Highlight all nodes with 'data-brackets-id' value * that matches id, or if id is an array, matches any of the given ids. * Should be called by subclass implementations of @@ -329,7 +329,7 @@ define(function (require, exports, module) { }); this.highlightRule(selector); }; - + /** * Redraw active highlights. */ @@ -338,6 +338,6 @@ define(function (require, exports, module) { this.protocol.evaluate("_LD.redrawHighlights()"); } }; - + module.exports = LiveDocument; -}); \ No newline at end of file +}); diff --git a/src/LiveDevelopment/MultiBrowserImpl/documents/LiveHTMLDocument.js b/src/LiveDevelopment/MultiBrowserImpl/documents/LiveHTMLDocument.js index de59f87afdc..1763796657c 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/documents/LiveHTMLDocument.js +++ b/src/LiveDevelopment/MultiBrowserImpl/documents/LiveHTMLDocument.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -55,52 +55,52 @@ define(function (require, exports, module) { */ function LiveHTMLDocument(protocol, urlResolver, doc, editor) { LiveDocument.apply(this, arguments); - + this._instrumentationEnabled = false; this._relatedDocuments = { stylesheets: {}, scripts: {} }; - + this._onChange = this._onChange.bind(this); this.doc.on("change", this._onChange); - + this._onRelated = this._onRelated.bind(this); this.protocol.on("DocumentRelated", this._onRelated); - + this._onStylesheetAdded = this._onStylesheetAdded.bind(this); this.protocol.on("StylesheetAdded", this._onStylesheetAdded); - + this._onStylesheetRemoved = this._onStylesheetRemoved.bind(this); this.protocol.on("StylesheetRemoved", this._onStylesheetRemoved); - + this._onScriptAdded = this._onScriptAdded.bind(this); this.protocol.on("ScriptAdded", this._onScriptAdded); - + this._onScriptRemoved = this._onScriptRemoved.bind(this); this.protocol.on("ScriptRemoved", this._onScriptRemoved); - + } - + LiveHTMLDocument.prototype = Object.create(LiveDocument.prototype); LiveHTMLDocument.prototype.constructor = LiveHTMLDocument; LiveHTMLDocument.prototype.parentClass = LiveDocument.prototype; - + EventDispatcher.makeEventDispatcher(LiveHTMLDocument.prototype); - + /** * @override * Returns true if document edits appear live in the connected browser. - * @return {boolean} + * @return {boolean} */ LiveHTMLDocument.prototype.isLiveEditingEnabled = function () { return this._instrumentationEnabled; }; - + /** * @override * Called to turn instrumentation on or off for this file. Triggered by being - * requested from the browser. + * requested from the browser. * TODO: this doesn't seem necessary...if we're a live document, we should * always have instrumentation on anyway. * @param {boolean} enabled @@ -116,12 +116,12 @@ define(function (require, exports, module) { HTMLInstrumentation.scanDocument(this.doc); HTMLInstrumentation._markText(this.editor); } - + this._instrumentationEnabled = enabled; }; - + /** - * Returns the instrumented version of the file. + * Returns the instrumented version of the file. * @return {{body: string}} instrumented doc */ LiveHTMLDocument.prototype.getResponseData = function (enabled) { @@ -129,7 +129,7 @@ define(function (require, exports, module) { if (this._instrumentationEnabled) { body = HTMLInstrumentation.generateInstrumentedHTML(this.editor, this.protocol.getRemoteScript()); } - + return { body: body || this.doc.getText() }; @@ -143,7 +143,7 @@ define(function (require, exports, module) { this.doc.off("change", this._onChange); this.parentClass.close.call(this); }; - + /** * @override * Update the highlights in the browser based on the cursor position. @@ -207,10 +207,10 @@ define(function (require, exports, module) { var self = this, result = HTMLInstrumentation.getUnappliedEditList(this.editor, change), applyEditsPromise; - + if (result.edits) { applyEditsPromise = this.protocol.evaluate("_LD.applyDOMEdits(" + JSON.stringify(result.edits) + ")"); - + applyEditsPromise.always(function () { if (!isNestedTimer) { PerfUtils.addMeasurement(perfTimerName); @@ -220,7 +220,7 @@ define(function (require, exports, module) { this.errors = result.errors || []; this._updateErrorDisplay(); - + // Debug-only: compare in-memory vs. in-browser DOM // edit this file or set a conditional breakpoint at the top of this function: // "this._debug = true, false" @@ -232,8 +232,8 @@ define(function (require, exports, module) { }); } }; - - + + /** * @private * Handles message DocumentRelated from the browser. @@ -244,7 +244,7 @@ define(function (require, exports, module) { this._relatedDocuments = msg.related; return; }; - + /** * @private * Handles message Stylesheet.Added from the browser. @@ -255,7 +255,7 @@ define(function (require, exports, module) { this._relatedDocuments.stylesheets[msg.href] = true; return; }; - + /** * @private * Handles message Stylesheet.Removed from the browser. @@ -266,7 +266,7 @@ define(function (require, exports, module) { delete (this._relatedDocuments.stylesheets[msg.href]); return; }; - + /** * @private * Handles message Script.Added from the browser. @@ -288,7 +288,7 @@ define(function (require, exports, module) { delete (this._relatedDocuments.scripts[msg.src]); return; }; - + /** * For the given path, check if the document is related to the live HTML document. * Related means that is an external Javascript or CSS file that is included as part of the DOM. @@ -304,4 +304,4 @@ define(function (require, exports, module) { }; // Export the class module.exports = LiveHTMLDocument; -}); \ No newline at end of file +}); diff --git a/src/LiveDevelopment/MultiBrowserImpl/language/HTMLInstrumentation.js b/src/LiveDevelopment/MultiBrowserImpl/language/HTMLInstrumentation.js index d1ceb807143..b2fb7c96e40 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/language/HTMLInstrumentation.js +++ b/src/LiveDevelopment/MultiBrowserImpl/language/HTMLInstrumentation.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2014 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. - * + * */ @@ -38,8 +38,8 @@ * These IDs are also included in "data-brackets-id" attributes that are inserted in the * HTML code that's served to the browser via the Live Development server. * - * The primary function for that functionality is generateInstrumentedHTML(). This does just - * what it says - it will read the HTML content in the doc and generate instrumented code by + * The primary function for that functionality is generateInstrumentedHTML(). This does just + * what it says - it will read the HTML content in the doc and generate instrumented code by * injecting "data-brackets-id" attributes. Additionally, it caches the parsed DOM for use * by future updates. * @@ -57,15 +57,15 @@ define(function (require, exports, module) { var DocumentManager = require("document/DocumentManager"), HTMLDOMDiff = require("language/HTMLDOMDiff"), HTMLSimpleDOM = require("LiveDevelopment/MultiBrowserImpl/language/HTMLSimpleDOM"); - + var allowIncremental = true; - + // Hash of scanned documents. Key is the full path of the doc. Value is an object // with two properties: timestamp and dom. Timestamp is the document timestamp, // dom is the root node of a simple DOM tree. var _cachedValues = {}; - /** + /** * @private * Removes the cached information (DOM, timestamp, etc.) used by HTMLInstrumentation * for the given document. @@ -78,7 +78,7 @@ define(function (require, exports, module) { document.off(".htmlInstrumentation"); } } - + /** * @private * Checks if two CodeMirror-style {line, ch} positions are equal. @@ -89,11 +89,11 @@ define(function (require, exports, module) { function _posEq(pos1, pos2) { return pos1 && pos2 && pos1.line === pos2.line && pos1.ch === pos2.ch; } - + /** * @private * Filters the given marks to find the ones that correspond to instrumented tags, - * sorts them by their starting position, and looks up and/or stores their ranges + * sorts them by their starting position, and looks up and/or stores their ranges * in the given markCache. * @param {Array} marks An array of mark objects returned by CodeMirror. * @param {Object} markCache An object that maps tag IDs to {mark, range} objects. @@ -118,10 +118,10 @@ define(function (require, exports, module) { mark1.range.from.ch - mark2.range.from.ch : mark1.range.from.line - mark2.range.from.line); }); - + return marks; } - + /** * @private * Finds the mark for the DOM node at the given position in the editor. @@ -130,20 +130,20 @@ define(function (require, exports, module) { * @param {boolean} preferParent If true, and the pos is at one or the other edge of the * innermost marked range, return the immediately enclosing mark instead. * @param {Object=} markCache An optional cache to look up positions of existing - * markers. (This avoids calling the find() operation on marks multiple times, + * markers. (This avoids calling the find() operation on marks multiple times, * which is expensive.) * @return {Object} The CodeMirror mark object that represents the DOM node at the * given position. */ function _getMarkerAtDocumentPos(editor, pos, preferParent, markCache) { var marks, match; - + markCache = markCache || {}; marks = _getSortedTagMarks(editor._codeMirror.findMarksAt(pos), markCache); if (!marks.length) { return null; } - + // The mark with the latest start is the innermost one. match = marks[marks.length - 1]; if (preferParent) { @@ -158,7 +158,7 @@ define(function (require, exports, module) { } } } - + return match.mark; } @@ -170,10 +170,10 @@ define(function (require, exports, module) { * NOTE: This function is "private" for now (has a leading underscore), since * the API is likely to change in the future. * - * @param {Editor} editor The editor to scan. + * @param {Editor} editor The editor to scan. * @param {{line: number, ch: number}} pos The position to find the DOM marker for. * @param {Object=} markCache An optional cache to look up positions of existing - * markers. (This avoids calling the find() operation on marks multiple times, + * markers. (This avoids calling the find() operation on marks multiple times, * which is expensive.) * @return {number} tagID at the specified position, or -1 if there is no tag */ @@ -182,7 +182,7 @@ define(function (require, exports, module) { return (match) ? match.tagID : -1; } - + /** * Recursively walks the SimpleDOM starting at node and marking * all tags in the CodeMirror instance. The more useful interface @@ -201,7 +201,7 @@ define(function (require, exports, module) { var mark = cm.markText(node.startPos, node.endPos); mark.tagID = node.tagID; } - + /** * Clears the marks from the document and creates new ones. * @@ -210,7 +210,7 @@ define(function (require, exports, module) { */ function _markTextFromDOM(editor, dom) { var cm = editor._codeMirror; - + // Remove existing marks var marks = cm.getAllMarks(); cm.operation(function () { @@ -220,11 +220,11 @@ define(function (require, exports, module) { } }); }); - + // Mark _markTags(cm, dom); } - + /** * @constructor * Subclass of HTMLSimpleDOM.Builder that builds an updated DOM after changes have been made, @@ -242,13 +242,13 @@ define(function (require, exports, module) { var text, startOffset = 0, startOffsetPos; this.isIncremental = false; - + function isDangerousEdit(text) { // We don't consider & dangerous since entities only affect text content, not // overall DOM structure. return (/[<>\/=\"\']/).test(text); } - + // If there's more than one change, be conservative and assume we have to do a full reparse. if (changeList && changeList.length === 1) { // If the inserted or removed text doesn't have any characters that could change the @@ -273,20 +273,20 @@ define(function (require, exports, module) { } } } - + if (!this.changedTagID) { // We weren't able to incrementally update, so just rebuild and diff everything. text = editor.document.getText(); } - + HTMLSimpleDOM.Builder.call(this, text, startOffset, startOffsetPos); this.editor = editor; this.cm = editor._codeMirror; this.previousDOM = previousDOM; } - + DOMUpdater.prototype = Object.create(HTMLSimpleDOM.Builder.prototype); - + /** * @private * Returns true if the given node has an ancestor whose tagID is the given ID. @@ -301,7 +301,7 @@ define(function (require, exports, module) { } return !!ancestor; } - + /** * Overrides the `getID` method to return the tag ID from the document. If a viable tag * ID cannot be found in the document marks, then a new ID is returned. This will also @@ -315,7 +315,7 @@ define(function (require, exports, module) { // Get the mark at the start of the tagname (not before the beginning of the tag, because that's // actually inside the parent). var currentTagID = _getTagIDAtDocumentPos(this.editor, HTMLSimpleDOM._offsetPos(newTag.startPos, 1), markCache); - + // If the new tag is in an unmarked range, or the marked range actually corresponds to an // ancestor tag, then this must be a newly inserted tag, so give it a new tag ID. if (currentTagID === -1 || _hasAncestorWithID(newTag, currentTagID)) { @@ -330,7 +330,7 @@ define(function (require, exports, module) { } return currentTagID; }; - + /** * Updates the CodeMirror marks in the editor to reflect the new bounds of nodes in * the given nodeMap. @@ -343,7 +343,7 @@ define(function (require, exports, module) { var updateIDs = Object.keys(nodeMap), cm = this.cm, marks = cm.getAllMarks(); - + cm.operation(function () { marks.forEach(function (mark) { if (mark.hasOwnProperty("tagID") && nodeMap[mark.tagID]) { @@ -359,7 +359,7 @@ define(function (require, exports, module) { updateIDs.splice(updateIDs.indexOf(String(node.tagID)), 1); } }); - + // Any remaining updateIDs are new. updateIDs.forEach(function (id) { var node = nodeMap[id], mark; @@ -370,7 +370,7 @@ define(function (require, exports, module) { }); }); }; - + /** * @private * Creates a map from tagIDs to nodes in the given HTMLSimpleDOM subtree and @@ -379,7 +379,7 @@ define(function (require, exports, module) { */ DOMUpdater.prototype._buildNodeMap = function (root) { var nodeMap = {}; - + function walk(node) { if (node.tagID) { nodeMap[node.tagID] = node; @@ -388,11 +388,11 @@ define(function (require, exports, module) { node.children.forEach(walk); } } - + walk(root); root.nodeMap = nodeMap; }; - + /** * @private * Removes all nodes deleted between the oldSubtree and the newSubtree from the given nodeMap, @@ -410,7 +410,7 @@ define(function (require, exports, module) { delete nodeMap[key]; } }); - + if (deletedIDs.length) { // FUTURE: would be better to cache the mark for each node. Also, could // conceivably combine this with _updateMarkedRanges(). @@ -422,13 +422,13 @@ define(function (require, exports, module) { }); } }; - + /** * Reparses the document (or a portion of it if we can do it incrementally). * Note that in an incremental update, the old DOM is actually mutated (the new * subtree is swapped in for the old subtree). * @return {?{newDOM: Object, oldSubtree: Object, newSubtree: Object}} newDOM is - * the full new DOM. For a full update, oldSubtree is the full old DOM + * the full new DOM. For a full update, oldSubtree is the full old DOM * and newSubtree is the same as newDOM; for an incremental update, * oldSubtree is the portion of the old tree that was reparsed, * newSubtree is the updated version, and newDOM is actually the same @@ -444,7 +444,7 @@ define(function (require, exports, module) { oldSubtree: this.previousDOM, newSubtree: newSubtree }; - + if (!newSubtree) { return null; } @@ -453,7 +453,7 @@ define(function (require, exports, module) { // Find the old subtree that's going to get swapped out. var oldSubtree = this.previousDOM.nodeMap[this.changedTagID], parent = oldSubtree.parent; - + // If we didn't have a parent, then the whole tree changed anyway, so // we'll just return the default result. if (parent) { @@ -466,30 +466,30 @@ define(function (require, exports, module) { oldSubtree.parent = null; newSubtree.parent = parent; parent.children[childIndex] = newSubtree; - + // Overwrite any node mappings in the parent DOM with the // mappings for the new subtree. We keep the nodeMap around // on the new subtree so that the differ can use it later. $.extend(this.previousDOM.nodeMap, newSubtree.nodeMap); - + // Update marked ranges for all items in the new subtree. this._updateMarkedRanges(newSubtree.nodeMap, markCache); - + // Build a local nodeMap for the old subtree so the differ can // use it. this._buildNodeMap(oldSubtree); - + // Clean up the info for any deleted nodes that are no longer in // the new tree. this._handleDeletions(this.previousDOM.nodeMap, oldSubtree.nodeMap, newSubtree.nodeMap); - + // Update the signatures for all parents of the new subtree. var curParent = parent; while (curParent) { curParent.update(); curParent = curParent.parent; } - + result.newDOM = this.previousDOM; result.oldSubtree = oldSubtree; } @@ -497,10 +497,10 @@ define(function (require, exports, module) { } else { _markTextFromDOM(this.editor, result.newDOM); } - + return result; }; - + /** * @private * Builds a new DOM for the current state of the editor, diffs it against the @@ -527,21 +527,21 @@ define(function (require, exports, module) { if (!result) { return { errors: updater.errors }; } - + var edits = HTMLDOMDiff.domdiff(result.oldSubtree, result.newSubtree); - + // We're done with the nodeMap that was added to the subtree by the updater. if (result.newSubtree !== result.newDOM) { delete result.newSubtree.nodeMap; } - + return { dom: result.newDOM, edits: edits, _wasIncremental: updater.isIncremental // for unit tests only }; } - + /** * Calculates the DOM edits that are needed to update the browser from the state the * editor was in the last time that scanDocument(), getInstrumentedHTML(), or @@ -550,11 +550,11 @@ define(function (require, exports, module) { * * For simple text edits, this update is done quickly and incrementally. For structural * edits (edits that change the DOM structure or add/remove attributes), the update - * requires a full reparse. + * requires a full reparse. * - * If the document currently contains invalid HTML, no edits will be generated until - * getUnappliedEditList() is called when the document is valid, at which point the edits - * will reflect all the changes needed to catch the browser up with all the edits + * If the document currently contains invalid HTML, no edits will be generated until + * getUnappliedEditList() is called when the document is valid, at which point the edits + * will reflect all the changes needed to catch the browser up with all the edits * made while the document was invalid. * * @param {Editor} editor The editor containing the instrumented HTML @@ -566,15 +566,15 @@ define(function (require, exports, module) { */ function getUnappliedEditList(editor, changeList) { var cachedValue = _cachedValues[editor.document.file.fullPath]; - + // We might not have a previous DOM if the document was empty before this edit. if (!cachedValue || !cachedValue.dom || _cachedValues[editor.document.file.fullPath].invalid) { // We were in an invalid state, so do a full rebuild. changeList = null; } - + var result = _updateDOM(cachedValue && cachedValue.dom, editor, changeList); - + if (!result.errors) { _cachedValues[editor.document.file.fullPath] = { timestamp: editor.document.diskTimestamp, @@ -594,7 +594,7 @@ define(function (require, exports, module) { return { errors: result.errors }; } } - + /** * @private * Add SimpleDOMBuilder metadata to browser DOM tree JSON representation @@ -603,29 +603,29 @@ define(function (require, exports, module) { function _processBrowserSimpleDOM(browserRoot, editorRootTagID) { var nodeMap = {}, root; - + function _processElement(elem) { elem.tagID = elem.attributes["data-brackets-id"]; - + // remove data-brackets-id attribute for diff delete elem.attributes["data-brackets-id"]; - + elem.children.forEach(function (child) { // set parent child.parent = elem; - + if (child.isElement()) { _processElement(child); } else if (child.isText()) { child.update(); child.tagID = HTMLSimpleDOM.getTextNodeID(child); - + nodeMap[child.tagID] = child; } }); - + elem.update(); - + nodeMap[elem.tagID] = elem; // Choose the root element based on the root tag in the editor. @@ -634,7 +634,7 @@ define(function (require, exports, module) { root = elem; } } - + _processElement(browserRoot); root = root || browserRoot; @@ -642,7 +642,7 @@ define(function (require, exports, module) { return root; } - + /** * @private * Diff the browser DOM with the in-editor DOM @@ -653,18 +653,18 @@ define(function (require, exports, module) { var cachedValue = _cachedValues[editor.document.file.fullPath], editorRoot = cachedValue.dom, browserRoot; - + browserRoot = _processBrowserSimpleDOM(browserSimpleDOM, editorRoot.tagID); - + return { diff : HTMLDOMDiff.domdiff(editorRoot, browserRoot), browser : browserRoot, editor : editorRoot }; } - + DocumentManager.on("beforeDocumentDelete", _removeDocFromCache); - + /** * Parses the document, returning an HTMLSimpleDOM structure and caching it as the * initial state of the document. Will return a cached copy of the DOM if the @@ -674,7 +674,7 @@ define(function (require, exports, module) { * ahead of time so the DOM is cached and doesn't need to be rescanned when the * instrumented HTML is requested by the browser. * - * @param {Document} doc The doc to scan. + * @param {Document} doc The doc to scan. * @return {Object} Root DOM node of the document. */ function scanDocument(doc) { @@ -686,11 +686,11 @@ define(function (require, exports, module) { // _cachedValues[doc.file.fullPath].dirty = true; // } // }); - + // Assign to cache, but don't set a value yet _cachedValues[doc.file.fullPath] = null; } - + var cachedValue = _cachedValues[doc.file.fullPath]; // TODO: No longer look at doc or cached value "dirty" settings, because even if the doc is dirty, the dom // should generally be up to date unless the HTML is invalid. (However, the node offsets will be dirty of @@ -698,10 +698,10 @@ define(function (require, exports, module) { if (cachedValue && !cachedValue.invalid && cachedValue.timestamp === doc.diskTimestamp) { return cachedValue.dom; } - + var text = doc.getText(), dom = HTMLSimpleDOM.build(text); - + if (dom) { // Cache results _cachedValues[doc.file.fullPath] = { @@ -712,15 +712,15 @@ define(function (require, exports, module) { // Note that this was a full build, so we know that we can trust the node start/end offsets. dom.fullBuild = true; } - + return dom; } - + /** - * Generate instrumented HTML for the specified editor's document, and mark the associated tag - * ranges in the editor. Each tag has a "data-brackets-id" attribute with a unique ID for its - * value. For example, "
" becomes something like "
". The attribute - * value is just a number that is guaranteed to be unique. + * Generate instrumented HTML for the specified editor's document, and mark the associated tag + * ranges in the editor. Each tag has a "data-brackets-id" attribute with a unique ID for its + * value. For example, "
" becomes something like "
". The attribute + * value is just a number that is guaranteed to be unique. * * Also stores marks in the given editor that correspond to the tag ranges. These marks are used * to track the DOM structure for in-browser highlighting and live HTML updating. @@ -741,11 +741,11 @@ define(function (require, exports, module) { lastIndex = 0, remoteScriptInserted = false, markCache; - + if (!dom) { return null; } - + // Ensure that the marks in the editor are up to date with respect to the given DOM. // (But only do this if the dom we got back from scanDocument() was a full rebuild. Otherwise, // rely on the marks in the editor.) @@ -759,13 +759,13 @@ define(function (require, exports, module) { } }); } - + // Walk through the dom nodes and insert the 'data-brackets-id' attribute at the - // end of the open tag + // end of the open tag function walk(node) { if (node.tag) { var attrText = " data-brackets-id='" + node.tagID + "'"; - + // If the dom was fully rebuilt, use its offsets. Otherwise, use the marks in the // associated editor, since they'll be more up to date. var startOffset; @@ -780,12 +780,12 @@ define(function (require, exports, module) { startOffset = node.start; } } - + // Insert the attribute as the first attribute in the tag. var insertIndex = startOffset + node.tag.length + 1; gen += orig.substr(lastIndex, insertIndex - lastIndex) + attrText; lastIndex = insertIndex; - + // If we have a script to inject and this is the head tag, inject it immediately // after the open tag. if (remoteScript && !remoteScriptInserted && node.tag === "head") { @@ -795,15 +795,15 @@ define(function (require, exports, module) { remoteScriptInserted = true; } } - + if (node.isElement()) { node.children.forEach(walk); } } - + walk(dom); gen += orig.substr(lastIndex); - + if (remoteScript && !remoteScriptInserted) { // if the remote script couldn't be injected before (e.g. due to missing "head" tag), // append it at the end @@ -812,9 +812,9 @@ define(function (require, exports, module) { return gen; } - + /** - * Mark the text for the specified editor. Either scanDocument() or + * Mark the text for the specified editor. Either scanDocument() or * generateInstrumentedHTML() must be called before this function * is called. * @@ -827,7 +827,7 @@ define(function (require, exports, module) { function _markText(editor) { var cache = _cachedValues[editor.document.file.fullPath], dom = cache && cache.dom; - + if (!dom) { console.error("Couldn't find the dom for " + editor.document.file.fullPath); return; @@ -835,10 +835,10 @@ define(function (require, exports, module) { console.error("Tried to mark text from a stale DOM for " + editor.document.file.fullPath); return; } - + _markTextFromDOM(editor, dom); } - + /** * @private * Clear the DOM cache. For unit testing only. @@ -856,7 +856,7 @@ define(function (require, exports, module) { exports._allowIncremental = allowIncremental; exports._getBrowserDiff = _getBrowserDiff; exports._resetCache = _resetCache; - + // public API exports.scanDocument = scanDocument; exports.generateInstrumentedHTML = generateInstrumentedHTML; diff --git a/src/LiveDevelopment/MultiBrowserImpl/language/HTMLSimpleDOM.js b/src/LiveDevelopment/MultiBrowserImpl/language/HTMLSimpleDOM.js index a47c4c50a9a..b2cf46ef488 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/language/HTMLSimpleDOM.js +++ b/src/LiveDevelopment/MultiBrowserImpl/language/HTMLSimpleDOM.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2014 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. - * + * */ @@ -28,15 +28,15 @@ define(function (require, exports, module) { "use strict"; - + var Tokenizer = require("language/HTMLTokenizer").Tokenizer, MurmurHash3 = require("thirdparty/murmurhash3_gc"), PerfUtils = require("utils/PerfUtils"); - + var seed = Math.floor(Math.random() * 65535); - + var tagID = 1; - + /** * A list of tags whose start causes any of a given set of immediate parent * tags to close. This mostly comes from the HTML5 spec section on omitted close tags: @@ -113,7 +113,7 @@ define(function (require, exports, module) { track: true, wbr: true }; - + /** * @constructor * @@ -127,9 +127,9 @@ define(function (require, exports, module) { function SimpleNode(properties) { $.extend(this, properties); } - + SimpleNode.prototype = { - + /** * Updates signatures used to optimize the number of comparisons done during * diffing. This is important to call if you change: @@ -161,7 +161,7 @@ define(function (require, exports, module) { this.textSignature = MurmurHash3.hashString(this.content, this.content.length, seed); } }, - + /** * Updates the signature of this node's attributes. Call this after making attribute changes. */ @@ -169,7 +169,7 @@ define(function (require, exports, module) { var attributeString = JSON.stringify(this.attributes); this.attributeSignature = MurmurHash3.hashString(attributeString, attributeString.length, seed); }, - + /** * Is this node an element node? * @@ -178,7 +178,7 @@ define(function (require, exports, module) { isElement: function () { return !!this.children; }, - + /** * Is this node a text node? * @@ -188,7 +188,7 @@ define(function (require, exports, module) { return !this.children; } }; - + /** * @private * @@ -205,7 +205,7 @@ define(function (require, exports, module) { } return textNode.parent.children[childIndex - 1].tagID + "t"; } - + /** * @private * @@ -214,7 +214,7 @@ define(function (require, exports, module) { function _addPos(pos1, pos2) { return {line: pos1.line + pos2.line, ch: (pos2.line === 0 ? pos1.ch + pos2.ch : pos2.ch)}; } - + /** * @private * @@ -224,14 +224,14 @@ define(function (require, exports, module) { function _offsetPos(pos, offset) { return {line: pos.line, ch: pos.ch + offset}; } - + /** * @constructor * * A Builder creates a SimpleDOM tree of SimpleNode objects representing the * "important" contents of an HTML document. It does not include things like comments. * The nodes include information about their position in the text provided. - * + * * @param {string} text The text to parse * @param {?int} startOffset starting offset in the text * @param {?{line: int, ch: int}} startOffsetPos line/ch position in the text @@ -249,7 +249,7 @@ define(function (require, exports, module) { var error = { token: token }, startPos = token ? (token.startPos || token.endPos) : this.startOffsetPos, endPos = token ? token.endPos : this.startOffsetPos; - + error.startPos = _addPos(this.startOffsetPos, startPos); error.endPos = _addPos(this.startOffsetPos, endPos); @@ -259,7 +259,7 @@ define(function (require, exports, module) { this.errors.push(error); }; - + /** * Builds the SimpleDOM. * @@ -273,24 +273,24 @@ define(function (require, exports, module) { var stack = this.stack; var attributeName = null; var nodeMap = {}; - + markCache = markCache || {}; - + // Start timers for building full and partial DOMs. // Appropriate timer is used, and the other is discarded. var timerBuildFull = "HTMLInstr. Build DOM Full"; var timerBuildPart = "HTMLInstr. Build DOM Partial"; PerfUtils.markStart([timerBuildFull, timerBuildPart]); - + function closeTag(endIndex, endPos) { lastClosedTag = stack[stack.length - 1]; stack.pop(); lastClosedTag.update(); - + lastClosedTag.end = self.startOffset + endIndex; lastClosedTag.endPos = _addPos(self.startOffsetPos, endPos); } - + while ((token = this.t.nextToken()) !== null) { // lastTextNode is used to glue text nodes together // If the last node we saw was text but this one is not, then we're done gluing. @@ -298,7 +298,7 @@ define(function (require, exports, module) { if (token.type !== "text" && token.type !== "comment" && lastTextNode) { lastTextNode = null; } - + if (token.type === "error") { PerfUtils.finalizeMeasurement(timerBuildFull); // discard PerfUtils.addMeasurement(timerBuildPart); // use @@ -307,7 +307,7 @@ define(function (require, exports, module) { } else if (token.type === "opentagname") { var newTagName = token.contents.toLowerCase(), newTag; - + if (openImpliesClose.hasOwnProperty(newTagName)) { var closable = openImpliesClose[newTagName]; while (stack.length > 0 && closable.hasOwnProperty(stack[stack.length - 1].tag)) { @@ -316,7 +316,7 @@ define(function (require, exports, module) { closeTag(token.start - 1, _offsetPos(token.startPos, -1)); } } - + newTag = new SimpleNode({ tag: token.contents.toLowerCase(), children: [], @@ -326,20 +326,20 @@ define(function (require, exports, module) { startPos: _addPos(this.startOffsetPos, _offsetPos(token.startPos, -1)) // ok because we know the previous char was a "<" }); newTag.tagID = this.getID(newTag, markCache); - + // During undo in particular, it's possible that tag IDs may be reused and // the marks in the document may be misleading. If a tag ID has been reused, // we apply a new tag ID to ensure that our edits come out correctly. if (nodeMap[newTag.tagID]) { newTag.tagID = this.getNewID(); } - + nodeMap[newTag.tagID] = newTag; if (newTag.parent) { newTag.parent.children.push(newTag); } this.currentTag = newTag; - + if (voidElements.hasOwnProperty(newTag.tag)) { // This is a self-closing element. newTag.update(); @@ -425,7 +425,7 @@ define(function (require, exports, module) { if (stack.length) { var parent = stack[stack.length - 1]; var newNode; - + // Check to see if we're continuing a previous text. if (lastTextNode) { newNode = lastTextNode; @@ -440,13 +440,13 @@ define(function (require, exports, module) { nodeMap[newNode.tagID] = newNode; lastTextNode = newNode; } - + newNode.update(); } } lastIndex = token.end; } - + // If we have any tags hanging open (e.g. html or body), fail the parse if we're in strict mode, // otherwise close them at the end of the document. if (stack.length) { @@ -466,7 +466,7 @@ define(function (require, exports, module) { } } } - + var dom = lastClosedTag; if (!dom) { // This can happen if the document has no nontrivial content, or if the user tries to @@ -475,14 +475,14 @@ define(function (require, exports, module) { this._logError(token); return null; } - + dom.nodeMap = nodeMap; PerfUtils.addMeasurement(timerBuildFull); // use PerfUtils.finalizeMeasurement(timerBuildPart); // discard - + return dom; }; - + /** * Returns a new tag ID. * @@ -491,9 +491,9 @@ define(function (require, exports, module) { Builder.prototype.getNewID = function () { return tagID++; }; - + /** - * Returns the best tag ID for the new tag object given. + * Returns the best tag ID for the new tag object given. * The default implementation just calls `getNewID` * and returns a unique ID. * @@ -501,7 +501,7 @@ define(function (require, exports, module) { * @return {int} unique tag ID */ Builder.prototype.getID = Builder.prototype.getNewID; - + /** * Builds a SimpleDOM from the text provided. If `strict` mode is true, parsing * will halt as soon as any error is seen and null will be returned. @@ -514,7 +514,7 @@ define(function (require, exports, module) { var builder = new Builder(text); return builder.build(strict); } - + /** * @private * @@ -526,7 +526,7 @@ define(function (require, exports, module) { function _dumpDOM(root) { var result = "", indent = ""; - + function walk(node) { if (node.tag) { result += indent + "TAG " + node.tagID + " " + node.tag + " " + JSON.stringify(node.attributes) + "\n"; @@ -540,18 +540,18 @@ define(function (require, exports, module) { } } walk(root); - + return result; } - + // Public API exports.build = build; exports.Builder = Builder; exports.SimpleNode = SimpleNode; - + // Private API exports._dumpDOM = _dumpDOM; exports._offsetPos = _offsetPos; exports._getTextNodeID = getTextNodeID; exports._seed = seed; -}); \ No newline at end of file +}); diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/Launcher.js b/src/LiveDevelopment/MultiBrowserImpl/launchers/Launcher.js index 029da08ec22..119dfaa601f 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/launchers/Launcher.js +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/Launcher.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2014 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, forin: true, maxerr: 50, regexp: true */ @@ -27,17 +27,17 @@ define(function (require, exports, module) { "use strict"; - + var FileUtils = require("file/FileUtils"), NodeDomain = require("utils/NodeDomain"); - + var _bracketsPath = FileUtils.getNativeBracketsDirectoryPath(), _modulePath = FileUtils.getNativeModuleDirectoryPath(module), _nodePath = "node/LauncherDomain", _domainPath = [_bracketsPath, _modulePath, _nodePath].join("/"), _nodeDomain = new NodeDomain("launcher", _domainPath); - - + + /** * Launch the given URL in the system default browser. * @param {string} url @@ -46,8 +46,8 @@ define(function (require, exports, module) { // launch from node domain _nodeDomain.exec("launch", url); } - - // Exports + + // Exports exports.launch = launch; -}); \ No newline at end of file +}); diff --git a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/LauncherDomain.js b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/LauncherDomain.js index 8791a2a79cc..53bebb7b6c1 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/launchers/node/LauncherDomain.js +++ b/src/LiveDevelopment/MultiBrowserImpl/launchers/node/LauncherDomain.js @@ -1,33 +1,33 @@ /* * Copyright (c) 2014 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, node: true */ (function () { "use strict"; - + var open = require("open"); - + /** * @private * The Brackets domain manager for registering node extensions. @@ -43,8 +43,8 @@ function _cmdLaunch(url) { open(url); } - - + + /** * Initializes the domain and registers commands. * @param {DomainManager} domainManager The DomainManager for the server @@ -69,5 +69,5 @@ } exports.init = init; - + }()); diff --git a/src/LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol.js b/src/LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol.js index 6144ca25ffc..9c528da16a1 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol.js +++ b/src/LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2014 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, forin: true, maxerr: 50, regexp: true */ @@ -31,54 +31,54 @@ * response is returned through a promise as an object. Scripts that implement remote logic are * provided during the instrumentation stage by "getRemoteFunctions()". * - * Events raised by the remote browser are dispatched as jQuery events which type is equal to the 'method' - * property. The received message object is dispatched as the first parameter and enriched with a + * Events raised by the remote browser are dispatched as jQuery events which type is equal to the 'method' + * property. The received message object is dispatched as the first parameter and enriched with a * 'clientId' property being the client ID of the remote browser. * - * It keeps active connections which are updated when receiving "connect" and "close" from the - * underlying transport. Events "Connection.connect"/"Connection.close" are triggered as + * It keeps active connections which are updated when receiving "connect" and "close" from the + * underlying transport. Events "Connection.connect"/"Connection.close" are triggered as * propagation of transport's "connect"/"close". - * + * */ define(function (require, exports, module) { "use strict"; - + var EventDispatcher = require("utils/EventDispatcher"); - + // Text of the script we'll inject into the browser that handles protocol requests. var LiveDevProtocolRemote = require("text!LiveDevelopment/MultiBrowserImpl/protocol/remote/LiveDevProtocolRemote.js"), DocumentObserver = require("text!LiveDevelopment/MultiBrowserImpl/protocol/remote/DocumentObserver.js"), RemoteFunctions = require("text!LiveDevelopment/Agents/RemoteFunctions.js"); - + /** * @private * Active connections. * @type {Object} */ var _connections = {}; - + /** * @private * The low-level transport we're communicating over, set by `setTransport()`. * @type {{start: function(), send: function(number|Array., string), close: function(number), getRemoteScript: function(): ?string}} */ var _transport = null; - + /** * @private * A unique message serial number, used to match up responses with request messages. * @type {number} */ var _nextMsgId = 1; - + /** * @private * A map of response IDs to deferreds, for messages that are awaiting responses. * @type {Object} */ var _responseDeferreds = {}; - + /** * Returns an array of the client IDs that are being managed by this live document. * @return {Array.} @@ -86,7 +86,7 @@ define(function (require, exports, module) { function getConnectionIds() { return Object.keys(_connections); } - + /** * @private * Handles a message received from the remote protocol handler via the transport. @@ -118,7 +118,7 @@ define(function (require, exports, module) { exports.trigger(event, msg); } } - + /** * @private * Dispatches a message to the remote protocol handler via the transport. @@ -131,7 +131,7 @@ define(function (require, exports, module) { function _send(msg, clients) { var id = _nextMsgId++, result = new $.Deferred(); - + // broadcast if there are no specific clients clients = clients || getConnectionIds(); msg.id = id; @@ -139,7 +139,7 @@ define(function (require, exports, module) { _transport.send(clients, JSON.stringify(msg)); return result.promise(); } - + /** * @private * Handles when a connection is made to the live development protocol handler. @@ -158,7 +158,7 @@ define(function (require, exports, module) { url: url }); } - + /** * @private * Handles when a connection is closed. @@ -170,8 +170,8 @@ define(function (require, exports, module) { clientId: clientId }); } - - + + /** * Sets the transport that should be used by the protocol. See `LiveDevelopment.setTransport()` * for more detail on the transport. @@ -182,7 +182,7 @@ define(function (require, exports, module) { _transport.off(".livedev"); } _transport = transport; - + _transport .on("connect.livedev", function (event, msg) { _connect(msg[0], msg[1]); @@ -195,11 +195,11 @@ define(function (require, exports, module) { }); _transport.start(); } - - + + /** * Returns a script that should be injected into the HTML that's launched in the - * browser in order to implement remote commands that handle protocol requests. + * browser in order to implement remote commands that handle protocol requests. * Includes the \n"; } - + /** * Returns a script that should be injected into the HTML that's launched in the * browser in order to handle protocol requests. Includes the \n" + remoteFunctionsScript; } - + /** * Protocol method. Evaluates the given script in the browser (in global context), and returns a promise * that will be fulfilled with the result of the script, if any. @@ -246,7 +246,7 @@ define(function (require, exports, module) { clients ); } - + /** * Protocol method. Reloads a CSS styleseet in the browser (by replacing its text) given its url. * @param {string} url Absolute URL of the stylesheet @@ -267,7 +267,7 @@ define(function (require, exports, module) { } ); } - + /** * Protocol method. Rretrieves the content of a given stylesheet (for unit testing) * @param {number|Array.} clients A client ID or array of client IDs that should navigate to the given URL. @@ -286,7 +286,7 @@ define(function (require, exports, module) { clients ); } - + /** * Protocol method. Reloads the page that is currently loaded into the browser, optionally ignoring cache. * @param {number|Array.} clients A client ID or array of client IDs that should reload the page. @@ -305,9 +305,9 @@ define(function (require, exports, module) { clients ); } - + /** - * Protocol method. Navigates current page to the given URL. + * Protocol method. Navigates current page to the given URL. * @param {number|Array.} clients A client ID or array of client IDs that should navigate to the given URL. * @param {string} url URL to navigate the page to. * @return {$.Promise} A promise that's resolved with the return value from the first client that responds @@ -324,7 +324,7 @@ define(function (require, exports, module) { clients ); } - + /** * Closes the connection to the given client. Proxies to the transport. * @param {number} clientId @@ -332,16 +332,16 @@ define(function (require, exports, module) { function close(clientId) { _transport.close(clientId); } - + function closeAllConnections() { getConnectionIds().forEach(function (clientId) { close(clientId); }); _connections = {}; } - + EventDispatcher.makeEventDispatcher(exports); - + // public API exports.setTransport = setTransport; exports.getRemoteScript = getRemoteScript; diff --git a/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/DocumentObserver.js b/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/DocumentObserver.js index 75f42136830..51418c22ac2 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/DocumentObserver.js +++ b/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/DocumentObserver.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2014 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, forin: true, maxerr: 50, regexp: true */ @@ -26,16 +26,16 @@ (function (global) { "use strict"; - + var ProtocolManager = global._Brackets_LiveDev_ProtocolManager; - + var _document = null; var _transport; - + /** * Retrieves related documents (external CSS and JS files) - * + * * @return {{scripts: object, stylesheets: object}} Related scripts and stylesheets */ function related() { @@ -52,7 +52,7 @@ rel.scripts[_document.scripts[i].src] = true; } } - + var s, j; //traverse @import rules var traverseRules = function _traverseRules(sheet, base) { @@ -90,12 +90,12 @@ } return rel; } - + /** * Common functions. */ var Utils = { - + isExternalStylesheet: function (node) { return (node.nodeName.toUpperCase() === "LINK" && node.rel === "stylesheet" && node.href); }, @@ -103,40 +103,40 @@ return (node.nodeName.toUpperCase() === "SCRIPT" && node.src); } }; - + /** * CSS related commands and notifications */ var CSS = { - + /** * Maintains a map of stylesheets loaded thorugh @import rules and their parents. * Populated by extractImports, consumed by notifyImportsAdded / notifyImportsRemoved. * @type { */ stylesheets : {}, - + /** - * Check the stylesheet that was just added be really loaded + * Check the stylesheet that was just added be really loaded * to be able to extract potential import-ed stylesheets. * It invokes notifyStylesheetAdded once the sheet is loaded. * @param {string} href Absolute URL of the stylesheet. */ checkForStylesheetLoaded : function (href) { var self = this; - + // Inspect CSSRules for @imports: // styleSheet obejct is required to scan CSSImportRules but // browsers differ on the implementation of MutationObserver interface. - // Webkit triggers notifications before stylesheets are loaded, + // Webkit triggers notifications before stylesheets are loaded, // Firefox does it after loading. - // There are also differences on when 'load' event is triggered for + // There are also differences on when 'load' event is triggered for // the 'link' nodes. Webkit triggers it before stylesheet is loaded. // Some references to check: // http://www.phpied.com/when-is-a-stylesheet-really-loaded/ // http://stackoverflow.com/questions/17747616/webkit-dynamically-created-stylesheet-when-does-it-really-load - // http://stackoverflow.com/questions/11425209/are-dom-mutation-observers-slower-than-dom-mutation-events + // http://stackoverflow.com/questions/11425209/are-dom-mutation-observers-slower-than-dom-mutation-events // // TODO: This is just a temporary 'cross-browser' solution, it needs optimization. var loadInterval = setInterval(function () { @@ -152,35 +152,35 @@ } }, 50); }, - + onStylesheetRemoved : function (url) { // get style node created when setting new text for stylesheet. var s = document.getElementById(url); - // remove + // remove if (s && s.parentNode && s.parentNode.removeChild) { s.parentNode.removeChild(s); } }, - + /** - * Send a notification for the stylesheet added and + * Send a notification for the stylesheet added and * its import-ed styleshets based on document.stylesheets diff - * from previous status. It also updates stylesheets status. + * from previous status. It also updates stylesheets status. */ notifyStylesheetAdded : function () { var added = {}, current, newStatus; - + current = this.stylesheets; newStatus = related().stylesheets; - + Object.keys(newStatus).forEach(function (v, i) { if (!current[v]) { added[v] = newStatus[v]; } }); - + Object.keys(added).forEach(function (v, i) { _transport.send(JSON.stringify({ method: "StylesheetAdded", @@ -188,25 +188,25 @@ roots: [added[v]] })); }); - + this.stylesheets = newStatus; }, - + /** - * Send a notification for the removed stylesheet and + * Send a notification for the removed stylesheet and * its import-ed styleshets based on document.stylesheets diff * from previous status. It also updates stylesheets status. */ notifyStylesheetRemoved : function () { - + var self = this; var removed = {}, newStatus, current; - + current = self.stylesheets; newStatus = related().stylesheets; - + Object.keys(current).forEach(function (v, i) { if (!newStatus[v]) { removed[v] = current[v]; @@ -214,7 +214,7 @@ self.onStylesheetRemoved(current[v]); } }); - + Object.keys(removed).forEach(function (v, i) { _transport.send(JSON.stringify({ method: "StylesheetRemoved", @@ -222,12 +222,12 @@ roots: [removed[v]] })); }); - + self.stylesheets = newStatus; } }; - + /* process related docs added */ function _onNodesAdded(nodes) { var i; @@ -250,7 +250,7 @@ var i; //iterate on removed nodes for (i = 0; i < nodes.length; i++) { - + // check for external JS files if (Utils.isExternalScript(nodes[i])) { _transport.send(JSON.stringify({ @@ -284,7 +284,7 @@ subtree: true }); } else { - // use MutationEvents as fallback + // use MutationEvents as fallback document.addEventListener('DOMNodeInserted', function niLstnr(e) { _onNodesAdded([e.target]); }); @@ -293,11 +293,11 @@ }); } } - - + + /** * Start listening for events and send initial related documents message. - * + * * @param {HTMLDocument} document * @param {object} transport Live development transport connection */ @@ -306,10 +306,10 @@ _document = document; // start listening to node changes _enableListeners(); - + var rel = related(); - - // send the current status of related docs. + + // send the current status of related docs. _transport.send(JSON.stringify({ method: "DocumentRelated", related: rel @@ -317,13 +317,13 @@ // initialize stylesheets with current status for further notifications. CSS.stylesheets = rel.stylesheets; } - + /** * Stop listening. * TODO currently a no-op. */ function stop() { - + } var DocumentObserver = { @@ -331,7 +331,7 @@ stop: stop, related: related }; - + ProtocolManager.setDocumentObserver(DocumentObserver); - -}(this)); \ No newline at end of file + +}(this)); diff --git a/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/LiveDevProtocolRemote.js b/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/LiveDevProtocolRemote.js index 82df671037a..d5963765c62 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/LiveDevProtocolRemote.js +++ b/src/LiveDevelopment/MultiBrowserImpl/protocol/remote/LiveDevProtocolRemote.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2014 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, forin: true, maxerr: 50, regexp: true */ @@ -30,7 +30,7 @@ (function (global) { "use strict"; - + // This protocol handler assumes that there is also an injected transport script that // has the following methods: // setCallbacks(obj) - a method that takes an object with a "message" callback that @@ -40,20 +40,20 @@ /** * Manage messaging between Editor and Browser at the protocol layer. - * Handle messages that arrives through the current transport and dispatch them + * Handle messages that arrives through the current transport and dispatch them * to subscribers. Subscribers are handlers that implements remote commands/functions. - * Property 'method' of messages body is used as the 'key' to identify message types. + * Property 'method' of messages body is used as the 'key' to identify message types. * Provide a 'send' operation that allows remote commands sending messages to the Editor. */ var MessageBroker = { - + /** * Collection of handlers (subscribers) per each method. - * To be pushed by 'on' and consumed by 'trigger' stored this way: + * To be pushed by 'on' and consumed by 'trigger' stored this way: * handlers[method] = [handler1, handler2, ...] */ handlers: {}, - + /** * Dispatch messages to handlers according to msg.method value. * @param {Object} msg Message to be dispatched. @@ -68,7 +68,7 @@ } // get handlers for msg.method msgHandlers = this.handlers[msg.method]; - + if (msgHandlers && msgHandlers.length > 0) { // invoke handlers with the received message msgHandlers.forEach(function (handler) { @@ -89,7 +89,7 @@ return; } }, - + /** * Send a response of a particular message to the Editor. * Original message must provide an 'id' property @@ -104,7 +104,7 @@ response.id = orig.id; this.send(response); }, - + /** * Subscribe handlers to specific messages. * @param {string} method Message type. @@ -122,7 +122,7 @@ // add handler to the stack this.handlers[method].push(handler); }, - + /** * Send a message to the Editor. * @param {string} msgStr Message to be sent. @@ -131,7 +131,7 @@ transport.send(JSON.stringify(msgStr)); } }; - + /** * Runtime Domain. Implements remote commands for "Runtime.*" */ @@ -147,21 +147,21 @@ }); } }; - + // subscribe handler to method Runtime.evaluate MessageBroker.on("Runtime.evaluate", Runtime.evaluate); - + /** * CSS Domain. */ var CSS = { - + setStylesheetText : function (msg) { - + if (!msg || !msg.params || !msg.params.text || !msg.params.url) { return; } - + var i, node; @@ -178,7 +178,7 @@ // now can remove the style element previously created (if any) node.ownerNode.parentNode.removeChild(node.ownerNode); } else if (node.href === msg.params.url && !node.disabled) { - // if the link element to change + // if the link element to change head.insertBefore(s, node.ownerNode); // insert the style element here node.disabled = true; i++; // since we have just inserted a stylesheet @@ -186,7 +186,7 @@ } s.id = msg.params.url; }, - + /** * retrieves the content of the stylesheet * TODO: it now depends on reloadCSS implementation @@ -222,16 +222,16 @@ } } } - + MessageBroker.respond(msg, { text: text }); } }; - + MessageBroker.on("CSS.setStylesheetText", CSS.setStylesheetText); MessageBroker.on("CSS.getStylesheetText", CSS.getStylesheetText); - + /** * Page Domain. */ @@ -244,7 +244,7 @@ // just reload the page window.location.reload(msg.params.ignoreCache); }, - + /** * Navigate to a different page. * @param {Object} msg @@ -256,48 +256,48 @@ } } }; - + // subscribe handler to method Page.reload MessageBroker.on("Page.reload", Page.reload); MessageBroker.on("Page.navigate", Page.navigate); MessageBroker.on("ConnectionClose", Page.close); - - - + + + // By the time this executes, there must already be an active transport. if (!transport) { console.error("[Brackets LiveDev] No transport set"); return; } - + var ProtocolManager = { - + _documentObserver: {}, - + _protocolHandler: {}, - + enable: function () { transport.setCallbacks(this._protocolHandler); transport.enable(); }, - + onConnect: function () { this._documentObserver.start(window.document, transport); }, - + onClose: function () { var body = document.getElementsByTagName("body")[0], overlay = document.createElement("div"), background = document.createElement("div"), status = document.createElement("div"); - + overlay.style.width = "100%"; overlay.style.height = "100%"; overlay.style.zIndex = 2227; overlay.style.position = "absolute"; overlay.style.top = 0; overlay.style.left = 0; - + background.style.backgroundColor = "#fff"; background.style.opacity = 0.5; background.style.width = "100%"; @@ -319,18 +319,18 @@ overlay.appendChild(background); overlay.appendChild(status); body.appendChild(overlay); - + // change the title as well document.title = "(Brackets Live Preview: closed) " + document.title; }, - + setDocumentObserver: function (documentOberver) { if (!documentOberver) { return; } this._documentObserver = documentOberver; }, - + setProtocolHandler: function (protocolHandler) { if (!protocolHandler) { return; @@ -338,10 +338,10 @@ this._protocolHandler = protocolHandler; } }; - + // exposing ProtocolManager global._Brackets_LiveDev_ProtocolManager = ProtocolManager; - + /** * The remote handler for the protocol. */ @@ -362,20 +362,20 @@ // delegates handling/routing to MessageBroker. MessageBroker.trigger(msg); }, - + close: function (evt) { ProtocolManager.onClose(); }, - + connect: function (evt) { ProtocolManager.onConnect(); } }; - + ProtocolManager.setProtocolHandler(ProtocolHandler); - + window.addEventListener('load', function () { ProtocolManager.enable(); }); - + }(this)); diff --git a/src/LiveDevelopment/MultiBrowserImpl/transports/NodeSocketTransport.js b/src/LiveDevelopment/MultiBrowserImpl/transports/NodeSocketTransport.js index dcec6ef7c24..bf8e2bca9ac 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/transports/NodeSocketTransport.js +++ b/src/LiveDevelopment/MultiBrowserImpl/transports/NodeSocketTransport.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2014 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, forin: true, maxerr: 50, regexp: true */ @@ -31,24 +31,24 @@ define(function (require, exports, module) { "use strict"; - + var FileUtils = require("file/FileUtils"), EventDispatcher = require("utils/EventDispatcher"), NodeDomain = require("utils/NodeDomain"); - + // The script that will be injected into the previewed HTML to handle the other side of the socket connection. var NodeSocketTransportRemote = require("text!LiveDevelopment/MultiBrowserImpl/transports/remote/NodeSocketTransportRemote.js"); // The node extension that actually provides the WebSocket server. - + var domainPath = FileUtils.getNativeBracketsDirectoryPath() + "/" + FileUtils.getNativeModuleDirectoryPath(module) + "/node/NodeSocketTransportDomain"; - + var NodeSocketTransportDomain = new NodeDomain("nodeSocketTransport", domainPath); - + // This must match the port declared in NodeSocketTransportDomain.js. // TODO: randomize this? var SOCKET_PORT = 8123; - + /** * Returns the script that should be injected into the browser to handle the other end of the transport. * @return {string} @@ -61,10 +61,10 @@ define(function (require, exports, module) { } // Events - + // We can simply retrigger the events we receive from the node domain directly, since they're in // the same format expected by clients of the transport. - + ["connect", "message", "close"].forEach(function (type) { NodeSocketTransportDomain.on(type, function () { console.log("NodeSocketTransport - event - " + type + " - " + JSON.stringify(Array.prototype.slice.call(arguments, 1))); @@ -72,12 +72,12 @@ define(function (require, exports, module) { exports.trigger(type, Array.prototype.slice.call(arguments, 1)); }); }); - + EventDispatcher.makeEventDispatcher(exports); - + // Exports exports.getRemoteScript = getRemoteScript; - + // Proxy the node domain methods directly through, since they have exactly the same // signatures as the ones we're supposed to provide. ["start", "send", "close"].forEach(function (method) { diff --git a/src/LiveDevelopment/MultiBrowserImpl/transports/node/NodeSocketTransportDomain.js b/src/LiveDevelopment/MultiBrowserImpl/transports/node/NodeSocketTransportDomain.js index e98094661d3..e7a4cd7d88d 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/transports/node/NodeSocketTransportDomain.js +++ b/src/LiveDevelopment/MultiBrowserImpl/transports/node/NodeSocketTransportDomain.js @@ -1,62 +1,62 @@ /* * Copyright (c) 2014 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, node: true */ (function () { "use strict"; - + var WebSocketServer = require("ws").Server, _ = require("lodash"); - + /** * @private * The WebSocket server we listen for incoming connections on. * @type {?WebSocketServer} */ var _wsServer; - + /** * @private * The Brackets domain manager for registering node extensions. * @type {?DomainManager} */ var _domainManager; - + /** * @private * The ID that should be allocated to the next client that connects to the transport. * @type {number} */ var _nextClientId = 1; - + /** * @private * A map of client IDs to the URL and WebSocket for the given ID. * @type {Object.} */ var _clients = {}; - + // This must match the port declared in NodeSocketTransport.js. // TODO: randomize this? var SOCKET_PORT = 8123; @@ -72,7 +72,7 @@ return (client.socket === ws); }); } - + /** * @private * Creates the WebSocketServer and handles incoming connections. @@ -91,7 +91,7 @@ console.error("nodeSocketTransport: Error parsing message: " + msg); return; } - + // See the comment in NodeSocketTransportRemote.connect() for why we have an extra // layer of transport-layer message objects surrounding the protocol messaging. @@ -134,7 +134,7 @@ }); } } - + /** * Initializes the socket server. * @param {string} url @@ -142,7 +142,7 @@ function _cmdStart(url) { _createServer(); } - + /** * Sends a transport-layer message over the socket. * @param {number|Array.} idOrArray A client ID or array of client IDs to send the message to. @@ -161,7 +161,7 @@ } }); } - + /** * Closes the connection for a given client ID. * @param {number} clientId @@ -173,7 +173,7 @@ delete _clients[clientId]; } } - + /** * Initializes the domain and registers commands. * @param {DomainManager} domainManager The DomainManager for the server @@ -238,7 +238,7 @@ ] ); } - + exports.init = init; - + }()); diff --git a/src/LiveDevelopment/MultiBrowserImpl/transports/remote/NodeSocketTransportRemote.js b/src/LiveDevelopment/MultiBrowserImpl/transports/remote/NodeSocketTransportRemote.js index 477893f3722..047ec1eb18b 100644 --- a/src/LiveDevelopment/MultiBrowserImpl/transports/remote/NodeSocketTransportRemote.js +++ b/src/LiveDevelopment/MultiBrowserImpl/transports/remote/NodeSocketTransportRemote.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2014 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 browser: true, vars: true, plusplus: true, devel: true, nomen: true, indent: 4, forin: true, maxerr: 50, regexp: true */ @@ -31,7 +31,7 @@ (function (global) { "use strict"; - + var WebSocketTransport = { /** * @private @@ -39,14 +39,14 @@ * @type {?WebSocket} */ _ws: null, - + /** * @private * An object that contains callbacks to handle various transport events. See `setCallbacks()`. * @type {?{connect: ?function, message: ?function(string), close: ?function}} */ _callbacks: null, - + /** * Sets the callbacks that should be called when various transport events occur. All callbacks * are optional, but you should at least implement "message" or nothing interesting will happen :) @@ -63,7 +63,7 @@ this._callbacks = callbacks; } }, - + /** * Connects to the NodeSocketTransport in Brackets at the given WebSocket URL. * @param {string} url @@ -71,11 +71,11 @@ connect: function (url) { var self = this; this._ws = new WebSocket(url); - + // One potential source of confusion: the transport sends two "types" of messages - // these are distinct from the protocol's own messages. This is because this transport // needs to send an initial "connect" message telling the Brackets side of the transport - // the URL of the page that it's connecting from, distinct from the actual protocol + // the URL of the page that it's connecting from, distinct from the actual protocol // message traffic. Actual protocol messages are sent as a JSON payload in a message of // type "message". // @@ -83,7 +83,7 @@ // talks to an iframe within the same process already knows what URL that iframe is // pointing to, so the only comunication that needs to happen via postMessage() is the // actual protocol message strings, and no extra wrapping is necessary. - + this._ws.onopen = function (event) { // Send the initial "connect" message to tell the other end what URL we're from. self._ws.send(JSON.stringify({ @@ -109,7 +109,7 @@ }; // TODO: onerror }, - + /** * Sends a message over the transport. * @param {string} msgStr The message to send. @@ -126,8 +126,8 @@ console.log("[Brackets LiveDev] Tried to send message over closed connection: " + msgStr); } }, - - /** + + /** * Establish web socket connection. */ enable: function () { diff --git a/src/LiveDevelopment/Servers/BaseServer.js b/src/LiveDevelopment/Servers/BaseServer.js index bf14064e1aa..b46363058ce 100644 --- a/src/LiveDevelopment/Servers/BaseServer.js +++ b/src/LiveDevelopment/Servers/BaseServer.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the + * 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, forin: true, maxerr: 50, regexp: true */ @@ -46,7 +46,7 @@ define(function (require, exports, module) { } /** - * Returns a base url for current project. + * Returns a base url for current project. * * @return {string} * Base url for current project. @@ -127,7 +127,7 @@ define(function (require, exports, module) { // Use base url to translate to local file path. // Need to use encoded project path because it's decoded below. path = url.replace(baseUrl, encodeURI(this._root)); - + return decodeURI(path); } @@ -148,7 +148,7 @@ define(function (require, exports, module) { // Base implementation always resolves return $.Deferred().resolve().promise(); }; - + /** * Determines if this server can serve local file. LiveDevServerManager * calls this method when determining if a server can serve a file. @@ -171,10 +171,10 @@ define(function (require, exports, module) { if (!liveDocument) { return; } - + // use the project relative path as a key to lookup requests var key = this._documentKey(liveDocument.doc.file.fullPath); - + this._setDocInfo(liveDocument); this._liveDocuments[key] = liveDocument; }; @@ -187,9 +187,9 @@ define(function (require, exports, module) { if (!liveDocument) { return; } - + var key = this._liveDocuments[this._documentKey(liveDocument.doc.file.fullPath)]; - + if (key) { delete this._liveDocuments[key]; } diff --git a/src/LiveDevelopment/Servers/FileServer.js b/src/LiveDevelopment/Servers/FileServer.js index 5a94649f4d4..554dd6dc02a 100644 --- a/src/LiveDevelopment/Servers/FileServer.js +++ b/src/LiveDevelopment/Servers/FileServer.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the + * 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, forin: true, maxerr: 50, regexp: true */ @@ -26,7 +26,7 @@ define(function (require, exports, module) { "use strict"; - + var BaseServer = require("LiveDevelopment/Servers/BaseServer").BaseServer, LiveDevelopmentUtils = require("LiveDevelopment/LiveDevelopmentUtils"); @@ -50,7 +50,7 @@ define(function (require, exports, module) { function FileServer(config) { BaseServer.call(this, config); } - + FileServer.prototype = Object.create(BaseServer.prototype); FileServer.prototype.constructor = FileServer; diff --git a/src/LiveDevelopment/Servers/UserServer.js b/src/LiveDevelopment/Servers/UserServer.js index 08775203192..b4cd44fb17d 100644 --- a/src/LiveDevelopment/Servers/UserServer.js +++ b/src/LiveDevelopment/Servers/UserServer.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the + * 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, forin: true, maxerr: 50, regexp: true */ @@ -26,7 +26,7 @@ define(function (require, exports, module) { "use strict"; - + var BaseServer = require("LiveDevelopment/Servers/BaseServer").BaseServer, LiveDevelopmentUtils = require("LiveDevelopment/LiveDevelopmentUtils"); @@ -47,7 +47,7 @@ define(function (require, exports, module) { function UserServer(config) { BaseServer.call(this, config); } - + UserServer.prototype = Object.create(BaseServer.prototype); UserServer.prototype.constructor = UserServer; diff --git a/src/LiveDevelopment/main.js b/src/LiveDevelopment/main.js index 04586a2215b..dd770bc76ac 100644 --- a/src/LiveDevelopment/main.js +++ b/src/LiveDevelopment/main.js @@ -50,7 +50,7 @@ define(function main(require, exports, module) { Strings = require("strings"), ExtensionUtils = require("utils/ExtensionUtils"), StringUtils = require("utils/StringUtils"); - + var params = new UrlParams(); var config = { experimental: false, // enable experimental features @@ -70,10 +70,10 @@ define(function main(require, exports, module) { _allStatusStyles = ["warning", "info", "success", "out-of-sync", "sync-error"].join(" "); var _$btnGoLive; // reference to the GoLive button - + // current selected implementation (LiveDevelopment | LiveDevMultiBrowser) var LiveDevImpl; - + // "livedev.multibrowser" preference var PREF_MULTIBROWSER = "multibrowser"; var prefs = PreferencesManager.getExtensionPrefs("livedev"); @@ -99,21 +99,21 @@ define(function main(require, exports, module) { return val; } - + /* Toggles or sets the "livedev.multibrowser" preference */ function _toggleLivePreviewMultiBrowser(value) { var val = _togglePref(PREF_MULTIBROWSER, value); - + CommandManager.get(Commands.TOGGLE_LIVE_PREVIEW_MB_MODE).setChecked(val); // Issue #10217: multi-browser does not support user server, so disable // the setting if it is enabled. CommandManager.get(Commands.FILE_PROJECT_SETTINGS).setEnabled(!val); } - + /** Load Live Development LESS Style */ function _loadStyles() { var lessText = require("text!LiveDevelopment/main.less"); - + less.render(lessText, function onParse(err, tree) { console.assert(!err, err); ExtensionUtils.addEmbeddedStyleSheet(tree.css); @@ -174,7 +174,7 @@ define(function main(require, exports, module) { function _showStatusChangeReason(reason) { // Destroy the previous twipsy (options are not updated otherwise) _$btnGoLive.twipsy("hide").removeData("twipsy"); - + // If there was no reason or the action was an explicit request by the user, don't show a twipsy if (!reason || reason === "explicit_close") { return; @@ -185,7 +185,7 @@ define(function main(require, exports, module) { if (!translatedReason) { translatedReason = StringUtils.format(Strings.LIVE_DEV_CLOSED_UNKNOWN_REASON, reason); } - + // Configure the twipsy var options = { placement: "left", @@ -199,7 +199,7 @@ define(function main(require, exports, module) { // Show the twipsy with the explanation _$btnGoLive.twipsy(options).twipsy("show"); } - + /** Create the menu item "Go Live" */ function _setupGoLiveButton() { if (!_$btnGoLive) { @@ -222,7 +222,7 @@ define(function main(require, exports, module) { // Initialize tooltip for 'not connected' state _setLabel(_$btnGoLive, null, _status[1].style, _status[1].tooltip); } - + /** Maintains state of the Live Preview menu item */ function _setupGoLiveMenu() { LiveDevImpl.on("statusChange", function statusChange(event, status) { @@ -236,7 +236,7 @@ define(function main(require, exports, module) { function _updateHighlightCheckmark() { CommandManager.get(Commands.FILE_LIVE_HIGHLIGHT).setChecked(config.highlight); } - + function _handlePreviewHighlightCommand() { config.highlight = !config.highlight; _updateHighlightCheckmark(); @@ -247,7 +247,7 @@ define(function main(require, exports, module) { } PreferencesManager.setViewState("livedev.highlight", config.highlight); } - + /** * Sets the MultiBrowserLiveDev implementation if multibrowser is truthy, * keeps default LiveDevelopment implementation based on CDT otherwise. @@ -257,7 +257,7 @@ define(function main(require, exports, module) { if (multibrowser) { // set implemenation LiveDevImpl = MultiBrowserLiveDev; - // update styles for UI status + // update styles for UI status _status = [ { tooltip: Strings.LIVE_DEV_STATUS_TIP_NOT_CONNECTED, style: "warning" }, { tooltip: Strings.LIVE_DEV_STATUS_TIP_NOT_CONNECTED, style: "" }, @@ -286,7 +286,7 @@ define(function main(require, exports, module) { // toggle the menu _toggleLivePreviewMultiBrowser(multibrowser); } - + /** Setup window references to useful LiveDevelopment modules */ function _setupDebugHelpers() { window.ld = LiveDevelopment; @@ -300,25 +300,25 @@ define(function main(require, exports, module) { LiveDevelopment.reload(); } } - + /** Initialize LiveDevelopment */ AppInit.appReady(function () { params.parse(); Inspector.init(config); LiveDevelopment.init(config); - - // init experimental multi-browser implementation + + // init experimental multi-browser implementation // it can be enable by setting 'livedev.multibrowser' preference to true. - // It has to be initiated at this point in case of dynamically switching + // It has to be initiated at this point in case of dynamically switching // by changing the preference value. MultiBrowserLiveDev.init(config); _loadStyles(); _updateHighlightCheckmark(); - + _setImplementation(prefs.get(PREF_MULTIBROWSER)); - + if (config.debug) { _setupDebugHelpers(); } @@ -329,7 +329,7 @@ define(function main(require, exports, module) { DocumentManager.getCurrentDocument()) { _handleGoLiveCommand(); } - + // Redraw highlights when window gets focus. This ensures that the highlights // will be in sync with any DOM changes that may have occurred. $(window).focus(function () { @@ -337,10 +337,10 @@ define(function main(require, exports, module) { LiveDevelopment.redrawHighlight(); } }); - + multiBrowserPref .on("change", function () { - // Stop the current session if it is open and set implementation based on + // Stop the current session if it is open and set implementation based on // the pref value. We could start the new implementation immediately, but // since the current document is potentially a user preferences file, Live // Preview will not locate the html file to serve. @@ -357,27 +357,27 @@ define(function main(require, exports, module) { }); }); - + // init prefs PreferencesManager.stateManager.definePreference("livedev.highlight", "boolean", true) .on("change", function () { config.highlight = PreferencesManager.getViewState("livedev.highlight"); _updateHighlightCheckmark(); }); - + PreferencesManager.convertPreferences(module, { "highlight": "user livedev.highlight", "afterFirstLaunch": "user livedev.afterFirstLaunch" }, true); - + config.highlight = PreferencesManager.getViewState("livedev.highlight"); - + // init commands CommandManager.register(Strings.CMD_LIVE_FILE_PREVIEW, Commands.FILE_LIVE_FILE_PREVIEW, _handleGoLiveCommand); CommandManager.register(Strings.CMD_LIVE_HIGHLIGHT, Commands.FILE_LIVE_HIGHLIGHT, _handlePreviewHighlightCommand); CommandManager.register(Strings.CMD_RELOAD_LIVE_PREVIEW, Commands.CMD_RELOAD_LIVE_PREVIEW, _handleReloadLivePreviewCommand); CommandManager.register(Strings.CMD_TOGGLE_LIVE_PREVIEW_MB_MODE, Commands.TOGGLE_LIVE_PREVIEW_MB_MODE, _toggleLivePreviewMultiBrowser); - + CommandManager.get(Commands.FILE_LIVE_HIGHLIGHT).setEnabled(false); // Export public functions diff --git a/src/brackets.js b/src/brackets.js index ba1f9aa4d0f..a362e8d2d43 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -102,7 +102,7 @@ define(function (require, exports, module) { require("thirdparty/lodash"); require("language/XMLUtils"); require("language/JSONUtils"); - + // DEPRECATED: In future we want to remove the global CodeMirror, but for now we // expose our required CodeMirror globally so as to avoid breaking extensions in the // interim. @@ -114,7 +114,7 @@ define(function (require, exports, module) { return CodeMirror; } }); - + // Load modules that self-register and just need to get included in the main project require("command/DefaultMenus"); require("document/ChangedDocumentTracker"); @@ -127,18 +127,18 @@ define(function (require, exports, module) { require("help/HelpCommandHandlers"); require("search/FindInFilesUI"); require("search/FindReplace"); - + // Compatibility shim for PanelManager to WorkspaceManager migration require("view/PanelManager"); - + PerfUtils.addMeasurement("brackets module dependencies resolved"); - + // Local variables var params = new UrlParams(); - + // read URL params params.parse(); - + /** * Setup test object @@ -219,16 +219,16 @@ define(function (require, exports, module) { // Use quiet scrollbars if we aren't on Lion. If we're on Lion, only // use native scroll bars when the mouse is not plugged in or when - // using the "Always" scroll bar setting. + // using the "Always" scroll bar setting. var osxMatch = /Mac OS X 10\D([\d+])\D/.exec(navigator.userAgent); if (osxMatch && osxMatch[1] && Number(osxMatch[1]) >= 7) { // test a scrolling div for scrollbars var $testDiv = $("
").appendTo(window.document.body); - + if ($testDiv.outerWidth() === $testDiv.get(0).clientWidth) { $(".sidebar").removeClass("quiet-scrollbars"); } - + $testDiv.remove(); } @@ -238,7 +238,7 @@ define(function (require, exports, module) { // extensions fail to load. var extensionPathOverride = params.get("extensions"); // used by unit tests var extensionLoaderPromise = ExtensionLoader.init(extensionPathOverride ? extensionPathOverride.split(",") : null); - + // Load the initial project after extensions have loaded extensionLoaderPromise.always(function () { // Signal that extensions are loaded @@ -249,13 +249,13 @@ define(function (require, exports, module) { var initialProjectPath = ProjectManager.getInitialProjectPath(); ProjectManager.openProject(initialProjectPath).always(function () { _initTest(); - + // If this is the first launch, and we have an index.html file in the project folder (which should be // the samples folder on first launch), open it automatically. (We explicitly check for the // samples folder in case this is the first time we're launching Brackets after upgrading from // an old version that might not have set the "afterFirstLaunch" pref.) var deferred = new $.Deferred(); - + if (!params.get("skipSampleProjectLoad") && !PreferencesManager.getViewState("afterFirstLaunch")) { PreferencesManager.setViewState("afterFirstLaunch", "true"); if (ProjectManager.isWelcomeProjectPath(initialProjectPath)) { @@ -273,13 +273,13 @@ define(function (require, exports, module) { } else { deferred.resolve(); } - + deferred.always(function () { // Signal that Brackets is loaded AppInit._dispatchReady(AppInit.APP_READY); - + PerfUtils.addMeasurement("Application Startup"); - + if (PreferencesManager._isUserScopeCorrupt()) { var userPrefFullPath = PreferencesManager.getUserPrefFile(); // user scope can get corrupt only if the file exists, is readable, @@ -301,9 +301,9 @@ define(function (require, exports, module) { }); }); } - + }); - + // See if any startup files were passed to the application if (brackets.app.getPendingFilesToOpen) { brackets.app.getPendingFilesToOpen(function (err, paths) { @@ -322,14 +322,14 @@ define(function (require, exports, module) { }); } } - + /** * Setup event handlers prior to dispatching AppInit.HTML_READY */ function _beforeHTMLReady() { // Add the platform (mac, win or linux) to the body tag so we can have platform-specific CSS rules $("body").addClass("platform-" + brackets.platform); - + // Browser-hosted version may also have different CSS (e.g. since '#titlebar' is shown) if (brackets.inBrowser) { $("body").addClass("in-browser"); @@ -352,24 +352,24 @@ define(function (require, exports, module) { }; }()); } - + // Localize MainViewHTML and inject into tag $("body").html(Mustache.render(MainViewHTML, { shouldAddAA: (brackets.platform === "mac"), Strings: Strings })); // Update title $("title").text(brackets.config.app_title); - + // Respond to dragging & dropping files/folders onto the window by opening them. If we don't respond // to these events, the file would load in place of the Brackets UI DragAndDrop.attachHandlers(); - + // TODO: (issue 269) to support IE, need to listen to document instead (and even then it may not work when focus is in an input field?) $(window).focus(function () { // This call to syncOpenDocuments() *should* be a no-op now that we have // file watchers, but is still here as a safety net. FileSyncManager.syncOpenDocuments(); }); - + // Prevent unhandled middle button clicks from triggering native behavior // Example: activating AutoScroll (see #510) $("html").on("mousedown", ".inline-widget", function (e) { @@ -377,7 +377,7 @@ define(function (require, exports, module) { e.preventDefault(); } }); - + // The .no-focus style is added to clickable elements that should // not steal focus. Calling preventDefault() on mousedown prevents // focus from going to the click target. @@ -393,7 +393,7 @@ define(function (require, exports, module) { e.preventDefault(); } }); - + // Prevent clicks on any link from navigating to a different page (which could lose unsaved // changes). We can't use a simple .on("click", "a") because of http://bugs.jquery.com/ticket/3861: // jQuery hides non-left clicks from such event handlers, yet middle-clicks still cause CEF to @@ -449,7 +449,7 @@ define(function (require, exports, module) { } return real_windowOpen.apply(window, arguments); }; - + // jQuery patch to shim deprecated usage of $() on EventDispatchers var DefaultCtor = jQuery.fn.init; jQuery.fn.init = function (firstArg, secondArg) { @@ -471,7 +471,7 @@ define(function (require, exports, module) { return jQObject; }; } - + // Wait for view state to load. var viewStateTimer = PerfUtils.markStart("User viewstate loading"); PreferencesManager._smUserScopeLoading.always(function () { diff --git a/src/command/CommandManager.js b/src/command/CommandManager.js index 337cb16ea7f..4fe940ce102 100644 --- a/src/command/CommandManager.js +++ b/src/command/CommandManager.js @@ -35,23 +35,23 @@ */ define(function (require, exports, module) { "use strict"; - + var EventDispatcher = require("utils/EventDispatcher"); - - + + /** * Map of all registered global commands * @type {Object.} */ var _commands = {}; - + /** * Temporary copy of commands map for restoring after testing * TODO (issue #1039): implement separate require contexts for unit tests * @type {Object.} */ var _commandsOriginal = {}; - + /** * Events: * - enabledStateChange @@ -93,7 +93,7 @@ define(function (require, exports, module) { if (!this._enabled) { return (new $.Deferred()).reject().promise(); } - + var result = this._commandFn.apply(this, arguments); if (!result) { // If command does not return a promise, assume that it handled the @@ -202,9 +202,9 @@ define(function (require, exports, module) { var command = new Command(name, id, commandFn); _commands[id] = command; - + exports.trigger("commandRegistered", command); - + return command; } @@ -232,12 +232,12 @@ define(function (require, exports, module) { var command = new Command(null, id, commandFn); _commands[id] = command; - + exports.trigger("commandRegistered", command); - + return command; } - + /** * Clear all commands for unit testing, but first make copy of commands so that * they can be restored afterward @@ -254,7 +254,7 @@ define(function (require, exports, module) { _commands = _commandsOriginal; _commandsOriginal = {}; } - + /** * Retrieves a Command object by id * @param {string} id @@ -263,7 +263,7 @@ define(function (require, exports, module) { function get(id) { return _commands[id]; } - + /** * Returns the ids of all registered commands * @return {Array.} @@ -280,20 +280,20 @@ define(function (require, exports, module) { */ function execute(id) { var command = _commands[id]; - + if (command) { try { exports.trigger("beforeExecuteCommand", id); } catch (err) { console.error(err); } - + return command.execute.apply(command, Array.prototype.slice.call(arguments, 1)); } else { return (new $.Deferred()).reject().promise(); } } - + EventDispatcher.makeEventDispatcher(exports); // Define public API diff --git a/src/command/Commands.js b/src/command/Commands.js index 258e3ed91a0..9089404cc92 100644 --- a/src/command/Commands.js +++ b/src/command/Commands.js @@ -2,21 +2,21 @@ * 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. * */ @@ -27,13 +27,13 @@ define(function (require, exports, module) { "use strict"; - + var DeprecationWarning = require("utils/DeprecationWarning"); - + /** * List of constants for global command IDs. */ - + // FILE exports.FILE_NEW_UNTITLED = "file.newDoc"; // DocumentCommandHandlers.js handleFileNew() exports.FILE_NEW = "file.newFile"; // DocumentCommandHandlers.js handleFileNewInProject() @@ -58,11 +58,11 @@ define(function (require, exports, module) { exports.FILE_REFRESH = "file.refresh"; // ProjectManager.js refreshFileTree() exports.FILE_OPEN_PREFERENCES = "file.openPreferences"; // PreferencesManager.js _handleOpenPreferences() exports.FILE_OPEN_KEYMAP = "file.openKeyMap"; // KeyBindingManager.js _openUserKeyMap() - + // File shell callbacks - string must MATCH string in native code (appshell/command_callbacks.h) exports.FILE_CLOSE_WINDOW = "file.close_window"; // DocumentCommandHandlers.js handleFileCloseWindow() exports.FILE_QUIT = "file.quit"; // DocumentCommandHandlers.js handleFileQuit() - + // EDIT // File shell callbacks - string must MATCH string in native code (appshell/command_callbacks.h) exports.EDIT_UNDO = "edit.undo"; // EditorCommandHandlers.js handleUndo() @@ -71,7 +71,7 @@ define(function (require, exports, module) { exports.EDIT_COPY = "edit.copy"; // EditorCommandHandlers.js ignoreCommand() exports.EDIT_PASTE = "edit.paste"; // EditorCommandHandlers.js ignoreCommand() exports.EDIT_SELECT_ALL = "edit.selectAll"; // EditorCommandHandlers.js _handleSelectAll() - + exports.EDIT_SELECT_LINE = "edit.selectLine"; // EditorCommandHandlers.js selectLine() exports.EDIT_SPLIT_SEL_INTO_LINES = "edit.splitSelIntoLines"; // EditorCommandHandlers.js splitSelIntoLines() exports.EDIT_ADD_CUR_TO_NEXT_LINE = "edit.addCursorToNextLine"; // EditorCommandHandlers.js addCursorToNextLine() @@ -88,7 +88,7 @@ define(function (require, exports, module) { exports.EDIT_OPEN_LINE_BELOW = "edit.openLineBelow"; // EditorCommandHandlers.js openLineBelow() exports.TOGGLE_CLOSE_BRACKETS = "edit.autoCloseBrackets"; // EditorOptionHandlers.js _getToggler() exports.SHOW_CODE_HINTS = "edit.showCodeHints"; // CodeHintManager.js _startNewSession() - + // FIND exports.CMD_FIND = "cmd.find"; // FindReplace.js _launchFind() exports.CMD_FIND_IN_FILES = "cmd.findInFiles"; // FindInFilesUI.js _showFindBar() @@ -101,7 +101,7 @@ define(function (require, exports, module) { exports.CMD_REPLACE = "cmd.replace"; // FindReplace.js _replace() exports.CMD_REPLACE_IN_FILES = "cmd.replaceInFiles"; // FindInFilesUI.js _showReplaceBar() exports.CMD_REPLACE_IN_SUBTREE = "cmd.replaceInSubtree"; // FindInFilesUI.js _showReplaceBarForSubtree() - + // VIEW exports.CMD_THEMES_OPEN_SETTINGS = "view.themesOpenSetting"; // MenuCommands.js Settings.open() exports.VIEW_HIDE_SIDEBAR = "view.toggleSidebar"; // SidebarView.js toggle() @@ -117,7 +117,7 @@ define(function (require, exports, module) { exports.CMD_OPEN = "cmd.open"; exports.CMD_ADD_TO_WORKINGSET_AND_OPEN = "cmd.addToWorkingSetAndOpen"; // DocumentCommandHandlers.js handleOpenDocumentInNewPane() - + // NAVIGATE exports.NAVIGATE_NEXT_DOC = "navigate.nextDoc"; // DocumentCommandHandlers.js handleGoNextDoc() exports.NAVIGATE_PREV_DOC = "navigate.prevDoc"; // DocumentCommandHandlers.js handleGoPrevDoc() @@ -135,7 +135,7 @@ define(function (require, exports, module) { exports.QUICK_EDIT_NEXT_MATCH = "navigate.nextMatch"; // MultiRangeInlineEditor.js _nextRange() exports.QUICK_EDIT_PREV_MATCH = "navigate.previousMatch"; // MultiRangeInlineEditor.js _previousRange() exports.CSS_QUICK_EDIT_NEW_RULE = "navigate.newRule"; // CSSInlineEditor.js _handleNewRule() - + // HELP exports.HELP_CHECK_FOR_UPDATE = "help.checkForUpdate"; // HelpCommandHandlers.js _handleCheckForUpdates() exports.HELP_HOW_TO_USE_BRACKETS = "help.howToUseBrackets"; // HelpCommandHandlers.js _handleLinkMenuItem() @@ -146,32 +146,32 @@ define(function (require, exports, module) { exports.HELP_SHOW_EXT_FOLDER = "help.showExtensionsFolder"; // HelpCommandHandlers.js _handleShowExtensionsFolder() exports.HELP_HOMEPAGE = "help.homepage"; // HelpCommandHandlers.js _handleLinkMenuItem() exports.HELP_TWITTER = "help.twitter"; // HelpCommandHandlers.js _handleLinkMenuItem() - + // Working Set Configuration exports.CMD_WORKINGSET_SORT_BY_ADDED = "cmd.sortWorkingSetByAdded"; // WorkingSetSort.js _handleSort() exports.CMD_WORKINGSET_SORT_BY_NAME = "cmd.sortWorkingSetByName"; // WorkingSetSort.js _handleSort() exports.CMD_WORKINGSET_SORT_BY_TYPE = "cmd.sortWorkingSetByType"; // WorkingSetSort.js _handleSort() exports.CMD_WORKING_SORT_TOGGLE_AUTO = "cmd.sortWorkingSetToggleAuto"; // WorkingSetSort.js _handleToggleAutoSort() - + // Split View exports.CMD_SPLITVIEW_NONE = "cmd.splitViewNone"; // SidebarView.js _handleSplitNone() exports.CMD_SPLITVIEW_VERTICAL = "cmd.splitViewVertical"; // SidebarView.js _handleSplitVertical() exports.CMD_SPLITVIEW_HORIZONTAL = "cmd.splitViewHorizontal"; // SidebarView.js _handleSplitHorizontal() - + // File shell callbacks - string must MATCH string in native code (appshell/command_callbacks.h) exports.HELP_ABOUT = "help.about"; // HelpCommandHandlers.js _handleAboutDialog() - + // APP exports.APP_RELOAD = "app.reload"; // DocumentCommandHandlers.js handleReload() exports.APP_RELOAD_WITHOUT_EXTS = "app.reload_without_exts"; // DocumentCommandHandlers.js handleReloadWithoutExts() - + // File shell callbacks - string must MATCH string in native code (appshell/command_callbacks.h) exports.APP_ABORT_QUIT = "app.abort_quit"; // DocumentCommandHandlers.js handleAbortQuit() exports.APP_BEFORE_MENUPOPUP = "app.before_menupopup"; // DocumentCommandHandlers.js handleBeforeMenuPopup() - + // ADD_TO_WORKING_SET is deprectated but we need a handler for it because the new command doesn't return the same result as the legacy command exports.FILE_ADD_TO_WORKING_SET = "file.addToWorkingSet"; // Deprecated through DocumentCommandHandlers.js handleFileAddToWorkingSet - + // Show or Hide sidebar exports.HIDE_SIDEBAR = "view.hideSidebar"; // SidebarView.js hide() exports.SHOW_SIDEBAR = "view.showSidebar"; // SidebarView.js show() diff --git a/src/command/DefaultMenus.js b/src/command/DefaultMenus.js index 9528f0609c1..90f091b84b1 100644 --- a/src/command/DefaultMenus.js +++ b/src/command/DefaultMenus.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the + * 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. - * + * */ @@ -30,12 +30,12 @@ */ define(function (require, exports, module) { "use strict"; - + var AppInit = require("utils/AppInit"), Commands = require("command/Commands"), Menus = require("command/Menus"), Strings = require("strings"); - + AppInit.htmlReady(function () { /* * File menu @@ -57,13 +57,13 @@ define(function (require, exports, module) { menu.addMenuItem(Commands.FILE_PROJECT_SETTINGS); menu.addMenuDivider(); menu.addMenuItem(Commands.FILE_EXTENSION_MANAGER); - + // suppress redundant quit menu item on mac if (brackets.platform !== "mac" || !brackets.nativeMenus) { menu.addMenuDivider(); menu.addMenuItem(Commands.FILE_QUIT); } - + /* * Edit menu */ @@ -97,7 +97,7 @@ define(function (require, exports, module) { menu.addMenuItem(Commands.SHOW_CODE_HINTS); menu.addMenuDivider(); menu.addMenuItem(Commands.TOGGLE_CLOSE_BRACKETS); - + /* * Find menu */ @@ -113,7 +113,7 @@ define(function (require, exports, module) { menu.addMenuDivider(); menu.addMenuItem(Commands.CMD_REPLACE); menu.addMenuItem(Commands.CMD_REPLACE_IN_FILES); - + /* * View menu */ @@ -137,7 +137,7 @@ define(function (require, exports, module) { menu.addMenuItem(Commands.FILE_LIVE_HIGHLIGHT); menu.addMenuDivider(); menu.addMenuItem(Commands.VIEW_TOGGLE_INSPECTION); - + /* * Navigate menu */ @@ -161,7 +161,7 @@ define(function (require, exports, module) { menu.addMenuItem(Commands.CSS_QUICK_EDIT_NEW_RULE); menu.addMenuDivider(); menu.addMenuItem(Commands.TOGGLE_QUICK_DOCS); - + /* * Help menu */ @@ -189,16 +189,16 @@ define(function (require, exports, module) { menu.addMenuItem(Commands.HELP_SHOW_EXT_FOLDER); var hasAboutItem = (brackets.platform !== "mac" || !brackets.nativeMenus); - + // Add final divider only if we have a homepage URL or twitter URL or about item if (hasAboutItem || brackets.config.homepage_url || brackets.config.twitter_url) { menu.addMenuDivider(); } - + if (brackets.config.homepage_url) { menu.addMenuItem(Commands.HELP_HOMEPAGE); } - + if (brackets.config.twitter_url) { menu.addMenuItem(Commands.HELP_TWITTER); } @@ -206,12 +206,12 @@ define(function (require, exports, module) { if (hasAboutItem) { menu.addMenuItem(Commands.HELP_ABOUT); } - - + + /* * Context Menus */ - + // WorkingSet context menu - Unlike most context menus, we can't attach // listeners here because the DOM nodes for each pane's working set are // created dynamically. Each WorkingSetView attaches its own listeners. @@ -226,19 +226,19 @@ define(function (require, exports, module) { workingset_cmenu.addMenuItem(Commands.CMD_REPLACE_IN_SUBTREE); workingset_cmenu.addMenuDivider(); workingset_cmenu.addMenuItem(Commands.FILE_CLOSE); - + var workingset_configuration_menu = Menus.registerContextMenu(Menus.ContextMenuIds.WORKING_SET_CONFIG_MENU); workingset_configuration_menu.addMenuItem(Commands.CMD_WORKINGSET_SORT_BY_ADDED); workingset_configuration_menu.addMenuItem(Commands.CMD_WORKINGSET_SORT_BY_NAME); workingset_configuration_menu.addMenuItem(Commands.CMD_WORKINGSET_SORT_BY_TYPE); workingset_configuration_menu.addMenuDivider(); workingset_configuration_menu.addMenuItem(Commands.CMD_WORKING_SORT_TOGGLE_AUTO); - + var splitview_menu = Menus.registerContextMenu(Menus.ContextMenuIds.SPLITVIEW_MENU); splitview_menu.addMenuItem(Commands.CMD_SPLITVIEW_NONE); splitview_menu.addMenuItem(Commands.CMD_SPLITVIEW_VERTICAL); splitview_menu.addMenuItem(Commands.CMD_SPLITVIEW_HORIZONTAL); - + var project_cmenu = Menus.registerContextMenu(Menus.ContextMenuIds.PROJECT_MENU); project_cmenu.addMenuItem(Commands.FILE_NEW); project_cmenu.addMenuItem(Commands.FILE_NEW_FOLDER); @@ -250,7 +250,7 @@ define(function (require, exports, module) { project_cmenu.addMenuItem(Commands.CMD_REPLACE_IN_SUBTREE); project_cmenu.addMenuDivider(); project_cmenu.addMenuItem(Commands.FILE_REFRESH); - + var editor_cmenu = Menus.registerContextMenu(Menus.ContextMenuIds.EDITOR_MENU); // editor_cmenu.addMenuItem(Commands.NAVIGATE_JUMPTO_DEFINITION); editor_cmenu.addMenuItem(Commands.TOGGLE_QUICK_EDIT); @@ -263,7 +263,7 @@ define(function (require, exports, module) { inline_editor_cmenu.addMenuDivider(); inline_editor_cmenu.addMenuItem(Commands.QUICK_EDIT_PREV_MATCH); inline_editor_cmenu.addMenuItem(Commands.QUICK_EDIT_NEXT_MATCH); - + /** * Context menu for code editors (both full-size and inline) * Auto selects the word the user clicks if the click does not occur over @@ -307,7 +307,7 @@ define(function (require, exports, module) { }); /** - * Context menu for folder tree + * Context menu for folder tree */ $("#project-files-container").on("contextmenu", function (e) { project_cmenu.open(e); @@ -323,7 +323,7 @@ define(function (require, exports, module) { $(window).contextmenu(function (e) { e.preventDefault(); }); - + /* * General menu event processing */ diff --git a/src/command/KeyBindingManager.js b/src/command/KeyBindingManager.js index 263f59d7852..72571a19983 100644 --- a/src/command/KeyBindingManager.js +++ b/src/command/KeyBindingManager.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -49,7 +49,7 @@ define(function (require, exports, module) { _ = require("thirdparty/lodash"); var KeyboardPrefs = JSON.parse(require("text!base-config/keyboard.json")); - + var KEYMAP_FILENAME = "keymap.json", _userKeyMapFilePath = brackets.app.getApplicationSupportDirectory() + "/" + KEYMAP_FILENAME; @@ -66,7 +66,7 @@ define(function (require, exports, module) { * @typedef {{shortcut: !string, * commandID: ?string}} UserKeyBinding */ - + /** * @private * Maps shortcut descriptor to a command id. @@ -74,14 +74,14 @@ define(function (require, exports, module) { */ var _customKeyMap = {}, _customKeyMapCache = {}; - + /** * @private * Maps commandID to the list of shortcuts that are bound to it. * @type {!Object.>} */ var _commandMap = {}; - + /** * @private * An array of command ID for all the available commands including the commands @@ -89,7 +89,7 @@ define(function (require, exports, module) { * @type {Array.} */ var _allCommands = []; - + /** * @private * Maps key names to the corresponding unicode symols @@ -110,9 +110,9 @@ define(function (require, exports, module) { /** * @private - * Flag to show key binding errors in the key map file. Default is true and - * it will be set to false when reloading without extensions. This flag is not - * used to suppress errors in loading or parsing the key map file. So if the key + * Flag to show key binding errors in the key map file. Default is true and + * it will be set to false when reloading without extensions. This flag is not + * used to suppress errors in loading or parsing the key map file. So if the key * map file is corrupt, then the error dialog still shows up. * * @type {boolean} @@ -125,14 +125,14 @@ define(function (require, exports, module) { * @type {boolean} */ var _enabled = true; - + /** * @private * Stack of registered global keydown hooks. * @type {Array.} */ var _globalKeydownHooks = []; - + /** * @private * Forward declaration for JSLint. @@ -150,11 +150,11 @@ define(function (require, exports, module) { "DETECTED" : 1, "DETECTED_AND_IGNORED": 2 // For consecutive ctrl keydown events while a Ctrl key is being hold down }; - + /** * @private - * Flags used to determine whether right Alt key is pressed. When it is pressed, - * the following two keydown events are triggered in that specific order. + * Flags used to determine whether right Alt key is pressed. When it is pressed, + * the following two keydown events are triggered in that specific order. * * 1. _ctrlDown - flag used to record { ctrlKey: true, keyIdentifier: "Control", ... } keydown event * 2. _altGrDown - flag used to record { ctrlKey: true, altKey: true, keyIdentifier: "Alt", ... } keydown event @@ -163,7 +163,7 @@ define(function (require, exports, module) { */ var _ctrlDown = CtrlDownStates.NOT_YET_DETECTED, _altGrDown = false; - + /** * @private * Used to record the timeStamp property of the last keydown event. @@ -177,16 +177,16 @@ define(function (require, exports, module) { * @type {string} */ var _lastKeyIdentifier; - - /* + + /* * @private * Constant used for checking the interval between Control keydown event and Alt keydown event. - * If the right Alt key is down we get Control keydown followed by Alt keydown within 30 ms. if + * If the right Alt key is down we get Control keydown followed by Alt keydown within 30 ms. if * the user is pressing Control key and then Alt key, the interval will be larger than 30 ms. * @type {number} */ var MAX_INTERVAL_FOR_CTRL_ALT_KEYS = 30; - + /** * @private * Forward declaration for JSLint. @@ -197,7 +197,7 @@ define(function (require, exports, module) { /** * @private * Resets all the flags and removes _onCtrlUp event listener. - * + * */ function _quitAltGrMode() { _enabled = true; @@ -207,11 +207,11 @@ define(function (require, exports, module) { _lastKeyIdentifier = null; $(window).off("keyup", _onCtrlUp); } - + /** * @private * Detects the release of AltGr key by checking all keyup events - * until we receive one with ctrl key code. Once detected, reset + * until we receive one with ctrl key code. Once detected, reset * all the flags and also remove this event listener. * * @param {!KeyboardEvent} e keyboard event object @@ -222,14 +222,14 @@ define(function (require, exports, module) { _quitAltGrMode(); } }; - + /** * @private - * Detects whether AltGr key is pressed. When it is pressed, the first keydown event has - * ctrlKey === true with keyIdentifier === "Control". The next keydown event with - * altKey === true, ctrlKey === true and keyIdentifier === "Alt" is sent within 30 ms. Then - * the next keydown event with altKey === true, ctrlKey === true and keyIdentifier === "Control" - * is sent. If the user keep holding AltGr key down, then the second and third + * Detects whether AltGr key is pressed. When it is pressed, the first keydown event has + * ctrlKey === true with keyIdentifier === "Control". The next keydown event with + * altKey === true, ctrlKey === true and keyIdentifier === "Alt" is sent within 30 ms. Then + * the next keydown event with altKey === true, ctrlKey === true and keyIdentifier === "Control" + * is sent. If the user keep holding AltGr key down, then the second and third * keydown events are repeatedly sent out alternately. If the user is also holding down Ctrl * key, then either keyIdentifier === "Control" or keyIdentifier === "Alt" is repeatedly sent * but not alternately. @@ -250,7 +250,7 @@ define(function (require, exports, module) { if (_ctrlDown !== CtrlDownStates.DETECTED_AND_IGNORED && e.ctrlKey && e.keyIdentifier === "Control") { _ctrlDown = CtrlDownStates.DETECTED; } else if (e.repeat && e.ctrlKey && e.keyIdentifier === "Control") { - // We get here if the user is holding down left/right Control key. Set it to false + // We get here if the user is holding down left/right Control key. Set it to false // so that we don't misidentify the combination of Ctrl and Alt keys as AltGr key. _ctrlDown = CtrlDownStates.DETECTED_AND_IGNORED; } else if (_ctrlDown === CtrlDownStates.DETECTED && e.altKey && e.ctrlKey && e.keyIdentifier === "Alt" && @@ -267,7 +267,7 @@ define(function (require, exports, module) { _lastTimeStamp = e.timeStamp; } else if (e.keyIdentifier === "Control" || e.keyIdentifier === "Alt") { // If the user is NOT holding down AltGr key or is also pressing Ctrl key, - // then _lastKeyIdentifier will be the same as keyIdentifier in the current + // then _lastKeyIdentifier will be the same as keyIdentifier in the current // key event. So we need to quit AltGr mode to re-enable KBM. if (e.altKey && e.ctrlKey && e.keyIdentifier === _lastKeyIdentifier) { _quitAltGrMode(); @@ -276,7 +276,7 @@ define(function (require, exports, module) { } } } - + /** * @private */ @@ -305,9 +305,9 @@ define(function (require, exports, module) { console.log("KeyBindingManager _buildKeyDescriptor() - No key provided!"); return ""; } - + var keyDescriptor = []; - + if (hasMacCtrl) { keyDescriptor.push("Ctrl"); } @@ -328,11 +328,11 @@ define(function (require, exports, module) { } keyDescriptor.push(key); - + return keyDescriptor.join("-"); } - - + + /** * normalizes the incoming key descriptor so the modifier keys are always specified in the correct order * @param {string} The string for a key descriptor, can be in any order, the result will be Ctrl-Alt-Shift- @@ -352,10 +352,10 @@ define(function (require, exports, module) { } left = left.trim().toLowerCase(); right = right.trim().toLowerCase(); - + return (left.length > 0 && left === right); } - + origDescriptor.split("-").forEach(function parseDescriptor(ele, i, arr) { if (_compareModifierString("ctrl", ele)) { if (brackets.platform === "mac") { @@ -386,7 +386,7 @@ define(function (require, exports, module) { key = ele; } }); - + if (error) { return null; } @@ -395,37 +395,37 @@ define(function (require, exports, module) { if (key === "" && origDescriptor.search(/^.+--$/) !== -1) { key = "-"; } - + // '+' char is valid if it's the only key. Keyboard shortcut strings should use // unicode characters (unescaped). Keyboard shortcut display strings may use // unicode escape sequences (e.g. \u20AC euro sign) if ((key.indexOf("+")) >= 0 && (key.length > 1)) { return null; } - + // Ensure that the first letter of the key name is in upper case and the rest are // in lower case. i.e. 'a' => 'A' and 'up' => 'Up' if (/^[a-z]/i.test(key)) { key = _.capitalize(key.toLowerCase()); } - + // Also make sure that the second word of PageUp/PageDown has the first letter in upper case. if (/^Page/.test(key)) { key = key.replace(/(up|down)$/, function (match, p1) { return _.capitalize(p1); }); } - - // No restriction on single character key yet, but other key names are restricted to either + + // No restriction on single character key yet, but other key names are restricted to either // Function keys or those listed in _keyNames array. if (key.length > 1 && !/F\d+/.test(key) && _keyNames.indexOf(key) === -1) { return null; } - + return _buildKeyDescriptor(hasMacCtrl, hasCtrl, hasAlt, hasShift, key); } - + /** * @private * Looks for keycodes that have os-inconsistent keys and fixes them. @@ -443,8 +443,8 @@ define(function (require, exports, module) { } else if (keycode >= KeyEvent.DOM_VK_NUMPAD0 && keycode <= KeyEvent.DOM_VK_NUMPAD9) { return String(keycode - KeyEvent.DOM_VK_NUMPAD0); } - - + + switch (keycode) { case KeyEvent.DOM_VK_SEMICOLON: return ";"; @@ -477,7 +477,7 @@ define(function (require, exports, module) { return key; } } - + /** * Takes a keyboard event and translates it into a key in a key map */ @@ -487,7 +487,7 @@ define(function (require, exports, module) { hasAlt = (event.altKey), hasShift = (event.shiftKey), key = String.fromCharCode(event.keyCode); - + //From the W3C, if we can get the KeyboardEvent.keyIdentifier then look here //As that will let us use keys like then function keys "F5" for commands. The //full set of values we can use is here @@ -502,7 +502,7 @@ define(function (require, exports, module) { key = ident; } } - + // Translate some keys to their common names if (key === "\t") { key = "Tab"; @@ -520,7 +520,7 @@ define(function (require, exports, module) { return _buildKeyDescriptor(hasMacCtrl, hasCtrl, hasAlt, hasShift, key); } - + /** * Convert normalized key representation to display appropriate for platform. * @param {!string} descriptor Normalized key descriptor. @@ -528,7 +528,7 @@ define(function (require, exports, module) { */ function formatKeyDescriptor(descriptor) { var displayStr; - + if (brackets.platform === "mac") { displayStr = descriptor.replace(/-(?!$)/g, ""); // remove dashes displayStr = displayStr.replace("Ctrl", "\u2303"); // Ctrl > control symbol @@ -575,23 +575,23 @@ define(function (require, exports, module) { } var normalizedKey = normalizeKeyDescriptorString(key); - + if (!normalizedKey) { console.log("Fail to nomalize " + key); } else if (_isKeyAssigned(normalizedKey)) { var binding = _keyMap[normalizedKey], command = CommandManager.get(binding.commandID), bindings = _commandMap[binding.commandID]; - + // delete key binding record delete _keyMap[normalizedKey]; - + if (bindings) { // delete mapping from command to key binding _commandMap[binding.commandID] = bindings.filter(function (b) { return (b.key !== normalizedKey); }); - + if (command) { command.trigger("keyBindingRemoved", {key: normalizedKey, displayKey: binding.displayKey}); } @@ -603,25 +603,25 @@ define(function (require, exports, module) { * @private * * Updates _allCommands array and _defaultKeyMap with the new key binding - * if it is not yet in the _allCommands array. _allCommands array is initialized + * if it is not yet in the _allCommands array. _allCommands array is initialized * only in extensionsLoaded event. So any new commands or key bindings added after * that will be updated here. * - * @param {{commandID: string, key: string, displayKey:string, explicitPlatform: string}} newBinding + * @param {{commandID: string, key: string, displayKey:string, explicitPlatform: string}} newBinding */ function _updateCommandAndKeyMaps(newBinding) { if (_allCommands.length === 0) { return; } - + if (newBinding && newBinding.commandID && _allCommands.indexOf(newBinding.commandID) === -1) { _defaultKeyMap[newBinding.commandID] = _.cloneDeep(newBinding); - + // Process user key map again to catch any reassignment to all new key bindings added from extensions. _loadUserKeyMap(); } } - + /** * @private * @@ -652,8 +652,8 @@ define(function (require, exports, module) { } else { targetPlatform = brackets.platform; } - - + + // Skip if the key binding is not for this platform. if (explicitPlatform === "mac" && brackets.platform !== "mac") { return null; @@ -668,18 +668,18 @@ define(function (require, exports, module) { keyBinding.displayKey = keyBinding.displayKey.replace("Ctrl", "Cmd"); } } - + normalized = normalizeKeyDescriptorString(key); - - // skip if the key binding is invalid + + // skip if the key binding is invalid if (!normalized) { console.error("Unable to parse key binding " + key + ". Permitted modifiers: Ctrl, Cmd, Alt, Opt, Shift; separated by '-' (not '+')."); return null; } - + // check for duplicate key bindings existing = _keyMap[normalized]; - + // for cross-platform compatibility if (exports.useWindowsCompatibleBindings) { // windows-only key bindings are used as the default binding @@ -693,17 +693,17 @@ define(function (require, exports, module) { // do not clobber existing binding with windows-only binding return null; } - + // target this windows binding for the current platform targetPlatform = brackets.platform; } } - + // skip if this binding doesn't match the current platform if (targetPlatform !== brackets.platform) { return null; } - + // skip if the key is already assigned if (existing) { if (!existing.explicitPlatform && explicitPlatform) { @@ -712,7 +712,7 @@ define(function (require, exports, module) { existing = false; } } - + // delete existing bindings when // (1) replacing a windows-compatible binding with a generic or // platform-specific binding @@ -721,16 +721,16 @@ define(function (require, exports, module) { isWindowsCompatible, isReplaceGeneric, ignoreGeneric; - + existingBindings.forEach(function (binding) { // remove windows-only bindings in _commandMap isWindowsCompatible = exports.useWindowsCompatibleBindings && binding.explicitPlatform === "win"; - + // remove existing generic binding isReplaceGeneric = !binding.explicitPlatform && explicitPlatform; - + if (isWindowsCompatible || isReplaceGeneric) { bindingsToDelete.push(binding); } else { @@ -743,34 +743,34 @@ define(function (require, exports, module) { // explicit command binding overrides this one return null; } - + if (existing) { // do not re-assign a key binding console.error("Cannot assign " + normalized + " to " + commandID + ". It is already assigned to " + _keyMap[normalized].commandID); return null; } - + // remove generic or windows-compatible bindings bindingsToDelete.forEach(function (binding) { removeBinding(binding.key); }); - + // optional display-friendly string (e.g. CMD-+ instead of CMD-=) normalizedDisplay = (keyBinding.displayKey) ? normalizeKeyDescriptorString(keyBinding.displayKey) : normalized; - + // 1-to-many commandID mapping to key binding if (!_commandMap[commandID]) { _commandMap[commandID] = []; } - + result = { key : normalized, displayKey : normalizedDisplay, explicitPlatform : explicitPlatform }; - + _commandMap[commandID].push(result); - + // 1-to-1 key binding to commandID _keyMap[normalized] = { commandID : commandID, @@ -778,18 +778,18 @@ define(function (require, exports, module) { displayKey : normalizedDisplay, explicitPlatform : explicitPlatform }; - + if (!userBindings) { _updateCommandAndKeyMaps(_keyMap[normalized]); } - + // notify listeners command = CommandManager.get(commandID); - + if (command) { command.trigger("keyBindingAdded", result); } - + return result; } @@ -852,31 +852,31 @@ define(function (require, exports, module) { function addBinding(command, keyBindings, platform) { var commandID = "", results; - + if (!command) { console.error("addBinding(): missing required parameter: command"); return; } - + if (!keyBindings) { return; } - + if (typeof (command) === "string") { commandID = command; } else { commandID = command.getID(); } - + if (Array.isArray(keyBindings)) { var keyBinding; results = []; // process platform-specific bindings first keyBindings.sort(_sortByPlatform); - + keyBindings.forEach(function addSingleBinding(keyBindingRequest) { // attempt to add keybinding keyBinding = _addBinding(commandID, keyBindingRequest, keyBindingRequest.platform); - + if (keyBinding) { results.push(keyBinding); } @@ -884,7 +884,7 @@ define(function (require, exports, module) { } else { results = _addBinding(commandID, keyBindings, platform); } - + return results; } @@ -897,22 +897,22 @@ define(function (require, exports, module) { function getKeyBindings(command) { var bindings = [], commandID = ""; - + if (!command) { console.error("getKeyBindings(): missing required parameter: command"); return []; } - + if (typeof (command) === "string") { commandID = command; } else { commandID = command.getID(); } - + bindings = _commandMap[commandID]; return bindings || []; } - + /** * Adds default key bindings when commands are registered to CommandManager * @param {$.Event} event jQuery event @@ -921,34 +921,34 @@ define(function (require, exports, module) { function _handleCommandRegistered(event, command) { var commandId = command.getID(), defaults = KeyboardPrefs[commandId]; - + if (defaults) { addBinding(commandId, defaults); } } - + /** - * Adds a global keydown hook that gets first crack at keydown events - * before standard keybindings do. This is intended for use by modal or - * semi-modal UI elements like dialogs or the code hint list that should - * execute before normal command bindings are run. - * - * The hook is passed one parameter, the original keyboard event. If the - * hook handles the event (or wants to block other global hooks from + * Adds a global keydown hook that gets first crack at keydown events + * before standard keybindings do. This is intended for use by modal or + * semi-modal UI elements like dialogs or the code hint list that should + * execute before normal command bindings are run. + * + * The hook is passed one parameter, the original keyboard event. If the + * hook handles the event (or wants to block other global hooks from * handling the event), it should return true. Note that this will *only* * stop other global hooks and KeyBindingManager from handling the * event; to prevent further event propagation, you will need to call * stopPropagation(), stopImmediatePropagation(), and/or preventDefault() * as usual. * - * Multiple keydown hooks can be registered, and are executed in order, + * Multiple keydown hooks can be registered, and are executed in order, * most-recently-added first. - * + * * (We have to have a special API for this because (1) handlers are normally - * called in least-recently-added order, and we want most-recently-added; - * (2) native DOM events don't have a way for us to find out if + * called in least-recently-added order, and we want most-recently-added; + * (2) native DOM events don't have a way for us to find out if * stopImmediatePropagation()/stopPropagation() has been called on the - * event, so we have to have some other way for one of the hooks to + * event, so we have to have some other way for one of the hooks to * indicate that it wants to block the other hooks from running.) * * @param {function(Event): boolean} hook The global hook to add. @@ -956,7 +956,7 @@ define(function (require, exports, module) { function addGlobalKeydownHook(hook) { _globalKeydownHooks.push(hook); } - + /** * Removes a global keydown hook added by `addGlobalKeydownHook`. * Does not need to be the most recently added hook. @@ -969,7 +969,7 @@ define(function (require, exports, module) { _globalKeydownHooks.splice(index, 1); } } - + /** * Handles a given keydown event, checking global hooks first before * deciding to handle it ourselves. @@ -997,14 +997,14 @@ define(function (require, exports, module) { _handleKeyEvent, true ); - + exports.useWindowsCompatibleBindings = (brackets.platform !== "mac") && (brackets.platform !== "win"); }); - + /** * @private - * Displays an error dialog and also opens the user key map file for editing only if + * Displays an error dialog and also opens the user key map file for editing only if * the error is not the loading file error. * * @param {?string} err Error type returned from JSON parser or open file operation @@ -1014,13 +1014,13 @@ define(function (require, exports, module) { // Asynchronously loading Dialogs module to avoid the circular dependency require(["widgets/Dialogs"], function (Dialogs) { var errorMessage = Strings.ERROR_KEYMAP_CORRUPT; - + if (err === FileSystemError.UNSUPPORTED_ENCODING) { errorMessage = Strings.ERROR_LOADING_KEYMAP; } else if (message) { errorMessage = message; } - + Dialogs.showModalDialog( DefaultDialogs.DIALOG_ID_ERROR, Strings.ERROR_KEYMAP_TITLE, @@ -1033,11 +1033,11 @@ define(function (require, exports, module) { }); }); } - + /** * @private * - * Checks whether the given command ID is a special command that the user can't bind + * Checks whether the given command ID is a special command that the user can't bind * to another shortcut. * @param {!string} commandID A string referring to a specific command * @return {boolean} true if normalizedKey is a special command, false otherwise. @@ -1046,10 +1046,10 @@ define(function (require, exports, module) { if (brackets.platform === "mac" && commandID === "file.quit") { return true; } - + return (_specialCommands.indexOf(commandID) > -1); } - + /** * @private * @@ -1062,24 +1062,24 @@ define(function (require, exports, module) { if (!normalizedKey) { return false; } - + if (_reservedShortcuts.indexOf(normalizedKey) > -1 || _reservedShortcuts.indexOf(normalizedKey.replace("Cmd", "Ctrl")) > -1) { return true; } - + if (brackets.platform === "mac" && _macReservedShortcuts.indexOf(normalizedKey) > -1) { return true; } - + return false; } - + /** * @private * * Creates a bullet list item for any item in the given list. - * @param {Array.} list An array of strings to be converted into a + * @param {Array.} list An array of strings to be converted into a * message string with a bullet list. * @return {string} the html text version of the list */ @@ -1091,13 +1091,13 @@ define(function (require, exports, module) { message += ""; return message; } - + /** * @private * * Gets the corresponding unicode symbol of an arrow key for display in the menu. * @param {string} key The non-modifier key used in the shortcut. It does not need to be normalized. - * @return {string} An empty string if key is not one of those we want to show with the unicode symbol. + * @return {string} An empty string if key is not one of those we want to show with the unicode symbol. * Otherwise, the corresponding unicode symbol is returned. */ function _getDisplayKey(key) { @@ -1108,12 +1108,12 @@ define(function (require, exports, module) { } return displayKey; } - + /** * @private * - * Applies each user key binding to all the affected commands and updates _keyMap. - * Shows errors in a dialog and then opens the user key map file if any of the following + * Applies each user key binding to all the affected commands and updates _keyMap. + * Shows errors in a dialog and then opens the user key map file if any of the following * is detected while applying the user key bindings. * - A key binding is attempting to modify a special command. * - A key binding is attempting to assign a shortcut of a special command to another one. @@ -1132,19 +1132,19 @@ define(function (require, exports, module) { multipleKeys = [], duplicateBindings = [], errorMessage = ""; - + _.forEach(_customKeyMap, function (commandID, key) { var normalizedKey = normalizeKeyDescriptorString(key), existingBindings = _commandMap[commandID] || []; - // Skip this since we don't allow user to update key binding of a special + // Skip this since we don't allow user to update key binding of a special // command like cut, copy, paste, undo, redo and select all. if (_isSpecialCommand(commandID)) { restrictedCommands.push(commandID); return; } - // Skip this since we don't allow user to update a shortcut used in + // Skip this since we don't allow user to update a shortcut used in // a special command or any Mac system command. if (_isReservedShortcuts(normalizedKey)) { restrictedKeys.push(key); @@ -1156,11 +1156,11 @@ define(function (require, exports, module) { invalidKeys.push(key); return; } - + if (_isKeyAssigned(normalizedKey)) { if (remappedKeys.indexOf(normalizedKey) !== -1) { // JSON parser already removed all the duplicates that have the exact - // same case or order in their keys. So we're only detecting duplicate + // same case or order in their keys. So we're only detecting duplicate // bindings that have different orders or different cases used in the key. duplicateBindings.push(key); return; @@ -1234,7 +1234,7 @@ define(function (require, exports, module) { _showErrorsAndOpenKeyMap("", errorMessage); } } - + /** * @private * @@ -1266,7 +1266,7 @@ define(function (require, exports, module) { addBinding(commandID, defaults, brackets.platform); } - // Reassign the default key binding of the previously modified command. + // Reassign the default key binding of the previously modified command. // e.g. "Cmd-W": "file.open" in _customKeyMapCache will require us to reassign Cmd-W // shortcut to file.close command. if (defaultCommand && defaultCommand.key) { @@ -1274,7 +1274,7 @@ define(function (require, exports, module) { } }); } - + /** * @private * @@ -1296,7 +1296,7 @@ define(function (require, exports, module) { * * Reads in the user key map file and parses its content into JSON. * Returns the user key bindings if JSON has "overrides". - * Otherwise, returns an empty object or an error if the file + * Otherwise, returns an empty object or an error if the file * cannot be parsed or loaded. * * @return {$.Promise} a jQuery promise that will be resolved with the JSON @@ -1307,7 +1307,7 @@ define(function (require, exports, module) { function _readUserKeyMap() { var file = FileSystem.getFileForPath(_getUserKeyMapFilePath()), result = new $.Deferred(); - + file.exists(function (err, doesExist) { if (doesExist) { FileUtils.readAsText(file) @@ -1343,20 +1343,20 @@ define(function (require, exports, module) { * @private * * Reads in the user key bindings and updates the key map with each user key - * binding by removing the existing one assigned to each key and adding - * new one for the specified command id. Shows errors and opens the user + * binding by removing the existing one assigned to each key and adding + * new one for the specified command id. Shows errors and opens the user * key map file if it cannot be parsed. * * This function is wrapped with debounce so that its execution is always delayed - * by 200 ms. The delay is required because when this function is called some + * by 200 ms. The delay is required because when this function is called some * extensions may still be adding some commands and their key bindings asychronously. */ _loadUserKeyMap = _.debounce(function () { _readUserKeyMap() .then(function (keyMap) { // Some extensions may add a new command without any key binding. So - // we always have to get all commands again to ensure that we also have - // those from any extensions installed during the current session. + // we always have to get all commands again to ensure that we also have + // those from any extensions installed during the current session. _allCommands = CommandManager.getAll(); _customKeyMapCache = _.cloneDeep(_customKeyMap); @@ -1367,11 +1367,11 @@ define(function (require, exports, module) { _showErrorsAndOpenKeyMap(err); }); }, 200); - + /** * @private * - * Opens the existing key map file or creates a new one with default content + * Opens the existing key map file or creates a new one with default content * if it does not exist. */ function _openUserKeyMap() { @@ -1384,7 +1384,7 @@ define(function (require, exports, module) { var defaultContent = "{\n \"documentation\": \"https://github.com/adobe/brackets/wiki/User-Key-Bindings\"," + "\n \"overrides\": {" + "\n \n }\n}\n"; - + FileUtils.writeText(file, defaultContent, true) .done(function () { CommandManager.execute(Commands.FILE_OPEN, { fullPath: userKeyMapPath }); @@ -1392,7 +1392,7 @@ define(function (require, exports, module) { } }); } - + // Due to circular dependencies, not safe to call on() directly EventDispatcher.on_duringInit(CommandManager, "commandRegistered", _handleCommandRegistered); CommandManager.register(Strings.CMD_OPEN_KEYMAP, Commands.FILE_OPEN_KEYMAP, _openUserKeyMap); @@ -1405,7 +1405,7 @@ define(function (require, exports, module) { } }); }); - + /** * @private * @@ -1417,11 +1417,11 @@ define(function (require, exports, module) { // Keep a copy of the default key bindings before loading user key bindings. _defaultKeyMap = _.cloneDeep(_keyMap); } - + /** * @private * - * Sets the full file path to the user key map file. Only used by unit tests + * Sets the full file path to the user key map file. Only used by unit tests * to load a test file instead of the actual user key map file. * * @param {string} fullPath file path to the user key map file. @@ -1429,7 +1429,7 @@ define(function (require, exports, module) { function _setUserKeyMapFilePath(fullPath) { _userKeyMapFilePath = fullPath; } - + AppInit.extensionsLoaded(function () { var params = new UrlParams(); params.parse(); @@ -1457,7 +1457,7 @@ define(function (require, exports, module) { exports.getKeyBindings = getKeyBindings; exports.addGlobalKeydownHook = addGlobalKeydownHook; exports.removeGlobalKeydownHook = removeGlobalKeydownHook; - + /** * Use windows-specific bindings if no other are found (e.g. Linux). * Core Brackets modules that use key bindings should always define at @@ -1467,7 +1467,7 @@ define(function (require, exports, module) { * not Linux. */ exports.useWindowsCompatibleBindings = false; - + // For unit testing only exports._handleKey = _handleKey; exports._handleKeyEvent = _handleKeyEvent; diff --git a/src/command/Menus.js b/src/command/Menus.js index d648f230725..fb370519b02 100644 --- a/src/command/Menus.js +++ b/src/command/Menus.js @@ -94,11 +94,11 @@ define(function (require, exports, module) { EDIT_COMMENT_SELECTION: {sectionMarker: Commands.EDIT_LINE_COMMENT}, EDIT_CODE_HINTS_COMMANDS: {sectionMarker: Commands.SHOW_CODE_HINTS}, EDIT_TOGGLE_OPTIONS: {sectionMarker: Commands.TOGGLE_CLOSE_BRACKETS}, - + FIND_FIND_COMMANDS: {sectionMarker: Commands.CMD_FIND}, FIND_FIND_IN_COMMANDS: {sectionMarker: Commands.CMD_FIND_IN_FILES}, FIND_REPLACE_COMMANDS: {sectionMarker: Commands.CMD_REPLACE}, - + VIEW_HIDESHOW_COMMANDS: {sectionMarker: Commands.VIEW_HIDE_SIDEBAR}, VIEW_FONTSIZE_COMMANDS: {sectionMarker: Commands.VIEW_INCREASE_FONT_SIZE}, VIEW_TOGGLE_OPTIONS: {sectionMarker: Commands.TOGGLE_ACTIVE_LINE}, @@ -367,7 +367,7 @@ define(function (require, exports, module) { */ Menu.prototype._getRelativeMenuItem = function (relativeID, position) { var $relativeElement; - + if (relativeID) { if (position === FIRST_IN_SECTION || position === LAST_IN_SECTION) { if (!relativeID.hasOwnProperty("sectionMarker")) { @@ -554,7 +554,7 @@ define(function (require, exports, module) { menuItem, name, commandID; - + if (!command) { console.error("addMenuItem(): missing required parameters: command"); return null; @@ -955,7 +955,7 @@ define(function (require, exports, module) { // Remove all of the menu items in the menu menu = getMenu(id); - + _.forEach(menuItemMap, function (value, key) { if (_.startsWith(key, id)) { if (value.isDivider) { @@ -1067,18 +1067,18 @@ define(function (require, exports, module) { width: $menuWindow.width() }, clip = ViewUtils.getElementClipSize($window, elementRect); - + if (clip.bottom > 0) { posTop = Math.max(0, posTop - clip.bottom); } posTop -= 30; // shift top for hidden parent element posLeft += 5; - + if (clip.right > 0) { posLeft = Math.max(0, posLeft - clip.right); } - + // open the context menu at final location $menuAnchor.addClass("open") .css({"left": posLeft, "top": posTop}); @@ -1172,7 +1172,7 @@ define(function (require, exports, module) { // Deprecated menu ids DeprecationWarning.deprecateConstant(ContextMenuIds, "WORKING_SET_MENU", "WORKING_SET_CONTEXT_MENU"); DeprecationWarning.deprecateConstant(ContextMenuIds, "WORKING_SET_SETTINGS_MENU", "WORKING_SET_CONFIG_MENU"); - + // Define public API exports.AppMenuBar = AppMenuBar; exports.ContextMenuIds = ContextMenuIds; diff --git a/src/dependencies.js b/src/dependencies.js index a6d4565667b..65db27f6a22 100644 --- a/src/dependencies.js +++ b/src/dependencies.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the + * 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, evil:true */ @@ -29,16 +29,16 @@ */ window.setTimeout(function () { "use strict"; - + var key, missingDeps = ""; var deps = { "Mustache": window.Mustache, "jQuery": window.$, "RequireJS": window.require }; - + for (key in deps) { if (deps.hasOwnProperty(key) && !deps[key]) { missingDeps += "
  • " + key + "
  • "; } } - + if (missingDeps.length > 0) { var str = "

    Missing libraries

    " + "

    Oops! One or more required libraries could not be found.

    " + @@ -47,7 +47,7 @@ window.setTimeout(function () { "
    git submodule update --init
    " + "

    If you're still having problems, please contact us via one of the channels mentioned at the bottom of the README.

    " + "

    Reload Brackets

    "; - + document.write(str); } -}, 1000); \ No newline at end of file +}, 1000); diff --git a/src/document/ChangedDocumentTracker.js b/src/document/ChangedDocumentTracker.js index 77a4b44a8d7..55b27f9636d 100644 --- a/src/document/ChangedDocumentTracker.js +++ b/src/document/ChangedDocumentTracker.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -30,10 +30,10 @@ */ define(function (require, exports, module) { "use strict"; - + var DocumentManager = require("document/DocumentManager"), ProjectManager = require("project/ProjectManager"); - + /** * Tracks "change" events on opened Documents. Used to monitor changes * to documents in-memory and update caches. Assumes all documents have @@ -44,7 +44,7 @@ define(function (require, exports, module) { */ function ChangedDocumentTracker() { var self = this; - + this._changedPaths = {}; this._windowFocus = true; this._addListener = this._addListener.bind(this); @@ -67,7 +67,7 @@ define(function (require, exports, module) { $(window).focus(this._onWindowFocus); } - + /** * @private * Assumes all files are changed when the window loses and regains focus. @@ -90,7 +90,7 @@ define(function (require, exports, module) { ChangedDocumentTracker.prototype._onWindowFocus = function (event, doc) { this._windowFocus = true; }; - + /** * @private * Tracks changed documents. @@ -100,15 +100,15 @@ define(function (require, exports, module) { // then leave it changed. this._changedPaths[doc.file.fullPath] = true; }; - + /** - * Empty the set of dirty paths. Begin tracking new dirty documents. + * Empty the set of dirty paths. Begin tracking new dirty documents. */ ChangedDocumentTracker.prototype.reset = function () { this._changedPaths = {}; this._windowFocus = false; }; - + /** * Check if a file path is dirty. * @param {!string} file path @@ -117,7 +117,7 @@ define(function (require, exports, module) { ChangedDocumentTracker.prototype.isPathChanged = function (path) { return this._windowFocus || this._changedPaths[path]; }; - + /** * Get the set of changed paths since the last reset. * @return {Array.} Changed file paths @@ -127,4 +127,4 @@ define(function (require, exports, module) { }; module.exports = ChangedDocumentTracker; -}); \ No newline at end of file +}); diff --git a/src/document/Document.js b/src/document/Document.js index 33ba006f4a2..aea8e407c76 100644 --- a/src/document/Document.js +++ b/src/document/Document.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -27,7 +27,7 @@ define(function (require, exports, module) { "use strict"; - + var EditorManager = require("editor/EditorManager"), EventDispatcher = require("utils/EventDispatcher"), FileUtils = require("file/FileUtils"), @@ -36,14 +36,14 @@ define(function (require, exports, module) { LanguageManager = require("language/LanguageManager"), CodeMirror = require("thirdparty/CodeMirror/lib/codemirror"), _ = require("thirdparty/lodash"); - + /** * Model for the contents of a single file and its current modification state. * See DocumentManager documentation for important usage notes. * * Document dispatches these events: * - * __change__ -- When the text of the editor changes (including due to undo/redo). + * __change__ -- When the text of the editor changes (including due to undo/redo). * * Passes ({Document}, {ChangeList}), where ChangeList is an array * of change record objects. Each change record looks like: @@ -51,7 +51,7 @@ define(function (require, exports, module) { * { from: start of change, expressed as {line: , ch: }, * to: end of change, expressed as {line: , ch: }, * text: array of lines of text to replace existing text } - * + * * The line and ch offsets are both 0-based. * * The ch offset in "from" is inclusive, but the ch offset in "to" is exclusive. For example, @@ -60,13 +60,13 @@ define(function (require, exports, module) { * * If "from" and "to" are undefined, then this is a replacement of the entire text content. * - * IMPORTANT: If you listen for the "change" event, you MUST also addRef() the document + * IMPORTANT: If you listen for the "change" event, you MUST also addRef() the document * (and releaseRef() it whenever you stop listening). You should also listen to the "deleted" * event. * * __deleted__ -- When the file for this document has been deleted. All views onto the document should * be closed. The document will no longer be editable or dispatch "change" events. - * + * * __languageChanged__ -- When the value of getLanguage() has changed. 2nd argument is the old value, * 3rd argument is the new value. * @@ -80,20 +80,20 @@ define(function (require, exports, module) { this._updateLanguage(); this.refreshText(rawText, initialTimestamp, true); } - + EventDispatcher.makeEventDispatcher(Document.prototype); - + /** * List of editors which were initialized as master editors for this doc. */ Document.prototype._associatedFullEditors = []; - + /** * Number of clients who want this Document to stay alive. The Document is listed in * DocumentManager._openDocuments whenever refCount > 0. */ Document.prototype._refCount = 0; - + /** * The File for this document. Need not lie within the project. * If Document is untitled, this is an InMemoryFile object. @@ -106,27 +106,27 @@ define(function (require, exports, module) { * @type {!Language} */ Document.prototype.language = null; - + /** * Whether this document has unsaved changes or not. * When this changes on any Document, DocumentManager dispatches a "dirtyFlagChange" event. * @type {boolean} */ Document.prototype.isDirty = false; - + /** * Whether this document is currently being saved. * @type {boolean} */ Document.prototype.isSaving = false; - + /** * What we expect the file's timestamp to be on disk. If the timestamp differs from this, then * it means the file was modified by an app other than Brackets. * @type {!Date} */ Document.prototype.diskTimestamp = null; - + /** * The timestamp of the document at the point where the user last said to keep changes that conflict * with the current disk version. Can also be -1, indicating that the file was deleted on disk at the @@ -142,13 +142,13 @@ define(function (require, exports, module) { * @type {boolean} */ Document.prototype._refreshInProgress = false; - + /** * The text contents of the file, or null if our backing model is _masterEditor. * @type {?string} */ Document.prototype._text = null; - + /** * Editor object representing the full-size editor UI for this document. May be null if Document * has not yet been modified or been the currentDocument; in that case, our backing model is the @@ -156,18 +156,18 @@ define(function (require, exports, module) { * @type {?Editor} */ Document.prototype._masterEditor = null; - + /** * The content's line-endings style. If a Document is created on empty text, or text with * inconsistent line endings, defaults to the current platform's standard endings. * @type {FileUtils.LINE_ENDINGS_CRLF|FileUtils.LINE_ENDINGS_LF} */ Document.prototype._lineEndings = null; - + /** Add a ref to keep this Document alive */ Document.prototype.addRef = function () { //console.log("+++REF+++ "+this); - + if (this._refCount === 0) { //console.log("+++ adding to open list"); if (exports.trigger("_afterDocumentCreate", this)) { @@ -192,7 +192,7 @@ define(function (require, exports, module) { } } }; - + /** * Attach a backing Editor to the Document, enabling setText() to be called. Assumes Editor has * already been initialized with the value of getText(). ONLY Editor should call this (and only @@ -206,13 +206,13 @@ define(function (require, exports, module) { this._associatedFullEditors.push(this._masterEditor); } } - + this._text = null; this._masterEditor = masterEditor; - + masterEditor.on("change", this._handleEditorChange.bind(this)); }; - + /** * Detach the backing Editor from the Document, disallowing setText(). The text content is * stored back onto _text so other Document clients continue to have read-only access. ONLY @@ -225,7 +225,7 @@ define(function (require, exports, module) { // _text represents the raw text, so fetch without normalized line endings this._text = this.getText(true); this._associatedFullEditors.splice(this._associatedFullEditors.indexOf(this._masterEditor), 1); - + // Identify the most recently created full editor before this and set that as new master editor if (this._associatedFullEditors.length > 0) { this._masterEditor = this._associatedFullEditors[this._associatedFullEditors.length - 1]; @@ -234,10 +234,10 @@ define(function (require, exports, module) { } } }; - + /** - * Toggles the master editor which has gained focus from a pool of full editors - * To be used internally by Editor only + * Toggles the master editor which has gained focus from a pool of full editors + * To be used internally by Editor only */ Document.prototype._toggleMasterEditor = function (masterEditor) { // Do a check before processing the request to ensure inline editors are not being set as master editor @@ -251,7 +251,7 @@ define(function (require, exports, module) { this._masterEditor = masterEditor; } }; - + /** * Disassociates an editor from this document if present in the associated editor list * To be used internally by Editor only when destroyed and not the current master editor for the document @@ -262,7 +262,7 @@ define(function (require, exports, module) { this._associatedFullEditors.splice(this._associatedFullEditors.indexOf(editor), 1); } }; - + /** * Guarantees that _masterEditor is non-null. If needed, asks EditorManager to create a new master * editor bound to this Document (which in turn causes Document._makeEditable() to be called). @@ -273,7 +273,7 @@ define(function (require, exports, module) { EditorManager._createUnattachedMasterEditor(this); } }; - + /** * Returns the document's current contents; may not be saved to disk yet. Whenever this * value changes, the Document dispatches a "change" event. @@ -294,7 +294,7 @@ define(function (require, exports, module) { } } return codeMirrorText; - + } else { // Optimized path that doesn't require creating master editor if (useOriginalLineEndings) { @@ -304,12 +304,12 @@ define(function (require, exports, module) { } } }; - + /** Normalizes line endings the same way CodeMirror would */ Document.normalizeText = function (text) { return text.replace(/\r\n/g, "\n"); }; - + /** * Sets the contents of the document. Treated as an edit. Line endings will be rewritten to * match the document's current line-ending style. @@ -320,7 +320,7 @@ define(function (require, exports, module) { this._masterEditor._codeMirror.setValue(text); // _handleEditorChange() triggers "change" event }; - + /** * @private * Triggers the appropriate events when a change occurs: "change" on the Document instance @@ -331,7 +331,7 @@ define(function (require, exports, module) { this.trigger("change", this, changeList); exports.trigger("documentChange", this, changeList); }; - + /** * Sets the contents of the document. Treated as reloading the document from disk: the document * will be marked clean with a new timestamp, the undo/redo history is cleared, and we re-check @@ -347,13 +347,13 @@ define(function (require, exports, module) { // If clean, don't transiently mark dirty during refresh // (we'll still send change events though, of course) this._refreshInProgress = true; - + if (this._masterEditor) { this._masterEditor._resetText(text); // clears undo history too // _handleEditorChange() triggers "change" event for us } else { this._text = text; - + if (!initial) { // We fake a change record here that looks like CodeMirror's text change records, but // omits "from" and "to", by which we mean the entire text has changed. @@ -364,33 +364,33 @@ define(function (require, exports, module) { } } this._updateTimestamp(newTimestamp); - + // If Doc was dirty before refresh, reset it to clean now (don't always call, to avoid no-op dirtyFlagChange events) Since // _resetText() above already ensures Editor state is clean, it's safe to skip _markClean() as long as our own state is already clean too. if (this.isDirty) { this._markClean(); } this._refreshInProgress = false; - + // Sniff line-ending style this._lineEndings = FileUtils.sniffLineEndings(text); if (!this._lineEndings) { this._lineEndings = FileUtils.getPlatformLineEndings(); } - + exports.trigger("_documentRefreshed", this); PerfUtils.addMeasurement(perfTimerName); }; - + /** * Adds, replaces, or removes text. If a range is given, the text at that range is replaced with the * given new text; if text == "", then the entire range is effectively deleted. If 'end' is omitted, * then the new text is inserted at that point and all existing text is preserved. Line endings will * be rewritten to match the document's current line-ending style. - * + * * IMPORTANT NOTE: Because of #1688, do not use this in cases where you might be - * operating on a linked document (like the main document for an inline editor) + * operating on a linked document (like the main document for an inline editor) * during an outer CodeMirror operation (like a key event that's handled by the * editor itself). A common case of this is code hints in inline editors. In * such cases, use `editor._codeMirror.replaceRange()` instead. This should be @@ -400,7 +400,7 @@ define(function (require, exports, module) { * @param {!{line:number, ch:number}} start Start of range, inclusive (if 'to' specified) or insertion point (if not) * @param {?{line:number, ch:number}} end End of range, exclusive; optional * @param {?string} origin Optional string used to batch consecutive edits for undo. - * If origin starts with "+", then consecutive edits with the same origin will be batched for undo if + * If origin starts with "+", then consecutive edits with the same origin will be batched for undo if * they are close enough together in time. * If origin starts with "*", then all consecutive edit with the same origin will be batched for * undo. @@ -413,7 +413,7 @@ define(function (require, exports, module) { this._masterEditor._codeMirror.replaceRange(text, start, end, origin); // _handleEditorChange() triggers "change" event }; - + /** * Returns the characters in the given range. Line endings are normalized to '\n'. * @param {!{line:number, ch:number}} start Start of range, inclusive @@ -424,7 +424,7 @@ define(function (require, exports, module) { this._ensureMasterEditor(); return this._masterEditor._codeMirror.getRange(start, end); }; - + /** * Returns the text of the given line (excluding any line ending characters) * @param {number} Zero-based line number @@ -434,7 +434,7 @@ define(function (require, exports, module) { this._ensureMasterEditor(); return this._masterEditor._codeMirror.getLine(lineNum); }; - + /** * Batches a series of related Document changes. Repeated calls to replaceRange() should be wrapped in a * batch for efficiency. Begins the batch, calls doOperation(), ends the batch, and then returns. @@ -442,11 +442,11 @@ define(function (require, exports, module) { */ Document.prototype.batchOperation = function (doOperation) { this._ensureMasterEditor(); - + var self = this; self._masterEditor._codeMirror.operation(doOperation); }; - + /** * Handles changes from the master backing Editor. Changes are triggered either by direct edits * to that Editor's UI, OR by our setText()/refreshText() methods. @@ -457,7 +457,7 @@ define(function (require, exports, module) { if (this._masterEditor !== editor) { return; } - + // TODO: This needs to be kept in sync with SpecRunnerUtils.createMockActiveDocument(). In the // future, we should fix things so that we either don't need mock documents or that this // is factored so it will just run in both. @@ -465,17 +465,17 @@ define(function (require, exports, module) { // Sync isDirty from CodeMirror state var wasDirty = this.isDirty; this.isDirty = !editor._codeMirror.isClean(); - + // Notify if isDirty just changed (this also auto-adds us to working set if needed) if (wasDirty !== this.isDirty) { exports.trigger("_dirtyFlagChange", this); } } - + // Notify that Document's text has changed this._notifyDocumentChange(changeList); }; - + /** * @private */ @@ -486,7 +486,7 @@ define(function (require, exports, module) { } exports.trigger("_dirtyFlagChange", this); }; - + /** * @private */ @@ -495,8 +495,8 @@ define(function (require, exports, module) { // Clear the "keep changes" timestamp since it's no longer relevant. this.keepChangesTime = null; }; - - /** + + /** * Called when the document is saved (which currently happens in DocumentCommandHandlers). Marks the * document not dirty and notifies listeners of the save. */ @@ -504,9 +504,9 @@ define(function (require, exports, module) { if (!this._masterEditor) { console.log("### Warning: saving a Document that is not modifiable!"); } - + this._markClean(); - + // TODO: (issue #295) fetching timestamp async creates race conditions (albeit unlikely ones) var thisDoc = this; this.file.stat(function (err, stat) { @@ -518,11 +518,11 @@ define(function (require, exports, module) { exports.trigger("_documentSaved", thisDoc); }); }; - + /** - * Adjusts a given position taking a given replaceRange-type edit into account. + * Adjusts a given position taking a given replaceRange-type edit into account. * If the position is within the original edit range (start and end inclusive), - * it gets pushed to the end of the content that replaced the range. Otherwise, + * it gets pushed to the end of the content that replaced the range. Otherwise, * if it's after the edit, it gets adjusted so it refers to the same character * it did before the edit. * @param {!{line:number, ch: number}} pos The position to adjust. @@ -550,7 +550,7 @@ define(function (require, exports, module) { } return {line: line, ch: ch}; }; - + /** * Like _.each(), but if given a single item not in an array, acts as * if it were an array containing just that item. @@ -562,7 +562,7 @@ define(function (require, exports, module) { cb(itemOrArr, 0); } } - + /** * Helper function for edit operations that operate on multiple selections. Takes an "edit list" * that specifies a list of replaceRanges that should occur, but where all the positions are with @@ -582,15 +582,15 @@ define(function (require, exports, module) { * * @param {!Array.<{edit: {text: string, start:{line: number, ch: number}, end:?{line: number, ch: number}} * | Array.<{text: string, start:{line: number, ch: number}, end:?{line: number, ch: number}}>, - * selection: ?{start:{line:number, ch:number}, end:{line:number, ch:number}, + * selection: ?{start:{line:number, ch:number}, end:{line:number, ch:number}, * primary:boolean, reversed: boolean, isBeforeEdit: boolean}>} - * | ?Array.<{start:{line:number, ch:number}, end:{line:number, ch:number}, + * | ?Array.<{start:{line:number, ch:number}, end:{line:number, ch:number}, * primary:boolean, reversed: boolean, isBeforeEdit: boolean}>}>} edits * Specifies the list of edits to perform in a manner similar to CodeMirror's `replaceRange`. This array * will be mutated. * * `edit` is the edit to perform: - * `text` will replace the current contents of the range between `start` and `end`. + * `text` will replace the current contents of the range between `start` and `end`. * If `end` is unspecified, the text is inserted at `start`. * `start` and `end` should be positions relative to the document *ignoring* all other edit descriptions * (i.e., as if you were only performing this one edit on the document). @@ -609,7 +609,7 @@ define(function (require, exports, module) { * and then specify a resulting selection that shouldn't be fixed up for any of those edits (but should be * fixed up for edits related to other selections). It can also be useful if you have several selections * that should ignore the effects of a given edit because you've fixed them up already (this commonly happens - * with line-oriented edits where multiple cursors on the same line should be ignored, but still tracked). + * with line-oriented edits where multiple cursors on the same line should be ignored, but still tracked). * Within an edit group, edit positions must be specified relative to previous edits within that group. Also, * the total bounds of edit groups must not overlap (e.g. edits in one group can't surround an edit from another group). * @@ -619,7 +619,7 @@ define(function (require, exports, module) { */ Document.prototype.doMultipleEdits = function (edits, origin) { var self = this; - + // Sort the edits backwards, so we don't have to adjust the edit positions as we go along // (though we do have to adjust the selection positions). edits.sort(function (editDesc1, editDesc2) { @@ -635,11 +635,11 @@ define(function (require, exports, module) { return CodeMirror.cmpPos(edit2.start, edit1.start); } }); - + // Pull out the selections, in the same order as the edits. var result = _.cloneDeep(_.pluck(edits, "selection")); - - // Preflight the edits to specify "end" if unspecified and make sure they don't overlap. + + // Preflight the edits to specify "end" if unspecified and make sure they don't overlap. // (We don't want to do it during the actual edits, since we don't want to apply some of // the edits before we find out.) _.each(edits, function (editDesc, index) { @@ -661,7 +661,7 @@ define(function (require, exports, module) { } }); }); - + // Perform the edits. this.batchOperation(function () { _.each(edits, function (editDesc, index) { @@ -689,7 +689,7 @@ define(function (require, exports, module) { }); }); }); - + result = _.chain(result) .filter(function (item) { return item !== undefined; @@ -704,7 +704,7 @@ define(function (require, exports, module) { }); return result; }; - + /* (pretty toString(), to aid debugging) */ Document.prototype.toString = function () { var dirtyInfo = (this.isDirty ? " (dirty!)" : " (clean)"); @@ -712,7 +712,7 @@ define(function (require, exports, module) { var refInfo = " refs:" + this._refCount; return "[Document " + this.file.fullPath + dirtyInfo + editorInfo + refInfo + "]"; }; - + /** * Returns the language this document is written in. * The language returned is based on the file extension. @@ -721,7 +721,7 @@ define(function (require, exports, module) { Document.prototype.getLanguage = function () { return this.language; }; - + /** * Updates the language to match the current mapping given by LanguageManager */ @@ -732,22 +732,22 @@ define(function (require, exports, module) { this.trigger("languageChanged", oldLanguage, this.language); } }; - + /** Called when Document.file has been modified (due to a rename) */ Document.prototype._notifyFilePathChanged = function () { // File extension may have changed this._updateLanguage(); }; - + /** * Is this an untitled document? - * + * * @return {boolean} - whether or not the document is untitled */ Document.prototype.isUntitled = function () { return this.file instanceof InMemoryFile; }; - + // We dispatch events from the module level, and the instance level. Instance events are wired up // in the Document constructor. EventDispatcher.makeEventDispatcher(exports); diff --git a/src/document/DocumentCommandHandlers.js b/src/document/DocumentCommandHandlers.js index dba78974dcb..2af75899659 100644 --- a/src/document/DocumentCommandHandlers.js +++ b/src/document/DocumentCommandHandlers.js @@ -93,7 +93,7 @@ define(function (require, exports, module) { * @type {string} */ var _osDash = brackets.platform === "mac" ? "\u2014" : "-"; - + /** * String template for window title when no file is open. * @type {string} @@ -254,7 +254,7 @@ define(function (require, exports, module) { _updateTitle(); } } - + /** * Shows an error dialog indicating that the given file could not be opened due to the given error * @param {!FileSystemError} name @@ -277,7 +277,7 @@ define(function (require, exports, module) { * Creates a document and displays an editor for the specified file path. * @param {!string} fullPath * @param {boolean=} silent If true, don't show error message - * @param {string=} paneId, the id oi the pane in which to open the file. Can be undefined, a valid pane id or ACTIVE_PANE. + * @param {string=} paneId, the id oi the pane in which to open the file. Can be undefined, a valid pane id or ACTIVE_PANE. * @param {{*}=} options, command options * @return {$.Promise} a jQuery promise that will either * - be resolved with a file for the specified file path or @@ -350,8 +350,8 @@ define(function (require, exports, module) { * @param {boolean=} silent - If true, don't show error message * @param {string=} paneId - the pane in which to open the file. Can be undefined, a valid pane id or ACTIVE_PANE * @param {{*}=} options - options to pass to MainViewManager._open - * @return {$.Promise} a jQuery promise resolved with a Document object or - * rejected with an err + * @return {$.Promise} a jQuery promise resolved with a Document object or + * rejected with an err */ function _doOpenWithOptionalPath(fullPath, silent, paneId, options) { var result; @@ -376,7 +376,7 @@ define(function (require, exports, module) { filesToOpen.push(FileSystem.getFileForPath(path)); }); MainViewManager.addListToWorkingSet(paneId, filesToOpen); - + _doOpen(paths[paths.length - 1], silent, paneId, options) .done(function (file) { _defaultOpenDialogFullPath = @@ -449,7 +449,7 @@ define(function (require, exports, module) { silent = (commandData && commandData.silent) || false, paneId = (commandData && commandData.paneId) || MainViewManager.ACTIVE_PANE, result = new $.Deferred(); - + _doOpenWithOptionalPath(fileInfo.path, silent, paneId, commandData && commandData.options) .done(function (file) { HealthLogger.fileOpened(fileInfo.path); @@ -1723,7 +1723,7 @@ define(function (require, exports, module) { } else if (brackets.platform === "mac") { showInOS = Strings.CMD_SHOW_IN_FINDER; } - + // Define public API exports.showFileOpenError = showFileOpenError; diff --git a/src/document/DocumentManager.js b/src/document/DocumentManager.js index 52e1c440cc4..073e17a8a28 100644 --- a/src/document/DocumentManager.js +++ b/src/document/DocumentManager.js @@ -26,7 +26,7 @@ /*global define, $ */ /** - * DocumentManager maintains a list of currently 'open' Documents. The DocumentManager is responsible + * DocumentManager maintains a list of currently 'open' Documents. The DocumentManager is responsible * for coordinating document operations and dispatching certain document events. * * Document is the model for a file's contents; it dispatches events whenever those contents change. @@ -66,10 +66,10 @@ * only, but is also triggered for non-editor views e.g. image files). * * - fileNameChange -- When the name of a file or folder has changed. The 2nd arg is the old name. - * The 3rd arg is the new name. Generally, however, file objects have already been changed by the - * time this event is dispatched so code that relies on matching the filename to a file object + * The 3rd arg is the new name. Generally, however, file objects have already been changed by the + * time this event is dispatched so code that relies on matching the filename to a file object * will need to compare the newname. - * + * * - pathDeleted -- When a file or folder has been deleted. The 2nd arg is the path that was deleted. * * To listen for events, do something like this: (see EventDispatcher for details on this pattern) @@ -79,9 +79,9 @@ */ define(function (require, exports, module) { "use strict"; - + var _ = require("thirdparty/lodash"); - + var AppInit = require("utils/AppInit"), EventDispatcher = require("utils/EventDispatcher"), DocumentModule = require("document/Document"), @@ -122,7 +122,7 @@ define(function (require, exports, module) { */ function getOpenDocumentForPath(fullPath) { var id; - + // Need to walk all open documents and check for matching path. We can't // use getFileForPath(fullPath).id since the file it returns won't match // an Untitled document's InMemoryFile. @@ -135,22 +135,22 @@ define(function (require, exports, module) { } return null; } - + /** * Returns the Document that is currently open in the editor UI. May be null. * @return {?Document} */ function getCurrentDocument() { var file = MainViewManager.getCurrentlyViewedFile(MainViewManager.ACTIVE_PANE); - + if (file) { return getOpenDocumentForPath(file.fullPath); } - + return null; } - + /** * Returns a list of items in the working set in UI list order. May be 0-length, but never null. * @deprecated Use MainViewManager.getWorkingSet() instead @@ -175,7 +175,7 @@ define(function (require, exports, module) { DeprecationWarning.deprecationWarning("Use MainViewManager.findInWorkingSet() instead of DocumentManager.findInWorkingSet()", true); return MainViewManager.findInWorkingSet(MainViewManager.ACTIVE_PANE, fullPath); } - + /** * Returns all Documents that are 'open' in the UI somewhere (for now, this means open in an * inline editor and/or a full-size editor). Only these Documents can be modified, and only @@ -192,11 +192,11 @@ define(function (require, exports, module) { } return result; } - - + + /** * Adds the given file to the end of the working set list. - * @deprecated Use MainViewManager.addToWorkingSet() instead + * @deprecated Use MainViewManager.addToWorkingSet() instead * @param {!File} file * @param {number=} index Position to add to list (defaults to last); -1 is ignored * @param {boolean=} forceRedraw If true, a working set change notification is always sent @@ -206,11 +206,11 @@ define(function (require, exports, module) { DeprecationWarning.deprecationWarning("Use MainViewManager.addToWorkingSet() instead of DocumentManager.addToWorkingSet()", true); MainViewManager.addToWorkingSet(MainViewManager.ACTIVE_PANE, file, index, forceRedraw); } - + /** - * @deprecated Use MainViewManager.addListToWorkingSet() instead + * @deprecated Use MainViewManager.addListToWorkingSet() instead * Adds the given file list to the end of the working set list. - * If a file in the list has its own custom viewer, then it + * If a file in the list has its own custom viewer, then it * is not added into the working set. * Does not change which document is currently open in the editor. * More efficient than calling addToWorkingSet() (in a loop) for @@ -222,9 +222,9 @@ define(function (require, exports, module) { MainViewManager.addListToWorkingSet(MainViewManager.ACTIVE_PANE, fileList); } - + /** - * closes a list of files + * closes a list of files * @deprecated Use CommandManager.execute(Commands.FILE_CLOSE_LIST) instead * @param {!Array.} list - list of File objectgs to close */ @@ -232,7 +232,7 @@ define(function (require, exports, module) { DeprecationWarning.deprecationWarning("Use CommandManager.execute(Commands.FILE_CLOSE_LIST, {PaneId: MainViewManager.ALL_PANES, fileList: list}) instead of DocumentManager.removeListFromWorkingSet()", true); CommandManager.execute(Commands.FILE_CLOSE_LIST, {PaneId: MainViewManager.ALL_PANES, fileList: list}); } - + /** * closes all open files * @deprecated CommandManager.execute(Commands.FILE_CLOSE_ALL) instead @@ -243,7 +243,7 @@ define(function (require, exports, module) { } /** - * closes the specified file file + * closes the specified file file * @deprecated use CommandManager.execute(Commands.FILE_CLOSE, {File: file}) instead * @param {!File} file - the file to close */ @@ -251,27 +251,27 @@ define(function (require, exports, module) { DeprecationWarning.deprecationWarning("Use CommandManager.execute(Commands.FILE_CLOSE, {File: file} instead of DocumentManager.closeFullEditor()", true); CommandManager.execute(Commands.FILE_CLOSE, {File: file}); } - + /** * opens the specified document for editing in the currently active pane * @deprecated use CommandManager.execute(Commands.CMD_OPEN, {fullPath: doc.file.fullPath}) instead - * @param {!Document} document The Document to make current. + * @param {!Document} document The Document to make current. */ function setCurrentDocument(doc) { DeprecationWarning.deprecationWarning("Use CommandManager.execute(Commands.CMD_OPEN) instead of DocumentManager.setCurrentDocument()", true); CommandManager.execute(Commands.CMD_OPEN, {fullPath: doc.file.fullPath}); } - + /** - * freezes the Working Set MRU list + * freezes the Working Set MRU list * @deprecated use MainViewManager.beginTraversal() instead */ function beginDocumentNavigation() { DeprecationWarning.deprecationWarning("Use MainViewManager.beginTraversal() instead of DocumentManager.beginDocumentNavigation()", true); MainViewManager.beginTraversal(); } - + /** * ends document navigation and moves the current file to the front of the MRU list in the Working Set * @deprecated use MainViewManager.endTraversal() instead @@ -280,7 +280,7 @@ define(function (require, exports, module) { DeprecationWarning.deprecationWarning("Use MainViewManager.endTraversal() instead of DocumentManager.finalizeDocumentNavigation()", true); MainViewManager.endTraversal(); } - + /** * Get the next or previous file in the working set, in MRU order (relative to currentDocument). May * return currentDocument itself if working set is length 1. @@ -294,7 +294,7 @@ define(function (require, exports, module) { } return null; } - + /** * Cleans up any loose Documents whose only ref is its own master Editor, and that Editor is not * rooted in the UI anywhere. This can happen if the Editor is auto-created via Document APIs that @@ -310,8 +310,8 @@ define(function (require, exports, module) { } }); } - - + + /** * Gets an existing open Document for the given file, or creates a new one if the Document is * not currently open ('open' means referenced by the UI somewhere). Always use this method to @@ -322,7 +322,7 @@ define(function (require, exports, module) { * if you are going to display its contents in a piece of UI - then you must addRef() the Document * and listen for changes on it. (Note: opening the Document in an Editor automatically manages * refs and listeners for that Editor UI). - * + * * If all you need is the Document's getText() value, use the faster getDocumentText() instead. * * @param {!string} fullPath @@ -336,35 +336,35 @@ define(function (require, exports, module) { // use existing document return new $.Deferred().resolve(doc).promise(); } else { - + // Should never get here if the fullPath refers to an Untitled document if (fullPath.indexOf(_untitledDocumentPath) === 0) { console.error("getDocumentForPath called for non-open untitled document: " + fullPath); return new $.Deferred().reject().promise(); } - + var file = FileSystem.getFileForPath(fullPath), pendingPromise = getDocumentForPath._pendingDocumentPromises[file.id]; - + if (pendingPromise) { // wait for the result of a previous request return pendingPromise; } else { var result = new $.Deferred(), promise = result.promise(); - + // log this document's Promise as pending getDocumentForPath._pendingDocumentPromises[file.id] = promise; - + // create a new document var perfTimerName = PerfUtils.markStart("getDocumentForPath:\t" + fullPath); - + result.done(function () { PerfUtils.addMeasurement(perfTimerName); }).fail(function () { PerfUtils.finalizeMeasurement(perfTimerName); }); - + FileUtils.readAsText(file) .always(function () { // document is no longer pending @@ -372,21 +372,21 @@ define(function (require, exports, module) { }) .done(function (rawText, readTimestamp) { doc = new DocumentModule.Document(file, readTimestamp, rawText); - + // This is a good point to clean up any old dangling Documents _gcDocuments(); - + result.resolve(doc); }) .fail(function (fileError) { result.reject(fileError); }); - + return promise; } } } - + /** * Document promises that are waiting to be resolved. It is possible for multiple clients * to request the same document simultaneously before the initial request has completed. @@ -397,20 +397,20 @@ define(function (require, exports, module) { * @type {Object.} */ getDocumentForPath._pendingDocumentPromises = {}; - + /** * Gets the text of a Document (including any unsaved changes), or would-be Document if the * file is not actually open. More efficient than getDocumentForPath(). Use when you're reading * document(s) but don't need to hang onto a Document object. - * + * * If the file is open this is equivalent to calling getOpenDocumentForPath().getText(). If the * file is NOT open, this is like calling getDocumentForPath()...getText() but more efficient. * Differs from plain FileUtils.readAsText() in two ways: (a) line endings are still normalized * as in Document.getText(); (b) unsaved changes are returned if there are any. - * + * * @param {!File} file The file to get the text for. * @param {boolean=} checkLineEndings Whether to return line ending information. Default false (slightly more efficient). - * @return {$.Promise} + * @return {$.Promise} * A promise that is resolved with three parameters: * contents - string: the document's text * timestamp - Date: the last time the document was changed on disk (might not be the same as the last time it was changed in memory) @@ -438,8 +438,8 @@ define(function (require, exports, module) { } return result.promise(); } - - + + /** * Creates an untitled document. The associated File has a fullPath that * looks like /some-random-string/Untitled-counter.fileExt. @@ -453,12 +453,12 @@ define(function (require, exports, module) { fullPath = _untitledDocumentPath + "/" + filename, now = new Date(), file = new InMemoryFile(fullPath, FileSystem); - + FileSystem.addEntryForPathIfRequired(file, fullPath); return new DocumentModule.Document(file, now, ""); } - + /** * Reacts to a file being deleted: if there is a Document for this file, causes it to dispatch a * "deleted" event; ensures it's not the currentDocument; and removes this file from the working @@ -472,19 +472,19 @@ define(function (require, exports, module) { * * NOTE: This function is not for general consumption, is considered private and may be deprecated * without warning in a future release. - * + * * @param {!File} file */ function notifyFileDeleted(file) { // Notify all editors to close as well exports.trigger("pathDeleted", file.fullPath); - + var doc = getOpenDocumentForPath(file.fullPath); - + if (doc) { doc.trigger("deleted"); } - + // At this point, all those other views SHOULD have released the Doc if (doc && doc._refCount > 0) { console.warn("Deleted " + file.fullPath + " Document still has " + doc._refCount + " references. Did someone addRef() without listening for 'deleted'?"); @@ -498,15 +498,15 @@ define(function (require, exports, module) { * @param {string} fullPath The path of the file/folder that has been deleted */ function notifyPathDeleted(fullPath) { - // FileSyncManager.syncOpenDocuments() does all the work prompting + // FileSyncManager.syncOpenDocuments() does all the work prompting // the user to save any unsaved changes and then calls us back // via notifyFileDeleted FileSyncManager.syncOpenDocuments(Strings.FILE_DELETED_TITLE); - + if (!getOpenDocumentForPath(fullPath) && !MainViewManager.findInAllWorkingSets(fullPath).length) { // For images not open in the workingset, - // FileSyncManager.syncOpenDocuments() will + // FileSyncManager.syncOpenDocuments() will // not tell us to close those views exports.trigger("pathDeleted", fullPath); } @@ -520,19 +520,19 @@ define(function (require, exports, module) { * @param {string} newName The new name of the file/folder */ function notifyPathNameChanged(oldName, newName) { - // Notify all open documents + // Notify all open documents _.forEach(_openDocuments, function (doc) { - // TODO: Only notify affected documents? For now _notifyFilePathChange + // TODO: Only notify affected documents? For now _notifyFilePathChange // just updates the language if the extension changed, so it's fine // to call for all open docs. doc._notifyFilePathChanged(); }); - + // Send a "fileNameChange" event. This will trigger the views to update. exports.trigger("fileNameChange", oldName, newName); } - - + + /** * @private * Update document @@ -561,7 +561,7 @@ define(function (require, exports, module) { } }); } - + // For compatibility DocumentModule .on("_afterDocumentCreate", function (event, doc) { @@ -592,20 +592,20 @@ define(function (require, exports, module) { exports.trigger("dirtyFlagChange", doc); if (doc.isDirty) { MainViewManager.addToWorkingSet(MainViewManager.ACTIVE_PANE, doc.file); - + // We just dirtied a doc and added it to the active working set // this may have come from an internal dirtying so if it was // added to a working set that had no active document then - // open the document + // open the document // - // See: https://github.com/adobe/brackets/issues/9569 + // See: https://github.com/adobe/brackets/issues/9569 // // NOTE: Adding a file to the active working set may not actually add - // it to the active working set (e.g. the document was already + // it to the active working set (e.g. the document was already // opened to the inactive working set.) // // Check that it was actually added to the active working set - + if (!MainViewManager.getCurrentlyViewedFile() && MainViewManager.findInWorkingSet(MainViewManager.ACTIVE_PANE, doc.file.fullPath) !== -1) { CommandManager.execute(Commands.FILE_OPEN, {fullPath: doc.file.fullPath}); @@ -615,11 +615,11 @@ define(function (require, exports, module) { .on("_documentSaved", function (event, doc) { exports.trigger("documentSaved", doc); }); - + /** * @private * Examine each preference key for migration of the working set files. - * If the key has a prefix of "files_/", then it is a working set files + * If the key has a prefix of "files_/", then it is a working set files * preference from old preference model. * * @param {string} key The key of the preference to be examined @@ -633,17 +633,17 @@ define(function (require, exports, module) { var projectPath = key.substr(pathPrefix.length); return "user project.files " + projectPath; } - + return null; } - - + + // Set up event dispatch EventDispatcher.makeEventDispatcher(exports); - + // This deprecated event is dispatched manually from "currentFileChange" below EventDispatcher.markDeprecated(exports, "currentDocumentChange", "MainViewManager.currentFileChange"); - + // These deprecated events are automatically dispatched by DeprecationWarning, set up in AppInit.extensionsLoaded() EventDispatcher.markDeprecated(exports, "workingSetAdd", "MainViewManager.workingSetAdd"); EventDispatcher.markDeprecated(exports, "workingSetAddList", "MainViewManager.workingSetAddList"); @@ -651,7 +651,7 @@ define(function (require, exports, module) { EventDispatcher.markDeprecated(exports, "workingSetRemoveList", "MainViewManager.workingSetRemoveList"); EventDispatcher.markDeprecated(exports, "workingSetSort", "MainViewManager.workingSetSort"); - /* + /* * After extensionsLoaded, register the proxying listeners that convert newer events to * deprecated events. This ensures that extension listeners still run later than core * listeners. If we registered these proxies earlier, extensions would get the deprecated @@ -675,15 +675,15 @@ define(function (require, exports, module) { _proxyDeprecatedEvent("workingSetRemoveList"); _proxyDeprecatedEvent("workingSetSort"); }); - - + + PreferencesManager.convertPreferences(module, {"files_": "user"}, true, _checkPreferencePrefix); // Handle file saves that may affect preferences exports.on("documentSaved", function (e, doc) { PreferencesManager.fileChanged(doc.file.fullPath); }); - + MainViewManager.on("currentFileChange", function (e, newFile, newPaneId, oldFile) { var newDoc = null, oldDoc = null; @@ -691,15 +691,15 @@ define(function (require, exports, module) { if (newFile) { newDoc = getOpenDocumentForPath(newFile.fullPath); } - + if (oldFile) { oldDoc = getOpenDocumentForPath(oldFile.fullPath); } - + if (oldDoc) { oldDoc.off("languageChanged.DocumentManager"); } - + if (newDoc) { PreferencesManager._setCurrentLanguage(newDoc.getLanguage().getId()); newDoc.on("languageChanged.DocumentManager", function (e, oldLang, newLang) { @@ -709,15 +709,15 @@ define(function (require, exports, module) { } else { PreferencesManager._setCurrentLanguage(undefined); } - + if (newDoc !== oldDoc) { // Dispatch deprecated event with doc args (not File args as the new event uses) exports.trigger("currentDocumentChange", newDoc, oldDoc); } }); - - // Deprecated APIs + + // Deprecated APIs exports.getWorkingSet = getWorkingSet; exports.findInWorkingSet = findInWorkingSet; exports.addToWorkingSet = addToWorkingSet; @@ -730,7 +730,7 @@ define(function (require, exports, module) { exports.setCurrentDocument = setCurrentDocument; exports.closeFullEditor = closeFullEditor; exports.closeAll = closeAll; - + // Define public API exports.Document = DocumentModule.Document; exports.getDocumentForPath = getDocumentForPath; @@ -738,7 +738,7 @@ define(function (require, exports, module) { exports.getDocumentText = getDocumentText; exports.createUntitledDocument = createUntitledDocument; exports.getAllOpenDocuments = getAllOpenDocuments; - + // For internal use only exports.notifyPathNameChanged = notifyPathNameChanged; exports.notifyPathDeleted = notifyPathDeleted; diff --git a/src/document/InMemoryFile.js b/src/document/InMemoryFile.js index 01eab4876c7..6c638c089e0 100644 --- a/src/document/InMemoryFile.js +++ b/src/document/InMemoryFile.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the + * 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. - * + * */ @@ -29,34 +29,34 @@ * Represents a file that will never exist on disk - a placeholder backing file for untitled Documents. NO ONE * other than DocumentManager should create instances of InMemoryFile. It is valid to test for one (`instanceof * InMemoryFile`), but it's better to check `doc.isUntitled` where possible. - * + * * Attempts to read/write an InMemoryFile will always fail, and exists() always yields false. InMemoryFile.fullPath * is just a placeholder, and should not be displayed anywhere in the UI; fullPath IS guaranteed to be unique, however. - * + * * An InMemoryFile is not added to the filesystem index, so if you ask the the filesystem anything about this * object, it won't know what you're talking about (`filesystem.getFileForPath(someInMemFile.fullPath)` will not * return someInMemFile). */ define(function (require, exports, module) { "use strict"; - + var File = require("filesystem/File"), FileSystemError = require("filesystem/FileSystemError"); - + function InMemoryFile(fullPath, fileSystem) { File.call(this, fullPath, fileSystem); } - + InMemoryFile.prototype = Object.create(File.prototype); InMemoryFile.prototype.constructor = InMemoryFile; InMemoryFile.prototype.parentClass = File.prototype; - + // Stub out invalid calls inherited from File - + /** * Reject any attempts to read the file. * - * Read a file as text. + * Read a file as text. * * @param {Object=} options Currently unused. * @param {function (number, string, object)} callback @@ -67,7 +67,7 @@ define(function (require, exports, module) { } callback(FileSystemError.NOT_FOUND); }; - + /** * Rejects any attempts to write the file. * @@ -82,30 +82,30 @@ define(function (require, exports, module) { } callback(FileSystemError.NOT_FOUND); }; - - + + // Stub out invalid calls inherited from FileSystemEntry - + InMemoryFile.prototype.exists = function (callback) { callback(null, false); }; - + InMemoryFile.prototype.stat = function (callback) { callback(FileSystemError.NOT_FOUND); }; - + InMemoryFile.prototype.unlink = function (callback) { callback(FileSystemError.NOT_FOUND); }; - + InMemoryFile.prototype.rename = function (newName, callback) { callback(FileSystemError.NOT_FOUND); }; - + InMemoryFile.prototype.moveToTrash = function (callback) { callback(FileSystemError.NOT_FOUND); }; - + // Export this class module.exports = InMemoryFile; }); diff --git a/src/document/TextRange.js b/src/document/TextRange.js index 886160040a2..8361ebb80d6 100644 --- a/src/document/TextRange.js +++ b/src/document/TextRange.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -29,10 +29,10 @@ */ define(function (require, exports, module) { "use strict"; - + var EventDispatcher = require("utils/EventDispatcher"); - - + + /** * Stores a range of lines that is automatically maintained as the Document changes. The range * MAY drop out of sync with the Document in certain edge cases; startLine & endLine will become @@ -62,7 +62,7 @@ define(function (require, exports, module) { function TextRange(document, startLine, endLine) { this.startLine = startLine; this.endLine = endLine; - + this.document = document; document.addRef(); // store this-bound versions of listeners so we can remove them later @@ -72,8 +72,8 @@ define(function (require, exports, module) { document.on("deleted", this._handleDocumentDeleted); } EventDispatcher.makeEventDispatcher(TextRange.prototype); - - + + /** Detaches from the Document. The TextRange will no longer update or send change events */ TextRange.prototype.dispose = function (editor, change) { // Disconnect from Document @@ -81,8 +81,8 @@ define(function (require, exports, module) { this.document.off("change", this._handleDocumentChange); this.document.off("deleted", this._handleDocumentDeleted); }; - - + + /** * Containing document * @type {!Document} @@ -100,8 +100,8 @@ define(function (require, exports, module) { * @type {?number} Null after "lostSync" is dispatched */ TextRange.prototype.endLine = null; - - + + /** * Applies a single Document change object (out of the linked list of multiple such objects) * to this range. @@ -113,19 +113,19 @@ define(function (require, exports, module) { // console.log(this + " applying change to (" + // (change.from && (change.from.line+","+change.from.ch)) + " - " + // (change.to && (change.to.line+","+change.to.ch)) + ")"); - + // Special case: the range is no longer meaningful since the entire text was replaced if (!change.from || !change.to) { this.startLine = null; this.endLine = null; return {hasChanged: true, hasContentChanged: true}; - + // Special case: certain changes around the edges of the range are problematic, because // if they're undone, we'll be unable to determine how to fix up the range to include the // undone content. (The "undo" will just look like an insertion outside our bounds.) So // in those cases, we destroy the range instead of fixing it up incorrectly. The specific // cases are: - // 1. Edit crosses the start boundary of the inline editor (defined as character 0 + // 1. Edit crosses the start boundary of the inline editor (defined as character 0 // of the first line). // 2. Edit crosses the end boundary of the inline editor (defined as the newline at // the end of the last line). @@ -138,14 +138,14 @@ define(function (require, exports, module) { this.startLine = null; this.endLine = null; return {hasChanged: true, hasContentChanged: true}; - + // Normal case: update the range end points if any content was added before them. Note that // we don't rely on line handles for this since we want to gracefully handle cases where the // start or end line was deleted during a change. } else { var numAdded = change.text.length - (change.to.line - change.from.line + 1); var result = {hasChanged: false, hasContentChanged: false}; - + // This logic is so simple because we've already excluded all cases where the change // crosses the range boundaries if (numAdded !== 0) { @@ -163,13 +163,13 @@ define(function (require, exports, module) { // start of the change is within the range, we know the content changed. result.hasContentChanged = true; } - + // console.log("Now " + this); - + return result; } }; - + /** * Updates the range based on the changeList from a Document "change" event. Dispatches a * "change" event if the range was adjusted at all. Dispatches a "lostSync" event instead if the @@ -183,14 +183,14 @@ define(function (require, exports, module) { var result = this._applySingleChangeToRange(changeList[i]); hasChanged = hasChanged || result.hasChanged; hasContentChanged = hasContentChanged || result.hasContentChanged; - + // If we lost sync with the range, just bail now if (this.startLine === null || this.endLine === null) { this.trigger("lostSync"); break; } } - + if (hasChanged) { this.trigger("change"); } @@ -198,22 +198,22 @@ define(function (require, exports, module) { this.trigger("contentChange"); } }; - + TextRange.prototype._handleDocumentChange = function (event, doc, changeList) { this._applyChangesToRange(changeList); }; - + TextRange.prototype._handleDocumentDeleted = function (event) { this.trigger("lostSync"); }; - - + + /* (pretty toString(), to aid debugging) */ TextRange.prototype.toString = function () { return "[TextRange " + this.startLine + "-" + this.endLine + " in " + this.document + "]"; }; - - + + // Define public API exports.TextRange = TextRange; }); diff --git a/src/editor/CSSInlineEditor.js b/src/editor/CSSInlineEditor.js index 68ea5655354..b499c14f9cf 100644 --- a/src/editor/CSSInlineEditor.js +++ b/src/editor/CSSInlineEditor.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -27,7 +27,7 @@ define(function (require, exports, module) { "use strict"; - + // Load dependent modules var CSSUtils = require("language/CSSUtils"), DropdownButton = require("widgets/DropdownButton").DropdownButton, @@ -44,14 +44,14 @@ define(function (require, exports, module) { Strings = require("strings"), ViewUtils = require("utils/ViewUtils"), _ = require("thirdparty/lodash"); - + var _newRuleCmd, _newRuleHandlers = []; function _getCSSFilesInProject() { return ProjectManager.getAllFiles(ProjectManager.getLanguageFilter(["css", "less", "scss"])); } - + /** * Given a position in an HTML editor, returns the relevant selector for the attribute/tag * surrounding that position, or "" if none is found. @@ -64,7 +64,7 @@ define(function (require, exports, module) { var tagInfo = HTMLUtils.getTagInfo(editor, pos), selectorName = "", reason; - + if (tagInfo.position.tokenType === HTMLUtils.TAG_NAME || tagInfo.position.tokenType === HTMLUtils.CLOSING_TAG) { // Type selector selectorName = tagInfo.tagName; @@ -73,7 +73,7 @@ define(function (require, exports, module) { if (tagInfo.attr.name === "class") { // Class selector. We only look for the class name // that includes the insertion point. For example, if - // the attribute is: + // the attribute is: // class="error-dialog modal hide" // and the insertion point is inside "modal", we want ".modal" var attributeValue = tagInfo.attr.value; @@ -106,7 +106,7 @@ define(function (require, exports, module) { reason = Strings.ERROR_CSSQUICKEDIT_UNSUPPORTEDATTR; } } - + return { selectorName: selectorName, reason: reason @@ -128,7 +128,7 @@ define(function (require, exports, module) { inlineEditor.editor.setCursorPos(newRuleInfo.pos.line, newRuleInfo.pos.ch); }); } - + /** * @private * Handle the "new rule" menu item by dispatching it to the handler for the focused inline editor. @@ -144,7 +144,7 @@ define(function (require, exports, module) { } } } - + /** Item renderer for stylesheet-picker dropdown */ function _stylesheetListRenderer(item) { var html = "" + _.escape(item.name); @@ -154,7 +154,7 @@ define(function (require, exports, module) { html += ""; return html; } - + /** * This function is registered with EditManager as an inline editor provider. It creates a CSSInlineEditor * when cursor is on an HTML tag name, class attribute, or id attribute, find associated @@ -172,20 +172,20 @@ define(function (require, exports, module) { if (hostEditor.getLanguageForSelection().getId() !== "html") { return null; } - + // Only provide CSS editor if the selection is within a single line var sel = hostEditor.getSelection(); if (sel.start.line !== sel.end.line) { return null; } - + // Always use the selection start for determining selector name. The pos // parameter is usually the selection end. var selectorResult = _getSelectorName(hostEditor, sel.start); if (selectorResult.selectorName === "") { return selectorResult.reason || null; } - + var selectorName = selectorResult.selectorName; var result = new $.Deferred(), @@ -200,7 +200,7 @@ define(function (require, exports, module) { function _onDropdownSelect(event, fileInfo) { _addRule(selectorName, cssInlineEditor, fileInfo.fullPath); } - + /** * @private * Checks to see if there are any stylesheets in the project, and returns the appropriate @@ -214,7 +214,7 @@ define(function (require, exports, module) { }); return result; } - + /** * @private * Update the enablement of associated menu commands. @@ -222,7 +222,7 @@ define(function (require, exports, module) { function _updateCommands() { _newRuleCmd.setEnabled(cssInlineEditor.hasFocus() && !newRuleButton.$button.hasClass("disabled")); } - + /** * @private * Create a new rule on click. @@ -239,7 +239,7 @@ define(function (require, exports, module) { } } } - + /** * @private * Sort files with LESS/SCSS above CSS, and then within each grouping sort by path & filename @@ -258,7 +258,7 @@ define(function (require, exports, module) { return FileUtils.comparePaths(a.fullPath, b.fullPath); } } - + /** * @private * Prepare file list for display @@ -266,7 +266,7 @@ define(function (require, exports, module) { function _prepFileList(files) { // First, sort list (the same ordering we use for the results list) files.sort(_fileComparator); - + // Find any files that share the same name (with different path) var fileNames = {}; files.forEach(function (file) { @@ -275,7 +275,7 @@ define(function (require, exports, module) { } fileNames[file.name].push(file); }); - + // For any duplicate filenames, set subDirStr to a path snippet the helps // the user distinguish each file in the list. _.forEach(fileNames, function (files) { @@ -289,11 +289,11 @@ define(function (require, exports, module) { return files; } - + function _onHostEditorScroll() { newRuleButton.closeDropdown(); } - + CSSUtils.findMatchingRules(selectorName, hostEditor.document) .done(function (rules) { var inlineEditorDeferred = new $.Deferred(); @@ -318,15 +318,15 @@ define(function (require, exports, module) { newRuleButton.$button.addClass("btn-mini stylesheet-button"); $header.append(newRuleButton.$button); _newRuleHandlers.push({inlineEditor: cssInlineEditor, handler: _handleNewRuleClick}); - + hostEditor.on("scroll", _onHostEditorScroll); - + result.resolve(cssInlineEditor); - + // Now that dialog has been built, collect list of stylesheets var stylesheetsPromise = _getCSSFilesInProject(); - + // After both the stylesheets are loaded and the inline editor has been added to the DOM, // update the UI accordingly. (Those can happen in either order, so we need to wait for both.) // Note that the stylesheetsPromise needs to be passed first in order for the fileInfos to be @@ -335,7 +335,7 @@ define(function (require, exports, module) { $.when(stylesheetsPromise, inlineEditorDeferred.promise()) .done(function (fileInfos) { cssFileInfos = _prepFileList(fileInfos); - + // "New Rule" button is disabled by default and gets enabled // here if there are any stylesheets in project if (cssFileInfos.length > 0) { @@ -344,7 +344,7 @@ define(function (require, exports, module) { // Force focus to the button so the user can create a new rule from the keyboard. newRuleButton.$button.focus(); } - + if (cssFileInfos.length === 1) { // Make it look & feel like a plain button in this case newRuleButton.$button.removeClass("btn-dropdown"); @@ -355,7 +355,7 @@ define(function (require, exports, module) { newRuleButton.on("select", _onDropdownSelect); } } - + _updateCommands(); }); }) @@ -363,12 +363,12 @@ define(function (require, exports, module) { console.warn("Error in findMatchingRules()", error); result.reject(); }); - + return result.promise(); } EditorManager.registerInlineEditProvider(htmlToCSSProvider); - + _newRuleCmd = CommandManager.register(Strings.CMD_CSS_QUICK_EDIT_NEW_RULE, Commands.CSS_QUICK_EDIT_NEW_RULE, _handleNewRule); _newRuleCmd.setEnabled(false); }); diff --git a/src/editor/CodeHintList.js b/src/editor/CodeHintList.js index 7912b9145b2..b8ed7c62117 100644 --- a/src/editor/CodeHintList.js +++ b/src/editor/CodeHintList.js @@ -1,24 +1,24 @@ /* * 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 */ @@ -26,7 +26,7 @@ define(function (require, exports, module) { "use strict"; - + // Load dependent modules var KeyBindingManager = require("command/KeyBindingManager"), Menus = require("command/Menus"), @@ -35,7 +35,7 @@ define(function (require, exports, module) { ValidationUtils = require("utils/ValidationUtils"), ViewUtils = require("utils/ViewUtils"), PopUpManager = require("widgets/PopUpManager"); - + var CodeHintListHTML = require("text!htmlContent/code-hint-list.html"); /** @@ -82,7 +82,7 @@ define(function (require, exports, module) { * @type {Editor} */ this.editor = editor; - + /** * Whether the currently selected hint should be inserted on a tab key event * @@ -121,7 +121,7 @@ define(function (require, exports, module) { .append($("") .hide()) .append(""); - + this._keydownHook = this._keydownHook.bind(this); } @@ -134,10 +134,10 @@ define(function (require, exports, module) { */ CodeHintList.prototype._setSelectedIndex = function (index) { var items = this.$hintMenu.find("li"); - + // Range check index = Math.max(-1, Math.min(index, items.length - 1)); - + // Clear old highlight if (this.selectedIndex !== -1) { $(items[this.selectedIndex]).find("a").removeClass("highlight"); @@ -198,7 +198,7 @@ define(function (require, exports, module) { new RegExp(StringUtils.regexEscape(match), "i"), "$&" ); - + view.hints.push({ formattedHint: "" + displayName + "" }); }; } else { @@ -207,7 +207,7 @@ define(function (require, exports, module) { }; } - // clear the list + // clear the list this.$hintMenu.find("li").remove(); // if there are no hints then close the list; otherwise add them and @@ -221,30 +221,30 @@ define(function (require, exports, module) { if (index >= self.maxResults) { return true; } - + _addHint(item); }); - + // render code hint list var $ul = this.$hintMenu.find("ul.dropdown-menu"), $parent = $ul.parent(); - + // remove list temporarily to save rendering time $ul.remove().append(Mustache.render(CodeHintListHTML, view)); - + $ul.children("li").each(function (index, element) { var hint = self.hints[index], $element = $(element); - + // store hint on each list item $element.data("hint", hint); - + // insert jQuery hint objects after the template is rendered if (hint.jquery) { $element.find(".codehint-item").append(hint); } }); - + // delegate list item events to the top-level ul list element $ul.on("click", "li", function (e) { // Don't let the click propagate upward (otherwise it will @@ -254,15 +254,15 @@ define(function (require, exports, module) { self.handleSelect($(this).data("hint")); } }); - + // Lists with wide results require different formatting if (this.hints.handleWideResults) { $ul.find("li a").addClass("wide-result"); } - + // attach to DOM $parent.append($ul); - + this._setSelectedIndex(selectInitial ? 0 : -1); } }; @@ -291,7 +291,7 @@ define(function (require, exports, module) { } posTop -= 30; // shift top for hidden parent element - + var menuWidth = $menuWindow.width(); var availableWidth = menuWidth; var rightOverhang = posLeft + menuWidth - $window.width(); @@ -304,7 +304,7 @@ define(function (require, exports, module) { return {left: posLeft, top: posTop, width: availableWidth}; }; - + /** * Check whether keyCode is one of the keys that we handle or not. * @@ -364,7 +364,7 @@ define(function (require, exports, module) { $items = self.$hintMenu.find("li"), $view = self.$hintMenu.find("ul.dropdown-menu"), itemHeight; - + if ($items.length !== 0) { itemHeight = $($items[0]).height(); if (itemHeight) { @@ -393,7 +393,7 @@ define(function (require, exports, module) { event.keyCode === KeyEvent.DOM_VK_PAGE_UP || event.keyCode === KeyEvent.DOM_VK_PAGE_DOWN)) { this.handleClose(); - + // Let the event bubble. return false; } else if (keyCode === KeyEvent.DOM_VK_UP) { @@ -427,19 +427,19 @@ define(function (require, exports, module) { // So, assume that pending text dismisses hints and let event bubble. return false; } - + // Trigger a click handler to commmit the selected item $(this.$hintMenu.find("li")[this.selectedIndex]).trigger("click"); } else { // Let the event bubble. return false; } - + event.stopImmediatePropagation(); event.preventDefault(); return true; } - + // If we didn't handle it, let other global keydown hooks handle it. return false; }; @@ -456,7 +456,7 @@ define(function (require, exports, module) { if (this.opened && !this.$hintMenu.hasClass("open")) { this.opened = false; } - + return this.opened; }; @@ -473,15 +473,15 @@ define(function (require, exports, module) { if (this.hints.length) { // Need to add the menu to the DOM before trying to calculate its ideal location. $("#codehint-menu-bar > ul").append(this.$hintMenu); - + var hintPos = this._calcHintListLocation(); - + this.$hintMenu.addClass("open") .css({"left": hintPos.left, "top": hintPos.top, "width": hintPos.width + "px"}); this.opened = true; - + PopUpManager.addPopUp(this.$hintMenu, this.handleClose, true); - + KeyBindingManager.addGlobalKeydownHook(this._keydownHook); } }; @@ -509,13 +509,13 @@ define(function (require, exports, module) { */ CodeHintList.prototype.close = function () { this.opened = false; - + if (this.$hintMenu) { this.$hintMenu.removeClass("open"); PopUpManager.removePopUp(this.$hintMenu); this.$hintMenu.remove(); } - + KeyBindingManager.removeGlobalKeydownHook(this._keydownHook); }; @@ -536,9 +536,9 @@ define(function (require, exports, module) { CodeHintList.prototype.onClose = function (callback) { // TODO: Due to #1381, this won't get called if the user clicks out of // the code hint menu. That's (sort of) okay right now since it doesn't - // really matter if a single old invisible code hint list is lying - // around (it will ignore keydown events, and it'll get closed the next - // time the user pops up a code hint). Once #1381 is fixed this issue + // really matter if a single old invisible code hint list is lying + // around (it will ignore keydown events, and it'll get closed the next + // time the user pops up a code hint). Once #1381 is fixed this issue // should go away. this.handleClose = callback; }; diff --git a/src/editor/CodeHintManager.js b/src/editor/CodeHintManager.js index 920990a5bc1..0621bf392ec 100644 --- a/src/editor/CodeHintManager.js +++ b/src/editor/CodeHintManager.js @@ -265,7 +265,7 @@ define(function (require, exports, module) { PreferencesManager.on("change", "showCodeHints", function () { codeHintsEnabled = PreferencesManager.get("showCodeHints"); }); - + /** * Comparator to sort providers from high to low priority */ @@ -358,7 +358,7 @@ define(function (require, exports, module) { */ function _getProvidersForLanguageId(languageId) { var providers = hintProviders[languageId] || hintProviders.all; - + // Exclude providers that are explicitly disabled in the preferences. // All code hint providers that do not have their constructor // names listed in the preferences are enabled by default. @@ -477,7 +477,7 @@ define(function (require, exports, module) { if (editor.getSelections().length > 1) { return; } - + // Find a suitable provider, if any var language = editor.getLanguageForSelection(), enabledProviders = _getProvidersForLanguageId(language.getId()); @@ -586,7 +586,7 @@ define(function (require, exports, module) { } } } - + /** * Handle a selection change event in the editor. If the selection becomes a * multiple selection, end our current session. diff --git a/src/editor/Editor.js b/src/editor/Editor.js index 3a0b4d6e760..622040b169a 100644 --- a/src/editor/Editor.js +++ b/src/editor/Editor.js @@ -54,7 +54,7 @@ * - optionChange -- Triggered when an option for the editor is changed. The 2nd arg to the listener * is a string containing the editor option that is changing. The 3rd arg, which can be any * data type, is the new value for the editor option. - * - beforeDestroy - Triggered before the object is about to dispose of all its internal state data + * - beforeDestroy - Triggered before the object is about to dispose of all its internal state data * so that listeners can cache things like scroll pos, etc... * * The Editor also dispatches "change" events internally, but you should listen for those on @@ -65,7 +65,7 @@ */ define(function (require, exports, module) { "use strict"; - + var AnimationUtils = require("utils/AnimationUtils"), Async = require("utils/Async"), CodeMirror = require("thirdparty/CodeMirror/lib/codemirror"), @@ -99,9 +99,9 @@ define(function (require, exports, module) { UPPERCASE_COLORS = "uppercaseColors", USE_TAB_CHAR = "useTabChar", WORD_WRAP = "wordWrap"; - + var cmOptions = {}; - + /** * Constants * @type {number} @@ -112,7 +112,7 @@ define(function (require, exports, module) { DEFAULT_TAB_SIZE = 4, MAX_SPACE_UNITS = 10, MAX_TAB_SIZE = 10; - + // Mappings from Brackets preferences to CodeMirror options cmOptions[CLOSE_BRACKETS] = "autoCloseBrackets"; cmOptions[CLOSE_TAGS] = "autoCloseTags"; @@ -127,7 +127,7 @@ define(function (require, exports, module) { cmOptions[TAB_SIZE] = "tabSize"; cmOptions[USE_TAB_CHAR] = "indentWithTabs"; cmOptions[WORD_WRAP] = "lineWrapping"; - + PreferencesManager.definePreference(CLOSE_BRACKETS, "boolean", true, { description: Strings.DESCRIPTION_CLOSE_BRACKETS }); @@ -207,17 +207,17 @@ define(function (require, exports, module) { PreferencesManager.definePreference(WORD_WRAP, "boolean", true, { description: Strings.DESCRIPTION_WORD_WRAP }); - + var editorOptions = Object.keys(cmOptions); /** Editor preferences */ - + /** * Guard flag to prevent focus() reentrancy (via blur handlers), even across Editors * @type {boolean} */ var _duringFocus = false; - + /** * Constant: ignore upper boundary when centering text * @type {number} @@ -228,7 +228,7 @@ define(function (require, exports, module) { /** * @private * Create a copy of the given CodeMirror position - * @param {!CodeMirror.Pos} pos + * @param {!CodeMirror.Pos} pos * @return {CodeMirror.Pos} */ function _copyPos(pos) { @@ -265,7 +265,7 @@ define(function (require, exports, module) { * @type {Array.} */ var _instances = []; - + /** * Creates a new CodeMirror editor instance bound to the given Document. The Document need not have * a "master" Editor realized yet, even if makeMasterEditor is false; in that case, the first time @@ -291,22 +291,22 @@ define(function (require, exports, module) { var isReadOnly = options && options.isReadOnly; _instances.push(this); - + // Attach to document: add ref & handlers this.document = document; document.addRef(); - + if (container.jquery) { // CodeMirror wants a DOM element, not a jQuery wrapper container = container.get(0); } - + var $container = $(container); - + if (range) { // attach this first: want range updated before we process a change this._visibleRange = new TextRange(document, range.startLine, range.endLine); } - + // store this-bound version of listeners so we can remove them later this._handleDocumentChange = this._handleDocumentChange.bind(this); this._handleDocumentDeleted = this._handleDocumentDeleted.bind(this); @@ -319,19 +319,19 @@ define(function (require, exports, module) { document.on("_dirtyFlagChange", this._doWorkingSetSync); var mode = this._getModeFromDocument(); - + // (if makeMasterEditor, we attach the Doc back to ourselves below once we're fully initialized) - + this._inlineWidgets = []; this._inlineWidgetQueues = {}; this._hideMarks = []; this._lastEditorWidth = null; - + this._$messagePopover = null; - + // To track which pane the editor is being attached to if it's a full editor this._paneId = null; - + // Editor supplies some standard keyboard behavior extensions of its own var codeMirrorKeyMap = { "Tab": function () { self._handleTabKey(); }, @@ -361,21 +361,21 @@ define(function (require, exports, module) { "End": "goLineRight", "Cmd-Right": "goLineRight" }; - + var currentOptions = this._currentOptions = _.zipObject( editorOptions, _.map(editorOptions, function (prefName) { return self._getOption(prefName); }) ); - + // When panes are created *after* the showLineNumbers option has been turned off - // we need to apply the show-line-padding class or the text will be juxtaposed + // we need to apply the show-line-padding class or the text will be juxtaposed // to the edge of the editor which makes it not easy to read. The code below to handle // that the option change only applies the class to panes that have already been created // This line ensures that the class is applied to any editor created after the fact $container.toggleClass("show-line-padding", Boolean(!this._getOption("showLineNumbers"))); - + // Create the CodeMirror instance // (note: CodeMirror doesn't actually require using 'new', but jslint complains without it) this._codeMirror = new CodeMirror(container, { @@ -401,14 +401,14 @@ define(function (require, exports, module) { tabSize : currentOptions[TAB_SIZE], readOnly : isReadOnly }); - + // Can't get CodeMirror's focused state without searching for // CodeMirror-focused. Instead, track focus via onFocus and onBlur // options and track state with this._focused this._focused = false; - + this._installEditorListeners(); - + this.on("cursorActivity", function (event, editor) { self._handleCursorActivity(event); }); @@ -418,16 +418,16 @@ define(function (require, exports, module) { this.on("change", function (event, editor, changeList) { self._handleEditorChange(changeList); }); - + // Set code-coloring mode BEFORE populating with text, to avoid a flash of uncolored text this._codeMirror.setOption("mode", mode); - + // Initially populate with text. This will send a spurious change event, so need to make // sure this is understood as a 'sync from document' case, not a genuine edit this._duringSync = true; this._resetText(document.getText()); this._duringSync = false; - + if (range) { this._updateHiddenLines(); this.setCursorPos(range.startLine, 0); @@ -437,14 +437,14 @@ define(function (require, exports, module) { if (makeMasterEditor) { document._makeEditable(this); } - + // Add scrollTop property to this object for the scroll shadow code to use Object.defineProperty(this, "scrollTop", { get: function () { return this._codeMirror.getScrollInfo().top; } }); - + // Add an $el getter for Pane Views Object.defineProperty(this, "$el", { get: function () { @@ -452,24 +452,24 @@ define(function (require, exports, module) { } }); } - + EventDispatcher.makeEventDispatcher(Editor.prototype); EventDispatcher.markDeprecated(Editor.prototype, "keyEvent", "'keydown/press/up'"); - + Editor.prototype.markPaneId = function (paneId) { this._paneId = paneId; - // In case this Editor is initialized not as the first full editor for the document - // and the document is already dirty and present in another working set, make sure + // In case this Editor is initialized not as the first full editor for the document + // and the document is already dirty and present in another working set, make sure // to add this documents to the new panes working set. this._doWorkingSetSync(null, this.document); }; - + Editor.prototype._doWorkingSetSync = function (event, doc) { if (doc === this.document && this._paneId && this.document.isDirty) { MainViewManager.addToWorkingSet(this._paneId, this.document.file, -1, false); } }; - + /** * Removes this editor from the DOM and detaches from the Document. If this is the "master" * Editor that is secretly providing the Document's backing state, then the Document reverts to @@ -481,27 +481,27 @@ define(function (require, exports, module) { // CodeMirror docs for getWrapperElement() say all you have to do is "Remove this from your // tree to delete an editor instance." $(this.getRootElement()).remove(); - + _instances.splice(_instances.indexOf(this), 1); - + // Disconnect from Document this.document.releaseRef(); this.document.off("change", this._handleDocumentChange); this.document.off("deleted", this._handleDocumentDeleted); this.document.off("languageChanged", this._handleDocumentLanguageChanged); this.document.off("_dirtyFlagChange", this._doWorkingSetSync); - + if (this._visibleRange) { // TextRange also refs the Document this._visibleRange.dispose(); } - + // If we're the Document's master editor, disconnecting from it has special meaning if (this.document._masterEditor === this) { this.document._makeNonEditable(); } else { this.document._disassociateEditor(this); } - + // Destroying us destroys any inline widgets we're hosting. Make sure their closeCallbacks // run, at least, since they may also need to release Document refs var self = this; @@ -509,7 +509,7 @@ define(function (require, exports, module) { self._removeInlineWidgetInternal(inlineWidget); }); }; - + /** * @private * Handle any cursor movement in editor, including selecting and unselecting text. @@ -567,7 +567,7 @@ define(function (require, exports, module) { usingTabs = instance.getOption("indentWithTabs"), indentUnit = instance.getOption("indentUnit"), edits = []; - + _.each(selections, function (sel) { var indentStr = "", i, numSpaces; if (usingTabs) { @@ -580,10 +580,10 @@ define(function (require, exports, module) { } edits.push({edit: {text: indentStr, start: sel.start}}); }); - + this.document.doMultipleEdits(edits); }; - + /** * @private * Helper function for `_handleTabKey()` (case 3) - see comment in that function. @@ -598,10 +598,10 @@ define(function (require, exports, module) { _.each(selections, function (sel) { lineLengths[sel.start.line] = instance.getLine(sel.start.line).length; }); - + // First, try to do a smart indent on all selections. CodeMirror.commands.indentAuto(instance); - + // If there were no code or selection changes, then indent each selection one more indent. var changed = false, newSelections = this.getSelections(); @@ -619,30 +619,30 @@ define(function (require, exports, module) { } else { changed = true; } - + if (!changed) { CodeMirror.commands.indentMore(instance); } }; - + /** * @private * Handle Tab key press. */ Editor.prototype._handleTabKey = function () { // Tab key handling is done as follows: - // 1. If any of the selections are multiline, just add one indent level to the + // 1. If any of the selections are multiline, just add one indent level to the // beginning of all lines that intersect any selection. - // 2. Otherwise, if any of the selections is a cursor or single-line range that + // 2. Otherwise, if any of the selections is a cursor or single-line range that // ends at or after the first non-whitespace character in a line: // - if indentation is set to tabs, just insert a hard tab before each selection. // - if indentation is set to spaces, insert the appropriate number of spaces before // each selection to get to its next soft tab stop. - // 3. Otherwise (all selections are cursors or single-line, and are in the whitespace + // 3. Otherwise (all selections are cursors or single-line, and are in the whitespace // before their respective lines), try to autoindent each line based on the mode. // If none of the cursors moved and no space was added, then add one indent level // to the beginning of all lines. - + // Note that in case 2, we do the "dumb" insertion even if the cursor is immediately // before the first non-whitespace character in a line. It might seem more convenient // to do autoindent in that case. However, the problem is if that line is already @@ -666,25 +666,25 @@ define(function (require, exports, module) { selectionType = "indentAtSelection"; } }); - + switch (selectionType) { case "indentAtBeginning": // Case 1 CodeMirror.commands.indentMore(instance); break; - + case "indentAtSelection": // Case 2 this._addIndentAtEachSelection(selections); break; - + case "indentAuto": // Case 3 this._autoIndentEachSelection(selections); break; } }; - + /** * @private * Handle left arrow, right arrow, backspace and delete keys when soft tabs are used. @@ -694,10 +694,10 @@ define(function (require, exports, module) { Editor.prototype._handleSoftTabNavigation = function (direction, functionName) { var instance = this._codeMirror, overallJump = null; - + if (!instance.getOption("indentWithTabs") && PreferencesManager.get(SOFT_TABS)) { var indentUnit = instance.getOption("indentUnit"); - + _.each(this.getSelections(), function (sel) { if (CodeMirror.cmpPos(sel.start, sel.end) !== 0) { // This is a range - it will just collapse/be deleted regardless of the jump we set, so @@ -705,7 +705,7 @@ define(function (require, exports, module) { // we want to keep looking at other ranges.) return; } - + var cursor = sel.start, jump = (indentUnit === 0) ? 1 : cursor.ch % indentUnit, line = instance.getLine(cursor.line); @@ -718,7 +718,7 @@ define(function (require, exports, module) { if (indentUnit) { jump = indentUnit - jump; } - + // Don't jump if it would take us past the end of the line, or if there are // non-whitespace characters within the jump distance. if (cursor.ch + jump > line.length || line.substr(cursor.ch, jump).search(/\S/) !== -1) { @@ -738,8 +738,8 @@ define(function (require, exports, module) { } } - // Did we calculate a jump, and is this jump value either the first one or - // consistent with all the other jumps? If so, we're good. Otherwise, bail + // Did we calculate a jump, and is this jump value either the first one or + // consistent with all the other jumps? If so, we're good. Otherwise, bail // out of the foreach, since as soon as we hit an inconsistent jump we don't // have to look any further. if (jump !== null && @@ -751,14 +751,14 @@ define(function (require, exports, module) { } }); } - + if (overallJump === null) { // Just do the default move, which is one char in the given direction. overallJump = direction; } instance[functionName](overallJump, "char"); }; - + /** * Determine the mode to use from the document's language * Uses "text/plain" if the language does not define a mode @@ -770,15 +770,15 @@ define(function (require, exports, module) { // here so we're always explicit, avoiding console noise. return this.document.getLanguage().getMode() || "text/plain"; }; - - + + /** * Selects all text and maintains the current scroll position. */ Editor.prototype.selectAllNoScroll = function () { var cm = this._codeMirror, info = this._codeMirror.getScrollInfo(); - + // Note that we do not have to check for the visible range here. This // concern is handled internally by code mirror. cm.operation(function () { @@ -786,14 +786,14 @@ define(function (require, exports, module) { cm.execCommand("selectAll"); }); }; - + /** * @return {boolean} True if editor is not showing the entire text of the document (i.e. an inline editor) */ Editor.prototype.isTextSubset = function () { return Boolean(this._visibleRange); }; - + /** * Ensures that the lines that are actually hidden in the inline editor correspond to * the desired visible range. @@ -814,7 +814,7 @@ define(function (require, exports, module) { }); } }; - + Editor.prototype._applyChanges = function (changeList) { // _visibleRange has already updated via its own Document listener. See if this change caused // it to lose sync. If so, our whole view is stale - signal our owner to close us. @@ -840,14 +840,14 @@ define(function (require, exports, module) { } else { cm.replaceRange(newText, change.from, change.to, change.origin); } - + } }); - + // The update above may have inserted new lines - must hide any that fall outside our range this._updateHiddenLines(); }; - + /** * Responds to changes in the CodeMirror editor's text, syncing the changes to the Document. * There are several cases where we want to ignore a CodeMirror change: @@ -861,10 +861,10 @@ define(function (require, exports, module) { if (this._duringSync) { return; } - + // Secondary editor: force creation of "master" editor backing the model, if doesn't exist yet this.document._ensureMasterEditor(); - + if (this.document._masterEditor !== this) { // Secondary editor: // we're not the ground truth; if we got here, this was a real editor change (not a @@ -876,7 +876,7 @@ define(function (require, exports, module) { this._duringSync = true; this.document._masterEditor._applyChanges(changeList); this._duringSync = false; - + // Update which lines are hidden inside our editor, since we're not going to go through // _applyChanges() in our own editor. this._updateHiddenLines(); @@ -885,7 +885,7 @@ define(function (require, exports, module) { // we're the ground truth; nothing else to do, since Document listens directly to us // note: this change might have been a real edit made by the user, OR this might have // been a change synced from another editor - + // The "editorChange" event is mostly for the use of the CodeHintManager. // It differs from the normal "change" event, that it's actually publicly usable, // whereas the "change" event should be listened to on the document. Also the @@ -893,7 +893,7 @@ define(function (require, exports, module) { // CodeHintManager needs to hook in here when other things are already done. this.trigger("editorChange", this, changeList); }; - + /** * Responds to changes in the Document's text, syncing the changes into our CodeMirror instance. * There are several cases where we want to ignore a Document change: @@ -907,7 +907,7 @@ define(function (require, exports, module) { if (this._duringSync) { return; } - + if (this.document._masterEditor !== this) { // Secondary editor: // we're not the ground truth; and if we got here, this was a Document change that @@ -921,7 +921,7 @@ define(function (require, exports, module) { // we're the ground truth; nothing to do since Document change is just echoing our // editor changes }; - + /** * Responds to the Document's underlying file being deleted. The Document is now basically dead, * so we must close. @@ -930,22 +930,22 @@ define(function (require, exports, module) { // Pass the delete event along as the cause (needed in MultiRangeInlineEditor) this.trigger("lostContent", event); }; - + /** * Responds to language changes, for instance when the file extension is changed. */ Editor.prototype._handleDocumentLanguageChanged = function (event) { this._codeMirror.setOption("mode", this._getModeFromDocument()); }; - - + + /** * Install event handlers on the CodeMirror instance, translating them into * jQuery events on the Editor instance. */ Editor.prototype._installEditorListeners = function () { var self = this; - + // Redispatch these CodeMirror key events as Editor events function _onKeyEvent(instance, event) { self.trigger("keyEvent", self, event); // deprecated @@ -955,7 +955,7 @@ define(function (require, exports, module) { this._codeMirror.on("keydown", _onKeyEvent); this._codeMirror.on("keypress", _onKeyEvent); this._codeMirror.on("keyup", _onKeyEvent); - + // FUTURE: if this list grows longer, consider making this a more generic mapping // NOTE: change is a "private" event--others shouldn't listen to it on Editor, only on // Document @@ -988,7 +988,7 @@ define(function (require, exports, module) { // Set this full editor as master editor for the document self.document._toggleMasterEditor(self); }); - + this._codeMirror.on("blur", function () { self._focused = false; self.trigger("blur", self); @@ -1016,7 +1016,7 @@ define(function (require, exports, module) { elt.style.paddingLeft = (basePadding + off) + "px"; }); }; - + /** * Sets the contents of the editor, clears the undo/redo history and marks the document clean. Dispatches a change event. * Semi-private: only Document should call this. @@ -1027,16 +1027,16 @@ define(function (require, exports, module) { var cursorPos = this.getCursorPos(), scrollPos = this.getScrollPos(); - + // This *will* fire a change event, but we clear the undo immediately afterward this._codeMirror.setValue(text); this._codeMirror.refresh(); - + // Make sure we can't undo back to the empty state before setValue(), and mark // the document clean. this._codeMirror.clearHistory(); this._codeMirror.markClean(); - + // restore cursor and scroll positions this.setCursorPos(cursorPos); this.setScrollPos(scrollPos.x, scrollPos.y); @@ -1052,7 +1052,7 @@ define(function (require, exports, module) { Editor.prototype.getFile = function () { return this.document.file; }; - + /** * Gets the current cursor position within the editor. * @param {boolean} expandTabs If true, return the actual visual column number instead of the character offset in @@ -1074,13 +1074,13 @@ define(function (require, exports, module) { which = "to"; } var cursor = _copyPos(this._codeMirror.getCursor(which)); - + if (expandTabs) { cursor.ch = this.getColOffset(cursor); } return cursor; }; - + /** * Returns the display column (zero-based) for a given string-based pos. Differs from pos.ch only * when the line contains preceding \t chars. Result depends on the current tab size setting. @@ -1107,7 +1107,7 @@ define(function (require, exports, module) { } return column; }; - + /** * Returns the string-based pos for a given display column (zero-based) in given line. Differs from column * only when the line contains preceding \t chars. Result depends on the current tab size setting. @@ -1135,7 +1135,7 @@ define(function (require, exports, module) { } return i; }; - + /** * Sets the cursor position within the editor. Removes any selection. * @param {number} line The 0 based line number. @@ -1153,7 +1153,7 @@ define(function (require, exports, module) { this.centerOnCursor(); } }; - + /** * Set the editor size in pixels or percentage * @param {(number|string)} width @@ -1162,10 +1162,10 @@ define(function (require, exports, module) { Editor.prototype.setSize = function (width, height) { this._codeMirror.setSize(width, height); }; - + /** @const */ var CENTERING_MARGIN = 0.15; - + /** * Scrolls the editor viewport to vertically center the line with the cursor, * but only if the cursor is currently near the edges of the viewport or @@ -1178,14 +1178,14 @@ define(function (require, exports, module) { Editor.prototype.centerOnCursor = function (centerOptions) { var $scrollerElement = $(this.getScrollerElement()); var editorHeight = $scrollerElement.height(); - + // we need to make adjustments for the statusbar's padding on the bottom and the menu bar on top. var statusBarHeight = $scrollerElement.outerHeight() - editorHeight; var menuBarHeight = $scrollerElement.offset().top; - + var documentCursorPosition = this._codeMirror.cursorCoords(null, "local").bottom; var screenCursorPosition = this._codeMirror.cursorCoords(null, "page").bottom - menuBarHeight; - + // If the cursor is already reasonably centered, we won't // make any change. "Reasonably centered" is defined as // not being within CENTERING_MARGIN of the top or bottom @@ -1231,18 +1231,18 @@ define(function (require, exports, module) { return (start.line < pos.line || start.ch <= pos.ch) && // inclusive (end.line > pos.line || end.ch > pos.ch); // exclusive } - + } return false; }; - + /** * @return {boolean} True if there's a text selection; false if there's just an insertion point */ Editor.prototype.hasSelection = function () { return this._codeMirror.somethingSelected(); }; - + /** * @private * Takes an anchor/head pair and returns a start/end pair where the start is guaranteed to be <= end, and a "reversed" flag indicating @@ -1258,26 +1258,26 @@ define(function (require, exports, module) { return {start: _copyPos(anchorPos), end: _copyPos(headPos), reversed: false}; } } - + /** * Gets the current selection; if there is more than one selection, returns the primary selection * (generally the last one made). Start is inclusive, end is exclusive. If there is no selection, * returns the current cursor position as both the start and end of the range (i.e. a selection * of length zero). If `reversed` is set, then the head of the selection (the end of the selection - * that would be changed if the user extended the selection) is before the anchor. + * that would be changed if the user extended the selection) is before the anchor. * @return {!{start:{line:number, ch:number}, end:{line:number, ch:number}}, reversed:boolean} */ Editor.prototype.getSelection = function () { return _normalizeRange(this.getCursorPos(false, "anchor"), this.getCursorPos(false, "head")); }; - + /** - * Returns an array of current selections, nonoverlapping and sorted in document order. + * Returns an array of current selections, nonoverlapping and sorted in document order. * Each selection is a start/end pair, with the start guaranteed to come before the end. * Cursors are represented as a range whose start is equal to the end. * If `reversed` is set, then the head of the selection * (the end of the selection that would be changed if the user extended the selection) - * is before the anchor. + * is before the anchor. * If `primary` is set, then that selection is the primary selection. * @return {Array.<{start:{line:number, ch:number}, end:{line:number, ch:number}, reversed:boolean, primary:boolean}>} */ @@ -1294,7 +1294,7 @@ define(function (require, exports, module) { return result; }); }; - + /** * Takes the given selections, and expands each selection so it encompasses whole lines. Merges * adjacent line selections together. Keeps track of each original selection associated with a given @@ -1307,7 +1307,7 @@ define(function (require, exports, module) { * expandEndAtStartOfLine: true if a range selection that ends at the beginning of a line should be expanded * to encompass the line. Default false. * mergeAdjacent: true if adjacent line ranges should be merged. Default true. - * @return {Array.<{selectionForEdit: {start:{line:number, ch:number}, end:{line:number, ch:number}, reversed:boolean, primary:boolean}, + * @return {Array.<{selectionForEdit: {start:{line:number, ch:number}, end:{line:number, ch:number}, reversed:boolean, primary:boolean}, * selectionsToTrack: Array.<{start:{line:number, ch:number}, end:{line:number, ch:number}, reversed:boolean, primary:boolean}>}>} * The combined line selections. For each selection, `selectionForEdit` is the line selection, and `selectionsToTrack` is * the set of original selections that combined to make up the given line selection. Note that the selectionsToTrack will @@ -1318,13 +1318,13 @@ define(function (require, exports, module) { var self = this; options = options || {}; _.defaults(options, { expandEndAtStartOfLine: false, mergeAdjacent: true }); - + // Combine adjacent lines with selections so they don't collide with each other, as they would // if we did them individually. var combinedSelections = [], prevSel; _.each(selections, function (sel) { var newSel = _.cloneDeep(sel); - + // Adjust selection to encompass whole lines. newSel.start.ch = 0; // The end of the selection becomes the start of the next line, if it isn't already @@ -1348,7 +1348,7 @@ define(function (require, exports, module) { }); return combinedSelections; }; - + /** * Returns the currently selected text, or "" if no selection. Includes \n if the * selection spans multiple lines (does NOT reflect the Document's line-endings style). By @@ -1365,7 +1365,7 @@ define(function (require, exports, module) { return this.document.getRange(sel.start, sel.end); } }; - + /** * Sets the current selection. Start is inclusive, end is exclusive. Places the cursor at the * end of the selection range. Optionally centers around the cursor after @@ -1381,7 +1381,7 @@ define(function (require, exports, module) { Editor.prototype.setSelection = function (start, end, center, centerOptions, origin) { this.setSelections([{start: start, end: end || start}], center, centerOptions, origin); }; - + /** * Sets a multiple selection, with the "primary" selection (the one returned by * getSelection() and getCursorPos()) defaulting to the last if not specified. @@ -1431,7 +1431,7 @@ define(function (require, exports, module) { var word = this._codeMirror.findWordAt(pos); this.setSelection(word.anchor, word.head); }; - + /** * Gets the total number of lines in the the document (includes lines not visible in the viewport) * @return {!number} @@ -1439,7 +1439,7 @@ define(function (require, exports, module) { Editor.prototype.lineCount = function () { return this._codeMirror.lineCount(); }; - + /** * Deterines if line is fully visible. * @param {number} zero-based index of the line to test @@ -1454,7 +1454,7 @@ define(function (require, exports, module) { // Check top and bottom and return false for partially visible lines. return (coords.top >= top && coords.bottom <= bottom); }; - + /** * Gets the number of the first visible line in the editor. * @return {number} The 0-based index of the first visible line. @@ -1462,7 +1462,7 @@ define(function (require, exports, module) { Editor.prototype.getFirstVisibleLine = function () { return (this._visibleRange ? this._visibleRange.startLine : 0); }; - + /** * Gets the number of the last visible line in the editor. * @return {number} The 0-based index of the last visible line. @@ -1480,7 +1480,7 @@ define(function (require, exports, module) { if (to <= from) { return; } - + // We set clearWhenEmpty: false so that if there's a blank line at the beginning or end of // the document, and that's the only hidden line, we can still actually hide it. Doing so // requires us to create a 0-length marked span, which would ordinarily be cleaned up by CM @@ -1490,7 +1490,7 @@ define(function (require, exports, module) { {line: to - 1, ch: this._codeMirror.getLine(to - 1).length}, {collapsed: true, inclusiveLeft: true, inclusiveRight: true, clearWhenEmpty: false} ); - + return value; }; @@ -1509,7 +1509,7 @@ define(function (require, exports, module) { Editor.prototype.getScrollerElement = function () { return this._codeMirror.getScrollerElement(); }; - + /** * Gets the root DOM node of the editor. * @return {!HTMLDivElement} The editor's root DOM node. @@ -1518,7 +1518,7 @@ define(function (require, exports, module) { return this._codeMirror.getWrapperElement(); }; - + /** * Gets the lineSpace element within the editor (the container around the individual lines of code). * FUTURE: This is fairly CodeMirror-specific. Logic that depends on this may break if we switch @@ -1528,7 +1528,7 @@ define(function (require, exports, module) { Editor.prototype._getLineSpaceElement = function () { return $(".CodeMirror-lines", this.getScrollerElement()).children().get(0); }; - + /** * Returns the current scroll position of the editor. * @return {{x:number, y:number}} The x,y scroll position in pixels @@ -1537,7 +1537,7 @@ define(function (require, exports, module) { var scrollInfo = this._codeMirror.getScrollInfo(); return { x: scrollInfo.left, y: scrollInfo.top }; }; - + /** * Restores and adjusts the current scroll position of the editor. * @param {{x:number, y:number}} scrollPos - The x,y scroll position in pixels @@ -1546,7 +1546,7 @@ define(function (require, exports, module) { Editor.prototype.adjustScrollPos = function (scrollPos, heightDelta) { this._codeMirror.scrollTo(scrollPos.x, scrollPos.y + heightDelta); }; - + /** * Sets the current scroll position of the editor. * @param {number} x scrollLeft position in pixels @@ -1555,7 +1555,7 @@ define(function (require, exports, module) { Editor.prototype.setScrollPos = function (x, y) { this._codeMirror.scrollTo(x, y); }; - + /* * Returns the current text height of the editor. * @return {number} Height of the text in pixels @@ -1563,7 +1563,7 @@ define(function (require, exports, module) { Editor.prototype.getTextHeight = function () { return this._codeMirror.defaultTextHeight(); }; - + /** * Adds an inline widget below the given line. If any inline widget was already open for that * line, it is closed without warning. @@ -1587,23 +1587,23 @@ define(function (require, exports, module) { }); return deferred.promise(); }; - + /** * @private * Does the actual work of addInlineWidget(). */ Editor.prototype._addInlineWidgetInternal = function (pos, inlineWidget, scrollLineIntoView, deferred) { var self = this; - + this.removeAllInlineWidgetsForLine(pos.line).done(function () { if (scrollLineIntoView === undefined) { scrollLineIntoView = true; } - + if (scrollLineIntoView) { self._codeMirror.scrollIntoView(pos); } - + inlineWidget.info = self._codeMirror.addLineWidget(pos.line, inlineWidget.htmlContent, { coverGutter: true, noHScroll: true }); CodeMirror.on(inlineWidget.info.line, "delete", function () { @@ -1623,20 +1623,20 @@ define(function (require, exports, module) { inlineWidget.onAdded(); }); }; - + /** * Removes all inline widgets */ Editor.prototype.removeAllInlineWidgets = function () { // copy the array because _removeInlineWidgetInternal will modify the original var widgets = [].concat(this.getInlineWidgets()); - + return Async.doInParallel( widgets, this.removeInlineWidget.bind(this) ); }; - + /** * Removes the given inline widget. * @param {number} inlineWidget The widget to remove. @@ -1651,14 +1651,14 @@ define(function (require, exports, module) { self._removeInlineWidgetInternal(inlineWidget); deferred.resolve(); } - + if (!inlineWidget.closePromise) { // Remove the inline widget from our internal list immediately, so // everyone external to us knows it's essentially already gone. We // don't want to wait until it's done animating closed (but we do want // the other stuff in _removeInlineWidgetInternal to wait until then). self._removeInlineWidgetFromList(inlineWidget); - + // If we're not visible (in which case the widget will have 0 client height), // don't try to do the animation, because nothing will happen and we won't get // called back right away. (The animation would happen later when we switch @@ -1674,7 +1674,7 @@ define(function (require, exports, module) { } return inlineWidget.closePromise; }; - + /** * Removes all inline widgets for a given line * @param {number} lineNum The line number to modify @@ -1683,7 +1683,7 @@ define(function (require, exports, module) { var lineInfo = this._codeMirror.lineInfo(lineNum), widgetInfos = (lineInfo && lineInfo.widgets) ? [].concat(lineInfo.widgets) : null, self = this; - + if (widgetInfos && widgetInfos.length) { // Map from CodeMirror LineWidget to Brackets InlineWidget var inlineWidget, @@ -1707,7 +1707,7 @@ define(function (require, exports, module) { return new $.Deferred().resolve().promise(); } }; - + /** * Cleans up the given inline widget from our internal list of widgets. It's okay * to call this multiple times for the same widget--it will just do nothing if @@ -1724,7 +1724,7 @@ define(function (require, exports, module) { } } }; - + /** * Removes the inline widget from the editor and notifies it to clean itself up. * @param {InlineWidget} inlineWidget an inline widget. @@ -1736,7 +1736,7 @@ define(function (require, exports, module) { inlineWidget.isClosed = true; } }; - + /** * Returns a list of all inline widgets currently open in this editor. Each entry contains the * inline's id, and the data parameter that was passed to addInlineWidget(). @@ -1745,20 +1745,20 @@ define(function (require, exports, module) { Editor.prototype.getInlineWidgets = function () { return this._inlineWidgets; }; - + /** * Returns the currently focused inline widget, if any. * @return {?InlineWidget} */ Editor.prototype.getFocusedInlineWidget = function () { var result = null; - + this.getInlineWidgets().forEach(function (widget) { if (widget.hasFocus()) { result = widget; } }); - + return result; }; @@ -1788,7 +1788,7 @@ define(function (require, exports, module) { } _removeListeners(); } - + // PopUpManager.removePopUp() is called either directly by this closure, or by // PopUpManager as a result of another popup being invoked. function _removeMessagePopover() { @@ -1809,17 +1809,17 @@ define(function (require, exports, module) { if (this._$messagePopover) { _removeMessagePopover(); } - + // Make sure cursor is in view cursorPos = this.getCursorPos(); this._codeMirror.scrollIntoView(cursorPos); - + // Determine if arrow is above or below cursorCoord = this._codeMirror.charCoords(cursorPos); - + // Assume popover height is max of 2 lines arrowBelow = (cursorCoord.top > 100); - + // Text is dynamic, so build popover first so we can measure final width this._$messagePopover = $("
    ").addClass("popover-message").appendTo($("body")); if (!arrowBelow) { @@ -1829,19 +1829,19 @@ define(function (require, exports, module) { if (arrowBelow) { $("
    ").addClass("arrowBelow").appendTo(this._$messagePopover); } - + // Estimate where to position popover. top = (arrowBelow) ? cursorCoord.top - this._$messagePopover.height() - POPOVER_MARGIN : cursorCoord.bottom + POPOVER_MARGIN; left = cursorCoord.left - (this._$messagePopover.width() / 2); - + popoverRect = { top: top, left: left, height: this._$messagePopover.height(), width: this._$messagePopover.width() }; - + // See if popover is clipped on any side clip = ViewUtils.getElementClipSize($("#editor-holder"), popoverRect); @@ -1851,10 +1851,10 @@ define(function (require, exports, module) { } else if (clip.right > 0) { left -= clip.right; } - + // Popover text and arrow are positioned individually this._$messagePopover.css({"top": top, "left": left}); - + // Position popover arrow centered over/under cursor... arrowCenter = cursorCoord.left - left; @@ -1889,7 +1889,7 @@ define(function (require, exports, module) { } }); }; - + /** * Returns the offset of the top of the virtual scroll area relative to the browser window (not the editor * itself). Mainly useful for calculations related to scrollIntoView(), where you're starting with the @@ -1922,7 +1922,7 @@ define(function (require, exports, module) { inlineWidget.info.changed(); } } - + function setOuterHeight() { function finishAnimating(e) { if (e.target === node) { @@ -1962,7 +1962,7 @@ define(function (require, exports, module) { }); } }; - + /** * @private * Get the starting line number for an inline widget. @@ -1972,7 +1972,7 @@ define(function (require, exports, module) { Editor.prototype._getInlineWidgetLineNumber = function (inlineWidget) { return this._codeMirror.getLineNumber(inlineWidget.info.line); }; - + /** Gives focus to the editor control */ Editor.prototype.focus = function () { // Focusing an editor synchronously triggers focus/blur handlers. If a blur handler attemps to focus @@ -1983,7 +1983,7 @@ define(function (require, exports, module) { if (_duringFocus) { return; } - + _duringFocus = true; try { this._codeMirror.focus(); @@ -1991,17 +1991,17 @@ define(function (require, exports, module) { _duringFocus = false; } }; - + /** Returns true if the editor has focus */ Editor.prototype.hasFocus = function () { return this._focused; }; - - /* + + /* * @typedef {scrollPos:{x:number, y:number},Array.<{start:{line:number, ch:number},end:{line:number, ch:number}}>} EditorViewState */ - - /* + + /* * returns the view state for the editor * @return {!EditorViewState} */ @@ -2010,9 +2010,9 @@ define(function (require, exports, module) { selections: this.getSelections(), scrollPos: this.getScrollPos() }; - + }; - + /* * Restores the view state * @param {!EditorViewState} viewState - the view state object to restore @@ -2030,7 +2030,7 @@ define(function (require, exports, module) { this.setScrollPos(viewState.scrollPos.x, viewState.scrollPos.y); } }; - + /** * Re-renders the editor UI * @param {boolean=} handleResize true if this is in response to resizing the editor. Default false. @@ -2046,7 +2046,7 @@ define(function (require, exports, module) { focusedItem.focus(); } }; - + /** * Re-renders the editor, and all children inline editors. * @param {boolean=} handleResize true if this is in response to resizing the editor. Default false. @@ -2057,17 +2057,17 @@ define(function (require, exports, module) { inlineWidget.refresh(); }); }; - + /** Undo the last edit. */ Editor.prototype.undo = function () { this._codeMirror.undo(); }; - + /** Redo the last un-done edit. */ Editor.prototype.redo = function () { this._codeMirror.redo(); }; - + /** * View API Visibility Change Notification handler. This is also * called by the native "setVisible" API which refresh can be optimized @@ -2084,7 +2084,7 @@ define(function (require, exports, module) { }); } }; - + /** * Shows or hides the editor within its parent. Does not force its ancestors to * become visible. @@ -2095,7 +2095,7 @@ define(function (require, exports, module) { this.$el.css("display", (show ? "" : "none")); this.notifyVisibilityChange(show, refresh); }; - + /** * Returns true if the editor is fully visible--i.e., is in the DOM, all ancestors are * visible, and has a non-zero width/height. @@ -2103,7 +2103,7 @@ define(function (require, exports, module) { Editor.prototype.isFullyVisible = function () { return $(this.getRootElement()).is(":visible"); }; - + /** * Gets the syntax-highlighting mode for the given range. * Returns null if the mode at the start of the selection differs from the mode at the end - @@ -2131,7 +2131,7 @@ define(function (require, exports, module) { return startMode; } }; - + /** * Gets the syntax-highlighting mode for the current selection or cursor position. (The mode may * vary within one file due to embedded languages, e.g. JS embedded in an HTML script block). See @@ -2157,7 +2157,7 @@ define(function (require, exports, module) { // Shortcut the first check to avoid getModeAt(), which can be expensive if (primarySel.start.line !== primarySel.end.line || primarySel.start.ch !== primarySel.end.ch) { var endMode = TokenUtils.getModeAt(this._codeMirror, primarySel.end); - + if (startMode.name !== endMode.name) { return null; } @@ -2169,7 +2169,7 @@ define(function (require, exports, module) { // We already checked this before, so we know it's not mixed. return false; } - + var rangeMode = self.getModeForRange(sel.start, sel.end, true); return (!rangeMode || rangeMode.name !== startMode.name); }); @@ -2183,15 +2183,15 @@ define(function (require, exports, module) { return this._codeMirror.getOption("mode"); } }; - + /* * gets the language for the selection. (Javascript selected from an HTML document or CSS selected from an HTML document, etc...) - * @return {!Language} + * @return {!Language} */ Editor.prototype.getLanguageForSelection = function () { return this.document.getLanguage().getLanguageForMode(this.getModeForSelection()); }; - + /** * Gets the syntax-highlighting mode for the document. * @@ -2210,14 +2210,14 @@ define(function (require, exports, module) { /** - * The Editor's last known width. - * Used in conjunction with updateLayout to recompute the layout + * The Editor's last known width. + * Used in conjunction with updateLayout to recompute the layout * if the the parent container changes its size since our last layout update. * @type {?number} */ Editor.prototype._lastEditorWidth = null; - - + + /** * If true, we're in the middle of syncing to/from the Document. Used to ignore spurious change * events caused by us (vs. change events caused by others, which we need to pay attention to). @@ -2233,7 +2233,7 @@ define(function (require, exports, module) { * @type {!CodeMirror} */ Editor.prototype._codeMirror = null; - + /** * @private * @type {!Array.<{id:number, data:Object}>} @@ -2245,47 +2245,47 @@ define(function (require, exports, module) { * @type {?TextRange} */ Editor.prototype._visibleRange = null; - + /** * @private * @type {Object} * Promise queues for inline widgets being added to a given line. */ Editor.prototype._inlineWidgetQueues = null; - + /** * @private * @type {Array} * A list of objects corresponding to the markers that are hiding lines in the current editor. */ Editor.prototype._hideMarks = null; - + /** * @private - * + * * Retrieve the value of the named preference for this document. - * + * * @param {string} prefName Name of preference to retrieve. * @return {*} current value of that pref */ Editor.prototype._getOption = function (prefName) { return PreferencesManager.get(prefName, PreferencesManager._buildContext(this.document.file.fullPath, this.document.getLanguage().getId())); }; - + /** * @private - * + * * Updates the editor to the current value of prefName for the file being edited. - * + * * @param {string} prefName Name of the preference to visibly update */ Editor.prototype._updateOption = function (prefName) { var oldValue = this._currentOptions[prefName], newValue = this._getOption(prefName); - + if (oldValue !== newValue) { this._currentOptions[prefName] = newValue; - + if (prefName === USE_TAB_CHAR) { this._codeMirror.setOption(cmOptions[prefName], newValue); this._codeMirror.setOption("indentUnit", newValue === true ? @@ -2304,14 +2304,14 @@ define(function (require, exports, module) { } else { this._codeMirror.setOption(cmOptions[prefName], newValue); } - + this.trigger("optionChange", prefName, newValue); } }; - + /** * @private - * + * * Used to ensure that "style active line" is turned off when there is a selection. */ Editor.prototype._updateStyleActiveLine = function () { @@ -2324,10 +2324,10 @@ define(function (require, exports, module) { } }; - /** + /** * resizes the editor to fill its parent container * should not be used on inline editors - * @param {boolean=} forceRefresh - forces the editor to update its layout + * @param {boolean=} forceRefresh - forces the editor to update its layout * even if it already matches the container's height / width */ Editor.prototype.updateLayout = function (forceRefresh) { @@ -2335,7 +2335,7 @@ define(function (require, exports, module) { curWidth = $(curRoot).width(), $editorHolder = this.$el.parent(), editorAreaHt = $editorHolder.height(); - + if (!curRoot.style.height || $(curRoot).height() !== editorAreaHt) { // Call setSize() instead of $.height() to allow CodeMirror to // check for options like line wrapping @@ -2354,10 +2354,10 @@ define(function (require, exports, module) { this.refreshAll(forceRefresh); } }; - - + + // Global settings that affect Editor instances that share the same preference locations - + /** * Sets whether to use tab characters (vs. spaces) when inserting new text. * Affects any editors that share the same preference location. @@ -2369,7 +2369,7 @@ define(function (require, exports, module) { var options = fullPath && {context: fullPath}; return PreferencesManager.set(USE_TAB_CHAR, value, options); }; - + /** * Gets whether the specified or current file uses tab characters (vs. spaces) when inserting new text * @param {string=} fullPath Path to file to get preference for @@ -2378,7 +2378,7 @@ define(function (require, exports, module) { Editor.getUseTabChar = function (fullPath) { return PreferencesManager.get(USE_TAB_CHAR, _buildPreferencesContext(fullPath)); }; - + /** * Sets tab character width. * Affects any editors that share the same preference location. @@ -2390,7 +2390,7 @@ define(function (require, exports, module) { var options = fullPath && {context: fullPath}; return PreferencesManager.set(TAB_SIZE, value, options); }; - + /** * Get indent unit * @param {string=} fullPath Path to file to get preference for @@ -2399,7 +2399,7 @@ define(function (require, exports, module) { Editor.getTabSize = function (fullPath) { return PreferencesManager.get(TAB_SIZE, _buildPreferencesContext(fullPath)); }; - + /** * Sets indentation width. * Affects any editors that share the same preference location. @@ -2411,7 +2411,7 @@ define(function (require, exports, module) { var options = fullPath && {context: fullPath}; return PreferencesManager.set(SPACE_UNITS, value, options); }; - + /** * Get indentation width * @param {string=} fullPath Path to file to get preference for @@ -2420,7 +2420,7 @@ define(function (require, exports, module) { Editor.getSpaceUnits = function (fullPath) { return PreferencesManager.get(SPACE_UNITS, _buildPreferencesContext(fullPath)); }; - + /** * Sets the auto close brackets. * Affects any editors that share the same preference location. @@ -2432,7 +2432,7 @@ define(function (require, exports, module) { var options = fullPath && {context: fullPath}; return PreferencesManager.set(CLOSE_BRACKETS, value, options); }; - + /** * Gets whether the specified or current file uses auto close brackets * @param {string=} fullPath Path to file to get preference for @@ -2441,7 +2441,7 @@ define(function (require, exports, module) { Editor.getCloseBrackets = function (fullPath) { return PreferencesManager.get(CLOSE_BRACKETS, _buildPreferencesContext(fullPath)); }; - + /** * Sets show line numbers option. * Affects any editors that share the same preference location. @@ -2453,7 +2453,7 @@ define(function (require, exports, module) { var options = fullPath && {context: fullPath}; return PreferencesManager.set(SHOW_LINE_NUMBERS, value, options); }; - + /** * Returns true if show line numbers is enabled for the specified or current file * @param {string=} fullPath Path to file to get preference for @@ -2462,7 +2462,7 @@ define(function (require, exports, module) { Editor.getShowLineNumbers = function (fullPath) { return PreferencesManager.get(SHOW_LINE_NUMBERS, _buildPreferencesContext(fullPath)); }; - + /** * Sets show active line option. * Affects any editors that share the same preference location. @@ -2473,7 +2473,7 @@ define(function (require, exports, module) { Editor.setShowActiveLine = function (value, fullPath) { return PreferencesManager.set(STYLE_ACTIVE_LINE, value); }; - + /** * Returns true if show active line is enabled for the specified or current file * @param {string=} fullPath Path to file to get preference for @@ -2482,7 +2482,7 @@ define(function (require, exports, module) { Editor.getShowActiveLine = function (fullPath) { return PreferencesManager.get(STYLE_ACTIVE_LINE, _buildPreferencesContext(fullPath)); }; - + /** * Sets word wrap option. * Affects any editors that share the same preference location. @@ -2494,7 +2494,7 @@ define(function (require, exports, module) { var options = fullPath && {context: fullPath}; return PreferencesManager.set(WORD_WRAP, value, options); }; - + /** * Returns true if word wrap is enabled for the specified or current file * @param {string=} fullPath Path to file to get preference for @@ -2503,7 +2503,7 @@ define(function (require, exports, module) { Editor.getWordWrap = function (fullPath) { return PreferencesManager.get(WORD_WRAP, _buildPreferencesContext(fullPath)); }; - + /** * Runs callback for every Editor instance that currently exists * @param {!function(!Editor)} callback @@ -2511,7 +2511,7 @@ define(function (require, exports, module) { Editor.forEveryEditor = function (callback) { _instances.forEach(callback); }; - + /** * @private * Toggles the left padding of all code editors. Used to provide more @@ -2528,12 +2528,12 @@ define(function (require, exports, module) { $holders.push($editorHolder); } }); - + _.each($holders, function ($holder) { $holder.toggleClass("show-line-padding", Boolean(showLinePadding)); }); }; - + // Set up listeners for preference changes editorOptions.forEach(function (prefName) { PreferencesManager.on("change", prefName, function () { @@ -2542,10 +2542,10 @@ define(function (require, exports, module) { }); }); }); - + /** * @private - * + * * Manage the conversion from old-style localStorage prefs to the new file-based ones. */ function _convertPreferences() { @@ -2555,9 +2555,9 @@ define(function (require, exports, module) { }); PreferencesManager.convertPreferences(module, rules); } - + _convertPreferences(); - + // Define public API exports.Editor = Editor; exports.BOUNDARY_CHECK_NORMAL = BOUNDARY_CHECK_NORMAL; diff --git a/src/editor/EditorCommandHandlers.js b/src/editor/EditorCommandHandlers.js index 48d45652972..c7de86f0d4a 100644 --- a/src/editor/EditorCommandHandlers.js +++ b/src/editor/EditorCommandHandlers.js @@ -1,24 +1,24 @@ /* * 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 */ @@ -40,13 +40,13 @@ define(function (require, exports, module) { TokenUtils = require("utils/TokenUtils"), CodeMirror = require("thirdparty/CodeMirror/lib/codemirror"), _ = require("thirdparty/lodash"); - + /** * List of constants */ var DIRECTION_UP = -1; var DIRECTION_DOWN = +1; - + /** * @private * Creates special regular expressions that matches the line prefix but not the block prefix or suffix @@ -58,7 +58,7 @@ define(function (require, exports, module) { var i, character, escapedCharacter, subExps = [], prevChars = ""; - + for (i = lineSyntax.length; i < blockSyntax.length; i++) { character = blockSyntax.charAt(i); escapedCharacter = StringUtils.regexEscape(character); @@ -70,7 +70,7 @@ define(function (require, exports, module) { } return new RegExp("^\\s*" + StringUtils.regexEscape(lineSyntax) + "($|" + subExps.join("|") + ")"); } - + /** * @private * Creates regular expressions for multiple line comment prefixes @@ -81,11 +81,11 @@ define(function (require, exports, module) { */ function _createLineExpressions(prefixes, blockPrefix, blockSuffix) { var lineExp = [], escapedPrefix, nothingPushed; - + prefixes.forEach(function (prefix) { escapedPrefix = StringUtils.regexEscape(prefix); nothingPushed = true; - + if (blockPrefix && blockPrefix.indexOf(prefix) === 0) { lineExp.push(_createSpecialLineExp(prefix, blockPrefix)); nothingPushed = false; @@ -100,7 +100,7 @@ define(function (require, exports, module) { }); return lineExp; } - + /** * @private * Returns true if any regular expression matches the given string @@ -113,7 +113,7 @@ define(function (require, exports, module) { return string.match(exp); }); } - + /** * @private * Returns the line comment prefix that best matches the string. Since there might be line comment prefixes @@ -133,7 +133,7 @@ define(function (require, exports, module) { }); return result; } - + /** * @private * Searches between startLine and endLine to check if there is at least one line commented with a line comment, and @@ -147,7 +147,7 @@ define(function (require, exports, module) { function _containsNotLineComment(editor, startLine, endLine, lineExp) { var i, line, containsNotLineComment = false; - + for (i = startLine; i <= endLine; i++) { line = editor.document.getLine(i); // A line is commented out if it starts with 0-N whitespace chars, then a line comment prefix @@ -158,13 +158,13 @@ define(function (require, exports, module) { } return containsNotLineComment; } - + /** * @private * Generates an edit that adds or removes line-comment tokens to all the lines in the selected range, * preserving selection and cursor position. Applies to currently focused Editor. The given selection * must already be a line selection in the form returned by `Editor.convertToLineSelections()`. - * + * * If all non-whitespace lines are already commented out, then we uncomment; otherwise we comment * out. Commenting out adds the prefix at column 0 of every line. Uncommenting removes the first prefix * on each line (if any - empty lines might not have one). @@ -174,7 +174,7 @@ define(function (require, exports, module) { * @param {string=} blockPrefix, e.g. "" * @param {!Editor} editor The editor to edit within. - * @param {!{selectionForEdit: {start:{line:number, ch:number}, end:{line:number, ch:number}, reversed:boolean, primary:boolean}, + * @param {!{selectionForEdit: {start:{line:number, ch:number}, end:{line:number, ch:number}, reversed:boolean, primary:boolean}, * selectionsToTrack: Array.<{start:{line:number, ch:number}, end:{line:number, ch:number}, reversed:boolean, primary:boolean}>}} * lineSel A line selection as returned from `Editor.convertToLineSelections()`. `selectionForEdit` is the selection to perform * the line comment operation on, and `selectionsToTrack` are a set of selections associated with this line that need to be @@ -203,7 +203,7 @@ define(function (require, exports, module) { // some editors like Sublime don't comment them out) var i, line, prefix, commentI, containsNotLineComment = _containsNotLineComment(editor, startLine, endLine, lineExp); - + if (containsNotLineComment) { // Comment out - prepend the first prefix to each line for (i = startLine; i <= endLine; i++) { @@ -236,14 +236,14 @@ define(function (require, exports, module) { } return {edit: editGroup, selection: trackedSels}; } - + /** * @private * Given a token context it will search backwards to determine if the given token is part of a block comment * that doesn't start at the initial token. This is used to know if a line comment is part of a block comment * or if a block delimiter is the prefix or suffix, by passing a token context at that position. Since the * token context will be moved backwards a lot, it is better to pass a new context. - * + * * @param {!{editor:{CodeMirror}, pos:{ch:{number}, line:{number}}, token:{object}}} ctx token context * @param {!string} prefix the block comment prefix * @param {!string} suffix the block comment suffix @@ -255,12 +255,12 @@ define(function (require, exports, module) { function _isPrevTokenABlockComment(ctx, prefix, suffix, prefixExp, suffixExp, lineExp) { // Start searching from the previous token var result = TokenUtils.moveSkippingWhitespace(TokenUtils.movePrevToken, ctx); - + // Look backwards until we find a none line comment token while (result && _matchExpressions(ctx.token.string, lineExp)) { result = TokenUtils.moveSkippingWhitespace(TokenUtils.movePrevToken, ctx); } - + // If we are now in a block comment token if (result && ctx.token.type === "comment") { // If it doesnt matches either prefix or suffix, we know is a block comment @@ -277,18 +277,18 @@ define(function (require, exports, module) { } return false; } - + /** * Generates an edit that adds or removes block-comment tokens to the selection, preserving selection * and cursor position. Applies to the currently focused Editor. - * + * * If the selection is inside a block-comment or one block-comment is inside or partially inside the selection * it will uncomment, otherwise it will comment out, unless if there are multiple block comments inside the selection, * where it does nothing. * Commenting out adds the prefix before the selection and the suffix after. * Uncommenting removes them. - * + * * If all the lines inside the selection are line-comment and if the selection is not inside a block-comment, it will * line uncomment all the lines, otherwise it will block comment/uncomment. In the first case, we return null to * indicate to the caller that it needs to handle this selection as a line comment. @@ -323,25 +323,25 @@ define(function (require, exports, module) { result = true, editGroup = [], edit; - + var searchCtx, atSuffix, suffixEnd, initialPos, endLine; - + if (!selectionsToTrack) { // Track the original selection. selectionsToTrack = [_.cloneDeep(sel)]; } - + // First move the context to the first none white-space token if (!ctx.token.type && !/\S/.test(ctx.token.string)) { result = TokenUtils.moveSkippingWhitespace(TokenUtils.moveNextToken, ctx); } - + // Next, move forwards until we find a comment inside the selection while (result && ctx.token.type !== "comment") { result = TokenUtils.moveSkippingWhitespace(TokenUtils.moveNextToken, ctx) && editor.indexFromPos(ctx.pos) <= selEndIndex; commentAtStart = false; } - + // We are now in a comment, lets check if it is a block or a line comment if (result && ctx.token.type === "comment") { // This token might be at a line comment, but we can't be sure yet @@ -352,16 +352,16 @@ define(function (require, exports, module) { if (ctx.token.start === 0 && !ctx.token.string.match(/^\\s*/) && commentAtStart) { searchCtx = TokenUtils.getInitialContext(editor._codeMirror, {line: ctx.pos.line, ch: ctx.token.start}); isBlockComment = _isPrevTokenABlockComment(searchCtx, prefix, suffix, prefixExp, suffixExp, lineExp); - + // If not, we already know that is a line comment } else { isBlockComment = false; } - + // If it was not a line comment, it has to be a block comment } else { isBlockComment = true; - + // If we are in a line that only has a prefix or a suffix and the prefix and suffix are the same string, // lets find first if this is a prefix or suffix and move the context position to the inside of the block comment. // This means that the token will be anywere inside the block comment, including the lines with the delimiters. @@ -376,36 +376,36 @@ define(function (require, exports, module) { } } } - + if (isBlockComment) { // Save the initial position to start searching for the suffix from here initialPos = _.cloneDeep(ctx.pos); - + // Find the position of the start of the prefix result = true; while (result && !ctx.token.string.match(prefixExp)) { result = TokenUtils.moveSkippingWhitespace(TokenUtils.movePrevToken, ctx); } prefixPos = result && {line: ctx.pos.line, ch: ctx.token.start}; - + // Restore the context at the initial position to find the position of the start of the suffix, // but only when we found the prefix alone in one line if (ctx.token.string === prefix && prefix === suffix) { ctx = TokenUtils.getInitialContext(editor._codeMirror, _.cloneDeep(initialPos)); } - + while (result && !ctx.token.string.match(suffixExp)) { result = TokenUtils.moveSkippingWhitespace(TokenUtils.moveNextToken, ctx); } suffixPos = result && {line: ctx.pos.line, ch: ctx.token.end - suffix.length}; - + // Lets check if there are more comments in the selection. We do nothing if there is one do { result = TokenUtils.moveSkippingWhitespace(TokenUtils.moveNextToken, ctx) && editor.indexFromPos(ctx.pos) <= selEndIndex; } while (result && !ctx.token.string.match(prefixExp)); invalidComment = result && !!ctx.token.string.match(prefixExp); - + // Make sure we didn't search so far backward or forward that we actually found a block comment // that's entirely before or after the selection. suffixEnd = suffixPos && { line: suffixPos.line, ch: suffixPos.ch + suffix.length }; @@ -472,7 +472,7 @@ define(function (require, exports, module) { } } // Now adjust for the prefix insertion. In this case, we do - // want to adjust positions that are exactly at the insertion + // want to adjust positions that are exactly at the insertion // point. if (CodeMirror.cmpPos(pos, sel.start) >= 0) { if (completeLineSel) { @@ -483,7 +483,7 @@ define(function (require, exports, module) { } } } - + updatePosForEdit(trackedSel.start); updatePosForEdit(trackedSel.end); }); @@ -495,7 +495,7 @@ define(function (require, exports, module) { var line = doc.getLine(prefixPos.line).trim(), prefixAtStart = prefixPos.ch === 0 && prefix.length === line.length, suffixAtStart = false; - + if (suffixPos) { line = doc.getLine(suffixPos.line).trim(); suffixAtStart = suffixPos.ch === 0 && suffix.length === line.length; @@ -525,16 +525,16 @@ define(function (require, exports, module) { edit = {edit: editGroup, selection: selectionsToTrack}; } - + return edit; } - - + + /** * Generates an edit that adds or removes block-comment tokens to the selection, preserving selection * and cursor position. Applies to the currently focused Editor. The selection must already be a * line selection in the form returned by `Editor.convertToLineSelections()`. - * + * * The implementation uses blockCommentPrefixSuffix, with the exception of the case where * there is no selection on a uncommented and not empty line. In this case the whole lines gets * commented in a block-comment. @@ -542,7 +542,7 @@ define(function (require, exports, module) { * @param {!Editor} editor * @param {!String} prefix * @param {!String} suffix - * @param {!{selectionForEdit: {start:{line:number, ch:number}, end:{line:number, ch:number}, reversed:boolean, primary:boolean}, + * @param {!{selectionForEdit: {start:{line:number, ch:number}, end:{line:number, ch:number}, reversed:boolean, primary:boolean}, * selectionsToTrack: Array.<{start:{line:number, ch:number}, end:{line:number, ch:number}, reversed:boolean, primary:boolean}>}} * lineSel A line selection as returned from `Editor.convertToLineSelections()`. `selectionForEdit` is the selection to perform * the line comment operation on, and `selectionsToTrack` are a set of selections associated with this line that need to be @@ -554,17 +554,17 @@ define(function (require, exports, module) { */ function _getLineCommentPrefixSuffixEdit(editor, prefix, suffix, lineSel) { var sel = lineSel.selectionForEdit; - + // For one-line selections, we shrink the selection to exclude the trailing newline. if (sel.end.line === sel.start.line + 1 && sel.end.ch === 0) { sel.end = {line: sel.start.line, ch: editor.document.getLine(sel.start.line).length}; } - + // Now just run the standard block comment code, but make sure to track any associated selections // that were subsumed into this line selection. return _getBlockCommentPrefixSuffixEdit(editor, prefix, suffix, [], sel, lineSel.selectionsToTrack); } - + /** * @private * Generates an array of edits for toggling line comments on the given selections. @@ -603,7 +603,7 @@ define(function (require, exports, module) { }); return edits; } - + /** * Invokes a language-specific line-comment/uncomment handler * @param {?Editor} editor If unspecified, applies to the currently focused editor @@ -613,10 +613,10 @@ define(function (require, exports, module) { if (!editor) { return; } - + editor.setSelections(editor.document.doMultipleEdits(_getLineCommentEdits(editor, editor.getSelections()))); } - + /** * Invokes a language-specific block-comment/uncomment handler * @param {?Editor} editor If unspecified, applies to the currently focused editor @@ -626,7 +626,7 @@ define(function (require, exports, module) { if (!editor) { return; } - + var edits = [], lineCommentSels = []; _.each(editor.getSelections(), function (sel) { @@ -651,15 +651,15 @@ define(function (require, exports, module) { edits.push(edit); } }); - + // Handle any line-comment edits. It's okay if these are out-of-order with the other edits, since // they shouldn't overlap, and `doMultipleEdits()` will take care of sorting the edits so the // selections can be tracked appropriately. edits.push.apply(edits, _getLineCommentEdits(editor, lineCommentSels)); - + editor.setSelections(editor.document.doMultipleEdits(edits)); } - + /** * Duplicates the selected text, or current line if no selection. The cursor/selection is left * on the second copy. @@ -686,7 +686,7 @@ define(function (require, exports, module) { rangeSels.push(sel); } }); - + var cursorLineSels = editor.convertToLineSelections(cursorSels); _.each(cursorLineSels, function (lineSel, index) { var sel = lineSel.selectionForEdit; @@ -713,7 +713,7 @@ define(function (require, exports, module) { if (!editor) { return; } - + // Walk the selections, calculating the deletion edits we need to do as we go; // document.doMultipleEdits() will take care of adjusting the edit locations when // it actually performs the edits. @@ -722,7 +722,7 @@ define(function (require, exports, module) { to, lineSelections = editor.convertToLineSelections(editor.getSelections()), edits = []; - + _.each(lineSelections, function (lineSel, index) { var sel = lineSel.selectionForEdit; @@ -730,7 +730,7 @@ define(function (require, exports, module) { to = sel.end; // this is already at the beginning of the line after the last selected line if (to.line === editor.getLastVisibleLine() + 1) { // Instead of deleting the newline after the last line, delete the newline - // before the beginning of the line--unless this is the entire visible content + // before the beginning of the line--unless this is the entire visible content // of the editor, in which case just delete the line content. if (from.line > editor.getFirstVisibleLine()) { from.line -= 1; @@ -746,9 +746,9 @@ define(function (require, exports, module) { }); doc.doMultipleEdits(edits); } - + /** - * Moves the selected text, or current line if no selection. The cursor/selection + * Moves the selected text, or current line if no selection. The cursor/selection * moves with the line/lines. * @param {Editor} editor - target editor * @param {Number} direction - direction of the move (-1,+1) => (Up,Down) @@ -758,7 +758,7 @@ define(function (require, exports, module) { if (!editor) { return; } - + var doc = editor.document, lineSelections = editor.convertToLineSelections(editor.getSelections()), isInlineWidget = !!EditorManager.getFocusedInlineWidget(), @@ -769,7 +769,7 @@ define(function (require, exports, module) { edits = [], newSels = [], pos = {}; - + _.each(lineSelections, function (lineSel) { var sel = lineSel.selectionForEdit, editGroup = []; @@ -826,7 +826,7 @@ define(function (require, exports, module) { editGroup.push({text: "", start: { line: sel.end.line - 1, ch: lineLength }, end: { line: sel.end.line, ch: 0 }}); } editGroup.push({text: nextText, start: { line: sel.start.line, ch: 0 }}); - + // In this case, we don't need to track selections, because the edits are done in such a way that // the existing selections will automatically be updated properly by CodeMirror as it does the edits. edits.push({edit: editGroup}); @@ -854,17 +854,17 @@ define(function (require, exports, module) { editor._codeMirror.scrollIntoView(pos); } } - + /** - * Moves the selected text, or current line if no selection, one line up. The cursor/selection + * Moves the selected text, or current line if no selection, one line up. The cursor/selection * moves with the line/lines. */ function moveLineUp(editor) { moveLine(editor, DIRECTION_UP); } - + /** - * Moves the selected text, or current line if no selection, one line down. The cursor/selection + * Moves the selected text, or current line if no selection, one line down. The cursor/selection * moves with the line/lines. */ function moveLineDown(editor) { @@ -882,7 +882,7 @@ define(function (require, exports, module) { if (!editor) { return; } - + var selections = editor.getSelections(), isInlineWidget = !!EditorManager.getFocusedInlineWidget(), lastLine = editor.getLastVisibleLine(), @@ -890,15 +890,15 @@ define(function (require, exports, module) { edits = [], newSelections, line; - - // First, insert all the newlines (skipping multiple selections on the same line), + + // First, insert all the newlines (skipping multiple selections on the same line), // then indent them all. (We can't easily do them all at once, because doMultipleEdits() // won't do the indentation for us, but we want its help tracking any selection changes // as the result of the edits.) - + // Note that we don't just use `editor.getLineSelections()` here because we don't actually want // to coalesce adjacent selections - we just want to ignore dupes. - + doc.batchOperation(function () { _.each(selections, function (sel, index) { if (index === 0 || @@ -936,7 +936,7 @@ define(function (require, exports, module) { } }); newSelections = doc.doMultipleEdits(edits, "+input"); - + // Now indent each added line (which doesn't mess up any line numbers, and // we're going to set the character offset to the last position on each line anyway). _.each(newSelections, function (sel) { @@ -978,10 +978,10 @@ define(function (require, exports, module) { if (!editor) { return; } - + editor._codeMirror.execCommand("indentMore"); } - + /** * Unindent a line of text if no selection. Otherwise, unindent all lines in selection. */ @@ -990,7 +990,7 @@ define(function (require, exports, module) { if (!editor) { return; } - + editor._codeMirror.execCommand("indentLess"); } @@ -1002,7 +1002,7 @@ define(function (require, exports, module) { editor.setSelections(_.pluck(editor.convertToLineSelections(editor.getSelections(), { expandEndAtStartOfLine: true }), "selectionForEdit")); } } - + /** * @private * Takes the current selection and splits each range into separate selections, one per line. @@ -1053,7 +1053,7 @@ define(function (require, exports, module) { editor.setSelections(origSels.concat(newSels)); } } - + /** * @private * Adds a cursor on the previous line before each selected range to the selection. @@ -1062,7 +1062,7 @@ define(function (require, exports, module) { function addCursorToPrevLine(editor) { addCursorToSelection(editor, -1); } - + /** * @private * Adds a cursor on the next line after each selected range to the selection. @@ -1075,14 +1075,14 @@ define(function (require, exports, module) { function handleUndoRedo(operation) { var editor = EditorManager.getFocusedEditor(); var result = new $.Deferred(); - + if (editor) { editor[operation](); result.resolve(); } else { result.reject(); } - + return result.promise(); } @@ -1096,14 +1096,14 @@ define(function (require, exports, module) { /** * Special command handler that just ignores the command. This is used for Cut, Copy, and Paste. - * These menu items are handled natively, but need to be registered in our JavaScript code so the + * These menu items are handled natively, but need to be registered in our JavaScript code so the * menu items can be created. */ function ignoreCommand() { // Do nothing. The shell will call the native handler for the command. return (new $.Deferred()).reject().promise(); } - + function _handleSelectAll() { var result = new $.Deferred(), editor = EditorManager.getFocusedEditor(); @@ -1117,7 +1117,7 @@ define(function (require, exports, module) { return result.promise(); } - + // Register commands CommandManager.register(Strings.CMD_INDENT, Commands.EDIT_INDENT, indentText); CommandManager.register(Strings.CMD_UNINDENT, Commands.EDIT_UNINDENT, unindentText); diff --git a/src/editor/EditorManager.js b/src/editor/EditorManager.js index 6676d805195..e2b5f6b7ad8 100644 --- a/src/editor/EditorManager.js +++ b/src/editor/EditorManager.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -35,10 +35,10 @@ * must have some knowledge about Document's internal state (we access its _editor property). * * This module dispatches the following events: - * - activeEditorChange -- Fires after the active editor (full or inline). + * - activeEditorChange -- Fires after the active editor (full or inline). * * Doesn't fire when editor temporarily loses focus to a non-editor - * control (e.g. search toolbar or modal dialog, or window deactivation). + * control (e.g. search toolbar or modal dialog, or window deactivation). * * Does fire when focus moves between inline editor and its full-size container. * @@ -50,12 +50,12 @@ * The 2nd arg to the listener is which Editor became active; the 3rd arg is * which Editor is deactivated as a result. Either one may be null. * NOTE (#1257): `getFocusedEditor()` sometimes lags behind this event. Listeners - * should use the arguments or call `getActiveEditor()` to reliably see which Editor + * should use the arguments or call `getActiveEditor()` to reliably see which Editor * just gained focus. */ define(function (require, exports, module) { "use strict"; - + // Load dependent modules var Commands = require("command/Commands"), EventDispatcher = require("utils/EventDispatcher"), @@ -71,23 +71,23 @@ define(function (require, exports, module) { Strings = require("strings"), LanguageManager = require("language/LanguageManager"), DeprecationWarning = require("utils/DeprecationWarning"); - - + + /** * Currently focused Editor (full-size, inline, or otherwise) * @type {?Editor} * @private */ var _lastFocusedEditor = null; - + /** - * Registered inline-editor widget providers sorted descending by priority. + * Registered inline-editor widget providers sorted descending by priority. * @see {@link #registerInlineEditProvider}. * @type {Array.<{priority:number, provider:function(...)}>} * @private */ var _inlineEditProviders = []; - + /** * Registered inline documentation widget providers sorted descending by priority. * @see {@link #registerInlineDocsProvider}. @@ -95,25 +95,25 @@ define(function (require, exports, module) { * @private */ var _inlineDocsProviders = []; - + /** - * Registered jump-to-definition providers. + * Registered jump-to-definition providers. * @see {@link #registerJumpToDefProvider}. * @private * @type {Array.} */ var _jumpToDefProviders = []; - - + + /** * DOM element to house any hidden editors created soley for inline widgets * @private * @type {jQuery} */ var _$hiddenEditorsContainer; - - - /** + + + /** * Retrieves the visible full-size Editor for the currently opened file in the ACTIVE_PANE * @return {?Editor} editor of the current view or null */ @@ -123,20 +123,20 @@ define(function (require, exports, module) { return doc && doc._masterEditor; } - - /** - * Updates _viewStateCache from the given editor's actual current state + + /** + * Updates _viewStateCache from the given editor's actual current state * @private * @param {!Editor} editor - editor to cache data for */ function _saveEditorViewState(editor) { ViewStateManager.updateViewState(editor); } - - /** - * Updates _viewStateCache from the given editor's actual current state - * @param {!Editor} editor - editor restore cached data + + /** + * Updates _viewStateCache from the given editor's actual current state + * @param {!Editor} editor - editor restore cached data * @private */ function _restoreEditorViewState(editor) { @@ -146,7 +146,7 @@ define(function (require, exports, module) { editor.restoreViewState(viewState); } } - + /** * Editor focus handler to change the currently active editor @@ -161,15 +161,15 @@ define(function (require, exports, module) { } var previous = _lastFocusedEditor; _lastFocusedEditor = current; - + exports.trigger("activeEditorChange", current, previous); } - + /** * Current File Changed handler - * MainViewManager dispatches a "currentFileChange" event whenever the currently viewed - * file changes. Which could mean that the previously viewed file has been closed or a - * non-editor view (image) has been given focus. _notifyAcitveEditorChanged is also hooked + * MainViewManager dispatches a "currentFileChange" event whenever the currently viewed + * file changes. Which could mean that the previously viewed file has been closed or a + * non-editor view (image) has been given focus. _notifyAcitveEditorChanged is also hooked * up to editor.focus to handle focus events for editors which handles changing focus between * two editors but, because editormanager maintains a "_lastFocusedEditor" state, we have to * "nullify" that state whenever the focus goes to a non-editor or when the current editor is closed @@ -181,7 +181,7 @@ define(function (require, exports, module) { var doc = file && DocumentManager.getOpenDocumentForPath(file.fullPath); _notifyActiveEditorChanged(doc && doc._masterEditor); } - + /** * Creates a new Editor bound to the given Document. * The editor is appended to the given container as a visible child. @@ -201,31 +201,31 @@ define(function (require, exports, module) { editor.on("focus", function () { _notifyActiveEditorChanged(editor); }); - + editor.on("beforeDestroy", function () { if (editor.$el.is(":visible")) { _saveEditorViewState(editor); } }); - + return editor; } - + /** * @private * Finds an inline widget provider from the given list that can offer a widget for the current cursor * position, and once the widget has been created inserts it into the editor. * * @param {!Editor} editor The host editor - * @param {Array.<{priority:number, provider:function(...)}>} providers + * @param {Array.<{priority:number, provider:function(...)}>} providers * prioritized list of providers * @param {string=} defaultErrorMsg Default message to display if no providers return non-null - * @return {$.Promise} a promise that will be resolved when an InlineWidget + * @return {$.Promise} a promise that will be resolved when an InlineWidget * is created or rejected if no inline providers have offered one. */ function _openInlineWidget(editor, providers, defaultErrorMsg) { PerfUtils.markStart(PerfUtils.INLINE_WIDGET_OPEN); - + // Run through inline-editor providers until one responds var pos = editor.getCursorPos(), inlinePromise, @@ -233,7 +233,7 @@ define(function (require, exports, module) { result = new $.Deferred(), errorMsg, providerRet; - + // Query each provider in priority order. Provider may return: // 1. `null` to indicate it does not apply to current cursor position // 2. promise that should resolve to an InlineWidget @@ -257,7 +257,7 @@ define(function (require, exports, module) { // Use default error message if none other provided errorMsg = errorMsg || defaultErrorMsg; - + // If one of them will provide a widget, show it inline once ready if (inlinePromise) { inlinePromise.done(function (inlineWidget) { @@ -277,15 +277,15 @@ define(function (require, exports, module) { editor.displayErrorMessageAtCursor(errorMsg); result.reject(); } - + return result.promise(); } - - + + /** * Closes any focused inline widget. Else, asynchronously asks providers to create one. * - * @param {Array.<{priority:number, provider:function(...)}>} providers + * @param {Array.<{priority:number, provider:function(...)}>} providers * prioritized list of providers * @param {string=} errorMsg Default message to display if no providers return non-null * @return {!Promise} A promise resolved with true if an inline widget is opened or false @@ -294,12 +294,12 @@ define(function (require, exports, module) { */ function _toggleInlineWidget(providers, errorMsg) { var result = new $.Deferred(); - + var currentEditor = getCurrentFullEditor(); - + if (currentEditor) { var inlineWidget = currentEditor.getFocusedInlineWidget(); - + if (inlineWidget) { // an inline widget's editor has focus, so close it PerfUtils.markStart(PerfUtils.INLINE_WIDGET_CLOSE); @@ -320,10 +320,10 @@ define(function (require, exports, module) { // Can not open an inline editor without a host editor result.reject(); } - + return result.promise(); } - + /** * Inserts a prioritized provider object into the array in sorted (descending) order. * @private @@ -337,22 +337,22 @@ define(function (require, exports, module) { priority: priority, provider: provider }; - + for (index = 0; index < array.length; index++) { if (array[index].priority < priority) { break; } } - + array.splice(index, 0, prioritizedProvider); } - - + + /** - * Creates a hidden, unattached master editor that is needed when a document is created for the + * Creates a hidden, unattached master editor that is needed when a document is created for the * sole purpose of creating an inline editor so operations that require a master editor can be performed * Only called from Document._ensureMasterEditor() - * The editor view is placed in a hidden part of the DOM but can later be moved to a visible pane + * The editor view is placed in a hidden part of the DOM but can later be moved to a visible pane * when the document is opened using pane.addView() * @param {!Document} doc - document to create a hidden editor for */ @@ -366,7 +366,7 @@ define(function (require, exports, module) { // and hide it editor.setVisible(false); } - + /** * Removes the given widget UI from the given hostEditor (agnostic of what the widget's content * is). The widget's onClosed() callback will be run as a result. @@ -384,21 +384,21 @@ define(function (require, exports, module) { if (cursorLine !== widgetLine) { hostEditor.setCursorPos({ line: widgetLine, pos: 0 }); } - + hostEditor.focus(); } - + return hostEditor.removeInlineWidget(inlineWidget); } - + /** * Registers a new inline editor provider. When Quick Edit is invoked each registered provider is * asked if it wants to provide an inline editor given the current editor and cursor location. * An optional priority parameter is used to give providers with higher priority an opportunity * to provide an inline editor before providers with lower priority. - * + * * @param {function(!Editor, !{line:number, ch:number}):?($.Promise|string)} provider - * @param {number=} priority + * @param {number=} priority * The provider returns a promise that will be resolved with an InlineWidget, or returns a string * indicating why the provider cannot respond to this case (or returns null to indicate no reason). */ @@ -414,9 +414,9 @@ define(function (require, exports, module) { * asked if it wants to provide inline docs given the current editor and cursor location. * An optional priority parameter is used to give providers with higher priority an opportunity * to provide an inline editor before providers with lower priority. - * + * * @param {function(!Editor, !{line:number, ch:number}):?($.Promise|string)} provider - * @param {number=} priority + * @param {number=} priority * The provider returns a promise that will be resolved with an InlineWidget, or returns a string * indicating why the provider cannot respond to this case (or returns null to indicate no reason). */ @@ -426,12 +426,12 @@ define(function (require, exports, module) { } _insertProviderSorted(_inlineDocsProviders, provider, priority); } - + /** * Registers a new jump-to-definition provider. When jump-to-definition is invoked each * registered provider is asked if it wants to provide jump-to-definition results, given - * the current editor and cursor location. - * + * the current editor and cursor location. + * * @param {function(!Editor, !{line:number, ch:number}):?$.Promise} provider * The provider returns a promise that is resolved whenever it's done handling the operation, * or returns null to indicate the provider doesn't want to respond to this case. It is entirely @@ -440,7 +440,7 @@ define(function (require, exports, module) { function registerJumpToDefProvider(provider) { _jumpToDefProviders.push(provider); } - + /** * @private * Given a host editor, return a list of all Editors in all its open inline widgets. (Ignoring @@ -451,7 +451,7 @@ define(function (require, exports, module) { */ function getInlineEditors(hostEditor) { var inlineEditors = []; - + if (hostEditor) { hostEditor.getInlineWidgets().forEach(function (widget) { if (widget instanceof InlineTextEditor && widget.editor) { @@ -462,13 +462,13 @@ define(function (require, exports, module) { return inlineEditors; } - - - + + + /** * @private * Creates a new "full-size" (not inline) Editor for the given Document, and sets it as the - * Document's master backing editor. The editor is not yet visible; + * Document's master backing editor. The editor is not yet visible; * Semi-private: should only be called within this module or by Document. * @param {!Document} document Document whose main/full Editor to create * @param {!Pane} pane Pane in which the editor will be hosted @@ -484,8 +484,8 @@ define(function (require, exports, module) { exports.trigger("_fullEditorCreatedForDocument", document, editor, pane.id); return editor; } - - + + /** * Creates a new inline Editor instance for the given Document. * The editor is not yet visible or attached to a host editor. @@ -506,11 +506,11 @@ define(function (require, exports, module) { $(inlineContent).hide(); var inlineEditor = _createEditorForDocument(doc, false, inlineContent, range); $(inlineContent).show(); - + return { content: inlineContent, editor: inlineEditor }; } - /** + /** * Returns focus to the last visible editor that had focus. If no editor visible, does nothing. * This function should be called to restore editor focus after it has been temporarily * removed. For example, after a dialog with editable text is closed. @@ -519,7 +519,7 @@ define(function (require, exports, module) { DeprecationWarning.deprecationWarning("Use MainViewManager.focusActivePane() instead of EditorManager.focusEditor().", true); MainViewManager.focusActivePane(); } - + /** * @deprecated * resizes the editor @@ -541,8 +541,8 @@ define(function (require, exports, module) { // Ensure a main editor exists for this document to show in the UI var createdNewEditor = false, editor = document._masterEditor; - - //Check if a master editor is not set already or the current master editor doesn't belong + + //Check if a master editor is not set already or the current master editor doesn't belong //to the pane container requested - to support creation of multiple full editors if (!editor || editor._paneId !== pane.id) { // Performance (see #4757) Chrome wastes time messing with selection @@ -550,7 +550,7 @@ define(function (require, exports, module) { if (window.getSelection && window.getSelection().empty) { // Chrome window.getSelection().empty(); } - + // Editor doesn't exist: populate a new Editor with the text editor = _createFullEditorForDocument(document, pane, editorOptions); createdNewEditor = true; @@ -571,44 +571,44 @@ define(function (require, exports, module) { /** * @deprecated use MainViewManager.getCurrentlyViewedFile() instead - * @return {string=} path of the file currently viewed in the active, full sized editor or null when there is no active editor + * @return {string=} path of the file currently viewed in the active, full sized editor or null when there is no active editor */ function getCurrentlyViewedPath() { DeprecationWarning.deprecationWarning("Use MainViewManager.getCurrentlyViewedFile() instead of EditorManager.getCurrentlyViewedPath().", true); - + // We only want to return a path of a document object // not other things like images, etc... var currentPath = MainViewManager.getCurrentlyViewedPath(MainViewManager.ACTIVE_PANE), doc; - + if (currentPath) { doc = DocumentManager.getOpenDocumentForPath(currentPath); } - + if (doc) { return currentPath; } - + return null; } - + /** - * @deprecated There is no equivelent API moving forward. + * @deprecated There is no equivelent API moving forward. * Use MainViewManager._initialize() from a unit test to create a Main View attached to a specific DOM element */ function setEditorHolder() { throw new Error("EditorManager.setEditorHolder() has been removed."); } - + /** - * @deprecated Register a View Factory instead + * @deprecated Register a View Factory instead * @see MainViewFactory::#registerViewFactory */ function registerCustomViewer() { throw new Error("EditorManager.registerCustomViewer() has been removed."); } - /** + /** * Determines if the file can be opened in an editor * @param {!string} fullPath - file to be opened * @return {boolean} true if the file can be opened in an editor, false if not @@ -616,8 +616,8 @@ define(function (require, exports, module) { function canOpenPath(fullPath) { return !LanguageManager.getLanguageForPath(fullPath).isBinary(); } - - /** + + /** * Opens the specified document in the given pane * @param {!Document} doc - the document to open * @param {!Pane} pane - the pane to open the document in @@ -634,7 +634,7 @@ define(function (require, exports, module) { PerfUtils.addMeasurement(perfTimerName); } - + /** * Returns the currently focused inline widget, if any. * @return {?InlineWidget} @@ -658,11 +658,11 @@ define(function (require, exports, module) { } return null; } - + /** * Returns the currently focused editor instance (full-sized OR inline editor). * This function is similar to getActiveEditor(), with one main difference: this - * function will only return editors that currently have focus, whereas + * function will only return editors that currently have focus, whereas * getActiveEditor() will return the last visible editor that was given focus (but * may not currently have focus because, for example, a dialog with editable text * is open). @@ -671,7 +671,7 @@ define(function (require, exports, module) { function getFocusedEditor() { var currentEditor = getCurrentFullEditor(); if (currentEditor) { - + // See if any inlines have focus var focusedInline = _getFocusedInlineEditor(); if (focusedInline) { @@ -683,13 +683,13 @@ define(function (require, exports, module) { return currentEditor; } } - + return null; } - + /** - * Returns the current active editor (full-sized OR inline editor). This editor may not - * have focus at the moment, but it is visible and was the last editor that was given + * Returns the current active editor (full-sized OR inline editor). This editor may not + * have focus at the moment, but it is visible and was the last editor that was given * focus. Returns null if no editors are active. * @see #getFocusedEditor * @return {?Editor} @@ -698,7 +698,7 @@ define(function (require, exports, module) { return _lastFocusedEditor; } - + /** * Asynchronously asks providers to handle jump-to-definition. * @return {!Promise} Resolved when the provider signals that it's done; rejected if no @@ -709,14 +709,14 @@ define(function (require, exports, module) { var promise, i, result = new $.Deferred(); - + var editor = getActiveEditor(); - + if (editor) { var pos = editor.getCursorPos(); PerfUtils.markStart(PerfUtils.JUMP_TO_DEFINITION); - + // Run through providers until one responds for (i = 0; i < providers.length && !promise; i++) { var provider = providers[i]; @@ -738,16 +738,16 @@ define(function (require, exports, module) { PerfUtils.finalizeMeasurement(PerfUtils.JUMP_TO_DEFINITION); result.reject(); } - + } else { result.reject(); } - + return result.promise(); } - - - /** + + + /** * file removed from pane handler. * @param {jQuery.Event} e * @param {File|Array.} removedFiles - file, path or array of files or paths that are being removed @@ -760,7 +760,7 @@ define(function (require, exports, module) { MainViewManager._destroyEditorIfNotNeeded(doc); } }; - + // when files are removed from a pane then // we should destroy any unnecssary views if ($.isArray(removedFiles)) { @@ -772,17 +772,17 @@ define(function (require, exports, module) { } } - + // Set up event dispatching EventDispatcher.makeEventDispatcher(exports); - + // File-based preferences handling exports.on("activeEditorChange", function (e, current) { if (current && current.document && current.document.file) { PreferencesManager._setCurrentFile(current.document.file.fullPath); } }); - + // Initialize: command handlers CommandManager.register(Strings.CMD_TOGGLE_QUICK_EDIT, Commands.TOGGLE_QUICK_EDIT, function () { return _toggleInlineWidget(_inlineEditProviders, Strings.ERROR_QUICK_EDIT_PROVIDER_NOT_FOUND); @@ -798,7 +798,7 @@ define(function (require, exports, module) { MainViewManager.on("currentFileChange", _handleCurrentFileChange); MainViewManager.on("workingSetRemove workingSetRemoveList", _handleRemoveFromPaneView); - + // For unit tests and internal use only exports._createFullEditorForDocument = _createFullEditorForDocument; exports._notifyActiveEditorChanged = _notifyActiveEditorChanged; @@ -806,7 +806,7 @@ define(function (require, exports, module) { // Internal Use only exports._saveEditorViewState = _saveEditorViewState; exports._createUnattachedMasterEditor = _createUnattachedMasterEditor; - + // Define public API exports.createInlineEditorForDocument = createInlineEditorForDocument; exports.getFocusedInlineWidget = getFocusedInlineWidget; @@ -819,12 +819,12 @@ define(function (require, exports, module) { exports.getActiveEditor = getActiveEditor; exports.getCurrentFullEditor = getCurrentFullEditor; exports.getFocusedEditor = getFocusedEditor; - - + + exports.registerInlineEditProvider = registerInlineEditProvider; exports.registerInlineDocsProvider = registerInlineDocsProvider; exports.registerJumpToDefProvider = registerJumpToDefProvider; - + // Deprecated exports.registerCustomViewer = registerCustomViewer; exports.resizeEditor = resizeEditor; diff --git a/src/editor/EditorOptionHandlers.js b/src/editor/EditorOptionHandlers.js index 1af9cfa5bf3..7fb7c8e7714 100644 --- a/src/editor/EditorOptionHandlers.js +++ b/src/editor/EditorOptionHandlers.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the + * 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 */ @@ -26,7 +26,7 @@ define(function (require, exports, module) { "use strict"; - + var AppInit = require("utils/AppInit"), Editor = require("editor/Editor").Editor, Commands = require("command/Commands"), @@ -34,16 +34,16 @@ define(function (require, exports, module) { PreferencesManager = require("preferences/PreferencesManager"), Strings = require("strings"), _ = require("thirdparty/lodash"); - + // Constants for the preferences referred to in this file var SHOW_LINE_NUMBERS = "showLineNumbers", STYLE_ACTIVE_LINE = "styleActiveLine", WORD_WRAP = "wordWrap", CLOSE_BRACKETS = "closeBrackets"; - + /** * @private - * + * * Maps from preference names to the command names needed to update the checked status. */ var _optionMapping = {}; @@ -51,12 +51,12 @@ define(function (require, exports, module) { _optionMapping[STYLE_ACTIVE_LINE] = Commands.TOGGLE_ACTIVE_LINE; _optionMapping[WORD_WRAP] = Commands.TOGGLE_WORD_WRAP; _optionMapping[CLOSE_BRACKETS] = Commands.TOGGLE_CLOSE_BRACKETS; - + /** * @private - * + * * Updates the command checked status based on the preference name given. - * + * * @param {string} name Name of preference that has changed */ function _updateCheckedState(name) { @@ -66,18 +66,18 @@ define(function (require, exports, module) { } CommandManager.get(mapping).setChecked(PreferencesManager.get(name)); } - + // Listen to preference changes for the preferences we care about Object.keys(_optionMapping).forEach(function (preference) { PreferencesManager.on("change", preference, function () { _updateCheckedState(preference); }); }); - + /** * @private * Creates a function that will toggle the named preference. - * + * * @param {string} prefName Name of preference that should be toggled by the function */ function _getToggler(prefName) { @@ -85,17 +85,17 @@ define(function (require, exports, module) { PreferencesManager.set(prefName, !PreferencesManager.get(prefName)); }; } - + function _init() { _.each(_optionMapping, function (commandName, prefName) { CommandManager.get(commandName).setChecked(PreferencesManager.get(prefName)); }); - + if (!Editor.getShowLineNumbers()) { Editor._toggleLinePadding(true); } } - + CommandManager.register(Strings.CMD_TOGGLE_LINE_NUMBERS, Commands.TOGGLE_LINE_NUMBERS, _getToggler(SHOW_LINE_NUMBERS)); CommandManager.register(Strings.CMD_TOGGLE_ACTIVE_LINE, Commands.TOGGLE_ACTIVE_LINE, _getToggler(STYLE_ACTIVE_LINE)); CommandManager.register(Strings.CMD_TOGGLE_WORD_WRAP, Commands.TOGGLE_WORD_WRAP, _getToggler(WORD_WRAP)); diff --git a/src/editor/EditorStatusBar.js b/src/editor/EditorStatusBar.js index 1998c5466e5..da839e34136 100644 --- a/src/editor/EditorStatusBar.js +++ b/src/editor/EditorStatusBar.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the + * 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. - * + * */ @@ -30,7 +30,7 @@ */ define(function (require, exports, module) { "use strict"; - + // Load dependent modules var _ = require("thirdparty/lodash"), AnimationUtils = require("utils/AnimationUtils"), @@ -45,7 +45,7 @@ define(function (require, exports, module) { StatusBar = require("widgets/StatusBar"), Strings = require("strings"), StringUtils = require("utils/StringUtils"); - + /* StatusBar indicators */ var languageSelect, // this is a DropdownButton instance $cursorInfo, @@ -54,11 +54,11 @@ define(function (require, exports, module) { $indentWidthLabel, $indentWidthInput, $statusOverwrite; - + /** Special list item for the 'set as default' gesture in language switcher dropdown */ var LANGUAGE_SET_AS_DEFAULT = {}; - - + + /** * Determine string based on count * @param {number} number Count @@ -69,7 +69,7 @@ define(function (require, exports, module) { function _formatCountable(number, singularStr, pluralStr) { return StringUtils.format(number > 1 ? pluralStr : singularStr, number); } - + /** * Update file mode * @param {Editor} editor Current editor @@ -77,7 +77,7 @@ define(function (require, exports, module) { function _updateLanguageInfo(editor) { var doc = editor.document, lang = doc.getLanguage(); - + // Ensure width isn't left locked by a previous click of the dropdown (which may not have resulted in a "change" event at the time) languageSelect.$button.css("width", "auto"); // Setting Untitled documents to non-text mode isn't supported yet, so disable the switcher in that case for now @@ -85,7 +85,7 @@ define(function (require, exports, module) { // Show the current language as button title languageSelect.$button.text(lang.getName()); } - + /** * Update file information * @param {Editor} editor Current editor @@ -94,7 +94,7 @@ define(function (require, exports, module) { var lines = editor.lineCount(); $fileInfo.text(_formatCountable(lines, Strings.STATUSBAR_LINE_COUNT_SINGULAR, Strings.STATUSBAR_LINE_COUNT_PLURAL)); } - + /** * Update indent type and size * @param {string} fullPath Path to file in current editor @@ -114,7 +114,7 @@ define(function (require, exports, module) { function _getIndentSize(fullPath) { return Editor.getUseTabChar(fullPath) ? Editor.getTabSize(fullPath) : Editor.getSpaceUnits(fullPath); } - + /** * Update indent size * @param {string} fullPath Path to file in current editor @@ -124,7 +124,7 @@ define(function (require, exports, module) { $indentWidthLabel.text(size); $indentWidthInput.val(size); } - + /** * Toggle indent type */ @@ -136,7 +136,7 @@ define(function (require, exports, module) { _updateIndentType(fullPath); _updateIndentSize(fullPath); } - + /** * Update cursor(s)/selection(s) information * @param {Event} event (unused) @@ -147,9 +147,9 @@ define(function (require, exports, module) { // compute columns, account for tab size var cursor = editor.getCursorPos(true); - + var cursorStr = StringUtils.format(Strings.STATUSBAR_CURSOR_POSITION, cursor.line + 1, cursor.ch + 1); - + var sels = editor.getSelections(), selStr = ""; @@ -170,22 +170,22 @@ define(function (require, exports, module) { } $cursorInfo.text(cursorStr + selStr); } - + /** * Change indent size * @param {string} fullPath Path to file in current editor - * @param {string} value Size entered into status bar + * @param {string} value Size entered into status bar */ function _changeIndentWidth(fullPath, value) { $indentWidthLabel.removeClass("hidden"); $indentWidthInput.addClass("hidden"); - + // remove all event handlers from the input field $indentWidthInput.off("blur keyup"); - + // restore focus to the editor MainViewManager.focusActivePane(); - + var valInt = parseInt(value, 10); if (Editor.getUseTabChar(fullPath)) { if (!Editor.setTabSize(valInt, fullPath)) { @@ -203,7 +203,7 @@ define(function (require, exports, module) { // column position may change when tab size changes _updateCursorInfo(); } - + /** * Update insert/overwrite label * @param {Event} event (unused) @@ -236,7 +236,7 @@ define(function (require, exports, module) { _updateOverwriteLabel(event, editor, newstate, true); editor.toggleOverwrite(newstate); } - + /** * Initialize insert/overwrite indicator * @param {Editor} currentEditor Current editor @@ -245,12 +245,12 @@ define(function (require, exports, module) { currentEditor.toggleOverwrite($statusOverwrite.text() === Strings.STATUSBAR_OVERWRITE); $statusOverwrite.attr("title", Strings.STATUSBAR_INSOVR_TOOLTIP); } - + /** * Handle active editor change event * @param {Event} event (unused) * @param {Editor} current Current editor - * @param {Editor} previous Previous editor + * @param {Editor} previous Previous editor */ function _onActiveEditorChange(event, current, previous) { if (previous) { @@ -258,13 +258,13 @@ define(function (require, exports, module) { previous.document.off(".statusbar"); previous.document.releaseRef(); } - + if (!current) { StatusBar.hideAllPanes(); } else { var fullPath = current.document.file.fullPath; StatusBar.showAllPanes(); - + current.on("cursorActivity.statusbar", _updateCursorInfo); current.on("optionChange.statusbar", function () { _updateIndentType(fullPath); @@ -275,12 +275,12 @@ define(function (require, exports, module) { window.setTimeout(function () { _updateFileInfo(current); }, 0); }); current.on("overwriteToggle.statusbar", _updateOverwriteLabel); - + current.document.addRef(); current.document.on("languageChanged.statusbar", function () { _updateLanguageInfo(current); }); - + _updateCursorInfo(null, current); _updateLanguageInfo(current); _updateFileInfo(current); @@ -289,7 +289,7 @@ define(function (require, exports, module) { _updateIndentSize(fullPath); } } - + /** * Populate the languageSelect DropdownButton's menu with all registered Languages */ @@ -298,42 +298,42 @@ define(function (require, exports, module) { var languages = _.values(LanguageManager.getLanguages()).filter(function (language) { return !language.isBinary(); }); - + // sort dropdown alphabetically languages.sort(function (a, b) { return a.getName().toLowerCase().localeCompare(b.getName().toLowerCase()); }); - + languageSelect.items = languages; - + // Add option to top of menu for persisting the override languageSelect.items.unshift("---"); languageSelect.items.unshift(LANGUAGE_SET_AS_DEFAULT); } - + /** * Initialize */ function _init() { - + $cursorInfo = $("#status-cursor"); $fileInfo = $("#status-file"); $indentType = $("#indent-type"); $indentWidthLabel = $("#indent-width-label"); $indentWidthInput = $("#indent-width-input"); $statusOverwrite = $("#status-overwrite"); - + languageSelect = new DropdownButton("", [], function (item, index) { var document = EditorManager.getActiveEditor().document, defaultLang = LanguageManager.getLanguageForPath(document.file.fullPath, true); - + if (item === LANGUAGE_SET_AS_DEFAULT) { var label = _.escape(StringUtils.format(Strings.STATUSBAR_SET_DEFAULT_LANG, LanguageManager.getCompoundFileExtension(document.file.fullPath))); return { html: label, enabled: document.getLanguage() !== defaultLang }; } - + var html = _.escape(item.getName()); - + // Show indicators for currently selected & default languages for the current file if (item === defaultLang) { html += " " + Strings.STATUSBAR_DEFAULT_LANG + ""; @@ -343,12 +343,12 @@ define(function (require, exports, module) { } return html; }); - + languageSelect.dropdownExtraClasses = "dropdown-status-bar"; languageSelect.$button.addClass("btn-status-bar"); $("#status-language").append(languageSelect.$button); languageSelect.$button.attr("title", Strings.STATUSBAR_LANG_TOOLTIP); - + // indentation event handlers $indentType.on("click", _toggleIndentType); $indentWidthLabel @@ -360,7 +360,7 @@ define(function (require, exports, module) { $indentWidthLabel.addClass("hidden"); $indentWidthInput.removeClass("hidden"); $indentWidthInput.focus(); - + $indentWidthInput .on("blur", function () { _changeIndentWidth(fullPath, $indentWidthInput.val()); @@ -380,13 +380,13 @@ define(function (require, exports, module) { languageSelect.on("select", function (e, lang) { var document = EditorManager.getActiveEditor().document, fullPath = document.file.fullPath; - + if (lang === LANGUAGE_SET_AS_DEFAULT) { // Set file's current language in preferences as a file extension override (only enabled if not default already) var fileExtensionMap = PreferencesManager.get("language.fileExtensions"); fileExtensionMap[LanguageManager.getCompoundFileExtension(fullPath)] = document.getLanguage().getId(); PreferencesManager.set("language.fileExtensions", fileExtensionMap); - + } else { // Set selected language as a path override for just this one file (not persisted) var defaultLang = LanguageManager.getLanguageForPath(fullPath, true); @@ -400,7 +400,7 @@ define(function (require, exports, module) { // Initialize: status bar focused listener EditorManager.on("activeEditorChange", _onActiveEditorChange); - + AppInit.htmlReady(_init); AppInit.appReady(function () { // Populate language switcher with all languages after startup; update it later if this set changes diff --git a/src/editor/ImageViewer.js b/src/editor/ImageViewer.js index 6ddcd3c632e..0b830ec3fb5 100644 --- a/src/editor/ImageViewer.js +++ b/src/editor/ImageViewer.js @@ -1,24 +1,24 @@ /* * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the + * 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 */ @@ -26,7 +26,7 @@ define(function (require, exports, module) { "use strict"; - + var DocumentManager = require("document/DocumentManager"), ImageViewTemplate = require("text!htmlContent/image-view.html"), ProjectManager = require("project/ProjectManager"), @@ -37,14 +37,14 @@ define(function (require, exports, module) { FileSystem = require("filesystem/FileSystem"), FileUtils = require("file/FileUtils"), _ = require("thirdparty/lodash"); - - + + var _viewers = {}; - + /** - * ImageView objects are constructed when an image is opened + * ImageView objects are constructed when an image is opened * @see {@link Pane} for more information about where ImageViews are rendered - * + * * @constructor * @param {!File} file - The image file object to render * @param {!jQuery} container - The container to render the image view in @@ -53,14 +53,14 @@ define(function (require, exports, module) { this.file = file; this.$el = $(Mustache.render(ImageViewTemplate, {fullPath: FileUtils.encodeFilePath(file.fullPath), now: new Date().valueOf()})); - + $container.append(this.$el); this._naturalWidth = 0; this._naturalHeight = 0; this._scale = 100; // 100% this._scaleDivInfo = null; // coordinates of hidden scale sticker - + this.relPath = ProjectManager.makeProjectRelativeIfPossible(this.file.fullPath); this.$imagePath = this.$el.find(".image-path"); @@ -75,24 +75,24 @@ define(function (require, exports, module) { this.$y_value = this.$el.find(".y-value"); this.$horzGuide = this.$el.find(".horz-guide"); this.$vertGuide = this.$el.find(".vert-guide"); - + this.$imagePath.text(this.relPath).attr("title", this.relPath); this.$imagePreview.on("load", _.bind(this._onImageLoaded, this)); - + _viewers[file.fullPath] = this; } /** - * DocumentManger.fileNameChange handler - when an image is renamed, we must + * DocumentManger.fileNameChange handler - when an image is renamed, we must * update the view - * + * * @param {jQuery.Event} e - event - * @param {!string} oldPath - the name of the file that's changing changing - * @param {!string} newPath - the name of the file that's changing changing + * @param {!string} oldPath - the name of the file that's changing changing + * @param {!string} newPath - the name of the file that's changing changing * @private */ ImageView.prototype._onFilenameChange = function (e, oldPath, newPath) { - /* + /* * File objects are already updated when the event is triggered * so we just need to see if the file has the same path as our image */ @@ -103,8 +103,8 @@ define(function (require, exports, module) { }; /** - * .on("load") handler - updates content of the image view - * initializes computed values + * .on("load") handler - updates content of the image view + * initializes computed values * installs event handlers * @param {Event} e - event * @private @@ -113,17 +113,17 @@ define(function (require, exports, module) { // add dimensions and size this._naturalWidth = e.currentTarget.naturalWidth; this._naturalHeight = e.currentTarget.naturalHeight; - + var extension = FileUtils.getFileExtension(this.file.fullPath); var dimensionString = this._naturalWidth + " × " + this._naturalHeight + " " + Strings.UNIT_PIXELS; - + if (extension === "ico") { dimensionString += " (" + Strings.IMAGE_VIEWER_LARGEST_ICON + ")"; } - + // get image size var self = this; - + this.file.stat(function (err, stat) { if (err) { self.$imageData.html(dimensionString); @@ -139,26 +139,26 @@ define(function (require, exports, module) { .replace("—", "-")); } }); - + // make sure we always show the right file name DocumentManager.on("fileNameChange.ImageView", _.bind(this._onFilenameChange, this)); - + this.$imageTip.hide(); this.$imageGuides.hide(); - + this.$image.on("mousemove.ImageView", ".image-preview", _.bind(this._showImageTip, this)) .on("mouseleave.ImageView", ".image-preview", _.bind(this._hideImageTip, this)); this._updateScale(); }; - + /** * Update the scale element * @private */ ImageView.prototype._updateScale = function () { var currentWidth = this.$imagePreview.width(); - + if (currentWidth && currentWidth < this._naturalWidth) { this._scale = currentWidth / this._naturalWidth * 100; this.$imageScale.text(Math.floor(this._scale) + "%") @@ -172,8 +172,8 @@ define(function (require, exports, module) { this.$imageScale.text("").hide(); } }; - - + + /** * Show image coordinates under the mouse cursor * @param {Event} e - event @@ -185,7 +185,7 @@ define(function (require, exports, module) { if (Math.floor(this._scale) === 0) { return; } - + var x = Math.round(e.offsetX * 100 / this._scale), y = Math.round(e.offsetY * 100 / this._scale), imagePos = this.$imagePreview.position(), @@ -195,37 +195,37 @@ define(function (require, exports, module) { height = this.$imagePreview.height(), windowWidth = $(window).width(), fourDigitImageWidth = this._naturalWidth.toString().length === 4, - + // @todo -- seems a bit strange that we're computing sizes // using magic numbers - + infoWidth1 = 112, // info div width 96px + vertical toolbar width 16px infoWidth2 = 120, // info div width 104px (for 4-digit image width) + vertical toolbar width 16px tipOffsetX = 10, // adjustment for info div left from x coordinate of cursor tipOffsetY = -54, // adjustment for info div top from y coordinate of cursor tipMinusOffsetX1 = -82, // for less than 4-digit image width - tipMinusOffsetX2 = -90; // for 4-digit image width - - // Check whether we're getting mousemove events beyond the image boundaries due to a browser bug + tipMinusOffsetX2 = -90; // for 4-digit image width + + // Check whether we're getting mousemove events beyond the image boundaries due to a browser bug // or the rounding calculation above for a scaled image. For example, if an image is 120 px wide, - // we should get mousemove events in the range of 0 <= x < 120, but not 120 or more. If we get + // we should get mousemove events in the range of 0 <= x < 120, but not 120 or more. If we get // a value beyond the range, then simply handle the event as if it were a mouseleave. if (x < 0 || x >= this._naturalWidth || y < 0 || y >= this._naturalHeight) { this._hideImageTip(e); this.$imagePreview.css("cursor", "auto"); return; } - + this.$imagePreview.css("cursor", "none"); - + this._handleMouseEnterOrExitScaleSticker(left, top); - + // Check whether to show the image tip on the left. if ((e.pageX + infoWidth1) > windowWidth || (fourDigitImageWidth && (e.pageX + infoWidth2) > windowWidth)) { tipOffsetX = fourDigitImageWidth ? tipMinusOffsetX2 : tipMinusOffsetX1; } - + this.$x_value.text(x + "px"); this.$y_value.text(y + "px"); @@ -233,23 +233,23 @@ define(function (require, exports, module) { left: left + tipOffsetX, top: top + tipOffsetY }).show(); - + this.$horzGuide.css({ left: imagePos.left, top: top, width: width - 1 }).show(); - + this.$vertGuide.css({ left: left, top: imagePos.top, height: height - 1 }).show(); }; - + /** * Hide image coordinates info tip - * @param {Event} e - event + * @param {Event} e - event * @private */ ImageView.prototype._hideImageTip = function (e) { @@ -260,7 +260,7 @@ define(function (require, exports, module) { bottom = imagePos.top + this.$imagePreview.height(), x = targetPos.left + e.offsetX, y = targetPos.top + e.offsetY; - + // Hide image tip and guides only if the cursor is outside of the image. if (x < imagePos.left || x >= right || y < imagePos.top || y >= bottom) { @@ -271,7 +271,7 @@ define(function (require, exports, module) { } } }; - + /** * Hides both guides and the tip * @private @@ -280,9 +280,9 @@ define(function (require, exports, module) { this.$imageTip.hide(); this.$imageGuides.hide(); }; - + /** - * Check mouse entering/exiting the scale sticker. + * Check mouse entering/exiting the scale sticker. * Hide it when entering and show it again when exiting. * * @param {number} offsetX mouse offset from the left of the previewing image @@ -298,28 +298,28 @@ define(function (require, exports, module) { scaleDivTop, scaleDivRight, scaleDivBottom; - + if (this._scaleDivInfo) { scaleDivLeft = this._scaleDivInfo.left; scaleDivTop = this._scaleDivInfo.top; scaleDivRight = this._scaleDivInfo.right; scaleDivBottom = this._scaleDivInfo.bottom; - + if ((imgWidth + imagePos.left) < scaleDivRight) { scaleDivRight = imgWidth + imagePos.left; } - + if ((imgHeight + imagePos.top) < scaleDivBottom) { scaleDivBottom = imgHeight + imagePos.top; } - + } else { scaleDivLeft = scaleDivPos.left; scaleDivTop = scaleDivPos.top; scaleDivRight = this.$imageScale.width() + scaleDivLeft; scaleDivBottom = this.$imageScale.height() + scaleDivTop; } - + if (this._scaleDivInfo) { // See whether the cursor is no longer inside the hidden scale div. // If so, show it again. @@ -348,29 +348,29 @@ define(function (require, exports, module) { * View Interface functions */ - /* + /* * Retrieves the file object for this view * return {!File} the file object for this view */ ImageView.prototype.getFile = function () { return this.file; }; - - /* + + /* * Updates the layout of the view */ ImageView.prototype.updateLayout = function () { this._hideGuidesAndTip(); - + var $container = this.$el.parent(); - + var pos = $container.position(), iWidth = $container.innerWidth(), iHeight = $container.innerHeight(), oWidth = $container.outerWidth(), oHeight = $container.outerHeight(); - - // $view is "position:absolute" so + + // $view is "position:absolute" so // we have to update the height, width and position this.$el.css({top: pos.top + ((oHeight - iHeight) / 2), left: pos.left + ((oWidth - iWidth) / 2), @@ -379,7 +379,7 @@ define(function (require, exports, module) { this._updateScale(); }; - /* + /* * Destroys the view */ ImageView.prototype.destroy = function () { @@ -388,8 +388,8 @@ define(function (require, exports, module) { this.$image.off(".ImageView"); this.$el.remove(); }; - - /* + + /* * Refreshes the image preview with what's on disk */ ImageView.prototype.refresh = function () { @@ -397,29 +397,29 @@ define(function (require, exports, module) { now = new Date().valueOf(), index = noCacheUrl.indexOf("?"); - // strip the old param off + // strip the old param off if (index > 0) { noCacheUrl = noCacheUrl.slice(0, index); } - - // add a new param which will force chrome to - // re-read the image from disk + + // add a new param which will force chrome to + // re-read the image from disk noCacheUrl = noCacheUrl + "?ver=" + now; - - // Update the DOM node with the src URL + + // Update the DOM node with the src URL this.$imagePreview.attr("src", noCacheUrl); }; - - /* + + /* * Creates an image view object and adds it to the specified pane * @param {!File} file - the file to create an image of * @param {!Pane} pane - the pane in which to host the view - * @return {jQuery.Promise} + * @return {jQuery.Promise} */ function _createImageView(file, pane) { var view = pane.getViewForPath(file.fullPath); - + if (view) { pane.showView(view); } else { @@ -428,9 +428,9 @@ define(function (require, exports, module) { } return new $.Deferred().resolve().promise(); } - + /** - * Handles file system change events so we can refresh + * Handles file system change events so we can refresh * image viewers for the files that changed on disk due to external editors * @param {jQuery.event} event - event object * @param {?File} file - file object that changed @@ -438,12 +438,12 @@ define(function (require, exports, module) { * @param {Array.=} removed If entry is a Directory, contains zero or more removed children */ function _handleFileSystemChange(event, entry, added, removed) { - // this may have been called because files were added + // this may have been called because files were added // or removed to the file system. We don't care about those if (!entry || entry.isDirectory) { return; } - + // Look for a viewer for the changed file var viewer = _viewers[entry.fullPath]; @@ -452,14 +452,14 @@ define(function (require, exports, module) { viewer.refresh(); } } - + /* * Install an event listener to receive all file system change events * so we can refresh the view when changes are made to the image in an external editor */ FileSystem.on("change", _handleFileSystemChange); - /* + /* * Initialization, register our view factory */ MainViewFactory.registerViewFactory({ @@ -471,9 +471,9 @@ define(function (require, exports, module) { return _createImageView(file, pane); } }); - - /* - * This is for extensions that want to create a + + /* + * This is for extensions that want to create a * view factory based on ImageViewer */ exports.ImageView = ImageView; diff --git a/src/editor/InlineTextEditor.js b/src/editor/InlineTextEditor.js index 4a3395875b7..4ecb9062c51 100644 --- a/src/editor/InlineTextEditor.js +++ b/src/editor/InlineTextEditor.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -28,7 +28,7 @@ define(function (require, exports, module) { "use strict"; - + // Load dependent modules var CodeMirror = require("thirdparty/CodeMirror/lib/codemirror"), EventDispatcher = require("utils/EventDispatcher"), @@ -48,7 +48,7 @@ define(function (require, exports, module) { // the width of the div. $indicatorDiv.css("width", isDirty ? 16 : 0); } - + /** * Respond to dirty flag change event. If the dirty flag is associated with an inline editor, * show (or hide) the dirty indicator. @@ -57,7 +57,7 @@ define(function (require, exports, module) { function _dirtyFlagChangeHandler(event, doc) { var $dirtyIndicators = $(".inline-text-editor .dirty-indicator"), $indicator; - + $dirtyIndicators.each(function (index, indicator) { $indicator = $(this); if ($indicator.data("fullPath") === doc.file.fullPath) { @@ -65,7 +65,7 @@ define(function (require, exports, module) { } }); } - + /** * @constructor * @extends {InlineWidget} @@ -74,7 +74,7 @@ define(function (require, exports, module) { InlineWidget.call(this); this.editor = null; - + // We need to set this as a capture handler so CodeMirror doesn't handle Esc before we see it. this.handleKeyDown = this.handleKeyDown.bind(this); this.htmlContent.addEventListener("keydown", this.handleKeyDown, true); @@ -82,7 +82,7 @@ define(function (require, exports, module) { InlineTextEditor.prototype = Object.create(InlineWidget.prototype); InlineTextEditor.prototype.constructor = InlineTextEditor; InlineTextEditor.prototype.parentClass = InlineWidget.prototype; - + InlineTextEditor.prototype.$wrapper = null; /** @type {Editor} */ InlineTextEditor.prototype.editor = null; @@ -97,10 +97,10 @@ define(function (require, exports, module) { */ function _syncGutterWidths(hostEditor) { var allHostedEditors = EditorManager.getInlineEditors(hostEditor); - + // add the host itself to the list too allHostedEditors.push(hostEditor); - + var maxWidth = 0; allHostedEditors.forEach(function (editor) { var $gutter = $(editor._codeMirror.getGutterElement()).find(".CodeMirror-linenumbers"); @@ -110,17 +110,17 @@ define(function (require, exports, module) { maxWidth = curWidth; } }); - + if (allHostedEditors.length === 1) { //There's only the host, just refresh the gutter allHostedEditors[0]._codeMirror.setOption("gutters", allHostedEditors[0]._codeMirror.getOption("gutters")); return; } - + maxWidth = maxWidth + "px"; allHostedEditors.forEach(function (editor) { $(editor._codeMirror.getGutterElement()).find(".CodeMirror-linenumbers").css("min-width", maxWidth); - + // Force CodeMirror to refresh the gutter editor._codeMirror.setOption("gutters", editor._codeMirror.getOption("gutters")); }); @@ -131,14 +131,14 @@ define(function (require, exports, module) { */ InlineTextEditor.prototype.onClosed = function () { InlineTextEditor.prototype.parentClass.onClosed.apply(this, arguments); - + _syncGutterWidths(this.hostEditor); - + // Destroy the inline editor. this.setInlineContent(null); this.htmlContent.removeEventListener("keydown", this.handleKeyDown, true); }; - + /** * Update the inline editor's height when the number of lines change. The * base implementation of this method does nothing. @@ -158,7 +158,7 @@ define(function (require, exports, module) { var self = this; InlineTextEditor.prototype.parentClass.onAdded.apply(this, arguments); - + if (this.editor) { this.editor.refresh(); } @@ -174,14 +174,14 @@ define(function (require, exports, module) { } }, 0); }); - + _syncGutterWidths(this.hostEditor); - + if (this.editor) { this.editor.focus(); } }; - + /** * @return {?Editor} If an Editor within this inline editor has focus, returns it. Otherwise returns null. */ @@ -213,7 +213,7 @@ define(function (require, exports, module) { */ InlineTextEditor.prototype.setInlineContent = function (doc, startLine, endLine) { var self = this; - + // Destroy the previous editor if we had one and clear out the filename info. if (this.editor) { this.editor.off(".InlineTextEditor"); @@ -223,23 +223,23 @@ define(function (require, exports, module) { .removeAttr("title"); this.$filename.html(""); } - + if (!doc) { return; } - + var range = { startLine: startLine, endLine: endLine }; - + // dirty indicator, with file path stored on it var $dirtyIndicatorDiv = $("
    ") .addClass("dirty-indicator") .html("•") .width(0); // initialize indicator as hidden $dirtyIndicatorDiv.data("fullPath", doc.file.fullPath); - + this.$lineNumber = $(""); // update contents of filename link @@ -247,7 +247,7 @@ define(function (require, exports, module) { .append(doc.file.name + " : ") .append(this.$lineNumber) .attr("title", doc.file.fullPath); - + // clicking filename jumps to full editor view this.$filename.on("click.InlineTextEditor", function () { CommandManager.execute(Commands.FILE_OPEN, { fullPath: doc.file.fullPath }) @@ -258,7 +258,7 @@ define(function (require, exports, module) { var inlineInfo = EditorManager.createInlineEditorForDocument(doc, range, this.$editorHolder.get(0)); this.editor = inlineInfo.editor; - + // Init line number display this._updateLineRange(inlineInfo.editor); @@ -277,12 +277,12 @@ define(function (require, exports, module) { self._updateLineRange(editor); } }); - + // If Document's file is deleted, or Editor loses sync with Document, delegate to this._onLostContent() this.editor.on("lostContent.InlineTextEditor", function () { self._onLostContent.apply(self, arguments); }); - + // set dirty indicator state _showDirtyIndicator($dirtyIndicatorDiv, doc.isDirty); }; @@ -328,7 +328,7 @@ define(function (require, exports, module) { // We need to call this explicitly whenever the host editor is reshown this.sizeInlineWidgetToContents(); }; - + /** * If Document's file is deleted, or Editor loses sync with Document, just close */ @@ -337,8 +337,8 @@ define(function (require, exports, module) { // better than leaving it open but suddenly removing one rule from the result list. this.close(); }; - - + + // Consolidate all dirty document updates // Due to circular dependencies, not safe to call on() directly EventDispatcher.on_duringInit(DocumentManager, "dirtyFlagChange", _dirtyFlagChangeHandler); diff --git a/src/editor/InlineWidget.js b/src/editor/InlineWidget.js index 2280f53b7ce..3dcd176431c 100644 --- a/src/editor/InlineWidget.js +++ b/src/editor/InlineWidget.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ @@ -32,14 +32,14 @@ define(function (require, exports, module) { var EditorManager = require("editor/EditorManager"), EventDispatcher = require("utils/EventDispatcher"), KeyEvent = require("utils/KeyEvent"); - + /** * @constructor * */ function InlineWidget() { var self = this; - + // create the outer wrapper div this.htmlContent = window.document.createElement("div"); this.$htmlContent = $(this.htmlContent).addClass("inline-widget").attr("tabindex", "-1"); @@ -72,7 +72,7 @@ define(function (require, exports, module) { * @type {number} */ InlineWidget.prototype.height = 0; - + /** * Closes this inline widget and all its contained Editors * @return {$.Promise} A promise that's resolved when the widget is fully closed. @@ -81,7 +81,7 @@ define(function (require, exports, module) { return EditorManager.closeInlineWidget(this.hostEditor, this); // closeInlineWidget() causes our onClosed() handler to be called }; - + /** * @return {boolean} True if any part of the inline widget is focused */ @@ -90,7 +90,7 @@ define(function (require, exports, module) { htmlContent = this.$htmlContent[0]; return $.contains(htmlContent, focusedItem) || htmlContent === focusedItem; }; - + /** * Called any time inline is closed, whether manually or automatically. */ @@ -101,7 +101,7 @@ define(function (require, exports, module) { /** * Called once content is parented in the host editor's DOM. Useful for performing tasks like setting * focus or measuring content, which require htmlContent to be in the DOM tree. - * + * * IMPORTANT: onAdded() MUST be overridden to call hostEditor.setInlineWidgetHeight() at least once to * set the initial height (required to animate it open). The widget will never open otherwise. */ @@ -115,21 +115,21 @@ define(function (require, exports, module) { InlineWidget.prototype.load = function (hostEditor) { this.hostEditor = hostEditor; }; - + /** * Called when the editor containing the inline is made visible. */ InlineWidget.prototype.onParentShown = function () { // do nothing - base implementation }; - + /** * Called when the parent editor does a full refresh--for example, when the font size changes. */ InlineWidget.prototype.refresh = function () { // do nothing - base implementation }; - + exports.InlineWidget = InlineWidget; }); diff --git a/src/editor/MultiRangeInlineEditor.js b/src/editor/MultiRangeInlineEditor.js index 39bddea2804..a70dc3bd2c5 100644 --- a/src/editor/MultiRangeInlineEditor.js +++ b/src/editor/MultiRangeInlineEditor.js @@ -1,24 +1,24 @@ /* * 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. - * + * */ // FUTURE: Merge part (or all) of this class with InlineTextEditor @@ -27,19 +27,19 @@ /*global define, $, window */ /** - * An inline editor for displaying and editing multiple text ranges. Each range corresponds to a - * contiguous set of lines in a file. - * + * An inline editor for displaying and editing multiple text ranges. Each range corresponds to a + * contiguous set of lines in a file. + * * In the current implementation, only one range is visible at a time. A list on the right side - * of the editor allows the user to select which range is visible. + * of the editor allows the user to select which range is visible. * * This module does not dispatch any events. */ define(function (require, exports, module) { "use strict"; - + var _ = require("thirdparty/lodash"); - + // Load dependent modules var TextRange = require("document/TextRange").TextRange, InlineTextEditor = require("editor/InlineTextEditor").InlineTextEditor, @@ -50,7 +50,7 @@ define(function (require, exports, module) { Commands = require("command/Commands"), Strings = require("strings"), CommandManager = require("command/CommandManager"); - + var _prevMatchCmd, _nextMatchCmd; /** @@ -62,14 +62,14 @@ define(function (require, exports, module) { function _parseStyleSize($target, styleName) { return parseInt($target.css(styleName), 10); } - + /** Returns a 'context' object for getting/setting project-specific preferences */ function _getPrefsContext() { var projectRoot = ProjectManager.getProjectRoot(); // note: null during unit tests! return { location : { scope: "user", layer: "project", layerID: projectRoot && projectRoot.fullPath } }; } - - + + /** * Stores one search result: its source file, line range, etc. plus the DOM node representing it * in the results list. @@ -83,7 +83,7 @@ define(function (require, exports, module) { SearchResultItem.prototype.name = null; SearchResultItem.prototype.textRange = null; SearchResultItem.prototype.$listItem = null; - + function _updateRangeLabel(listItem, range, labelCB) { if (labelCB) { range.name = labelCB(range.textRange); @@ -92,8 +92,8 @@ define(function (require, exports, module) { listItem.html(text); listItem.attr("title", listItem.text()); } - - + + /** * @constructor * @param {Array.<{name:String,document:Document,lineStart:number,lineEnd:number}>} ranges The text @@ -109,7 +109,7 @@ define(function (require, exports, module) { */ function MultiRangeInlineEditor(ranges, messageCB, labelCB, fileComparator) { InlineTextEditor.call(this); - + // Store the results to show in the range list. This creates TextRanges bound to the Document, // which will stay up to date automatically (but we must be sure to detach them later) this._ranges = ranges.map(function (rangeResult) { @@ -117,10 +117,10 @@ define(function (require, exports, module) { }); this._messageCB = messageCB; this._labelCB = labelCB; - + this._selectedRangeIndex = -1; this._collapsedFiles = {}; - + // Set up list sort order this._fileComparator = fileComparator || function defaultComparator(file1, file2) { return FileUtils.comparePaths(file1.fullPath, file2.fullPath); @@ -132,40 +132,40 @@ define(function (require, exports, module) { MultiRangeInlineEditor.prototype = Object.create(InlineTextEditor.prototype); MultiRangeInlineEditor.prototype.constructor = MultiRangeInlineEditor; MultiRangeInlineEditor.prototype.parentClass = InlineTextEditor.prototype; - + MultiRangeInlineEditor.prototype.$messageDiv = null; MultiRangeInlineEditor.prototype.$relatedContainer = null; MultiRangeInlineEditor.prototype.$related = null; MultiRangeInlineEditor.prototype.$selectedMarker = null; - + /** Includes all the _ranges[i].$listItem items, as well as section headers */ MultiRangeInlineEditor.prototype.$rangeList = null; - + /** * List of search results. Section headers are not represented in this list (they are implied before each group of * of consecutive results from the same Document). * @type {!Array.} */ MultiRangeInlineEditor.prototype._ranges = null; - + /** Index into this._ranges - indices do not include section headers */ MultiRangeInlineEditor.prototype._selectedRangeIndex = null; - + /** * Map from fullPath to true if collapsed. May not agree with preferences, in cases where multiple inline editors make * concurrent changes. * @type {!Object.} */ MultiRangeInlineEditor.prototype._collapsedFiles = null; - + MultiRangeInlineEditor.prototype._messageCB = null; MultiRangeInlineEditor.prototype._labelCB = null; MultiRangeInlineEditor.prototype._fileComparator = null; - + /** @type {!Object.} Map from fullPath to section header DOM node */ MultiRangeInlineEditor.prototype._$headers = null; - - + + /** * @private * Add a new result item
  • to the range list UI ($rangeList) and saves it in range.$listItem @@ -174,12 +174,12 @@ define(function (require, exports, module) { MultiRangeInlineEditor.prototype._createListItem = function (range) { var self = this, $rangeItem = $("
  • "); - + // Attach filename for unit test use $rangeItem.data("filename", range.textRange.document.file.name); - + $rangeItem.appendTo(this.$rangeList); - + _updateRangeLabel($rangeItem, range); $rangeItem.mousedown(function () { self.setSelectedIndex(self._ranges.indexOf(range)); @@ -187,7 +187,7 @@ define(function (require, exports, module) { range.$listItem = $rangeItem; }; - + /** Collapses/expands a file section in the range list UI */ MultiRangeInlineEditor.prototype._toggleSection = function (fullPath, duringInit) { var $headerItem = this._$headers[fullPath]; @@ -211,10 +211,10 @@ define(function (require, exports, module) { // Show/hide selection indicator if selection was in collapsed section this._updateSelectedMarker(false); - + // Changing height of rule list may change ht of overall editor this._ruleListHeightChanged(); - + // If user expands collapsed section and nothing selected yet, select first result in this section if (this._selectedRangeIndex === -1 && !isCollapsing && !duringInit) { var index = _.findIndex(this._ranges, function (resultItem) { @@ -223,29 +223,29 @@ define(function (require, exports, module) { this.setSelectedIndex(index); } }; - + /** Adds a file section header
  • to the range list UI ($rangeList) and adds it to the this._$headers map */ MultiRangeInlineEditor.prototype._createHeaderItem = function (doc) { var $headerItem = $("
  • " + _.escape(doc.file.name) + "
  • ") .attr("title", ProjectManager.makeProjectRelativeIfPossible(doc.file.fullPath)) .appendTo(this.$rangeList); - + $headerItem.click(function () { this._toggleSection(doc.file.fullPath); }.bind(this)); - + this._$headers[doc.file.fullPath] = $headerItem; }; - + /** Refresh the contents of $rangeList */ MultiRangeInlineEditor.prototype._renderList = function () { this.$rangeList.empty(); this._$headers = {}; - + var self = this, lastSectionDoc, numItemsInSection = 0; - + // After seeing all results for a given file, update its header with total # of results function finalizeSection() { if (lastSectionDoc) { @@ -255,40 +255,40 @@ define(function (require, exports, module) { } } } - + this._ranges.forEach(function (resultItem) { if (lastSectionDoc !== resultItem.textRange.document) { // Finalize previous section finalizeSection(); - + // Initialize new section lastSectionDoc = resultItem.textRange.document; numItemsInSection = 0; - + // Create filename header for new section this._createHeaderItem(lastSectionDoc); } numItemsInSection++; this._createListItem(resultItem); }, this); - + // Finalize last section finalizeSection(); }; - - - /** + + + /** * @override * @param {!Editor} hostEditor Outer Editor instance that inline editor will sit within. - * + * */ MultiRangeInlineEditor.prototype.load = function (hostEditor) { MultiRangeInlineEditor.prototype.parentClass.load.apply(this, arguments); - + // Create the message area this.$messageDiv = $("
    ") .addClass("inline-editor-message"); - + // Prevent touch scroll events from bubbling up to the parent editor. this.$editorHolder.on("mousewheel.MultiRangeInlineEditor", function (e) { e.stopPropagation(); @@ -296,30 +296,30 @@ define(function (require, exports, module) { // Outer container for border-left and scrolling this.$relatedContainer = $("
    ").addClass("related-container"); - + // List "selection" highlight this.$selectedMarker = $("
    ").appendTo(this.$relatedContainer).addClass("selection"); // Inner container this.$related = $("
    ").appendTo(this.$relatedContainer).addClass("related"); - + // Range list this.$rangeList = $("