Implemented PDF options
This commit is contained in:
parent
ae8adddf5d
commit
3f8b5a865a
@ -18,10 +18,10 @@ module.exports = function(req, res, next) {
|
||||
}
|
||||
|
||||
// Margins
|
||||
var marginRight = parseInt(options.marginRight);
|
||||
params.push('-R', isNaN(marginRight) ? 25 : marginRight);
|
||||
var marginTop = parseInt(options.marginTop);
|
||||
params.push('-T', isNaN(marginTop) ? 25 : marginTop);
|
||||
var marginRight = parseInt(options.marginRight);
|
||||
params.push('-R', isNaN(marginRight) ? 25 : marginRight);
|
||||
var marginBottom = parseInt(options.marginBottom);
|
||||
params.push('-B', isNaN(marginBottom) ? 25 : marginBottom);
|
||||
var marginLeft = parseInt(options.marginLeft);
|
||||
@ -42,8 +42,7 @@ module.exports = function(req, res, next) {
|
||||
options.footerFontSize && params.push('--footer-font-size ', options.footerFontSize);
|
||||
|
||||
// Page size
|
||||
var pageSize = options.pageSize;
|
||||
params.push('--page-size', authorizedPageSizes.indexOf(pageSize) === -1 ? 'A4' : pageSize);
|
||||
params.push('--page-size', authorizedPageSizes.indexOf(options.pageSize) === -1 ? 'A4' : options.pageSize);
|
||||
|
||||
// wkhtmltopdf can't access /dev/stdout on Amazon EC2 for some reason
|
||||
var filePath = '/tmp/' + Date.now() + '.pdf';
|
||||
|
@ -14,9 +14,10 @@ define([
|
||||
"text!html/bodyIndex.html",
|
||||
"text!html/bodyViewer.html",
|
||||
"text!html/tooltipSettingsTemplate.html",
|
||||
"text!html/tooltipSettingsPdfOptions.html",
|
||||
"storage",
|
||||
'pagedown'
|
||||
], function($, _, crel, editor, layout, constants, utils, storage, settings, eventMgr, MonetizeJS, bodyIndexHTML, bodyViewerHTML, settingsTemplateTooltipHTML) {
|
||||
], function($, _, crel, editor, layout, constants, utils, storage, settings, eventMgr, MonetizeJS, bodyIndexHTML, bodyViewerHTML, settingsTemplateTooltipHTML, settingsPdfOptionsTooltipHTML) {
|
||||
|
||||
var core = {};
|
||||
|
||||
@ -142,8 +143,8 @@ define([
|
||||
utils.setInputValue("#textarea-settings-publish-template", settings.template);
|
||||
// PDF template
|
||||
utils.setInputValue("#textarea-settings-pdf-template", settings.pdfTemplate);
|
||||
// PDF page size
|
||||
utils.setInputValue("#input-settings-pdf-page-size", settings.pdfPageSize);
|
||||
// PDF options
|
||||
utils.setInputValue("#textarea-settings-pdf-options", settings.pdfOptions);
|
||||
// SSH proxy
|
||||
utils.setInputValue("#input-settings-ssh-proxy", settings.sshProxy);
|
||||
|
||||
@ -189,8 +190,8 @@ define([
|
||||
newSettings.template = utils.getInputTextValue("#textarea-settings-publish-template", event);
|
||||
// PDF template
|
||||
newSettings.pdfTemplate = utils.getInputTextValue("#textarea-settings-pdf-template", event);
|
||||
// PDF page size
|
||||
newSettings.pdfPageSize = utils.getInputValue("#input-settings-pdf-page-size");
|
||||
// PDF options
|
||||
newSettings.pdfOptions = utils.getInputJSONValue("#textarea-settings-pdf-options", event);
|
||||
// SSH proxy
|
||||
newSettings.sshProxy = utils.checkUrl(utils.getInputTextValue("#input-settings-ssh-proxy", event), true);
|
||||
|
||||
@ -331,10 +332,12 @@ define([
|
||||
});
|
||||
var $alerts = $();
|
||||
|
||||
function hasPaid(payments) {
|
||||
return payments && (
|
||||
function isSponsor(payments) {
|
||||
var result = payments && (
|
||||
(payments.chargeOption && payments.chargeOption.alias == 'once') ||
|
||||
(payments.subscriptionOption && payments.subscriptionOption.alias == 'yearly'));
|
||||
eventMgr.isSponsor = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function removeAlerts() {
|
||||
@ -346,11 +349,10 @@ define([
|
||||
monetize.getPayments({
|
||||
pricingOptions: [
|
||||
'once',
|
||||
'monthly',
|
||||
'yearly'
|
||||
]
|
||||
}, function(err, payments) {
|
||||
if(hasPaid(payments)) {
|
||||
if(isSponsor(payments)) {
|
||||
eventMgr.onMessage('Thank you for sponsoring StackEdit!');
|
||||
removeAlerts();
|
||||
}
|
||||
@ -363,7 +365,7 @@ define([
|
||||
}
|
||||
monetize.getPaymentsImmediate(function(err, payments) {
|
||||
removeAlerts();
|
||||
if(!hasPaid(payments)) {
|
||||
if(!isSponsor(payments)) {
|
||||
_.each(document.querySelectorAll('.modal-body'), function(modalBodyElt) {
|
||||
var $elt = $('<div class="alert alert-danger">Please consider <a href="#">sponsoring StackEdit</a> for $5/year (or <a href="#">sign in</a> if you\'re already a sponsor).</div>');
|
||||
$elt.find('a').click(performPayment);
|
||||
@ -542,6 +544,7 @@ define([
|
||||
'<b class="text-danger">NOTE: Backlinks in Stack Exchange Q/A are not welcome.</b>'
|
||||
].join(''));
|
||||
utils.createTooltip(".tooltip-template", settingsTemplateTooltipHTML);
|
||||
utils.createTooltip(".tooltip-pdf-options", settingsPdfOptionsTooltipHTML);
|
||||
|
||||
// Avoid dropdown panels to close on click
|
||||
$("div.dropdown-menu").click(function(e) {
|
||||
|
@ -10,6 +10,11 @@ define([
|
||||
|
||||
var dialogAbout = new Extension("dialogAbout", 'Dialog "About"');
|
||||
|
||||
var eventMgr;
|
||||
dialogAbout.onEventMgrCreated = function(eventMgrParameter) {
|
||||
eventMgr = eventMgrParameter;
|
||||
};
|
||||
|
||||
var monetize = new MonetizeJS({
|
||||
applicationID: 'iklMbzDI7dvMEScb'
|
||||
});
|
||||
@ -22,6 +27,7 @@ define([
|
||||
monetize.getPayments({
|
||||
summary: true
|
||||
}, function() {
|
||||
eventMgr.onMessage('Please refresh the page for your sponsorship to take effect.');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -89,7 +89,7 @@
|
||||
<a href="#" data-toggle="collapse" data-target=".collapse-synchronize"
|
||||
class="list-group-item">
|
||||
<div><i class="icon-refresh"></i> Synchronize</div>
|
||||
<small>Backup, collaborate in the cloud</small>
|
||||
<small>Backup, collaborate...</small>
|
||||
</a>
|
||||
<div class="sub-menu collapse collapse-synchronize clearfix">
|
||||
<ul class="nav alert alert-danger show-already-synchronized">
|
||||
@ -159,7 +159,7 @@
|
||||
<li><a class="action-download-template" href="#"><i
|
||||
class="icon-download"></i> Using template</a></li>
|
||||
<li><a class="action-download-pdf" href="#"><i
|
||||
class="icon-download"></i> As PDF</a></li>
|
||||
class="icon-download"></i> As PDF <sup class="text-danger">sponsor</sup></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -1072,14 +1072,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label" for="input-settings-pdf-page-size">PDF page size</label>
|
||||
<label class="col-sm-4 control-label" for="textarea-settings-pdf-options">PDF options
|
||||
<a href="#" class="tooltip-pdf-options">(?)</a>
|
||||
</label>
|
||||
<div class="col-sm-7">
|
||||
<select id="input-settings-pdf-page-size" class="form-control">
|
||||
<option value="A3">A3</option>
|
||||
<option value="A4">A4</option>
|
||||
<option value="Legal">Legal</option>
|
||||
<option value="Letter">Letter</option>
|
||||
</select>
|
||||
<textarea id="textarea-settings-pdf-options"
|
||||
class="form-control"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@ -1303,4 +1301,24 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div class="modal fade modal-sponsorship-required">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
|
||||
<div class="modal-header">
|
||||
<h2 class="modal-title">Sponsorship required</h2>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>This feature is restricted to sponsors only as it's a web service hosted on Amazon EC2.
|
||||
Note that sponsoring StackEdit would cost you only <b>$5/year</b>...</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="btn btn-primary"
|
||||
data-dismiss="modal">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="dropboxjs" data-app-key="x0k2l8puemfvg0o"></div>
|
||||
|
19
public/res/html/tooltipSettingsPdfOptions.html
Normal file
19
public/res/html/tooltipSettingsPdfOptions.html
Normal file
@ -0,0 +1,19 @@
|
||||
Option object in JSON format. Possible attributes:
|
||||
<br><br>
|
||||
<b>marginTop</b>,
|
||||
<b>marginRight</b>,
|
||||
<b>marginBottom</b>,
|
||||
<b>marginLeft</b>,<br>
|
||||
<b>headerCenter</b>,
|
||||
<b>headerLeft</b>,
|
||||
<b>headerRight</b>,
|
||||
<b>headerFontName</b>,
|
||||
<b>headerFontSize</b>,<br>
|
||||
<b>footerCenter</b>,
|
||||
<b>footerLeft</b>,
|
||||
<b>footerRight</b>,
|
||||
<b>footerFontName</b>,
|
||||
<b>footerFontSize</b><br>
|
||||
<b>pageSize</b><br><br>
|
||||
Please check out the
|
||||
<a target="_blank" href="http://wkhtmltopdf.org/usage/wkhtmltopdf.txt">wkhtmltopdf documentation</a> for more info.
|
@ -86,7 +86,7 @@ define([
|
||||
var syncIndex = createSyncIndex(path);
|
||||
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
|
||||
if(fileDesc !== undefined) {
|
||||
return eventMgr.onError('"' + fileDesc.title + '" was already imported.');
|
||||
return eventMgr.onError('"' + fileDesc.title + '" is already in your local documents.');
|
||||
}
|
||||
importPaths.push(path);
|
||||
});
|
||||
|
@ -91,7 +91,7 @@ define([
|
||||
var syncIndex = createSyncIndex(doc.id);
|
||||
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
|
||||
if(fileDesc !== undefined) {
|
||||
return eventMgr.onError('"' + fileDesc.title + '" was already imported.');
|
||||
return eventMgr.onError('"' + fileDesc.title + '" is already in your local documents.');
|
||||
}
|
||||
importIds.push(doc.id);
|
||||
});
|
||||
|
@ -1,376 +1,391 @@
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"constants",
|
||||
"utils",
|
||||
"storage",
|
||||
"settings",
|
||||
"eventMgr",
|
||||
"fileSystem",
|
||||
"fileMgr",
|
||||
"sharing",
|
||||
"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, Provider, AsyncTask) {
|
||||
"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 = {};
|
||||
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();
|
||||
// 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);
|
||||
}
|
||||
});
|
||||
});
|
||||
// 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);
|
||||
}
|
||||
});
|
||||
})();
|
||||
// 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,
|
||||
// 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;
|
||||
}
|
||||
};
|
||||
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);
|
||||
}
|
||||
}
|
||||
// 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) {
|
||||
// Recursive function to publish a file on multiple locations
|
||||
var publishAttributesList = [];
|
||||
var publishFileDesc;
|
||||
var publishHTML;
|
||||
|
||||
// No more publish location for this document
|
||||
if(publishAttributesList.length === 0) {
|
||||
callback(errorFlag);
|
||||
return;
|
||||
}
|
||||
function publishLocation(callback, errorFlag) {
|
||||
|
||||
// Dequeue a synchronized location
|
||||
var publishAttributes = publishAttributesList.pop();
|
||||
// No more publish location for this document
|
||||
if(publishAttributesList.length === 0) {
|
||||
callback(errorFlag);
|
||||
return;
|
||||
}
|
||||
|
||||
// Format the content
|
||||
var content = getPublishContent(publishFileDesc, publishAttributes, publishHTML);
|
||||
var title = (publishFileDesc.frontMatter || {}).title || publishFileDesc.title;
|
||||
// Dequeue a synchronized location
|
||||
var publishAttributes = publishAttributesList.pop();
|
||||
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
// Format the content
|
||||
var content = getPublishContent(publishFileDesc, publishAttributes, publishHTML);
|
||||
var title = (publishFileDesc.frontMatter || {}).title || publishFileDesc.title;
|
||||
|
||||
// Get the html from the onPreviewFinished callback
|
||||
var currentHTML;
|
||||
eventMgr.addListener("onPreviewFinished", function(htmlWithComments, htmlWithoutComments) {
|
||||
currentHTML = {
|
||||
withComments: htmlWithComments,
|
||||
withoutComments: htmlWithoutComments
|
||||
};
|
||||
});
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
|
||||
// Listen to offline status changes
|
||||
var isOffline = false;
|
||||
eventMgr.addListener("onOfflineChanged", function(isOfflineParam) {
|
||||
isOffline = isOfflineParam;
|
||||
});
|
||||
// Get the html from the onPreviewFinished callback
|
||||
var currentHTML;
|
||||
eventMgr.addListener("onPreviewFinished", function(htmlWithComments, htmlWithoutComments) {
|
||||
currentHTML = {
|
||||
withComments: htmlWithComments,
|
||||
withoutComments: htmlWithoutComments
|
||||
};
|
||||
});
|
||||
|
||||
var publishRunning = false;
|
||||
publisher.publish = function() {
|
||||
// If publish is running or offline
|
||||
if(publishRunning === true || isOffline === true) {
|
||||
return;
|
||||
}
|
||||
// Listen to offline status changes
|
||||
var isOffline = false;
|
||||
eventMgr.addListener("onOfflineChanged", function(isOfflineParam) {
|
||||
isOffline = isOfflineParam;
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
};
|
||||
var publishRunning = false;
|
||||
publisher.publish = function() {
|
||||
// If publish is running or offline
|
||||
if(publishRunning === true || isOffline === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate a publishIndex associated to a file and store publishAttributes
|
||||
function createPublishIndex(fileDesc, publishAttributes) {
|
||||
var publishIndex;
|
||||
do {
|
||||
publishIndex = "publish." + utils.randomString();
|
||||
} while (_.has(storage, publishIndex));
|
||||
publishAttributes.publishIndex = publishIndex;
|
||||
fileDesc.addPublishLocation(publishAttributes);
|
||||
eventMgr.onNewPublishSuccess(fileDesc, publishAttributes);
|
||||
}
|
||||
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);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Initialize the "New publication" dialog
|
||||
var newLocationProvider;
|
||||
function initNewLocation(provider) {
|
||||
var defaultPublishFormat = provider.defaultPublishFormat || "markdown";
|
||||
newLocationProvider = provider;
|
||||
$(".publish-provider-name").text(provider.providerName);
|
||||
// Generate a publishIndex associated to a file and store publishAttributes
|
||||
function createPublishIndex(fileDesc, publishAttributes) {
|
||||
var publishIndex;
|
||||
do {
|
||||
publishIndex = "publish." + utils.randomString();
|
||||
} while(_.has(storage, publishIndex));
|
||||
publishAttributes.publishIndex = publishIndex;
|
||||
fileDesc.addPublishLocation(publishAttributes);
|
||||
eventMgr.onNewPublishSuccess(fileDesc, publishAttributes);
|
||||
}
|
||||
|
||||
// Show/hide controls depending on provider
|
||||
$('.modal-publish [class*=" modal-publish-"]').hide().filter(".modal-publish-" + provider.providerId).show();
|
||||
// Initialize the "New publication" dialog
|
||||
var newLocationProvider;
|
||||
|
||||
// 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);
|
||||
function initNewLocation(provider) {
|
||||
var defaultPublishFormat = provider.defaultPublishFormat || "markdown";
|
||||
newLocationProvider = provider;
|
||||
$(".publish-provider-name").text(provider.providerName);
|
||||
|
||||
// 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);
|
||||
}
|
||||
// Show/hide controls depending on provider
|
||||
$('.modal-publish [class*=" modal-publish-"]').hide().filter(".modal-publish-" + provider.providerId).show();
|
||||
|
||||
// Open dialog box
|
||||
$(".modal-publish").modal();
|
||||
}
|
||||
// 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);
|
||||
|
||||
// Add a new publish location to a local document
|
||||
function performNewLocation(event) {
|
||||
var provider = newLocationProvider;
|
||||
var publishAttributes = provider.newPublishAttributes(event);
|
||||
if(publishAttributes === undefined) {
|
||||
return;
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
});
|
||||
// Open dialog box
|
||||
$(".modal-publish").modal();
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
// Add a new publish location to a local document
|
||||
function performNewLocation(event) {
|
||||
var provider = newLocationProvider;
|
||||
var publishAttributes = provider.newPublishAttributes(event);
|
||||
if(publishAttributes === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var initPublishButtonTmpl = [
|
||||
'<li>',
|
||||
' <a href="#"',
|
||||
' class="action-init-publish-<%= provider.providerId %>">',
|
||||
' <i class="icon-provider-<%= provider.providerId %>"></i> <%= provider.providerName %>',
|
||||
' </a>',
|
||||
'</li>'
|
||||
].join('');
|
||||
eventMgr.addListener("onReady", function() {
|
||||
if(window.viewerMode === false) {
|
||||
// Add every provider in the panel menu
|
||||
var publishMenuElt = document.querySelector('.menu-panel .publish-on-provider-list');
|
||||
var publishMenuHtml = _.reduce(providerMap, function(result, provider) {
|
||||
return result + _.template(initPublishButtonTmpl, {
|
||||
provider: provider
|
||||
});
|
||||
}, '');
|
||||
publishMenuElt.innerHTML = publishMenuHtml;
|
||||
_.each(providerMap, function(provider) {
|
||||
// Click on open publish dialog
|
||||
$(publishMenuElt.querySelector('.action-init-publish-' + provider.providerId)).click(function() {
|
||||
initNewLocation(provider);
|
||||
});
|
||||
// Click on perform new publication
|
||||
$(".action-publish-" + provider.providerId).click(function() {
|
||||
initNewLocation(provider);
|
||||
});
|
||||
});
|
||||
}
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$(".action-process-publish").click(performNewLocation);
|
||||
// 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 $customTmplCollapseElt = $('.publish-custom-template-collapse').collapse({
|
||||
toggle: false
|
||||
});
|
||||
var $customTmplTextareaElt = $('#textarea-publish-custom-template');
|
||||
var doCustomTmplCollapse = _.debounce(function() {
|
||||
$customTmplCollapseElt.collapse(utils.getInputRadio("radio-publish-format") == 'template' ? 'show' : 'hide');
|
||||
}, 100);
|
||||
$("#checkbox-publish-custom-template").change(function() {
|
||||
$customTmplTextareaElt.prop('disabled', !this.checked);
|
||||
});
|
||||
$("input:radio[name=radio-publish-format]").change(function() {
|
||||
doCustomTmplCollapse();
|
||||
});
|
||||
$('.modal-publish').on('hidden.bs.modal', function() {
|
||||
$customTmplCollapseElt.collapse('hide');
|
||||
});
|
||||
var initPublishButtonTmpl = [
|
||||
'<li>',
|
||||
' <a href="#"',
|
||||
' class="action-init-publish-<%= provider.providerId %>">',
|
||||
' <i class="icon-provider-<%= provider.providerId %>"></i> <%= provider.providerName %>',
|
||||
' </a>',
|
||||
'</li>'
|
||||
].join('');
|
||||
eventMgr.addListener("onReady", function() {
|
||||
if(window.viewerMode === false) {
|
||||
// Add every provider in the panel menu
|
||||
var publishMenuElt = document.querySelector('.menu-panel .publish-on-provider-list');
|
||||
var publishMenuHtml = _.reduce(providerMap, function(result, provider) {
|
||||
return result + _.template(initPublishButtonTmpl, {
|
||||
provider: provider
|
||||
});
|
||||
}, '');
|
||||
publishMenuElt.innerHTML = publishMenuHtml;
|
||||
_.each(providerMap, function(provider) {
|
||||
// Click on open publish dialog
|
||||
$(publishMenuElt.querySelector('.action-init-publish-' + provider.providerId)).click(function() {
|
||||
initNewLocation(provider);
|
||||
});
|
||||
// Click on perform new publication
|
||||
$(".action-publish-" + provider.providerId).click(function() {
|
||||
initNewLocation(provider);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Save As menu items
|
||||
$(".action-download-md").click(function() {
|
||||
var content = fileMgr.currentFile.content;
|
||||
var title = fileMgr.currentFile.title;
|
||||
utils.saveAs(content, title + ".md");
|
||||
});
|
||||
$(".action-download-html").click(function() {
|
||||
var title = fileMgr.currentFile.title;
|
||||
utils.saveAs(currentHTML.withoutComments, title + ".html");
|
||||
});
|
||||
$(".action-download-template").click(function() {
|
||||
var fileDesc = fileMgr.currentFile;
|
||||
var content = publisher.applyTemplate(fileDesc, undefined, currentHTML);
|
||||
utils.saveAs(content, fileDesc.title + (settings.template.indexOf("documentHTML") === -1 ? ".md" : ".html"));
|
||||
});
|
||||
$(".action-download-pdf").click(function() {
|
||||
var fileDesc = fileMgr.currentFile;
|
||||
var content = publisher.applyTemplate(fileDesc, {
|
||||
customTmpl: settings.pdfTemplate
|
||||
}, currentHTML);
|
||||
var task = new AsyncTask();
|
||||
var pdf;
|
||||
task.onRun(function() {
|
||||
if(isOffline === true) {
|
||||
eventMgr.onError("Operation not available in offline mode.");
|
||||
task.chain();
|
||||
return;
|
||||
}
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', constants.HTMLTOPDF_URL, true);
|
||||
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||
xhr.responseType = 'blob';
|
||||
xhr.onreadystatechange = function() {
|
||||
if(this.readyState == 4) {
|
||||
if(this.status == 200) {
|
||||
pdf = this.response;
|
||||
}
|
||||
else {
|
||||
eventMgr.onError("Error when trying to generate PDF: " + this.status);
|
||||
}
|
||||
task.chain();
|
||||
}
|
||||
};
|
||||
xhr.send(content);
|
||||
});
|
||||
task.onSuccess(function() {
|
||||
if(pdf !== undefined) {
|
||||
utils.saveAs(pdf, fileMgr.currentFile.title + ".pdf");
|
||||
}
|
||||
});
|
||||
task.enqueue();
|
||||
});
|
||||
});
|
||||
$(".action-process-publish").click(performNewLocation);
|
||||
|
||||
eventMgr.onPublisherCreated(publisher);
|
||||
return publisher;
|
||||
var $customTmplCollapseElt = $('.publish-custom-template-collapse').collapse({
|
||||
toggle: false
|
||||
});
|
||||
var $customTmplTextareaElt = $('#textarea-publish-custom-template');
|
||||
var doCustomTmplCollapse = _.debounce(function() {
|
||||
$customTmplCollapseElt.collapse(utils.getInputRadio("radio-publish-format") == 'template' ? 'show' : 'hide');
|
||||
}, 100);
|
||||
$("#checkbox-publish-custom-template").change(function() {
|
||||
$customTmplTextareaElt.prop('disabled', !this.checked);
|
||||
});
|
||||
$("input:radio[name=radio-publish-format]").change(function() {
|
||||
doCustomTmplCollapse();
|
||||
});
|
||||
$('.modal-publish').on('hidden.bs.modal', function() {
|
||||
$customTmplCollapseElt.collapse('hide');
|
||||
});
|
||||
|
||||
// Save As menu items
|
||||
$(".action-download-md").click(function() {
|
||||
var content = fileMgr.currentFile.content;
|
||||
var title = fileMgr.currentFile.title;
|
||||
utils.saveAs(content, title + ".md");
|
||||
});
|
||||
$(".action-download-html").click(function() {
|
||||
var title = fileMgr.currentFile.title;
|
||||
utils.saveAs(currentHTML.withoutComments, title + ".html");
|
||||
});
|
||||
$(".action-download-template").click(function() {
|
||||
var fileDesc = fileMgr.currentFile;
|
||||
var content = publisher.applyTemplate(fileDesc, undefined, currentHTML);
|
||||
utils.saveAs(content, fileDesc.title + (settings.template.indexOf("documentHTML") === -1 ? ".md" : ".html"));
|
||||
});
|
||||
var monetize = new MonetizeJS({
|
||||
applicationID: 'iklMbzDI7dvMEScb'
|
||||
});
|
||||
$(".action-download-pdf").click(function() {
|
||||
var fileDesc = fileMgr.currentFile;
|
||||
var content = publisher.applyTemplate(fileDesc, {
|
||||
customTmpl: settings.pdfTemplate
|
||||
}, currentHTML);
|
||||
var task = new AsyncTask();
|
||||
var pdf, token;
|
||||
task.onRun(function() {
|
||||
if(isOffline === true) {
|
||||
eventMgr.onError("Operation not available in offline mode.");
|
||||
return task.chain();
|
||||
}
|
||||
if(!eventMgr.isSponsor) {
|
||||
$('.modal-sponsorship-required').modal('show');
|
||||
return task.chain();
|
||||
}
|
||||
monetize.getTokenImmediate(function(err, result) {
|
||||
token = result || '';
|
||||
task.chain();
|
||||
});
|
||||
});
|
||||
task.onRun(function() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', constants.HTMLTOPDF_URL + '?token=' + encodeURIComponent(token) + '&options=' + encodeURIComponent(settings.pdfOptions), true);
|
||||
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||
xhr.responseType = 'blob';
|
||||
xhr.onreadystatechange = function() {
|
||||
if(this.readyState == 4) {
|
||||
if(this.status == 200) {
|
||||
pdf = this.response;
|
||||
}
|
||||
else {
|
||||
eventMgr.onError("Error when trying to generate PDF: " + this.status);
|
||||
}
|
||||
task.chain();
|
||||
}
|
||||
};
|
||||
xhr.send(content);
|
||||
});
|
||||
task.onSuccess(function() {
|
||||
if(pdf !== undefined) {
|
||||
utils.saveAs(pdf, fileMgr.currentFile.title + ".pdf");
|
||||
}
|
||||
});
|
||||
task.enqueue();
|
||||
});
|
||||
});
|
||||
|
||||
eventMgr.onPublisherCreated(publisher);
|
||||
return publisher;
|
||||
});
|
||||
|
@ -52,10 +52,10 @@ define([
|
||||
constants.MAIN_URL,
|
||||
'libs/MathJax/MathJax.js?config=TeX-AMS_HTML"></script>\n',
|
||||
'</head>\n',
|
||||
'<body class="pdf"><%= documentHTML %></body>\n',
|
||||
'<body><%= documentHTML %></body>\n',
|
||||
'</html>'
|
||||
].join(""),
|
||||
pdfPageSize: 'A4',
|
||||
pdfOptions: '{}',
|
||||
sshProxy: constants.SSH_PROXY_URL,
|
||||
extensionSettings: {}
|
||||
};
|
||||
|
@ -129,7 +129,7 @@ define([
|
||||
// For input control
|
||||
function inputError(element, event) {
|
||||
if(event !== undefined) {
|
||||
element.stop(true, true).addClass("error").delay(1000).queue(function() {
|
||||
element.stop(true, true).addClass("error").delay(3000).queue(function() {
|
||||
$(this).removeClass("error");
|
||||
$(this).dequeue();
|
||||
});
|
||||
@ -223,6 +223,23 @@ define([
|
||||
return value;
|
||||
};
|
||||
|
||||
// Return input value and check that it's a valid JSON
|
||||
utils.getInputJSONValue = function(element, event) {
|
||||
element = jqElt(element);
|
||||
var value = utils.getInputTextValue(element, event);
|
||||
if(value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
try {
|
||||
JSON.parse(value);
|
||||
}
|
||||
catch(e) {
|
||||
inputError(element, event);
|
||||
return undefined;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
// Return checkbox boolean value
|
||||
utils.getInputChecked = function(element) {
|
||||
element = jqElt(element);
|
||||
|
Loading…
Reference in New Issue
Block a user