define([ "jquery", "underscore", "constants", "utils", "storage", "settings", "eventMgr", "fileSystem", "fileMgr", "sharing", "monetizejs", "classes/Provider", "classes/AsyncTask", "providers/bloggerProvider", "providers/bloggerPageProvider", "providers/dropboxProvider", "providers/gistProvider", "providers/githubProvider", "providers/gdriveProvider", "providers/gdrivesecProvider", "providers/gdriveterProvider", "providers/sshProvider", "providers/tumblrProvider", "providers/wordpressProvider" ], function($, _, constants, utils, storage, settings, eventMgr, fileSystem, fileMgr, sharing, MonetizeJS, Provider, AsyncTask) { var publisher = {}; // Create a map with providerId: providerModule var providerMap = _.chain(arguments).map(function(argument) { return argument instanceof Provider && argument.isPublishEnabled === true && [ argument.providerId, argument ]; }).compact().object().value(); // Retrieve publish locations from storage (function() { var publishIndexMap = {}; _.each(fileSystem, function(fileDesc) { utils.retrieveIndexArray(fileDesc.fileIndex + ".publish").forEach(function(publishIndex) { try { var publishAttributes = JSON.parse(storage[publishIndex]); // Store publishIndex publishAttributes.publishIndex = publishIndex; // Replace provider ID by provider module in attributes var provider = providerMap[publishAttributes.provider]; if(!provider) { throw new Error("Invalid provider ID: " + publishAttributes.provider); } publishAttributes.provider = provider; fileDesc.publishLocations[publishIndex] = publishAttributes; publishIndexMap[publishIndex] = publishAttributes; } catch(e) { // storage can be corrupted eventMgr.onError(e); // Remove publish location utils.removeIndexFromArray(fileDesc.fileIndex + ".publish", publishIndex); } }); }); // Clean fields from deleted files in local storage Object.keys(storage).forEach(function(key) { var match = key.match(/publish\.\S+/); if(match && !publishIndexMap.hasOwnProperty(match[0])) { storage.removeItem(key); } }); })(); // Apply template to the current document publisher.applyTemplate = function(fileDesc, publishAttributes, html) { try { var template = (publishAttributes && publishAttributes.customTmpl) || settings.template; return _.template(template, { documentTitle: fileDesc.title, documentMarkdown: fileDesc.content, strippedDocumentMarkdown: fileDesc.content.substring(fileDesc.frontMatter ? fileDesc.frontMatter._frontMatter.length : 0), documentHTML: html.withoutComments, documentHTMLWithFrontMatter: (fileDesc.frontMatter ? fileDesc.frontMatter._frontMatter : '') + html.withoutComments, documentHTMLWithComments: html.withComments, frontMatter: fileDesc.frontMatter, publishAttributes: publishAttributes }); } catch(e) { eventMgr.onError(e); return e.message; } }; // Used to get content to publish function getPublishContent(fileDesc, publishAttributes, html) { if(publishAttributes.format === undefined) { publishAttributes.format = utils.getInputRadio("radio-publish-format"); if(publishAttributes.format == 'template' && utils.getInputChecked("#checkbox-publish-custom-template")) { publishAttributes.customTmpl = utils.getInputValue('#textarea-publish-custom-template'); } } if(publishAttributes.format == "markdown") { return fileDesc.content; } else if(publishAttributes.format == "html") { return html.withoutComments; } else { return publisher.applyTemplate(fileDesc, publishAttributes, html); } } // Recursive function to publish a file on multiple locations var publishAttributesList = []; var publishFileDesc; var publishHTML; function publishLocation(callback, errorFlag) { // No more publish location for this document if(publishAttributesList.length === 0) { callback(errorFlag); return; } // Dequeue a synchronized location var publishAttributes = publishAttributesList.pop(); // Format the content var content = getPublishContent(publishFileDesc, publishAttributes, publishHTML); var title = (publishFileDesc.frontMatter || {}).title || publishFileDesc.title; // Call the provider publishAttributes.provider.publish(publishAttributes, publishFileDesc.frontMatter, title, content, function(error) { if(error !== undefined) { var errorMsg = error.toString(); if(errorMsg.indexOf("|removePublish") !== -1) { publishFileDesc.removePublishLocation(publishAttributes); eventMgr.onPublishRemoved(publishFileDesc, publishAttributes); } if(errorMsg.indexOf("|stopPublish") !== -1) { callback(error); return; } } publishLocation(callback, errorFlag || error); }); } // Get the html from the onPreviewFinished callback var currentHTML; eventMgr.addListener("onPreviewFinished", function(htmlWithComments, htmlWithoutComments) { currentHTML = { withComments: htmlWithComments, withoutComments: htmlWithoutComments }; }); // Listen to offline status changes var isOffline = false; eventMgr.addListener("onOfflineChanged", function(isOfflineParam) { isOffline = isOfflineParam; }); var publishRunning = false; publisher.publish = function() { // If publish is running or offline if(publishRunning === true || isOffline === true) { return; } publishRunning = true; eventMgr.onPublishRunning(true); publishFileDesc = fileMgr.currentFile; publishHTML = currentHTML; publishAttributesList = _.values(publishFileDesc.publishLocations); publishLocation(function(errorFlag) { publishRunning = false; eventMgr.onPublishRunning(false); if(errorFlag === undefined) { eventMgr.onPublishSuccess(publishFileDesc); } }); }; // Generate a publishIndex associated to a file and store publishAttributes function createPublishIndex(fileDesc, publishAttributes) { var publishIndex; do { publishIndex = "publish." + utils.id(); } while(_.has(storage, publishIndex)); publishAttributes.publishIndex = publishIndex; fileDesc.addPublishLocation(publishAttributes); eventMgr.onNewPublishSuccess(fileDesc, publishAttributes); } // Initialize the "New publication" dialog var newLocationProvider; function initNewLocation(provider) { var defaultPublishFormat = provider.defaultPublishFormat || "markdown"; newLocationProvider = provider; $(".publish-provider-name").text(provider.providerName); // Show/hide controls depending on provider $('.modal-publish [class*=" modal-publish-"]').hide().filter(".modal-publish-" + provider.providerId).show(); // Reset fields utils.resetModalInputs(); utils.setInputRadio("radio-publish-format", defaultPublishFormat); utils.setInputChecked("#checkbox-publish-custom-template", false); utils.setInputValue('#textarea-publish-custom-template', settings.template); // Load preferences var publishPreferences = utils.retrieveIgnoreError(provider.providerId + ".publishPreferences"); if(publishPreferences) { _.each(provider.publishPreferencesInputIds, function(inputId) { var publishPreferenceValue = publishPreferences[inputId]; if(_.isBoolean(publishPreferenceValue)) { utils.setInputChecked("#input-publish-" + inputId, publishPreferenceValue); } else { utils.setInputValue("#input-publish-" + inputId, publishPreferenceValue); } }); utils.setInputRadio("radio-publish-format", publishPreferences.format); utils.setInputChecked("#checkbox-publish-custom-template", publishPreferences.customTmpl !== undefined); utils.setInputValue('#textarea-publish-custom-template', publishPreferences.customTmpl || settings.template); } // Open dialog box $(".modal-publish").modal(); } // Add a new publish location to a local document function performNewLocation(event) { var provider = newLocationProvider; var publishAttributes = provider.newPublishAttributes(event); if(publishAttributes === undefined) { return; } // Perform provider's publishing var fileDesc = fileMgr.currentFile; var content = getPublishContent(fileDesc, publishAttributes, currentHTML); var title = (fileDesc.frontMatter && fileDesc.frontMatter.title) || fileDesc.title; provider.publish(publishAttributes, fileDesc.frontMatter, title, content, function(error) { if(error === undefined) { publishAttributes.provider = provider; sharing.createLink(publishAttributes, function() { createPublishIndex(fileDesc, publishAttributes); }); } }); // Store input values as preferences for next time we open the publish // dialog var publishPreferences = {}; _.each(provider.publishPreferencesInputIds, function(inputId) { var inputElt = document.getElementById("input-publish-" + inputId); if(inputElt.type == 'checkbox') { publishPreferences[inputId] = inputElt.checked; } else { publishPreferences[inputId] = inputElt.value; } }); publishPreferences.format = publishAttributes.format; publishPreferences.customTmpl = publishAttributes.customTmpl; storage[provider.providerId + ".publishPreferences"] = JSON.stringify(publishPreferences); } var initPublishButtonTmpl = [ '