define( [ "jquery", "utils", "underscore", "bootstrap", "extensions/notifications", "extensions/markdown-extra", "extensions/toc", "extensions/math-jax", "extensions/scroll-link" ], function($, utils) { var extensionManager = {}; // Create a list of extensions var extensionList = _.chain(arguments) .map(function(argument) { return _.isObject(argument) && argument.extensionId && argument; }).compact().value(); // Return every named callbacks implemented in extensions function getExtensionCallbackList(hookName) { return _.chain(extensionList) .map(function(extension) { return extension.config.enabled && extension[hookName]; }).compact().value(); } // Return a function that calls every callbacks from extensions function createHook(hookName) { var callbackList = getExtensionCallbackList(hookName); return function() { console.debug(hookName); var callbackArguments = arguments; _.each(callbackList, function(callback) { callback.apply(null, callbackArguments); }); }; } // Add a Hook to the extensionManager function addHook(hookName) { extensionManager[hookName] = createHook(hookName); } var accordionTmpl = [ '
', '
', '', '', '<%= extensionName %>', '', '
', '
', '
<%= settingsBloc %>
', '
', '
'].join(""); function createSettings(extension) { $("#accordion-extensions").append($(_.template(accordionTmpl, { extensionId: extension.extensionId, extensionName: extension.extensionName, optional: extension.optional, settingsBloc: extension.settingsBloc }))); } extensionManager.init = function(extensionSettings) { // Set extension config extensionSettings = extensionSettings || {}; _.each(extensionList, function(extension) { extension.config = _.extend({}, extension.defaultConfig, extensionSettings[extension.extensionId]); extension.config.enabled = !extension.optional || extension.config.enabled === undefined || extension.config.enabled === true; }); // Load/Save extension config from/to settings extensionManager["onLoadSettings"] = function() { console.debug("onLoadSettings"); _.each(extensionList, function(extension) { utils.setInputChecked("#input-enable-extension-" + extension.extensionId, extension.config.enabled); var onLoadSettingsCallback = extension.onLoadSettings; onLoadSettingsCallback && onLoadSettingsCallback(); }); }; extensionManager["onSaveSettings"] = function(newExtensionSettings, event) { console.debug("onSaveSettings"); _.each(extensionList, function(extension) { var newExtensionConfig = extension.defaultConfig || {}; newExtensionConfig.enabled = utils.getInputChecked("#input-enable-extension-" + extension.extensionId); var onSaveSettingsCallback = extension.onSaveSettings; onSaveSettingsCallback && onSaveSettingsCallback(newExtensionConfig, event); newExtensionSettings[extension.extensionId] = newExtensionConfig; }); }; addHook("onMessage"); addHook("onError"); addHook("onOfflineChanged"); // To store reference to modules that are accessible from extensions addHook("onFileManagerCreated"); addHook("onSynchronizerCreated"); addHook("onPublisherCreated"); // Operations on files addHook("onFileSystemLoaded"); addHook("onFileCreated"); addHook("onFileDeleted"); addHook("onFileChanged"); addHook("onFileSelected"); addHook("onTitleChanged"); addHook("onSyncImportSuccess"); addHook("onSyncExportSuccess"); addHook("onSyncRemoved"); addHook("onPublishSuccess"); addHook("onNewPublishSuccess"); addHook("onPublishRemoved"); // Operations on Layout addHook("onLayoutConfigure"); addHook("onLayoutCreated"); // Operations on PageDown addHook("onEditorConfigure"); var onPreviewFinished = createHook("onPreviewFinished"); var onAsyncPreviewCallbackList = getExtensionCallbackList("onAsyncPreview"); extensionManager["onAsyncPreview"] = function() { console.debug("onAsyncPreview"); // Call onPreviewFinished callbacks when all async preview are finished var counter = 0; function tryFinished() { if(counter === onAsyncPreviewCallbackList.length) { onPreviewFinished(); } } _.each(onAsyncPreviewCallbackList, function(asyncPreviewCallback) { asyncPreviewCallback(function() { counter++; tryFinished(); }); }); tryFinished(); }; // Call onReady callbacks var onReady = createHook("onReady"); extensionManager["onReady"] = function() { // Create accordion in settings dialog _.each(extensionList, createSettings); onReady(); }; }; return extensionManager; });