Example #1
0
 PreferencesManager._smUserScopeLoading.always(function () {
     PerfUtils.addMeasurement(viewStateTimer);
     // Dispatch htmlReady event
     _beforeHTMLReady();
     AppInit._dispatchReady(AppInit.HTML_READY);
     $(window.document).ready(_onReady);
 });
Example #2
0
 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();
                 });
             });
     }
     
 });
Example #3
0
        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));
        });
Example #4
0
            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
            });
Example #5
0
 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);
             });
     }
     
 });
Example #6
0
 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();
 }
Example #7
0
        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 });
                    });
                }
            }
        });
Example #8
0
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);
});
Example #9
0
 deferred.always(function () {
     // Signal that Brackets is loaded
     AppInit._dispatchReady(AppInit.APP_READY);
     
     PerfUtils.addMeasurement("Application Startup");
 });
Example #10
0
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);
    
});
Example #11
0
 _initExtensions().always(function () {
     AppInit._dispatchReady(AppInit.APP_READY);
 });
Example #12
0
            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);
                        });
                    }
                });
            });
Example #13
0
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);
    
});
Example #14
0
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);
});