Implement Splitview
@ -40,6 +40,7 @@ define(function GotoAgent(require, exports, module) {
|
||||
|
||||
var DocumentManager = require("document/DocumentManager");
|
||||
var EditorManager = require("editor/EditorManager");
|
||||
var MainViewManager = require("view/MainViewManager");
|
||||
|
||||
/** Return the URL without the query string
|
||||
* @param {string} URL
|
||||
@ -172,7 +173,7 @@ define(function GotoAgent(require, exports, module) {
|
||||
path = decodeURI(path);
|
||||
var promise = DocumentManager.getDocumentForPath(path);
|
||||
promise.done(function onDone(doc) {
|
||||
DocumentManager.setCurrentDocument(doc);
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, doc);
|
||||
if (location) {
|
||||
openLocation(location, noFlash);
|
||||
}
|
||||
|
@ -155,6 +155,10 @@ define(function HTMLDocumentModule(require, exports, module) {
|
||||
self._onChange(event, editor, change);
|
||||
});
|
||||
|
||||
$(this.editor).on("beforeDestroy.HTMLDocument", function (event, editor) {
|
||||
self._onDestroy(event, editor);
|
||||
});
|
||||
|
||||
// Experimental code
|
||||
if (LiveDevelopment.config.experimental) {
|
||||
$(HighlightAgent).on("highlight.HTMLDocument", function (event, node) {
|
||||
@ -266,6 +270,18 @@ define(function HTMLDocumentModule(require, exports, module) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Triggered when the editor is being destroyed
|
||||
* @param {$.Event} event Event
|
||||
* @param {!Editor} editor The editor being destroyed
|
||||
*/
|
||||
HTMLDocument.prototype._onDestroy = function (event, editor) {
|
||||
if (this.editor === editor) {
|
||||
this.detachFromEditor();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Triggered on change by the editor
|
||||
* @param {$.Event} event Event
|
||||
|
@ -85,6 +85,7 @@ define(function LiveDevelopment(require, exports, module) {
|
||||
FileSystemError = require("filesystem/FileSystemError"),
|
||||
FileUtils = require("file/FileUtils"),
|
||||
LiveDevServerManager = require("LiveDevelopment/LiveDevServerManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
NativeApp = require("utils/NativeApp"),
|
||||
PreferencesDialogs = require("preferences/PreferencesDialogs"),
|
||||
ProjectManager = require("project/ProjectManager"),
|
||||
@ -1318,18 +1319,18 @@ define(function LiveDevelopment(require, exports, module) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: need to run _onDocumentChange() after load if doc != currentDocument here? Maybe not, since activeEditorChange
|
||||
// TODO: need to run _onFileChanged() after load if doc != currentDocument here? Maybe not, since activeEditorChange
|
||||
// doesn't trigger it, while inline editors can still cause edits in doc other than currentDoc...
|
||||
_getInitialDocFromCurrent().done(function (doc) {
|
||||
var prepareServerPromise = (doc && _prepareServer(doc)) || new $.Deferred().reject(),
|
||||
otherDocumentsInWorkingFiles;
|
||||
|
||||
if (doc && !doc._masterEditor) {
|
||||
otherDocumentsInWorkingFiles = DocumentManager.getWorkingSet().length;
|
||||
DocumentManager.addToWorkingSet(doc.file);
|
||||
otherDocumentsInWorkingFiles = MainViewManager.getWorkingSet(MainViewManager.ALL_PANES).length;
|
||||
MainViewManager.addToWorkingSet(MainViewManager.ACTIVE_PANE, doc.file);
|
||||
|
||||
if (!otherDocumentsInWorkingFiles) {
|
||||
DocumentManager.setCurrentDocument(doc);
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, doc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1371,9 +1372,9 @@ define(function LiveDevelopment(require, exports, module) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* DocumentManager currentDocumentChange event handler.
|
||||
* MainViewManager.currentFileChange event handler.
|
||||
*/
|
||||
function _onDocumentChange() {
|
||||
function _onFileChanged() {
|
||||
var doc = _getCurrentDocument();
|
||||
|
||||
if (!doc || !Inspector.connected()) {
|
||||
@ -1472,10 +1473,13 @@ define(function LiveDevelopment(require, exports, module) {
|
||||
// We may get interim added/removed events when pushing incremental updates
|
||||
$(CSSAgent).on("styleSheetAdded.livedev", _styleSheetAdded);
|
||||
|
||||
$(DocumentManager).on("currentDocumentChange", _onDocumentChange)
|
||||
$(MainViewManager)
|
||||
.on("currentFileChange", _onFileChanged);
|
||||
$(DocumentManager)
|
||||
.on("documentSaved", _onDocumentSaved)
|
||||
.on("dirtyFlagChange", _onDirtyFlagChange);
|
||||
$(ProjectManager).on("beforeProjectClose beforeAppClose", close);
|
||||
$(ProjectManager)
|
||||
.on("beforeProjectClose beforeAppClose", close);
|
||||
|
||||
// Register user defined server provider
|
||||
LiveDevServerManager.registerServer({ create: _createUserServer }, 99);
|
||||
|
@ -105,6 +105,7 @@ define(function (require, exports, module) {
|
||||
DeprecationWarning = require("utils/DeprecationWarning"),
|
||||
ViewCommandHandlers = require("view/ViewCommandHandlers"),
|
||||
ThemeManager = require("view/ThemeManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
_ = require("thirdparty/lodash");
|
||||
|
||||
// DEPRECATED: In future we want to remove the global CodeMirror, but for now we
|
||||
@ -139,6 +140,9 @@ define(function (require, exports, module) {
|
||||
require("file/NativeFileSystem");
|
||||
require("file/NativeFileError");
|
||||
|
||||
// Compatibility shim for PanelManager to WorkspaceManager migration
|
||||
require("view/PanelManager");
|
||||
|
||||
PerfUtils.addMeasurement("brackets module dependencies resolved");
|
||||
|
||||
// Local variables
|
||||
@ -188,6 +192,8 @@ define(function (require, exports, module) {
|
||||
LanguageManager : LanguageManager,
|
||||
LiveDevelopment : require("LiveDevelopment/LiveDevelopment"),
|
||||
LiveDevServerManager : require("LiveDevelopment/LiveDevServerManager"),
|
||||
MainViewManager : MainViewManager,
|
||||
MainViewFactory : require("view/MainViewFactory"),
|
||||
Menus : Menus,
|
||||
MultiRangeInlineEditor : require("editor/MultiRangeInlineEditor").MultiRangeInlineEditor,
|
||||
NativeApp : NativeApp,
|
||||
@ -198,7 +204,6 @@ define(function (require, exports, module) {
|
||||
ScrollTrackMarkers : require("search/ScrollTrackMarkers"),
|
||||
UpdateNotification : require("utils/UpdateNotification"),
|
||||
WorkingSetView : WorkingSetView,
|
||||
|
||||
doneLoading : false
|
||||
};
|
||||
|
||||
@ -213,8 +218,6 @@ define(function (require, exports, module) {
|
||||
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(
|
||||
@ -248,6 +251,9 @@ define(function (require, exports, module) {
|
||||
|
||||
// Load the initial project after extensions have loaded
|
||||
extensionLoaderPromise.always(function () {
|
||||
// Signal that extensions are loaded
|
||||
AppInit._dispatchReady(AppInit.EXTENSIONS_LOADED);
|
||||
|
||||
// Finish UI initialization
|
||||
ViewCommandHandlers.restoreFontSize();
|
||||
var initialProjectPath = ProjectManager.getInitialProjectPath();
|
||||
@ -265,7 +271,7 @@ define(function (require, exports, module) {
|
||||
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 });
|
||||
var promise = CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: file.fullPath });
|
||||
promise.then(deferred.resolve, deferred.reject);
|
||||
} else {
|
||||
deferred.reject();
|
||||
|
@ -30,24 +30,6 @@ define(function (require, exports, module) {
|
||||
|
||||
var DeprecationWarning = require("utils/DeprecationWarning");
|
||||
|
||||
/**
|
||||
* @private
|
||||
* Create a deprecation warning and action for updated Command constants
|
||||
* @param {!string} oldConstant
|
||||
* @param {!string} newConstant
|
||||
*/
|
||||
function _deprecateCommand(oldConstant, newConstant) {
|
||||
var warning = "Use Commands." + newConstant + " instead of Commands." + oldConstant,
|
||||
newValue = exports[newConstant];
|
||||
|
||||
Object.defineProperty(exports, oldConstant, {
|
||||
get: function () {
|
||||
DeprecationWarning.deprecationWarning(warning, true);
|
||||
return newValue;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* List of constants for global command IDs.
|
||||
*/
|
||||
@ -56,7 +38,7 @@ define(function (require, exports, module) {
|
||||
exports.FILE_NEW_UNTITLED = "file.newDoc"; // DocumentCommandHandlers.js handleFileNew()
|
||||
exports.FILE_NEW = "file.newFile"; // DocumentCommandHandlers.js handleFileNewInProject()
|
||||
exports.FILE_NEW_FOLDER = "file.newFolder"; // DocumentCommandHandlers.js handleNewFolderInProject()
|
||||
exports.FILE_OPEN = "file.open"; // DocumentCommandHandlers.js handleFileOpen()
|
||||
exports.FILE_OPEN = "file.open"; // DocumentCommandHandlers.js handleDocumentOpen()
|
||||
exports.FILE_OPEN_FOLDER = "file.openFolder"; // ProjectManager.js openProject()
|
||||
exports.FILE_SAVE = "file.save"; // DocumentCommandHandlers.js handleFileSave()
|
||||
exports.FILE_SAVE_ALL = "file.saveAll"; // DocumentCommandHandlers.js handleFileSaveAll()
|
||||
@ -64,7 +46,6 @@ define(function (require, exports, module) {
|
||||
exports.FILE_CLOSE = "file.close"; // DocumentCommandHandlers.js handleFileClose()
|
||||
exports.FILE_CLOSE_ALL = "file.close_all"; // DocumentCommandHandlers.js handleFileCloseAll()
|
||||
exports.FILE_CLOSE_LIST = "file.close_list"; // DocumentCommandHandlers.js handleFileCloseList()
|
||||
exports.FILE_ADD_TO_WORKING_SET = "file.addToWorkingSet"; // DocumentCommandHandlers.js handleFileAddToWorkingSet()
|
||||
exports.FILE_OPEN_DROPPED_FILES = "file.openDroppedFiles"; // DragAndDrop.js openDroppedFiles()
|
||||
exports.FILE_LIVE_FILE_PREVIEW = "file.liveFilePreview"; // LiveDevelopment/main.js _handleGoLiveCommand()
|
||||
exports.CMD_RELOAD_LIVE_PREVIEW = "file.reloadLivePreview"; // LiveDevelopment/main.js _handleReloadLivePreviewCommand()
|
||||
@ -133,10 +114,15 @@ define(function (require, exports, module) {
|
||||
exports.TOGGLE_LINE_NUMBERS = "view.toggleLineNumbers"; // EditorOptionHandlers.js _getToggler()
|
||||
exports.TOGGLE_ACTIVE_LINE = "view.toggleActiveLine"; // EditorOptionHandlers.js _getToggler()
|
||||
exports.TOGGLE_WORD_WRAP = "view.toggleWordWrap"; // EditorOptionHandlers.js _getToggler()
|
||||
exports.SORT_WORKINGSET_BY_ADDED = "view.sortWorkingSetByAdded"; // WorkingSetSort.js _handleSortWorkingSetByAdded()
|
||||
exports.SORT_WORKINGSET_BY_NAME = "view.sortWorkingSetByName"; // WorkingSetSort.js _handleSortWorkingSetByName()
|
||||
exports.SORT_WORKINGSET_BY_TYPE = "view.sortWorkingSetByType"; // WorkingSetSort.js _handleSortWorkingSetByType()
|
||||
exports.SORT_WORKINGSET_AUTO = "view.sortWorkingSetAuto"; // WorkingSetSort.js _handleAutomaticSort()
|
||||
|
||||
exports.CMD_ADD_TO_WORKINGSET_AND_OPEN = "cmd.addToWorkingSetAndOpen"; // DocumentCommandHandlers.js handleOpenDocumentInNewPane()
|
||||
exports.CMD_OPEN = "cmd.open";
|
||||
|
||||
exports.CMD_ADD_TO_WORKINGSET_AND_OPEN = "cmd.addToWorkingSetAndOpen"; // DocumentCommandHandlers.js handleOpenDocumentInNewPane()
|
||||
exports.CMD_WORKINGSET_SORT_BY_ADDED = "cmd.sortWorkingSetByAdded"; // WorkingSetSort.js _handleSort()
|
||||
exports.CMD_WORKINGSET_SORT_BY_NAME = "cmd.sortWorkingSetByName"; // WorkingSetSort.js _handleSort()
|
||||
exports.CMD_WORKINGSET_SORT_BY_TYPE = "cmd.sortWorkingSetByType"; // WorkingSetSort.js _handleSort()
|
||||
exports.CMD_WORKING_SORT_TOGGLE_AUTO = "cmd.sortWorkingSetToggleAuto"; // WorkingSetSort.js _handleToggleAutoSort()
|
||||
|
||||
// NAVIGATE
|
||||
exports.NAVIGATE_NEXT_DOC = "navigate.nextDoc"; // DocumentCommandHandlers.js handleGoNextDoc()
|
||||
@ -176,15 +162,24 @@ define(function (require, exports, module) {
|
||||
exports.APP_ABORT_QUIT = "app.abort_quit"; // DocumentCommandHandlers.js handleAbortQuit()
|
||||
exports.APP_BEFORE_MENUPOPUP = "app.before_menupopup"; // DocumentCommandHandlers.js handleBeforeMenuPopup()
|
||||
|
||||
// ADD_TO_WORKING_SET is deprectated but we need a handler for it because the new command doesn't return the same result as the legacy command
|
||||
exports.FILE_ADD_TO_WORKING_SET = "file.addToWorkingSet"; // Deprecated through DocumentCommandHandlers.js handleFileAddToWorkingSet
|
||||
|
||||
// DEPRECATED: Working Set Commands
|
||||
DeprecationWarning.deprecateConstant(exports, "SORT_WORKINGSET_BY_ADDED", "CMD_WORKINGSET_SORT_BY_ADDED");
|
||||
DeprecationWarning.deprecateConstant(exports, "SORT_WORKINGSET_BY_NAME", "CMD_WORKINGSET_SORT_BY_NAME");
|
||||
DeprecationWarning.deprecateConstant(exports, "SORT_WORKINGSET_BY_TYPE", "CMD_WORKINGSET_SORT_BY_TYPE");
|
||||
DeprecationWarning.deprecateConstant(exports, "SORT_WORKINGSET_AUTO", "CMD_WORKING_SORT_TOGGLE_AUTO");
|
||||
|
||||
// DEPRECATED: Edit commands that were moved from the Edit Menu to the Find Menu
|
||||
_deprecateCommand("EDIT_FIND", "CMD_FIND");
|
||||
_deprecateCommand("EDIT_FIND_IN_SELECTED", "CMD_FIND_IN_SELECTED");
|
||||
_deprecateCommand("EDIT_FIND_IN_SUBTREE", "CMD_FIND_IN_SUBTREE");
|
||||
_deprecateCommand("EDIT_FIND_NEXT", "CMD_FIND_NEXT");
|
||||
_deprecateCommand("EDIT_FIND_PREVIOUS", "CMD_FIND_PREVIOUS");
|
||||
_deprecateCommand("EDIT_FIND_ALL_AND_SELECT", "CMD_FIND_ALL_AND_SELECT");
|
||||
_deprecateCommand("EDIT_ADD_NEXT_MATCH", "CMD_ADD_NEXT_MATCH");
|
||||
_deprecateCommand("EDIT_SKIP_CURRENT_MATCH", "CMD_SKIP_CURRENT_MATCH");
|
||||
_deprecateCommand("EDIT_REPLACE", "CMD_REPLACE");
|
||||
DeprecationWarning.deprecateConstant(exports, "EDIT_FIND", "CMD_FIND");
|
||||
DeprecationWarning.deprecateConstant(exports, "EDIT_FIND_IN_SELECTED", "CMD_FIND_IN_SELECTED");
|
||||
DeprecationWarning.deprecateConstant(exports, "EDIT_FIND_IN_SUBTREE", "CMD_FIND_IN_SUBTREE");
|
||||
DeprecationWarning.deprecateConstant(exports, "EDIT_FIND_NEXT", "CMD_FIND_NEXT");
|
||||
DeprecationWarning.deprecateConstant(exports, "EDIT_FIND_PREVIOUS", "CMD_FIND_PREVIOUS");
|
||||
DeprecationWarning.deprecateConstant(exports, "EDIT_FIND_ALL_AND_SELECT", "CMD_FIND_ALL_AND_SELECT");
|
||||
DeprecationWarning.deprecateConstant(exports, "EDIT_ADD_NEXT_MATCH", "CMD_ADD_NEXT_MATCH");
|
||||
DeprecationWarning.deprecateConstant(exports, "EDIT_SKIP_CURRENT_MATCH", "CMD_SKIP_CURRENT_MATCH");
|
||||
DeprecationWarning.deprecateConstant(exports, "EDIT_REPLACE", "CMD_REPLACE");
|
||||
});
|
||||
|
||||
|
@ -205,6 +205,36 @@ define(function (require, exports, module) {
|
||||
menu.addMenuItem(Commands.HELP_ABOUT);
|
||||
}
|
||||
|
||||
/*
|
||||
* WorkingSet context and gear menus
|
||||
* NOTE: Unlike most context menus defined here, these menus cannot
|
||||
* be setup to listen to click or context menu events when
|
||||
* this module intializes because the DOM nodes for these are
|
||||
* created by pane views which are created at runtime.
|
||||
* All other context menus have DOM elements to attach to
|
||||
* out of index.html
|
||||
*/
|
||||
|
||||
var workingset_cmenu = Menus.registerContextMenu(Menus.ContextMenuIds.WORKING_SET_CONTEXT_MENU);
|
||||
workingset_cmenu.addMenuItem(Commands.FILE_SAVE);
|
||||
workingset_cmenu.addMenuItem(Commands.FILE_SAVE_AS);
|
||||
workingset_cmenu.addMenuItem(Commands.FILE_RENAME);
|
||||
workingset_cmenu.addMenuItem(Commands.NAVIGATE_SHOW_IN_FILE_TREE);
|
||||
workingset_cmenu.addMenuItem(Commands.NAVIGATE_SHOW_IN_OS);
|
||||
workingset_cmenu.addMenuDivider();
|
||||
workingset_cmenu.addMenuItem(Commands.CMD_FIND_IN_SUBTREE);
|
||||
workingset_cmenu.addMenuItem(Commands.CMD_REPLACE_IN_SUBTREE);
|
||||
workingset_cmenu.addMenuDivider();
|
||||
workingset_cmenu.addMenuItem(Commands.FILE_CLOSE);
|
||||
|
||||
var workingset_configuration_menu = Menus.registerContextMenu(Menus.ContextMenuIds.WORKING_SET_CONFIG_MENU);
|
||||
workingset_configuration_menu.addMenuItem(Commands.CMD_WORKINGSET_SORT_BY_ADDED);
|
||||
workingset_configuration_menu.addMenuItem(Commands.CMD_WORKINGSET_SORT_BY_NAME);
|
||||
workingset_configuration_menu.addMenuItem(Commands.CMD_WORKINGSET_SORT_BY_TYPE);
|
||||
workingset_configuration_menu.addMenuDivider();
|
||||
workingset_configuration_menu.addMenuItem(Commands.CMD_WORKING_SORT_TOGGLE_AUTO);
|
||||
|
||||
|
||||
/*
|
||||
* Context Menus
|
||||
*/
|
||||
@ -220,26 +250,6 @@ define(function (require, exports, module) {
|
||||
project_cmenu.addMenuDivider();
|
||||
project_cmenu.addMenuItem(Commands.FILE_REFRESH);
|
||||
|
||||
var working_set_cmenu = Menus.registerContextMenu(Menus.ContextMenuIds.WORKING_SET_MENU);
|
||||
working_set_cmenu.addMenuItem(Commands.FILE_SAVE);
|
||||
working_set_cmenu.addMenuItem(Commands.FILE_SAVE_AS);
|
||||
working_set_cmenu.addMenuItem(Commands.FILE_RENAME);
|
||||
working_set_cmenu.addMenuItem(Commands.NAVIGATE_SHOW_IN_FILE_TREE);
|
||||
working_set_cmenu.addMenuItem(Commands.NAVIGATE_SHOW_IN_OS);
|
||||
working_set_cmenu.addMenuDivider();
|
||||
working_set_cmenu.addMenuItem(Commands.CMD_FIND_IN_SUBTREE);
|
||||
working_set_cmenu.addMenuItem(Commands.CMD_REPLACE_IN_SUBTREE);
|
||||
working_set_cmenu.addMenuDivider();
|
||||
working_set_cmenu.addMenuItem(Commands.FILE_CLOSE);
|
||||
|
||||
|
||||
var working_set_settings_cmenu = Menus.registerContextMenu(Menus.ContextMenuIds.WORKING_SET_SETTINGS_MENU);
|
||||
working_set_settings_cmenu.addMenuItem(Commands.SORT_WORKINGSET_BY_ADDED);
|
||||
working_set_settings_cmenu.addMenuItem(Commands.SORT_WORKINGSET_BY_NAME);
|
||||
working_set_settings_cmenu.addMenuItem(Commands.SORT_WORKINGSET_BY_TYPE);
|
||||
working_set_settings_cmenu.addMenuDivider();
|
||||
working_set_settings_cmenu.addMenuItem(Commands.SORT_WORKINGSET_AUTO);
|
||||
|
||||
var editor_cmenu = Menus.registerContextMenu(Menus.ContextMenuIds.EDITOR_MENU);
|
||||
// editor_cmenu.addMenuItem(Commands.NAVIGATE_JUMPTO_DEFINITION);
|
||||
editor_cmenu.addMenuItem(Commands.TOGGLE_QUICK_EDIT);
|
||||
@ -294,20 +304,12 @@ define(function (require, exports, module) {
|
||||
});
|
||||
|
||||
/**
|
||||
* Context menus for folder tree & working set list
|
||||
* Context menu for folder tree
|
||||
*/
|
||||
$("#project-files-container").on("contextmenu", function (e) {
|
||||
project_cmenu.open(e);
|
||||
});
|
||||
|
||||
$("#open-files-container").on("contextmenu", function (e) {
|
||||
working_set_cmenu.open(e);
|
||||
});
|
||||
|
||||
/**
|
||||
* Dropdown menu for workspace sorting
|
||||
*/
|
||||
Menus.ContextMenu.assignContextMenuToSelector("#working-set-option-btn", working_set_settings_cmenu);
|
||||
|
||||
// Prevent the browser context menu since Brackets creates a custom context menu
|
||||
$(window).contextmenu(function (e) {
|
||||
|
@ -61,11 +61,10 @@ define(function (require, exports, module) {
|
||||
EDITOR_MENU: "editor-context-menu",
|
||||
INLINE_EDITOR_MENU: "inline-editor-context-menu",
|
||||
PROJECT_MENU: "project-context-menu",
|
||||
WORKING_SET_MENU: "working-set-context-menu",
|
||||
WORKING_SET_SETTINGS_MENU: "working-set-settings-context-menu"
|
||||
WORKING_SET_CONTEXT_MENU: "workingset-context-menu",
|
||||
WORKING_SET_CONFIG_MENU: "workingset-configuration-menu"
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Brackets Application Menu Section Constants
|
||||
* It is preferred that plug-ins specify the location of new MenuItems
|
||||
@ -1176,6 +1175,10 @@ define(function (require, exports, module) {
|
||||
return cmenu;
|
||||
}
|
||||
|
||||
// Deprecated menu ids
|
||||
DeprecationWarning.deprecateConstant(ContextMenuIds, "WORKING_SET_MENU", "WORKING_SET_CONTEXT_MENU");
|
||||
DeprecationWarning.deprecateConstant(ContextMenuIds, "WORKING_SET_SETTINGS_MENU", "WORKING_SET_CONFIG_MENU");
|
||||
|
||||
// Define public API
|
||||
exports.AppMenuBar = AppMenuBar;
|
||||
exports.ContextMenuIds = ContextMenuIds;
|
||||
|
@ -227,7 +227,7 @@ define(function (require, exports, module) {
|
||||
*/
|
||||
Document.prototype._ensureMasterEditor = function () {
|
||||
if (!this._masterEditor) {
|
||||
EditorManager._createFullEditorForDocument(this);
|
||||
EditorManager._createUnattachedMasterEditor(this);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -34,8 +34,10 @@ define(function (require, exports, module) {
|
||||
var AppInit = require("utils/AppInit"),
|
||||
CommandManager = require("command/CommandManager"),
|
||||
Commands = require("command/Commands"),
|
||||
DeprecationWarning = require("utils/DeprecationWarning"),
|
||||
ProjectManager = require("project/ProjectManager"),
|
||||
DocumentManager = require("document/DocumentManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
EditorManager = require("editor/EditorManager"),
|
||||
FileSystem = require("filesystem/FileSystem"),
|
||||
FileSystemError = require("filesystem/FileSystemError"),
|
||||
@ -56,7 +58,8 @@ define(function (require, exports, module) {
|
||||
Inspector = require("LiveDevelopment/Inspector/Inspector"),
|
||||
Menus = require("command/Menus"),
|
||||
UrlParams = require("utils/UrlParams").UrlParams,
|
||||
StatusBar = require("widgets/StatusBar");
|
||||
StatusBar = require("widgets/StatusBar"),
|
||||
WorkspaceManager = require("view/WorkspaceManager");
|
||||
|
||||
/**
|
||||
* Handlers for commands related to document handling (opening, saving, etc.)
|
||||
@ -127,9 +130,13 @@ define(function (require, exports, module) {
|
||||
*/
|
||||
var handleFileSaveAs;
|
||||
|
||||
function updateTitle() {
|
||||
/**
|
||||
* Updates the title bar with new file title or dirty indicator
|
||||
* @private
|
||||
*/
|
||||
function _updateTitle() {
|
||||
var currentDoc = DocumentManager.getCurrentDocument(),
|
||||
currentlyViewedPath = EditorManager.getCurrentlyViewedPath(),
|
||||
currentlyViewedPath = MainViewManager.getCurrentlyViewedPath(MainViewManager.ACTIVE_PANE),
|
||||
windowTitle = brackets.config.app_title;
|
||||
|
||||
if (!brackets.nativeMenus) {
|
||||
@ -161,7 +168,7 @@ define(function (require, exports, module) {
|
||||
var newToolbarHeight = _$titleContainerToolbar.height();
|
||||
if (_lastToolbarHeight !== newToolbarHeight) {
|
||||
_lastToolbarHeight = newToolbarHeight;
|
||||
EditorManager.resizeEditor();
|
||||
WorkspaceManager.recomputeLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,7 +191,7 @@ define(function (require, exports, module) {
|
||||
/**
|
||||
* Returns a short title for a given document.
|
||||
*
|
||||
* @param {Document} doc
|
||||
* @param {Document} doc - the document to compute the short title for
|
||||
* @return {string} - a short title for doc.
|
||||
*/
|
||||
function _shortTitleForDocument(doc) {
|
||||
@ -200,36 +207,36 @@ define(function (require, exports, module) {
|
||||
}
|
||||
}
|
||||
|
||||
function updateDocumentTitle() {
|
||||
var newDocument = DocumentManager.getCurrentDocument();
|
||||
/**
|
||||
* Handles currentFileChange and filenameChanged events and updates the titlebar
|
||||
*/
|
||||
function handleCurrentFileChange() {
|
||||
var newFile = MainViewManager.getCurrentlyViewedFile(MainViewManager.ACTIVE_PANE);
|
||||
|
||||
// TODO: This timer is causing a "Recursive tests with the same name are not supported"
|
||||
// exception. This code should be removed (if not needed), or updated with a unique
|
||||
// timer name (if needed).
|
||||
// var perfTimerName = PerfUtils.markStart("DocumentCommandHandlers._onCurrentDocumentChange():\t" + (!newDocument || newDocument.file.fullPath));
|
||||
if (newFile) {
|
||||
var newDocument = DocumentManager.getOpenDocumentForPath(newFile.fullPath);
|
||||
|
||||
if (newDocument) {
|
||||
_currentTitlePath = _shortTitleForDocument(newDocument);
|
||||
} else {
|
||||
var currentlyViewedFilePath = EditorManager.getCurrentlyViewedPath();
|
||||
if (currentlyViewedFilePath) {
|
||||
_currentTitlePath = ProjectManager.makeProjectRelativeIfPossible(currentlyViewedFilePath);
|
||||
_currentTitlePath = ProjectManager.makeProjectRelativeIfPossible(newFile.fullPath);
|
||||
}
|
||||
} else {
|
||||
_currentTitlePath = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Update title text & "dirty dot" display
|
||||
updateTitle();
|
||||
|
||||
// PerfUtils.addMeasurement(perfTimerName);
|
||||
_updateTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles dirtyFlagChange event and updates the title bar if necessary
|
||||
*/
|
||||
function handleDirtyChange(event, changedDoc) {
|
||||
var currentDoc = DocumentManager.getCurrentDocument();
|
||||
|
||||
if (currentDoc && changedDoc.file.fullPath === currentDoc.file.fullPath) {
|
||||
updateTitle();
|
||||
_updateTitle();
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,37 +245,29 @@ define(function (require, exports, module) {
|
||||
* Creates a document and displays an editor for the specified file path.
|
||||
* @param {!string} fullPath
|
||||
* @param {boolean=} silent If true, don't show error message
|
||||
* @param {string=} paneId, the id oi the pane in which to open the file. Can be undefined, a valid pane id or ACTIVE_PANE.
|
||||
* @return {$.Promise} a jQuery promise that will either
|
||||
* - be resolved with a document for the specified file path or
|
||||
* - be resolved without document, i.e. when an image is displayed or
|
||||
* - be resolved with a file for the specified file path or
|
||||
* - be rejected if the file can not be read.
|
||||
* If paneId is undefined, the ACTIVE_PANE constant
|
||||
*/
|
||||
function doOpen(fullPath, silent) {
|
||||
function _doOpen(fullPath, silent, paneId) {
|
||||
var result = new $.Deferred();
|
||||
|
||||
// workaround for https://github.com/adobe/brackets/issues/6001
|
||||
// TODO should be removed once bug is closed.
|
||||
// if we are already displaying a file do nothing but resolve immediately.
|
||||
// this fixes timing issues in test cases.
|
||||
if (EditorManager.getCurrentlyViewedPath() === fullPath) {
|
||||
result.resolve(DocumentManager.getCurrentDocument());
|
||||
if (MainViewManager.getCurrentlyViewedPath(MainViewManager.ACTIVE_PANE) === fullPath) {
|
||||
result.resolve(MainViewManager.getCurrentlyViewedFile(MainViewManager.ACTIVE_PANE));
|
||||
return result.promise();
|
||||
}
|
||||
|
||||
function _cleanup(fullFilePath) {
|
||||
if (!fullFilePath || EditorManager.showingCustomViewerForPath(fullFilePath)) {
|
||||
// We get here only after the user renames a file that makes it no longer belong to a
|
||||
// custom viewer but the file is still showing in the current custom viewer. This only
|
||||
// occurs on Mac since opening a non-text file always fails on Mac and triggers an error
|
||||
// message that in turn calls _cleanup() after the user clicks OK in the message box.
|
||||
// So we need to explicitly close the currently viewing image file whose filename is
|
||||
// no longer valid. Calling notifyPathDeleted will close the image vieer and then select
|
||||
// the previously opened text file or show no-editor if none exists.
|
||||
EditorManager.notifyPathDeleted(fullFilePath);
|
||||
} else {
|
||||
// For performance, we do lazy checking of file existence, so it may be in working set
|
||||
DocumentManager.removeFromWorkingSet(FileSystem.getFileForPath(fullFilePath));
|
||||
EditorManager.focusEditor();
|
||||
if (fullFilePath) {
|
||||
// For performance, we do lazy checking of file existence, so it may be in workingset
|
||||
MainViewManager._removeView(paneId, FileSystem.getFileForPath(fullFilePath));
|
||||
MainViewManager.focusActivePane();
|
||||
}
|
||||
result.reject();
|
||||
}
|
||||
@ -283,7 +282,7 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
if (!fullPath) {
|
||||
console.error("doOpen() called without fullPath");
|
||||
console.error("_doOpen() called without fullPath");
|
||||
result.reject();
|
||||
} else {
|
||||
var perfTimerName = PerfUtils.markStart("Open File:\t" + fullPath);
|
||||
@ -291,31 +290,16 @@ define(function (require, exports, module) {
|
||||
PerfUtils.addMeasurement(perfTimerName);
|
||||
});
|
||||
|
||||
var viewProvider = EditorManager.getCustomViewerForPath(fullPath);
|
||||
if (viewProvider) {
|
||||
var file = FileSystem.getFileForPath(fullPath);
|
||||
file.exists(function (fileError, fileExists) {
|
||||
if (fileExists) {
|
||||
EditorManager._showCustomViewer(viewProvider, fullPath);
|
||||
result.resolve();
|
||||
} else {
|
||||
fileError = fileError || FileSystemError.NOT_FOUND;
|
||||
_showErrorAndCleanUp(fileError);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
// Load the file if it was never open before, and then switch to it in the UI
|
||||
DocumentManager.getDocumentForPath(fullPath)
|
||||
.done(function (doc) {
|
||||
DocumentManager.setCurrentDocument(doc);
|
||||
result.resolve(doc);
|
||||
MainViewManager._open(paneId, file)
|
||||
.done(function () {
|
||||
result.resolve(file);
|
||||
})
|
||||
.fail(function (fileError) {
|
||||
_showErrorAndCleanUp(fileError, fullPath);
|
||||
result.reject();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return result.promise();
|
||||
}
|
||||
@ -328,16 +312,17 @@ define(function (require, exports, module) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* Creates a document and displays an editor for the specified file path.
|
||||
* Opens a file and displays its view (editor, image view, etc...) for the specified path.
|
||||
* If no path is specified, a file prompt is provided for input.
|
||||
* @param {?string} fullPath - The path of the file to open; if it's null we'll prompt for it
|
||||
* @param {boolean=} silent - If true, don't show error message
|
||||
* @return {$.Promise} a jQuery promise that will be resolved with a new
|
||||
* document for the specified file path or be resolved without document, i.e. when an image is displayed,
|
||||
* or rejected if the file can not be read.
|
||||
* @param {string=} paneId - the pane in which to open the file. Can be undefined, a valid pane id or ACTIVE_PANE
|
||||
* @return {$.Promise} a jQuery promise resolved with a Document object or
|
||||
* rejected with an err
|
||||
*/
|
||||
function _doOpenWithOptionalPath(fullPath, silent) {
|
||||
function _doOpenWithOptionalPath(fullPath, silent, paneId) {
|
||||
var result;
|
||||
paneId = paneId || MainViewManager.ACTIVE_PANE;
|
||||
if (!fullPath) {
|
||||
// Create placeholder deferred
|
||||
result = new $.Deferred();
|
||||
@ -350,7 +335,7 @@ define(function (require, exports, module) {
|
||||
FileSystem.showOpenDialog(true, false, Strings.OPEN_FILE, _defaultOpenDialogFullPath, null, function (err, paths) {
|
||||
if (!err) {
|
||||
if (paths.length > 0) {
|
||||
// Add all files to the working set without verifying that
|
||||
// Add all files to the workingset without verifying that
|
||||
// they still exist on disk (for faster opening)
|
||||
var filesToOpen = [],
|
||||
filteredPaths = DragAndDrop.filterFilesToOpen(paths);
|
||||
@ -358,16 +343,14 @@ define(function (require, exports, module) {
|
||||
filteredPaths.forEach(function (file) {
|
||||
filesToOpen.push(FileSystem.getFileForPath(file));
|
||||
});
|
||||
DocumentManager.addListToWorkingSet(filesToOpen);
|
||||
MainViewManager.addListToWorkingSet(paneId, filesToOpen);
|
||||
|
||||
doOpen(filteredPaths[filteredPaths.length - 1], silent)
|
||||
.done(function (doc) {
|
||||
// doc may be null, i.e. if an image has been opened.
|
||||
// Then we do not add the opened file to the working set.
|
||||
if (doc) {
|
||||
DocumentManager.addToWorkingSet(doc.file);
|
||||
}
|
||||
_defaultOpenDialogFullPath = FileUtils.getDirectoryPath(EditorManager.getCurrentlyViewedPath());
|
||||
_doOpen(filteredPaths[filteredPaths.length - 1], silent, paneId)
|
||||
.done(function (file) {
|
||||
_defaultOpenDialogFullPath =
|
||||
FileUtils.getDirectoryPath(
|
||||
MainViewManager.getCurrentlyViewedPath(paneId)
|
||||
);
|
||||
})
|
||||
// Send the resulting document that was opened
|
||||
.then(result.resolve, result.reject);
|
||||
@ -378,7 +361,7 @@ define(function (require, exports, module) {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
result = doOpen(fullPath, silent);
|
||||
result = _doOpen(fullPath, silent, paneId);
|
||||
}
|
||||
|
||||
return result.promise();
|
||||
@ -410,28 +393,54 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the given file and makes it the current document. Does NOT add it to the working set.
|
||||
* @param {!{fullPath:string}} Params for FILE_OPEN command;
|
||||
* the fullPath string is of the form "path[:lineNumber[:columnNumber]]"
|
||||
* lineNumber and columnNumber are 1-origin: the very first line is line 1, and the very first column is column 1.
|
||||
* @typedef {{fullPath:?string=, silent:boolean=, paneId:string=}} FileCommandData
|
||||
* fullPath: is in the form "path[:lineNumber[:columnNumber]]"
|
||||
* lineNumber and columnNumber are 1-origin: lines and columns are 1-based
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {{fullPath:?string=, index:number=, silent:boolean=, forceRedraw:boolean=, paneId:string=}} PaneCommandData
|
||||
* fullPath: is in the form "path[:lineNumber[:columnNumber]]"
|
||||
* lineNumber and columnNumber are 1-origin: lines and columns are 1-based
|
||||
*/
|
||||
|
||||
/**
|
||||
* Opens the given file and makes it the current file. Does NOT add it to the workingset.
|
||||
* @param {FileCommandData=} commandData - record with the following properties:
|
||||
* fullPath: File to open;
|
||||
* silent: optional flag to suppress error messages;
|
||||
* paneId: optional PaneId (defaults to active pane)
|
||||
* @return {$.Promise} a jQuery promise that will be resolved with a file object
|
||||
*/
|
||||
function handleFileOpen(commandData) {
|
||||
var fileInfo = _parseDecoratedPath(commandData ? commandData.fullPath : null),
|
||||
silent = commandData ? commandData.silent : false;
|
||||
return _doOpenWithOptionalPath(fileInfo.path, silent)
|
||||
.always(function () {
|
||||
silent = (commandData && commandData.silent) || false,
|
||||
paneId = (commandData && commandData.paneId) || MainViewManager.ACTIVE_PANE,
|
||||
result = new $.Deferred();
|
||||
|
||||
_doOpenWithOptionalPath(fileInfo.path, silent, paneId)
|
||||
.done(function (file) {
|
||||
MainViewManager.setActivePaneId(paneId);
|
||||
|
||||
// If a line and column number were given, position the editor accordingly.
|
||||
if (fileInfo.line !== null) {
|
||||
if (fileInfo.column === null || (fileInfo.column <= 0)) {
|
||||
fileInfo.column = 1;
|
||||
}
|
||||
|
||||
// setCursorPos expects line/column numbers as 0-origin, so we subtract 1
|
||||
EditorManager.getCurrentFullEditor().setCursorPos(fileInfo.line - 1, fileInfo.column - 1, true);
|
||||
EditorManager.getCurrentFullEditor().setCursorPos(fileInfo.line - 1,
|
||||
fileInfo.column - 1,
|
||||
true);
|
||||
}
|
||||
|
||||
// Give the editor focus
|
||||
EditorManager.focusEditor();
|
||||
result.resolve(file);
|
||||
})
|
||||
.fail(function (err) {
|
||||
result.reject(err);
|
||||
});
|
||||
|
||||
return result;
|
||||
// Testing notes: here are some recommended manual tests for handleFileOpen, on macintosh.
|
||||
// Do all tests with brackets already running, and also with brackets not already running.
|
||||
//
|
||||
@ -446,20 +455,81 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the given file, makes it the current document, AND adds it to the working set
|
||||
* only if the file does not have a custom viewer.
|
||||
* @param {!{fullPath:string, index:number=, forceRedraw:boolean}} commandData File to open; optional position in
|
||||
* working set list (defaults to last); optional flag to force working set redraw
|
||||
* Opens the given file, makes it the current file, does NOT add it to the workingset
|
||||
* @param {FileCommandData} commandData
|
||||
* fullPath: File to open;
|
||||
* silent: optional flag to suppress error messages;
|
||||
* paneId: optional PaneId (defaults to active pane)
|
||||
* @return {$.Promise} a jQuery promise that will be resolved with @type {Document}
|
||||
*/
|
||||
function handleDocumentOpen(commandData) {
|
||||
var result = new $.Deferred();
|
||||
handleFileOpen(commandData)
|
||||
.done(function (file) {
|
||||
// if we succeeded with an open file
|
||||
// then we need to resolve that to a document.
|
||||
// getOpenDocumentForPath will return null if there isn't a
|
||||
// supporting document for that file (e.g. an image)
|
||||
var doc = DocumentManager.getOpenDocumentForPath(file.fullPath);
|
||||
result.resolve(doc);
|
||||
})
|
||||
.fail(function (err) {
|
||||
result.reject(err);
|
||||
});
|
||||
|
||||
return result.promise();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the given file, makes it the current file, AND adds it to the workingset
|
||||
* @param {!PaneCommandData} commandData - record with the following properties:
|
||||
* fullPath: File to open;
|
||||
* index: optional index to position in workingset (defaults to last);
|
||||
* silent: optional flag to suppress error messages;
|
||||
* forceRedraw: flag to force the working set view redraw;
|
||||
* paneId: optional PaneId (defaults to active pane)
|
||||
* @return {$.Promise} a jQuery promise that will be resolved with a @type {File}
|
||||
*/
|
||||
function handleFileAddToWorkingSetAndOpen(commandData) {
|
||||
return handleFileOpen(commandData).done(function (file) {
|
||||
var paneId = (commandData && commandData.paneId) || MainViewManager.ACTIVE_PANE;
|
||||
MainViewManager.addToWorkingSet(paneId, file, commandData.index, commandData.forceRedraw);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Opens the given file, makes it the current document, AND adds it to the workingset
|
||||
* @param {!PaneCommandData} commandData - record with the following properties:
|
||||
* fullPath: File to open;
|
||||
* index: optional index to position in workingset (defaults to last);
|
||||
* silent: optional flag to suppress error messages;
|
||||
* forceRedraw: flag to force the working set view redraw;
|
||||
* paneId: optional PaneId (defaults to active pane)
|
||||
* @return {$.Promise} a jQuery promise that will be resolved with @type {File}
|
||||
*/
|
||||
function handleFileAddToWorkingSet(commandData) {
|
||||
return handleFileOpen(commandData).done(function (doc) {
|
||||
// addToWorkingSet is synchronous
|
||||
// When opening a file with a custom viewer, we get a null doc.
|
||||
// So check it before we add it to the working set.
|
||||
if (doc) {
|
||||
DocumentManager.addToWorkingSet(doc.file, commandData.index, commandData.forceRedraw);
|
||||
}
|
||||
// This is a legacy deprecated command that
|
||||
// will use the new command and resolve with a document
|
||||
// as the legacy command would only support.
|
||||
DeprecationWarning.deprecationWarning("Commands.FILE_ADD_TO_WORKING_SET has been deprecated. Use Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN instead.");
|
||||
var result = new $.Deferred();
|
||||
|
||||
handleFileAddToWorkingSetAndOpen(commandData)
|
||||
.done(function (file) {
|
||||
// if we succeeded with an open file
|
||||
// then we need to resolve that to a document.
|
||||
// getOpenDocumentForPath will return null if there isn't a
|
||||
// supporting document for that file (e.g. an image)
|
||||
var doc = DocumentManager.getOpenDocumentForPath(file.fullPath);
|
||||
result.resolve(doc);
|
||||
})
|
||||
.fail(function (err) {
|
||||
result.reject(err);
|
||||
});
|
||||
|
||||
return result.promise();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -507,6 +577,8 @@ define(function (require, exports, module) {
|
||||
|
||||
/**
|
||||
* Bottleneck function for creating new files and folders in the project tree.
|
||||
* @private
|
||||
* @param {boolean} isFolder - true if creating a new folder, false if creating a new file
|
||||
*/
|
||||
function _handleNewItemInProject(isFolder) {
|
||||
if (fileNewInProgress) {
|
||||
@ -519,7 +591,7 @@ define(function (require, exports, module) {
|
||||
// If a file is currently selected in the tree, put it next to it.
|
||||
// If a directory is currently selected in the tree, put it in it.
|
||||
// If an Untitled document is selected or nothing is selected in the tree, put it at the root of the project.
|
||||
// (Note: 'selected' may be an item that's selected in the working set and not the tree; but in that case
|
||||
// (Note: 'selected' may be an item that's selected in the workingset and not the tree; but in that case
|
||||
// ProjectManager.createNewItem() ignores the baseDir we give it and falls back to the project root on its own)
|
||||
var baseDirEntry,
|
||||
selected = ProjectManager.getSelectedItem();
|
||||
@ -545,7 +617,7 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new untitled document in the working set, and make it the current document.
|
||||
* Create a new untitled document in the workingset, and make it the current document.
|
||||
* Promise is resolved (synchronously) with the newly-created Document.
|
||||
*/
|
||||
function handleFileNew() {
|
||||
@ -556,8 +628,7 @@ define(function (require, exports, module) {
|
||||
var defaultExtension = ""; // disable preference setting for now
|
||||
|
||||
var doc = DocumentManager.createUntitledDocument(_nextUntitledIndexToUse++, defaultExtension);
|
||||
DocumentManager.setCurrentDocument(doc);
|
||||
EditorManager.focusEditor();
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, doc);
|
||||
|
||||
return new $.Deferred().resolve(doc).promise();
|
||||
}
|
||||
@ -692,7 +763,7 @@ define(function (require, exports, module) {
|
||||
result.resolve(file);
|
||||
}
|
||||
result.always(function () {
|
||||
EditorManager.focusEditor();
|
||||
MainViewManager.focusActivePane();
|
||||
});
|
||||
return result.promise();
|
||||
}
|
||||
@ -700,6 +771,7 @@ define(function (require, exports, module) {
|
||||
/**
|
||||
* Reverts the Document to the current contents of its file on disk. Discards any unsaved changes
|
||||
* in the Document.
|
||||
* @private
|
||||
* @param {Document} doc
|
||||
* @param {boolean=} suppressError If true, then a failure to read the file will be ignored and the
|
||||
* resulting promise will be resolved rather than rejected.
|
||||
@ -707,7 +779,7 @@ define(function (require, exports, module) {
|
||||
* rejected with a FileSystemError if the file cannot be read (after showing an error
|
||||
* dialog to the user).
|
||||
*/
|
||||
function doRevert(doc, suppressError) {
|
||||
function _doRevert(doc, suppressError) {
|
||||
var result = new $.Deferred();
|
||||
|
||||
FileUtils.readAsText(doc.file)
|
||||
@ -763,21 +835,23 @@ define(function (require, exports, module) {
|
||||
result.resolve(newFile);
|
||||
}
|
||||
|
||||
// Replace old document with new one in open editor & working set
|
||||
// Replace old document with new one in open editor & workingset
|
||||
function openNewFile() {
|
||||
var fileOpenPromise;
|
||||
|
||||
if (FileViewController.getFileSelectionFocus() === FileViewController.PROJECT_MANAGER) {
|
||||
// If selection is in the tree, leave working set unchanged - even if orig file is in the list
|
||||
// If selection is in the tree, leave workingset unchanged - even if orig file is in the list
|
||||
fileOpenPromise = FileViewController
|
||||
.openAndSelectDocument(path, FileViewController.PROJECT_MANAGER);
|
||||
} else {
|
||||
// If selection is in working set, replace orig item in place with the new file
|
||||
var index = DocumentManager.findInWorkingSet(doc.file.fullPath);
|
||||
// Remove old file from working set; no redraw yet since there's a pause before the new file is opened
|
||||
DocumentManager.removeFromWorkingSet(doc.file, true);
|
||||
// Add new file to working set, and ensure we now redraw (even if index hasn't changed)
|
||||
fileOpenPromise = handleFileAddToWorkingSet({fullPath: path, index: index, forceRedraw: true});
|
||||
// If selection is in workingset, replace orig item in place with the new file
|
||||
var info = MainViewManager.findInAllWorkingSets(doc.file.fullPath).shift();
|
||||
|
||||
// Remove old file from workingset; no redraw yet since there's a pause before the new file is opened
|
||||
MainViewManager._removeView(info.paneId, doc.file, true);
|
||||
|
||||
// Add new file to workingset, and ensure we now redraw (even if index hasn't changed)
|
||||
fileOpenPromise = handleFileAddToWorkingSetAndOpen({fullPath: path, paneId: info.paneId, index: info.index, forceRedraw: true});
|
||||
}
|
||||
|
||||
// always configure editor after file is opened
|
||||
@ -805,12 +879,12 @@ define(function (require, exports, module) {
|
||||
.done(function () {
|
||||
// If there were unsaved changes before Save As, they don't stay with the old
|
||||
// file anymore - so must revert the old doc to match disk content.
|
||||
// Only do this if the doc was dirty: doRevert on a file that is not dirty and
|
||||
// not in the working set has the side effect of adding it to the working set.
|
||||
// Only do this if the doc was dirty: _doRevert on a file that is not dirty and
|
||||
// not in the workingset has the side effect of adding it to the workingset.
|
||||
if (doc.isDirty && !(doc.isUntitled())) {
|
||||
// if the file is dirty it must be in the working set
|
||||
// doRevert is side effect free in this case
|
||||
doRevert(doc).always(openNewFile);
|
||||
// if the file is dirty it must be in the workingset
|
||||
// _doRevert is side effect free in this case
|
||||
_doRevert(doc).always(openNewFile);
|
||||
} else {
|
||||
openNewFile();
|
||||
}
|
||||
@ -834,7 +908,11 @@ define(function (require, exports, module) {
|
||||
// (Issue #4489) if we're saving an untitled document, go ahead and switch to this document
|
||||
// in the editor, so that if we're, for example, saving several files (ie. Save All),
|
||||
// then the user can visually tell which document we're currently prompting them to save.
|
||||
DocumentManager.setCurrentDocument(doc);
|
||||
var info = MainViewManager.findInAllWorkingSets(origPath).shift();
|
||||
|
||||
if (info) {
|
||||
MainViewManager._open(info.paneId, doc.file);
|
||||
}
|
||||
|
||||
// If the document is untitled, default to project root.
|
||||
saveAsDefaultPath = ProjectManager.getProjectRoot().fullPath;
|
||||
@ -931,7 +1009,7 @@ define(function (require, exports, module) {
|
||||
});
|
||||
return savePromise;
|
||||
} else {
|
||||
// working set entry that was never actually opened - ignore
|
||||
// workingset entry that was never actually opened - ignore
|
||||
filesAfterSave.push(file);
|
||||
return (new $.Deferred()).resolve().promise();
|
||||
}
|
||||
@ -947,7 +1025,7 @@ define(function (require, exports, module) {
|
||||
* @return {$.Promise}
|
||||
*/
|
||||
function saveAll() {
|
||||
return _saveFileList(DocumentManager.getWorkingSet());
|
||||
return _saveFileList(MainViewManager.getWorkingSet(MainViewManager.ALL_PANES));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -986,7 +1064,7 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the specified file: removes it from the working set, and closes the main editor if one
|
||||
* Closes the specified file: removes it from the workingset, and closes the main editor if one
|
||||
* is open. Prompts user about saving changes first, if document is dirty.
|
||||
*
|
||||
* @param {?{file: File, promptOnly:boolean}} commandData Optional bag of arguments:
|
||||
@ -1002,58 +1080,28 @@ define(function (require, exports, module) {
|
||||
function handleFileClose(commandData) {
|
||||
var file,
|
||||
promptOnly,
|
||||
_forceClose;
|
||||
_forceClose,
|
||||
paneId = MainViewManager.ACTIVE_PANE;
|
||||
|
||||
if (commandData) {
|
||||
file = commandData.file;
|
||||
promptOnly = commandData.promptOnly;
|
||||
_forceClose = commandData._forceClose;
|
||||
paneId = commandData.paneId || paneId;
|
||||
}
|
||||
|
||||
// utility function for handleFileClose: closes document & removes from working set
|
||||
// utility function for handleFileClose: closes document & removes from workingset
|
||||
function doClose(file) {
|
||||
if (!promptOnly) {
|
||||
// This selects a different document if the working set has any other options
|
||||
DocumentManager.closeFullEditor(file);
|
||||
|
||||
EditorManager.focusEditor();
|
||||
MainViewManager._close(paneId, file);
|
||||
}
|
||||
}
|
||||
|
||||
var result = new $.Deferred(), promise = result.promise();
|
||||
|
||||
function doCloseCustomViewer() {
|
||||
if (!promptOnly) {
|
||||
var nextFile = DocumentManager.getNextPrevFile(1);
|
||||
if (nextFile) {
|
||||
// opening a text file will automatically close the custom viewer.
|
||||
// This is done in the currentDocumentChange handler in EditorManager
|
||||
doOpen(nextFile.fullPath).always(function () {
|
||||
EditorManager.focusEditor();
|
||||
result.resolve();
|
||||
});
|
||||
} else {
|
||||
EditorManager._closeCustomViewer();
|
||||
result.resolve();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close custom viewer if, either
|
||||
// - a custom viewer is currently displayed and no file specified in command data
|
||||
// - a custom viewer is currently displayed and the file specified in command data
|
||||
// is the file in the custom viewer
|
||||
if (!DocumentManager.getCurrentDocument()) {
|
||||
if ((EditorManager.getCurrentlyViewedPath() && !file) ||
|
||||
(file && file.fullPath === EditorManager.getCurrentlyViewedPath())) {
|
||||
doCloseCustomViewer();
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
|
||||
// Default to current document if doc is null
|
||||
if (!file && DocumentManager.getCurrentDocument()) {
|
||||
file = DocumentManager.getCurrentDocument().file;
|
||||
if (!file) {
|
||||
file = MainViewManager.getCurrentlyViewedFile(MainViewManager.ACTIVE_PANE);
|
||||
}
|
||||
|
||||
// No-op if called when nothing is open; TODO: (issue #273) should command be grayed out instead?
|
||||
@ -1123,30 +1171,30 @@ define(function (require, exports, module) {
|
||||
// we want to ignore errors during the revert, since we don't want a failed revert
|
||||
// to throw a dialog if the document isn't actually open in the UI.
|
||||
var suppressError = !DocumentManager.getOpenDocumentForPath(file.fullPath);
|
||||
doRevert(doc, suppressError)
|
||||
_doRevert(doc, suppressError)
|
||||
.then(result.resolve, result.reject);
|
||||
}
|
||||
}
|
||||
});
|
||||
result.always(function () {
|
||||
EditorManager.focusEditor();
|
||||
MainViewManager.focusActivePane();
|
||||
});
|
||||
} else {
|
||||
// File is not open, or IS open but Document not dirty: close immediately
|
||||
doClose(file);
|
||||
EditorManager.focusEditor();
|
||||
MainViewManager.focusActivePane();
|
||||
result.resolve();
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Array.<FileEntry>} list
|
||||
* @param {boolean} promptOnly
|
||||
* @param {boolean} clearCurrentDoc
|
||||
* @param {!Array.<File>} list - the list of files to close
|
||||
* @param {boolean} promptOnly - true to just prompt for saving documents with actually closing them.
|
||||
* @param {boolean} _forceClose Whether to force all the documents to close even if they have unsaved changes. For unit testing only.
|
||||
* @return {jQuery.Promise} promise that is resolved or rejected when the function finishes.
|
||||
*/
|
||||
function _closeList(list, promptOnly, clearCurrentDoc, _forceClose) {
|
||||
function _closeList(list, promptOnly, _forceClose) {
|
||||
var result = new $.Deferred(),
|
||||
unsavedDocs = [];
|
||||
|
||||
@ -1222,7 +1270,7 @@ define(function (require, exports, module) {
|
||||
result.done(function (listAfterSave) {
|
||||
listAfterSave = listAfterSave || list;
|
||||
if (!promptOnly) {
|
||||
DocumentManager.removeListFromWorkingSet(listAfterSave, clearCurrentDoc);
|
||||
MainViewManager._closeList(MainViewManager.ALL_PANES, listAfterSave);
|
||||
}
|
||||
});
|
||||
|
||||
@ -1230,7 +1278,7 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes all open documents; equivalent to calling handleFileClose() for each document, except
|
||||
* Closes all open files; equivalent to calling handleFileClose() for each document, except
|
||||
* that unsaved changes are confirmed once, in bulk.
|
||||
* @param {?{promptOnly: boolean, _forceClose: boolean}}
|
||||
* If promptOnly is true, only displays the relevant confirmation UI and does NOT
|
||||
@ -1241,20 +1289,24 @@ define(function (require, exports, module) {
|
||||
* @return {$.Promise} a promise that is resolved when all files are closed
|
||||
*/
|
||||
function handleFileCloseAll(commandData) {
|
||||
return _closeList(DocumentManager.getWorkingSet(),
|
||||
(commandData && commandData.promptOnly), true, (commandData && commandData._forceClose)).done(function () {
|
||||
if (!DocumentManager.getCurrentDocument()) {
|
||||
EditorManager._closeCustomViewer();
|
||||
}
|
||||
});
|
||||
return _closeList(MainViewManager.getAllOpenFiles(),
|
||||
(commandData && commandData.promptOnly), (commandData && commandData._forceClose));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes a list of open files; equivalent to calling handleFileClose() for each document, except
|
||||
* that unsaved changes are confirmed once, in bulk.
|
||||
* @param {?{promptOnly: boolean, _forceClose: boolean}}
|
||||
* If promptOnly is true, only displays the relevant confirmation UI and does NOT
|
||||
* actually close any documents. This is useful when chaining close-all together with
|
||||
* other user prompts that may be cancelable.
|
||||
* If _forceClose is true, forces the files to close with no confirmation even if dirty.
|
||||
* Should only be used for unit test cleanup.
|
||||
* @return {$.Promise} a promise that is resolved when all files are closed
|
||||
*/
|
||||
function handleFileCloseList(commandData) {
|
||||
return _closeList(commandData.fileList, false, false).done(function () {
|
||||
if (!DocumentManager.getCurrentDocument()) {
|
||||
EditorManager._closeCustomViewer();
|
||||
}
|
||||
});
|
||||
return _closeList(commandData.fileList);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1266,6 +1318,9 @@ define(function (require, exports, module) {
|
||||
* @private
|
||||
* Common implementation for close/quit/reload which all mostly
|
||||
* the same except for the final step
|
||||
* @param {Object} commandData - (not referenced)
|
||||
* @param {!function()} postCloseHandler - called after close
|
||||
* @param {!function()} failHandler - called when the save fails to cancel closing the window
|
||||
*/
|
||||
function _handleWindowGoingAway(commandData, postCloseHandler, failHandler) {
|
||||
if (_windowGoingAway) {
|
||||
@ -1313,7 +1368,10 @@ define(function (require, exports, module) {
|
||||
$(PopUpManager).triggerHandler("beforeMenuPopup");
|
||||
}
|
||||
|
||||
/** Confirms any unsaved changes, then closes the window */
|
||||
/**
|
||||
* Confirms any unsaved changes, then closes the window
|
||||
* @param {Object} command data
|
||||
*/
|
||||
function handleFileCloseWindow(commandData) {
|
||||
return _handleWindowGoingAway(
|
||||
commandData,
|
||||
@ -1332,9 +1390,8 @@ define(function (require, exports, module) {
|
||||
// Prefer selected sidebar item (which could be a folder)
|
||||
var entry = ProjectManager.getSelectedItem();
|
||||
if (!entry) {
|
||||
// Else use current file (not selected in ProjectManager if not visible in tree or working set)
|
||||
var doc = DocumentManager.getCurrentDocument();
|
||||
entry = doc && doc.file;
|
||||
// Else use current file (not selected in ProjectManager if not visible in tree or workingset)
|
||||
entry = MainViewManager.getCurrentlyViewedFile();
|
||||
}
|
||||
if (entry) {
|
||||
ProjectManager.renameItemInline(entry);
|
||||
@ -1368,8 +1425,7 @@ define(function (require, exports, module) {
|
||||
*/
|
||||
function detectDocumentNavEnd(event) {
|
||||
if (event.keyCode === KeyEvent.DOM_VK_CONTROL) { // Ctrl key
|
||||
DocumentManager.finalizeDocumentNavigation();
|
||||
|
||||
MainViewManager.endTraversal();
|
||||
_addedNavKeyHandler = false;
|
||||
$(window.document.body).off("keyup", detectDocumentNavEnd);
|
||||
}
|
||||
@ -1377,10 +1433,14 @@ define(function (require, exports, module) {
|
||||
|
||||
/** Navigate to the next/previous (MRU) document. Don't update MRU order yet */
|
||||
function goNextPrevDoc(inc) {
|
||||
var file = DocumentManager.getNextPrevFile(inc);
|
||||
if (file) {
|
||||
DocumentManager.beginDocumentNavigation();
|
||||
CommandManager.execute(Commands.FILE_OPEN, { fullPath: file.fullPath });
|
||||
var result = MainViewManager.traverseToNextViewByMRU(inc);
|
||||
if (result) {
|
||||
var file = result.file,
|
||||
paneId = result.paneId;
|
||||
|
||||
MainViewManager.beginTraversal();
|
||||
CommandManager.execute(Commands.FILE_OPEN, {fullPath: file.fullPath,
|
||||
paneId: paneId });
|
||||
|
||||
// Listen for ending of Ctrl+Tab sequence
|
||||
if (!_addedNavKeyHandler) {
|
||||
@ -1390,17 +1450,22 @@ define(function (require, exports, module) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Next Doc command handler **/
|
||||
function handleGoNextDoc() {
|
||||
goNextPrevDoc(+1);
|
||||
|
||||
}
|
||||
/** Previous Doc command handler **/
|
||||
function handleGoPrevDoc() {
|
||||
goNextPrevDoc(-1);
|
||||
}
|
||||
|
||||
/** Show in File Tree command handler **/
|
||||
function handleShowInTree() {
|
||||
ProjectManager.showInTree(DocumentManager.getCurrentDocument().file);
|
||||
ProjectManager.showInTree(MainViewManager.getCurrentlyViewedFile(MainViewManager.ACTIVE_PANE));
|
||||
}
|
||||
|
||||
/** Delete file command handler **/
|
||||
function handleFileDelete() {
|
||||
var entry = ProjectManager.getSelectedItem();
|
||||
if (entry.isDirectory) {
|
||||
@ -1434,7 +1499,7 @@ define(function (require, exports, module) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Show the selected sidebar (tree or working set) item in Finder/Explorer */
|
||||
/** Show the selected sidebar (tree or workingset) item in Finder/Explorer */
|
||||
function handleShowInOS() {
|
||||
var entry = ProjectManager.getSelectedItem();
|
||||
if (entry) {
|
||||
@ -1523,16 +1588,27 @@ define(function (require, exports, module) {
|
||||
});
|
||||
}
|
||||
|
||||
function handleReload() {
|
||||
/**
|
||||
* Restarts brackets Handler
|
||||
* @param {boolean=} loadWithoutExtensions - true to restart without extensions,
|
||||
* otherwise extensions are loadeed as it is durning a typical boot
|
||||
*/
|
||||
function handleReload(loadWithoutExtensions) {
|
||||
var href = window.location.href,
|
||||
params = new UrlParams();
|
||||
|
||||
// Make sure the Reload Without User Extensions parameter is removed
|
||||
params.parse();
|
||||
|
||||
if (loadWithoutExtensions) {
|
||||
if (!params.get("reloadWithoutUserExts")) {
|
||||
params.put("reloadWithoutUserExts", true);
|
||||
}
|
||||
} else {
|
||||
if (params.get("reloadWithoutUserExts")) {
|
||||
params.remove("reloadWithoutUserExts");
|
||||
}
|
||||
}
|
||||
|
||||
if (href.indexOf("?") !== -1) {
|
||||
href = href.substring(0, href.indexOf("?"));
|
||||
@ -1549,29 +1625,11 @@ define(function (require, exports, module) {
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function handleReloadWithoutExts() {
|
||||
var href = window.location.href,
|
||||
params = new UrlParams();
|
||||
|
||||
params.parse();
|
||||
|
||||
if (!params.get("reloadWithoutUserExts")) {
|
||||
params.put("reloadWithoutUserExts", true);
|
||||
}
|
||||
|
||||
if (href.indexOf("?") !== -1) {
|
||||
href = href.substring(0, href.indexOf("?"));
|
||||
}
|
||||
|
||||
href += "?" + params.toString();
|
||||
|
||||
// Give Mac native menus extra time to update shortcut highlighting.
|
||||
// Prevents the menu highlighting from getting messed up after reload.
|
||||
window.setTimeout(function () {
|
||||
browserReload(href);
|
||||
}, 100);
|
||||
}
|
||||
/** Reload Without Extensions commnad handler **/
|
||||
var handleReloadWithoutExts = _.partial(handleReload, true);
|
||||
|
||||
/** Do some initialization when the DOM is ready **/
|
||||
AppInit.htmlReady(function () {
|
||||
// If in Reload Without User Extensions mode, update UI and log console message
|
||||
var params = new UrlParams(),
|
||||
@ -1607,9 +1665,15 @@ define(function (require, exports, module) {
|
||||
showInOS = Strings.CMD_SHOW_IN_FINDER;
|
||||
}
|
||||
|
||||
// Register global commands
|
||||
CommandManager.register(Strings.CMD_FILE_OPEN, Commands.FILE_OPEN, handleFileOpen);
|
||||
CommandManager.register(Strings.CMD_ADD_TO_WORKING_SET, Commands.FILE_ADD_TO_WORKING_SET, handleFileAddToWorkingSet);
|
||||
// Deprecated commands
|
||||
CommandManager.register(Strings.CMD_ADD_TO_WORKINGSET_AND_OPEN, Commands.FILE_ADD_TO_WORKING_SET, handleFileAddToWorkingSet);
|
||||
CommandManager.register(Strings.CMD_FILE_OPEN, Commands.FILE_OPEN, handleDocumentOpen);
|
||||
|
||||
// New commands
|
||||
CommandManager.register(Strings.CMD_FILE_OPEN, Commands.CMD_OPEN, handleFileOpen);
|
||||
CommandManager.register(Strings.CMD_ADD_TO_WORKINGSET_AND_OPEN, Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, handleFileAddToWorkingSetAndOpen);
|
||||
|
||||
// File Commands
|
||||
CommandManager.register(Strings.CMD_FILE_NEW_UNTITLED, Commands.FILE_NEW_UNTITLED, handleFileNew);
|
||||
CommandManager.register(Strings.CMD_FILE_NEW, Commands.FILE_NEW, handleFileNewInProject);
|
||||
CommandManager.register(Strings.CMD_FILE_NEW_FOLDER, Commands.FILE_NEW_FOLDER, handleNewFolderInProject);
|
||||
@ -1619,15 +1683,19 @@ define(function (require, exports, module) {
|
||||
CommandManager.register(Strings.CMD_FILE_RENAME, Commands.FILE_RENAME, handleFileRename);
|
||||
CommandManager.register(Strings.CMD_FILE_DELETE, Commands.FILE_DELETE, handleFileDelete);
|
||||
|
||||
// Close Commands
|
||||
CommandManager.register(Strings.CMD_FILE_CLOSE, Commands.FILE_CLOSE, handleFileClose);
|
||||
CommandManager.register(Strings.CMD_FILE_CLOSE_ALL, Commands.FILE_CLOSE_ALL, handleFileCloseAll);
|
||||
CommandManager.register(Strings.CMD_FILE_CLOSE_LIST, Commands.FILE_CLOSE_LIST, handleFileCloseList);
|
||||
CommandManager.register(quitString, Commands.FILE_QUIT, handleFileQuit);
|
||||
|
||||
// Traversal
|
||||
CommandManager.register(Strings.CMD_NEXT_DOC, Commands.NAVIGATE_NEXT_DOC, handleGoNextDoc);
|
||||
CommandManager.register(Strings.CMD_PREV_DOC, Commands.NAVIGATE_PREV_DOC, handleGoPrevDoc);
|
||||
CommandManager.register(Strings.CMD_SHOW_IN_TREE, Commands.NAVIGATE_SHOW_IN_FILE_TREE, handleShowInTree);
|
||||
|
||||
// Special Commands
|
||||
CommandManager.register(showInOS, Commands.NAVIGATE_SHOW_IN_OS, handleShowInOS);
|
||||
CommandManager.register(quitString, Commands.FILE_QUIT, handleFileQuit);
|
||||
CommandManager.register(Strings.CMD_SHOW_IN_TREE, Commands.NAVIGATE_SHOW_IN_FILE_TREE, handleShowInTree);
|
||||
|
||||
// These commands have no UI representation and are only used internally
|
||||
CommandManager.registerInternal(Commands.APP_ABORT_QUIT, handleAbortQuit);
|
||||
@ -1638,8 +1706,8 @@ define(function (require, exports, module) {
|
||||
|
||||
// Listen for changes that require updating the editor titlebar
|
||||
$(DocumentManager).on("dirtyFlagChange", handleDirtyChange);
|
||||
$(DocumentManager).on("fileNameChange", updateDocumentTitle);
|
||||
$(EditorManager).on("currentlyViewedFileChange", updateDocumentTitle);
|
||||
$(DocumentManager).on("fileNameChange", handleCurrentFileChange);
|
||||
$(MainViewManager).on("currentFileChange", handleCurrentFileChange);
|
||||
|
||||
// Reset the untitled document counter before changing projects
|
||||
$(ProjectManager).on("beforeProjectClose", function () { _nextUntitledIndexToUse = 1; });
|
||||
|
@ -54,6 +54,8 @@
|
||||
* - optionChange -- Triggered when an option for the editor is changed. The 2nd arg to the listener
|
||||
* is a string containing the editor option that is changing. The 3rd arg, which can be any
|
||||
* data type, is the new value for the editor option.
|
||||
* - beforeDestroy - Triggered before the object is about to dispose of all its internal state data
|
||||
* so that listeners can cache things like scroll pos, etc...
|
||||
*
|
||||
* The Editor also dispatches "change" events internally, but you should listen for those on
|
||||
* Documents, not Editors.
|
||||
@ -194,7 +196,7 @@ define(function (require, exports, module) {
|
||||
* @param {!boolean} makeMasterEditor If true, this Editor will set itself as the (secret) "master"
|
||||
* Editor for the Document. If false, this Editor will attach to the Document as a "slave"/
|
||||
* secondary editor.
|
||||
* @param {!jQueryObject} container Container to add the editor to.
|
||||
* @param {!jQueryObject|DomNode} container Container to add the editor to.
|
||||
* @param {{startLine: number, endLine: number}=} range If specified, range of lines within the document
|
||||
* to display in this editor. Inclusive.
|
||||
*/
|
||||
@ -207,6 +209,13 @@ define(function (require, exports, module) {
|
||||
this.document = document;
|
||||
document.addRef();
|
||||
|
||||
if (container.jquery) {
|
||||
// CodeMirror wants a DOM element, not a jQuery wrapper
|
||||
container = container.get(0);
|
||||
}
|
||||
|
||||
var $container = $(container);
|
||||
|
||||
if (range) { // attach this first: want range updated before we process a change
|
||||
this._visibleRange = new TextRange(document, range.startLine, range.endLine);
|
||||
}
|
||||
@ -226,6 +235,7 @@ define(function (require, exports, module) {
|
||||
this._inlineWidgets = [];
|
||||
this._inlineWidgetQueues = {};
|
||||
this._hideMarks = [];
|
||||
this._lastEditorWidth = null;
|
||||
|
||||
this._$messagePopover = null;
|
||||
|
||||
@ -263,6 +273,13 @@ define(function (require, exports, module) {
|
||||
})
|
||||
);
|
||||
|
||||
// When panes are created *after* the showLineNumbers option has been turned off
|
||||
// we need to apply the show-line-padding class or the text will be juxtaposed
|
||||
// to the edge of the editor which makes it not easy to read. The code below to handle
|
||||
// that the option change only applies the class to panes that have already been created
|
||||
// This line ensures that the class is applied to any editor created after the fact
|
||||
$container.toggleClass("show-line-padding", Boolean(!this._getOption("showLineNumbers")));
|
||||
|
||||
// Create the CodeMirror instance
|
||||
// (note: CodeMirror doesn't actually require using 'new', but jslint complains without it)
|
||||
this._codeMirror = new CodeMirror(container, {
|
||||
@ -328,6 +345,13 @@ define(function (require, exports, module) {
|
||||
return this._codeMirror.getScrollInfo().top;
|
||||
}
|
||||
});
|
||||
|
||||
// Add an $el getter for Pane Views
|
||||
Object.defineProperty(this, "$el", {
|
||||
get: function () {
|
||||
return $(this.getRootElement());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -336,6 +360,8 @@ define(function (require, exports, module) {
|
||||
* a read-only string-backed mode.
|
||||
*/
|
||||
Editor.prototype.destroy = function () {
|
||||
$(this).triggerHandler("beforeDestroy", [this]);
|
||||
|
||||
// CodeMirror docs for getWrapperElement() say all you have to do is "Remove this from your
|
||||
// tree to delete an editor instance."
|
||||
$(this.getRootElement()).remove();
|
||||
@ -488,7 +514,6 @@ define(function (require, exports, module) {
|
||||
/**
|
||||
* @private
|
||||
* Handle Tab key press.
|
||||
* @param {!CodeMirror} instance CodeMirror instance.
|
||||
*/
|
||||
Editor.prototype._handleTabKey = function () {
|
||||
// Tab key handling is done as follows:
|
||||
@ -887,6 +912,15 @@ define(function (require, exports, module) {
|
||||
PerfUtils.addMeasurement(perfTimerName);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the file associated with this editor
|
||||
* This is a required Pane-View interface method
|
||||
* @return {!File} the file associated with this editor
|
||||
*/
|
||||
Editor.prototype.getFile = function () {
|
||||
return this.document.file;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the current cursor position within the editor.
|
||||
* @param {boolean} expandTabs If true, return the actual visual column number instead of the character offset in
|
||||
@ -896,7 +930,7 @@ define(function (require, exports, module) {
|
||||
* selection that moves when you press shift+arrow), or "anchor" (the
|
||||
* fixed side of the selection). Omitting the argument is the same as
|
||||
* passing "head". A {line, ch} object will be returned.)
|
||||
* @return !{line:number, ch:number}
|
||||
* @return {!{line:number, ch:number}}
|
||||
*/
|
||||
Editor.prototype.getCursorPos = function (expandTabs, which) {
|
||||
// Translate "start" and "end" to the official CM names (it actually
|
||||
@ -997,6 +1031,7 @@ define(function (require, exports, module) {
|
||||
this._codeMirror.setSize(width, height);
|
||||
};
|
||||
|
||||
/** @const */
|
||||
var CENTERING_MARGIN = 0.15;
|
||||
|
||||
/**
|
||||
@ -1365,6 +1400,7 @@ define(function (require, exports, module) {
|
||||
return this._codeMirror.getWrapperElement();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the lineSpace element within the editor (the container around the individual lines of code).
|
||||
* FUTURE: This is fairly CodeMirror-specific. Logic that depends on this may break if we switch
|
||||
@ -1384,6 +1420,15 @@ define(function (require, exports, module) {
|
||||
return { x: scrollInfo.left, y: scrollInfo.top };
|
||||
};
|
||||
|
||||
/**
|
||||
* Restores and adjusts the current scroll position of the editor.
|
||||
* @param {{x:number, y:number}} scrollPos - The x,y scroll position in pixels
|
||||
* @param {!number} heightDelta - The amount of delta H to apply to the scroll position
|
||||
*/
|
||||
Editor.prototype.adjustScrollPos = function (scrollPos, heightDelta) {
|
||||
this._codeMirror.scrollTo(scrollPos.x, scrollPos.y + heightDelta);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the current scroll position of the editor.
|
||||
* @param {number} x scrollLeft position in pixels
|
||||
@ -1490,8 +1535,6 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
if (!inlineWidget.closePromise) {
|
||||
var lineNum = this._getInlineWidgetLineNumber(inlineWidget);
|
||||
|
||||
// Remove the inline widget from our internal list immediately, so
|
||||
// everyone external to us knows it's essentially already gone. We
|
||||
// don't want to wait until it's done animating closed (but we do want
|
||||
@ -1585,6 +1628,22 @@ define(function (require, exports, module) {
|
||||
return this._inlineWidgets;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the currently focused inline widget, if any.
|
||||
* @return {?InlineWidget}
|
||||
*/
|
||||
Editor.prototype.getFocusedInlineWidget = function () {
|
||||
var result = null;
|
||||
|
||||
this.getInlineWidgets().forEach(function (widget) {
|
||||
if (widget.hasFocus()) {
|
||||
result = widget;
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Display temporary popover message at current cursor position. Display message above
|
||||
* cursor if space allows, otherwise below.
|
||||
@ -1595,7 +1654,6 @@ define(function (require, exports, module) {
|
||||
var arrowBelow, cursorPos, cursorCoord, popoverRect,
|
||||
top, left, clip, arrowCenter, arrowLeft,
|
||||
self = this,
|
||||
$editorHolder = $("#editor-holder"),
|
||||
POPOVER_MARGIN = 10,
|
||||
POPOVER_ARROW_HALF_WIDTH = 10,
|
||||
POPOVER_ARROW_HALF_BASE = POPOVER_ARROW_HALF_WIDTH + 3; // 3 is border radius
|
||||
@ -1667,7 +1725,7 @@ define(function (require, exports, module) {
|
||||
};
|
||||
|
||||
// See if popover is clipped on any side
|
||||
clip = ViewUtils.getElementClipSize($editorHolder, popoverRect);
|
||||
clip = ViewUtils.getElementClipSize($("#editor-holder"), popoverRect);
|
||||
|
||||
// Prevent horizontal clipping
|
||||
if (clip.left > 0) {
|
||||
@ -1821,6 +1879,40 @@ define(function (require, exports, module) {
|
||||
return this._focused;
|
||||
};
|
||||
|
||||
/*
|
||||
* @typedef {scrollPos:{x:number, y:number},Array.<{start:{line:number, ch:number},end:{line:number, ch:number}}>} EditorViewState
|
||||
*/
|
||||
|
||||
/*
|
||||
* returns the view state for the editor
|
||||
* @return {!EditorViewState}
|
||||
*/
|
||||
Editor.prototype.getViewState = function () {
|
||||
return {
|
||||
selections: this.getSelections(),
|
||||
scrollPos: this.getScrollPos()
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* Restores the view state
|
||||
* @param {!EditorViewState} viewState - the view state object to restore
|
||||
*/
|
||||
Editor.prototype.restoreViewState = function (viewState) {
|
||||
if (viewState.selection) {
|
||||
// We no longer write out single-selection, but there might be some view state
|
||||
// from an older version.
|
||||
this.setSelection(viewState.selection.start, viewState.selection.end);
|
||||
}
|
||||
if (viewState.selections) {
|
||||
this.setSelections(viewState.selections);
|
||||
}
|
||||
if (viewState.scrollPos) {
|
||||
this.setScrollPos(viewState.scrollPos.x, viewState.scrollPos.y);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Re-renders the editor UI
|
||||
* @param {boolean=} handleResize true if this is in response to resizing the editor. Default false.
|
||||
@ -1859,13 +1951,12 @@ define(function (require, exports, module) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows or hides the editor within its parent. Does not force its ancestors to
|
||||
* become visible.
|
||||
* View API Visibility Change Notification handler. This is also
|
||||
* called by the native "setVisible" API which refresh can be optimized
|
||||
* @param {boolean} show true to show the editor, false to hide it
|
||||
* @param {boolean} refresh true (default) to refresh the editor, false to skip refreshing it
|
||||
*/
|
||||
Editor.prototype.setVisible = function (show, refresh) {
|
||||
$(this.getRootElement()).css("display", (show ? "" : "none"));
|
||||
Editor.prototype.notifyVisibilityChange = function (show, refresh) {
|
||||
if (show && (refresh || refresh === undefined)) {
|
||||
this.refresh();
|
||||
}
|
||||
@ -1876,6 +1967,17 @@ define(function (require, exports, module) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows or hides the editor within its parent. Does not force its ancestors to
|
||||
* become visible.
|
||||
* @param {boolean} show true to show the editor, false to hide it
|
||||
* @param {boolean} refresh true (default) to refresh the editor, false to skip refreshing it
|
||||
*/
|
||||
Editor.prototype.setVisible = function (show, refresh) {
|
||||
this.$el.css("display", (show ? "" : "none"));
|
||||
this.notifyVisibilityChange(show, refresh);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the editor is fully visible--i.e., is in the DOM, all ancestors are
|
||||
* visible, and has a non-zero width/height.
|
||||
@ -1896,7 +1998,7 @@ define(function (require, exports, module) {
|
||||
* the start and end.
|
||||
* @return {?(Object|string)} Name of syntax-highlighting mode, or object containing a "name" property
|
||||
* naming the mode along with configuration options required by the mode.
|
||||
* See {@link LanguageManager#getLanguageForPath()} and {@link Language#getMode()}.
|
||||
* @see {@link LanguageManager#getLanguageForPath()} and {@link Language#getMode()}.
|
||||
*/
|
||||
Editor.prototype.getModeForRange = function (start, end, knownMixed) {
|
||||
var outerMode = this._codeMirror.getMode(),
|
||||
@ -1922,7 +2024,7 @@ define(function (require, exports, module) {
|
||||
*
|
||||
* @return {?(Object|string)} Name of syntax-highlighting mode, or object containing a "name" property
|
||||
* naming the mode along with configuration options required by the mode.
|
||||
* See {@link LanguageManager#getLanguageForPath()} and {@link Language#getMode()}.
|
||||
* @see {@link LanguageManager#getLanguageForPath()} and {@link Language#getMode()}.
|
||||
*/
|
||||
Editor.prototype.getModeForSelection = function () {
|
||||
// Check for mixed mode info
|
||||
@ -1964,6 +2066,10 @@ define(function (require, exports, module) {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* gets the language for the selection. (Javascript selected from an HTML document or CSS selected from an HTML document, etc...)
|
||||
* @return {!Language}
|
||||
*/
|
||||
Editor.prototype.getLanguageForSelection = function () {
|
||||
return this.document.getLanguage().getLanguageForMode(this.getModeForSelection());
|
||||
};
|
||||
@ -1983,6 +2089,16 @@ define(function (require, exports, module) {
|
||||
*/
|
||||
Editor.prototype.document = null;
|
||||
|
||||
|
||||
/**
|
||||
* The Editor's last known width.
|
||||
* Used in conjunction with updateLayout to recompute the layout
|
||||
* if the the parent container changes its size since our last layout update.
|
||||
* @type {?number}
|
||||
*/
|
||||
Editor.prototype._lastEditorWidth = null;
|
||||
|
||||
|
||||
/**
|
||||
* If true, we're in the middle of syncing to/from the Document. Used to ignore spurious change
|
||||
* events caused by us (vs. change events caused by others, which we need to pay attention to).
|
||||
@ -2089,6 +2205,38 @@ define(function (require, exports, module) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* resizes the editor to fill its parent container
|
||||
* should not be used on inline editors
|
||||
* @param {boolean=} forceRefresh - forces the editor to update its layout
|
||||
* even if it already matches the container's height / width
|
||||
*/
|
||||
Editor.prototype.updateLayout = function (forceRefresh) {
|
||||
var curRoot = this.getRootElement(),
|
||||
curWidth = $(curRoot).width(),
|
||||
$editorHolder = this.$el.parent(),
|
||||
editorAreaHt = $editorHolder.height();
|
||||
|
||||
if (!curRoot.style.height || $(curRoot).height() !== editorAreaHt) {
|
||||
// Call setSize() instead of $.height() to allow CodeMirror to
|
||||
// check for options like line wrapping
|
||||
this.setSize(null, editorAreaHt);
|
||||
if (forceRefresh === undefined) {
|
||||
forceRefresh = true;
|
||||
}
|
||||
} else if (curWidth !== this._lastEditorWidth) {
|
||||
if (forceRefresh === undefined) {
|
||||
forceRefresh = true;
|
||||
}
|
||||
}
|
||||
this._lastEditorWidth = curWidth;
|
||||
|
||||
if (forceRefresh) {
|
||||
this.refreshAll(forceRefresh);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Global settings that affect Editor instances that share the same preference locations
|
||||
|
||||
/**
|
||||
@ -2245,7 +2393,18 @@ define(function (require, exports, module) {
|
||||
* @param {boolean} showLinePadding
|
||||
*/
|
||||
Editor._toggleLinePadding = function (showLinePadding) {
|
||||
$("#editor-holder").toggleClass("show-line-padding", showLinePadding);
|
||||
// apply class to all pane DOM nodes
|
||||
var $holders = [];
|
||||
_instances.forEach(function (editor) {
|
||||
var $editorHolder = editor.$el.parent();
|
||||
if ($holders.indexOf($editorHolder) === -1) {
|
||||
$holders.push($editorHolder);
|
||||
}
|
||||
});
|
||||
|
||||
_.each($holders, function ($holder) {
|
||||
$holder.toggleClass("show-line-padding", Boolean(showLinePadding));
|
||||
});
|
||||
};
|
||||
|
||||
// Set up listeners for preference changes
|
||||
|
@ -37,6 +37,7 @@ define(function (require, exports, module) {
|
||||
AppInit = require("utils/AppInit"),
|
||||
DropdownButton = require("widgets/DropdownButton").DropdownButton,
|
||||
EditorManager = require("editor/EditorManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
Editor = require("editor/Editor").Editor,
|
||||
FileUtils = require("file/FileUtils"),
|
||||
KeyEvent = require("utils/KeyEvent"),
|
||||
@ -184,7 +185,7 @@ define(function (require, exports, module) {
|
||||
$indentWidthInput.off("blur keyup");
|
||||
|
||||
// restore focus to the editor
|
||||
EditorManager.focusEditor();
|
||||
MainViewManager.focusActivePane();
|
||||
|
||||
var valInt = parseInt(value, 10);
|
||||
if (Editor.getUseTabChar(fullPath)) {
|
||||
@ -260,10 +261,10 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
if (!current) {
|
||||
StatusBar.hide(); // calls resizeEditor() if needed
|
||||
StatusBar.hide();
|
||||
} else {
|
||||
var fullPath = current.document.file.fullPath;
|
||||
StatusBar.show(); // calls resizeEditor() if needed
|
||||
StatusBar.show();
|
||||
|
||||
$(current).on("cursorActivity.statusbar", _updateCursorInfo);
|
||||
$(current).on("optionChange.statusbar", function () {
|
||||
|
@ -28,62 +28,258 @@ define(function (require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
var DocumentManager = require("document/DocumentManager"),
|
||||
EditorManager = require("editor/EditorManager"),
|
||||
ImageHolderTemplate = require("text!htmlContent/image-holder.html"),
|
||||
PanelManager = require("view/PanelManager"),
|
||||
ImageViewTemplate = require("text!htmlContent/image-view.html"),
|
||||
ProjectManager = require("project/ProjectManager"),
|
||||
LanguageManager = require("language/LanguageManager"),
|
||||
MainViewFactory = require("view/MainViewFactory"),
|
||||
Strings = require("strings"),
|
||||
StringUtils = require("utils/StringUtils"),
|
||||
FileSystem = require("filesystem/FileSystem"),
|
||||
FileUtils = require("file/FileUtils");
|
||||
FileUtils = require("file/FileUtils"),
|
||||
_ = require("thirdparty/lodash");
|
||||
|
||||
var _naturalWidth = 0,
|
||||
_naturalHeight = 0,
|
||||
_scale = 100,
|
||||
_scaleDivInfo = null; // coordinates of hidden scale sticker
|
||||
|
||||
/** Update the scale element, i.e. on resize
|
||||
* @param {!string} currentWidth actual width of image in view
|
||||
var _viewers = {};
|
||||
|
||||
/**
|
||||
* ImageView objects are constructed when an image is opened
|
||||
* @see {@link Pane} for more information about where ImageViews are rendered
|
||||
*
|
||||
* @constructor
|
||||
* @param {!File} file - The image file object to render
|
||||
* @param {!jQuery} container - The container to render the image view in
|
||||
*/
|
||||
function _updateScale(currentWidth) {
|
||||
if (currentWidth && currentWidth < _naturalWidth) {
|
||||
_scale = currentWidth / _naturalWidth * 100;
|
||||
$("#img-scale").text(Math.floor(_scale) + "%")
|
||||
// Keep the position of the image scale div relative to the image.
|
||||
.css("left", $("#img-preview").position().left + 5)
|
||||
.show();
|
||||
} else {
|
||||
// Reset everything related to the image scale sticker before hiding it.
|
||||
_scale = 100;
|
||||
_scaleDivInfo = null;
|
||||
$("#img-scale").text("").hide();
|
||||
}
|
||||
}
|
||||
function ImageView(file, $container) {
|
||||
this.file = file;
|
||||
this.$el = $(Mustache.render(ImageViewTemplate, {fullPath: file.fullPath}));
|
||||
|
||||
function _hideGuidesAndTip() {
|
||||
$("#img-tip").hide();
|
||||
$(".img-guide").hide();
|
||||
}
|
||||
$container.append(this.$el);
|
||||
|
||||
/** handle editor resize event, i.e. update scale sticker */
|
||||
function _onEditorAreaResize() {
|
||||
_hideGuidesAndTip();
|
||||
_updateScale($("#img-preview").width());
|
||||
this._naturalWidth = 0;
|
||||
this._naturalHeight = 0;
|
||||
this._scale = 100; // 100%
|
||||
this._scaleDivInfo = null; // coordinates of hidden scale sticker
|
||||
|
||||
this.relPath = ProjectManager.makeProjectRelativeIfPossible(this.file.fullPath);
|
||||
|
||||
this.$imagePath = this.$el.find(".image-path");
|
||||
this.$imagePreview = this.$el.find(".image-preview");
|
||||
this.$imageData = this.$el.find(".image-data");
|
||||
|
||||
this.$image = this.$el.find(".image");
|
||||
this.$imageTip = this.$el.find(".image-tip");
|
||||
this.$imageGuides = this.$el.find(".image-guide");
|
||||
this.$imageScale = this.$el.find(".image-scale");
|
||||
this.$x_value = this.$el.find(".x-value");
|
||||
this.$y_value = this.$el.find(".y-value");
|
||||
this.$horzGuide = this.$el.find(".horz-guide");
|
||||
this.$vertGuide = this.$el.find(".vert-guide");
|
||||
|
||||
this.$imagePath.text(this.relPath).attr("title", this.relPath);
|
||||
this.$imagePreview.on("load", _.bind(this._onImageLoaded, this));
|
||||
|
||||
_viewers[file.fullPath] = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update file name if necessary
|
||||
* DocumentManger.fileNameChange handler - when an image is renamed, we must
|
||||
* update the view
|
||||
*
|
||||
* @param {jQuery.Event} e - event
|
||||
* @param {!string} oldPath - the name of the file that's changing changing
|
||||
* @param {!string} newPath - the name of the file that's changing changing
|
||||
* @private
|
||||
*/
|
||||
function _onFileNameChange(e, oldName, newName) {
|
||||
var oldRelPath = ProjectManager.makeProjectRelativeIfPossible(oldName),
|
||||
currentPath = $("#img-path").text();
|
||||
ImageView.prototype._onFilenameChange = function (e, oldPath, newPath) {
|
||||
/*
|
||||
* File objects are already updated when the event is triggered
|
||||
* so we just need to see if the file has the same path as our image
|
||||
*/
|
||||
if (this.file.fullPath === newPath) {
|
||||
this.relPath = ProjectManager.makeProjectRelativeIfPossible(newPath);
|
||||
this.$imagePath.text(this.relPath).attr("title", this.relPath);
|
||||
}
|
||||
};
|
||||
|
||||
if (currentPath === oldRelPath) {
|
||||
var newRelName = ProjectManager.makeProjectRelativeIfPossible(newName);
|
||||
$("#img-path").text(newRelName)
|
||||
.attr("title", newRelName);
|
||||
/**
|
||||
* <img>.on("load") handler - updates content of the image view
|
||||
* initializes computed values
|
||||
* installs event handlers
|
||||
* @param {Event} e - event
|
||||
* @private
|
||||
*/
|
||||
ImageView.prototype._onImageLoaded = function (e) {
|
||||
// add dimensions and size
|
||||
this._naturalWidth = e.currentTarget.naturalWidth;
|
||||
this._naturalHeight = e.currentTarget.naturalHeight;
|
||||
|
||||
var extension = FileUtils.getFileExtension(this.file.fullPath);
|
||||
var dimensionString = this._naturalWidth + " × " + this._naturalHeight + " " + Strings.UNIT_PIXELS;
|
||||
|
||||
if (extension === "ico") {
|
||||
dimensionString += " (" + Strings.IMAGE_VIEWER_LARGEST_ICON + ")";
|
||||
}
|
||||
|
||||
// get image size
|
||||
var self = this;
|
||||
|
||||
this.file.stat(function (err, stat) {
|
||||
if (err) {
|
||||
self.$imageData.html(dimensionString);
|
||||
} else {
|
||||
var sizeString = "";
|
||||
if (stat.size) {
|
||||
sizeString = " — " + StringUtils.prettyPrintBytes(stat.size, 2);
|
||||
}
|
||||
var dimensionAndSize = dimensionString + sizeString;
|
||||
self.$imageData.html(dimensionAndSize)
|
||||
.attr("title", dimensionAndSize
|
||||
.replace("×", "x")
|
||||
.replace("—", "-"));
|
||||
}
|
||||
});
|
||||
|
||||
// make sure we always show the right file name
|
||||
$(DocumentManager).on("fileNameChange", _.bind(this._onFilenameChange, this));
|
||||
|
||||
this.$imageTip.hide();
|
||||
this.$imageGuides.hide();
|
||||
|
||||
this.$image.on("mousemove.ImageView", ".image-preview", _.bind(this._showImageTip, this))
|
||||
.on("mouseleave.ImageView", ".image-preview", _.bind(this._hideImageTip, this));
|
||||
|
||||
this._updateScale();
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the scale element
|
||||
* @private
|
||||
*/
|
||||
ImageView.prototype._updateScale = function () {
|
||||
var currentWidth = this.$imagePreview.width();
|
||||
|
||||
if (currentWidth && currentWidth < this._naturalWidth) {
|
||||
this._scale = currentWidth / this._naturalWidth * 100;
|
||||
this.$imageScale.text(Math.floor(this._scale) + "%")
|
||||
// Keep the position of the image scale div relative to the image.
|
||||
.css("left", this.$imagePreview.position().left + 5)
|
||||
.show();
|
||||
} else {
|
||||
// Reset everything related to the image scale sticker before hiding it.
|
||||
this._scale = 100;
|
||||
this._scaleDivInfo = null;
|
||||
this.$imageScale.text("").hide();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show image coordinates under the mouse cursor
|
||||
* @param {Event} e - event
|
||||
* @private
|
||||
*/
|
||||
ImageView.prototype._showImageTip = function (e) {
|
||||
// Don't show image tip if this._scale is close to zero.
|
||||
// since we won't have enough room to show tip anyway.
|
||||
if (Math.floor(this._scale) === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var x = Math.round(e.offsetX * 100 / this._scale),
|
||||
y = Math.round(e.offsetY * 100 / this._scale),
|
||||
$target = $(e.target),
|
||||
imagePos = this.$imagePreview.position(),
|
||||
left = e.offsetX + imagePos.left,
|
||||
top = e.offsetY + imagePos.top,
|
||||
width = this.$imagePreview.width(),
|
||||
height = this.$imagePreview.height(),
|
||||
windowWidth = $(window).width(),
|
||||
fourDigitImageWidth = this._naturalWidth.toString().length === 4,
|
||||
|
||||
// @todo -- seems a bit strange that we're computing sizes
|
||||
// using magic numbers
|
||||
|
||||
infoWidth1 = 112, // info div width 96px + vertical toolbar width 16px
|
||||
infoWidth2 = 120, // info div width 104px (for 4-digit image width) + vertical toolbar width 16px
|
||||
tipOffsetX = 10, // adjustment for info div left from x coordinate of cursor
|
||||
tipOffsetY = -54, // adjustment for info div top from y coordinate of cursor
|
||||
tipMinusOffsetX1 = -82, // for less than 4-digit image width
|
||||
tipMinusOffsetX2 = -90; // for 4-digit image width
|
||||
|
||||
// Check whether we're getting mousemove events beyond the image boundaries due to a browser bug
|
||||
// or the rounding calculation above for a scaled image. For example, if an image is 120 px wide,
|
||||
// we should get mousemove events in the range of 0 <= x < 120, but not 120 or more. If we get
|
||||
// a value beyond the range, then simply handle the event as if it were a mouseleave.
|
||||
if (x < 0 || x >= this._naturalWidth || y < 0 || y >= this._naturalHeight) {
|
||||
this._hideImageTip(e);
|
||||
this.$imagePreview.css("cursor", "auto");
|
||||
return;
|
||||
}
|
||||
|
||||
this.$imagePreview.css("cursor", "none");
|
||||
|
||||
this._handleMouseEnterOrExitScaleSticker(left, top);
|
||||
|
||||
// Check whether to show the image tip on the left.
|
||||
if ((e.pageX + infoWidth1) > windowWidth ||
|
||||
(fourDigitImageWidth && (e.pageX + infoWidth2) > windowWidth)) {
|
||||
tipOffsetX = fourDigitImageWidth ? tipMinusOffsetX2 : tipMinusOffsetX1;
|
||||
}
|
||||
|
||||
this.$x_value.text(x + "px");
|
||||
this.$y_value.text(y + "px");
|
||||
|
||||
this.$imageTip.css({
|
||||
left: left + tipOffsetX,
|
||||
top: top + tipOffsetY
|
||||
}).show();
|
||||
|
||||
this.$horzGuide.css({
|
||||
left: imagePos.left,
|
||||
top: top,
|
||||
width: width - 1
|
||||
}).show();
|
||||
|
||||
this.$vertGuide.css({
|
||||
left: left,
|
||||
top: imagePos.top,
|
||||
height: height - 1
|
||||
}).show();
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide image coordinates info tip
|
||||
* @param {Event} e - event
|
||||
* @private
|
||||
*/
|
||||
ImageView.prototype._hideImageTip = function (e) {
|
||||
var $target = $(e.target),
|
||||
targetPos = $target.position(),
|
||||
imagePos = this.$imagePreview.position(),
|
||||
right = imagePos.left + this.$imagePreview.width(),
|
||||
bottom = imagePos.top + this.$imagePreview.height(),
|
||||
x = targetPos.left + e.offsetX,
|
||||
y = targetPos.top + e.offsetY;
|
||||
|
||||
// Hide image tip and guides only if the cursor is outside of the image.
|
||||
if (x < imagePos.left || x >= right ||
|
||||
y < imagePos.top || y >= bottom) {
|
||||
this._hideGuidesAndTip();
|
||||
if (this._scaleDivInfo) {
|
||||
this._scaleDivInfo = null;
|
||||
this.$imageScale.show();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Hides both guides and the tip
|
||||
* @private
|
||||
*/
|
||||
ImageView.prototype._hideGuidesAndTip = function () {
|
||||
this.$imageTip.hide();
|
||||
this.$imageGuides.hide();
|
||||
};
|
||||
|
||||
/**
|
||||
* Check mouse entering/exiting the scale sticker.
|
||||
@ -91,22 +287,23 @@ define(function (require, exports, module) {
|
||||
*
|
||||
* @param {number} offsetX mouse offset from the left of the previewing image
|
||||
* @param {number} offsetY mouseoffset from the top of the previewing image
|
||||
* @private
|
||||
*/
|
||||
function _handleMouseEnterOrExitScaleSticker(offsetX, offsetY) {
|
||||
var imagePos = $("#img-preview").position(),
|
||||
scaleDivPos = $("#img-scale").position(),
|
||||
imgWidth = $("#img-preview").width(),
|
||||
imgHeight = $("#img-preview").height(),
|
||||
ImageView.prototype._handleMouseEnterOrExitScaleSticker = function (offsetX, offsetY) {
|
||||
var imagePos = this.$imagePreview.position(),
|
||||
scaleDivPos = this.$imageScale.position(),
|
||||
imgWidth = this.$imagePreview.width(),
|
||||
imgHeight = this.$imagePreview.height(),
|
||||
scaleDivLeft,
|
||||
scaleDivTop,
|
||||
scaleDivRight,
|
||||
scaleDivBottom;
|
||||
|
||||
if (_scaleDivInfo) {
|
||||
scaleDivLeft = _scaleDivInfo.left;
|
||||
scaleDivTop = _scaleDivInfo.top;
|
||||
scaleDivRight = _scaleDivInfo.right;
|
||||
scaleDivBottom = _scaleDivInfo.bottom;
|
||||
if (this._scaleDivInfo) {
|
||||
scaleDivLeft = this._scaleDivInfo.left;
|
||||
scaleDivTop = this._scaleDivInfo.top;
|
||||
scaleDivRight = this._scaleDivInfo.right;
|
||||
scaleDivBottom = this._scaleDivInfo.bottom;
|
||||
|
||||
if ((imgWidth + imagePos.left) < scaleDivRight) {
|
||||
scaleDivRight = imgWidth + imagePos.left;
|
||||
@ -119,17 +316,17 @@ define(function (require, exports, module) {
|
||||
} else {
|
||||
scaleDivLeft = scaleDivPos.left;
|
||||
scaleDivTop = scaleDivPos.top;
|
||||
scaleDivRight = $("#img-scale").width() + scaleDivLeft;
|
||||
scaleDivBottom = $("#img-scale").height() + scaleDivTop;
|
||||
scaleDivRight = this.$imageScale.width() + scaleDivLeft;
|
||||
scaleDivBottom = this.$imageScale.height() + scaleDivTop;
|
||||
}
|
||||
|
||||
if (_scaleDivInfo) {
|
||||
if (this._scaleDivInfo) {
|
||||
// See whether the cursor is no longer inside the hidden scale div.
|
||||
// If so, show it again.
|
||||
if ((offsetX < scaleDivLeft || offsetX > scaleDivRight) ||
|
||||
(offsetY < scaleDivTop || offsetY > scaleDivBottom)) {
|
||||
_scaleDivInfo = null;
|
||||
$("#img-scale").show();
|
||||
this._scaleDivInfo = null;
|
||||
this.$imageScale.show();
|
||||
}
|
||||
} else if ((offsetX >= scaleDivLeft && offsetX <= scaleDivRight) &&
|
||||
(offsetY >= scaleDivTop && offsetY <= scaleDivBottom)) {
|
||||
@ -138,189 +335,143 @@ define(function (require, exports, module) {
|
||||
if (offsetX < (imagePos.left + imgWidth) &&
|
||||
offsetY < (imagePos.top + imgHeight)) {
|
||||
// Remember image scale div coordinates before hiding it.
|
||||
_scaleDivInfo = {left: scaleDivPos.left,
|
||||
this._scaleDivInfo = {left: scaleDivPos.left,
|
||||
top: scaleDivPos.top,
|
||||
right: scaleDivRight,
|
||||
bottom: scaleDivBottom};
|
||||
$("#img-scale").hide();
|
||||
}
|
||||
this.$imageScale.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide image coordinates info tip
|
||||
*
|
||||
* @param {MouseEvent} e mouse leave event
|
||||
* View Interface functions
|
||||
*/
|
||||
function _hideImageTip(e) {
|
||||
var $target = $(e.target),
|
||||
targetPos = $target.position(),
|
||||
imagePos = $("#img-preview").position(),
|
||||
right = imagePos.left + $("#img-preview").width(),
|
||||
bottom = imagePos.top + $("#img-preview").height(),
|
||||
x = targetPos.left + e.offsetX,
|
||||
y = targetPos.top + e.offsetY;
|
||||
|
||||
// Hide image tip and guides only if the cursor is outside of the image.
|
||||
if (x < imagePos.left || x >= right ||
|
||||
y < imagePos.top || y >= bottom) {
|
||||
_hideGuidesAndTip();
|
||||
if (_scaleDivInfo) {
|
||||
_scaleDivInfo = null;
|
||||
$("#img-scale").show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show image coordinates under the mouse cursor
|
||||
*
|
||||
* @param {MouseEvent} e mouse move event
|
||||
/*
|
||||
* Retrieves the file object for this view
|
||||
* return {!File} the file object for this view
|
||||
*/
|
||||
function _showImageTip(e) {
|
||||
// Don't show image tip if _scale is close to zero.
|
||||
// since we won't have enough room to show tip anyway.
|
||||
if (Math.floor(_scale) === 0) {
|
||||
return;
|
||||
}
|
||||
ImageView.prototype.getFile = function () {
|
||||
return this.file;
|
||||
};
|
||||
|
||||
var x = Math.round(e.offsetX * 100 / _scale),
|
||||
y = Math.round(e.offsetY * 100 / _scale),
|
||||
$target = $(e.target),
|
||||
imagePos = $("#img-preview").position(),
|
||||
left = e.offsetX + imagePos.left,
|
||||
top = e.offsetY + imagePos.top,
|
||||
width = $("#img-preview").width(),
|
||||
height = $("#img-preview").height(),
|
||||
windowWidth = $(window).width(),
|
||||
fourDigitImageWidth = _naturalWidth.toString().length === 4,
|
||||
infoWidth1 = 112, // info div width 96px + vertical toolbar width 16px
|
||||
infoWidth2 = 120, // info div width 104px (for 4-digit image width) + vertical toolbar width 16px
|
||||
tipOffsetX = 10, // adjustment for info div left from x coordinate of cursor
|
||||
tipOffsetY = -54, // adjustment for info div top from y coordinate of cursor
|
||||
tipMinusOffsetX1 = -82, // for less than 4-digit image width
|
||||
tipMinusOffsetX2 = -90; // for 4-digit image width
|
||||
|
||||
// Check whether we're getting mousemove events beyond the image boundaries due to a browser bug
|
||||
// or the rounding calculation above for a scaled image. For example, if an image is 120 px wide,
|
||||
// we should get mousemove events in the range of 0 <= x < 120, but not 120 or more. If we get
|
||||
// a value beyond the range, then simply handle the event as if it were a mouseleave.
|
||||
if (x < 0 || x >= _naturalWidth || y < 0 || y >= _naturalHeight) {
|
||||
_hideImageTip(e);
|
||||
$("#img-preview").css("cursor", "auto");
|
||||
return;
|
||||
}
|
||||
|
||||
$("#img-preview").css("cursor", "none");
|
||||
|
||||
_handleMouseEnterOrExitScaleSticker(left, top);
|
||||
|
||||
// Check whether to show the image tip on the left.
|
||||
if ((e.pageX + infoWidth1) > windowWidth ||
|
||||
(fourDigitImageWidth && (e.pageX + infoWidth2) > windowWidth)) {
|
||||
tipOffsetX = fourDigitImageWidth ? tipMinusOffsetX2 : tipMinusOffsetX1;
|
||||
}
|
||||
|
||||
$("#x-value").text(x + "px");
|
||||
$("#y-value").text(y + "px");
|
||||
|
||||
$("#img-tip").css({
|
||||
left: left + tipOffsetX,
|
||||
top: top + tipOffsetY
|
||||
}).show();
|
||||
|
||||
$("#horiz-guide").css({
|
||||
left: imagePos.left,
|
||||
top: top,
|
||||
width: width - 1
|
||||
}).show();
|
||||
|
||||
$("#vert-guide").css({
|
||||
left: left,
|
||||
top: imagePos.top,
|
||||
height: height - 1
|
||||
}).show();
|
||||
}
|
||||
|
||||
/**
|
||||
* sign off listeners when editor manager closes
|
||||
* the image viewer
|
||||
/*
|
||||
* Updates the layout of the view
|
||||
*/
|
||||
function onRemove() {
|
||||
$(PanelManager).off("editorAreaResize", _onEditorAreaResize);
|
||||
$(DocumentManager).off("fileNameChange", _onFileNameChange);
|
||||
$("#img").off("mousemove", "#img-preview", _showImageTip)
|
||||
.off("mouseleave", "#img-preview", _hideImageTip);
|
||||
}
|
||||
ImageView.prototype.updateLayout = function () {
|
||||
this._hideGuidesAndTip();
|
||||
|
||||
/**
|
||||
* Perform decorations on the view that require loading the image in the browser,
|
||||
* i.e. getting actual and natural width and height andplacing the scale sticker
|
||||
* @param {!string} fullPath Path to the image file
|
||||
* @param {!jQueryObject} $editorHolder The DOM element to append the view to.
|
||||
var $container = this.$el.parent();
|
||||
|
||||
var pos = $container.position(),
|
||||
iWidth = $container.innerWidth(),
|
||||
iHeight = $container.innerHeight(),
|
||||
oWidth = $container.outerWidth(),
|
||||
oHeight = $container.outerHeight();
|
||||
|
||||
// $view is "position:absolute" so
|
||||
// we have to update the height, width and position
|
||||
this.$el.css({top: pos.top + ((oHeight - iHeight) / 2),
|
||||
left: pos.left + ((oWidth - iWidth) / 2),
|
||||
width: iWidth,
|
||||
height: iHeight});
|
||||
this._updateScale();
|
||||
};
|
||||
|
||||
/*
|
||||
* Destroys the view
|
||||
*/
|
||||
function render(fullPath, $editorHolder) {
|
||||
var relPath = ProjectManager.makeProjectRelativeIfPossible(fullPath),
|
||||
$customViewer = $(Mustache.render(ImageHolderTemplate, {fullPath: fullPath}));
|
||||
ImageView.prototype.destroy = function () {
|
||||
delete _viewers[this.file.fullPath];
|
||||
$(DocumentManager).off("fileNameChange", _.bind(this._onFilenameChange, this));
|
||||
this.$image.off(".ImageView");
|
||||
this.$el.remove();
|
||||
};
|
||||
|
||||
// place DOM node to hold image
|
||||
$editorHolder.append($customViewer);
|
||||
/*
|
||||
* Refreshes the image preview with what's on disk
|
||||
*/
|
||||
ImageView.prototype.refresh = function () {
|
||||
var noCacheUrl = this.$imagePreview.attr("src"),
|
||||
now = new Date().valueOf();
|
||||
|
||||
_scale = 100; // initialize to 100
|
||||
_scaleDivInfo = null;
|
||||
|
||||
$("#img-path").text(relPath)
|
||||
.attr("title", relPath);
|
||||
$("#img-preview").on("load", function () {
|
||||
// add dimensions and size
|
||||
_naturalWidth = this.naturalWidth;
|
||||
_naturalHeight = this.naturalHeight;
|
||||
var ext = FileUtils.getFileExtension(fullPath);
|
||||
var dimensionString = _naturalWidth + " × " + this.naturalHeight + " " + Strings.UNIT_PIXELS;
|
||||
if (ext === "ico") {
|
||||
dimensionString += " (" + Strings.IMAGE_VIEWER_LARGEST_ICON + ")";
|
||||
}
|
||||
// get image size
|
||||
var file = FileSystem.getFileForPath(fullPath);
|
||||
file.stat(function (err, stat) {
|
||||
if (err) {
|
||||
$("#img-data").html(dimensionString);
|
||||
// Append a #<time-stamp> fragement to the URL
|
||||
// to force a reload of the image
|
||||
if (noCacheUrl.indexOf("#") > 0) {
|
||||
noCacheUrl = noCacheUrl.replace(/#\d+/, "#" + now);
|
||||
} else {
|
||||
var sizeString = "";
|
||||
if (stat.size) {
|
||||
sizeString = " — " + StringUtils.prettyPrintBytes(stat.size, 2);
|
||||
}
|
||||
var dimensionAndSize = dimensionString + sizeString;
|
||||
$("#img-data").html(dimensionAndSize)
|
||||
.attr("title", dimensionAndSize
|
||||
.replace("×", "x")
|
||||
.replace("—", "-"));
|
||||
}
|
||||
});
|
||||
$("#image-holder").show();
|
||||
|
||||
// listen to resize to update the scale sticker
|
||||
$(PanelManager).on("editorAreaResize", _onEditorAreaResize);
|
||||
|
||||
// make sure we always show the right file name
|
||||
$(DocumentManager).on("fileNameChange", _onFileNameChange);
|
||||
|
||||
$("#img-tip").hide();
|
||||
$(".img-guide").hide();
|
||||
$("#img").on("mousemove", "#img-preview", _showImageTip)
|
||||
.on("mouseleave", "#img-preview", _hideImageTip);
|
||||
|
||||
_updateScale($(this).width());
|
||||
|
||||
});
|
||||
return $customViewer;
|
||||
noCacheUrl = noCacheUrl + "#" + now;
|
||||
}
|
||||
|
||||
EditorManager.registerCustomViewer("image", {
|
||||
render: render,
|
||||
onRemove: onRemove
|
||||
// Update the DOM node with the src URL
|
||||
this.$imagePreview.attr("src", noCacheUrl);
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates an image view object and adds it to the specified pane
|
||||
* @param {!File} file - the file to create an image of
|
||||
* @param {!Pane} pane - the pane in which to host the view
|
||||
* @return {jQuery.Promise}
|
||||
*/
|
||||
function _createImageView(file, pane) {
|
||||
var view = pane.getViewForPath(file.fullPath);
|
||||
|
||||
if (view) {
|
||||
pane.showView(view);
|
||||
} else {
|
||||
view = new ImageView(file, pane.$el);
|
||||
pane.addView(view, true);
|
||||
}
|
||||
return new $.Deferred().resolve().promise();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles file system change events so we can refresh
|
||||
* image viewers for the files that changed on disk due to external editors
|
||||
* @param {jQuery.event} event - event object
|
||||
* @param {?File} file - file object that changed
|
||||
* @param {Array.<FileSystemEntry>=} added If entry is a Directory, contains zero or more added children
|
||||
* @param {Array.<FileSystemEntry>=} removed If entry is a Directory, contains zero or more removed children
|
||||
*/
|
||||
function _handleFileSystemChange(event, entry, added, removed) {
|
||||
// this may have been called because files were added
|
||||
// or removed to the file system. We don't care about those
|
||||
if (!entry || entry.isDirectory) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Look for a viewer for the changed file
|
||||
var viewer = _viewers[entry.fullPath];
|
||||
|
||||
// viewer found, call its refresh method
|
||||
if (viewer) {
|
||||
viewer.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Install an event listener to receive all file system change events
|
||||
* so we can refresh the view when changes are made to the image in an external editor
|
||||
*/
|
||||
FileSystem.on("change", _handleFileSystemChange);
|
||||
|
||||
/*
|
||||
* Initialization, register our view factory
|
||||
*/
|
||||
MainViewFactory.registerViewFactory({
|
||||
canOpenFile: function (fullPath) {
|
||||
var lang = LanguageManager.getLanguageForPath(fullPath);
|
||||
return (lang.getId() === "image");
|
||||
},
|
||||
openFile: function (file, pane) {
|
||||
return _createImageView(file, pane);
|
||||
}
|
||||
});
|
||||
|
||||
exports.render = render;
|
||||
exports.onRemove = onRemove;
|
||||
/*
|
||||
* This is for extensions that want to create a
|
||||
* view factory based on ImageViewer
|
||||
*/
|
||||
exports.ImageView = ImageView;
|
||||
});
|
||||
|
@ -38,14 +38,6 @@ define(function (require, exports, module) {
|
||||
InlineWidget = require("editor/InlineWidget").InlineWidget,
|
||||
KeyEvent = require("utils/KeyEvent");
|
||||
|
||||
/**
|
||||
* Returns editor holder width (not CodeMirror's width).
|
||||
* @private
|
||||
*/
|
||||
function _editorHolderWidth() {
|
||||
return $("#editor-holder").width();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows or hides the dirty indicator
|
||||
* @private
|
||||
|
@ -31,8 +31,9 @@ define(function (require, exports, module) {
|
||||
CommandManager = brackets.getModule("command/CommandManager"),
|
||||
Commands = brackets.getModule("command/Commands"),
|
||||
DocumentManager = brackets.getModule("document/DocumentManager"),
|
||||
MainViewManager = brackets.getModule("view/MainViewManager"),
|
||||
Strings = brackets.getModule("strings"),
|
||||
workingSetCmenu = Menus.getContextMenu(Menus.ContextMenuIds.WORKING_SET_MENU),
|
||||
workingSetListCmenu = Menus.getContextMenu(Menus.ContextMenuIds.WORKING_SET_CONTEXT_MENU),
|
||||
PreferencesManager = brackets.getModule("preferences/PreferencesManager");
|
||||
|
||||
// Constants
|
||||
@ -54,20 +55,17 @@ define(function (require, exports, module) {
|
||||
* @param {string} mode
|
||||
*/
|
||||
function handleClose(mode) {
|
||||
var targetIndex = DocumentManager.findInWorkingSet(DocumentManager.getCurrentDocument().file.fullPath),
|
||||
workingSet = DocumentManager.getWorkingSet().slice(0),
|
||||
var targetIndex = MainViewManager.findInWorkingSet(MainViewManager.ACTIVE_PANE, MainViewManager.getCurrentlyViewedPath(MainViewManager.ACTIVE_PANE)),
|
||||
workingSetList = MainViewManager.getWorkingSet(MainViewManager.ACTIVE_PANE),
|
||||
start = (mode === closeBelow) ? (targetIndex + 1) : 0,
|
||||
end = (mode === closeAbove) ? (targetIndex) : (workingSet.length),
|
||||
end = (mode === closeAbove) ? (targetIndex) : (workingSetList.length),
|
||||
files = [],
|
||||
i;
|
||||
|
||||
if (mode === closeOthers) {
|
||||
end--;
|
||||
workingSet.splice(targetIndex, 1);
|
||||
}
|
||||
|
||||
for (i = start; i < end; i++) {
|
||||
files.push(workingSet[i]);
|
||||
if ((mode === closeOthers && i !== targetIndex) || (mode !== closeOthers)) {
|
||||
files.push(workingSetList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
CommandManager.execute(Commands.FILE_CLOSE_LIST, {fileList: files});
|
||||
@ -77,25 +75,25 @@ define(function (require, exports, module) {
|
||||
* Enable/Disable the menu items depending on which document is selected in the working set
|
||||
*/
|
||||
function contextMenuOpenHandler() {
|
||||
var doc = DocumentManager.getCurrentDocument();
|
||||
var file = MainViewManager.getCurrentlyViewedFile(MainViewManager.ACTIVE_PANE);
|
||||
|
||||
if (doc) {
|
||||
var docIndex = DocumentManager.findInWorkingSet(doc.file.fullPath),
|
||||
workingSet = DocumentManager.getWorkingSet().slice(0);
|
||||
if (file) {
|
||||
var targetIndex = MainViewManager.findInWorkingSet(MainViewManager.ACTIVE_PANE, file.fullPath),
|
||||
workingSetListSize = MainViewManager.getWorkingSetSize(MainViewManager.ACTIVE_PANE);
|
||||
|
||||
if (docIndex === workingSet.length - 1) { // hide "Close Others Below" if the last file in Working Files is selected
|
||||
if (targetIndex === workingSetListSize - 1) { // hide "Close Others Below" if the last file in Working Files is selected
|
||||
CommandManager.get(closeBelow).setEnabled(false);
|
||||
} else {
|
||||
CommandManager.get(closeBelow).setEnabled(true);
|
||||
}
|
||||
|
||||
if (workingSet.length === 1) { // hide "Close Others" if there is only one file in Working Files
|
||||
if (workingSetListSize === 1) { // hide "Close Others" if there is only one file in Working Files
|
||||
CommandManager.get(closeOthers).setEnabled(false);
|
||||
} else {
|
||||
CommandManager.get(closeOthers).setEnabled(true);
|
||||
}
|
||||
|
||||
if (docIndex === 0) { // hide "Close Others Above" if the first file in Working Files is selected
|
||||
if (targetIndex === 0) { // hide "Close Others Above" if the first file in Working Files is selected
|
||||
CommandManager.get(closeAbove).setEnabled(false);
|
||||
} else {
|
||||
CommandManager.get(closeAbove).setEnabled(true);
|
||||
@ -126,25 +124,25 @@ define(function (require, exports, module) {
|
||||
|
||||
if (prefs.closeBelow !== menuEntriesShown.closeBelow) {
|
||||
if (prefs.closeBelow) {
|
||||
workingSetCmenu.addMenuItem(closeBelow, "", Menus.AFTER, Commands.FILE_CLOSE);
|
||||
workingSetListCmenu.addMenuItem(closeBelow, "", Menus.AFTER, Commands.FILE_CLOSE);
|
||||
} else {
|
||||
workingSetCmenu.removeMenuItem(closeBelow);
|
||||
workingSetListCmenu.removeMenuItem(closeBelow);
|
||||
}
|
||||
}
|
||||
|
||||
if (prefs.closeOthers !== menuEntriesShown.closeOthers) {
|
||||
if (prefs.closeOthers) {
|
||||
workingSetCmenu.addMenuItem(closeOthers, "", Menus.AFTER, Commands.FILE_CLOSE);
|
||||
workingSetListCmenu.addMenuItem(closeOthers, "", Menus.AFTER, Commands.FILE_CLOSE);
|
||||
} else {
|
||||
workingSetCmenu.removeMenuItem(closeOthers);
|
||||
workingSetListCmenu.removeMenuItem(closeOthers);
|
||||
}
|
||||
}
|
||||
|
||||
if (prefs.closeAbove !== menuEntriesShown.closeAbove) {
|
||||
if (prefs.closeAbove) {
|
||||
workingSetCmenu.addMenuItem(closeAbove, "", Menus.AFTER, Commands.FILE_CLOSE);
|
||||
workingSetListCmenu.addMenuItem(closeAbove, "", Menus.AFTER, Commands.FILE_CLOSE);
|
||||
} else {
|
||||
workingSetCmenu.removeMenuItem(closeAbove);
|
||||
workingSetListCmenu.removeMenuItem(closeAbove);
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,13 +166,13 @@ define(function (require, exports, module) {
|
||||
});
|
||||
|
||||
if (prefs.closeBelow) {
|
||||
workingSetCmenu.addMenuItem(closeBelow, "", Menus.AFTER, Commands.FILE_CLOSE);
|
||||
workingSetListCmenu.addMenuItem(closeBelow, "", Menus.AFTER, Commands.FILE_CLOSE);
|
||||
}
|
||||
if (prefs.closeOthers) {
|
||||
workingSetCmenu.addMenuItem(closeOthers, "", Menus.AFTER, Commands.FILE_CLOSE);
|
||||
workingSetListCmenu.addMenuItem(closeOthers, "", Menus.AFTER, Commands.FILE_CLOSE);
|
||||
}
|
||||
if (prefs.closeAbove) {
|
||||
workingSetCmenu.addMenuItem(closeAbove, "", Menus.AFTER, Commands.FILE_CLOSE);
|
||||
workingSetListCmenu.addMenuItem(closeAbove, "", Menus.AFTER, Commands.FILE_CLOSE);
|
||||
}
|
||||
menuEntriesShown = prefs;
|
||||
}
|
||||
@ -184,7 +182,7 @@ define(function (require, exports, module) {
|
||||
initializeCommands();
|
||||
|
||||
// Add a context menu open handler
|
||||
$(workingSetCmenu).on("beforeContextMenuOpen", contextMenuOpenHandler);
|
||||
$(workingSetListCmenu).on("beforeContextMenuOpen", contextMenuOpenHandler);
|
||||
|
||||
prefs.on("change", prefChangeHandler);
|
||||
});
|
||||
|
@ -34,6 +34,7 @@ define(function (require, exports, module) {
|
||||
Dialogs,
|
||||
EditorManager,
|
||||
DocumentManager,
|
||||
MainViewManager,
|
||||
FileSystem;
|
||||
|
||||
describe("CloseOthers", function () {
|
||||
@ -86,6 +87,7 @@ define(function (require, exports, module) {
|
||||
$ = testWindow.$;
|
||||
brackets = testWindow.brackets;
|
||||
DocumentManager = testWindow.brackets.test.DocumentManager;
|
||||
MainViewManager = testWindow.brackets.test.MainViewManager;
|
||||
CommandManager = testWindow.brackets.test.CommandManager;
|
||||
EditorManager = testWindow.brackets.test.EditorManager;
|
||||
Dialogs = testWindow.brackets.test.Dialogs;
|
||||
@ -127,16 +129,21 @@ define(function (require, exports, module) {
|
||||
|
||||
|
||||
function runCloseOthers() {
|
||||
var ws = DocumentManager.getWorkingSet(),
|
||||
var ws = MainViewManager.getWorkingSet(MainViewManager.ACTIVE_PANE),
|
||||
promise;
|
||||
|
||||
if (ws.length > docSelectIndex) {
|
||||
DocumentManager.getDocumentForPath(ws[docSelectIndex].fullPath).done(function (doc) {
|
||||
DocumentManager.setCurrentDocument(doc);
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, doc);
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
promise = CommandManager.execute(cmdToRun);
|
||||
waitsForDone(promise, cmdToRun);
|
||||
});
|
||||
runs(function () {
|
||||
expect(MainViewManager.getCurrentlyViewedPath(MainViewManager.ACTIVE_PANE)).toEqual(ws[docSelectIndex].fullPath, "Path of document in editor after close others command should be the document that was selected");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,10 +151,10 @@ define(function (require, exports, module) {
|
||||
docSelectIndex = 2;
|
||||
cmdToRun = "file.close_others";
|
||||
|
||||
runs(runCloseOthers);
|
||||
runCloseOthers();
|
||||
|
||||
runs(function () {
|
||||
expect(DocumentManager.getWorkingSet().length).toEqual(1);
|
||||
expect(MainViewManager.getWorkingSet(MainViewManager.ACTIVE_PANE).length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
@ -155,10 +162,10 @@ define(function (require, exports, module) {
|
||||
docSelectIndex = 2;
|
||||
cmdToRun = "file.close_above";
|
||||
|
||||
runs(runCloseOthers);
|
||||
runCloseOthers();
|
||||
|
||||
runs(function () {
|
||||
expect(DocumentManager.getWorkingSet().length).toEqual(3);
|
||||
expect(MainViewManager.getWorkingSet(MainViewManager.ACTIVE_PANE).length).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
@ -166,10 +173,10 @@ define(function (require, exports, module) {
|
||||
docSelectIndex = 1;
|
||||
cmdToRun = "file.close_below";
|
||||
|
||||
runs(runCloseOthers);
|
||||
runCloseOthers();
|
||||
|
||||
runs(function () {
|
||||
expect(DocumentManager.getWorkingSet().length).toEqual(2);
|
||||
expect(MainViewManager.getWorkingSet(MainViewManager.ACTIVE_PANE).length).toEqual(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -159,11 +159,11 @@
|
||||
|
||||
/* Non-editor styling */
|
||||
|
||||
#image-holder,
|
||||
#not-editor {
|
||||
.image-view,
|
||||
.not-editor {
|
||||
background-color: @background;
|
||||
}
|
||||
|
||||
#image-holder {
|
||||
.view-pane .image-view {
|
||||
color: @foreground;
|
||||
}
|
||||
|
@ -549,7 +549,7 @@ define(function (require, exports, module) {
|
||||
*
|
||||
* @param {Array} hints - array of hints
|
||||
* @param {StringMatcher} matcher
|
||||
* @returns {Array} - array of matching hints.
|
||||
* @return {Array} - array of matching hints.
|
||||
*/
|
||||
function filterWithQueryAndMatcher(hints, matcher) {
|
||||
var matchResults = $.map(hints, function (hint) {
|
||||
|
@ -29,6 +29,7 @@ define(function (require, exports, module) {
|
||||
|
||||
var Commands = brackets.getModule("command/Commands"),
|
||||
CommandManager = brackets.getModule("command/CommandManager"),
|
||||
MainViewManager = brackets.getModule("view/MainViewManager"),
|
||||
DocumentManager = brackets.getModule("document/DocumentManager"),
|
||||
Editor = brackets.getModule("editor/Editor").Editor,
|
||||
EditorManager = brackets.getModule("editor/EditorManager"),
|
||||
@ -54,7 +55,7 @@ define(function (require, exports, module) {
|
||||
CommandManager.register("test-file-open", Commands.FILE_OPEN, function (fileInfo) {
|
||||
// Register a command for FILE_OPEN, which the jump to def code will call
|
||||
return DocumentManager.getDocumentForPath(fileInfo.fullPath).done(function (doc) {
|
||||
DocumentManager.setCurrentDocument(doc);
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, doc);
|
||||
});
|
||||
});
|
||||
|
||||
@ -440,7 +441,7 @@ define(function (require, exports, module) {
|
||||
|
||||
// The following call ensures that the document is reloaded
|
||||
// from disk before each test
|
||||
DocumentManager.closeAll();
|
||||
MainViewManager._closeAll(MainViewManager.ALL_PANES);
|
||||
SpecRunnerUtils.destroyMockEditor(testDoc);
|
||||
testEditor = null;
|
||||
testDoc = null;
|
||||
|
@ -74,12 +74,12 @@ define(function (require, exports, module) {
|
||||
* @param {!number} openOffset The offset index location within openFile to open an inline editor.
|
||||
* @param {?boolean} expectInline Use false to verify that an inline editor should not be opened. Omit otherwise.
|
||||
*/
|
||||
var _initInlineTest = function (openFile, openOffset, expectInline, workingSet) {
|
||||
var _initInlineTest = function (openFile, openOffset, expectInline, filesToOpen) {
|
||||
var allFiles,
|
||||
inlineOpened = null,
|
||||
spec = this;
|
||||
|
||||
workingSet = workingSet || [];
|
||||
filesToOpen = filesToOpen || [];
|
||||
expectInline = (expectInline !== undefined) ? expectInline : true;
|
||||
|
||||
runs(function () {
|
||||
@ -89,8 +89,8 @@ define(function (require, exports, module) {
|
||||
SpecRunnerUtils.loadProjectInTestWindow(tempPath);
|
||||
|
||||
runs(function () {
|
||||
workingSet.push(openFile);
|
||||
waitsForDone(SpecRunnerUtils.openProjectFiles(workingSet), "openProjectFiles");
|
||||
filesToOpen.push(openFile);
|
||||
waitsForDone(SpecRunnerUtils.openProjectFiles(filesToOpen), "openProjectFiles");
|
||||
});
|
||||
|
||||
if (openOffset !== undefined) {
|
||||
|
@ -54,7 +54,7 @@ define(function (require, exports, module) {
|
||||
|
||||
/**
|
||||
* @param {string} query what the user is searching for
|
||||
* @returns {Array.<SearchResult>} sorted and filtered results that match the query
|
||||
* @return {Array.<SearchResult>} sorted and filtered results that match the query
|
||||
*/
|
||||
function search(query, matcher) {
|
||||
var selectorList = matcher.selectorList;
|
||||
|
@ -87,7 +87,7 @@ define(function (require, exports, module) {
|
||||
|
||||
/**
|
||||
* @param {string} query what the user is searching for
|
||||
* @returns {Array.<SearchResult>} sorted and filtered results that match the query
|
||||
* @return {Array.<SearchResult>} sorted and filtered results that match the query
|
||||
*/
|
||||
function search(query, matcher) {
|
||||
var idList = matcher.idList;
|
||||
|
@ -80,7 +80,7 @@ define(function (require, exports, module) {
|
||||
/**
|
||||
* @param {string} query what the user is searching for
|
||||
* @param {StringMatch.StringMatcher} matcher object that caches search-in-progress data
|
||||
* @returns {Array.<SearchResult>} sorted and filtered results that match the query
|
||||
* @return {Array.<SearchResult>} sorted and filtered results that match the query
|
||||
*/
|
||||
function search(query, matcher) {
|
||||
var functionList = matcher.functionList;
|
||||
|
@ -36,6 +36,7 @@ define(function (require, exports, module) {
|
||||
KeyBindingManager = brackets.getModule("command/KeyBindingManager"),
|
||||
Menus = brackets.getModule("command/Menus"),
|
||||
EditorManager = brackets.getModule("editor/EditorManager"),
|
||||
MainViewManager = brackets.getModule("view/MainViewManager"),
|
||||
ExtensionUtils = brackets.getModule("utils/ExtensionUtils"),
|
||||
FileSystem = brackets.getModule("filesystem/FileSystem"),
|
||||
AppInit = brackets.getModule("utils/AppInit"),
|
||||
@ -268,7 +269,8 @@ define(function (require, exports, module) {
|
||||
$("#titlebar .nav").off("click", closeDropdown);
|
||||
$dropdown = null;
|
||||
|
||||
EditorManager.focusEditor();
|
||||
MainViewManager.focusActivePane();
|
||||
|
||||
$(window).off("keydown", keydownHook);
|
||||
}
|
||||
|
||||
|
@ -29,9 +29,8 @@ define(function (require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
// Modules from the SpecRunner window
|
||||
var DocumentManager = brackets.getModule("document/DocumentManager"),
|
||||
Editor = brackets.getModule("editor/Editor").Editor,
|
||||
EditorManager = brackets.getModule("editor/EditorManager"),
|
||||
var MasterDocumentManager = brackets.getModule("document/DocumentManager"),
|
||||
MasterMainViewManager = brackets.getModule("view/MainViewManager"),
|
||||
FileUtils = brackets.getModule("file/FileUtils"),
|
||||
SpecRunnerUtils = brackets.getModule("spec/SpecRunnerUtils"),
|
||||
UrlCodeHints = require("main");
|
||||
@ -68,7 +67,7 @@ define(function (require, exports, module) {
|
||||
|
||||
function setupTests(testFilePath) {
|
||||
runs(function () {
|
||||
DocumentManager.getDocumentForPath(testFilePath).done(function (doc) {
|
||||
MasterDocumentManager.getDocumentForPath(testFilePath).done(function (doc) {
|
||||
testDocument = doc;
|
||||
});
|
||||
});
|
||||
@ -80,7 +79,7 @@ define(function (require, exports, module) {
|
||||
// create Editor instance (containing a CodeMirror instance)
|
||||
runs(function () {
|
||||
testEditor = createMockEditor(testDocument);
|
||||
DocumentManager.setCurrentDocument(testDocument);
|
||||
MasterMainViewManager._edit(MasterMainViewManager.ACTIVE_PANE, testDocument);
|
||||
});
|
||||
}
|
||||
|
||||
@ -88,8 +87,7 @@ define(function (require, exports, module) {
|
||||
runs(function () {
|
||||
// The following call ensures that the document is reloaded
|
||||
// from disk before each test
|
||||
DocumentManager.closeAll();
|
||||
|
||||
MasterMainViewManager._closeAll(MasterMainViewManager.ALL_PANES);
|
||||
SpecRunnerUtils.destroyMockEditor(testDocument);
|
||||
testEditor = null;
|
||||
testDocument = null;
|
||||
@ -302,6 +300,7 @@ define(function (require, exports, module) {
|
||||
CommandManager,
|
||||
Commands,
|
||||
DocumentManager,
|
||||
MainViewManager,
|
||||
EditorManager;
|
||||
|
||||
it("should hint site root '/'", function () {
|
||||
@ -314,6 +313,7 @@ define(function (require, exports, module) {
|
||||
Commands = brackets.test.Commands;
|
||||
DocumentManager = brackets.test.DocumentManager;
|
||||
EditorManager = brackets.test.EditorManager;
|
||||
MainViewManager = brackets.test.MainViewManager;
|
||||
});
|
||||
});
|
||||
|
||||
@ -337,7 +337,7 @@ define(function (require, exports, module) {
|
||||
}, "Unable to open test document", 2000);
|
||||
|
||||
runs(function () {
|
||||
DocumentManager.setCurrentDocument(testDocument);
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, testDocument);
|
||||
testEditor = EditorManager.getCurrentFullEditor();
|
||||
testEditor.setCursorPos({ line: 22, ch: 12 });
|
||||
CommandManager.execute(Commands.SHOW_CODE_HINTS);
|
||||
@ -361,6 +361,7 @@ define(function (require, exports, module) {
|
||||
Commands = null;
|
||||
DocumentManager = null;
|
||||
EditorManager = null;
|
||||
MainViewManager = null;
|
||||
SpecRunnerUtils.closeTestWindow();
|
||||
});
|
||||
});
|
||||
|
@ -0,0 +1,12 @@
|
||||
<div class="brackets-config-central">
|
||||
<div class="config-options">
|
||||
<label>
|
||||
<p>Default file Extension When Creating New Files:</p>
|
||||
<input type="text" value="{{defaultExtension}}">
|
||||
</label>
|
||||
<label>
|
||||
<p>Number of space units for tabs</p>
|
||||
<input type="text" value="{{spaceUnits}}">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
After Width: | Height: | Size: 15 KiB |
120
src/extensions/samples/BracketsConfigCentral/main.js
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
|
||||
/*global define, brackets, window, $, Mustache, navigator */
|
||||
|
||||
define(function (require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
// Brackets modules
|
||||
var FileUtils = brackets.getModule("file/FileUtils"),
|
||||
ExtensionUtils = brackets.getModule("utils/ExtensionUtils"),
|
||||
DocumentManager = brackets.getModule("document/DocumentManager"),
|
||||
MainViewFactory = brackets.getModule("view/MainViewFactory"),
|
||||
ConfigViewContent = require("text!htmlContent/Config.html");
|
||||
|
||||
/* our module object */
|
||||
var _module = module;
|
||||
|
||||
/* @type {Object.<string, ConfigView>} List of open views */
|
||||
function ConfigView(doc, $container) {
|
||||
this.$container = $container;
|
||||
this.doc = doc;
|
||||
this.json = JSON.parse(this.doc.getText());
|
||||
this.$view = $(Mustache.render(ConfigViewContent, this.json));
|
||||
this.$view.css({
|
||||
"background-image": "url(file://" + FileUtils.getNativeModuleDirectoryPath(_module) + "/htmlContent/logo-sm.png)",
|
||||
"background-position": "bottom right",
|
||||
"background-repeat": "no-repeat"
|
||||
});
|
||||
$container.append(this.$view);
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves the file object for this view
|
||||
* return {!File} the file object for this view
|
||||
*/
|
||||
ConfigView.prototype.getFile = function () {
|
||||
return this.doc.file;
|
||||
};
|
||||
|
||||
/*
|
||||
* Updates the layout of the view
|
||||
*/
|
||||
ConfigView.prototype.updateLayout = function () {
|
||||
};
|
||||
|
||||
/*
|
||||
* Destroys the view
|
||||
*/
|
||||
ConfigView.prototype.destroy = function () {
|
||||
this.$view.remove();
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates a view of a file (.brackets.json)
|
||||
* @param {!File} file - the file to create a view for
|
||||
* @param {!Pane} pane - the pane where to create the view
|
||||
* @private
|
||||
*/
|
||||
function _createConfigViewOf(file, pane) {
|
||||
var result = new $.Deferred(),
|
||||
view = pane.findViewOfFile(file.fullPath);
|
||||
|
||||
if (view) {
|
||||
// existing view, then just show it
|
||||
pane.showView(view);
|
||||
result.resolve(view.getFile());
|
||||
} else {
|
||||
DocumentManager.getDocumentForPath(file.fullPath)
|
||||
.done(function (doc) {
|
||||
var view = new ConfigView(doc, pane.$el);
|
||||
pane.addView(view, true);
|
||||
result.resolve(doc.file);
|
||||
})
|
||||
.fail(function (fileError) {
|
||||
result.reject(fileError);
|
||||
});
|
||||
}
|
||||
return result.promise();
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a view factory that can create views for the file
|
||||
* `.brackets.json` in a project's root folder.
|
||||
*/
|
||||
var configViewFactory = {
|
||||
canOpenFile: function (fullPath) {
|
||||
var filename = fullPath.substr(fullPath.lastIndexOf("/") + 1);
|
||||
return (filename.toLowerCase() === ".brackets.json");
|
||||
},
|
||||
openFile: function (file, pane) {
|
||||
return _createConfigViewOf(file, pane);
|
||||
}
|
||||
};
|
||||
|
||||
/* load styles used by our template */
|
||||
ExtensionUtils.loadStyleSheet(module, "styles/styles.css");
|
||||
MainViewFactory.registerViewFactory(configViewFactory);
|
||||
});
|
12
src/extensions/samples/BracketsConfigCentral/package.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "JeffryBooher.BracketsConfigCentral",
|
||||
"title": "Brackets Config Central",
|
||||
"description": "A simple view factory provider",
|
||||
"homepage": "https://github.com/JeffryBooher",
|
||||
"version": "0.0.1",
|
||||
"author": "@JeffryBooher",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"brackets": ">=0.44.0"
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
.brackets-config-central
|
||||
{
|
||||
background-color: bisque;
|
||||
}
|
||||
|
||||
.brackets-config-central input[type="text"]
|
||||
{
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
.brackets-config-central .config-options
|
||||
{
|
||||
margin: 2em;
|
||||
}
|
||||
|
@ -164,6 +164,8 @@ define(function (require, exports, module) {
|
||||
result = Strings.CONTENTS_MODIFIED_ERR;
|
||||
} else if (name === FileSystemError.UNSUPPORTED_ENCODING) {
|
||||
result = Strings.UNSUPPORTED_ENCODING_ERR;
|
||||
} else if (name === FileSystemError.UNSUPPORTED_FILETYPE) {
|
||||
result = Strings.UNSUPPORTED_FILE_TYPE_ERR;
|
||||
} else {
|
||||
result = StringUtils.format(Strings.GENERIC_ERROR, name);
|
||||
}
|
||||
|
@ -34,6 +34,10 @@
|
||||
define(function (require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Enumerated File System Errors
|
||||
* @enum {string}
|
||||
*/
|
||||
module.exports = {
|
||||
UNKNOWN : "Unknown",
|
||||
INVALID_PARAMS : "InvalidParams",
|
||||
@ -46,7 +50,8 @@ define(function (require, exports, module) {
|
||||
TOO_MANY_ENTRIES : "TooManyEntries",
|
||||
ALREADY_EXISTS : "AlreadyExists",
|
||||
CONTENTS_MODIFIED : "ContentsModified",
|
||||
ROOT_NOT_WATCHED : "RootNotBeingWatched"
|
||||
ROOT_NOT_WATCHED : "RootNotBeingWatched",
|
||||
UNSUPPORTED_FILETYPE : "UnsupportedFileType"
|
||||
|
||||
// FUTURE: Add remote connection errors: timeout, not logged in, connection err, etc.
|
||||
};
|
||||
|
@ -1,26 +0,0 @@
|
||||
<div id="image-holder">
|
||||
<div id="img-centering">
|
||||
<div id="img-header">
|
||||
<div id="img-data"></div>
|
||||
<div id="img-path"></div>
|
||||
</div>
|
||||
<div id="img">
|
||||
<div id="img-scale"></div>
|
||||
<img id="img-preview" src="file:///{{fullPath}}">
|
||||
<div id="img-tip">
|
||||
<table class="tip-container">
|
||||
<tr>
|
||||
<td class="variable">x: </td>
|
||||
<td id="x-value"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="variable">y: </td>
|
||||
<td id="y-value"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="horiz-guide" class="img-guide"></div>
|
||||
<div id="vert-guide" class="img-guide"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
26
src/htmlContent/image-view.html
Normal file
@ -0,0 +1,26 @@
|
||||
<div class="image-view">
|
||||
<div class="image-centering">
|
||||
<div class="image-header">
|
||||
<div class="image-data"></div>
|
||||
<div class="image-path"></div>
|
||||
</div>
|
||||
<div class="image">
|
||||
<div class="image-scale"></div>
|
||||
<img class="image-preview" src="file:///{{fullPath}}">
|
||||
<div class="image-tip">
|
||||
<table class="tip-container">
|
||||
<tr>
|
||||
<td class="variable">x: </td>
|
||||
<td class="x-value"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="variable">y: </td>
|
||||
<td class="y-value"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="horz-guide image-guide"></div>
|
||||
<div class="vert-guide image-guide"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -41,15 +41,9 @@
|
||||
<!-- Main UI: horizontal set of sidebar, main content vertical stack, and vertical toolbar -->
|
||||
<div class="main-view">
|
||||
<div id="sidebar" class="sidebar panel quiet-scrollbars horz-resizable right-resizer collapsible" data-minsize="0" data-forceleft=".content">
|
||||
<div id="working-set-header">{{WORKING_FILES}}
|
||||
<div id="working-set-option-btn" class="btn-alt-quiet"></div>
|
||||
</div>
|
||||
<div id="open-files-container">
|
||||
<!-- This will contain runtime-generated <li>'s for each file in the working set -->
|
||||
<ul>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="working-set-list-container">
|
||||
|
||||
</div>
|
||||
<div id="project-files-header">
|
||||
<span id="project-title" class="title"></span>
|
||||
</div>
|
||||
@ -63,8 +57,8 @@
|
||||
(status bar is injected later - see StatusBar.init()).
|
||||
Note: all children must be in a vertical stack with heights explicitly set in a fixed
|
||||
unit such as px (not percent/em/auto). If you change the height later, you must
|
||||
call EditorManager.resizeEditor() each time. Otherwise editor-holder's height will
|
||||
not get set correctly. Use PanelManager to have this managed for you automatically.
|
||||
call WorkspaceManager.recomputeLayout() each time. Otherwise the layout will
|
||||
not get set correctly. Use WorkspaceManager to have this managed for you automatically.
|
||||
-->
|
||||
<div class="content">
|
||||
<!-- Horizontal titlebar containing menus & filename when inBrowser -->
|
||||
@ -79,10 +73,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Editors are programmatically created inside here -->
|
||||
<div id="editor-holder">
|
||||
<div id="not-editor">
|
||||
</div>
|
||||
<!-- View Panes are programatically created here -->
|
||||
</div>
|
||||
|
||||
<!-- Bottom panels and status bar are programmatically created here -->
|
||||
@ -112,3 +104,4 @@
|
||||
<div id="codehint-menu-bar">
|
||||
<ul data-dropdown="dropdown"></ul>
|
||||
</div>
|
||||
<div id="hidden-editors"></div>
|
3
src/htmlContent/pane.html
Normal file
@ -0,0 +1,3 @@
|
||||
<div id="{{id}}" class="view-pane">
|
||||
<div class="not-editor"></div>
|
||||
</div>
|
10
src/htmlContent/working-set.html
Normal file
@ -0,0 +1,10 @@
|
||||
<div id="{{id}}">
|
||||
<div class="working-set-header"><span class="working-set-header-title">{{WORKING_FILES}}</span>
|
||||
<div class="working-set-option-btn btn-alt-quiet"></div>
|
||||
</div>
|
||||
<div class="open-files-container">
|
||||
<!-- This will contain runtime-generated <li>'s for each file in the working set -->
|
||||
<ul>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
@ -43,10 +43,11 @@ define(function (require, exports, module) {
|
||||
|
||||
// Load dependent modules
|
||||
var Commands = require("command/Commands"),
|
||||
PanelManager = require("view/PanelManager"),
|
||||
WorkspaceManager = require("view/WorkspaceManager"),
|
||||
CommandManager = require("command/CommandManager"),
|
||||
DocumentManager = require("document/DocumentManager"),
|
||||
EditorManager = require("editor/EditorManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
FileUtils = require("file/FileUtils"),
|
||||
LanguageManager = require("language/LanguageManager"),
|
||||
PreferencesManager = require("preferences/PreferencesManager"),
|
||||
@ -474,8 +475,12 @@ define(function (require, exports, module) {
|
||||
function updateListeners() {
|
||||
if (_enabled) {
|
||||
// register our event listeners
|
||||
$(MainViewManager)
|
||||
.on("currentFileChange.codeInspection", function () {
|
||||
run();
|
||||
});
|
||||
$(DocumentManager)
|
||||
.on("currentDocumentChange.codeInspection currentDocumentLanguageChanged.codeInspection", function () {
|
||||
.on("currentDocumentLanguageChanged.codeInspection", function () {
|
||||
run();
|
||||
})
|
||||
.on("documentSaved.codeInspection documentRefreshed.codeInspection", function (event, document) {
|
||||
@ -485,6 +490,7 @@ define(function (require, exports, module) {
|
||||
});
|
||||
} else {
|
||||
$(DocumentManager).off(".codeInspection");
|
||||
$(MainViewManager).off(".codeInspection");
|
||||
}
|
||||
}
|
||||
|
||||
@ -577,7 +583,7 @@ define(function (require, exports, module) {
|
||||
AppInit.htmlReady(function () {
|
||||
// Create bottom panel to list error details
|
||||
var panelHtml = Mustache.render(PanelTemplate, Strings);
|
||||
var resultsPanel = PanelManager.createBottomPanel("errors", $(panelHtml), 100);
|
||||
var resultsPanel = WorkspaceManager.createBottomPanel("errors", $(panelHtml), 100);
|
||||
$problemsPanel = $("#problems-panel");
|
||||
|
||||
var $selectedRow;
|
||||
@ -608,7 +614,7 @@ define(function (require, exports, module) {
|
||||
|
||||
var editor = EditorManager.getCurrentFullEditor();
|
||||
editor.setCursorPos(line, character, true);
|
||||
EditorManager.focusEditor();
|
||||
MainViewManager.focusActivePane();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -38,6 +38,7 @@ define({
|
||||
"NO_MODIFICATION_ALLOWED_ERR_FILE" : "The permissions do not allow you to make modifications.",
|
||||
"CONTENTS_MODIFIED_ERR" : "The file has been modified outside of {APP_NAME}.",
|
||||
"UNSUPPORTED_ENCODING_ERR" : "{APP_NAME} currently only supports UTF-8 encoded text files.",
|
||||
"UNSUPPORTED_FILE_TYPE_ERR" : "The file is not a supported file type.",
|
||||
"FILE_EXISTS_ERR" : "The file or directory already exists.",
|
||||
"FILE" : "file",
|
||||
"FILE_TITLE" : "File",
|
||||
@ -220,6 +221,14 @@ define({
|
||||
"UNTITLED" : "Untitled",
|
||||
"WORKING_FILES" : "Working Files",
|
||||
|
||||
/**
|
||||
* MainViewManager
|
||||
*/
|
||||
"TOP" : "Top",
|
||||
"BOTTOM" : "Bottom",
|
||||
"LEFT" : "Left",
|
||||
"RIGHT" : "Right",
|
||||
|
||||
/**
|
||||
* Keyboard modifier names
|
||||
*/
|
||||
@ -276,7 +285,7 @@ define({
|
||||
"CMD_FILE_NEW" : "New File",
|
||||
"CMD_FILE_NEW_FOLDER" : "New Folder",
|
||||
"CMD_FILE_OPEN" : "Open\u2026",
|
||||
"CMD_ADD_TO_WORKING_SET" : "Add To Working Set",
|
||||
"CMD_ADD_TO_WORKINGSET_AND_OPEN" : "Add To Working Set and Open",
|
||||
"CMD_OPEN_DROPPED_FILES" : "Open Dropped Files",
|
||||
"CMD_OPEN_FOLDER" : "Open Folder\u2026",
|
||||
"CMD_FILE_CLOSE" : "Close",
|
||||
@ -355,10 +364,10 @@ define({
|
||||
"CMD_TOGGLE_WORD_WRAP" : "Word Wrap",
|
||||
"CMD_LIVE_HIGHLIGHT" : "Live Preview Highlight",
|
||||
"CMD_VIEW_TOGGLE_INSPECTION" : "Lint Files on Save",
|
||||
"CMD_SORT_WORKINGSET_BY_ADDED" : "Sort by Added",
|
||||
"CMD_SORT_WORKINGSET_BY_NAME" : "Sort by Name",
|
||||
"CMD_SORT_WORKINGSET_BY_TYPE" : "Sort by Type",
|
||||
"CMD_SORT_WORKINGSET_AUTO" : "Automatic Sort",
|
||||
"CMD_WORKINGSET_SORT_BY_ADDED" : "Sort by Added",
|
||||
"CMD_WORKINGSET_SORT_BY_NAME" : "Sort by Name",
|
||||
"CMD_WORKINGSET_SORT_BY_TYPE" : "Sort by Type",
|
||||
"CMD_WORKING_SORT_TOGGLE_AUTO" : "Automatic Sort",
|
||||
"CMD_THEMES" : "Themes\u2026",
|
||||
|
||||
// Navigate menu Commands
|
||||
|
@ -45,6 +45,7 @@ define(function (require, exports, module) {
|
||||
// Load dependent modules
|
||||
var ProjectManager = require("project/ProjectManager"),
|
||||
DocumentManager = require("document/DocumentManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
EditorManager = require("editor/EditorManager"),
|
||||
Commands = require("command/Commands"),
|
||||
CommandManager = require("command/CommandManager"),
|
||||
@ -181,7 +182,7 @@ define(function (require, exports, module) {
|
||||
*/
|
||||
function syncUnopenWorkingSet() {
|
||||
// We only care about working set entries that have never been open (have no Document).
|
||||
var unopenWorkingSetFiles = DocumentManager.getWorkingSet().filter(function (wsFile) {
|
||||
var unopenWorkingSetFiles = MainViewManager.getWorkingSet(MainViewManager.ALL_PANES).filter(function (wsFile) {
|
||||
return !DocumentManager.getOpenDocumentForPath(wsFile.fullPath);
|
||||
});
|
||||
|
||||
@ -471,7 +472,7 @@ define(function (require, exports, module) {
|
||||
|
||||
// If we showed a dialog, restore focus to editor
|
||||
if (editConflicts.length > 0 || deleteConflicts.length > 0) {
|
||||
EditorManager.focusEditor();
|
||||
MainViewManager.focusActivePane();
|
||||
}
|
||||
|
||||
// (Any errors that ocurred during presentConflicts() have already
|
||||
|
@ -50,13 +50,15 @@ define(function (require, exports, module) {
|
||||
|
||||
// Load dependent modules
|
||||
var DocumentManager = require("document/DocumentManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
CommandManager = require("command/CommandManager"),
|
||||
EditorManager = require("editor/EditorManager"),
|
||||
PerfUtils = require("utils/PerfUtils"),
|
||||
Commands = require("command/Commands");
|
||||
Commands = require("command/Commands"),
|
||||
DeprecationWarning = require("utils/DeprecationWarning");
|
||||
|
||||
/**
|
||||
* Tracks whether a "currentDocumentChange" notification occured due to a call to
|
||||
* Tracks whether a "currentFileChange" notification occured due to a call to
|
||||
* openAndSelectDocument.
|
||||
* @see FileviewController.openAndSelectDocument
|
||||
* @private
|
||||
@ -74,7 +76,7 @@ define(function (require, exports, module) {
|
||||
/**
|
||||
* Change the doc selection to the working set when ever a new file is added to the working set
|
||||
*/
|
||||
$(DocumentManager).on("workingSetAdd", function (event, addedFile) {
|
||||
$(MainViewManager).on("workingSetAdd", function (event, addedFile) {
|
||||
_fileSelectionFocus = WORKING_SET_VIEW;
|
||||
$(exports).triggerHandler("documentSelectionFocusChange");
|
||||
});
|
||||
@ -82,13 +84,12 @@ define(function (require, exports, module) {
|
||||
/**
|
||||
* Update the file selection focus whenever the contents of the editor area change
|
||||
*/
|
||||
$(EditorManager).on("currentlyViewedFileChange", function (event) {
|
||||
$(MainViewManager).on("currentFileChange", function (event, file, paneId) {
|
||||
var perfTimerName;
|
||||
// The the cause of the doc change was not openAndSelectDocument, so pick the best fileSelectionFocus
|
||||
if (!_curDocChangedDueToMe) {
|
||||
var curDoc = DocumentManager.getCurrentDocument();
|
||||
perfTimerName = PerfUtils.markStart("FileViewController._onCurrentDocumentChange():\t" + (!curDoc || curDoc.file.fullPath));
|
||||
if (curDoc && DocumentManager.findInWorkingSet(curDoc.file.fullPath) !== -1) {
|
||||
// The the cause of the doc change was not openAndSelectDocument, so pick the best fileSelectionFocus
|
||||
perfTimerName = PerfUtils.markStart("FileViewController._oncurrentFileChange():\t" + (file ? (file.fullPath) : "(no open file)"));
|
||||
if (file && MainViewManager.findInWorkingSet(paneId, file.fullPath) !== -1) {
|
||||
_fileSelectionFocus = WORKING_SET_VIEW;
|
||||
} else {
|
||||
_fileSelectionFocus = PROJECT_MANAGER;
|
||||
@ -104,16 +105,18 @@ define(function (require, exports, module) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @return {$.Promise}
|
||||
* @param {string=} paneId - the Pane to activate
|
||||
*/
|
||||
function _selectCurrentDocument() {
|
||||
function _activatePane(paneId) {
|
||||
if (paneId) {
|
||||
MainViewManager.setActivePaneId(paneId);
|
||||
} else {
|
||||
MainViewManager.focusActivePane();
|
||||
}
|
||||
// If fullPath corresonds to the current doc being viewed then opening the file won't
|
||||
// trigger a currentDocumentChanged event, so we need to trigger a documentSelectionFocusChange
|
||||
// trigger a currentFileChange event, so we need to trigger a documentSelectionFocusChange
|
||||
// in this case to signify the selection focus has changed even though the current document has not.
|
||||
$(exports).triggerHandler("documentSelectionFocusChange");
|
||||
|
||||
// Ensure the editor has focus even though we didn't open a new file.
|
||||
EditorManager.focusEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,11 +137,12 @@ define(function (require, exports, module) {
|
||||
/**
|
||||
* Opens a document if it's not open and selects the file in the UI corresponding to
|
||||
* fileSelectionFocus
|
||||
* @param {!fullPath}
|
||||
* @param {string} - must be either WORKING_SET_VIEW or PROJECT_MANAGER
|
||||
* @param {!fullPath} fullPath - full path of the document to open
|
||||
* @param {string} fileSelectionFocus - (WORKING_SET_VIEW || PROJECT_MANAGER)
|
||||
* @param {string} paneId - pane in which to open the document
|
||||
* @return {$.Promise}
|
||||
*/
|
||||
function openAndSelectDocument(fullPath, fileSelectionFocus) {
|
||||
function openAndSelectDocument(fullPath, fileSelectionFocus, paneId) {
|
||||
var result;
|
||||
|
||||
if (fileSelectionFocus !== PROJECT_MANAGER && fileSelectionFocus !== WORKING_SET_VIEW) {
|
||||
@ -148,21 +152,23 @@ define(function (require, exports, module) {
|
||||
|
||||
// Opening files are asynchronous and we want to know when this function caused a file
|
||||
// to open so that _fileSelectionFocus is set appropriatly. _curDocChangedDueToMe is set here
|
||||
// and checked in the currentDocumentChange handler
|
||||
// and checked in the currentFileChange handler
|
||||
_curDocChangedDueToMe = true;
|
||||
|
||||
_fileSelectionFocus = fileSelectionFocus;
|
||||
|
||||
paneId = (paneId || MainViewManager.ACTIVE_PANE);
|
||||
|
||||
// If fullPath corresonds to the current doc being viewed then opening the file won't
|
||||
// trigger a currentDocumentChanged event, so we need to trigger a documentSelectionFocusChange
|
||||
// trigger a currentFileChange event, so we need to trigger a documentSelectionFocusChange
|
||||
// in this case to signify the selection focus has changed even though the current document has not.
|
||||
var curDoc = DocumentManager.getCurrentDocument();
|
||||
if (curDoc && curDoc.file.fullPath === fullPath &&
|
||||
!EditorManager.getCustomViewerForPath(fullPath)) {
|
||||
_selectCurrentDocument();
|
||||
var currentPath = MainViewManager.getCurrentlyViewedPath(paneId);
|
||||
if (currentPath === fullPath) {
|
||||
_activatePane(paneId);
|
||||
result = (new $.Deferred()).resolve().promise();
|
||||
} else {
|
||||
result = CommandManager.execute(Commands.FILE_OPEN, {fullPath: fullPath});
|
||||
result = CommandManager.execute(Commands.FILE_OPEN, {fullPath: fullPath,
|
||||
paneId: paneId});
|
||||
}
|
||||
|
||||
// clear after notification is done
|
||||
@ -177,30 +183,24 @@ define(function (require, exports, module) {
|
||||
* Opens the specified document if it's not already open, adds it to the working set,
|
||||
* and selects it in the WorkingSetView
|
||||
* @param {!fullPath}
|
||||
* @param {?String} selectIn - specify either WORING_SET_VIEW or PROJECT_MANAGER.
|
||||
* Default is WORING_SET_VIEW.
|
||||
* @param {number=} index - insert into the working set list at this 0-based index
|
||||
* @param {string=} paneId - Pane in which to add the view. If omitted, the command default is to use the ACTIVE_PANE
|
||||
* @return {!$.Promise}
|
||||
*/
|
||||
function addToWorkingSetAndSelect(fullPath, selectIn, index) {
|
||||
function openFileAndAddToWorkingSet(fullPath, paneId) {
|
||||
var result = new $.Deferred(),
|
||||
promise = CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: fullPath, index: index});
|
||||
promise = CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, {fullPath: fullPath,
|
||||
paneId: paneId});
|
||||
|
||||
// This properly handles sending the right nofications in cases where the document
|
||||
// is already the current one. In that case we will want to notify with
|
||||
// documentSelectionFocusChange so the views change their selection
|
||||
promise.done(function (doc) {
|
||||
// FILE_ADD_TO_WORKING_SET command sets the current document. Update the
|
||||
promise.done(function (file) {
|
||||
// CMD_ADD_TO_WORKINGSET_AND_OPEN command sets the current document. Update the
|
||||
// selection focus only if doc is not null. When double-clicking on an
|
||||
// image file, we get a null doc here but we still want to keep _fileSelectionFocus
|
||||
// as PROJECT_MANAGER. Regardless of doc is null or not, call _selectCurrentDocument
|
||||
// as PROJECT_MANAGER. Regardless of doc is null or not, call _activatePane
|
||||
// to trigger documentSelectionFocusChange event.
|
||||
if (doc) {
|
||||
_fileSelectionFocus = selectIn || WORKING_SET_VIEW;
|
||||
}
|
||||
_selectCurrentDocument();
|
||||
|
||||
result.resolve(doc);
|
||||
result.resolve(file);
|
||||
}).fail(function (err) {
|
||||
result.reject(err);
|
||||
});
|
||||
@ -208,6 +208,34 @@ define(function (require, exports, module) {
|
||||
return result.promise();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the specified document if it's not already open, adds it to the working set,
|
||||
* and selects it in the WorkingSetView
|
||||
* @deprecated use FileViewController.openFileAndAddToWorkingSet() instead
|
||||
* @param {!fullPath}
|
||||
* @return {!$.Promise}
|
||||
*/
|
||||
function addToWorkingSetAndSelect(fullPath) {
|
||||
DeprecationWarning.deprecationWarning("Use FileViewController.openFileAndAddToWorkingSet() instead of FileViewController.addToWorkingSetAndSelect().", true);
|
||||
var result = new $.Deferred();
|
||||
openFileAndAddToWorkingSet(fullPath)
|
||||
.done(function (file) {
|
||||
var doc;
|
||||
|
||||
if (file) {
|
||||
doc = DocumentManager.getOpenDocumentForPath(file.fullPath);
|
||||
}
|
||||
|
||||
result.resolve(doc);
|
||||
})
|
||||
.fail(function (err) {
|
||||
result.reject(err);
|
||||
});
|
||||
return result.promise();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* returns either WORKING_SET_VIEW or PROJECT_MANAGER
|
||||
* @return {!String}
|
||||
@ -217,11 +245,14 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
|
||||
// Deprecated
|
||||
exports.addToWorkingSetAndSelect = addToWorkingSetAndSelect;
|
||||
|
||||
|
||||
// Define public API
|
||||
exports.getFileSelectionFocus = getFileSelectionFocus;
|
||||
exports.openAndSelectDocument = openAndSelectDocument;
|
||||
exports.addToWorkingSetAndSelect = addToWorkingSetAndSelect;
|
||||
exports.openFileAndAddToWorkingSet = openFileAndAddToWorkingSet;
|
||||
exports.setFileViewFocus = setFileViewFocus;
|
||||
exports.WORKING_SET_VIEW = WORKING_SET_VIEW;
|
||||
exports.PROJECT_MANAGER = PROJECT_MANAGER;
|
||||
|
@ -56,6 +56,7 @@ define(function (require, exports, module) {
|
||||
PreferencesDialogs = require("preferences/PreferencesDialogs"),
|
||||
PreferencesManager = require("preferences/PreferencesManager"),
|
||||
DocumentManager = require("document/DocumentManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
InMemoryFile = require("document/InMemoryFile"),
|
||||
CommandManager = require("command/CommandManager"),
|
||||
Commands = require("command/Commands"),
|
||||
@ -307,8 +308,7 @@ define(function (require, exports, module) {
|
||||
// Prefer file tree selection, else use working set selection
|
||||
var selectedEntry = _getTreeSelectedItem();
|
||||
if (!selectedEntry) {
|
||||
var doc = DocumentManager.getCurrentDocument();
|
||||
selectedEntry = (doc && doc.file);
|
||||
selectedEntry = MainViewManager.getCurrentlyViewedFile();
|
||||
}
|
||||
return selectedEntry;
|
||||
}
|
||||
@ -318,12 +318,12 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
function _documentSelectionFocusChange() {
|
||||
var curFile = EditorManager.getCurrentlyViewedPath();
|
||||
if (curFile && _hasFileSelectionFocus()) {
|
||||
var curFullPath = MainViewManager.getCurrentlyViewedPath(MainViewManager.ACTIVE_PANE);
|
||||
if (curFullPath && _hasFileSelectionFocus()) {
|
||||
var nodeFound = $("#project-files-container li").is(function (index) {
|
||||
var $treeNode = $(this),
|
||||
entry = $treeNode.data("entry");
|
||||
if (entry && entry.fullPath === curFile) {
|
||||
if (entry && entry.fullPath === curFullPath) {
|
||||
if (!_projectTree.jstree("is_selected", $treeNode)) {
|
||||
if ($treeNode.parents(".jstree-closed").length) {
|
||||
//don't auto-expand tree to show file - but remember it if parent is manually expanded later
|
||||
@ -650,12 +650,12 @@ define(function (require, exports, module) {
|
||||
function (event, data) {
|
||||
if (event.type === "open_node") {
|
||||
// select the current document if it becomes visible when this folder is opened
|
||||
var curDoc = DocumentManager.getCurrentDocument();
|
||||
var curFile = MainViewManager.getCurrentlyViewedFile();
|
||||
|
||||
if (_hasFileSelectionFocus() && curDoc && data) {
|
||||
if (_hasFileSelectionFocus() && curFile && data) {
|
||||
var entry = data.rslt.obj.data("entry");
|
||||
|
||||
if (entry && curDoc.file.fullPath.indexOf(entry.fullPath) === 0) {
|
||||
if (entry && curFile.fullPath.indexOf(entry.fullPath) === 0) {
|
||||
_forceSelection(data.rslt.obj, _lastSelected);
|
||||
} else {
|
||||
_redraw(true, false);
|
||||
@ -770,7 +770,7 @@ define(function (require, exports, module) {
|
||||
.bind("dblclick.jstree", function (event) {
|
||||
var entry = $(event.target).closest("li").data("entry");
|
||||
if (entry && entry.isFile && !_isInRename(event.target)) {
|
||||
FileViewController.addToWorkingSetAndSelect(entry.fullPath);
|
||||
FileViewController.openFileAndAddToWorkingSet(entry.fullPath);
|
||||
}
|
||||
if (_mouseupTimeoutId !== null) {
|
||||
window.clearTimeout(_mouseupTimeoutId);
|
||||
@ -1221,7 +1221,7 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
// close all the old files
|
||||
DocumentManager.closeAll();
|
||||
MainViewManager._closeAll(MainViewManager.ALL_PANES);
|
||||
|
||||
_unwatchProjectRoot().always(function () {
|
||||
// Finish closing old project (if any)
|
||||
@ -1846,9 +1846,9 @@ define(function (require, exports, module) {
|
||||
var entry = isFolder ? FileSystem.getDirectoryForPath(oldName) : FileSystem.getFileForPath(oldName);
|
||||
entry.rename(newName, function (err) {
|
||||
if (!err) {
|
||||
if (EditorManager.getCurrentlyViewedPath()) {
|
||||
if (MainViewManager.getCurrentlyViewedPath(MainViewManager.ACTIVE_PANE)) {
|
||||
FileViewController.openAndSelectDocument(
|
||||
EditorManager.getCurrentlyViewedPath(),
|
||||
MainViewManager.getCurrentlyViewedPath(MainViewManager.ACTIVE_PANE),
|
||||
FileViewController.getFileSelectionFocus()
|
||||
);
|
||||
}
|
||||
@ -2016,11 +2016,7 @@ define(function (require, exports, module) {
|
||||
|
||||
// Trigger notifications after tree updates are complete
|
||||
arr.forEach(function (entry) {
|
||||
if (DocumentManager.getCurrentDocument()) {
|
||||
DocumentManager.notifyPathDeleted(entry.fullPath);
|
||||
} else {
|
||||
EditorManager.notifyPathDeleted(entry.fullPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -2116,7 +2112,7 @@ define(function (require, exports, module) {
|
||||
.done(function (result) {
|
||||
// Add working set entries, if requested
|
||||
if (includeWorkingSet) {
|
||||
DocumentManager.getWorkingSet().forEach(function (file) {
|
||||
MainViewManager.getWorkingSet(MainViewManager.ALL_PANES).forEach(function (file) {
|
||||
if (result.indexOf(file) === -1 && !(file instanceof InMemoryFile)) {
|
||||
result.push(file);
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ define(function (require, exports, module) {
|
||||
var AppInit = require("utils/AppInit"),
|
||||
ProjectManager = require("project/ProjectManager"),
|
||||
WorkingSetView = require("project/WorkingSetView"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
CommandManager = require("command/CommandManager"),
|
||||
Commands = require("command/Commands"),
|
||||
Strings = require("strings"),
|
||||
@ -57,7 +58,8 @@ define(function (require, exports, module) {
|
||||
$sidebarMenuText,
|
||||
$openFilesContainer,
|
||||
$projectTitle,
|
||||
$projectFilesContainer;
|
||||
$projectFilesContainer,
|
||||
$workingSetViewsContainer;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -115,6 +117,7 @@ define(function (require, exports, module) {
|
||||
$openFilesContainer = $("#open-files-container");
|
||||
$projectTitle = $("#project-title");
|
||||
$projectFilesContainer = $("#project-files-container");
|
||||
$workingSetViewsContainer = $("#working-set-list-container");
|
||||
|
||||
function _resizeSidebarSelection() {
|
||||
var $element;
|
||||
@ -125,8 +128,6 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
// init
|
||||
WorkingSetView.create($openFilesContainer);
|
||||
|
||||
$sidebar.on("panelResizeStart", function (evt, width) {
|
||||
$sidebar.find(".sidebar-selection-triangle").css("display", "none");
|
||||
$sidebar.find(".scroller-shadow").css("display", "none");
|
||||
@ -163,11 +164,22 @@ define(function (require, exports, module) {
|
||||
if (!$sidebar.is(":visible")) {
|
||||
$sidebar.trigger("panelCollapsed");
|
||||
}
|
||||
|
||||
// wire up an event handler to monitor when panes are created
|
||||
$(MainViewManager).on("paneCreate", function (evt, paneId) {
|
||||
WorkingSetView.createWorkingSetViewForPane($workingSetViewsContainer, paneId);
|
||||
});
|
||||
|
||||
// create WorkingSetViews for each pane already created
|
||||
_.forEach(MainViewManager.getPaneIdList(), function (paneId) {
|
||||
WorkingSetView.createWorkingSetViewForPane($workingSetViewsContainer, paneId);
|
||||
});
|
||||
});
|
||||
|
||||
$(ProjectManager).on("projectOpen", _updateProjectTitle);
|
||||
CommandManager.register(Strings.CMD_HIDE_SIDEBAR, Commands.VIEW_HIDE_SIDEBAR, toggle);
|
||||
|
||||
|
||||
// Define public API
|
||||
exports.toggle = toggle;
|
||||
exports.show = show;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
|
||||
* Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -26,48 +26,73 @@
|
||||
/*global define, $, window */
|
||||
|
||||
/**
|
||||
* Manages the workingSet sort methods.
|
||||
* Manages the workingSetList sort methods.
|
||||
*/
|
||||
define(function (require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
var Commands = require("command/Commands"),
|
||||
CommandManager = require("command/CommandManager"),
|
||||
DocumentManager = require("document/DocumentManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
PreferencesManager = require("preferences/PreferencesManager"),
|
||||
FileUtils = require("file/FileUtils"),
|
||||
AppInit = require("utils/AppInit"),
|
||||
Strings = require("strings");
|
||||
|
||||
var defaultPrefs = {
|
||||
currentSort: Commands.SORT_WORKINGSET_BY_ADDED,
|
||||
automaticSort: false
|
||||
};
|
||||
Strings = require("strings"),
|
||||
_ = require("thirdparty/lodash");
|
||||
|
||||
/**
|
||||
* List of sorting method objects
|
||||
* @private
|
||||
* @type {Array.<Sort>}
|
||||
*/
|
||||
var _sorts = [];
|
||||
|
||||
/**
|
||||
* Denotes the current sort method object
|
||||
* @private
|
||||
* @type {Sort}
|
||||
*/
|
||||
var _currentSort = null;
|
||||
|
||||
/**
|
||||
* Denotes if automatic sorting is enabled or not
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
var _automaticSort = false;
|
||||
|
||||
|
||||
/**
|
||||
* Maps Legacy sort method names to new sort method names
|
||||
* @private
|
||||
* @type {boolean}
|
||||
* Used to know when to do the automatic sort for MRU order.
|
||||
* @type {object.<string: string>} oldname: newname
|
||||
*/
|
||||
var _openedDocument = false;
|
||||
var _sortPrefConversionMap = {
|
||||
"view.sortWorkingSetByAdded" : "cmd.sortWorkingSetByAdded",
|
||||
"view.sortWorkingSetByName" : "cmd.sortWorkingSetByName",
|
||||
"view.sortWorkingSetByType" : "cmd.sortWorkingSetByType"
|
||||
};
|
||||
|
||||
/**
|
||||
* Events which the sort command will listen for to trigger a sort
|
||||
* @constant {string}
|
||||
* @private
|
||||
*/
|
||||
var _SORT_EVENT_NAMES = "workingSetAdd workingSetAddList";
|
||||
|
||||
/**
|
||||
* Preference name
|
||||
* @constant {string}
|
||||
* @private
|
||||
*/
|
||||
var _WORKING_SET_SORT_PREF = "workingSetSortMethod";
|
||||
|
||||
/**
|
||||
* Legacy preference name
|
||||
* @constant {string}
|
||||
* @private
|
||||
*/
|
||||
var _LEGACY_SORT_PREF = "currentSort";
|
||||
|
||||
/**
|
||||
* Retrieves a Sort object by id
|
||||
@ -89,6 +114,27 @@ define(function (require, exports, module) {
|
||||
return _sorts[commandID];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the old brackets working set sort preference into the modern paneview sort preference
|
||||
* @private
|
||||
* @param {!string} sortMethod - sort preference to convert
|
||||
* @return {?string} new sort preference string or undefined if an sortMethod is not found
|
||||
*/
|
||||
function _convertSortPref(sortMethod) {
|
||||
if (!sortMethod) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_sortPrefConversionMap.hasOwnProperty(sortMethod)) {
|
||||
sortMethod = _sortPrefConversionMap[sortMethod];
|
||||
PreferencesManager.setViewState(_WORKING_SET_SORT_PREF, sortMethod);
|
||||
} else {
|
||||
sortMethod = null;
|
||||
}
|
||||
|
||||
return sortMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {boolean} Enabled state of Automatic Sort.
|
||||
*/
|
||||
@ -97,11 +143,11 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the sort listeners.
|
||||
* @private
|
||||
* Removes the sort DocumentManager listeners.
|
||||
*/
|
||||
function _removeListeners() {
|
||||
$(DocumentManager).off(".sort");
|
||||
$(MainViewManager).off(".sort");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,11 +156,11 @@ define(function (require, exports, module) {
|
||||
*/
|
||||
function setAutomatic(enable) {
|
||||
_automaticSort = enable;
|
||||
PreferencesManager.setViewState("automaticSort", enable);
|
||||
CommandManager.get(Commands.SORT_WORKINGSET_AUTO).setChecked(enable);
|
||||
_currentSort.setChecked(enable);
|
||||
PreferencesManager.setViewState("automaticSort", _automaticSort);
|
||||
CommandManager.get(Commands.CMD_WORKING_SORT_TOGGLE_AUTO).setChecked(_automaticSort);
|
||||
_currentSort.setChecked(_automaticSort);
|
||||
|
||||
if (enable) {
|
||||
if (_automaticSort) {
|
||||
_currentSort.sort();
|
||||
} else {
|
||||
_removeListeners();
|
||||
@ -122,16 +168,16 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the current sort MainViewManager listeners.
|
||||
* @private
|
||||
* Adds the current sort DocumentManager listeners.
|
||||
*/
|
||||
function _addListeners() {
|
||||
if (_automaticSort && _currentSort && _currentSort.getEvents()) {
|
||||
$(DocumentManager)
|
||||
$(MainViewManager)
|
||||
.on(_currentSort.getEvents(), function () {
|
||||
_currentSort.sort();
|
||||
})
|
||||
.on("workingSetDisableAutoSorting.sort", function () {
|
||||
.on("_workingSetDisableAutoSort.sort", function () {
|
||||
setAutomatic(false);
|
||||
});
|
||||
}
|
||||
@ -139,8 +185,8 @@ define(function (require, exports, module) {
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* Sets the current sort method and checks it on the context menu.
|
||||
* @private
|
||||
* @param {Sort} newSort
|
||||
*/
|
||||
function _setCurrentSort(newSort) {
|
||||
@ -153,8 +199,8 @@ define(function (require, exports, module) {
|
||||
newSort.setChecked(true);
|
||||
}
|
||||
|
||||
CommandManager.get(Commands.SORT_WORKINGSET_AUTO).setEnabled(!!newSort.getEvents());
|
||||
PreferencesManager.setViewState("currentSort", newSort.getCommandID());
|
||||
CommandManager.get(Commands.CMD_WORKING_SORT_TOGGLE_AUTO).setEnabled(!!newSort.getEvents());
|
||||
PreferencesManager.setViewState(_WORKING_SET_SORT_PREF, newSort.getCommandID());
|
||||
_currentSort = newSort;
|
||||
}
|
||||
}
|
||||
@ -162,12 +208,10 @@ define(function (require, exports, module) {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @private
|
||||
*
|
||||
* @param {string} commandID A valid command identifier.
|
||||
* @param {function(File, File): number} compareFn A valid sort
|
||||
* function (see register for a longer explanation).
|
||||
* @param {string} events Space-separated DocumentManager possible events
|
||||
* @param {string} events Space-separated WorkingSetSort possible events
|
||||
* ending with ".sort".
|
||||
*/
|
||||
function Sort(commandID, compareFn, events, automaticFn) {
|
||||
@ -193,7 +237,7 @@ define(function (require, exports, module) {
|
||||
};
|
||||
|
||||
/**
|
||||
* The DocumentManager events
|
||||
* Gets the event that this sort object is listening to
|
||||
* @return {string}
|
||||
*/
|
||||
Sort.prototype.getEvents = function () {
|
||||
@ -225,7 +269,7 @@ define(function (require, exports, module) {
|
||||
Sort.prototype.sort = function () {
|
||||
if (_currentSort === this) {
|
||||
_removeListeners();
|
||||
DocumentManager.sortWorkingSet(this._compareFn);
|
||||
MainViewManager._sortWorkingSet(MainViewManager.ALL_PANES, this._compareFn);
|
||||
_addListeners();
|
||||
}
|
||||
};
|
||||
@ -280,82 +324,109 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
|
||||
/** Command Handlers */
|
||||
function _handleSortWorkingSetByAdded() {
|
||||
get(Commands.SORT_WORKINGSET_BY_ADDED).execute();
|
||||
}
|
||||
|
||||
function _handleSortWorkingSetByName() {
|
||||
get(Commands.SORT_WORKINGSET_BY_NAME).execute();
|
||||
}
|
||||
|
||||
function _handleSortWorkingSetByType() {
|
||||
get(Commands.SORT_WORKINGSET_BY_TYPE).execute();
|
||||
}
|
||||
|
||||
function _handleAutomaticSort() {
|
||||
/**
|
||||
* Command Handler for CMD_WORKING_SORT_TOGGLE_AUTO
|
||||
* @private
|
||||
*/
|
||||
function _handleToggleAutoSort() {
|
||||
setAutomatic(!getAutomatic());
|
||||
}
|
||||
|
||||
/**
|
||||
* Command Handler for CMD_WORKINGSET_SORT_BY_*
|
||||
* @private
|
||||
* @param {!string} commandId identifies the sort method to use
|
||||
*/
|
||||
function _handleSort(commandId) {
|
||||
get(commandId).execute();
|
||||
}
|
||||
|
||||
// Register Sort Methods
|
||||
/**
|
||||
* Register Sort Methods
|
||||
*/
|
||||
register(
|
||||
Commands.SORT_WORKINGSET_BY_ADDED,
|
||||
function (file1, file2) {
|
||||
var index1 = DocumentManager.findInWorkingSetAddedOrder(file1.fullPath),
|
||||
index2 = DocumentManager.findInWorkingSetAddedOrder(file2.fullPath);
|
||||
Commands.CMD_WORKINGSET_SORT_BY_ADDED,
|
||||
function (paneId, file1, file2) {
|
||||
var index1 = MainViewManager.findInWorkingSetByAddedOrder(paneId, file1.fullPath),
|
||||
index2 = MainViewManager.findInWorkingSetByAddedOrder(paneId, file2.fullPath);
|
||||
|
||||
return index1 - index2;
|
||||
},
|
||||
"workingSetAdd workingSetAddList"
|
||||
_SORT_EVENT_NAMES
|
||||
);
|
||||
register(
|
||||
Commands.SORT_WORKINGSET_BY_NAME,
|
||||
function (file1, file2) {
|
||||
Commands.CMD_WORKINGSET_SORT_BY_NAME,
|
||||
function (paneId, file1, file2) {
|
||||
return FileUtils.compareFilenames(file1.name, file2.name, false);
|
||||
},
|
||||
"workingSetAdd workingSetAddList"
|
||||
_SORT_EVENT_NAMES
|
||||
);
|
||||
register(
|
||||
Commands.SORT_WORKINGSET_BY_TYPE,
|
||||
function (file1, file2) {
|
||||
Commands.CMD_WORKINGSET_SORT_BY_TYPE,
|
||||
function (paneId, file1, file2) {
|
||||
return FileUtils.compareFilenames(file1.name, file2.name, true);
|
||||
},
|
||||
"workingSetAdd workingSetAddList"
|
||||
_SORT_EVENT_NAMES
|
||||
);
|
||||
|
||||
|
||||
// Register Command Handlers
|
||||
CommandManager.register(Strings.CMD_SORT_WORKINGSET_BY_ADDED, Commands.SORT_WORKINGSET_BY_ADDED, _handleSortWorkingSetByAdded);
|
||||
CommandManager.register(Strings.CMD_SORT_WORKINGSET_BY_NAME, Commands.SORT_WORKINGSET_BY_NAME, _handleSortWorkingSetByName);
|
||||
CommandManager.register(Strings.CMD_SORT_WORKINGSET_BY_TYPE, Commands.SORT_WORKINGSET_BY_TYPE, _handleSortWorkingSetByType);
|
||||
CommandManager.register(Strings.CMD_SORT_WORKINGSET_AUTO, Commands.SORT_WORKINGSET_AUTO, _handleAutomaticSort);
|
||||
/**
|
||||
* Register Command Handlers
|
||||
*/
|
||||
CommandManager.register(Strings.CMD_WORKINGSET_SORT_BY_ADDED, Commands.CMD_WORKINGSET_SORT_BY_ADDED, _.partial(_handleSort, Commands.CMD_WORKINGSET_SORT_BY_ADDED));
|
||||
CommandManager.register(Strings.CMD_WORKINGSET_SORT_BY_NAME, Commands.CMD_WORKINGSET_SORT_BY_NAME, _.partial(_handleSort, Commands.CMD_WORKINGSET_SORT_BY_NAME));
|
||||
CommandManager.register(Strings.CMD_WORKINGSET_SORT_BY_TYPE, Commands.CMD_WORKINGSET_SORT_BY_TYPE, _.partial(_handleSort, Commands.CMD_WORKINGSET_SORT_BY_TYPE));
|
||||
CommandManager.register(Strings.CMD_WORKING_SORT_TOGGLE_AUTO, Commands.CMD_WORKING_SORT_TOGGLE_AUTO, _handleToggleAutoSort);
|
||||
|
||||
|
||||
// Initialize default values for sorting preferences
|
||||
PreferencesManager.stateManager.definePreference("currentSort", "string", Commands.SORT_WORKINGSET_BY_ADDED);
|
||||
/**
|
||||
* Initialize default values for sorting preferences
|
||||
*/
|
||||
PreferencesManager.stateManager.definePreference("automaticSort", "boolean", false);
|
||||
PreferencesManager.convertPreferences(module, {_LEGACY_SORT_PREF: "user", "automaticSort": "user"}, true);
|
||||
|
||||
PreferencesManager.convertPreferences(module, {"currentSort": "user", "automaticSort": "user"}, true);
|
||||
/**
|
||||
* Define a default sort method that's empty so that we
|
||||
* just convert and use the legacy sort method
|
||||
*/
|
||||
PreferencesManager.stateManager.definePreference(_WORKING_SET_SORT_PREF, "string", "");
|
||||
|
||||
// Initialize items dependent on extensions/workingSet
|
||||
/*
|
||||
* initializes global sort method from preference settings or the default
|
||||
*/
|
||||
function initSortMethod() {
|
||||
var sortMethod = PreferencesManager.getViewState(_WORKING_SET_SORT_PREF);
|
||||
|
||||
if (!sortMethod) {
|
||||
sortMethod = _convertSortPref(PreferencesManager.getViewState(_LEGACY_SORT_PREF));
|
||||
}
|
||||
|
||||
if (!sortMethod) {
|
||||
sortMethod = Commands.CMD_WORKINGSET_SORT_BY_ADDED;
|
||||
}
|
||||
return sortMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize items dependent on extensions/workingSetList
|
||||
*/
|
||||
AppInit.appReady(function () {
|
||||
var curSort = get(PreferencesManager.getViewState("currentSort")),
|
||||
var sortMethod = initSortMethod(),
|
||||
curSort = get(sortMethod),
|
||||
autoSort = PreferencesManager.getViewState("automaticSort");
|
||||
|
||||
if (curSort) {
|
||||
_setCurrentSort(curSort);
|
||||
}
|
||||
if (autoSort) {
|
||||
setAutomatic(true);
|
||||
setAutomatic(autoSort);
|
||||
}
|
||||
if (curSort && autoSort) {
|
||||
curSort.sort();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Define public API
|
||||
// Public API
|
||||
exports.register = register;
|
||||
exports.get = get;
|
||||
exports.getAutomatic = getAutomatic;
|
||||
|
@ -37,6 +37,7 @@ define(function (require, exports, module) {
|
||||
KeyEvent = require("utils/KeyEvent"),
|
||||
ModalBar = require("widgets/ModalBar").ModalBar,
|
||||
PreferencesManager = require("preferences/PreferencesManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
Strings = require("strings"),
|
||||
ViewUtils = require("utils/ViewUtils");
|
||||
|
||||
@ -240,7 +241,7 @@ define(function (require, exports, module) {
|
||||
self._modalBar = null;
|
||||
self._closed = true;
|
||||
FindBar._removeFindBar(self);
|
||||
EditorManager.focusEditor();
|
||||
MainViewManager.focusActivePane();
|
||||
$(self).trigger("close");
|
||||
});
|
||||
|
||||
|
@ -37,6 +37,7 @@ define(function (require, exports, module) {
|
||||
ProjectManager = require("project/ProjectManager"),
|
||||
DocumentModule = require("document/Document"),
|
||||
DocumentManager = require("document/DocumentManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
FileSystem = require("filesystem/FileSystem"),
|
||||
LanguageManager = require("language/LanguageManager"),
|
||||
SearchModel = require("search/SearchModel").SearchModel,
|
||||
@ -310,10 +311,7 @@ define(function (require, exports, module) {
|
||||
// Still need to make sure it's within project or working set
|
||||
// In getCandidateFiles(), this is covered by the baseline getAllFiles() itself
|
||||
if (file.fullPath.indexOf(ProjectManager.getProjectRoot().fullPath) !== 0) {
|
||||
var inWorkingSet = DocumentManager.getWorkingSet().some(function (wsFile) {
|
||||
return wsFile.fullPath === file.fullPath;
|
||||
});
|
||||
if (!inWorkingSet) {
|
||||
if (MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, file.fullPath) === -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ define(function (require, exports, module) {
|
||||
Dialogs = require("widgets/Dialogs"),
|
||||
DefaultDialogs = require("widgets/DefaultDialogs"),
|
||||
EditorManager = require("editor/EditorManager"),
|
||||
WorkspaceManager = require("view/WorkspaceManager"),
|
||||
FileFilters = require("search/FileFilters"),
|
||||
FileUtils = require("file/FileUtils"),
|
||||
FindBar = require("search/FindBar").FindBar,
|
||||
@ -117,7 +118,7 @@ define(function (require, exports, module) {
|
||||
function _showFindBar(scope, showReplace) {
|
||||
// If the scope is a file with a custom viewer, then we
|
||||
// don't show find in files dialog.
|
||||
if (scope && EditorManager.getCustomViewerForPath(scope.fullPath)) {
|
||||
if (scope && !EditorManager.canOpenPath(scope.fullPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -252,7 +253,7 @@ define(function (require, exports, module) {
|
||||
scrollPos = fullEditor.getScrollPos();
|
||||
scrollPos.y -= oldModalBarHeight; // modalbar already showing, adjust for old height
|
||||
}
|
||||
EditorManager.resizeEditor();
|
||||
WorkspaceManager.recomputeLayout();
|
||||
if (fullEditor) {
|
||||
fullEditor._codeMirror.scrollTo(scrollPos.x, scrollPos.y + _findBar._modalBar.height());
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ define(function (require, exports, module) {
|
||||
AppInit = require("utils/AppInit"),
|
||||
Commands = require("command/Commands"),
|
||||
DocumentManager = require("document/DocumentManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
ProjectManager = require("project/ProjectManager"),
|
||||
Strings = require("strings"),
|
||||
StringUtils = require("utils/StringUtils"),
|
||||
@ -47,7 +48,6 @@ define(function (require, exports, module) {
|
||||
FindUtils = require("search/FindUtils"),
|
||||
FindInFilesUI = require("search/FindInFilesUI"),
|
||||
ScrollTrackMarkers = require("search/ScrollTrackMarkers"),
|
||||
PanelManager = require("view/PanelManager"),
|
||||
Resizer = require("utils/Resizer"),
|
||||
StatusBar = require("widgets/StatusBar"),
|
||||
PreferencesManager = require("preferences/PreferencesManager"),
|
||||
@ -669,7 +669,7 @@ define(function (require, exports, module) {
|
||||
* When the user switches documents (or closes the last document), ensure that the find bar
|
||||
* closes, and also close the Replace All panel.
|
||||
*/
|
||||
function _handleDocumentChange() {
|
||||
function _handleFileChanged() {
|
||||
if (findBar) {
|
||||
findBar.close();
|
||||
}
|
||||
@ -745,7 +745,7 @@ define(function (require, exports, module) {
|
||||
}
|
||||
}
|
||||
|
||||
$(DocumentManager).on("currentDocumentChange", _handleDocumentChange);
|
||||
$(MainViewManager).on("currentFileChange", _handleFileChanged);
|
||||
|
||||
CommandManager.register(Strings.CMD_FIND, Commands.CMD_FIND, _launchFind);
|
||||
CommandManager.register(Strings.CMD_FIND_NEXT, Commands.CMD_FIND_NEXT, _findNext);
|
||||
|
@ -29,6 +29,7 @@ define(function (require, exports, module) {
|
||||
|
||||
var Async = require("utils/Async"),
|
||||
DocumentManager = require("document/DocumentManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
FileSystem = require("filesystem/FileSystem"),
|
||||
FileUtils = require("file/FileUtils"),
|
||||
ProjectManager = require("project/ProjectManager"),
|
||||
@ -176,7 +177,7 @@ define(function (require, exports, module) {
|
||||
options = options || {};
|
||||
// If we're forcing files open, or if the document is in the working set but not actually open
|
||||
// yet, we want to open the file and do the replacement in memory.
|
||||
if (!doc && (options.forceFilesOpen || DocumentManager.findInWorkingSet(fullPath) !== -1)) {
|
||||
if (!doc && (options.forceFilesOpen || MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, fullPath) !== -1)) {
|
||||
return DocumentManager.getDocumentForPath(fullPath).then(function (newDoc) {
|
||||
return _doReplaceInDocument(newDoc, matchInfo, replaceText, options.isRegexp);
|
||||
});
|
||||
@ -244,7 +245,7 @@ define(function (require, exports, module) {
|
||||
var newDoc = DocumentManager.getOpenDocumentForPath(firstPath);
|
||||
// newDoc might be null if the replacement failed.
|
||||
if (newDoc) {
|
||||
DocumentManager.setCurrentDocument(newDoc);
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, newDoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ define(function (require, exports, module) {
|
||||
|
||||
var DocumentManager = require("document/DocumentManager"),
|
||||
EditorManager = require("editor/EditorManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
MainViewFactory = require("view/MainViewFactory"),
|
||||
CommandManager = require("command/CommandManager"),
|
||||
Strings = require("strings"),
|
||||
StringUtils = require("utils/StringUtils"),
|
||||
@ -355,7 +357,7 @@ define(function (require, exports, module) {
|
||||
// So we call `prepareClose()` first, and finish the close later.
|
||||
doClose = false;
|
||||
this.modalBar.prepareClose();
|
||||
CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: fullPath})
|
||||
CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, {fullPath: fullPath})
|
||||
.done(function () {
|
||||
if (cursorPos) {
|
||||
var editor = EditorManager.getCurrentFullEditor();
|
||||
@ -372,7 +374,7 @@ define(function (require, exports, module) {
|
||||
|
||||
if (doClose) {
|
||||
this.close();
|
||||
EditorManager.focusEditor();
|
||||
MainViewManager.focusActivePane();
|
||||
}
|
||||
};
|
||||
|
||||
@ -876,7 +878,8 @@ define(function (require, exports, module) {
|
||||
|
||||
// Return files that are non-binary, or binary files that have a custom viewer
|
||||
function _filter(file) {
|
||||
return !LanguageManager.getLanguageForPath(file.fullPath).isBinary() || EditorManager.getCustomViewerForPath(file.fullPath);
|
||||
return !LanguageManager.getLanguageForPath(file.fullPath).isBinary()
|
||||
|| MainViewFactory.findSuitableFactoryForPath(file.fullPath);
|
||||
}
|
||||
|
||||
// Start fetching the file list, which will be needed the first time the user enters
|
||||
|
@ -37,7 +37,7 @@ define(function (require, exports, module) {
|
||||
|
||||
var Editor = require("editor/Editor"),
|
||||
EditorManager = require("editor/EditorManager"),
|
||||
PanelManager = require("view/PanelManager");
|
||||
WorkspaceManager = require("view/WorkspaceManager");
|
||||
|
||||
|
||||
/**
|
||||
@ -142,7 +142,7 @@ define(function (require, exports, module) {
|
||||
_calcScaling();
|
||||
|
||||
// Update tickmarks during editor resize (whenever resizing has paused/stopped for > 1/3 sec)
|
||||
$(PanelManager).on("editorAreaResize.ScrollTrackMarkers", _.debounce(function () {
|
||||
$(WorkspaceManager).on("workspaceUpdateLayout.ScrollTrackMarkers", _.debounce(function () {
|
||||
if (marks.length) {
|
||||
_calcScaling();
|
||||
$(".tickmark-track", editor.getRootElement()).empty();
|
||||
@ -155,7 +155,7 @@ define(function (require, exports, module) {
|
||||
$(".tickmark-track", curEditor.getRootElement()).remove();
|
||||
editor = null;
|
||||
marks = [];
|
||||
$(PanelManager).off("editorAreaResize.ScrollTrackMarkers");
|
||||
$(WorkspaceManager).off("workspaceUpdateLayout.ScrollTrackMarkers");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ define(function (require, exports, module) {
|
||||
FileViewController = require("project/FileViewController"),
|
||||
FileUtils = require("file/FileUtils"),
|
||||
FindUtils = require("search/FindUtils"),
|
||||
PanelManager = require("view/PanelManager"),
|
||||
WorkspaceManager = require("view/WorkspaceManager"),
|
||||
StringUtils = require("utils/StringUtils"),
|
||||
Strings = require("strings"),
|
||||
_ = require("thirdparty/lodash"),
|
||||
@ -75,7 +75,7 @@ define(function (require, exports, module) {
|
||||
function SearchResultsView(model, panelID, panelName) {
|
||||
var panelHtml = Mustache.render(searchPanelTemplate, {panelID: panelID});
|
||||
|
||||
this._panel = PanelManager.createBottomPanel(panelName, $(panelHtml), 100);
|
||||
this._panel = WorkspaceManager.createBottomPanel(panelName, $(panelHtml), 100);
|
||||
this._$summary = this._panel.$panel.find(".title");
|
||||
this._$table = this._panel.$panel.find(".table-container");
|
||||
this._model = model;
|
||||
@ -176,7 +176,7 @@ define(function (require, exports, module) {
|
||||
// Add the file to the working set on double click
|
||||
.on("dblclick.searchResults", ".table-container tr:not(.file-section)", function (e) {
|
||||
var item = self._searchList[$(this).data("file-index")];
|
||||
FileViewController.addToWorkingSetAndSelect(item.fullPath);
|
||||
FileViewController.openFileAndAddToWorkingSet(item.fullPath);
|
||||
})
|
||||
|
||||
// Add the click event listener directly on the table parent
|
||||
|
@ -71,6 +71,8 @@ html, body {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.resizing-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@ -132,6 +134,10 @@ a, img {
|
||||
}
|
||||
}
|
||||
|
||||
.forced-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.busyCursor {
|
||||
cursor: wait !important;
|
||||
}
|
||||
@ -316,7 +322,7 @@ a, img {
|
||||
position: relative;
|
||||
|
||||
/* Placeholder shown when there is no editor open */
|
||||
#not-editor {
|
||||
.not-editor {
|
||||
height: 100%;
|
||||
.vbox;
|
||||
.box-pack(center);
|
||||
@ -328,8 +334,17 @@ a, img {
|
||||
}
|
||||
}
|
||||
|
||||
.view-pane {
|
||||
display: block;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border: solid rgba(9, 9, 9, .05) 2px;
|
||||
box-sizing: border-box;
|
||||
|
||||
/* Image Preview */
|
||||
#image-holder {
|
||||
.image-view {
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
@ -337,20 +352,19 @@ a, img {
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
text-align: center;
|
||||
display: none;
|
||||
#img-centering {
|
||||
.image-centering {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-top: -50px; /* Offset as vertical align takes image metadata into account */
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
}
|
||||
#img-data {
|
||||
.image-data {
|
||||
font-weight: @font-weight-semibold;
|
||||
}
|
||||
}
|
||||
|
||||
#image-holder:before {
|
||||
.image-view:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
@ -358,7 +372,7 @@ a, img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#img-preview {
|
||||
.image-preview {
|
||||
background: url(images/preview_bg.png);
|
||||
box-shadow: 0 1px 3px @bc-shadow;
|
||||
max-height: 90%;
|
||||
@ -369,15 +383,15 @@ a, img {
|
||||
}
|
||||
}
|
||||
|
||||
#img-header {
|
||||
.image-header {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 38px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#img-data,
|
||||
#img-path {
|
||||
.image-data,
|
||||
.image-path {
|
||||
text-align: left;
|
||||
.user-select(text);
|
||||
white-space: nowrap;
|
||||
@ -385,22 +399,22 @@ a, img {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#img-data::selection,
|
||||
#img-path::selection {
|
||||
.image-data::selection,
|
||||
.image-path::selection {
|
||||
background: @selection-color-focused;
|
||||
}
|
||||
|
||||
#img {
|
||||
.image {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.img-guide,
|
||||
#img-tip,
|
||||
#img-scale {
|
||||
.image-guide,
|
||||
.image-tip,
|
||||
.image-scale {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#img-scale {
|
||||
.image-scale {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
@ -418,7 +432,7 @@ a, img {
|
||||
}
|
||||
}
|
||||
|
||||
#img-tip {
|
||||
.image-tip {
|
||||
display: block;
|
||||
position: absolute;
|
||||
text-align: left;
|
||||
@ -438,8 +452,8 @@ a, img {
|
||||
}
|
||||
}
|
||||
|
||||
#x-value,
|
||||
#y-value {
|
||||
.x-value,
|
||||
.y-value {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
@ -447,27 +461,37 @@ a, img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#horiz-guide {
|
||||
.horz-guide {
|
||||
background-image: url("images/horizontal-dash.svg");
|
||||
background-repeat: repeat-x;
|
||||
width: 8px;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
#vert-guide {
|
||||
.vert-guide {
|
||||
background-image: url("images/vertical-dash.svg");
|
||||
background-repeat: repeat-y;
|
||||
width: 1px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
#horiz-guide,
|
||||
#vert-guide {
|
||||
.horz-guide,
|
||||
.vert-guide {
|
||||
position: absolute;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.active-pane {
|
||||
border: solid rgba(0, 0, 255, .2) 2px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.dark & {
|
||||
border: solid rgba(255, 255, 255, .2) 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.vert-resizer {
|
||||
position: absolute;
|
||||
height: 6px;
|
||||
@ -638,7 +662,7 @@ a, img {
|
||||
|
||||
/* Project panel */
|
||||
|
||||
#working-set-header {
|
||||
.working-set-header {
|
||||
position: relative;
|
||||
height: 19px;
|
||||
padding: 10px 0 9px 12px;
|
||||
@ -653,13 +677,13 @@ a, img {
|
||||
}
|
||||
}
|
||||
|
||||
#working-set-option-btn {
|
||||
.working-set-option-btn {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: 7px;
|
||||
padding: 4px 6px;
|
||||
.sprite-icon(0, 0, 13px, 13px, "images/topcoat-settings-13.svg");
|
||||
background-position: center;
|
||||
background-position:center;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
@ -685,7 +709,7 @@ a, img {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#open-files-container {
|
||||
.open-files-container {
|
||||
.box-flex(0);
|
||||
background: @bc-sidebar-bg;
|
||||
padding: 0px;
|
||||
@ -704,14 +728,6 @@ a, img {
|
||||
padding: 0 0 0 8px;
|
||||
min-height: 18px;
|
||||
vertical-align: baseline;
|
||||
|
||||
&.selected a {
|
||||
color: @open-working-file-name-highlight;
|
||||
}
|
||||
|
||||
&.selected .extension {
|
||||
color: @open-working-file-ext-highlight;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
@ -742,6 +758,19 @@ a, img {
|
||||
}
|
||||
}
|
||||
|
||||
.open-files-container.active {
|
||||
|
||||
li {
|
||||
&.selected a {
|
||||
color: @open-working-file-name-highlight;
|
||||
}
|
||||
|
||||
&.selected .extension {
|
||||
color: @open-working-file-ext-highlight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-selection {
|
||||
background: @bc-sidebar-selection;
|
||||
border-top: 1px solid @bc-shadow-small;
|
||||
@ -780,7 +809,7 @@ a, img {
|
||||
}
|
||||
|
||||
//Initially start with the open files hidden, they will get show as files are added
|
||||
#open-files-container {
|
||||
.open-files-container {
|
||||
display:none;
|
||||
}
|
||||
|
||||
@ -2009,6 +2038,10 @@ label input {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#hidden-editors {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.theme-settings td {
|
||||
padding: 2px;
|
||||
}
|
||||
@ -2018,6 +2051,3 @@ label input {
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
.theme-settings .label {
|
||||
padding: 4px !important;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
*
|
||||
* This module defines 2 methods for client modules to attach callbacks:
|
||||
* - htmlReady - When the main application template is rendered
|
||||
* - extensionsRead - When the extension manager has loaded all extensions
|
||||
* - appReady - When Brackets completes loading all modules and extensions
|
||||
*
|
||||
* These are *not* jQuery events. Each method is similar to $(document).ready
|
||||
@ -39,18 +40,51 @@
|
||||
define(function (require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
// Fires when the base htmlContent/main-view.html is loaded
|
||||
/*
|
||||
* Fires when the base htmlContent/main-view.html is loaded
|
||||
* @type {string}
|
||||
* @const
|
||||
*/
|
||||
var HTML_READY = "htmlReady";
|
||||
|
||||
// Fires when all extensions are loaded
|
||||
/*
|
||||
* Fires when all extensions are loaded
|
||||
* @type {string}
|
||||
* @const
|
||||
*/
|
||||
var APP_READY = "appReady";
|
||||
|
||||
var status = { HTML_READY : false, APP_READY : false },
|
||||
callbacks = {};
|
||||
/*
|
||||
* Fires after extensions have been loaded
|
||||
* @type {string}
|
||||
* @const
|
||||
*/
|
||||
var EXTENSIONS_LOADED = "extensionsLoaded";
|
||||
|
||||
callbacks[HTML_READY] = [];
|
||||
callbacks[APP_READY] = [];
|
||||
/*
|
||||
* Map of each state's trigger
|
||||
* @type {Object.<string, boolean>}
|
||||
* @private
|
||||
*/
|
||||
var _status = { HTML_READY : false, APP_READY : false, EXTENSIONS_LOADED: false };
|
||||
|
||||
/*
|
||||
* Map of callbacks to states
|
||||
* @type {Object.<string, Array.<function()>>}
|
||||
* @private
|
||||
*/
|
||||
var _callbacks = {};
|
||||
|
||||
_callbacks[HTML_READY] = [];
|
||||
_callbacks[APP_READY] = [];
|
||||
_callbacks[EXTENSIONS_LOADED] = [];
|
||||
|
||||
|
||||
/*
|
||||
* calls the specified handler inside a try/catch handler
|
||||
* @param {function()} handler - the callback to call
|
||||
* @private
|
||||
*/
|
||||
function _callHandler(handler) {
|
||||
try {
|
||||
// TODO (issue 1034): We *could* use a $.Deferred for this, except deferred objects enter a broken
|
||||
@ -63,26 +97,37 @@ define(function (require, exports, module) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dispatches the event by calling all handlers registered for that type
|
||||
* @param {string} type - the event type to dispatch (APP_READY, EXTENSIONS_READY, HTML_READY)
|
||||
* @private
|
||||
*/
|
||||
function _dispatchReady(type) {
|
||||
var i,
|
||||
myHandlers = callbacks[type];
|
||||
myHandlers = _callbacks[type];
|
||||
|
||||
// mark this status complete
|
||||
status[type] = true;
|
||||
_status[type] = true;
|
||||
|
||||
for (i = 0; i < myHandlers.length; i++) {
|
||||
_callHandler(myHandlers[i]);
|
||||
}
|
||||
|
||||
// clear all callbacks after being called
|
||||
callbacks[type] = [];
|
||||
_callbacks[type] = [];
|
||||
}
|
||||
|
||||
function _addListener(type, callback) {
|
||||
if (status[type]) {
|
||||
_callHandler(callback);
|
||||
/*
|
||||
* adds a callback to the list of functions to call for the specified event type
|
||||
* @param {string} type - the event type to dispatch (APP_READY, EXTENSIONS_READY, HTML_READY)
|
||||
* @param {function} handler - callback funciton to call when the event is triggered
|
||||
* @private
|
||||
*/
|
||||
function _addListener(type, handler) {
|
||||
if (_status[type]) {
|
||||
_callHandler(handler);
|
||||
} else {
|
||||
callbacks[type].push(callback);
|
||||
_callbacks[type].push(handler);
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,27 +135,39 @@ define(function (require, exports, module) {
|
||||
* Adds a callback for the ready hook. Handlers are called after
|
||||
* htmlReady is done, the initial project is loaded, and all extensions are
|
||||
* loaded.
|
||||
* @param {function} callback
|
||||
* @param {function} handler - callback function to call when the event is fired
|
||||
*/
|
||||
function appReady(callback) {
|
||||
_addListener(APP_READY, callback);
|
||||
function appReady(handler) {
|
||||
_addListener(APP_READY, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a callback for the htmlReady hook. Handlers are called after the
|
||||
* main application html template is rendered.
|
||||
* @param {function} callback
|
||||
* @param {function} handler - callback function to call when the event is fired
|
||||
*/
|
||||
function htmlReady(callback) {
|
||||
_addListener(HTML_READY, callback);
|
||||
function htmlReady(handler) {
|
||||
_addListener(HTML_READY, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a callback for the extensionsLoaded hook. Handlers are called after the
|
||||
* extensions have been loaded
|
||||
* @param {function} handler - callback function to call when the event is fired
|
||||
*/
|
||||
function extensionsLoaded(handler) {
|
||||
_addListener(EXTENSIONS_LOADED, handler);
|
||||
}
|
||||
|
||||
// Public API
|
||||
exports.appReady = appReady;
|
||||
exports.htmlReady = htmlReady;
|
||||
exports.extensionsLoaded = extensionsLoaded;
|
||||
|
||||
exports.HTML_READY = HTML_READY;
|
||||
exports.APP_READY = APP_READY;
|
||||
exports.EXTENSIONS_LOADED = EXTENSIONS_LOADED;
|
||||
|
||||
// internal use only
|
||||
// Unit Test API
|
||||
exports._dispatchReady = _dispatchReady;
|
||||
});
|
@ -21,7 +21,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*global define, console */
|
||||
/*global define, console, $ */
|
||||
|
||||
/**
|
||||
* Utilities functions to display deprecation warning in the console.
|
||||
@ -55,7 +55,7 @@ define(function (require, exports, module) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Show deprecation message with the call stack if it
|
||||
* Show deprecation warning with the call stack if it
|
||||
* has never been displayed before.
|
||||
* @param {!string} message The deprecation message to be displayed.
|
||||
* @param {boolean=} oncePerCaller If true, displays the message once for each unique call location.
|
||||
@ -89,6 +89,91 @@ define(function (require, exports, module) {
|
||||
displayedWarnings[message][callerLocation] = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Counts the number of event handlers listening for the specified event on the specified object
|
||||
* @param {!Object} object - the object with the old event to dispatch
|
||||
* @param {!string} name - the name of the event
|
||||
* @return {!number} count of event handlers
|
||||
*/
|
||||
function getEventHandlerCount(object, name) {
|
||||
var count = 0,
|
||||
events = $._data(object, "events");
|
||||
|
||||
// If there are there any listeners then display a deprecation warning
|
||||
if (events && events.hasOwnProperty(name)) {
|
||||
var listeners = events[name];
|
||||
count = listeners.length;
|
||||
|
||||
if (listeners.hasOwnProperty("delegateCount")) {
|
||||
// we need to subtract 1 since delegateCount is counted
|
||||
// in the length computed above.
|
||||
count += (listeners.delegateCount - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a deprecation warning if there are listeners for the event
|
||||
*
|
||||
* ```
|
||||
* DeprecationWarning.deprecateEvent($(exports),
|
||||
* $(MainViewManager),
|
||||
* "workingSetAdd",
|
||||
* "workingSetAdd",
|
||||
* "DocumentManager.workingSetAdd",
|
||||
* "MainViewManager.workingSetAdd");
|
||||
* ```
|
||||
*
|
||||
* @param {Object} outbound - the object with the old event to dispatch
|
||||
* @param {Object} inbound - the object with the new event to map to the old event
|
||||
* @param {string} oldEventName - the name of the old event
|
||||
* @param {string} newEventName - the name of the new event
|
||||
* @param {string=} canonicalOutboundName - the canonical name of the old event
|
||||
* @param {string=} canonicalInboundName - the canonical name of the new event
|
||||
*/
|
||||
function deprecateEvent(outbound, inbound, oldEventName, newEventName, canonicalOutboundName, canonicalInboundName) {
|
||||
// create an event handler for the new event to listen for
|
||||
$(inbound).on(newEventName, function () {
|
||||
// Get the jQuery event data from the outbound object -- usually the module's exports
|
||||
var listenerCount = getEventHandlerCount(outbound, oldEventName);
|
||||
if (listenerCount > 0) {
|
||||
var message = "The Event " + (canonicalOutboundName || oldEventName) + " has been deprecated. Use " + (canonicalInboundName || newEventName) + " instead.";
|
||||
// We only want to show the deprecation warning once
|
||||
if (!displayedWarnings[message]) {
|
||||
displayedWarnings[message] = true;
|
||||
console.warn(message);
|
||||
}
|
||||
}
|
||||
|
||||
// dispatch the event even if there are no listeners just in case the jQuery data is wrong for some reason
|
||||
$(outbound).trigger(oldEventName, Array.prototype.slice.call(arguments, 1));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a deprecation warning and action for updated constants
|
||||
* @param {!string} old Menu Id
|
||||
* @param {!string} new Menu Id
|
||||
*/
|
||||
function deprecateConstant(obj, oldId, newId) {
|
||||
var warning = "Use Menus." + newId + " instead of Menus." + oldId,
|
||||
newValue = obj[newId];
|
||||
|
||||
Object.defineProperty(obj, oldId, {
|
||||
get: function () {
|
||||
deprecationWarning(warning, true);
|
||||
return newValue;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Define public API
|
||||
exports.deprecationWarning = deprecationWarning;
|
||||
exports.deprecateEvent = deprecateEvent;
|
||||
exports.getEventHandlerCount = getEventHandlerCount;
|
||||
exports.deprecateConstant = deprecateConstant;
|
||||
});
|
||||
|
@ -33,7 +33,9 @@ define(function (require, exports, module) {
|
||||
Commands = require("command/Commands"),
|
||||
Dialogs = require("widgets/Dialogs"),
|
||||
DefaultDialogs = require("widgets/DefaultDialogs"),
|
||||
DocumentManager = require("document/DocumentManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
MainViewFactory = require("view/MainViewFactory"),
|
||||
LanguageManager = require("language/LanguageManager"),
|
||||
FileSystem = require("filesystem/FileSystem"),
|
||||
EditorManager = require("editor/EditorManager"),
|
||||
FileUtils = require("file/FileUtils"),
|
||||
@ -42,26 +44,18 @@ define(function (require, exports, module) {
|
||||
StringUtils = require("utils/StringUtils");
|
||||
|
||||
/**
|
||||
* Return an array of files excluding all files with a custom viewer. If all files
|
||||
* in the array have their own custom viewers, then the last file is added back in
|
||||
* the array since only one file with custom viewer can be open at a time.
|
||||
* Return an array of files excluding all files without a registered viewer.
|
||||
*
|
||||
* @param {Array.<string>} files Array of files to filter before opening.
|
||||
* @return {Array.<string>}
|
||||
* @param {Array.<string>} paths - filenames to filter before opening.
|
||||
* @return {Array.<string>} paths which can actually be opened (may be empty)
|
||||
*/
|
||||
function filterFilesToOpen(files) {
|
||||
// Filter out all files that have their own custom viewers
|
||||
// since we don't keep them in the working set.
|
||||
var filteredFiles = files.filter(function (file) {
|
||||
return !EditorManager.getCustomViewerForPath(file);
|
||||
function filterFilesToOpen(paths) {
|
||||
// Filter out file in which we have no registered viewer
|
||||
var filteredFiles = paths.filter(function (fullPath) {
|
||||
return !LanguageManager.getLanguageForPath(fullPath).isBinary()
|
||||
|| MainViewFactory.findSuitableFactoryForPath(fullPath);
|
||||
});
|
||||
|
||||
// If all files have custom viewers, then add back the last file
|
||||
// so that we open it in its custom viewer.
|
||||
if (filteredFiles.length === 0 && files.length) {
|
||||
filteredFiles.push(files[files.length - 1]);
|
||||
}
|
||||
|
||||
return filteredFiles;
|
||||
}
|
||||
|
||||
@ -111,13 +105,13 @@ define(function (require, exports, module) {
|
||||
// file in the list, return. If this *is* the last file,
|
||||
// always open it so it gets selected.
|
||||
if (idx < filteredFiles.length - 1) {
|
||||
if (DocumentManager.findInWorkingSet(path) !== -1) {
|
||||
if (MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, path) !== -1) {
|
||||
result.resolve();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET,
|
||||
CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN,
|
||||
{fullPath: path, silent: true})
|
||||
.done(function () {
|
||||
result.resolve();
|
||||
|
@ -56,7 +56,7 @@ define(function (require, exports, module) {
|
||||
|
||||
/**
|
||||
* Stores require.js contexts of extensions
|
||||
* @type {Object<string, Object>}
|
||||
* @type {Object.<string, Object>}
|
||||
*/
|
||||
var contexts = {};
|
||||
|
||||
@ -146,38 +146,6 @@ define(function (require, exports, module) {
|
||||
return deferred.promise();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the extension that lives at baseUrl into its own Require.js context
|
||||
*
|
||||
* @param {!string} name, used to identify the extension
|
||||
* @param {!{baseUrl: string}} config object with baseUrl property containing absolute path of extension
|
||||
* @param {!string} entryPoint, name of the main js file to load
|
||||
* @return {!$.Promise} A promise object that is resolved when the extension is loaded, or rejected
|
||||
* if the extension fails to load or throws an exception immediately when loaded.
|
||||
* (Note: if extension contains a JS syntax error, promise is resolved not rejected).
|
||||
*/
|
||||
function loadExtension(name, config, entryPoint) {
|
||||
var promise = new $.Deferred();
|
||||
|
||||
// Try to load the package.json to figure out if we are loading a theme.
|
||||
ExtensionUtils.loadPackageJson(config.baseUrl).always(promise.resolve);
|
||||
|
||||
return promise
|
||||
.then(function(metadata) {
|
||||
// No special handling for themes... Let the promise propagate into the ExtensionManager
|
||||
if (metadata && "theme" in metadata) {
|
||||
return;
|
||||
}
|
||||
|
||||
return loadExtensionModule(name, config, entryPoint);
|
||||
})
|
||||
.then(function () {
|
||||
$(exports).triggerHandler("load", config.baseUrl);
|
||||
}, function (err) {
|
||||
$(exports).triggerHandler("loadFailed", config.baseUrl);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the extension module that lives at baseUrl into its own Require.js context
|
||||
*
|
||||
@ -253,6 +221,38 @@ define(function (require, exports, module) {
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the extension that lives at baseUrl into its own Require.js context
|
||||
*
|
||||
* @param {!string} name, used to identify the extension
|
||||
* @param {!{baseUrl: string}} config object with baseUrl property containing absolute path of extension
|
||||
* @param {!string} entryPoint, name of the main js file to load
|
||||
* @return {!$.Promise} A promise object that is resolved when the extension is loaded, or rejected
|
||||
* if the extension fails to load or throws an exception immediately when loaded.
|
||||
* (Note: if extension contains a JS syntax error, promise is resolved not rejected).
|
||||
*/
|
||||
function loadExtension(name, config, entryPoint) {
|
||||
var promise = new $.Deferred();
|
||||
|
||||
// Try to load the package.json to figure out if we are loading a theme.
|
||||
ExtensionUtils.loadPackageJson(config.baseUrl).always(promise.resolve);
|
||||
|
||||
return promise
|
||||
.then(function (metadata) {
|
||||
// No special handling for themes... Let the promise propagate into the ExtensionManager
|
||||
if (metadata && metadata.hasOwnProperty("theme")) {
|
||||
return;
|
||||
}
|
||||
|
||||
return loadExtensionModule(name, config, entryPoint);
|
||||
})
|
||||
.then(function () {
|
||||
$(exports).triggerHandler("load", config.baseUrl);
|
||||
}, function (err) {
|
||||
$(exports).triggerHandler("loadFailed", config.baseUrl);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs unit tests for the extension that lives at baseUrl into its own Require.js context
|
||||
*
|
||||
|
@ -143,9 +143,9 @@ define(function (require, exports, module) {
|
||||
* @param {?string} forceLeft CSS selector indicating element whose 'left' should be locked to the
|
||||
* the resizable element's size (useful for siblings laid out to the right of
|
||||
* the element). Must lie in element's parent's subtree.
|
||||
* @param {?boolean} createdByPanelManager For internal use only
|
||||
* @param {?boolean} createdByWorkspaceManager For internal use only
|
||||
*/
|
||||
function makeResizable(element, direction, position, minSize, collapsible, forceLeft, createdByPanelManager) {
|
||||
function makeResizable(element, direction, position, minSize, collapsible, forceLeft, createdByWorkspaceManager) {
|
||||
|
||||
var $resizer = $('<div class="' + direction + '-resizer"></div>'),
|
||||
$element = $(element),
|
||||
@ -177,9 +177,9 @@ define(function (require, exports, module) {
|
||||
// Important so min/max sizes behave predictably
|
||||
$element.css("box-sizing", "border-box");
|
||||
|
||||
// Detect legacy cases where panels in the editor area are created without using PanelManager APIs
|
||||
if ($parent[0] && $parent.is(".content") && !createdByPanelManager) {
|
||||
console.warn("Deprecated: resizable panels should be created via PanelManager.createBottomPanel(). Using Resizer directly will stop working in the future. \nElement:", element);
|
||||
// Detect legacy cases where panels in the editor area are created without using WorkspaceManager APIs
|
||||
if ($parent[0] && $parent.is(".content") && !createdByWorkspaceManager) {
|
||||
console.warn("Deprecated: resizable panels should be created via WorkspaceManager.createBottomPanel(). Using Resizer directly will stop working in the future. \nElement:", element);
|
||||
$(exports).triggerHandler("deprecatedPanelAdded", [$element]);
|
||||
}
|
||||
|
||||
@ -328,7 +328,7 @@ define(function (require, exports, module) {
|
||||
// between starting and current position, capped at minSize
|
||||
newSize = Math.max(startSize + directionIncrement * (startPosition - e[directionProperty]), minSize);
|
||||
|
||||
// respect max size if one provided (e.g. by PanelManager)
|
||||
// respect max size if one provided (e.g. by WorkspaceManager)
|
||||
var maxSize = $element.data("maxsize");
|
||||
if (maxSize !== undefined) {
|
||||
newSize = Math.min(newSize, maxSize);
|
||||
|
@ -232,6 +232,11 @@ define(function (require, exports, module) {
|
||||
}
|
||||
};
|
||||
|
||||
var hideSelectionMarker = function (event) {
|
||||
$selectionTriangle.addClass("forced-hidden");
|
||||
$selectionMarker.addClass("forced-hidden");
|
||||
};
|
||||
|
||||
var updateSelectionMarker = function (event, reveal) {
|
||||
// find the selected list item
|
||||
var $listItem = $listElement.find(selectedClassName).closest("li");
|
||||
@ -240,6 +245,9 @@ define(function (require, exports, module) {
|
||||
showTriangle = $listItem.hasClass(leafClassName);
|
||||
}
|
||||
|
||||
$selectionTriangle.removeClass("forced-hidden");
|
||||
$selectionMarker.removeClass("forced-hidden");
|
||||
|
||||
// always hide selection visuals first to force layout (issue #719)
|
||||
$selectionTriangle.hide();
|
||||
$selectionMarker.hide();
|
||||
@ -279,6 +287,7 @@ define(function (require, exports, module) {
|
||||
$listElement.on("selectionChanged", updateSelectionMarker);
|
||||
$scrollerElement.on("scroll", updateSelectionTriangle);
|
||||
$scrollerElement.on("selectionRedraw", updateSelectionTriangle);
|
||||
$scrollerElement.on("selectionHide", hideSelectionMarker);
|
||||
|
||||
// update immediately
|
||||
updateSelectionMarker();
|
||||
@ -467,6 +476,32 @@ define(function (require, exports, module) {
|
||||
return displayPaths;
|
||||
}
|
||||
|
||||
function traverseViewArray(viewArray, startIndex, direction) {
|
||||
if (Math.abs(direction) !== 1) {
|
||||
console.error("traverseViewArray called with unsupported direction: " + direction.toString());
|
||||
return null;
|
||||
}
|
||||
if (startIndex === -1) {
|
||||
// If doc not in view list, return most recent view list item
|
||||
if (viewArray.length > 0) {
|
||||
return viewArray[0];
|
||||
}
|
||||
} else if (viewArray.length > 1) {
|
||||
// If doc is in view list, return next/prev item with wrap-around
|
||||
startIndex += direction;
|
||||
if (startIndex >= viewArray.length) {
|
||||
startIndex = 0;
|
||||
} else if (startIndex < 0) {
|
||||
startIndex = viewArray.length - 1;
|
||||
}
|
||||
|
||||
return viewArray[startIndex];
|
||||
}
|
||||
|
||||
// If no doc open or view list empty, there is no "next" file
|
||||
return null;
|
||||
}
|
||||
|
||||
// handle all resize handlers in a single listener
|
||||
$(window).resize(_handleResize);
|
||||
|
||||
@ -480,4 +515,5 @@ define(function (require, exports, module) {
|
||||
exports.getFileEntryDisplay = getFileEntryDisplay;
|
||||
exports.toggleClass = toggleClass;
|
||||
exports.getDirNamesForDuplicateFiles = getDirNamesForDuplicateFiles;
|
||||
exports.traverseViewArray = traverseViewArray;
|
||||
});
|
||||
|
111
src/view/MainViewFactory.js
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
|
||||
/*global define, window, $, brackets */
|
||||
|
||||
/**
|
||||
* MainViewFactory is a singleton for managing view factories.
|
||||
*
|
||||
* Registering a view factory:
|
||||
*
|
||||
* registerViewFactory({
|
||||
* canOpen: function (fullPath) {
|
||||
* return (fullPath.slice(-4) === ".ico");
|
||||
* },
|
||||
* open: function(file, pane) {
|
||||
* return createIconView(file, pane);
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* The open method is used to open the file and construct
|
||||
* a view of it. Implementation should add the view to the pane
|
||||
*
|
||||
* function createIconView(file, pane) {
|
||||
* // IconView will construct its DOM and append
|
||||
* // it to pane.$el
|
||||
* var view = new IconView(file, pane.$el);
|
||||
* // Then tell the pane to add it to
|
||||
* // its view map and show it
|
||||
* pane.addView(view, true);
|
||||
* return new $.Deferred().resolve().promise();
|
||||
* }
|
||||
*
|
||||
* Factories should only create 1 view of a file per pane. Brackets currently only supports 1 view of
|
||||
* a file open at a given time but that may change to allow the same file open in more than 1 pane. Therefore
|
||||
* Factories can do a simple check to see if a view already exists and show it before creating a new one:
|
||||
*
|
||||
* var view = pane.getViewForPath(file.fullPath);
|
||||
* if (view) {
|
||||
* pane.showView(view);
|
||||
* } else {
|
||||
* return createIconView(file, pane);
|
||||
* }
|
||||
*
|
||||
*/
|
||||
define(function (require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
var _ = require("thirdparty/lodash");
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {canOpenFile:function(path:string):boolean, openFile:function(path:string, pane:Pane)} Factory
|
||||
*/
|
||||
|
||||
/**
|
||||
* The view registration Database
|
||||
* @private
|
||||
* @type {Array.<Factory>}
|
||||
*/
|
||||
var _factories = [];
|
||||
|
||||
/**
|
||||
* Registers a view factory
|
||||
* @param {!Factory} factory - the view factory to register
|
||||
*/
|
||||
function registerViewFactory(factory) {
|
||||
_factories.push(factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a factory that can open the specified file
|
||||
* @param {!string} fullPath - the file to open
|
||||
* @return {?Factory} A factory that can create a view for the path or undefined if there isn't one.
|
||||
*/
|
||||
function findSuitableFactoryForPath(fullPath) {
|
||||
return _.find(_factories, function (factory) {
|
||||
// This could get more complex in the future by searching in this order
|
||||
// 1) a factory that can open the file by fullPath
|
||||
// 2) a factory that can open the file by name
|
||||
// 3) a factory that can open the file by filetype
|
||||
return factory.canOpenFile(fullPath);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Public API
|
||||
*/
|
||||
exports.registerViewFactory = registerViewFactory;
|
||||
exports.findSuitableFactoryForPath = findSuitableFactoryForPath;
|
||||
});
|
1530
src/view/MainViewManager.js
Normal file
1097
src/view/Pane.js
Normal file
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
|
||||
* Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
@ -25,233 +25,34 @@
|
||||
/*global define, window, $, brackets */
|
||||
|
||||
/**
|
||||
* Manages layout of panels surrounding the editor area, and size of the editor area (but not its contents).
|
||||
*
|
||||
* Updates panel sizes when the window is resized. Maintains the max resizing limits for panels, based on
|
||||
* currently available window size.
|
||||
*
|
||||
* Events:
|
||||
* - editorAreaResize -- When editor-holder's size changes for any reason (including panel show/hide
|
||||
* panel resize, or the window resize).
|
||||
* The 2nd arg is the new editor-holder height.
|
||||
* The 3rd arg is a refreshHint flag for internal EditorManager use.
|
||||
* @deprecated This module provided for backwards compatibility. Use WorkspaceManager instead.
|
||||
*/
|
||||
define(function (require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
var AppInit = require("utils/AppInit"),
|
||||
Resizer = require("utils/Resizer");
|
||||
|
||||
var WorkspaceManager = require("view/WorkspaceManager"),
|
||||
DeprecationWarning = require("utils/DeprecationWarning");
|
||||
|
||||
/**
|
||||
* The ".content" vertical stack (editor + all header/footer panels)
|
||||
* @type {jQueryObject}
|
||||
* Creates a deprecation warning event handler
|
||||
* @param {!string} the event being deprecated
|
||||
* @param {!string} the new event to use
|
||||
*/
|
||||
var $windowContent;
|
||||
|
||||
/**
|
||||
* The "#editor-holder": has only one visible child, the current CodeMirror
|
||||
* instance (or the no-editor placeholder)
|
||||
* @type {jQueryObject}
|
||||
*/
|
||||
var $editorHolder;
|
||||
|
||||
/**
|
||||
* Have we already started listening for the end of the ongoing window resize?
|
||||
* @type {boolean}
|
||||
*/
|
||||
var windowResizing = false;
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the available height for the full-size Editor (or the no-editor placeholder),
|
||||
* accounting for the current size of all visible panels, toolbar, & status bar.
|
||||
* @return {number}
|
||||
*/
|
||||
function calcEditorHeight() {
|
||||
var availableHt = $windowContent.height();
|
||||
|
||||
$editorHolder.siblings().each(function (i, elem) {
|
||||
var $elem = $(elem);
|
||||
if ($elem.css("display") !== "none" && $elem.css("position") !== "absolute") {
|
||||
availableHt -= $elem.outerHeight();
|
||||
function _deprecateEvent(oldEventName, newEventName) {
|
||||
DeprecationWarning.deprecateEvent(exports,
|
||||
WorkspaceManager,
|
||||
oldEventName,
|
||||
newEventName,
|
||||
"PanelManager." + oldEventName,
|
||||
"MainViewManager." + newEventName);
|
||||
}
|
||||
});
|
||||
|
||||
// Clip value to 0 (it could be negative if a panel wants more space than we have)
|
||||
return Math.max(availableHt, 0);
|
||||
}
|
||||
|
||||
/** Updates panel resize limits to disallow making panels big enough to shrink editor area below 0 */
|
||||
function updateResizeLimits() {
|
||||
var editorAreaHeight = $editorHolder.height();
|
||||
|
||||
$editorHolder.siblings().each(function (i, elem) {
|
||||
var $elem = $(elem);
|
||||
if ($elem.css("display") === "none") {
|
||||
$elem.data("maxsize", editorAreaHeight);
|
||||
} else {
|
||||
$elem.data("maxsize", editorAreaHeight + $elem.outerHeight());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates a new size for editor-holder and resizes it accordingly, then and dispatches the "editorAreaResize"
|
||||
* event. (The editors within are resized by EditorManager, in response to that event).
|
||||
*
|
||||
* @param {string=} refreshHint One of "skip", "force", or undefined. See EditorManager docs.
|
||||
*/
|
||||
function triggerEditorResize(refreshHint) {
|
||||
// Find how much space is left for the editor
|
||||
var editorAreaHeight = calcEditorHeight();
|
||||
|
||||
$editorHolder.height(editorAreaHeight); // affects size of "not-editor" placeholder as well
|
||||
|
||||
// Resize editor to fill the space
|
||||
$(exports).trigger("editorAreaResize", [editorAreaHeight, refreshHint]);
|
||||
}
|
||||
|
||||
|
||||
/** Trigger editor area resize whenever the window is resized */
|
||||
function handleWindowResize() {
|
||||
// These are not initialized in Jasmine Spec Runner window until a test
|
||||
// is run that creates a mock document.
|
||||
if (!$windowContent || !$editorHolder) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Immediately adjust editor's height, but skip the refresh since CodeMirror will call refresh()
|
||||
// itself when it sees the window resize event
|
||||
// triggerEditorResize("skip");
|
||||
|
||||
// FIXME (issue #4564) Workaround https://github.com/marijnh/CodeMirror/issues/1787
|
||||
triggerEditorResize();
|
||||
|
||||
if (!windowResizing) {
|
||||
windowResizing = true;
|
||||
|
||||
// We don't need any fancy debouncing here - we just need to react before the user can start
|
||||
// resizing any panels at the new window size. So just listen for first mousemove once the
|
||||
// window resize releases mouse capture.
|
||||
$(window.document).one("mousemove", function () {
|
||||
windowResizing = false;
|
||||
updateResizeLimits();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** Trigger editor area resize whenever the given panel is shown/hidden/resized */
|
||||
function listenToResize($panel) {
|
||||
// Update editor height when shown/hidden, & continuously as panel is resized
|
||||
$panel.on("panelCollapsed panelExpanded panelResizeUpdate", function () {
|
||||
triggerEditorResize();
|
||||
});
|
||||
// Update max size of sibling panels when shown/hidden, & at *end* of resize gesture
|
||||
$panel.on("panelCollapsed panelExpanded panelResizeEnd", function () {
|
||||
updateResizeLimits();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Represents a panel below the editor area (a child of ".content").
|
||||
*
|
||||
* @param {!jQueryObject} $panel The entire panel, including any chrome, already in the DOM.
|
||||
* @param {number=} minSize Minimum height of panel in px.
|
||||
*/
|
||||
function Panel($panel, minSize) {
|
||||
this.$panel = $panel;
|
||||
|
||||
Resizer.makeResizable($panel[0], Resizer.DIRECTION_VERTICAL, Resizer.POSITION_TOP, minSize, false, undefined, true);
|
||||
listenToResize($panel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Panel instance
|
||||
* @type {jQueryObject}
|
||||
*/
|
||||
Panel.prototype.$panel = null;
|
||||
|
||||
Panel.prototype.isVisible = function () {
|
||||
return this.$panel.is(":visible");
|
||||
};
|
||||
|
||||
Panel.prototype.show = function () {
|
||||
Resizer.show(this.$panel[0]);
|
||||
};
|
||||
Panel.prototype.hide = function () {
|
||||
Resizer.hide(this.$panel[0]);
|
||||
};
|
||||
|
||||
Panel.prototype.setVisible = function (visible) {
|
||||
if (visible) {
|
||||
Resizer.show(this.$panel[0]);
|
||||
} else {
|
||||
Resizer.hide(this.$panel[0]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new resizable panel beneath the editor area and above the status bar footer. Panel is initially invisible.
|
||||
* The panel's size & visibility are automatically saved & restored as a view-state preference.
|
||||
*
|
||||
* @param {!string} id Unique id for this panel. Use package-style naming, e.g. "myextension.feature.panelname"
|
||||
* @param {!jQueryObject} $panel DOM content to use as the panel. Need not be in the document yet. Must have an id
|
||||
* attribute, for use as a preferences key.
|
||||
* @param {number=} minSize Minimum height of panel in px.
|
||||
* @return {!Panel}
|
||||
*/
|
||||
function createBottomPanel(id, $panel, minSize) {
|
||||
$panel.insertBefore("#status-bar");
|
||||
$panel.hide();
|
||||
updateResizeLimits(); // initialize panel's max size
|
||||
|
||||
return new Panel($panel, minSize);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used by EditorManager to notify us of layout changes our normal panel/window listeners wouldn't detect.
|
||||
* For internal use only: most code should call EditorManager.resizeEditor().
|
||||
*/
|
||||
function _notifyLayoutChange(refreshHint) {
|
||||
triggerEditorResize(refreshHint);
|
||||
updateResizeLimits();
|
||||
}
|
||||
|
||||
|
||||
// Attach to key parts of the overall UI, once created
|
||||
AppInit.htmlReady(function () {
|
||||
$windowContent = $(".content");
|
||||
$editorHolder = $("#editor-holder");
|
||||
|
||||
// Sidebar is a special case: it isn't a Panel, and is not created dynamically. Need to explicitly
|
||||
// listen for resize here.
|
||||
listenToResize($("#sidebar"));
|
||||
});
|
||||
|
||||
// Unit test only: allow passing in mock DOM notes, e.g. for use with SpecRunnerUtils.createMockEditor()
|
||||
function _setMockDOM($mockWindowContent, $mockEditorHolder) {
|
||||
$windowContent = $mockWindowContent;
|
||||
$editorHolder = $mockEditorHolder;
|
||||
}
|
||||
|
||||
// If someone adds a panel in the .content stack the old way, make sure we still listen for resize/show/hide
|
||||
// (Resizer emits a deprecation warning for us - no need to log anything here)
|
||||
$(Resizer).on("deprecatedPanelAdded", function (event, $panel) {
|
||||
listenToResize($panel);
|
||||
});
|
||||
|
||||
// Add this as a capture handler so we're guaranteed to run it before the editor does its own
|
||||
// refresh on resize.
|
||||
window.addEventListener("resize", handleWindowResize, true);
|
||||
|
||||
|
||||
// Define public API
|
||||
exports.createBottomPanel = createBottomPanel;
|
||||
exports._notifyLayoutChange = _notifyLayoutChange;
|
||||
exports._setMockDOM = _setMockDOM;
|
||||
exports.createBottomPanel = function (id, $panel, minSize) {
|
||||
DeprecationWarning.deprecationWarning("Use WorkspaceManager.createBottomPanel() instead of PanelManager.createBottomPanel().", true);
|
||||
return WorkspaceManager.createBottomPanel(id, $panel, minSize);
|
||||
};
|
||||
|
||||
// Deprecated PanelManager events
|
||||
_deprecateEvent("editorAreaResize", "workspaceUpdateLayout");
|
||||
});
|
||||
|
@ -44,6 +44,7 @@ define(function (require, exports, module) {
|
||||
PreferencesManager = require("preferences/PreferencesManager"),
|
||||
DocumentManager = require("document/DocumentManager"),
|
||||
ThemeSettings = require("view/ThemeSettings"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
AppInit = require("utils/AppInit");
|
||||
|
||||
var prefs = PreferencesManager.getExtensionPrefs("fonts");
|
||||
@ -486,7 +487,7 @@ define(function (require, exports, module) {
|
||||
prefs.definePreference("fontFamily", "string", DEFAULT_FONT_FAMILY);
|
||||
|
||||
// Update UI when opening or closing a document
|
||||
$(DocumentManager).on("currentDocumentChange", _updateUI);
|
||||
$(MainViewManager).on("currentFileChange", _updateUI);
|
||||
|
||||
// Update UI when Brackets finishes loading
|
||||
AppInit.appReady(init);
|
||||
|
101
src/view/ViewStateManager.js
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
|
||||
/*global define, $, window */
|
||||
|
||||
/**
|
||||
* ViewStateManager is a singleton for views to park their global viwe state. The state is saved
|
||||
* with project data but the View or View Factory is responsible for restoring the view state
|
||||
* when the view is created.
|
||||
*
|
||||
* Views should implement `getViewState()` so that the view state can be saved and that data is cached
|
||||
* for later use.
|
||||
*
|
||||
* Views or View Factories are responsible for restoring the view state when the view of that file is created
|
||||
* by recalling the cached state. Views determine what data is store in the view state and how to restore it.
|
||||
*/
|
||||
define(function (require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
var _ = require("thirdparty/lodash");
|
||||
|
||||
/**
|
||||
* The view state cache.
|
||||
* @type {Object.<string,*>}
|
||||
* @private
|
||||
*/
|
||||
var _viewStateCache = {};
|
||||
|
||||
/**
|
||||
* resets the view state cache
|
||||
*/
|
||||
function reset() {
|
||||
_viewStateCache = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the view state for the specfied file
|
||||
* @param {!File} file - the file to record the view state for
|
||||
* @param {?*} viewState - any data that the view needs to restore the view state.
|
||||
*/
|
||||
function _setViewState(file, viewState) {
|
||||
_viewStateCache[file.fullPath] = viewState;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the view state for the specified view
|
||||
* @param {!{!getFile:function():File, getViewState:function():*}} view - the to save state
|
||||
* @param {?*} viewState - any data that the view needs to restore the view state.
|
||||
*/
|
||||
function updateViewState(view) {
|
||||
if (view.getViewState) {
|
||||
_setViewState(view.getFile(), view.getViewState());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the view state for the specified file
|
||||
* @param {!File} file - the file to record the view state for
|
||||
* @return {?*} whatever data that was saved earlier with a call setViewState
|
||||
*/
|
||||
function getViewState(file) {
|
||||
return _viewStateCache[file.fullPath];
|
||||
}
|
||||
|
||||
/**
|
||||
* adds an array of view states
|
||||
* @param {!object.<string, *>} viewStates - View State object to append to the current set of view states
|
||||
*/
|
||||
function addViewStates(viewStates) {
|
||||
_viewStateCache = _.extend(_viewStateCache, viewStates);
|
||||
}
|
||||
|
||||
/*
|
||||
* Public API
|
||||
*/
|
||||
exports.reset = reset;
|
||||
exports.updateViewState = updateViewState;
|
||||
exports.getViewState = getViewState;
|
||||
exports.addViewStates = addViewStates;
|
||||
});
|
275
src/view/WorkspaceManager.js
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
|
||||
/*global define, window, $, brackets */
|
||||
|
||||
/**
|
||||
* Manages layout of panels surrounding the editor area, and size of the editor area (but not its contents).
|
||||
*
|
||||
* Updates panel sizes when the window is resized. Maintains the max resizing limits for panels, based on
|
||||
* currently available window size.
|
||||
*
|
||||
* Events:
|
||||
* `workspaceUpdateLayout` When workspace size changes for any reason (including panel show/hide panel resize, or the window resize).
|
||||
* The 2nd arg is the available workspace height.
|
||||
* The 3rd arg is a refreshHint flag for internal use (passed in to recomputeLayout)
|
||||
*/
|
||||
define(function (require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
var AppInit = require("utils/AppInit"),
|
||||
Resizer = require("utils/Resizer");
|
||||
|
||||
|
||||
/**
|
||||
* The ".content" vertical stack (editor + all header/footer panels)
|
||||
* @type {jQueryObject}
|
||||
*/
|
||||
var $windowContent;
|
||||
|
||||
/**
|
||||
* The "#editor-holder": has only one visible child, the current CodeMirror instance (or the no-editor placeholder)
|
||||
* @type {jQueryObject}
|
||||
*/
|
||||
var $editorHolder;
|
||||
|
||||
/**
|
||||
* Have we already started listening for the end of the ongoing window resize?
|
||||
* @type {boolean}
|
||||
*/
|
||||
var windowResizing = false;
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the available height for the full-size Editor (or the no-editor placeholder),
|
||||
* accounting for the current size of all visible panels, toolbar, & status bar.
|
||||
* @return {number}
|
||||
*/
|
||||
function calcAvailableHeight() {
|
||||
var availableHt = $windowContent.height();
|
||||
|
||||
$editorHolder.siblings().each(function (i, elem) {
|
||||
var $elem = $(elem);
|
||||
if ($elem.css("display") !== "none" && $elem.css("position") !== "absolute") {
|
||||
availableHt -= $elem.outerHeight();
|
||||
}
|
||||
});
|
||||
|
||||
// Clip value to 0 (it could be negative if a panel wants more space than we have)
|
||||
return Math.max(availableHt, 0);
|
||||
}
|
||||
|
||||
/** Updates panel resize limits to disallow making panels big enough to shrink editor area below 0 */
|
||||
function updateResizeLimits() {
|
||||
var editorAreaHeight = $editorHolder.height();
|
||||
|
||||
$editorHolder.siblings().each(function (i, elem) {
|
||||
var $elem = $(elem);
|
||||
if ($elem.css("display") === "none") {
|
||||
$elem.data("maxsize", editorAreaHeight);
|
||||
} else {
|
||||
$elem.data("maxsize", editorAreaHeight + $elem.outerHeight());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates a new size for editor-holder and resizes it accordingly, then and dispatches the "workspaceUpdateLayout"
|
||||
* event. (The editors within are resized by EditorManager, in response to that event).
|
||||
*
|
||||
* @param {string=} refreshHint One of "skip", "force", or undefined. See EditorManager docs.
|
||||
*/
|
||||
function triggerUpdateLayout(refreshHint) {
|
||||
// Find how much space is left for the editor
|
||||
var editorAreaHeight = calcAvailableHeight();
|
||||
|
||||
$editorHolder.height(editorAreaHeight); // affects size of "not-editor" placeholder as well
|
||||
|
||||
// Resize editor to fill the space
|
||||
$(exports).trigger("workspaceUpdateLayout", [editorAreaHeight, refreshHint]);
|
||||
}
|
||||
|
||||
|
||||
/** Trigger editor area resize whenever the window is resized */
|
||||
function handleWindowResize() {
|
||||
// These are not initialized in Jasmine Spec Runner window until a test
|
||||
// is run that creates a mock document.
|
||||
if (!$windowContent || !$editorHolder) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Immediately adjust editor's height, but skip the refresh since CodeMirror will call refresh()
|
||||
// itself when it sees the window resize event
|
||||
// triggerUpdateLayout("skip");
|
||||
|
||||
// FIXME (issue #4564) Workaround https://github.com/marijnh/CodeMirror/issues/1787
|
||||
triggerUpdateLayout();
|
||||
|
||||
if (!windowResizing) {
|
||||
windowResizing = true;
|
||||
|
||||
// We don't need any fancy debouncing here - we just need to react before the user can start
|
||||
// resizing any panels at the new window size. So just listen for first mousemove once the
|
||||
// window resize releases mouse capture.
|
||||
$(window.document).one("mousemove", function () {
|
||||
windowResizing = false;
|
||||
updateResizeLimits();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** Trigger editor area resize whenever the given panel is shown/hidden/resized
|
||||
* @param {!jQueryObject} $panel the jquery object in which to attach event handlers
|
||||
*/
|
||||
function listenToResize($panel) {
|
||||
// Update editor height when shown/hidden, & continuously as panel is resized
|
||||
$panel.on("panelCollapsed panelExpanded panelResizeUpdate", function () {
|
||||
triggerUpdateLayout();
|
||||
});
|
||||
// Update max size of sibling panels when shown/hidden, & at *end* of resize gesture
|
||||
$panel.on("panelCollapsed panelExpanded panelResizeEnd", function () {
|
||||
updateResizeLimits();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Represents a panel below the editor area (a child of ".content").
|
||||
* @constructor
|
||||
* @param {!jQueryObject} $panel The entire panel, including any chrome, already in the DOM.
|
||||
* @param {number=} minSize Minimum height of panel in px.
|
||||
*/
|
||||
function Panel($panel, minSize) {
|
||||
this.$panel = $panel;
|
||||
|
||||
Resizer.makeResizable($panel[0], Resizer.DIRECTION_VERTICAL, Resizer.POSITION_TOP, minSize, false, undefined, true);
|
||||
listenToResize($panel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dom node holding the rendered panel
|
||||
* @type {jQueryObject}
|
||||
*/
|
||||
Panel.prototype.$panel = null;
|
||||
|
||||
/**
|
||||
* Determines if the panel is visible
|
||||
* @return {boolean} true if visible, false if not
|
||||
*/
|
||||
Panel.prototype.isVisible = function () {
|
||||
return this.$panel.is(":visible");
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows the panel
|
||||
*/
|
||||
Panel.prototype.show = function () {
|
||||
Resizer.show(this.$panel[0]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hides the panel
|
||||
*/
|
||||
Panel.prototype.hide = function () {
|
||||
Resizer.hide(this.$panel[0]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the panel's visibility state
|
||||
* @param {boolean} visible true to show, false to hide
|
||||
*/
|
||||
Panel.prototype.setVisible = function (visible) {
|
||||
if (visible) {
|
||||
Resizer.show(this.$panel[0]);
|
||||
} else {
|
||||
Resizer.hide(this.$panel[0]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new resizable panel beneath the editor area and above the status bar footer. Panel is initially invisible.
|
||||
* The panel's size & visibility are automatically saved & restored as a view-state preference.
|
||||
*
|
||||
* @param {!string} id Unique id for this panel. Use package-style naming, e.g. "myextension.feature.panelname"
|
||||
* @param {!jQueryObject} $panel DOM content to use as the panel. Need not be in the document yet. Must have an id
|
||||
* attribute, for use as a preferences key.
|
||||
* @param {number=} minSize Minimum height of panel in px.
|
||||
* @return {!Panel}
|
||||
*/
|
||||
function createBottomPanel(id, $panel, minSize) {
|
||||
$panel.insertBefore("#status-bar");
|
||||
$panel.hide();
|
||||
updateResizeLimits(); // initialize panel's max size
|
||||
|
||||
return new Panel($panel, minSize);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called when an external widget has appeared and needs some of the space occupied
|
||||
* by the mainview manager
|
||||
* @param {boolean} refreshHint true to refresh the editor, false if not
|
||||
*/
|
||||
function recomputeLayout(refreshHint) {
|
||||
triggerUpdateLayout(refreshHint);
|
||||
updateResizeLimits();
|
||||
}
|
||||
|
||||
|
||||
/* Attach to key parts of the overall UI, once created */
|
||||
AppInit.htmlReady(function () {
|
||||
$windowContent = $(".content");
|
||||
$editorHolder = $("#editor-holder");
|
||||
|
||||
// Sidebar is a special case: it isn't a Panel, and is not created dynamically. Need to explicitly
|
||||
// listen for resize here.
|
||||
listenToResize($("#sidebar"));
|
||||
});
|
||||
|
||||
/* Unit test only: allow passing in mock DOM notes, e.g. for use with SpecRunnerUtils.createMockEditor() */
|
||||
function _setMockDOM($mockWindowContent, $mockEditorHolder) {
|
||||
$windowContent = $mockWindowContent;
|
||||
$editorHolder = $mockEditorHolder;
|
||||
}
|
||||
|
||||
/* If someone adds a panel in the .content stack the old way, make sure we still listen for resize/show/hide
|
||||
* (Resizer emits a deprecation warning for us - no need to log anything here)
|
||||
*/
|
||||
$(Resizer).on("deprecatedPanelAdded", function (event, $panel) {
|
||||
listenToResize($panel);
|
||||
});
|
||||
|
||||
/* Add this as a capture handler so we're guaranteed to run it before the editor does its own
|
||||
* refresh on resize.
|
||||
*/
|
||||
window.addEventListener("resize", handleWindowResize, true);
|
||||
|
||||
|
||||
// Define public API
|
||||
exports.createBottomPanel = createBottomPanel;
|
||||
exports.recomputeLayout = recomputeLayout;
|
||||
exports._setMockDOM = _setMockDOM;
|
||||
});
|
@ -43,7 +43,7 @@ define(function (require, exports, module) {
|
||||
|
||||
// Load dependent modules
|
||||
var DropdownEventHandler = require("utils/DropdownEventHandler").DropdownEventHandler,
|
||||
PanelManager = require("view/PanelManager"),
|
||||
WorkspaceManager = require("view/WorkspaceManager"),
|
||||
Menus = require("command/Menus"),
|
||||
ViewUtils = require("utils/ViewUtils"),
|
||||
_ = require("thirdparty/lodash");
|
||||
@ -277,7 +277,7 @@ define(function (require, exports, module) {
|
||||
this._dropdownEventHandler.open();
|
||||
|
||||
window.document.body.addEventListener("mousedown", this._onClickOutside, true);
|
||||
$(PanelManager).on("editorAreaResize", this.closeDropdown);
|
||||
$(WorkspaceManager).on("workspaceUpdateLayout", this.closeDropdown);
|
||||
|
||||
// Manage focus
|
||||
this._lastFocus = window.document.activeElement;
|
||||
@ -291,7 +291,7 @@ define(function (require, exports, module) {
|
||||
*/
|
||||
DropdownButton.prototype._onDropdownClose = function () {
|
||||
window.document.body.removeEventListener("mousedown", this._onClickOutside, true);
|
||||
$(PanelManager).off("editorAreaResize", this.closeDropdown);
|
||||
$(WorkspaceManager).off("workspaceUpdateLayout", this.closeDropdown);
|
||||
|
||||
// Restore focus to old pos, unless "select" handler changed it
|
||||
if (window.document.activeElement === this.$dropdown[0]) {
|
||||
|
@ -33,8 +33,10 @@ define(function (require, exports, module) {
|
||||
"use strict";
|
||||
|
||||
var EditorManager = require("editor/EditorManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
KeyEvent = require("utils/KeyEvent"),
|
||||
AnimationUtils = require("utils/AnimationUtils");
|
||||
AnimationUtils = require("utils/AnimationUtils"),
|
||||
WorkspaceManager = require("view/WorkspaceManager");
|
||||
|
||||
/**
|
||||
* Creates a modal bar whose contents are the given template.
|
||||
@ -77,9 +79,7 @@ define(function (require, exports, module) {
|
||||
// to the editor here, before opening up the new modal bar. This ensures that the old
|
||||
// focused item has time to react and close before the new modal bar is opened.
|
||||
// See bugs #4287 and #3424
|
||||
if (!EditorManager.getFocusedEditor()) {
|
||||
EditorManager.focusEditor();
|
||||
}
|
||||
MainViewManager.focusActivePane();
|
||||
|
||||
if (autoClose) {
|
||||
this._autoClose = true;
|
||||
@ -98,15 +98,9 @@ define(function (require, exports, module) {
|
||||
|
||||
// Preserve scroll position of the current full editor across the editor refresh, adjusting for the
|
||||
// height of the modal bar so the code doesn't appear to shift if possible.
|
||||
var fullEditor = EditorManager.getCurrentFullEditor(),
|
||||
scrollPos;
|
||||
if (fullEditor) {
|
||||
scrollPos = fullEditor.getScrollPos();
|
||||
}
|
||||
EditorManager.resizeEditor();
|
||||
if (fullEditor) {
|
||||
fullEditor._codeMirror.scrollTo(scrollPos.x, scrollPos.y + this.height());
|
||||
}
|
||||
MainViewManager.cacheScrollState(MainViewManager.ALL_PANES);
|
||||
WorkspaceManager.recomputeLayout(); // changes available ht for editor area
|
||||
MainViewManager.restoreAdjustedScrollState(MainViewManager.ALL_PANES, this.height());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,18 +154,16 @@ define(function (require, exports, module) {
|
||||
this._$root.css("top", top + "px");
|
||||
}
|
||||
|
||||
// Preserve scroll position of the current full editor across the editor refresh, adjusting for the
|
||||
// height of the modal bar so the code doesn't appear to shift if possible.
|
||||
var fullEditor = EditorManager.getCurrentFullEditor(),
|
||||
barHeight,
|
||||
scrollPos;
|
||||
if (restoreScrollPos && fullEditor) {
|
||||
barHeight = this.height();
|
||||
scrollPos = fullEditor.getScrollPos();
|
||||
// Preserve scroll position of all visible views
|
||||
// adjusting for the height of the modal bar so the code doesn't appear to shift if possible.
|
||||
var barHeight = this.height();
|
||||
if (restoreScrollPos) {
|
||||
MainViewManager.cacheScrollState(MainViewManager.ALL_PANES);
|
||||
}
|
||||
EditorManager.resizeEditor();
|
||||
if (restoreScrollPos && fullEditor) {
|
||||
fullEditor._codeMirror.scrollTo(scrollPos.x, scrollPos.y - barHeight);
|
||||
WorkspaceManager.recomputeLayout(); // changes available ht for editor area
|
||||
// restore scroll position of all vies
|
||||
if (restoreScrollPos) {
|
||||
MainViewManager.restoreAdjustedScrollState(MainViewManager.ALL_PANES, -barHeight);
|
||||
}
|
||||
};
|
||||
|
||||
@ -223,7 +215,7 @@ define(function (require, exports, module) {
|
||||
doRemove();
|
||||
}
|
||||
|
||||
EditorManager.focusEditor();
|
||||
MainViewManager.focusActivePane();
|
||||
|
||||
return result.promise();
|
||||
};
|
||||
|
@ -37,7 +37,8 @@ define(function (require, exports, module) {
|
||||
var AppInit = require("utils/AppInit"),
|
||||
StatusBarHTML = require("text!widgets/StatusBar.html"),
|
||||
EditorManager = require("editor/EditorManager"),
|
||||
Strings = require("strings");
|
||||
Strings = require("strings"),
|
||||
WorkspaceManager = require("view/WorkspaceManager");
|
||||
|
||||
var _init = false;
|
||||
|
||||
@ -185,7 +186,7 @@ define(function (require, exports, module) {
|
||||
|
||||
if ($statusBar.is(":visible")) {
|
||||
$statusBar.hide();
|
||||
EditorManager.resizeEditor(); // changes available ht for editor area
|
||||
WorkspaceManager.recomputeLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,7 +201,7 @@ define(function (require, exports, module) {
|
||||
|
||||
if (!$statusBar.is(":visible")) {
|
||||
$statusBar.show();
|
||||
EditorManager.resizeEditor(); // changes available ht for editor area
|
||||
WorkspaceManager.recomputeLayout();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,11 @@ pre {
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
/* Add some space between the menu and the list of tests. */
|
||||
.container-fluid {
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
@media (min-width: 728px) and (max-width: 1199px) {
|
||||
.navbar-fixed-top .container,
|
||||
.navbar-fixed-bottom .container {
|
||||
|
@ -47,7 +47,6 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
@ -63,6 +62,7 @@
|
||||
<li><a id="unit" href="?suite=unit">Unit</a></li>
|
||||
<li><a id="integration" href="?suite=integration">Integration</a></li>
|
||||
<li><a id="livepreview" href="?suite=livepreview">Live Preview</a></li>
|
||||
<li><a id="mainview" href="?suite=mainview">Main View</a></li>
|
||||
<li><a id="performance" href="?suite=performance">Performance</a></li>
|
||||
<li><a id="extension" href="?suite=extension">Extensions</a></li>
|
||||
<li><a id="reload" href="#">Reload</a></li>
|
||||
@ -72,6 +72,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="mock-main-view" style="position:absolute; height:1000px; width:1000px; left:-10000px; top:-10000px;"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -38,6 +38,7 @@ define(function (require, exports, module) {
|
||||
require("spec/DocumentManager-test");
|
||||
require("spec/DragAndDrop-test");
|
||||
require("spec/Editor-test");
|
||||
require("spec/EditorRedraw-test");
|
||||
require("spec/EditorCommandHandlers-test");
|
||||
require("spec/EditorOptionHandlers-test");
|
||||
require("spec/EditorManager-test");
|
||||
@ -59,10 +60,13 @@ define(function (require, exports, module) {
|
||||
require("spec/LanguageManager-test");
|
||||
require("spec/LiveDevelopment-test");
|
||||
require("spec/LowLevelFileIO-test");
|
||||
require("spec/MainViewFactory-test");
|
||||
require("spec/MainViewManager-test");
|
||||
require("spec/Menu-test");
|
||||
require("spec/MultiRangeInlineEditor-test");
|
||||
require("spec/NativeMenu-test");
|
||||
require("spec/NodeConnection-test");
|
||||
require("spec/Pane-test");
|
||||
require("spec/PreferencesBase-test");
|
||||
require("spec/PreferencesManager-test");
|
||||
require("spec/ProjectManager-test");
|
||||
@ -75,7 +79,9 @@ define(function (require, exports, module) {
|
||||
require("spec/UpdateNotification-test");
|
||||
require("spec/UrlParams-test");
|
||||
require("spec/ValidationUtils-test");
|
||||
require("spec/ViewFactory-test");
|
||||
//require("spec/ViewCommandHandlers-test");
|
||||
require("spec/ViewUtils-test");
|
||||
require("spec/WorkingSetView-test");
|
||||
require("spec/WorkingSetSort-test");
|
||||
});
|
@ -1498,7 +1498,7 @@ define(function (require, exports, module) {
|
||||
.fail(function () { gotError = true; });
|
||||
});
|
||||
|
||||
waitsFor(function () { return didOpen && !gotError; }, "FileViewController.addToWorkingSetAndSelect() timeout", 1000);
|
||||
waitsFor(function () { return didOpen && !gotError; }, "FileViewController.openAndSelectDocument() timeout", 1000);
|
||||
|
||||
var rules = null;
|
||||
|
||||
@ -1534,7 +1534,7 @@ define(function (require, exports, module) {
|
||||
.fail(function () { gotError = true; });
|
||||
});
|
||||
|
||||
waitsFor(function () { return didOpen && !gotError; }, "FileViewController.addToWorkingSetAndSelect() timeout", 1000);
|
||||
waitsFor(function () { return didOpen && !gotError; }, "FileViewController.openAndSelectDocument() timeout", 1000);
|
||||
|
||||
var rules = null;
|
||||
|
||||
|
@ -34,6 +34,7 @@ define(function (require, exports, module) {
|
||||
EditorManager, // loaded from brackets.test
|
||||
DocumentModule, // loaded from brackets.test
|
||||
DocumentManager, // loaded from brackets.test
|
||||
MainViewManager, // loaded from brackets.test
|
||||
SpecRunnerUtils = require("spec/SpecRunnerUtils");
|
||||
|
||||
|
||||
@ -229,6 +230,7 @@ define(function (require, exports, module) {
|
||||
EditorManager = testWindow.brackets.test.EditorManager;
|
||||
DocumentModule = testWindow.brackets.test.DocumentModule;
|
||||
DocumentManager = testWindow.brackets.test.DocumentManager;
|
||||
MainViewManager = testWindow.brackets.test.MainViewManager;
|
||||
|
||||
SpecRunnerUtils.loadProjectInTestWindow(testPath);
|
||||
});
|
||||
@ -241,7 +243,9 @@ define(function (require, exports, module) {
|
||||
EditorManager = null;
|
||||
DocumentModule = null;
|
||||
DocumentManager = null;
|
||||
MainViewManager = null;
|
||||
SpecRunnerUtils.closeTestWindow();
|
||||
testWindow = null;
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
@ -259,7 +263,7 @@ define(function (require, exports, module) {
|
||||
|
||||
|
||||
describe("Dirty flag and undo", function () {
|
||||
var promise, doc;
|
||||
var promise;
|
||||
|
||||
it("should not fire dirtyFlagChange when created", function () {
|
||||
var dirtyFlagListener = jasmine.createSpy();
|
||||
@ -395,6 +399,7 @@ define(function (require, exports, module) {
|
||||
|
||||
$(doc).off("change", changeListener);
|
||||
$(DocumentManager).off("dirtyFlagChange", dirtyFlagListener);
|
||||
doc = null;
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -480,7 +485,7 @@ define(function (require, exports, module) {
|
||||
cssMasterEditor;
|
||||
|
||||
runs(function () {
|
||||
promise = CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: HTML_FILE});
|
||||
promise = CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, {fullPath: HTML_FILE});
|
||||
waitsForDone(promise, "Open into working set");
|
||||
});
|
||||
runs(function () {
|
||||
@ -489,7 +494,7 @@ define(function (require, exports, module) {
|
||||
waitsForDone(promise, "Open inline editor");
|
||||
});
|
||||
runs(function () {
|
||||
expect(DocumentManager.findInWorkingSet(CSS_FILE)).toBe(-1);
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ACTIVE_PANE, CSS_FILE)).toBe(-1);
|
||||
expect(DocumentManager.getOpenDocumentForPath(CSS_FILE)).toBeTruthy();
|
||||
|
||||
// Force creation of master editor for CSS file
|
||||
|
@ -33,6 +33,7 @@ define(function (require, exports, module) {
|
||||
Commands, // loaded from brackets.test
|
||||
DocumentCommandHandlers, // loaded from brackets.test
|
||||
DocumentManager, // loaded from brackets.test
|
||||
MainViewManager, // loaded from brackets.test
|
||||
Dialogs, // loaded from brackets.test
|
||||
FileSystem, // loaded from brackets.test
|
||||
FileViewController, // loaded from brackets.test
|
||||
@ -65,6 +66,7 @@ define(function (require, exports, module) {
|
||||
Commands = testWindow.brackets.test.Commands;
|
||||
DocumentCommandHandlers = testWindow.brackets.test.DocumentCommandHandlers;
|
||||
DocumentManager = testWindow.brackets.test.DocumentManager;
|
||||
MainViewManager = testWindow.brackets.test.MainViewManager;
|
||||
Dialogs = testWindow.brackets.test.Dialogs;
|
||||
FileSystem = testWindow.brackets.test.FileSystem;
|
||||
FileViewController = testWindow.brackets.test.FileViewController;
|
||||
@ -78,8 +80,10 @@ define(function (require, exports, module) {
|
||||
Commands = null;
|
||||
DocumentCommandHandlers = null;
|
||||
DocumentManager = null;
|
||||
MainViewManager = null;
|
||||
Dialogs = null;
|
||||
FileViewController = null;
|
||||
EditorManager = null;
|
||||
SpecRunnerUtils.closeTestWindow();
|
||||
});
|
||||
|
||||
@ -97,7 +101,7 @@ define(function (require, exports, module) {
|
||||
// Call closeAll() directly. Some tests set a spy on the save as
|
||||
// dialog preventing SpecRunnerUtils.closeAllFiles() from
|
||||
// working properly.
|
||||
testWindow.brackets.test.DocumentManager.closeAll();
|
||||
testWindow.brackets.test.MainViewManager._closeAll(testWindow.brackets.test.MainViewManager.ALL_PANES);
|
||||
});
|
||||
});
|
||||
|
||||
@ -126,8 +130,8 @@ define(function (require, exports, module) {
|
||||
});
|
||||
|
||||
/** @return {Array.<Document>} */
|
||||
function getWorkingSetDocs() {
|
||||
return DocumentManager.getWorkingSet().map(function (file) {
|
||||
function getOpenDocsFromWorkingSet() {
|
||||
return MainViewManager.getWorkingSet(MainViewManager.ALL_PANES).map(function (file) {
|
||||
return DocumentManager.getOpenDocumentForPath(file.fullPath);
|
||||
});
|
||||
}
|
||||
@ -199,8 +203,8 @@ define(function (require, exports, module) {
|
||||
expect(noLongerUntitledDocument.isDirty).toBe(false);
|
||||
expect(noLongerUntitledDocument.isUntitled()).toBe(false);
|
||||
expect(noLongerUntitledDocument.file.fullPath).toEqual(newFilePath);
|
||||
expect(DocumentManager.findInWorkingSet(newFilePath)).toBeGreaterThan(-1);
|
||||
expect(DocumentManager.getWorkingSet().length).toEqual(1); // no remnant of untitled doc left
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, newFilePath)).toNotEqual(-1);
|
||||
expect(MainViewManager.getWorkingSet(MainViewManager.ALL_PANES).length).toEqual(1); // no remnant of untitled doc left
|
||||
|
||||
// Verify file exists, & clean up
|
||||
expectAndDelete(newFilePath);
|
||||
@ -265,8 +269,8 @@ define(function (require, exports, module) {
|
||||
expect(noLongerUntitledDocument.isDirty).toBe(false);
|
||||
expect(noLongerUntitledDocument.isUntitled()).toBe(false);
|
||||
expect(noLongerUntitledDocument.file.fullPath).toEqual(newFilePath);
|
||||
expect(DocumentManager.findInWorkingSet(newFilePath)).toBeGreaterThan(-1);
|
||||
expect(DocumentManager.getWorkingSet().length).toEqual(1); // no remnant of untitled doc left
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, newFilePath)).toNotEqual(-1);
|
||||
expect(MainViewManager.getWorkingSet(MainViewManager.ALL_PANES).length).toEqual(1); // no remnant of untitled doc left
|
||||
|
||||
// Verify file exists, & clean up
|
||||
expectAndDelete(newFilePath);
|
||||
@ -302,7 +306,7 @@ define(function (require, exports, module) {
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
expect(DocumentManager.getWorkingSet().length).toEqual(0);
|
||||
expect(MainViewManager.getWorkingSet(MainViewManager.ALL_PANES).length).toEqual(0);
|
||||
|
||||
// Verify file exists, & clean up
|
||||
expectAndDelete(newFilePath);
|
||||
@ -335,7 +339,7 @@ define(function (require, exports, module) {
|
||||
|
||||
expect(untitledDocument.isDirty).toBe(true);
|
||||
expect(untitledDocument.isUntitled()).toBe(true);
|
||||
expect(DocumentManager.findInWorkingSet(untitledDocument.file.fullPath)).toBeGreaterThan(-1);
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, untitledDocument.file.fullPath)).toNotEqual(-1);
|
||||
});
|
||||
});
|
||||
|
||||
@ -369,7 +373,7 @@ define(function (require, exports, module) {
|
||||
|
||||
expect(untitledDocument.isDirty).toBe(true);
|
||||
expect(untitledDocument.isUntitled()).toBe(true);
|
||||
expect(DocumentManager.findInWorkingSet(untitledDocument.file.fullPath)).toBeGreaterThan(-1);
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, untitledDocument.file.fullPath)).toNotEqual(-1);
|
||||
});
|
||||
});
|
||||
|
||||
@ -395,7 +399,7 @@ define(function (require, exports, module) {
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
expect(DocumentManager.getWorkingSet().length).toEqual(0);
|
||||
expect(MainViewManager.getWorkingSet(MainViewManager.ALL_PANES).length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
@ -413,7 +417,7 @@ define(function (require, exports, module) {
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
expect(DocumentManager.getWorkingSet().length).toEqual(0);
|
||||
expect(MainViewManager.getWorkingSet(MainViewManager.ALL_PANES).length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
@ -424,28 +428,28 @@ define(function (require, exports, module) {
|
||||
createUntitled(3);
|
||||
|
||||
runs(function () {
|
||||
var workingSetDocs = getWorkingSetDocs();
|
||||
expect(workingSetDocs.length).toEqual(3);
|
||||
var workingSetListDocs = getOpenDocsFromWorkingSet();
|
||||
expect(workingSetListDocs.length).toEqual(3);
|
||||
|
||||
// Expect non-conflicting dummy paths
|
||||
expect(workingSetDocs[0].file.fullPath).not.toBe(workingSetDocs[1].file.fullPath);
|
||||
expect(workingSetDocs[0].file.fullPath).not.toBe(workingSetDocs[2].file.fullPath);
|
||||
expect(workingSetDocs[1].file.fullPath).not.toBe(workingSetDocs[2].file.fullPath);
|
||||
expect(workingSetListDocs[0].file.fullPath).not.toBe(workingSetListDocs[1].file.fullPath);
|
||||
expect(workingSetListDocs[0].file.fullPath).not.toBe(workingSetListDocs[2].file.fullPath);
|
||||
expect(workingSetListDocs[1].file.fullPath).not.toBe(workingSetListDocs[2].file.fullPath);
|
||||
|
||||
// Expect separate Document objects
|
||||
expect(workingSetDocs[0]).not.toBe(workingSetDocs[1]);
|
||||
expect(workingSetDocs[0]).not.toBe(workingSetDocs[2]);
|
||||
expect(workingSetDocs[1]).not.toBe(workingSetDocs[2]);
|
||||
expect(workingSetListDocs[0]).not.toBe(workingSetListDocs[1]);
|
||||
expect(workingSetListDocs[0]).not.toBe(workingSetListDocs[2]);
|
||||
expect(workingSetListDocs[1]).not.toBe(workingSetListDocs[2]);
|
||||
|
||||
// Expect all Documents to be untitled
|
||||
workingSetDocs.forEach(function (doc) {
|
||||
workingSetListDocs.forEach(function (doc) {
|
||||
expect(doc.isUntitled()).toBe(true);
|
||||
});
|
||||
|
||||
// Expect separate, unique content
|
||||
expect(workingSetDocs[0].getText()).toBe("0");
|
||||
expect(workingSetDocs[1].getText()).toBe("1");
|
||||
expect(workingSetDocs[2].getText()).toBe("2");
|
||||
expect(workingSetListDocs[0].getText()).toBe("0");
|
||||
expect(workingSetListDocs[1].getText()).toBe("1");
|
||||
expect(workingSetListDocs[2].getText()).toBe("2");
|
||||
});
|
||||
});
|
||||
|
||||
@ -469,17 +473,17 @@ define(function (require, exports, module) {
|
||||
|
||||
runs(function () {
|
||||
// Expect clean Documents with correct, unique non-dummy paths
|
||||
var workingSetDocs = getWorkingSetDocs();
|
||||
expect(workingSetDocs.length).toEqual(3);
|
||||
var workingSetListDocs = getOpenDocsFromWorkingSet();
|
||||
expect(workingSetListDocs.length).toEqual(3);
|
||||
|
||||
workingSetDocs.forEach(function (doc, i) {
|
||||
workingSetListDocs.forEach(function (doc, i) {
|
||||
expect(doc.isUntitled()).toBe(false);
|
||||
expect(doc.isDirty).toBe(false);
|
||||
expect(doc.file.fullPath).toBe(getFilename(i));
|
||||
});
|
||||
|
||||
// Verify files exist & clean up
|
||||
workingSetDocs.forEach(function (doc, i) {
|
||||
workingSetListDocs.forEach(function (doc, i) {
|
||||
expectAndDelete(getFilename(i));
|
||||
});
|
||||
});
|
||||
@ -508,7 +512,7 @@ define(function (require, exports, module) {
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
expect(DocumentManager.getWorkingSet().length).toEqual(0);
|
||||
expect(MainViewManager.getWorkingSet(MainViewManager.ALL_PANES).length).toEqual(0);
|
||||
|
||||
// Verify files exist & clean up
|
||||
[0, 1, 2].forEach(function (i) {
|
||||
@ -546,10 +550,10 @@ define(function (require, exports, module) {
|
||||
|
||||
runs(function () {
|
||||
// Expect *only* first Document was saved - others remain untitled & dirty
|
||||
var workingSetDocs = getWorkingSetDocs();
|
||||
expect(workingSetDocs.length).toEqual(3);
|
||||
var workingSetListDocs = getOpenDocsFromWorkingSet();
|
||||
expect(workingSetListDocs.length).toEqual(3);
|
||||
|
||||
workingSetDocs.forEach(function (doc, i) {
|
||||
workingSetListDocs.forEach(function (doc, i) {
|
||||
if (i === 0) {
|
||||
// First file was saved when we confirmed save dialog
|
||||
expect(doc.isUntitled()).toBe(false);
|
||||
@ -601,10 +605,10 @@ define(function (require, exports, module) {
|
||||
|
||||
runs(function () {
|
||||
// Expect *all* Documents still open, and *only* first Document was saved
|
||||
var workingSetDocs = getWorkingSetDocs();
|
||||
expect(workingSetDocs.length).toEqual(3);
|
||||
var workingSetListDocs = getOpenDocsFromWorkingSet();
|
||||
expect(workingSetListDocs.length).toEqual(3);
|
||||
|
||||
workingSetDocs.forEach(function (doc, i) {
|
||||
workingSetListDocs.forEach(function (doc, i) {
|
||||
if (i === 0) {
|
||||
// First file was saved when we confirmed save dialog
|
||||
expect(doc.isUntitled()).toBe(false);
|
||||
@ -824,7 +828,7 @@ define(function (require, exports, module) {
|
||||
|
||||
runs(function () {
|
||||
// New file should not appear in working set
|
||||
expect(DocumentManager.findInWorkingSet(newFilePath)).toEqual(-1);
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, newFilePath)).toEqual(-1);
|
||||
|
||||
// Verify file exists & clean it up
|
||||
expectAndDelete(newFilePath);
|
||||
@ -862,8 +866,8 @@ define(function (require, exports, module) {
|
||||
|
||||
runs(function () {
|
||||
// Only new file should appear in working set
|
||||
expect(DocumentManager.findInWorkingSet(newFilePath)).toBeGreaterThan(-1);
|
||||
expect(DocumentManager.findInWorkingSet(filePath)).toEqual(-1);
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, newFilePath)).toNotEqual(-1);
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, filePath)).toEqual(-1);
|
||||
|
||||
// Verify file exists & clean it up
|
||||
expectAndDelete(newFilePath);
|
||||
@ -897,12 +901,12 @@ define(function (require, exports, module) {
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
expect(DocumentManager.findInWorkingSet(newFilePath)).toEqual(-1);
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, newFilePath)).toEqual(-1);
|
||||
});
|
||||
});
|
||||
|
||||
it("should maintain order within Working Set after Save As", function () {
|
||||
var index,
|
||||
var views,
|
||||
targetDoc;
|
||||
|
||||
runs(function () {
|
||||
@ -913,7 +917,7 @@ define(function (require, exports, module) {
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
index = DocumentManager.findInWorkingSet(filePath);
|
||||
views = MainViewManager.findInAllWorkingSets(filePath);
|
||||
targetDoc = DocumentManager.getOpenDocumentForPath(filePath);
|
||||
});
|
||||
|
||||
@ -926,8 +930,7 @@ define(function (require, exports, module) {
|
||||
|
||||
runs(function () {
|
||||
// save the file opened above to a different filename
|
||||
DocumentManager.setCurrentDocument(targetDoc);
|
||||
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, targetDoc);
|
||||
spyOn(FileSystem, 'showSaveDialog').andCallFake(function (dialogTitle, initialPath, proposedNewName, callback) {
|
||||
callback(undefined, newFilePath);
|
||||
});
|
||||
@ -938,8 +941,8 @@ define(function (require, exports, module) {
|
||||
|
||||
runs(function () {
|
||||
// New file should appear in working set at old file's index; old file shouldn't appear at all
|
||||
expect(DocumentManager.findInWorkingSet(newFilePath)).toEqual(index);
|
||||
expect(DocumentManager.findInWorkingSet(filePath)).toEqual(-1);
|
||||
expect(MainViewManager.findInAllWorkingSets(newFilePath)).toEqual(views);
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, filePath)).toEqual(-1);
|
||||
|
||||
// Verify file exists & clean it up
|
||||
expectAndDelete(newFilePath);
|
||||
@ -1102,6 +1105,10 @@ define(function (require, exports, module) {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
TODO: Disabled until image support is added for splitview
|
||||
|
||||
describe("Opens image file and validates EditorManager APIs", function () {
|
||||
it("should return null after opening an image", function () {
|
||||
var path = testPath + "/couz.png",
|
||||
@ -1115,7 +1122,7 @@ define(function (require, exports, module) {
|
||||
expect(EditorManager.getActiveEditor()).toEqual(null);
|
||||
expect(EditorManager.getCurrentFullEditor()).toEqual(null);
|
||||
expect(EditorManager.getFocusedEditor()).toEqual(null);
|
||||
expect(EditorManager.getCurrentlyViewedPath()).toEqual(path);
|
||||
expect(MainViewManager.getCurrentlyViewedPath(MainViewManager.ACTIVE_PANE)).toEqual(path);
|
||||
var d = DocumentManager.getCurrentDocument();
|
||||
expect(d).toEqual(null);
|
||||
});
|
||||
@ -1187,7 +1194,7 @@ define(function (require, exports, module) {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
*/
|
||||
describe("Open a text file while a text file is open", function () {
|
||||
it("should fire currentDocumentChange and activeEditorChange events", function () {
|
||||
|
||||
@ -1267,7 +1274,8 @@ define(function (require, exports, module) {
|
||||
e = EditorManager.getFocusedEditor();
|
||||
expect(e.document.file.fullPath).toBe(path);
|
||||
|
||||
expect(EditorManager.getCurrentlyViewedPath()).toEqual(path);
|
||||
e = EditorManager.getCurrentFullEditor();
|
||||
expect(e.document.file.fullPath).toBe(path);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -40,6 +40,7 @@ define(function (require, exports, module) {
|
||||
this.category = "integration";
|
||||
|
||||
var testPath = SpecRunnerUtils.getTestPath("/spec/DocumentCommandHandlers-test-files"),
|
||||
testFile = testPath + "/test.js",
|
||||
testWindow,
|
||||
_$,
|
||||
promise;
|
||||
@ -63,6 +64,7 @@ define(function (require, exports, module) {
|
||||
CommandManager = null;
|
||||
Commands = null;
|
||||
DocumentManager = null;
|
||||
EditorManager = null;
|
||||
SpecRunnerUtils.closeTestWindow();
|
||||
});
|
||||
|
||||
@ -80,48 +82,46 @@ define(function (require, exports, module) {
|
||||
// Call closeAll() directly. Some tests set a spy on the save as
|
||||
// dialog preventing SpecRunnerUtils.closeAllFiles() from
|
||||
// working properly.
|
||||
testWindow.brackets.test.DocumentManager.closeAll();
|
||||
testWindow.brackets.test.MainViewManager._closeAll(testWindow.brackets.test.MainViewManager.ALL_PANES);
|
||||
});
|
||||
});
|
||||
|
||||
describe("_clearCurrentDocument ", function () {
|
||||
it("should fire currentDocumentChange", function () {
|
||||
var docChangeListener = jasmine.createSpy();
|
||||
|
||||
describe("openDocument ", function () {
|
||||
it("Should report document in open documents list", function () {
|
||||
|
||||
runs(function () {
|
||||
_$(DocumentManager).on("currentDocumentChange", docChangeListener);
|
||||
expect(docChangeListener.callCount).toBe(0);
|
||||
promise = CommandManager.execute(Commands.FILE_OPEN, { fullPath: testPath + "/test.js" });
|
||||
promise = CommandManager.execute(Commands.FILE_OPEN, { fullPath: testFile });
|
||||
waitsForDone(promise, Commands.FILE_OPEN);
|
||||
});
|
||||
runs(function () {
|
||||
expect(docChangeListener.callCount).toBe(1);
|
||||
DocumentManager._clearCurrentDocument();
|
||||
expect(docChangeListener.callCount).toBe(2);
|
||||
|
||||
_$(DocumentManager).off("currentDocumentChange", docChangeListener);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("After _clearCurrentDocument ", function () {
|
||||
it("getCurrentDocument should return null ", function () {
|
||||
|
||||
runs(function () {
|
||||
promise = CommandManager.execute(Commands.FILE_OPEN, { fullPath: testPath + "/test.js" });
|
||||
waitsForDone(promise, Commands.FILE_OPEN);
|
||||
});
|
||||
runs(function () {
|
||||
expect(DocumentManager.getCurrentDocument()).toBeTruthy();
|
||||
DocumentManager._clearCurrentDocument();
|
||||
expect(DocumentManager.getCurrentDocument()).toBe(null);
|
||||
expect(DocumentManager.getOpenDocumentForPath(testFile)).toBeTruthy();
|
||||
expect(DocumentManager.getAllOpenDocuments().length).toEqual(1);
|
||||
expect(DocumentManager.getCurrentDocument().file.fullPath).toEqual(testFile);
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
promise = DocumentManager.getDocumentText({ fullPath: testFile });
|
||||
waitsForDone(promise, "DocumentManager.getDocumentText");
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
promise = CommandManager.execute(Commands.FILE_CLOSE_ALL);
|
||||
waitsForDone(promise, Commands.FILE_CLOSE_ALL);
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
expect(DocumentManager.getAllOpenDocuments().length).toEqual(0);
|
||||
expect(DocumentManager.getCurrentDocument()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
it("Should create a new untitled document", function () {
|
||||
runs(function () {
|
||||
var doc = DocumentManager.createUntitledDocument(1, ".txt");
|
||||
expect(doc).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
@ -32,6 +32,7 @@ define(function (require, exports, module) {
|
||||
var DocumentManager, // loaded from brackets.test
|
||||
DragAndDrop, // loaded from brackets.test
|
||||
EditorManager, // loaded from brackets.test
|
||||
MainViewManager, // loaded from brackets.test
|
||||
SpecRunnerUtils = require("spec/SpecRunnerUtils");
|
||||
|
||||
|
||||
@ -52,6 +53,7 @@ define(function (require, exports, module) {
|
||||
DocumentManager = testWindow.brackets.test.DocumentManager;
|
||||
DragAndDrop = testWindow.brackets.test.DragAndDrop;
|
||||
EditorManager = testWindow.brackets.test.EditorManager;
|
||||
MainViewManager = testWindow.brackets.test.MainViewManager;
|
||||
});
|
||||
});
|
||||
|
||||
@ -60,6 +62,7 @@ define(function (require, exports, module) {
|
||||
DocumentManager = null;
|
||||
DragAndDrop = null;
|
||||
EditorManager = null;
|
||||
MainViewManager = null;
|
||||
SpecRunnerUtils.closeTestWindow();
|
||||
});
|
||||
|
||||
@ -77,11 +80,17 @@ define(function (require, exports, module) {
|
||||
// Call closeAll() directly. Some tests set a spy on the save as
|
||||
// dialog preventing SpecRunnerUtils.closeAllFiles() from
|
||||
// working properly.
|
||||
testWindow.brackets.test.DocumentManager.closeAll();
|
||||
testWindow.brackets.test.MainViewManager._closeAll(testWindow.brackets.test.MainViewManager.ALL_PANES);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Testing openDroppedFiles function", function () {
|
||||
it("should activate a pane on drag over", function () {
|
||||
MainViewManager.setLayoutScheme(1, 2);
|
||||
var $paneEl = _$("#second-pane");
|
||||
$paneEl.triggerHandler("dragover");
|
||||
expect(MainViewManager.getActivePaneId()).toBe("second-pane");
|
||||
});
|
||||
|
||||
it("should NOT open any image file when a text file is in the dropped file list", function () {
|
||||
var jsFilePath = testPath + "/test.js";
|
||||
@ -94,7 +103,7 @@ define(function (require, exports, module) {
|
||||
runs(function () {
|
||||
var editor = EditorManager.getActiveEditor();
|
||||
expect(editor.document.file.fullPath).toBe(jsFilePath);
|
||||
expect(EditorManager.getCurrentlyViewedPath()).toEqual(jsFilePath);
|
||||
expect(MainViewManager.getCurrentlyViewedPath(MainViewManager.ACTIVE_PANE)).toEqual(jsFilePath);
|
||||
});
|
||||
});
|
||||
|
||||
@ -108,7 +117,7 @@ define(function (require, exports, module) {
|
||||
runs(function () {
|
||||
var editor = EditorManager.getActiveEditor();
|
||||
expect(editor).toBe(null);
|
||||
expect(EditorManager.getCurrentlyViewedPath()).toEqual(path);
|
||||
expect(MainViewManager.getCurrentlyViewedPath(MainViewManager.ACTIVE_PANE)).toEqual(path);
|
||||
});
|
||||
});
|
||||
|
||||
@ -123,10 +132,23 @@ define(function (require, exports, module) {
|
||||
runs(function () {
|
||||
var editor = EditorManager.getActiveEditor();
|
||||
expect(editor).toBe(null);
|
||||
expect(EditorManager.getCurrentlyViewedPath()).toEqual(lastImagePath);
|
||||
expect(MainViewManager.getCurrentlyViewedPath(MainViewManager.ACTIVE_PANE)).toEqual(lastImagePath);
|
||||
});
|
||||
});
|
||||
|
||||
it("should add images to the working set when they dropped from outside the project", function () {
|
||||
var imagesPath = SpecRunnerUtils.getTestPath("/spec/test-image-files");
|
||||
runs(function () {
|
||||
var files = [imagesPath + "/thermo.jpg", imagesPath + "/check.png"];
|
||||
promise = DragAndDrop.openDroppedFiles(files);
|
||||
waitsForDone(promise, "opening last image file from the dropped files");
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, imagesPath + "/thermo.jpg")).toNotEqual(-1);
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, imagesPath + "/check.png")).toNotEqual(-1);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
7
test/spec/EditorCommandHandlers-test-files/test.js
Normal file
@ -0,0 +1,7 @@
|
||||
function testMe() {
|
||||
console.log("this is a test");
|
||||
}
|
||||
|
||||
function main() {
|
||||
testMe();
|
||||
}
|
@ -131,7 +131,7 @@ define(function (require, exports, module) {
|
||||
var promise;
|
||||
|
||||
runs(function () {
|
||||
promise = CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: testPath + "/test.html"});
|
||||
promise = CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, {fullPath: testPath + "/test.html"});
|
||||
waitsForDone(promise, "Open into working set");
|
||||
});
|
||||
|
||||
@ -3759,6 +3759,29 @@ define(function (require, exports, module) {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Editor Navigation Commands", function () {
|
||||
it("should jump to definition", function () {
|
||||
var promise,
|
||||
selection;
|
||||
runs(function () {
|
||||
promise = CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, {fullPath: testPath + "/test.js"});
|
||||
waitsForDone(promise, "Open into working set");
|
||||
});
|
||||
runs(function () {
|
||||
myEditor = EditorManager.getCurrentFullEditor();
|
||||
myEditor.setCursorPos({line: 5, ch: 8});
|
||||
promise = CommandManager.execute(Commands.NAVIGATE_JUMPTO_DEFINITION);
|
||||
waitsForDone(promise, "Jump To Definition");
|
||||
});
|
||||
runs(function () {
|
||||
selection = myEditor.getSelection();
|
||||
expect(selection).toEqual({start: {line: 0, ch: 9},
|
||||
end: {line: 0, ch: 15},
|
||||
reversed: false});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("Open Line Above and Below - inline editor", function () {
|
||||
|
||||
|
@ -29,14 +29,13 @@ define(function (require, exports, module) {
|
||||
'use strict';
|
||||
|
||||
var EditorManager = require("editor/EditorManager"),
|
||||
PanelManager = require("view/PanelManager"),
|
||||
WorkspaceManager = require("view/WorkspaceManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
ViewStateManager = require("view/ViewStateManager"),
|
||||
SpecRunnerUtils = require("spec/SpecRunnerUtils");
|
||||
|
||||
describe("EditorManager", function () {
|
||||
|
||||
describe("resizeEditor() flag options", function () {
|
||||
var testEditor, testDoc, $root, $fakeContentDiv;
|
||||
|
||||
var pane, testEditor, testDoc, $fakeContentDiv, $fakeHolder;
|
||||
beforeEach(function () {
|
||||
// Normally the editor holder would be created inside a "content" div, which is
|
||||
// used in the available height calculation. We create a fake content div just to
|
||||
@ -45,165 +44,111 @@ define(function (require, exports, module) {
|
||||
.css("height", "200px")
|
||||
.appendTo(document.body);
|
||||
|
||||
// createMockEditor() creates the mock-editor-holder, and links EditorManager/PanelManager
|
||||
// to it (and links PanelManager to our content div)
|
||||
var mock = SpecRunnerUtils.createMockEditor("");
|
||||
|
||||
// move newly created mock-editor-holder into the content div we created above
|
||||
$("#mock-editor-holder")
|
||||
$fakeHolder = SpecRunnerUtils.createMockElement()
|
||||
.css("width", "1000px")
|
||||
.attr("id", "hidden-editors")
|
||||
.appendTo($fakeContentDiv);
|
||||
|
||||
testEditor = mock.editor;
|
||||
testDoc = mock.doc;
|
||||
$root = $(testEditor.getRootElement());
|
||||
|
||||
testDoc._masterEditor = testEditor;
|
||||
EditorManager._doShow(testDoc);
|
||||
pane = SpecRunnerUtils.createMockPane($fakeHolder);
|
||||
testDoc = SpecRunnerUtils.createMockDocument("");
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
$fakeHolder.remove();
|
||||
$fakeHolder = null;
|
||||
|
||||
$fakeContentDiv.remove();
|
||||
$fakeContentDiv = null;
|
||||
|
||||
SpecRunnerUtils.destroyMockEditor(testDoc);
|
||||
testEditor = null;
|
||||
testDoc = null;
|
||||
$root = null;
|
||||
pane = null;
|
||||
ViewStateManager.reset();
|
||||
});
|
||||
|
||||
// force cases
|
||||
it("should refresh if force is specified even if no width or height change", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
EditorManager.resizeEditor(); // cache the width
|
||||
describe("Create Editors", function () {
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
PanelManager._notifyLayoutChange(EditorManager.REFRESH_FORCE);
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
it("should create a new editor for a document and add it to a pane", function () {
|
||||
spyOn(pane, "addView");
|
||||
EditorManager.openDocument(testDoc, pane);
|
||||
expect(pane.addView).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should refresh if force is specified when width changed but height hasn't", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
EditorManager.resizeEditor(); // cache the width
|
||||
$root.width(300); // change the width
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
PanelManager._notifyLayoutChange(EditorManager.REFRESH_FORCE);
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
it("should use an existing editor for a document and show the editor", function () {
|
||||
spyOn(pane, "addView");
|
||||
spyOn(pane, "showView");
|
||||
var editor = SpecRunnerUtils.createEditorInstance(testDoc, pane.$el);
|
||||
EditorManager.openDocument(testDoc, pane);
|
||||
expect(pane.addView).toHaveBeenCalled();
|
||||
expect(pane.showView).toHaveBeenCalled();
|
||||
expect(pane.addView.calls[0].args[0]).toEqual(editor);
|
||||
});
|
||||
|
||||
it("should refresh if force is specified when height changed but width hasn't", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
EditorManager.resizeEditor(); // cache the width
|
||||
$root.height(300); // change the height (to be different from content div)
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
PanelManager._notifyLayoutChange(EditorManager.REFRESH_FORCE);
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should refresh if force is specified when both height and width changed", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
EditorManager.resizeEditor(); // cache the width
|
||||
$root.height(300); // change the height (to be different from content div)
|
||||
$root.width(300); // change the width
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
PanelManager._notifyLayoutChange(EditorManager.REFRESH_FORCE);
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
});
|
||||
describe("ViewStateManager", function () {
|
||||
var pane, testEditor, testDoc, $fakeContentDiv, $fakeHolder;
|
||||
beforeEach(function () {
|
||||
// Normally the editor holder would be created inside a "content" div, which is
|
||||
// used in the available height calculation. We create a fake content div just to
|
||||
// hold the height, and we'll place the editor holder in it.
|
||||
$fakeContentDiv = $("<div class='content'/>")
|
||||
.css("height", "200px")
|
||||
.appendTo(document.body);
|
||||
|
||||
// skip cases
|
||||
it("should NOT refresh if skip is specified if no width or height change", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
EditorManager.resizeEditor(); // cache the width
|
||||
$fakeHolder = SpecRunnerUtils.createMockElement()
|
||||
.css("width", "1000px")
|
||||
.attr("id", "hidden-editors")
|
||||
.appendTo($fakeContentDiv);
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
PanelManager._notifyLayoutChange(EditorManager.REFRESH_SKIP);
|
||||
expect(testEditor.refreshAll).not.toHaveBeenCalled();
|
||||
pane = SpecRunnerUtils.createMockPane($fakeHolder);
|
||||
testDoc = SpecRunnerUtils.createMockDocument("");
|
||||
});
|
||||
afterEach(function () {
|
||||
$fakeHolder.remove();
|
||||
$fakeHolder = null;
|
||||
|
||||
it("should NOT refresh if skip is specified when width changed but height hasn't", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
EditorManager.resizeEditor(); // cache the width
|
||||
$root.width(300); // change the width
|
||||
$fakeContentDiv.remove();
|
||||
$fakeContentDiv = null;
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
PanelManager._notifyLayoutChange(EditorManager.REFRESH_SKIP);
|
||||
expect(testEditor.refreshAll).not.toHaveBeenCalled();
|
||||
SpecRunnerUtils.destroyMockEditor(testDoc);
|
||||
testEditor = null;
|
||||
testDoc = null;
|
||||
pane = null;
|
||||
ViewStateManager.reset();
|
||||
});
|
||||
|
||||
it("should NOT refresh if skip is specified when height changed but width hasn't", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
EditorManager.resizeEditor(); // cache the width
|
||||
$root.height(300); // change the height (to be different from content div)
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
PanelManager._notifyLayoutChange(EditorManager.REFRESH_SKIP);
|
||||
expect(testEditor.refreshAll).not.toHaveBeenCalled();
|
||||
describe("Save/Restore View State", function () {
|
||||
it("should remember a file's view state", function () {
|
||||
ViewStateManager.addViewStates({ a: "1234" });
|
||||
expect(ViewStateManager.getViewState({fullPath: "a"})).toEqual("1234");
|
||||
ViewStateManager.addViewStates({ b: "Jeff was here" });
|
||||
expect(ViewStateManager.getViewState({fullPath: "B"})).toBeUndefined();
|
||||
expect(ViewStateManager.getViewState({fullPath: "b"})).toEqual("Jeff was here");
|
||||
});
|
||||
|
||||
it("should NOT refresh if skip is specified when both height and width changed", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
EditorManager.resizeEditor(); // cache the width
|
||||
$root.height(300); // change the height (to be different from content div)
|
||||
$root.width(300); // change the width
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
PanelManager._notifyLayoutChange(EditorManager.REFRESH_SKIP);
|
||||
expect(testEditor.refreshAll).not.toHaveBeenCalled();
|
||||
it("should extend the view state cache", function () {
|
||||
ViewStateManager.addViewStates({ a: "1234" });
|
||||
ViewStateManager.addViewStates({ b: "5678" });
|
||||
expect(ViewStateManager.getViewState({fullPath: "a"})).toEqual("1234");
|
||||
expect(ViewStateManager.getViewState({fullPath: "b"})).toEqual("5678");
|
||||
});
|
||||
|
||||
// unspecified cases
|
||||
it("should NOT refresh if unspecified if no width or height change", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
EditorManager.resizeEditor(); // cache the width
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
PanelManager._notifyLayoutChange();
|
||||
expect(testEditor.refreshAll).not.toHaveBeenCalled();
|
||||
it("should reset the view state cache", function () {
|
||||
ViewStateManager.addViewStates({ a: "1234" });
|
||||
ViewStateManager.addViewStates({ b: "5678" });
|
||||
ViewStateManager.reset();
|
||||
expect(ViewStateManager.getViewState({fullPath: "a"})).toBeUndefined();
|
||||
expect(ViewStateManager.getViewState({fullPath: "b"})).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should refresh if unspecified when width changed but height hasn't", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
EditorManager.resizeEditor(); // cache the width
|
||||
$root.width(300); // change the width
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
PanelManager._notifyLayoutChange();
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should refresh if unspecified when height changed but width hasn't", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
EditorManager.resizeEditor(); // cache the width
|
||||
$root.height(300); // change the height (to be different from content div)
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
PanelManager._notifyLayoutChange();
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should refresh if unspecified when both height and width changed", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
EditorManager.resizeEditor(); // cache the width
|
||||
$root.height(300); // change the height (to be different from content div)
|
||||
$root.width(300); // change the width
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
PanelManager._notifyLayoutChange();
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
it("should update the view state cache", function () {
|
||||
var myView = {
|
||||
getFile: function () {
|
||||
return {
|
||||
fullPath: "a"
|
||||
};
|
||||
},
|
||||
getViewState: function () {
|
||||
return "1234";
|
||||
}
|
||||
};
|
||||
ViewStateManager.updateViewState(myView);
|
||||
expect(ViewStateManager.getViewState({fullPath: "a"})).toEqual("1234");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -168,7 +168,7 @@ define(function (require, exports, module) {
|
||||
// Helper functions to open editors / toggle options
|
||||
function openEditor(fullPath) {
|
||||
runs(function () {
|
||||
var promise = CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: fullPath});
|
||||
var promise = CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, {fullPath: fullPath});
|
||||
waitsForDone(promise, "Open into working set");
|
||||
});
|
||||
}
|
||||
|
182
test/spec/EditorRedraw-test.js
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
|
||||
/*global define, describe, it, spyOn, expect, beforeEach, afterEach, waitsFor, runs, $ */
|
||||
|
||||
define(function (require, exports, module) {
|
||||
'use strict';
|
||||
|
||||
var EditorManager = require("editor/EditorManager"),
|
||||
WorkspaceManager = require("view/WorkspaceManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
SpecRunnerUtils = require("spec/SpecRunnerUtils");
|
||||
|
||||
describe("Editor Redrawing", function () {
|
||||
var testEditor, testDoc, $root;
|
||||
beforeEach(function () {
|
||||
testDoc = SpecRunnerUtils.createMockDocument("");
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, testDoc);
|
||||
testEditor = testDoc._masterEditor;
|
||||
$root = $(testEditor.getRootElement());
|
||||
WorkspaceManager._setMockDOM($("#mock-main-view"), $root.parent());
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
MainViewManager._closeAll(MainViewManager.ALL_PANES);
|
||||
SpecRunnerUtils.destroyMockEditor(testDoc);
|
||||
testEditor = null;
|
||||
testDoc = null;
|
||||
$root = null;
|
||||
WorkspaceManager._setMockDOM(undefined, undefined);
|
||||
});
|
||||
|
||||
// force cases
|
||||
describe("Editor Redraw Perforamnce", function () {
|
||||
it("should refresh if force is specified even if no width or height change", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
spyOn(testEditor, "refreshAll");
|
||||
WorkspaceManager.recomputeLayout(true);
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
});
|
||||
it("should refresh if force is specified when width changed but height hasn't", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
WorkspaceManager.recomputeLayout();
|
||||
$root.width(300); // change the width
|
||||
spyOn(testEditor, "refreshAll");
|
||||
WorkspaceManager.recomputeLayout(true);
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
});
|
||||
it("should refresh if force is specified when height changed but width hasn't", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
WorkspaceManager.recomputeLayout();
|
||||
$root.height(300); // change the height (to be different from content div)
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
WorkspaceManager.recomputeLayout(true);
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
});
|
||||
it("should refresh if force is specified when both height and width changed", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
WorkspaceManager.recomputeLayout();
|
||||
$root.height(300); // change the height (to be different from content div)
|
||||
$root.width(300); // change the width
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
WorkspaceManager.recomputeLayout(true);
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
});
|
||||
// skip cases
|
||||
it("should NOT refresh if skip is specified if no width or height change", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
WorkspaceManager.recomputeLayout();
|
||||
spyOn(testEditor, "refreshAll");
|
||||
WorkspaceManager.recomputeLayout(false);
|
||||
expect(testEditor.refreshAll).not.toHaveBeenCalled();
|
||||
});
|
||||
it("should NOT refresh if skip is specified when width changed but height hasn't", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
WorkspaceManager.recomputeLayout();
|
||||
$root.width(300); // change the width
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
WorkspaceManager.recomputeLayout(false);
|
||||
expect(testEditor.refreshAll).not.toHaveBeenCalled();
|
||||
});
|
||||
it("should NOT refresh if skip is specified when height changed but width hasn't", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
WorkspaceManager.recomputeLayout();
|
||||
$root.height(300); // change the height (to be different from content div)
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
WorkspaceManager.recomputeLayout(false);
|
||||
expect(testEditor.refreshAll).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should NOT refresh if skip is specified when both height and width changed", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
WorkspaceManager.recomputeLayout();
|
||||
$root.height(300); // change the height (to be different from content div)
|
||||
$root.width(300); // change the width
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
WorkspaceManager.recomputeLayout(false);
|
||||
expect(testEditor.refreshAll).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// unspecified cases
|
||||
it("should NOT refresh if unspecified if no width or height change", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
WorkspaceManager.recomputeLayout();
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
WorkspaceManager.recomputeLayout();
|
||||
expect(testEditor.refreshAll).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should refresh if unspecified when width changed but height hasn't", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
WorkspaceManager.recomputeLayout();
|
||||
$root.width(300); // change the width
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
WorkspaceManager.recomputeLayout();
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should refresh if unspecified when height changed but width hasn't", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
WorkspaceManager.recomputeLayout();
|
||||
$root.height(300); // change the height (to be different from content div)
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
WorkspaceManager.recomputeLayout();
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should refresh if unspecified when both height and width changed", function () {
|
||||
$root.height(200); // same as content div, so shouldn't be detected as a change
|
||||
$root.width(200);
|
||||
WorkspaceManager.recomputeLayout();
|
||||
$root.height(300); // change the height (to be different from content div)
|
||||
$root.width(300); // change the width
|
||||
|
||||
spyOn(testEditor, "refreshAll");
|
||||
WorkspaceManager.recomputeLayout();
|
||||
expect(testEditor.refreshAll).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -52,6 +52,7 @@ define(function (require, exports, module) {
|
||||
searchResults,
|
||||
CommandManager,
|
||||
DocumentManager,
|
||||
MainViewManager,
|
||||
EditorManager,
|
||||
FileFilters,
|
||||
FileSystem,
|
||||
@ -79,6 +80,7 @@ define(function (require, exports, module) {
|
||||
FindInFiles = testWindow.brackets.test.FindInFiles;
|
||||
FindInFilesUI = testWindow.brackets.test.FindInFilesUI;
|
||||
ProjectManager = testWindow.brackets.test.ProjectManager;
|
||||
MainViewManager = testWindow.brackets.test.MainViewManager;
|
||||
$ = testWindow.$;
|
||||
});
|
||||
});
|
||||
@ -92,6 +94,7 @@ define(function (require, exports, module) {
|
||||
FindInFiles = null;
|
||||
FindInFilesUI = null;
|
||||
ProjectManager = null;
|
||||
MainViewManager = null;
|
||||
$ = null;
|
||||
testWindow = null;
|
||||
SpecRunnerUtils.closeTestWindow();
|
||||
@ -496,7 +499,7 @@ define(function (require, exports, module) {
|
||||
|
||||
runs(function () {
|
||||
// Verify document is not yet in working set
|
||||
expect(DocumentManager.findInWorkingSet(filePath)).toBe(-1);
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, filePath)).toBe(-1);
|
||||
|
||||
// Get list in panel
|
||||
var $panelResults = $("#find-in-files-results table.bottom-panel-table tr");
|
||||
@ -508,7 +511,7 @@ define(function (require, exports, module) {
|
||||
$firstHit.dblclick();
|
||||
|
||||
// Verify document is now in working set
|
||||
expect(DocumentManager.findInWorkingSet(filePath)).not.toBe(-1);
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, filePath)).not.toBe(-1);
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_CLOSE_ALL), "closing all files");
|
||||
});
|
||||
});
|
||||
@ -524,7 +527,7 @@ define(function (require, exports, module) {
|
||||
|
||||
runs(function () {
|
||||
// Verify document is not yet in working set
|
||||
expect(DocumentManager.findInWorkingSet(filePath)).toBe(-1);
|
||||
expect(MainViewManager.findInWorkingSet(MainViewManager.ALL_PANES, filePath)).toBe(-1);
|
||||
|
||||
// Get list in panel
|
||||
$panelResults = $("#find-in-files-results table.bottom-panel-table tr");
|
||||
@ -782,7 +785,7 @@ define(function (require, exports, module) {
|
||||
describe("when in-memory document changes", function () {
|
||||
it("should update the results when a matching line is added, updating line numbers and adding the match", function () {
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: fullTestPath("foo.html") }));
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: fullTestPath("foo.html") }));
|
||||
});
|
||||
runs(function () {
|
||||
var doc = DocumentManager.getOpenDocumentForPath(fullTestPath("foo.html")),
|
||||
@ -823,7 +826,7 @@ define(function (require, exports, module) {
|
||||
|
||||
it("should update the results when a matching line is deleted, updating line numbers and removing the match", function () {
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: fullTestPath("foo.html") }));
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: fullTestPath("foo.html") }));
|
||||
});
|
||||
runs(function () {
|
||||
var doc = DocumentManager.getOpenDocumentForPath(fullTestPath("foo.html")),
|
||||
@ -860,7 +863,7 @@ define(function (require, exports, module) {
|
||||
|
||||
it("should replace matches in a portion of the document that was edited to include a new match", function () {
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: fullTestPath("foo.html") }));
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: fullTestPath("foo.html") }));
|
||||
});
|
||||
runs(function () {
|
||||
var doc = DocumentManager.getOpenDocumentForPath(fullTestPath("foo.html")),
|
||||
@ -901,7 +904,7 @@ define(function (require, exports, module) {
|
||||
|
||||
it("should completely remove the document from the results list if all matches in the document are deleted", function () {
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: fullTestPath("foo.html") }));
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: fullTestPath("foo.html") }));
|
||||
});
|
||||
runs(function () {
|
||||
var doc = DocumentManager.getOpenDocumentForPath(fullTestPath("foo.html")),
|
||||
@ -1292,10 +1295,10 @@ define(function (require, exports, module) {
|
||||
|
||||
// Open two of the documents we want to replace in memory.
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: testPath + "/css/foo.css" }), "opening document");
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: testPath + "/css/foo.css" }), "opening document");
|
||||
});
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: testPath + "/foo.js" }), "opening document");
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: testPath + "/foo.js" }), "opening document");
|
||||
});
|
||||
|
||||
// We can't use expectInMemoryFiles(), since this test requires everything to happen fully synchronously
|
||||
@ -1400,7 +1403,7 @@ define(function (require, exports, module) {
|
||||
openTestProjectCopy(defaultSourcePath);
|
||||
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: testPath + "/css/foo.css" }), "opening document");
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: testPath + "/css/foo.css" }), "opening document");
|
||||
});
|
||||
|
||||
doTestWithErrors({
|
||||
@ -1427,7 +1430,7 @@ define(function (require, exports, module) {
|
||||
openTestProjectCopy(defaultSourcePath);
|
||||
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: testPath + "/css/foo.css"}), "add file to working set");
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, {fullPath: testPath + "/css/foo.css"}), "add file to working set");
|
||||
});
|
||||
|
||||
doInMemoryTest({
|
||||
@ -1452,7 +1455,7 @@ define(function (require, exports, module) {
|
||||
};
|
||||
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: testPath + "/css/foo.css"}), "add file to working set");
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, {fullPath: testPath + "/css/foo.css"}), "add file to working set");
|
||||
});
|
||||
runs(function () {
|
||||
var doc = DocumentManager.getOpenDocumentForPath(testPath + "/css/foo.css");
|
||||
@ -1488,7 +1491,7 @@ define(function (require, exports, module) {
|
||||
openTestProjectCopy(defaultSourcePath);
|
||||
|
||||
runs(function () {
|
||||
DocumentManager.addToWorkingSet(FileSystem.getFileForPath(testPath + "/css/foo.css"));
|
||||
MainViewManager.addToWorkingSet(MainViewManager.ACTIVE_PANE, FileSystem.getFileForPath(testPath + "/css/foo.css"));
|
||||
});
|
||||
|
||||
doInMemoryTest({
|
||||
@ -1523,7 +1526,7 @@ define(function (require, exports, module) {
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
var workingSet = DocumentManager.getWorkingSet();
|
||||
var workingSet = MainViewManager.getWorkingSet(MainViewManager.ALL_PANES);
|
||||
expect(workingSet.some(function (file) { return file.fullPath === openFilePath; })).toBe(true);
|
||||
doc.releaseRef();
|
||||
});
|
||||
@ -1574,7 +1577,7 @@ define(function (require, exports, module) {
|
||||
openTestProjectCopy(defaultSourcePath);
|
||||
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: testPath + "/bar.txt"}), "open file");
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, {fullPath: testPath + "/bar.txt"}), "open file");
|
||||
});
|
||||
|
||||
doInMemoryTest({
|
||||
@ -1614,7 +1617,7 @@ define(function (require, exports, module) {
|
||||
openTestProjectCopy(defaultSourcePath);
|
||||
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, {fullPath: testPath + "/css/foo.css"}), "open file");
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, {fullPath: testPath + "/css/foo.css"}), "open file");
|
||||
});
|
||||
|
||||
doInMemoryTest({
|
||||
@ -1727,12 +1730,12 @@ define(function (require, exports, module) {
|
||||
|
||||
openTestProjectCopy(defaultSourcePath);
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: testPath + "/foo.html" }), "open file");
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: testPath + "/foo.html" }), "open file");
|
||||
});
|
||||
runs(function () {
|
||||
doc = DocumentManager.getOpenDocumentForPath(testPath + "/foo.html");
|
||||
expect(doc).toBeTruthy();
|
||||
DocumentManager.setCurrentDocument(doc);
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, doc);
|
||||
editor = doc._masterEditor;
|
||||
expect(editor).toBeTruthy();
|
||||
editor.setSelection({line: 4, ch: 7}, {line: 4, ch: 10});
|
||||
@ -1750,12 +1753,12 @@ define(function (require, exports, module) {
|
||||
|
||||
openTestProjectCopy(defaultSourcePath);
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: testPath + "/foo.html" }), "open file");
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: testPath + "/foo.html" }), "open file");
|
||||
});
|
||||
runs(function () {
|
||||
doc = DocumentManager.getOpenDocumentForPath(testPath + "/foo.html");
|
||||
expect(doc).toBeTruthy();
|
||||
DocumentManager.setCurrentDocument(doc);
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, doc);
|
||||
editor = doc._masterEditor;
|
||||
expect(editor).toBeTruthy();
|
||||
editor.setSelection({line: 4, ch: 7}, {line: 6, ch: 10});
|
||||
@ -1986,7 +1989,7 @@ define(function (require, exports, module) {
|
||||
it("should do single-file Replace All in an open file in the project", function () {
|
||||
openTestProjectCopy(defaultSourcePath);
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: testPath + "/foo.js" }), "open file");
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: testPath + "/foo.js" }), "open file");
|
||||
});
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_REPLACE), "open single-file replace bar");
|
||||
@ -2025,7 +2028,7 @@ define(function (require, exports, module) {
|
||||
});
|
||||
SpecRunnerUtils.loadProjectInTestWindow(blankProject);
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: externalFilePath }), "open external file");
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: externalFilePath }), "open external file");
|
||||
});
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_REPLACE), "open single-file replace bar");
|
||||
@ -2160,7 +2163,7 @@ define(function (require, exports, module) {
|
||||
it("should close the panel if a file is modified in memory", function () {
|
||||
openTestProjectCopy(defaultSourcePath);
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: testPath + "/foo.html" }), "open file");
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: testPath + "/foo.html" }), "open file");
|
||||
});
|
||||
openSearchBar(null, true);
|
||||
executeReplace("foo", "bar");
|
||||
@ -2183,7 +2186,7 @@ define(function (require, exports, module) {
|
||||
|
||||
openTestProjectCopy(defaultSourcePath);
|
||||
runs(function () {
|
||||
waitsForDone(CommandManager.execute(Commands.FILE_ADD_TO_WORKING_SET, { fullPath: testPath + "/foo.html" }), "open file");
|
||||
waitsForDone(CommandManager.execute(Commands.CMD_ADD_TO_WORKINGSET_AND_OPEN, { fullPath: testPath + "/foo.html" }), "open file");
|
||||
});
|
||||
runs(function () {
|
||||
doc = DocumentManager.getOpenDocumentForPath(testPath + "/foo.html");
|
||||
|
@ -33,6 +33,7 @@ define(function (require, exports, module) {
|
||||
EditorManager, // loaded from brackets.test
|
||||
FileSyncManager, // loaded from brackets.test
|
||||
DocumentManager, // loaded from brackets.test
|
||||
MainViewManager, // loaded from brackets.test
|
||||
FileViewController, // loaded from brackets.test
|
||||
InlineWidget = require("editor/InlineWidget").InlineWidget,
|
||||
Dialogs = require("widgets/Dialogs"),
|
||||
@ -81,18 +82,18 @@ define(function (require, exports, module) {
|
||||
* @param {string} openFile Project relative file path to open in a main editor.
|
||||
* @param {number} openOffset The offset index location within openFile to open an inline editor.
|
||||
* @param {boolean=} expectInline Use false to verify that an inline editor should not be opened. Omit otherwise.
|
||||
* @param {Array<{string}>=} workingSet Optional array of files to open in working set
|
||||
* @param {Array<{string}>=} documentList Optional array of files to open in working set
|
||||
*/
|
||||
function initInlineTest(openFile, openOffset, expectInline, workingSet) {
|
||||
function initInlineTest(openFile, openOffset, expectInline, documentList) {
|
||||
var editor;
|
||||
|
||||
workingSet = workingSet || [];
|
||||
documentList = documentList || [];
|
||||
|
||||
expectInline = (expectInline !== undefined) ? expectInline : true;
|
||||
|
||||
runs(function () {
|
||||
workingSet.push(openFile);
|
||||
waitsForDone(SpecRunnerUtils.openProjectFiles(workingSet), "FILE_OPEN timeout", 1000);
|
||||
documentList.push(openFile);
|
||||
waitsForDone(SpecRunnerUtils.openProjectFiles(documentList), "FILE_OPEN timeout", 1000);
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
@ -208,6 +209,7 @@ define(function (require, exports, module) {
|
||||
EditorManager = testWindow.brackets.test.EditorManager;
|
||||
FileSyncManager = testWindow.brackets.test.FileSyncManager;
|
||||
DocumentManager = testWindow.brackets.test.DocumentManager;
|
||||
MainViewManager = testWindow.brackets.test.MainViewManager;
|
||||
FileViewController = testWindow.brackets.test.FileViewController;
|
||||
});
|
||||
});
|
||||
@ -218,6 +220,7 @@ define(function (require, exports, module) {
|
||||
EditorManager = null;
|
||||
FileSyncManager = null;
|
||||
DocumentManager = null;
|
||||
MainViewManager = null;
|
||||
FileViewController = null;
|
||||
SpecRunnerUtils.closeTestWindow();
|
||||
|
||||
@ -1024,7 +1027,7 @@ define(function (require, exports, module) {
|
||||
initInlineTest("test1.html", 0);
|
||||
|
||||
runs(function () {
|
||||
var i = DocumentManager.findInWorkingSet(infos["test1.css"].fileEntry.fullPath);
|
||||
var i = MainViewManager.findInWorkingSet(MainViewManager.ACTIVE_PANE, infos["test1.css"].fileEntry.fullPath);
|
||||
expect(i).toEqual(-1);
|
||||
});
|
||||
});
|
||||
@ -1047,7 +1050,7 @@ define(function (require, exports, module) {
|
||||
inlineEditor.getCursorPos()
|
||||
);
|
||||
|
||||
var i = DocumentManager.findInWorkingSet(infos["test1.css"].fileEntry.fullPath);
|
||||
var i = MainViewManager.findInWorkingSet(MainViewManager.ACTIVE_PANE, infos["test1.css"].fileEntry.fullPath);
|
||||
expect(i).toEqual(1);
|
||||
|
||||
inlineEditor = null;
|
||||
@ -1073,7 +1076,7 @@ define(function (require, exports, module) {
|
||||
);
|
||||
|
||||
// activate the full editor
|
||||
DocumentManager.setCurrentDocument(cssDoc);
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, cssDoc);
|
||||
fullEditor = EditorManager.getCurrentFullEditor();
|
||||
|
||||
// sanity check
|
||||
@ -1123,7 +1126,7 @@ define(function (require, exports, module) {
|
||||
inlineEditor = hostEditor.getInlineWidgets()[0].editor;
|
||||
|
||||
// activate the full editor
|
||||
DocumentManager.setCurrentDocument(cssDoc);
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, cssDoc);
|
||||
fullEditor = EditorManager.getCurrentFullEditor();
|
||||
|
||||
// alias offsets to nice names
|
||||
@ -1518,7 +1521,7 @@ define(function (require, exports, module) {
|
||||
inlineEditor = hostEditor.getInlineWidgets()[0].editor;
|
||||
|
||||
// activate the full editor
|
||||
DocumentManager.setCurrentDocument(cssDoc);
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, cssDoc);
|
||||
fullEditor = EditorManager.getCurrentFullEditor();
|
||||
});
|
||||
});
|
||||
@ -1557,7 +1560,9 @@ define(function (require, exports, module) {
|
||||
|
||||
describe("InlineEditor provider prioritization", function () {
|
||||
var testWindow,
|
||||
testDocumentManager,
|
||||
testEditorManager,
|
||||
testMainViewManager,
|
||||
testDoc;
|
||||
|
||||
function getPositiveProviderCallback(widget) {
|
||||
@ -1577,8 +1582,16 @@ define(function (require, exports, module) {
|
||||
testWindow = w;
|
||||
Commands = testWindow.brackets.test.Commands;
|
||||
testEditorManager = testWindow.brackets.test.EditorManager;
|
||||
testMainViewManager = testWindow.brackets.test.MainViewManager;
|
||||
testDocumentManager = testWindow.brackets.test.DocumentManager;
|
||||
|
||||
testDoc = mock.doc;
|
||||
testEditorManager._doShow(testDoc);
|
||||
|
||||
testDocumentManager.getOpenDocumentForPath = function (fullPath) {
|
||||
return testDoc;
|
||||
};
|
||||
|
||||
testMainViewManager._edit(testMainViewManager.ACTIVE_PANE, testDoc);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1589,6 +1602,8 @@ define(function (require, exports, module) {
|
||||
Commands = null;
|
||||
testEditorManager = null;
|
||||
testDoc = null;
|
||||
testMainViewManager = null;
|
||||
testDocumentManager = null;
|
||||
});
|
||||
|
||||
|
||||
|
@ -33,6 +33,7 @@ define(function (require, exports, module) {
|
||||
var CodeMirror = require("thirdparty/CodeMirror2/lib/codemirror"),
|
||||
LanguageManager = require("language/LanguageManager"),
|
||||
DocumentManager = require("document/DocumentManager"),
|
||||
MainViewManager = require("view/MainViewManager"),
|
||||
PathUtils = require("thirdparty/path-utils/path-utils.min"),
|
||||
SpecRunnerUtils = require("spec/SpecRunnerUtils"),
|
||||
PreferencesManager = require("preferences/PreferencesManager"),
|
||||
@ -509,6 +510,7 @@ define(function (require, exports, module) {
|
||||
var DocumentManager,
|
||||
FileSystem,
|
||||
LanguageManager,
|
||||
MainViewManager,
|
||||
_$;
|
||||
|
||||
SpecRunnerUtils.createTempDirectory();
|
||||
@ -518,6 +520,7 @@ define(function (require, exports, module) {
|
||||
FileSystem = w.brackets.test.FileSystem;
|
||||
LanguageManager = w.brackets.test.LanguageManager;
|
||||
DocumentManager = w.brackets.test.DocumentManager;
|
||||
MainViewManager = w.brackets.test.MainViewManager;
|
||||
_$ = w.$;
|
||||
});
|
||||
|
||||
@ -544,7 +547,7 @@ define(function (require, exports, module) {
|
||||
|
||||
var renameDeferred = $.Deferred();
|
||||
runs(function () {
|
||||
DocumentManager.setCurrentDocument(doc);
|
||||
MainViewManager._edit(MainViewManager.ACTIVE_PANE, doc);
|
||||
javascript = LanguageManager.getLanguage("javascript");
|
||||
|
||||
// sanity check language
|
||||
@ -587,7 +590,6 @@ define(function (require, exports, module) {
|
||||
});
|
||||
|
||||
SpecRunnerUtils.closeTestWindow();
|
||||
|
||||
SpecRunnerUtils.removeTempDirectory();
|
||||
});
|
||||
|
||||
|
8
test/spec/MainViewFactory-test-files/css/citrus_mq.css
Normal file
@ -0,0 +1,8 @@
|
||||
/* Desktop */
|
||||
@import url("desktop.css");
|
||||
/* Phone */
|
||||
@import url("phone.css") only screen and (max-width:320px);
|
||||
/* Tablet */
|
||||
@import url("tablet.css") only screen and (min-width:321px) and (max-width:768px);
|
||||
|
||||
|
165
test/spec/MainViewFactory-test-files/css/desktop.css
Normal file
@ -0,0 +1,165 @@
|
||||
@charset "utf-8";
|
||||
/* CSS Document */
|
||||
|
||||
article, aside, figure, footer, header, nav, section {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
|
||||
color: #000;
|
||||
background-color: #66B034;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
#container {
|
||||
width: 840px;
|
||||
margin-top: 0px;
|
||||
margin-right: auto;
|
||||
margin-bottom: 0px;
|
||||
margin-left: auto;
|
||||
}
|
||||
#logo {
|
||||
background-image: url(../images/lrg_logo.png);
|
||||
background-repeat: no-repeat;
|
||||
height: 138px;
|
||||
width: 100%;
|
||||
}
|
||||
#logo h1, #logo h2 {
|
||||
position: absolute;
|
||||
top: -500px;
|
||||
}
|
||||
nav {
|
||||
padding-top: 150px;
|
||||
}
|
||||
#maincontent {
|
||||
margin-top: 80px;
|
||||
padding-top: 10px;
|
||||
padding-right: 0px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 0px;
|
||||
}
|
||||
ul {
|
||||
padding:0;
|
||||
margin:0;
|
||||
}
|
||||
nav ul {
|
||||
list-style: none;
|
||||
margin-bottom: 15px;
|
||||
font-weight: bold;
|
||||
font-size:20px;
|
||||
}
|
||||
nav ul li {
|
||||
float: left;
|
||||
}
|
||||
nav ul a {
|
||||
display: block;
|
||||
width:140px;
|
||||
padding: 10px;
|
||||
text-align:center;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
border: 1px solid #618A37;
|
||||
margin: 5px 0px;
|
||||
border-radius: 8px;
|
||||
-moz-box-shadow: 1px 1px 3px rgba(0,0,0,0.3);
|
||||
-webkit-box-shadow: 1px 1px 3px rgba(0,0,0,0.3);
|
||||
box-shadow: 1px 1px 3px rgba(0,0,0,0.3);
|
||||
text-shadow: 1px 1px 1px rgba(0,0,0,0.8);
|
||||
}
|
||||
nav ul a:link, nav ul a:visited {
|
||||
background: rgba(255,255,255,0.2);
|
||||
}
|
||||
nav ul a:hover, nav ul a:active, nav ul a:focus {
|
||||
background: rgba(255,255,255,0.4);
|
||||
}
|
||||
nav ul li:hover {
|
||||
margin-top:-10px;
|
||||
}
|
||||
nav ul li {
|
||||
float: left;
|
||||
-webkit-transition-duration:.5s;
|
||||
-webkit-transition-property:margin-top;
|
||||
-webkit-transition-timing-function:ease-in-out;
|
||||
-o-transition-duration:.5s;
|
||||
-o-transition-property:margin-top;
|
||||
-o-transition-timing-function:ease-in-out;
|
||||
-moz-transition-duration:.5s;
|
||||
-moz-transition-property:margin-top;
|
||||
-moz-transition-timing-function:ease-in-out;
|
||||
transition-duration:.5s;
|
||||
transition-property:margin-top;
|
||||
transition-timing-function:ease-in-out;
|
||||
}
|
||||
#vision {
|
||||
font-family:"Palatino Linotype", "Book Antiqua", Palatino, serif;
|
||||
font-size:32px;
|
||||
font-weight:bold;
|
||||
line-height:1.2;
|
||||
background-image:url(../images/lrg_hero.jpg);
|
||||
background-repeat:no-repeat;
|
||||
width: 409px;
|
||||
height:237px;
|
||||
padding:60px 370px 0 40px;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
.pod {
|
||||
background: #fff;
|
||||
padding: 10px;
|
||||
width: 244px;
|
||||
float:left;
|
||||
margin-right: 13px;
|
||||
}
|
||||
.podContent {
|
||||
margin-top:10px;
|
||||
width: 244px;
|
||||
height:181px;
|
||||
overflow:hidden;
|
||||
}
|
||||
#news .podContent {
|
||||
margin-top:12px;
|
||||
overflow:auto;
|
||||
}
|
||||
#news .podContent p {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
margin-left:6px;
|
||||
font-size:15px;
|
||||
}
|
||||
.pod h1 {
|
||||
background: #CCC;
|
||||
color: #000;
|
||||
padding:5px;
|
||||
background-image:url(../images/icon_chevron.png);
|
||||
background-repeat:no-repeat;
|
||||
background-position:95%;
|
||||
font-size:16px;
|
||||
font-weight:normal;
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
a.block {
|
||||
text-decoration:none;
|
||||
display:block;
|
||||
}
|
||||
time {
|
||||
font-weight:bold;
|
||||
display:inline-block;
|
||||
width:2.5em;
|
||||
}
|
||||
footer {
|
||||
padding: 10px 0;
|
||||
clear:both;
|
||||
color: #fff;
|
||||
}
|
||||
footer p {
|
||||
margin:0 0 5px 0;
|
||||
}
|
||||
#phone {
|
||||
font-weight:bold;
|
||||
color: #000;
|
||||
}
|
||||
#facebookTwitter {
|
||||
float:right;
|
||||
margin-right:25px;
|
||||
}
|
61
test/spec/MainViewFactory-test-files/css/phone.css
Normal file
@ -0,0 +1,61 @@
|
||||
@charset "utf-8";
|
||||
#container {
|
||||
width: 100%;
|
||||
}
|
||||
#logo {
|
||||
height:auto;
|
||||
width:270px;
|
||||
background-image: url(../images/sml_logo.png);
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
}
|
||||
nav {
|
||||
padding-top:100px;
|
||||
}
|
||||
nav ul {
|
||||
font-size:24px;
|
||||
}
|
||||
nav ul a {
|
||||
width:97%;
|
||||
padding-right:0;
|
||||
}
|
||||
nav ul li {
|
||||
float:none;
|
||||
}
|
||||
nav ul li:hover {
|
||||
margin-top:0;
|
||||
}
|
||||
#maincontent {
|
||||
margin-top: 0;
|
||||
padding:0;
|
||||
}
|
||||
#vision {
|
||||
background-image:none;
|
||||
width: 280px;
|
||||
height:auto;
|
||||
font-size:16px;
|
||||
line-height:normal;
|
||||
padding-top:0;
|
||||
}
|
||||
/* Uncomment the declarations in the following rules to hide the images in the pods. */
|
||||
.pod {
|
||||
width: 305px;
|
||||
/*padding-bottom:0;*/
|
||||
}
|
||||
/*.pod h1 {
|
||||
margin-bottom:0;
|
||||
}*/
|
||||
.podContent {
|
||||
width: 302px;
|
||||
height:180px;
|
||||
/*display:none;*/
|
||||
}
|
||||
/*#news .podContent {
|
||||
display:block;
|
||||
}*/
|
||||
footer p {
|
||||
margin-left:5px;
|
||||
}
|
||||
#facebookTwitter {
|
||||
margin-right:5px;
|
||||
}
|
47
test/spec/MainViewFactory-test-files/css/tablet.css
Normal file
@ -0,0 +1,47 @@
|
||||
@charset "utf-8";
|
||||
#container {
|
||||
width:700px;
|
||||
}
|
||||
#logo {
|
||||
background-image:url(../images/med_logo.png);
|
||||
height:100px;
|
||||
}
|
||||
nav {
|
||||
padding-top:110px;
|
||||
}
|
||||
nav ul {
|
||||
font-size:18px;
|
||||
}
|
||||
nav ul a {
|
||||
width:114px;
|
||||
}
|
||||
#maincontent {
|
||||
padding: 0;
|
||||
margin-left:5px;
|
||||
width: 700px;
|
||||
}
|
||||
#vision {
|
||||
background-image:url(../images/med_hero.jpg);
|
||||
width: 289px;
|
||||
height:217px;
|
||||
padding-top:45px;
|
||||
padding-right:350px;
|
||||
font-size:26px;
|
||||
}
|
||||
.pod {
|
||||
width: 305px;
|
||||
}
|
||||
.podContent {
|
||||
width: 302px;
|
||||
height:180px;
|
||||
}
|
||||
#events {
|
||||
margin-left:7px;
|
||||
}
|
||||
#news {
|
||||
width:650px;
|
||||
margin-top:20px;
|
||||
}
|
||||
footer p {
|
||||
margin-left:5px;
|
||||
}
|
BIN
test/spec/MainViewFactory-test-files/images/events.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
test/spec/MainViewFactory-test-files/images/icon_chevron.png
Normal file
After Width: | Height: | Size: 460 B |
BIN
test/spec/MainViewFactory-test-files/images/icon_facebook.png
Normal file
After Width: | Height: | Size: 926 B |
BIN
test/spec/MainViewFactory-test-files/images/icon_twitter.png
Normal file
After Width: | Height: | Size: 1005 B |
BIN
test/spec/MainViewFactory-test-files/images/lrg_hero.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
test/spec/MainViewFactory-test-files/images/lrg_logo.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
test/spec/MainViewFactory-test-files/images/med_hero.jpg
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
test/spec/MainViewFactory-test-files/images/med_logo.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
test/spec/MainViewFactory-test-files/images/sml_logo.png
Normal file
After Width: | Height: | Size: 19 KiB |