From bc9aa4e007b9a6979aea647865cfeec8b4671720 Mon Sep 17 00:00:00 2001 From: Couzteau Date: Thu, 28 Nov 2013 00:16:29 -0800 Subject: [PATCH 1/3] provide customViewerRegistry to enable extension developers to add CustomViewers --- src/editor/EditorManager.js | 60 +++++++++++++++++++++++++++---------- src/editor/ImageViewer.js | 31 +++++++++---------- 2 files changed, 59 insertions(+), 32 deletions(-) diff --git a/src/editor/EditorManager.js b/src/editor/EditorManager.js index 7a1e778e0b4..8b6f4744fa6 100644 --- a/src/editor/EditorManager.js +++ b/src/editor/EditorManager.js @@ -78,6 +78,8 @@ define(function (require, exports, module) { var _$currentCustomViewer = null; /** @type {?Object} view provider */ var _currentViewProvider = null; + /** @type {?Object} view provider registry */ + var _customViewerRegistry = {}; /** * Currently focused Editor (full-size, inline, or otherwise) @@ -625,9 +627,12 @@ define(function (require, exports, module) { /** Remove existing custom view if present */ function _removeCustomViewer() { - $(exports).triggerHandler("removeCustomViewer"); + if (_$currentCustomViewer) { _$currentCustomViewer.remove(); + if (_currentViewProvider.onRemove) { + _currentViewProvider.onRemove(); + } } _$currentCustomViewer = null; _currentViewProvider = null; @@ -663,15 +668,11 @@ define(function (require, exports, module) { // Hide the not-editor or reset current editor $("#not-editor").css("display", "none"); _nullifyEditor(); - + _currentViewProvider = provider; - _$currentCustomViewer = provider.getCustomViewHolder(fullPath); - - // place in window - $("#editor-holder").append(_$currentCustomViewer); // add path, dimensions and file size to the view after loading image - provider.render(fullPath); + _$currentCustomViewer = provider.render(fullPath, $("#editor-holder")); _setCurrentlyViewedPath(fullPath); } @@ -687,6 +688,39 @@ define(function (require, exports, module) { return (_currentViewProvider && _currentlyViewedPath === fullPath); } + /** + * Registers a new custom viewer provider. To create an extension that enables Brackets + * to view files that are not supported by CodeMirror, i.e. binary or proprietary + * file types, use this method to register a CustomViewer. + * + * A CustomViewer, such as ImageViewer in Brackets core needs to + * implement and export two methods: + * - render + * @param {!string} fullPath Path to the image file + * @param {!jQueryObject} $editorHolder The DOM element to append the view to. + * function render(fullPath, $editorHolder) + * - function onRemove() + * signs off listeners and performs any required clean up when editor manager closes + * the custom viewer + * + * By registering a CustomViewer with EditorManager Brackets is + * enabled to view files for one or more given file extensions. + * The first argument defines a so called languageId which bundles + * file extensions to be handled by the custom viewer, see more in LanguageManager JSDocs + * The second argument is an instantiated instance of the custom viewer that is ready to display + * files. + * + * @param {!String} languageId, i.e. string such as image, audio, etc to identify a language known to LanguageManager + * @param {!Object} provider custom view provider instance + */ + function registerCustomViewerProvider(langId, provider) { + if (!_customViewerRegistry[langId]) { + _customViewerRegistry[langId] = provider; + } else { + console.error("There already is a custom viewer registered for language id \"" + langId + "\""); + } + } + /** * Update file name if necessary */ @@ -705,15 +739,8 @@ define(function (require, exports, module) { */ function getCustomViewerForPath(fullPath) { var lang = LanguageManager.getLanguageForPath(fullPath); - if (lang.getId() === "image") { - // TODO: Extensibility - // For now we only have the image viewer, so just return ImageViewer object. - // Once we have each viewer registers with EditorManager as a provider, - // then we return the provider registered with the language id. - return ImageViewer; - } - return null; + return _customViewerRegistry[lang.getId()]; } /** @@ -972,6 +999,8 @@ define(function (require, exports, module) { }); CommandManager.register(Strings.CMD_JUMPTO_DEFINITION, Commands.NAVIGATE_JUMPTO_DEFINITION, _doJumpToDef); + registerCustomViewerProvider("image", ImageViewer); + // Create PerfUtils measurement PerfUtils.createPerfMeasurement("JUMP_TO_DEFINITION", "Jump-To-Definiiton"); @@ -1011,6 +1040,7 @@ define(function (require, exports, module) { exports.getInlineEditors = getInlineEditors; exports.closeInlineWidget = closeInlineWidget; exports.showCustomViewer = showCustomViewer; + exports.registerCustomViewerProvider = registerCustomViewerProvider; exports.getCustomViewerForPath = getCustomViewerForPath; exports.notifyPathDeleted = notifyPathDeleted; exports.closeCustomViewer = closeCustomViewer; diff --git a/src/editor/ImageViewer.js b/src/editor/ImageViewer.js index 9c368e36049..0149e898b38 100644 --- a/src/editor/ImageViewer.js +++ b/src/editor/ImageViewer.js @@ -268,22 +268,12 @@ define(function (require, exports, module) { } } - /** - * creates a DOM node to place in the editor-holder - * in order to display an image. - * @param {!string} fullPath path to image file - * @return {JQuery} - * - */ - function getCustomViewHolder(fullPath) { - return $(Mustache.render(ImageHolderTemplate, {fullPath: fullPath})); - } /** * sign off listeners when editor manager closes * the image viewer */ - function _removeListeners() { + function onRemove() { $(PanelManager).off("editorAreaResize", _onEditorAreaResize); $(DocumentManager).off("fileNameChange", _onFileNameChange); $("#img").off("mousemove", "#img-preview, #img-scale, #img-tip, .img-guide", _showImageTip) @@ -293,10 +283,15 @@ define(function (require, exports, module) { /** * 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 {!string} fullPath Path to the image file + * @param {!jQueryObject} $editorHolder The DOM element to append the view to. */ - function render(fullPath) { - var relPath = ProjectManager.makeProjectRelativeIfPossible(fullPath); + function render(fullPath, $editorHolder) { + var relPath = ProjectManager.makeProjectRelativeIfPossible(fullPath), + $customViewer = $(Mustache.render(ImageHolderTemplate, {fullPath: fullPath})); + + // place DOM node to hold image + $editorHolder.append($customViewer); _scale = 100; // initialize to 100 _scaleDivInfo = null; @@ -326,10 +321,11 @@ define(function (require, exports, module) { } }); $("#image-holder").show(); + // listen to resize to update the scale sticker $(PanelManager).on("editorAreaResize", _onEditorAreaResize); - // listen to removal to stop listening to resize events - $(EditorManager).on("removeCustomViewer", _removeListeners); + + // make sure we always show the right file name $(DocumentManager).on("fileNameChange", _onFileNameChange); $("#img-tip").hide(); @@ -349,8 +345,9 @@ define(function (require, exports, module) { $(".img-guide").css("cursor", "crosshair"); } }); + return $customViewer; } - exports.getCustomViewHolder = getCustomViewHolder; exports.render = render; + exports.onRemove = onRemove; }); From e64e32f0ad4c366a2ace3b6c7e459023b73ffc77 Mon Sep 17 00:00:00 2001 From: Couzteau Date: Wed, 4 Dec 2013 22:29:55 -0800 Subject: [PATCH 2/3] review feedback --- src/brackets.js | 1 + src/editor/EditorManager.js | 26 ++++++++++++-------------- src/editor/ImageViewer.js | 5 ++++- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/brackets.js b/src/brackets.js index 3d3cd9569ce..034b294a325 100644 --- a/src/brackets.js +++ b/src/brackets.js @@ -100,6 +100,7 @@ define(function (require, exports, module) { require("search/FindReplace"); require("extensibility/InstallExtensionDialog"); require("extensibility/ExtensionManagerDialog"); + require("editor/ImageViewer"); // Compatibility shims for filesystem API migration require("project/FileIndexManager"); diff --git a/src/editor/EditorManager.js b/src/editor/EditorManager.js index 8b6f4744fa6..1f1f3f48bfe 100644 --- a/src/editor/EditorManager.js +++ b/src/editor/EditorManager.js @@ -58,7 +58,6 @@ define(function (require, exports, module) { PerfUtils = require("utils/PerfUtils"), Editor = require("editor/Editor").Editor, InlineTextEditor = require("editor/InlineTextEditor").InlineTextEditor, - ImageViewer = require("editor/ImageViewer"), Strings = require("strings"), LanguageManager = require("language/LanguageManager"); @@ -689,31 +688,32 @@ define(function (require, exports, module) { } /** - * Registers a new custom viewer provider. To create an extension that enables Brackets - * to view files that are not supported by CodeMirror, i.e. binary or proprietary - * file types, use this method to register a CustomViewer. + * Registers a new custom viewer provider. To create an extension + * that enables Brackets to view files that cannot be shown as + * text such as binary files, use this method to register a CustomViewer. * * A CustomViewer, such as ImageViewer in Brackets core needs to * implement and export two methods: * - render * @param {!string} fullPath Path to the image file * @param {!jQueryObject} $editorHolder The DOM element to append the view to. - * function render(fullPath, $editorHolder) - * - function onRemove() + * - onRemove * signs off listeners and performs any required clean up when editor manager closes * the custom viewer * * By registering a CustomViewer with EditorManager Brackets is * enabled to view files for one or more given file extensions. * The first argument defines a so called languageId which bundles - * file extensions to be handled by the custom viewer, see more in LanguageManager JSDocs - * The second argument is an instantiated instance of the custom viewer that is ready to display + * file extensions to be handled by the custom viewer, see more + * in LanguageManager JSDocs. + * The second argument is an instance of the custom viewer that is ready to display * files. * - * @param {!String} languageId, i.e. string such as image, audio, etc to identify a language known to LanguageManager + * @param {!String} languageId, i.e. string such as image, audio, etc to + * identify a language known to LanguageManager * @param {!Object} provider custom view provider instance */ - function registerCustomViewerProvider(langId, provider) { + function registerCustomViewer(langId, provider) { if (!_customViewerRegistry[langId]) { _customViewerRegistry[langId] = provider; } else { @@ -998,9 +998,7 @@ define(function (require, exports, module) { return _toggleInlineWidget(_inlineDocsProviders); }); CommandManager.register(Strings.CMD_JUMPTO_DEFINITION, Commands.NAVIGATE_JUMPTO_DEFINITION, _doJumpToDef); - - registerCustomViewerProvider("image", ImageViewer); - + // Create PerfUtils measurement PerfUtils.createPerfMeasurement("JUMP_TO_DEFINITION", "Jump-To-Definiiton"); @@ -1040,7 +1038,7 @@ define(function (require, exports, module) { exports.getInlineEditors = getInlineEditors; exports.closeInlineWidget = closeInlineWidget; exports.showCustomViewer = showCustomViewer; - exports.registerCustomViewerProvider = registerCustomViewerProvider; + exports.registerCustomViewer = registerCustomViewer; exports.getCustomViewerForPath = getCustomViewerForPath; exports.notifyPathDeleted = notifyPathDeleted; exports.closeCustomViewer = closeCustomViewer; diff --git a/src/editor/ImageViewer.js b/src/editor/ImageViewer.js index 0149e898b38..cc8dbecfe6f 100644 --- a/src/editor/ImageViewer.js +++ b/src/editor/ImageViewer.js @@ -34,7 +34,8 @@ define(function (require, exports, module) { ProjectManager = require("project/ProjectManager"), Strings = require("strings"), StringUtils = require("utils/StringUtils"), - FileSystem = require("filesystem/FileSystem"); + FileSystem = require("filesystem/FileSystem"), + ImageViewer = require("editor/ImageViewer"); var _naturalWidth = 0, _scale = 100, @@ -348,6 +349,8 @@ define(function (require, exports, module) { return $customViewer; } + EditorManager.registerCustomViewer("image", ImageViewer); + exports.render = render; exports.onRemove = onRemove; }); From 4ef87fbab176828a1c6aef35215e215c47cda93e Mon Sep 17 00:00:00 2001 From: Couzteau Date: Thu, 5 Dec 2013 10:38:14 -0800 Subject: [PATCH 3/3] register ImageViewer more elegantly. --- src/editor/ImageViewer.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/editor/ImageViewer.js b/src/editor/ImageViewer.js index cc8dbecfe6f..c9eba893bf8 100644 --- a/src/editor/ImageViewer.js +++ b/src/editor/ImageViewer.js @@ -34,8 +34,7 @@ define(function (require, exports, module) { ProjectManager = require("project/ProjectManager"), Strings = require("strings"), StringUtils = require("utils/StringUtils"), - FileSystem = require("filesystem/FileSystem"), - ImageViewer = require("editor/ImageViewer"); + FileSystem = require("filesystem/FileSystem"); var _naturalWidth = 0, _scale = 100, @@ -349,7 +348,10 @@ define(function (require, exports, module) { return $customViewer; } - EditorManager.registerCustomViewer("image", ImageViewer); + EditorManager.registerCustomViewer("image", { + render: render, + onRemove: onRemove + }); exports.render = render; exports.onRemove = onRemove;