Implemented PDF options
This commit is contained in:
parent
ae8adddf5d
commit
3f8b5a865a
@ -18,10 +18,10 @@ module.exports = function(req, res, next) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Margins
|
// Margins
|
||||||
var marginRight = parseInt(options.marginRight);
|
|
||||||
params.push('-R', isNaN(marginRight) ? 25 : marginRight);
|
|
||||||
var marginTop = parseInt(options.marginTop);
|
var marginTop = parseInt(options.marginTop);
|
||||||
params.push('-T', isNaN(marginTop) ? 25 : 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);
|
var marginBottom = parseInt(options.marginBottom);
|
||||||
params.push('-B', isNaN(marginBottom) ? 25 : marginBottom);
|
params.push('-B', isNaN(marginBottom) ? 25 : marginBottom);
|
||||||
var marginLeft = parseInt(options.marginLeft);
|
var marginLeft = parseInt(options.marginLeft);
|
||||||
@ -42,8 +42,7 @@ module.exports = function(req, res, next) {
|
|||||||
options.footerFontSize && params.push('--footer-font-size ', options.footerFontSize);
|
options.footerFontSize && params.push('--footer-font-size ', options.footerFontSize);
|
||||||
|
|
||||||
// Page size
|
// Page size
|
||||||
var pageSize = options.pageSize;
|
params.push('--page-size', authorizedPageSizes.indexOf(options.pageSize) === -1 ? 'A4' : options.pageSize);
|
||||||
params.push('--page-size', authorizedPageSizes.indexOf(pageSize) === -1 ? 'A4' : pageSize);
|
|
||||||
|
|
||||||
// wkhtmltopdf can't access /dev/stdout on Amazon EC2 for some reason
|
// wkhtmltopdf can't access /dev/stdout on Amazon EC2 for some reason
|
||||||
var filePath = '/tmp/' + Date.now() + '.pdf';
|
var filePath = '/tmp/' + Date.now() + '.pdf';
|
||||||
|
@ -14,9 +14,10 @@ define([
|
|||||||
"text!html/bodyIndex.html",
|
"text!html/bodyIndex.html",
|
||||||
"text!html/bodyViewer.html",
|
"text!html/bodyViewer.html",
|
||||||
"text!html/tooltipSettingsTemplate.html",
|
"text!html/tooltipSettingsTemplate.html",
|
||||||
|
"text!html/tooltipSettingsPdfOptions.html",
|
||||||
"storage",
|
"storage",
|
||||||
'pagedown'
|
'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 = {};
|
var core = {};
|
||||||
|
|
||||||
@ -142,8 +143,8 @@ define([
|
|||||||
utils.setInputValue("#textarea-settings-publish-template", settings.template);
|
utils.setInputValue("#textarea-settings-publish-template", settings.template);
|
||||||
// PDF template
|
// PDF template
|
||||||
utils.setInputValue("#textarea-settings-pdf-template", settings.pdfTemplate);
|
utils.setInputValue("#textarea-settings-pdf-template", settings.pdfTemplate);
|
||||||
// PDF page size
|
// PDF options
|
||||||
utils.setInputValue("#input-settings-pdf-page-size", settings.pdfPageSize);
|
utils.setInputValue("#textarea-settings-pdf-options", settings.pdfOptions);
|
||||||
// SSH proxy
|
// SSH proxy
|
||||||
utils.setInputValue("#input-settings-ssh-proxy", settings.sshProxy);
|
utils.setInputValue("#input-settings-ssh-proxy", settings.sshProxy);
|
||||||
|
|
||||||
@ -189,8 +190,8 @@ define([
|
|||||||
newSettings.template = utils.getInputTextValue("#textarea-settings-publish-template", event);
|
newSettings.template = utils.getInputTextValue("#textarea-settings-publish-template", event);
|
||||||
// PDF template
|
// PDF template
|
||||||
newSettings.pdfTemplate = utils.getInputTextValue("#textarea-settings-pdf-template", event);
|
newSettings.pdfTemplate = utils.getInputTextValue("#textarea-settings-pdf-template", event);
|
||||||
// PDF page size
|
// PDF options
|
||||||
newSettings.pdfPageSize = utils.getInputValue("#input-settings-pdf-page-size");
|
newSettings.pdfOptions = utils.getInputJSONValue("#textarea-settings-pdf-options", event);
|
||||||
// SSH proxy
|
// SSH proxy
|
||||||
newSettings.sshProxy = utils.checkUrl(utils.getInputTextValue("#input-settings-ssh-proxy", event), true);
|
newSettings.sshProxy = utils.checkUrl(utils.getInputTextValue("#input-settings-ssh-proxy", event), true);
|
||||||
|
|
||||||
@ -331,10 +332,12 @@ define([
|
|||||||
});
|
});
|
||||||
var $alerts = $();
|
var $alerts = $();
|
||||||
|
|
||||||
function hasPaid(payments) {
|
function isSponsor(payments) {
|
||||||
return payments && (
|
var result = payments && (
|
||||||
(payments.chargeOption && payments.chargeOption.alias == 'once') ||
|
(payments.chargeOption && payments.chargeOption.alias == 'once') ||
|
||||||
(payments.subscriptionOption && payments.subscriptionOption.alias == 'yearly'));
|
(payments.subscriptionOption && payments.subscriptionOption.alias == 'yearly'));
|
||||||
|
eventMgr.isSponsor = result;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeAlerts() {
|
function removeAlerts() {
|
||||||
@ -346,11 +349,10 @@ define([
|
|||||||
monetize.getPayments({
|
monetize.getPayments({
|
||||||
pricingOptions: [
|
pricingOptions: [
|
||||||
'once',
|
'once',
|
||||||
'monthly',
|
|
||||||
'yearly'
|
'yearly'
|
||||||
]
|
]
|
||||||
}, function(err, payments) {
|
}, function(err, payments) {
|
||||||
if(hasPaid(payments)) {
|
if(isSponsor(payments)) {
|
||||||
eventMgr.onMessage('Thank you for sponsoring StackEdit!');
|
eventMgr.onMessage('Thank you for sponsoring StackEdit!');
|
||||||
removeAlerts();
|
removeAlerts();
|
||||||
}
|
}
|
||||||
@ -363,7 +365,7 @@ define([
|
|||||||
}
|
}
|
||||||
monetize.getPaymentsImmediate(function(err, payments) {
|
monetize.getPaymentsImmediate(function(err, payments) {
|
||||||
removeAlerts();
|
removeAlerts();
|
||||||
if(!hasPaid(payments)) {
|
if(!isSponsor(payments)) {
|
||||||
_.each(document.querySelectorAll('.modal-body'), function(modalBodyElt) {
|
_.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>');
|
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);
|
$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>'
|
'<b class="text-danger">NOTE: Backlinks in Stack Exchange Q/A are not welcome.</b>'
|
||||||
].join(''));
|
].join(''));
|
||||||
utils.createTooltip(".tooltip-template", settingsTemplateTooltipHTML);
|
utils.createTooltip(".tooltip-template", settingsTemplateTooltipHTML);
|
||||||
|
utils.createTooltip(".tooltip-pdf-options", settingsPdfOptionsTooltipHTML);
|
||||||
|
|
||||||
// Avoid dropdown panels to close on click
|
// Avoid dropdown panels to close on click
|
||||||
$("div.dropdown-menu").click(function(e) {
|
$("div.dropdown-menu").click(function(e) {
|
||||||
|
@ -10,6 +10,11 @@ define([
|
|||||||
|
|
||||||
var dialogAbout = new Extension("dialogAbout", 'Dialog "About"');
|
var dialogAbout = new Extension("dialogAbout", 'Dialog "About"');
|
||||||
|
|
||||||
|
var eventMgr;
|
||||||
|
dialogAbout.onEventMgrCreated = function(eventMgrParameter) {
|
||||||
|
eventMgr = eventMgrParameter;
|
||||||
|
};
|
||||||
|
|
||||||
var monetize = new MonetizeJS({
|
var monetize = new MonetizeJS({
|
||||||
applicationID: 'iklMbzDI7dvMEScb'
|
applicationID: 'iklMbzDI7dvMEScb'
|
||||||
});
|
});
|
||||||
@ -22,6 +27,7 @@ define([
|
|||||||
monetize.getPayments({
|
monetize.getPayments({
|
||||||
summary: true
|
summary: true
|
||||||
}, function() {
|
}, 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"
|
<a href="#" data-toggle="collapse" data-target=".collapse-synchronize"
|
||||||
class="list-group-item">
|
class="list-group-item">
|
||||||
<div><i class="icon-refresh"></i> Synchronize</div>
|
<div><i class="icon-refresh"></i> Synchronize</div>
|
||||||
<small>Backup, collaborate in the cloud</small>
|
<small>Backup, collaborate...</small>
|
||||||
</a>
|
</a>
|
||||||
<div class="sub-menu collapse collapse-synchronize clearfix">
|
<div class="sub-menu collapse collapse-synchronize clearfix">
|
||||||
<ul class="nav alert alert-danger show-already-synchronized">
|
<ul class="nav alert alert-danger show-already-synchronized">
|
||||||
@ -159,7 +159,7 @@
|
|||||||
<li><a class="action-download-template" href="#"><i
|
<li><a class="action-download-template" href="#"><i
|
||||||
class="icon-download"></i> Using template</a></li>
|
class="icon-download"></i> Using template</a></li>
|
||||||
<li><a class="action-download-pdf" href="#"><i
|
<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>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -1072,14 +1072,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<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">
|
<div class="col-sm-7">
|
||||||
<select id="input-settings-pdf-page-size" class="form-control">
|
<textarea id="textarea-settings-pdf-options"
|
||||||
<option value="A3">A3</option>
|
class="form-control"></textarea>
|
||||||
<option value="A4">A4</option>
|
|
||||||
<option value="Legal">Legal</option>
|
|
||||||
<option value="Letter">Letter</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@ -1303,4 +1301,24 @@
|
|||||||
</div>
|
</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>
|
<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 syncIndex = createSyncIndex(path);
|
||||||
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
|
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
|
||||||
if(fileDesc !== undefined) {
|
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);
|
importPaths.push(path);
|
||||||
});
|
});
|
||||||
|
@ -91,7 +91,7 @@ define([
|
|||||||
var syncIndex = createSyncIndex(doc.id);
|
var syncIndex = createSyncIndex(doc.id);
|
||||||
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
|
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
|
||||||
if(fileDesc !== undefined) {
|
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);
|
importIds.push(doc.id);
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,7 @@ define([
|
|||||||
"fileSystem",
|
"fileSystem",
|
||||||
"fileMgr",
|
"fileMgr",
|
||||||
"sharing",
|
"sharing",
|
||||||
|
"monetizejs",
|
||||||
"classes/Provider",
|
"classes/Provider",
|
||||||
"classes/AsyncTask",
|
"classes/AsyncTask",
|
||||||
"providers/bloggerProvider",
|
"providers/bloggerProvider",
|
||||||
@ -22,7 +23,7 @@ define([
|
|||||||
"providers/sshProvider",
|
"providers/sshProvider",
|
||||||
"providers/tumblrProvider",
|
"providers/tumblrProvider",
|
||||||
"providers/wordpressProvider"
|
"providers/wordpressProvider"
|
||||||
], function($, _, constants, utils, storage, settings, eventMgr, fileSystem, fileMgr, sharing, Provider, AsyncTask) {
|
], function($, _, constants, utils, storage, settings, eventMgr, fileSystem, fileMgr, sharing, MonetizeJS, Provider, AsyncTask) {
|
||||||
|
|
||||||
var publisher = {};
|
var publisher = {};
|
||||||
|
|
||||||
@ -114,6 +115,7 @@ define([
|
|||||||
var publishAttributesList = [];
|
var publishAttributesList = [];
|
||||||
var publishFileDesc;
|
var publishFileDesc;
|
||||||
var publishHTML;
|
var publishHTML;
|
||||||
|
|
||||||
function publishLocation(callback, errorFlag) {
|
function publishLocation(callback, errorFlag) {
|
||||||
|
|
||||||
// No more publish location for this document
|
// No more publish location for this document
|
||||||
@ -195,6 +197,7 @@ define([
|
|||||||
|
|
||||||
// Initialize the "New publication" dialog
|
// Initialize the "New publication" dialog
|
||||||
var newLocationProvider;
|
var newLocationProvider;
|
||||||
|
|
||||||
function initNewLocation(provider) {
|
function initNewLocation(provider) {
|
||||||
var defaultPublishFormat = provider.defaultPublishFormat || "markdown";
|
var defaultPublishFormat = provider.defaultPublishFormat || "markdown";
|
||||||
newLocationProvider = provider;
|
newLocationProvider = provider;
|
||||||
@ -332,21 +335,33 @@ define([
|
|||||||
var content = publisher.applyTemplate(fileDesc, undefined, currentHTML);
|
var content = publisher.applyTemplate(fileDesc, undefined, currentHTML);
|
||||||
utils.saveAs(content, fileDesc.title + (settings.template.indexOf("documentHTML") === -1 ? ".md" : ".html"));
|
utils.saveAs(content, fileDesc.title + (settings.template.indexOf("documentHTML") === -1 ? ".md" : ".html"));
|
||||||
});
|
});
|
||||||
|
var monetize = new MonetizeJS({
|
||||||
|
applicationID: 'iklMbzDI7dvMEScb'
|
||||||
|
});
|
||||||
$(".action-download-pdf").click(function() {
|
$(".action-download-pdf").click(function() {
|
||||||
var fileDesc = fileMgr.currentFile;
|
var fileDesc = fileMgr.currentFile;
|
||||||
var content = publisher.applyTemplate(fileDesc, {
|
var content = publisher.applyTemplate(fileDesc, {
|
||||||
customTmpl: settings.pdfTemplate
|
customTmpl: settings.pdfTemplate
|
||||||
}, currentHTML);
|
}, currentHTML);
|
||||||
var task = new AsyncTask();
|
var task = new AsyncTask();
|
||||||
var pdf;
|
var pdf, token;
|
||||||
task.onRun(function() {
|
task.onRun(function() {
|
||||||
if(isOffline === true) {
|
if(isOffline === true) {
|
||||||
eventMgr.onError("Operation not available in offline mode.");
|
eventMgr.onError("Operation not available in offline mode.");
|
||||||
task.chain();
|
return task.chain();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
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();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.open('POST', constants.HTMLTOPDF_URL, true);
|
xhr.open('POST', constants.HTMLTOPDF_URL + '?token=' + encodeURIComponent(token) + '&options=' + encodeURIComponent(settings.pdfOptions), true);
|
||||||
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||||
xhr.responseType = 'blob';
|
xhr.responseType = 'blob';
|
||||||
xhr.onreadystatechange = function() {
|
xhr.onreadystatechange = function() {
|
||||||
|
@ -52,10 +52,10 @@ define([
|
|||||||
constants.MAIN_URL,
|
constants.MAIN_URL,
|
||||||
'libs/MathJax/MathJax.js?config=TeX-AMS_HTML"></script>\n',
|
'libs/MathJax/MathJax.js?config=TeX-AMS_HTML"></script>\n',
|
||||||
'</head>\n',
|
'</head>\n',
|
||||||
'<body class="pdf"><%= documentHTML %></body>\n',
|
'<body><%= documentHTML %></body>\n',
|
||||||
'</html>'
|
'</html>'
|
||||||
].join(""),
|
].join(""),
|
||||||
pdfPageSize: 'A4',
|
pdfOptions: '{}',
|
||||||
sshProxy: constants.SSH_PROXY_URL,
|
sshProxy: constants.SSH_PROXY_URL,
|
||||||
extensionSettings: {}
|
extensionSettings: {}
|
||||||
};
|
};
|
||||||
|
@ -129,7 +129,7 @@ define([
|
|||||||
// For input control
|
// For input control
|
||||||
function inputError(element, event) {
|
function inputError(element, event) {
|
||||||
if(event !== undefined) {
|
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).removeClass("error");
|
||||||
$(this).dequeue();
|
$(this).dequeue();
|
||||||
});
|
});
|
||||||
@ -223,6 +223,23 @@ define([
|
|||||||
return value;
|
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
|
// Return checkbox boolean value
|
||||||
utils.getInputChecked = function(element) {
|
utils.getInputChecked = function(element) {
|
||||||
element = jqElt(element);
|
element = jqElt(element);
|
||||||
|
Loading…
Reference in New Issue
Block a user