PreferencesManager._smUserScopeLoading.always(function () { PerfUtils.addMeasurement(viewStateTimer); // Dispatch htmlReady event _beforeHTMLReady(); AppInit._dispatchReady(AppInit.HTML_READY); $(window.document).ready(_onReady); });
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, // but malformed. no need to check for its existance. var info = MainViewManager.findInAllWorkingSets(userPrefFullPath); var paneId; if (info.length) { paneId = info[0].paneId; } FileViewController.openFileAndAddToWorkingSet(userPrefFullPath, paneId) .done(function () { Dialogs.showModalDialog( DefaultDialogs.DIALOG_ID_ERROR, Strings.ERROR_PREFS_CORRUPT_TITLE, Strings.ERROR_PREFS_CORRUPT ).done(function () { // give the focus back to the editor with the pref file MainViewManager.focusActivePane(); }); }); } });
ProjectManager.openProject(initialProjectPath).done(function () { _initTest(); // WARNING: AppInit.appReady won't fire if ANY extension fails to // load or throws an error during init. To fix this, we need to // make a change to _initExtensions (filed as issue 1029) _initExtensions().always(AppInit._dispatchReady(AppInit.APP_READY)); });
extensionLoaderPromise.always(function () { // Signal that extensions are loaded AppInit._dispatchReady(AppInit.EXTENSIONS_LOADED); // Finish UI initialization ViewCommandHandlers.restoreFontSize(); // XXXBramble: the project loading logic happens based on a message // from the hosting app. See extensions/default/bramble/main.js });
deferred.always(function () { // Signal that Brackets is loaded AppInit._dispatchReady(AppInit.APP_READY); PerfUtils.addMeasurement("Application Startup"); if (PreferencesManager._isUserScopeCorrupt()) { Dialogs.showModalDialog( DefaultDialogs.DIALOG_ID_ERROR, Strings.ERROR_PREFS_CORRUPT_TITLE, Strings.ERROR_PREFS_CORRUPT ) .done(function () { CommandManager.execute(Commands.FILE_OPEN_PREFERENCES); }); } });
function _documentReadyHandler() { if (brackets.app.showDeveloperTools) { $("#show-dev-tools").click(function () { brackets.app.showDeveloperTools(); }); } else { $("#show-dev-tools").remove(); } $("#reload").click(function () { window.location.reload(true); }); $("#" + suite).closest("li").toggleClass("active", true); AppInit._dispatchReady(AppInit.APP_READY); jasmine.getEnv().execute(); }
ProjectManager.openProject(initialProjectPath).always(function () { _initTest(); // WARNING: AppInit.appReady won't fire if ANY extension fails to // load or throws an error during init. To fix this, we need to // make a change to _initExtensions (filed as issue 1029) _initExtensions().always(AppInit._dispatchReady(AppInit.APP_READY)); // 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 prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_CLIENT_ID); if (!params.get("skipSampleProjectLoad") && !prefs.getValue("afterFirstLaunch")) { prefs.setValue("afterFirstLaunch", "true"); if (ProjectManager.isWelcomeProjectPath(initialProjectPath)) { var dirEntry = new NativeFileSystem.DirectoryEntry(initialProjectPath); dirEntry.getFile("index.html", {}, function (fileEntry) { CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: fileEntry.fullPath }); }); } } });
define(function (require, exports, module) { "use strict"; // Load dependent non-module scripts require("widgets/bootstrap-dropdown"); require("widgets/bootstrap-modal"); require("thirdparty/path-utils/path-utils.min"); require("thirdparty/smart-auto-complete/jquery.smart_autocomplete"); // Load dependent modules var Global = require("utils/Global"), AppInit = require("utils/AppInit"), ProjectManager = require("project/ProjectManager"), DocumentManager = require("document/DocumentManager"), EditorManager = require("editor/EditorManager"), CSSInlineEditor = require("editor/CSSInlineEditor"), JSUtils = require("language/JSUtils"), WorkingSetView = require("project/WorkingSetView"), WorkingSetSort = require("project/WorkingSetSort"), DocumentCommandHandlers = require("document/DocumentCommandHandlers"), FileViewController = require("project/FileViewController"), FileSyncManager = require("project/FileSyncManager"), KeyBindingManager = require("command/KeyBindingManager"), Commands = require("command/Commands"), CommandManager = require("command/CommandManager"), CodeHintManager = require("editor/CodeHintManager"), JSLintUtils = require("language/JSLintUtils"), PerfUtils = require("utils/PerfUtils"), FileIndexManager = require("project/FileIndexManager"), QuickOpen = require("search/QuickOpen"), Menus = require("command/Menus"), FileUtils = require("file/FileUtils"), MainViewHTML = require("text!htmlContent/main-view.html"), Strings = require("strings"), Dialogs = require("widgets/Dialogs"), ExtensionLoader = require("utils/ExtensionLoader"), SidebarView = require("project/SidebarView"), Async = require("utils/Async"), UpdateNotification = require("utils/UpdateNotification"), UrlParams = require("utils/UrlParams").UrlParams, NativeFileSystem = require("file/NativeFileSystem").NativeFileSystem, PreferencesManager = require("preferences/PreferencesManager"), Resizer = require("utils/Resizer"), LiveDevelopmentMain = require("LiveDevelopment/main"), NodeConnection = require("utils/NodeConnection"), ExtensionUtils = require("utils/ExtensionUtils"); // Load modules that self-register and just need to get included in the main project require("command/DefaultMenus"); require("document/ChangedDocumentTracker"); require("editor/EditorCommandHandlers"); require("view/ViewCommandHandlers"); require("help/HelpCommandHandlers"); require("search/FindInFiles"); require("search/FindReplace"); PerfUtils.addMeasurement("brackets module dependencies resolved"); // Local variables var params = new UrlParams(), PREFERENCES_CLIENT_ID = "com.adobe.brackets.startup"; // read URL params params.parse(); function _initTest() { // TODO: (issue #265) Make sure the "test" object is not included in final builds // All modules that need to be tested from the context of the application // must to be added to this object. The unit tests cannot just pull // in the modules since they would run in context of the unit test window, // and would not have access to the app html/css. brackets.test = { PreferencesManager : PreferencesManager, ProjectManager : ProjectManager, DocumentCommandHandlers : DocumentCommandHandlers, FileViewController : FileViewController, DocumentManager : DocumentManager, EditorManager : EditorManager, Commands : Commands, WorkingSetView : WorkingSetView, JSLintUtils : JSLintUtils, PerfUtils : PerfUtils, JSUtils : JSUtils, CommandManager : CommandManager, FileSyncManager : FileSyncManager, FileIndexManager : FileIndexManager, Menus : Menus, KeyBindingManager : KeyBindingManager, CodeHintManager : CodeHintManager, CSSUtils : require("language/CSSUtils"), LiveDevelopment : require("LiveDevelopment/LiveDevelopment"), LiveDevServerManager : require("LiveDevelopment/LiveDevServerManager"), DOMAgent : require("LiveDevelopment/Agents/DOMAgent"), Inspector : require("LiveDevelopment/Inspector/Inspector"), NativeApp : require("utils/NativeApp"), ExtensionUtils : ExtensionUtils, UpdateNotification : require("utils/UpdateNotification"), doneLoading : false }; AppInit.appReady(function () { brackets.test.doneLoading = true; }); } function _onReady() { PerfUtils.addMeasurement("window.document Ready"); EditorManager.setEditorHolder($("#editor-holder")); // Let the user know Brackets doesn't run in a web browser yet if (brackets.inBrowser) { Dialogs.showModalDialog( Dialogs.DIALOG_ID_ERROR, Strings.ERROR_IN_BROWSER_TITLE, Strings.ERROR_IN_BROWSER ); } // 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. 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 = $("<div style='position:fixed;left:-50px;width:50px;height:50px;overflow:auto;'><div style='width:100px;height:100px;'/></div>").appendTo(window.document.body); if ($testDiv.outerWidth() === $testDiv.get(0).clientWidth) { $(".sidebar").removeClass("quiet-scrollbars"); } $testDiv.remove(); } // Load all extensions. This promise will complete even if one or more // extensions fail to load. var extensionLoaderPromise = ExtensionLoader.init(params.get("extensions")); // Load the initial project after extensions have loaded extensionLoaderPromise.always(function () { // Finish UI initialization 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 prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_CLIENT_ID), deferred = new $.Deferred(); if (!params.get("skipSampleProjectLoad") && !prefs.getValue("afterFirstLaunch")) { prefs.setValue("afterFirstLaunch", "true"); if (ProjectManager.isWelcomeProjectPath(initialProjectPath)) { var dirEntry = new NativeFileSystem.DirectoryEntry(initialProjectPath); dirEntry.getFile("index.html", {}, function (fileEntry) { var promise = CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: fileEntry.fullPath }); promise.pipe(deferred.resolve, deferred.reject); }, deferred.reject); } else { deferred.resolve(); } } else { deferred.resolve(); } deferred.always(function () { // Signal that Brackets is loaded AppInit._dispatchReady(AppInit.APP_READY); PerfUtils.addMeasurement("Application Startup"); }); // See if any startup files were passed to the application if (brackets.app.getPendingFilesToOpen) { brackets.app.getPendingFilesToOpen(function (err, files) { files.forEach(function (filename) { CommandManager.execute(Commands.FILE_OPEN, { fullPath: filename }); }); }); } }); }); // Check for updates if (!params.get("skipUpdateCheck") && !brackets.inBrowser) { // check once a day, plus 2 minutes, // as the check will skip if the last check was not -24h ago window.setInterval(UpdateNotification.checkForUpdate, 86520000); UpdateNotification.checkForUpdate(); } } /** * Setup event handlers prior to dispatching AppInit.HTML_READY */ function _beforeHTMLReady() { // Add the platform (mac or win) to the body tag so we can have platform-specific CSS rules $("body").addClass("platform-" + brackets.platform); // Localize MainViewHTML and inject into <BODY> tag $("body").html(Mustache.render(MainViewHTML, Strings)); // Update title $("title").text(brackets.config.app_title); // Prevent unhandled drag and drop of files into the browser from replacing // the entire Brackets app. This doesn't prevent children from choosing to // handle drops. $(window.document.body) .on("dragover", function (event) { if (event.originalEvent.dataTransfer.files) { event.stopPropagation(); event.preventDefault(); event.originalEvent.dataTransfer.dropEffect = "none"; } }) .on("drop", function (event) { if (event.originalEvent.dataTransfer.files) { event.stopPropagation(); event.preventDefault(); } }); // 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 () { FileSyncManager.syncOpenDocuments(); FileIndexManager.markDirty(); }); // Prevent unhandled middle button clicks from triggering native behavior // Example: activating AutoScroll (see #510) $("html").on("mousedown", ".inline-widget", function (e) { if (e.button === 1) { 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. $("html").on("mousedown", ".no-focus", function (e) { // Text fields should always be focusable. var $target = $(e.target), isTextField = $target.is("input[type=text]") || $target.is("input[type=number]") || $target.is("input[type=password]") || $target.is("input:not([type])") || // input with no type attribute defaults to text $target.is("textarea"); if (!isTextField) { e.preventDefault(); } }); } // Dispatch htmlReady event _beforeHTMLReady(); AppInit._dispatchReady(AppInit.HTML_READY); $(window.document).ready(_onReady); });
deferred.always(function () { // Signal that Brackets is loaded AppInit._dispatchReady(AppInit.APP_READY); PerfUtils.addMeasurement("Application Startup"); });
define(function (require, exports, module) { "use strict"; // Load dependent non-module scripts require("widgets/bootstrap-dropdown"); require("widgets/bootstrap-modal"); require("thirdparty/path-utils/path-utils.min"); require("thirdparty/smart-auto-complete/jquery.smart_autocomplete"); // Load LiveDeveopment require("LiveDevelopment/main"); // Load dependent modules var Global = require("utils/Global"), AppInit = require("utils/AppInit"), ProjectManager = require("project/ProjectManager"), DocumentManager = require("document/DocumentManager"), EditorManager = require("editor/EditorManager"), CSSInlineEditor = require("editor/CSSInlineEditor"), JSUtils = require("language/JSUtils"), WorkingSetView = require("project/WorkingSetView"), DocumentCommandHandlers = require("document/DocumentCommandHandlers"), FileViewController = require("project/FileViewController"), FileSyncManager = require("project/FileSyncManager"), KeyBindingManager = require("command/KeyBindingManager"), Commands = require("command/Commands"), CommandManager = require("command/CommandManager"), CodeHintManager = require("editor/CodeHintManager"), JSLintUtils = require("language/JSLintUtils"), PerfUtils = require("utils/PerfUtils"), FileIndexManager = require("project/FileIndexManager"), QuickOpen = require("search/QuickOpen"), Menus = require("command/Menus"), FileUtils = require("file/FileUtils"), MainViewHTML = require("text!htmlContent/main-view.html"), Strings = require("strings"), Dialogs = require("widgets/Dialogs"), ExtensionLoader = require("utils/ExtensionLoader"), SidebarView = require("project/SidebarView"), Async = require("utils/Async"), UpdateNotification = require("utils/UpdateNotification"), UrlParams = require("utils/UrlParams").UrlParams, NativeFileSystem = require("file/NativeFileSystem").NativeFileSystem, PreferencesManager = require("preferences/PreferencesManager"), Resizer = require("utils/Resizer"); // Local variables var params = new UrlParams(), PREFERENCES_CLIENT_ID = "com.adobe.brackets.startup"; // read URL params params.parse(); //Load modules that self-register and just need to get included in the main project require("document/ChangedDocumentTracker"); require("editor/EditorCommandHandlers"); require("view/ViewCommandHandlers"); require("debug/DebugCommandHandlers"); require("help/HelpCommandHandlers"); require("search/FindInFiles"); require("search/FindReplace"); require("utils/ExtensionUtils"); // TODO: (issue 1029) Add timeout to main extension loading promise, so that we always call this function // Making this fix will fix a warning (search for issue 1029) related to the global brackets 'ready' event. function _initExtensions() { // allow unit tests to override which plugin folder(s) to load var paths = params.get("extensions") || "default,user"; return Async.doInParallel(paths.split(","), function (item) { return ExtensionLoader.loadAllExtensionsInNativeDirectory( FileUtils.getNativeBracketsDirectoryPath() + "/extensions/" + item, "extensions/" + item ); }); } function _initTest() { // TODO: (issue #265) Make sure the "test" object is not included in final builds // All modules that need to be tested from the context of the application // must to be added to this object. The unit tests cannot just pull // in the modules since they would run in context of the unit test window, // and would not have access to the app html/css. brackets.test = { PreferencesManager : require("preferences/PreferencesManager"), ProjectManager : ProjectManager, DocumentCommandHandlers : DocumentCommandHandlers, FileViewController : FileViewController, DocumentManager : DocumentManager, EditorManager : EditorManager, Commands : Commands, WorkingSetView : WorkingSetView, JSLintUtils : JSLintUtils, PerfUtils : PerfUtils, JSUtils : JSUtils, CommandManager : require("command/CommandManager"), FileSyncManager : FileSyncManager, FileIndexManager : FileIndexManager, Menus : Menus, KeyBindingManager : KeyBindingManager, CodeHintManager : CodeHintManager, CSSUtils : require("language/CSSUtils"), LiveDevelopment : require("LiveDevelopment/LiveDevelopment"), Inspector : require("LiveDevelopment/Inspector/Inspector"), NativeApp : require("utils/NativeApp"), ExtensionUtils : require("utils/ExtensionUtils"), UpdateNotification : require("utils/UpdateNotification"), doneLoading : false }; AppInit.appReady(function () { brackets.test.doneLoading = true; }); } function _initDragAndDropListeners() { // Prevent unhandled drag and drop of files into the browser from replacing // the entire Brackets app. This doesn't prevent children from choosing to // handle drops. $(window.document.body) .on("dragover", function (event) { if (event.originalEvent.dataTransfer.files) { event.stopPropagation(); event.preventDefault(); event.originalEvent.dataTransfer.dropEffect = "none"; } }) .on("drop", function (event) { if (event.originalEvent.dataTransfer.files) { event.stopPropagation(); event.preventDefault(); } }); } function _initCommandHandlers() { // Most command handlers are automatically registered when their module is loaded (see "modules // that self-register" above for some). A few commands need an extra kick here though: DocumentCommandHandlers.init($("#main-toolbar")); } function _initWindowListeners() { // 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 () { FileSyncManager.syncOpenDocuments(); FileIndexManager.markDirty(); }); } function _onReady() { // Add the platform (mac or win) to the body tag so we can have platform-specific CSS rules $("body").addClass("platform-" + brackets.platform); EditorManager.setEditorHolder($("#editor-holder")); // Let the user know Brackets doesn't run in a web browser yet if (brackets.inBrowser) { Dialogs.showModalDialog( Dialogs.DIALOG_ID_ERROR, Strings.ERROR_IN_BROWSER_TITLE, Strings.ERROR_IN_BROWSER ); } _initDragAndDropListeners(); _initCommandHandlers(); KeyBindingManager.init(); Menus.init(); // key bindings should be initialized first _initWindowListeners(); // 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. 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 = $("<div style='position:fixed;left:-50px;width:50px;height:50px;overflow:auto;'><div style='width:100px;height:100px;'/></div>").appendTo(window.document.body); if ($testDiv.outerWidth() === $testDiv.get(0).clientWidth) { $(".sidebar").removeClass("quiet-scrollbars"); } $testDiv.remove(); } PerfUtils.addMeasurement("Application Startup"); // finish UI initialization before loading extensions var initialProjectPath = ProjectManager.getInitialProjectPath(); ProjectManager.openProject(initialProjectPath).always(function () { _initTest(); // WARNING: AppInit.appReady won't fire if ANY extension fails to // load or throws an error during init. To fix this, we need to // make a change to _initExtensions (filed as issue 1029) _initExtensions().always(AppInit._dispatchReady(AppInit.APP_READY)); // 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 prefs = PreferencesManager.getPreferenceStorage(PREFERENCES_CLIENT_ID); if (!params.get("skipSampleProjectLoad") && !prefs.getValue("afterFirstLaunch")) { prefs.setValue("afterFirstLaunch", "true"); if (ProjectManager.isWelcomeProjectPath(initialProjectPath)) { var dirEntry = new NativeFileSystem.DirectoryEntry(initialProjectPath); dirEntry.getFile("index.html", {}, function (fileEntry) { CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: fileEntry.fullPath }); }); } } }); // Check for updates if (!params.get("skipUpdateCheck")) { UpdateNotification.checkForUpdate(); } } // Prevent unhandled mousedown events from triggering native behavior // Example: activating AutoScroll when clicking the middle mouse button (see #510) $("html").on("mousedown", function (event) { event.preventDefault(); }); // Localize MainViewHTML and inject into <BODY> tag var templateVars = $.extend({ ABOUT_ICON : brackets.config.about_icon, APP_NAME_ABOUT_BOX : brackets.config.app_name_about, VERSION : brackets.metadata.version }, Strings); $("body").html(Mustache.render(MainViewHTML, templateVars)); // Update title $("title").text(brackets.config.app_title); // Dispatch htmlReady callbacks AppInit._dispatchReady(AppInit.HTML_READY); $(window.document).ready(_onReady); });
_initExtensions().always(function () { AppInit._dispatchReady(AppInit.APP_READY); });
extensionLoaderPromise.always(function () { // Signal that extensions are loaded AppInit._dispatchReady(AppInit.EXTENSIONS_LOADED); // Finish UI initialization ViewCommandHandlers.restoreFontSize(); 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)) { FileSystem.resolve(initialProjectPath + "index.html", function (err, file) { if (!err) { var promise = CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: file.fullPath }); promise.then(deferred.resolve, deferred.reject); } else { deferred.reject(); } }); } else { deferred.resolve(); } } 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, // but malformed. no need to check for its existance. var info = MainViewManager.findInAllWorkingSets(userPrefFullPath); var paneId; if (info.length) { paneId = info[0].paneId; } FileViewController.openFileAndAddToWorkingSet(userPrefFullPath, paneId) .done(function () { Dialogs.showModalDialog( DefaultDialogs.DIALOG_ID_ERROR, Strings.ERROR_PREFS_CORRUPT_TITLE, Strings.ERROR_PREFS_CORRUPT ).done(function () { // give the focus back to the editor with the pref file MainViewManager.focusActivePane(); }); }); } }); // See if any startup files were passed to the application if (brackets.app.getPendingFilesToOpen) { brackets.app.getPendingFilesToOpen(function (err, paths) { DragAndDrop.openDroppedFiles(paths); }); } }); });
define(function (require, exports, module) { "use strict"; // Load dependent non-module scripts require("widgets/bootstrap-dropdown"); require("widgets/bootstrap-modal"); require("thirdparty/path-utils/path-utils.min"); require("thirdparty/smart-auto-complete/jquery.smart_autocomplete"); // Load LiveDeveopment require("LiveDevelopment/main"); // Load dependent modules var Global = require("utils/Global"), AppInit = require("utils/AppInit"), ProjectManager = require("project/ProjectManager"), DocumentManager = require("document/DocumentManager"), EditorManager = require("editor/EditorManager"), CSSInlineEditor = require("editor/CSSInlineEditor"), JSUtils = require("language/JSUtils"), WorkingSetView = require("project/WorkingSetView"), DocumentCommandHandlers = require("document/DocumentCommandHandlers"), FileViewController = require("project/FileViewController"), FileSyncManager = require("project/FileSyncManager"), KeyBindingManager = require("command/KeyBindingManager"), Commands = require("command/Commands"), CommandManager = require("command/CommandManager"), BuildInfoUtils = require("utils/BuildInfoUtils"), CodeHintManager = require("editor/CodeHintManager"), JSLintUtils = require("language/JSLintUtils"), PerfUtils = require("utils/PerfUtils"), FileIndexManager = require("project/FileIndexManager"), QuickOpen = require("search/QuickOpen"), Menus = require("command/Menus"), FileUtils = require("file/FileUtils"), MainViewHTML = require("text!htmlContent/main-view.html"), Strings = require("strings"), Dialogs = require("widgets/Dialogs"), ExtensionLoader = require("utils/ExtensionLoader"), SidebarView = require("project/SidebarView"), Async = require("utils/Async"), UpdateNotification = require("utils/UpdateNotification"), UrlParams = require("utils/UrlParams").UrlParams; // Local variables var params = new UrlParams(); // read URL params params.parse(); //Load modules that self-register and just need to get included in the main project require("document/ChangedDocumentTracker"); require("editor/EditorCommandHandlers"); require("debug/DebugCommandHandlers"); require("view/ViewCommandHandlers"); require("search/FindInFiles"); require("search/FindReplace"); require("utils/ExtensionUtils"); // TODO: (issue 1029) Add timeout to main extension loading promise, so that we always call this function // Making this fix will fix a warning (search for issue 1029) related to the global brackets 'ready' event. function _initExtensions() { // allow unit tests to override which plugin folder(s) to load var paths = params.get("extensions") || "default,user"; return Async.doInParallel(paths.split(","), function (item) { return ExtensionLoader.loadAllExtensionsInNativeDirectory( FileUtils.getNativeBracketsDirectoryPath() + "/extensions/" + item, "extensions/" + item ); }); } function _initTest() { // TODO: (issue #265) Make sure the "test" object is not included in final builds // All modules that need to be tested from the context of the application // must to be added to this object. The unit tests cannot just pull // in the modules since they would run in context of the unit test window, // and would not have access to the app html/css. brackets.test = { PreferencesManager : require("preferences/PreferencesManager"), ProjectManager : ProjectManager, DocumentCommandHandlers : DocumentCommandHandlers, FileViewController : FileViewController, DocumentManager : DocumentManager, EditorManager : EditorManager, Commands : Commands, WorkingSetView : WorkingSetView, JSLintUtils : JSLintUtils, PerfUtils : PerfUtils, JSUtils : JSUtils, CommandManager : require("command/CommandManager"), FileSyncManager : FileSyncManager, FileIndexManager : FileIndexManager, Menus : Menus, KeyBindingManager : KeyBindingManager, CodeHintManager : CodeHintManager, CSSUtils : require("language/CSSUtils"), LiveDevelopment : require("LiveDevelopment/LiveDevelopment"), Inspector : require("LiveDevelopment/Inspector/Inspector"), NativeApp : require("utils/NativeApp"), ExtensionUtils : require("utils/ExtensionUtils"), UpdateNotification : require("utils/UpdateNotification"), doneLoading : false }; AppInit.appReady(function () { brackets.test.doneLoading = true; }); } function _initDragAndDropListeners() { // Prevent unhandled drag and drop of files into the browser from replacing // the entire Brackets app. This doesn't prevent children from choosing to // handle drops. $(window.document.body) .on("dragover", function (event) { if (event.originalEvent.dataTransfer.files) { event.stopPropagation(); event.preventDefault(); event.originalEvent.dataTransfer.dropEffect = "none"; } }) .on("drop", function (event) { if (event.originalEvent.dataTransfer.files) { event.stopPropagation(); event.preventDefault(); } }); } function _initCommandHandlers() { // Most command handlers are automatically registered when their module is loaded (see "modules // that self-register" above for some). A few commands need an extra kick here though: DocumentCommandHandlers.init($("#main-toolbar")); // About dialog CommandManager.register(Strings.CMD_ABOUT, Commands.HELP_ABOUT, function () { // If we've successfully determined a "build number" via .git metadata, add it to dialog var bracketsSHA = BuildInfoUtils.getBracketsSHA(), bracketsAppSHA = BuildInfoUtils.getBracketsAppSHA(), versionLabel = ""; if (bracketsSHA) { versionLabel += " (" + bracketsSHA.substr(0, 7) + ")"; } if (bracketsAppSHA) { versionLabel += " (shell " + bracketsAppSHA.substr(0, 7) + ")"; } $("#about-build-number").text(versionLabel); Dialogs.showModalDialog(Dialogs.DIALOG_ID_ABOUT); }); } function _initWindowListeners() { // 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 () { FileSyncManager.syncOpenDocuments(); FileIndexManager.markDirty(); }); } function _onReady() { // Add the platform (mac or win) to the body tag so we can have platform-specific CSS rules $("body").addClass("platform-" + brackets.platform); EditorManager.setEditorHolder($("#editor-holder")); // Let the user know Brackets doesn't run in a web browser yet if (brackets.inBrowser) { Dialogs.showModalDialog( Dialogs.DIALOG_ID_ERROR, Strings.ERROR_BRACKETS_IN_BROWSER_TITLE, Strings.ERROR_BRACKETS_IN_BROWSER ); } _initDragAndDropListeners(); _initCommandHandlers(); KeyBindingManager.init(); Menus.init(); // key bindings should be initialized first _initWindowListeners(); // Read "build number" SHAs off disk at the time the matching Brackets JS code is being loaded, instead // of later, when they may have been updated to a different version BuildInfoUtils.init(); // 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. 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 = $("<div style='position:fixed;left:-50px;width:50px;height:50px;overflow:auto;'><div style='width:100px;height:100px;'/></div>").appendTo(window.document.body); if ($testDiv.outerWidth() === $testDiv.get(0).clientWidth) { $(".sidebar").removeClass("quiet-scrollbars"); } $testDiv.remove(); } PerfUtils.addMeasurement("Application Startup"); // finish UI initialization before loading extensions var initialProjectPath = ProjectManager.getInitialProjectPath(); ProjectManager.openProject(initialProjectPath).done(function () { _initTest(); // WARNING: AppInit.appReady won't fire if ANY extension fails to // load or throws an error during init. To fix this, we need to // make a change to _initExtensions (filed as issue 1029) _initExtensions().always(AppInit._dispatchReady(AppInit.APP_READY)); }); // Check for updates if (!params.get("skipUpdateCheck")) { UpdateNotification.checkForUpdate(); } } // Localize MainViewHTML and inject into <BODY> tag $('body').html(Mustache.render(MainViewHTML, Strings)); AppInit._dispatchReady(AppInit.HTML_READY); $(window.document).ready(_onReady); });
define(function (require, exports, module) { "use strict"; // Load dependent non-module scripts require("widgets/bootstrap-dropdown"); require("widgets/bootstrap-modal"); require("widgets/bootstrap-twipsy-mod"); require("thirdparty/path-utils/path-utils.min"); require("thirdparty/smart-auto-complete-local/jquery.smart_autocomplete"); // Load dependent modules var Global = require("utils/Global"), AppInit = require("utils/AppInit"), LanguageManager = require("language/LanguageManager"), ProjectManager = require("project/ProjectManager"), DocumentManager = require("document/DocumentManager"), EditorManager = require("editor/EditorManager"), CSSInlineEditor = require("editor/CSSInlineEditor"), JSUtils = require("language/JSUtils"), WorkingSetView = require("project/WorkingSetView"), WorkingSetSort = require("project/WorkingSetSort"), DocumentCommandHandlers = require("document/DocumentCommandHandlers"), FileViewController = require("project/FileViewController"), FileSyncManager = require("project/FileSyncManager"), KeyBindingManager = require("command/KeyBindingManager"), Commands = require("command/Commands"), CommandManager = require("command/CommandManager"), CodeHintManager = require("editor/CodeHintManager"), PerfUtils = require("utils/PerfUtils"), FileSystem = require("filesystem/FileSystem"), QuickOpen = require("search/QuickOpen"), Menus = require("command/Menus"), FileUtils = require("file/FileUtils"), MainViewHTML = require("text!htmlContent/main-view.html"), Strings = require("strings"), Dialogs = require("widgets/Dialogs"), DefaultDialogs = require("widgets/DefaultDialogs"), ExtensionLoader = require("utils/ExtensionLoader"), SidebarView = require("project/SidebarView"), Async = require("utils/Async"), UpdateNotification = require("utils/UpdateNotification"), UrlParams = require("utils/UrlParams").UrlParams, PreferencesManager = require("preferences/PreferencesManager"), Resizer = require("utils/Resizer"), LiveDevelopmentMain = require("LiveDevelopment/main"), NodeConnection = require("utils/NodeConnection"), ExtensionUtils = require("utils/ExtensionUtils"), DragAndDrop = require("utils/DragAndDrop"), ColorUtils = require("utils/ColorUtils"), CodeInspection = require("language/CodeInspection"), NativeApp = require("utils/NativeApp"), _ = require("thirdparty/lodash"); // Load modules that self-register and just need to get included in the main project require("command/DefaultMenus"); require("document/ChangedDocumentTracker"); require("editor/EditorStatusBar"); require("editor/EditorCommandHandlers"); require("editor/EditorOptionHandlers"); require("view/ViewCommandHandlers"); require("help/HelpCommandHandlers"); require("search/FindInFiles"); require("search/FindReplace"); require("extensibility/InstallExtensionDialog"); require("extensibility/ExtensionManagerDialog"); // Compatibility shims for filesystem API migration require("project/FileIndexManager"); require("file/NativeFileSystem"); require("file/NativeFileError"); PerfUtils.addMeasurement("brackets module dependencies resolved"); // Local variables var params = new UrlParams(); // read URL params params.parse(); function _initTest() { // TODO: (issue #265) Make sure the "test" object is not included in final builds // All modules that need to be tested from the context of the application // must to be added to this object. The unit tests cannot just pull // in the modules since they would run in context of the unit test window, // and would not have access to the app html/css. brackets.test = { PreferencesManager : PreferencesManager, ProjectManager : ProjectManager, DocumentCommandHandlers : DocumentCommandHandlers, FileViewController : FileViewController, DocumentManager : DocumentManager, EditorManager : EditorManager, Commands : Commands, WorkingSetView : WorkingSetView, PerfUtils : PerfUtils, JSUtils : JSUtils, CommandManager : CommandManager, FileSyncManager : FileSyncManager, FileSystem : FileSystem, Menus : Menus, KeyBindingManager : KeyBindingManager, CodeHintManager : CodeHintManager, Dialogs : Dialogs, DefaultDialogs : DefaultDialogs, DragAndDrop : DragAndDrop, CodeInspection : CodeInspection, CSSUtils : require("language/CSSUtils"), LiveDevelopment : require("LiveDevelopment/LiveDevelopment"), LiveDevServerManager : require("LiveDevelopment/LiveDevServerManager"), DOMAgent : require("LiveDevelopment/Agents/DOMAgent"), Inspector : require("LiveDevelopment/Inspector/Inspector"), NativeApp : NativeApp, ExtensionLoader : ExtensionLoader, ExtensionUtils : ExtensionUtils, UpdateNotification : require("utils/UpdateNotification"), InstallExtensionDialog : require("extensibility/InstallExtensionDialog"), RemoteAgent : require("LiveDevelopment/Agents/RemoteAgent"), HTMLInstrumentation : require("language/HTMLInstrumentation"), MultiRangeInlineEditor : require("editor/MultiRangeInlineEditor").MultiRangeInlineEditor, LanguageManager : LanguageManager, doneLoading : false }; AppInit.appReady(function () { brackets.test.doneLoading = true; }); } function _onReady() { PerfUtils.addMeasurement("window.document Ready"); EditorManager.setEditorHolder($("#editor-holder")); // Let the user know Brackets doesn't run in a web browser yet if (brackets.inBrowser) { Dialogs.showModalDialog( DefaultDialogs.DIALOG_ID_ERROR, Strings.ERROR_IN_BROWSER_TITLE, Strings.ERROR_IN_BROWSER ); } // 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. 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 = $("<div style='position:fixed;left:-50px;width:50px;height:50px;overflow:auto;'><div style='width:100px;height:100px;'/></div>").appendTo(window.document.body); if ($testDiv.outerWidth() === $testDiv.get(0).clientWidth) { $(".sidebar").removeClass("quiet-scrollbars"); } $testDiv.remove(); } // Load default languages LanguageManager.ready.always(function () { // Load all extensions. This promise will complete even if one or more // 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 () { // Finish UI initialization 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 prefs = PreferencesManager.getPreferenceStorage(module), deferred = new $.Deferred(); if (!params.get("skipSampleProjectLoad") && !prefs.getValue("afterFirstLaunch")) { prefs.setValue("afterFirstLaunch", "true"); if (ProjectManager.isWelcomeProjectPath(initialProjectPath)) { FileSystem.resolve(initialProjectPath + "index.html", function (err, file) { if (!err) { var promise = CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: file.fullPath }); promise.then(deferred.resolve, deferred.reject); } else { deferred.reject(); } }); } else { deferred.resolve(); } } else { deferred.resolve(); } deferred.always(function () { // Signal that Brackets is loaded AppInit._dispatchReady(AppInit.APP_READY); PerfUtils.addMeasurement("Application Startup"); }); // See if any startup files were passed to the application if (brackets.app.getPendingFilesToOpen) { brackets.app.getPendingFilesToOpen(function (err, files) { DragAndDrop.openDroppedFiles(files); }); } }); }); }); // Check for updates if (!params.get("skipUpdateCheck") && !brackets.inBrowser) { // check once a day, plus 2 minutes, // as the check will skip if the last check was not -24h ago window.setInterval(UpdateNotification.checkForUpdate, 86520000); // Check for updates on App Ready AppInit.appReady(function () { UpdateNotification.checkForUpdate(); }); } } /** * Setup event handlers prior to dispatching AppInit.HTML_READY */ function _beforeHTMLReady() { // Add the platform (mac or win) 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"); } else { $("body").addClass("in-appshell"); } // Enable/Disable HTML Menus if (brackets.nativeMenus) { $("body").addClass("has-appshell-menus"); } else { // (issue #5310) workaround for bootstrap dropdown: prevent the menu item to grab // the focus -- override jquery focus implementation for top-level menu items (function () { var defaultFocus = $.fn.focus; $.fn.focus = function () { if (!this.hasClass("dropdown-toggle")) { return defaultFocus.apply(this, arguments); } }; }()); } // Localize MainViewHTML and inject into <BODY> tag $("body").html(Mustache.render(MainViewHTML, Strings)); // Update title $("title").text(brackets.config.app_title); // Prevent unhandled drag and drop of files into the browser from replacing // the entire Brackets app. This doesn't prevent children from choosing to // handle drops. $(window.document.body) .on("dragover", function (event) { var dropEffect = "none"; if (event.originalEvent.dataTransfer.files) { event.stopPropagation(); event.preventDefault(); // Don't allow drag-and-drop of files/folders when a modal dialog is showing. if ($(".modal.instance").length === 0 && DragAndDrop.isValidDrop(event.originalEvent.dataTransfer.items)) { dropEffect = "copy"; } event.originalEvent.dataTransfer.dropEffect = dropEffect; } }) .on("drop", function (event) { if (event.originalEvent.dataTransfer.files) { event.stopPropagation(); event.preventDefault(); brackets.app.getDroppedFiles(function (err, files) { if (!err) { DragAndDrop.openDroppedFiles(files); } }); } }); // 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) { if (e.button === 1) { 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. $("html").on("mousedown", ".no-focus", function (e) { // Text fields should always be focusable. var $target = $(e.target), isTextField = $target.is("input[type=text]") || $target.is("input[type=number]") || $target.is("input[type=password]") || $target.is("input:not([type])") || // input with no type attribute defaults to text $target.is("textarea"); if (!isTextField) { 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 // navigate. Also, a capture handler is more reliable than bubble. window.document.body.addEventListener("click", function (e) { // Check parents too, in case link has inline formatting tags var node = e.target, url; while (node) { if (node.tagName === "A") { url = node.getAttribute("href"); if (url && !url.match(/^#/)) { NativeApp.openURLInDefaultBrowser(url); } e.preventDefault(); break; } node = node.parentElement; } }, true); } // Dispatch htmlReady event _beforeHTMLReady(); AppInit._dispatchReady(AppInit.HTML_READY); $(window.document).ready(_onReady); });