Implemented markdown footnotes

This commit is contained in:
benweet 2013-06-23 00:48:57 +01:00
parent 56f1c3d8c4
commit abe18e41bf
56 changed files with 538 additions and 347 deletions

View File

@ -419,6 +419,13 @@ div.dropdown-menu textarea {
margin-top: 10px; margin-top: 10px;
} }
.footnote {
vertical-align: top;
position: relative;
top: -0.5em;
font-size: 0.8em;
}
.icon-link { .icon-link {
background-position: -72px -168px; background-position: -72px -168px;
} }
@ -642,6 +649,10 @@ div.dropdown-menu textarea {
text-align: left; text-align: left;
} }
.tooltip li {
line-height: 1.4;
}
/* Definition list */ /* Definition list */
dt,dd { dt,dd {
margin-top: 5px; margin-top: 5px;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

10
js/classes/Extension.js Normal file
View File

@ -0,0 +1,10 @@
define(function() {
function Extension(extensionId, extensionName, isOptional) {
this.extensionId = extensionId;
this.extensionName = extensionName;
this.isOptional = isOptional;
}
return Extension;
});

9
js/classes/Provider.js Normal file
View File

@ -0,0 +1,9 @@
define(function() {
function Provider(providerId, providerName) {
this.providerId = providerId;
this.providerName = providerName;
}
return Provider;
});

View File

@ -461,6 +461,28 @@ define([
} }
}); });
// Reset inputs
$(".action-reset-input").click(function() {
utils.resetModalInputs();
});
// Do periodic tasks
intervalId = window.setInterval(function() {
utils.updateCurrentTime();
checkWindowUnique();
if(isUserActive() === true || viewerMode === true) {
_.each(periodicCallbacks, function(callback) {
callback();
});
checkOnline();
}
}, 1000);
});
core.onReady(extensionMgr.onReady);
// After extensions onReady callbacks
core.onReady(function() {
// Tooltips // Tooltips
$(".tooltip-lazy-rendering").tooltip({ $(".tooltip-lazy-rendering").tooltip({
container: '#modal-settings', container: '#modal-settings',
@ -490,24 +512,7 @@ define([
e.stopPropagation(); e.stopPropagation();
}); });
// Reset inputs
$(".action-reset-input").click(function() {
utils.resetModalInputs();
});
// Do periodic tasks
intervalId = window.setInterval(function() {
utils.updateCurrentTime();
checkWindowUnique();
if(isUserActive() === true || viewerMode === true) {
_.each(periodicCallbacks, function(callback) {
callback();
});
checkOnline();
}
}, 1000);
}); });
core.onReady(extensionMgr.onReady);
return core; return core;
}); });

View File

@ -2,6 +2,7 @@ define([
"jquery", "jquery",
"underscore", "underscore",
"utils", "utils",
"classes/Extension",
"settings", "settings",
"text!html/settingsExtensionsAccordion.html", "text!html/settingsExtensionsAccordion.html",
"extensions/googleAnalytics", "extensions/googleAnalytics",
@ -20,20 +21,21 @@ define([
"extensions/documentTitle", "extensions/documentTitle",
"extensions/workingIndicator", "extensions/workingIndicator",
"extensions/notifications", "extensions/notifications",
"extensions/markdown-extra", "extensions/markdownExtra",
"extensions/markdownFootnotes",
"extensions/toc", "extensions/toc",
"extensions/mathJax", "extensions/mathJax",
"extensions/emailConverter", "extensions/emailConverter",
"extensions/scrollLink", "extensions/scrollLink",
"libs/bootstrap", "libs/bootstrap",
"libs/jquery.waitforimages" "libs/jquery.waitforimages"
], function($, _, utils, settings, settingsExtensionsAccordionHTML) { ], function($, _, utils, Extension, settings, settingsExtensionsAccordionHTML) {
var extensionMgr = {}; var extensionMgr = {};
// Create a list of extensions // Create a list of extensions
var extensionList = _.chain(arguments).map(function(argument) { var extensionList = _.chain(arguments).map(function(argument) {
return _.isObject(argument) && argument.extensionId && argument; return argument instanceof Extension && argument;
}).compact().value(); }).compact().value();
// Return every named callbacks implemented in extensions // Return every named callbacks implemented in extensions
@ -66,7 +68,7 @@ define([
extensionSettings = settings.extensionSettings || {}; extensionSettings = settings.extensionSettings || {};
_.each(extensionList, function(extension) { _.each(extensionList, function(extension) {
extension.config = _.extend({}, extension.defaultConfig, extensionSettings[extension.extensionId]); extension.config = _.extend({}, extension.defaultConfig, extensionSettings[extension.extensionId]);
extension.config.enabled = !extension.optional || extension.config.enabled === undefined || extension.config.enabled === true; extension.config.enabled = !extension.isOptional || extension.config.enabled === undefined || extension.config.enabled === true;
}); });
// Load/Save extension config from/to settings // Load/Save extension config from/to settings
@ -152,8 +154,8 @@ define([
$("#accordion-extensions").append($(_.template(settingsExtensionsAccordionHTML, { $("#accordion-extensions").append($(_.template(settingsExtensionsAccordionHTML, {
extensionId: extension.extensionId, extensionId: extension.extensionId,
extensionName: extension.extensionName, extensionName: extension.extensionName,
optional: extension.optional, isOptional: extension.isOptional,
settingsBloc: extension.settingsBloc settingsBlock: extension.settingsBlock
}))); })));
} }

View File

@ -1,21 +1,48 @@
define([ define([
"jquery", "jquery",
"underscore",
"utils",
"classes/Extension",
"text!html/buttonHtmlCode.html", "text!html/buttonHtmlCode.html",
], function($, buttonHtmlCodeHTML) { "text!html/buttonHtmlCodeSettingsBlock.html",
], function($, _, utils, Extension, buttonHtmlCodeHTML, buttonHtmlCodeSettingsBlockHTML) {
var buttonHtmlCode = { var buttonHtmlCode = new Extension("buttonHtmlCode", 'Button "HTML code"', true);
extensionId: "buttonHtmlCode", buttonHtmlCode.settingsBlock = buttonHtmlCodeSettingsBlockHTML;
extensionName: 'Button "HTML code"', buttonHtmlCode.defaultConfig = {
optional: true, template: "<%= documentHTML %>",
settingsBloc: '<p>Adds a "HTML code" button over the preview.</p>' };
buttonHtmlCode.onLoadSettings = function() {
utils.setInputValue("#textarea-html-code-template", buttonHtmlCode.config.template);
};
buttonHtmlCode.onSaveSettings = function(newConfig, event) {
newConfig.template = utils.getInputValue("#textarea-html-code-template");
}; };
buttonHtmlCode.onCreatePreviewButton = function() { buttonHtmlCode.onCreatePreviewButton = function() {
return $(buttonHtmlCodeHTML); return $(buttonHtmlCodeHTML);
}; };
var selectedFileDesc = undefined;
buttonHtmlCode.onFileSelected = function(fileDesc) {
selectedFileDesc = fileDesc;
};
buttonHtmlCode.onPreviewFinished = function() { buttonHtmlCode.onPreviewFinished = function() {
$("#input-html-code").val($("#wmd-preview").html()); try {
var htmlCode = _.template(buttonHtmlCode.config.template, {
documentTitle: selectedFileDesc.title,
documentMarkdown: selectedFileDesc.content,
documentHTML: $("#wmd-preview").html()
});
$("#input-html-code").val(htmlCode);
}
catch(e) {
extensionMgr.onError(e);
return e.message;
}
}; };
buttonHtmlCode.onReady = function() { buttonHtmlCode.onReady = function() {

View File

@ -1,14 +1,11 @@
define([ define([
"jquery", "jquery",
"classes/Extension",
"text!html/buttonMarkdownSyntax.html", "text!html/buttonMarkdownSyntax.html",
], function($, buttonMarkdownSyntaxHTML) { ], function($, Extension, buttonMarkdownSyntaxHTML) {
var buttonMarkdownSyntax = { var buttonMarkdownSyntax = new Extension("buttonMarkdownSyntax", 'Button "Markdown syntax', true);
extensionId: "buttonMarkdownSyntax", buttonMarkdownSyntax.settingsBlock = '<p>Adds a "Markdown syntax" button over the preview.</p>';
extensionName: 'Button "Markdown syntax"',
optional: true,
settingsBloc: '<p>Adds a "Markdown syntax" button over the preview.</p>'
};
buttonMarkdownSyntax.onCreatePreviewButton = function() { buttonMarkdownSyntax.onCreatePreviewButton = function() {
return $(buttonMarkdownSyntaxHTML); return $(buttonMarkdownSyntaxHTML);

View File

@ -1,14 +1,12 @@
define([ define([
"jquery", "jquery",
"underscore", "underscore",
"classes/Extension",
"text!html/buttonPublish.html", "text!html/buttonPublish.html",
], function($, _, buttonPublishHTML) { ], function($, _, Extension, buttonPublishHTML) {
var buttonPublish = { var buttonPublish = new Extension("buttonPublish", 'Button "Publish"');
extensionId: "buttonPublish", buttonPublish.settingsBlock = '<p>Adds a "Publish document" button in the navigation bar.</p>';
extensionName: 'Button "Publish"',
settingsBloc: '<p>Adds a "Publish document" button in the navigation bar.</p>'
};
var button = undefined; var button = undefined;
var currentFileDesc = undefined; var currentFileDesc = undefined;

View File

@ -1,16 +1,13 @@
define([ define([
"jquery", "jquery",
"underscore", "underscore",
"classes/Extension",
"text!html/buttonShare.html", "text!html/buttonShare.html",
"text!html/buttonShareLocation.html", "text!html/buttonShareLocation.html",
], function($, _, buttonShareHTML, buttonShareLocationHTML) { ], function($, _, Extension, buttonShareHTML, buttonShareLocationHTML) {
var buttonShare = { var buttonShare = new Extension("buttonShare", 'Button "Share"', true);
extensionId: "buttonShare", buttonShare.settingsBlock = '<p>Adds a "Share document" button in the navigation bar.</p>';
extensionName: 'Button "Share"',
optional: true,
settingsBloc: '<p>Adds a "Share document" button in the navigation bar.</p>'
};
buttonShare.onCreateButton = function() { buttonShare.onCreateButton = function() {
return $(buttonShareHTML); return $(buttonShareHTML);

View File

@ -2,23 +2,20 @@ define([
"jquery", "jquery",
"underscore", "underscore",
"utils", "utils",
"classes/Extension",
"text!html/buttonStat.html", "text!html/buttonStat.html",
"text!html/buttonStatSettingsBloc.html", "text!html/buttonStatSettingsBlock.html",
], function($, _, utils, buttonStatHTML, buttonStatSettingsBlocHTML) { ], function($, _, utils, Extension, buttonStatHTML, buttonStatSettingsBlockHTML) {
var buttonStat = { var buttonStat = new Extension("buttonStat", 'Button "Statistics"', true);
extensionId: "buttonStat", buttonStat.settingsBlock = buttonStatSettingsBlockHTML;
extensionName: 'Button "Statistics"', buttonStat.defaultConfig = {
optional: true, name1: "Characters",
defaultConfig: { value1: "\\S",
name1: "Characters", name2: "Words",
value1: "\\S", value2: "\\S+",
name2: "Words", name3: "Paragraphs",
value2: "\\S+", value3: "\\S.*",
name3: "Paragraphs",
value3: "\\S.*",
},
settingsBloc: buttonStatSettingsBlocHTML
}; };
buttonStat.onLoadSettings = function() { buttonStat.onLoadSettings = function() {

View File

@ -2,17 +2,15 @@ define([
"jquery", "jquery",
"underscore", "underscore",
"utils", "utils",
"classes/Extension",
"text!html/buttonSync.html", "text!html/buttonSync.html",
"text!html/buttonSyncSettingsBloc.html", "text!html/buttonSyncSettingsBlock.html",
], function($, _, utils, buttonSyncHTML, buttonSyncSettingsBlocHTML) { ], function($, _, utils, Extension, buttonSyncHTML, buttonSyncSettingsBlockHTML) {
var buttonSync = { var buttonSync = new Extension("buttonSync", 'Button "Synchronize"');
extensionId: "buttonSync", buttonSync.settingsBlock = buttonSyncSettingsBlockHTML;
extensionName: 'Button "Synchronize"', buttonSync.defaultConfig = {
defaultConfig: { syncPeriod: 180000
syncPeriod: 180000
},
settingsBloc: buttonSyncSettingsBlocHTML
}; };
buttonSync.onLoadSettings = function() { buttonSync.onLoadSettings = function() {

View File

@ -1,14 +1,11 @@
define([ define([
"jquery", "jquery",
"classes/Extension",
"text!html/buttonViewer.html", "text!html/buttonViewer.html",
], function($, buttonViewerHTML) { ], function($, Extension, buttonViewerHTML) {
var buttonViewer = { var buttonViewer = new Extension("buttonViewer", 'Button "Viewer"', true);
extensionId: "buttonViewer", buttonViewer.settingsBlock = '<p>Adds a "Viewer" button over the preview.</p>';
extensionName: 'Button "Viewer"',
optional: true,
settingsBloc: '<p>Adds a "Viewer" button over the preview.</p>'
};
buttonViewer.onCreatePreviewButton = function() { buttonViewer.onCreatePreviewButton = function() {
return $(buttonViewerHTML); return $(buttonViewerHTML);

View File

@ -1,14 +1,12 @@
define([ define([
"jquery", "jquery",
"underscore", "underscore",
"classes/Extension",
"text!html/dialogAbout.html", "text!html/dialogAbout.html",
], function($, _, dialogAboutHTML) { ], function($, _, Extension, dialogAboutHTML) {
var dialogAbout = { var dialogAbout = new Extension("dialogAbout", 'Dialog "About"');
extensionId: "dialogAbout", dialogAbout.settingsBlock = '<p>Prints the content of the "About" dialog box.</p>';
extensionName: 'Dialog "About"',
settingsBloc: '<p>Prints the content of the "About" dialog box.</p>'
};
var libraries = { var libraries = {
"Bootstrap": "http://twitter.github.io/bootstrap/", "Bootstrap": "http://twitter.github.io/bootstrap/",

View File

@ -1,14 +1,12 @@
define([ define([
"jquery", "jquery",
"underscore", "underscore",
"classes/Extension",
"text!html/dialogManagePublicationLocation.html", "text!html/dialogManagePublicationLocation.html",
], function($, _, dialogManagePublicationLocationHTML) { ], function($, _, Extension, dialogManagePublicationLocationHTML) {
var dialogManagePublication = { var dialogManagePublication = new Extension("dialogManagePublication", 'Dialog "Manage publication"');
extensionId: "dialogManagePublication", dialogManagePublication.settingsBlock = '<p>Populates the "Manage publication" dialog box.</p>';
extensionName: 'Dialog "Manage publication"',
settingsBloc: '<p>Populates the "Manage publication" dialog box.</p>'
};
var extensionMgr = undefined; var extensionMgr = undefined;
dialogManagePublication.onExtensionMgrCreated = function(extensionMgrParameter) { dialogManagePublication.onExtensionMgrCreated = function(extensionMgrParameter) {

View File

@ -1,14 +1,12 @@
define([ define([
"jquery", "jquery",
"underscore", "underscore",
"classes/Extension",
"text!html/dialogManageSynchronizationLocation.html", "text!html/dialogManageSynchronizationLocation.html",
], function($, _, dialogManageSynchronizationLocationHTML) { ], function($, _, Extension, dialogManageSynchronizationLocationHTML) {
var dialogManageSynchronization = { var dialogManageSynchronization = new Extension("dialogManageSynchronization", 'Dialog "Manage synchronization"');
extensionId: "dialogManageSynchronization", dialogManageSynchronization.settingsBlock = '<p>Populates the "Manage synchronization" dialog box.</p>';
extensionName: 'Dialog "Manage synchronization"',
settingsBloc: '<p>Populates the "Manage synchronization" dialog box.</p>'
};
var extensionMgr = undefined; var extensionMgr = undefined;
dialogManageSynchronization.onExtensionMgrCreated = function(extensionMgrParameter) { dialogManageSynchronization.onExtensionMgrCreated = function(extensionMgrParameter) {

View File

@ -2,15 +2,13 @@ define([
"jquery", "jquery",
"underscore", "underscore",
"utils", "utils",
"classes/Extension",
"toMarkdown", "toMarkdown",
"config", "config",
], function($, _, utils, toMarkdown) { ], function($, _, utils, Extension, toMarkdown) {
var dialogOpenHarddrive = { var dialogOpenHarddrive = new Extension("dialogOpenHarddrive", 'Dialog "Open from"');
extensionId: "dialogOpenHarddrive", dialogOpenHarddrive.settingsBlock = '<p>Handles the "Import from hard drive" and the "Convert HTML to Markdown" dialog boxes.</p>';
extensionName: 'Dialog "Open from"',
settingsBloc: '<p>Handles the "Import from hard drive" and the "Convert HTML to Markdown" dialog boxes.</p>'
};
var fileMgr = undefined; var fileMgr = undefined;
dialogOpenHarddrive.onFileMgrCreated = function(fileMgrParameter) { dialogOpenHarddrive.onFileMgrCreated = function(fileMgrParameter) {

View File

@ -2,20 +2,18 @@ define([
"jquery", "jquery",
"underscore", "underscore",
"utils", "utils",
"classes/Extension",
"mousetrap", "mousetrap",
"fileSystem", "fileSystem",
"text!html/documentSelectorSettingsBloc.html", "text!html/documentSelectorSettingsBlock.html",
], function($, _, utils, mousetrap, fileSystem, documentSelectorSettingsBlocHTML) { ], function($, _, utils, Extension, mousetrap, fileSystem, documentSelectorSettingsBlockHTML) {
var documentSelector = { var documentSelector = new Extension("documentSelector", 'Document Selector');
extensionId: "documentSelector", documentSelector.settingsBlock = documentSelectorSettingsBlockHTML;
extensionName: "Document Selector", documentSelector.defaultConfig = {
defaultConfig: { orderBy: "title",
orderBy: "title", shortcutPrevious: "Ctrl+[",
shortcutPrevious: "Ctrl+[", shortcutNext: "Ctrl+]"
shortcutNext: "Ctrl+]"
},
settingsBloc: documentSelectorSettingsBlocHTML
}; };
documentSelector.onLoadSettings = function() { documentSelector.onLoadSettings = function() {
@ -148,7 +146,8 @@ define([
}); });
// Handle key shortcut // Handle key shortcut
mousetrap.bind(documentSelector.config.shortcutPrevious.toLowerCase(), function() { var shortcutPrevious = documentSelector.config.shortcutPrevious.toLowerCase();
mousetrap.bind(shortcutPrevious, function() {
if(shortcutLi === undefined) { if(shortcutLi === undefined) {
$("#file-selector").parent().is(".open") || $(".action-open-file").click(); $("#file-selector").parent().is(".open") || $(".action-open-file").click();
shortcutLi = liMap[selectFileDesc.fileIndex]; shortcutLi = liMap[selectFileDesc.fileIndex];
@ -163,6 +162,7 @@ define([
}); });
return false; return false;
}); });
var shortcutNext = documentSelector.config.shortcutNext.toLowerCase();
mousetrap.bind(documentSelector.config.shortcutNext.toLowerCase(), function() { mousetrap.bind(documentSelector.config.shortcutNext.toLowerCase(), function() {
if(shortcutLi === undefined) { if(shortcutLi === undefined) {
$("#file-selector").parent().is(".open") || $(".action-open-file").click(); $("#file-selector").parent().is(".open") || $(".action-open-file").click();
@ -175,7 +175,14 @@ define([
}); });
return false; return false;
}); });
mousetrap.bind('ctrl', function() { var delimiter1 = shortcutPrevious.indexOf("+");
var shortcutSelect1 = delimiter1 === -1 ? shortcutPrevious : shortcutPrevious.substring(0, delimiter1);
var delimiter2 = shortcutNext.indexOf("+");
var shortcutSelect2 = delimiter2 === -1 ? shortcutNext : shortcutNext.substring(0, delimiter2);
mousetrap.bind([
shortcutSelect1,
shortcutSelect2
], function() {
if(shortcutLi !== undefined) { if(shortcutLi !== undefined) {
shortcutLi.find("a").click(); shortcutLi.find("a").click();
shortcutLi = undefined; shortcutLi = undefined;

View File

@ -1,13 +1,11 @@
define([ define([
"jquery", "jquery",
"underscore" "underscore",
], function($, _) { "classes/Extension",
], function($, _, Extension) {
var documentTitle = { var documentTitle = new Extension("documentTitle", "Document Title");
extensionId: "documentTitle", documentTitle.settingsBlock = '<p>Responsible for showing the document title in the navigation bar.</p>';
extensionName: "Document Title",
settingsBloc: '<p>Responsible for showing the document title in the navigation bar.</p>'
};
var layout = undefined; var layout = undefined;
documentTitle.onLayoutCreated = function(layoutParameter) { documentTitle.onLayoutCreated = function(layoutParameter) {

View File

@ -1,11 +1,9 @@
define(function() { define([
"classes/Extension",
], function(Extension) {
var emailConverter = { var emailConverter = new Extension("emailConverter", "Markdown Email", true);
extensionId: "emailConverter", emailConverter.settingsBlock = '<p>Converts email adresses in the form &lt;email@example.com&gt; into clickable links.</p>';
extensionName: "Email Converter",
optional: true,
settingsBloc: '<p>Converts email adresses in the form &lt;email@example.com&gt; into clickable links.</p>'
};
emailConverter.onEditorConfigure = function(editor) { emailConverter.onEditorConfigure = function(editor) {
editor.getConverter().hooks.chain("postConversion", function(text) { editor.getConverter().hooks.chain("postConversion", function(text) {

View File

@ -2,16 +2,13 @@ define([
"jquery", "jquery",
"underscore", "underscore",
"utils", "utils",
"classes/Extension",
"settings", "settings",
"config", "config",
], function($, _, utils, settings) { ], function($, _, utils, Extension, settings) {
var googleAnalytics = { var googleAnalytics = new Extension("googleAnalytics", "Google Analytics", true);
extensionId: "googleAnalytics", googleAnalytics.settingsBlock = '<p>Sends anonymous statistics about usage and errors to help improve StackEdit.</p>';
extensionName: 'Google Analytics',
optional: true,
settingsBloc: '<p>Sends anonymous statistics about usage and errors to help improve StackEdit.</p>'
};
var isLoaded = false; var isLoaded = false;
var isOffline = false; var isOffline = false;

View File

@ -1,17 +1,14 @@
define([ define([
"utils", "utils",
"text!html/markdownExtraSettingsBloc.html", "classes/Extension",
"text!html/markdownExtraSettingsBlock.html",
"libs/Markdown.Extra", "libs/Markdown.Extra",
], function(utils, markdownExtraSettingsBlocHTML) { ], function(utils, Extension, markdownExtraSettingsBlockHTML) {
var markdownExtra = { var markdownExtra = new Extension("markdownExtra", "Markdown Extra", true);
extensionId: "markdownExtra", markdownExtra.settingsBlock = markdownExtraSettingsBlockHTML;
extensionName: "Markdown Extra", markdownExtra.defaultConfig = {
optional: true, prettify: true
defaultConfig: {
prettify: true
},
settingsBloc: markdownExtraSettingsBlocHTML
}; };
markdownExtra.onLoadSettings = function() { markdownExtra.onLoadSettings = function() {

View File

@ -0,0 +1,100 @@
define([
"underscore",
"utils",
"classes/Extension",
], function(_, utils, Extension) {
var markdownFootnotes = new Extension("markdownFootnotes", "Markdown Footnotes", true);
markdownFootnotes.settingsBlock = '<p>Adds support for Markdown footnotes.</p>';
var inlineTags = new RegExp([
'^(<\\/?(a|abbr|acronym|applet|area|b|basefont|',
'bdo|big|button|cite|code|del|dfn|em|figcaption|',
'font|i|iframe|img|input|ins|kbd|label|map|',
'mark|meter|object|param|progress|q|ruby|rp|rt|s|',
'samp|script|select|small|span|strike|strong|',
'sub|sup|textarea|time|tt|u|var|wbr)[^>]*>|',
'<(br)\\s?\\/?>)$'
].join(''), 'i');
var previousPostConversion = undefined;
markdownFootnotes.onEditorConfigure = function(editor) {
var converter = editor.getConverter();
previousPostConversion = converter.hooks.postConversion;
converter.hooks.chain("postNormalization", _StripFootnoteDefinitions);
converter.hooks.chain("postBlockGamut", _DoFootnotes);
converter.hooks.chain("postConversion", _PrintFootnotes);
};
var footnotes = undefined;
var usedFootnotes = undefined;
function _StripFootnoteDefinitions(text) {
footnotes = {};
usedFootnotes = [];
text = text.replace(/\n[ ]{0,3}\[\^(.+?)\]\:[ \t]*\n?(.*?)\n{1,2}((?=\n[ ]{0,3}\S)|\Z)/g, function(wholeMatch, m1, m2) {
m1 = utils.slugify(m1);
m2 += "\n";
m2 = m2.replace(/^[ ]{0,3}/gm, "");
footnotes[m1] = m2;
return "\n";
});
return text;
}
var blockGamutHookCallback = undefined;
function _DoFootnotes(text, blockGamutHookCallbackParam) {
blockGamutHookCallback = blockGamutHookCallbackParam;
var footnoteCounter = 0;
text = text.replace(/\[\^(.+?)\]/g, function(wholeMatch, m1) {
var id = utils.slugify(m1);
var footnote = footnotes[id];
if(footnote === undefined) {
return "";
}
footnoteCounter++;
usedFootnotes.push(id);
return '<a href="#fn:' + id + '" id="fnref:' + id + '" title="See footnote" class="footnote">' + footnoteCounter + '</a>';
});
return text;
}
function _PrintFootnotes(text) {
if(usedFootnotes.length === 0) {
return text;
}
_.each(footnotes, function(footnote, id) {
var formattedfootnote = blockGamutHookCallback(footnote);
formattedfootnote = unescapeSpecialChars(formattedfootnote);
formattedfootnote = formattedfootnote.replace(/~D/g, "$$").replace(/~T/g, "~");
formattedfootnote = previousPostConversion(formattedfootnote);
formattedfootnote = formattedfootnote.replace(/<[^>]*>?/gi, function(tag) {
return tag.match(inlineTags) ? tag : '';
});
footnotes[id] = formattedfootnote;
});
text += '\n\n<div class="footnotes">\n<hr>\n<ol>\n\n';
_.each(usedFootnotes, function(id) {
var footnote = footnotes[id];
text += '<li id="fn:' + id + '">' + footnote + ' <a href="#fnref:' + id + '" title="Return to article" class="reversefootnote">&#8617;</a></li>\n\n';
});
text += '</ol>\n</div>';
return text;
}
// Duplicated from PageDown converter
function unescapeSpecialChars(text) {
// Swap back in all the special characters we've hidden.
text = text.replace(/~E(\d+)E/g, function(wholeMatch, m1) {
var charCodeToReplace = parseInt(m1);
return String.fromCharCode(charCodeToReplace);
});
return text;
}
return markdownFootnotes;
});

View File

@ -1,22 +1,65 @@
define([ define([
"libs/MathJax" "utils",
], function() { "classes/Extension",
"text!html/mathJaxSettingsBlock.html",
"libs/MathJax",
], function(utils, Extension, mathJaxSettingsBlockHTML) {
var mathJax = { var mathJax = new Extension("mathJax", "MathJax", true);
extensionId: "mathJax", mathJax.settingsBlock = mathJaxSettingsBlockHTML;
extensionName: "MathJax", mathJax.defaultConfig = {
optional: true, tex: "{}",
settingsBloc: '<p>Allows StackEdit to interpret LaTex mathematical expressions.</p>' tex2jax: '{ inlineMath: [["$","$"],["\\\\(","\\\\)"]], displayMath: [["$$","$$"],["\\[","\\]"]], processEscapes: true }'
}; };
mathJax.onReady = function() { mathJax.onLoadSettings = function() {
MathJax.Hub.Config({"HTML-CSS": {preferredFont: "TeX",availableFonts: ["STIX", "TeX"],linebreaks: {automatic: true},EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50), imageFont: null}, utils.setInputValue("#input-mathjax-config-tex", mathJax.config.tex);
tex2jax: {inlineMath: [["$", "$"], ["\\\\(", "\\\\)"]],displayMath: [["$$", "$$"], ["\\[", "\\]"]],processEscapes: true,ignoreClass: "tex2jax_ignore|dno"}, utils.setInputValue("#input-mathjax-config-tex2jax", mathJax.config.tex2jax);
TeX: {noUndefined: {attributes: {mathcolor: "red",mathbackground: "#FFEEEE",mathsize: "90%"}}, };
Safe: {allow: {URLs: "safe",classes: "safe",cssIDs: "safe",styles: "safe",fontsize: "all"}}},
messageStyle: "none" mathJax.onSaveSettings = function(newConfig, event) {
}); newConfig.tex = utils.getInputJsValue("#input-mathjax-config-tex", event);
}; newConfig.tex2jax = utils.getInputJsValue("#input-mathjax-config-tex2jax", event);
};
mathJax.onReady = function() {
eval("var tex = " + mathJax.config.tex);
eval("var tex2jax = " + mathJax.config.tex2jax);
MathJax.Hub.Config({
"HTML-CSS": {
preferredFont: "TeX",
availableFonts: [
"STIX",
"TeX"
],
linebreaks: {
automatic: true
},
EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50),
imageFont: null
},
tex2jax: tex2jax,
TeX: $.extend({
noUndefined: {
attributes: {
mathcolor: "red",
mathbackground: "#FFEEEE",
mathsize: "90%"
}
},
Safe: {
allow: {
URLs: "safe",
classes: "safe",
cssIDs: "safe",
styles: "safe",
fontsize: "all"
}
}
}, tex),
messageStyle: "none"
});
};
var ready = false; // true after initial typeset is complete var ready = false; // true after initial typeset is complete
var pending = false; // true when MathJax has been requested var pending = false; // true when MathJax has been requested

View File

@ -2,17 +2,15 @@ define([
"jquery", "jquery",
"underscore", "underscore",
"utils", "utils",
"classes/Extension",
"jgrowl", "jgrowl",
"text!html/notificationsSettingsBloc.html", "text!html/notificationsSettingsBlock.html",
], function($, _, utils, jGrowl, notificationsSettingsBlocHTML) { ], function($, _, utils, Extension, jGrowl, notificationsSettingsBlockHTML) {
var notifications = { var notifications = new Extension("notifications", "Notifications");
extensionId: "notifications", notifications.settingsBlock = notificationsSettingsBlockHTML;
extensionName: "Notifications", notifications.defaultConfig = {
defaultConfig: { timeout: 8000
timeout: 8000
},
settingsBloc: notificationsSettingsBlocHTML
}; };
notifications.onLoadSettings = function() { notifications.onLoadSettings = function() {

View File

@ -1,17 +1,14 @@
define([ define([
"jquery", "jquery",
"underscore", "underscore",
"text!html/scrollLinkSettingsBloc.html", "classes/Extension",
"text!html/scrollLinkSettingsBlock.html",
"libs/css_browser_selector", "libs/css_browser_selector",
"libs/jquery.mousewheel" "libs/jquery.mousewheel"
], function($, _, scrollLinkSettingsBlocHTML) { ], function($, _, Extension, scrollLinkSettingsBlockHTML) {
var scrollLink = { var scrollLink = new Extension("scrollLink", "Scroll Link", true);
extensionId: "scrollLink", scrollLink.settingsBlock = scrollLinkSettingsBlockHTML;
extensionName: "Scroll Link",
optional: true,
settingsBloc: scrollLinkSettingsBlocHTML
};
var mdSectionList = []; var mdSectionList = [];
var htmlSectionList = []; var htmlSectionList = [];

View File

@ -2,17 +2,14 @@ define([
"jquery", "jquery",
"underscore", "underscore",
"utils", "utils",
"text!html/tocSettingsBloc.html", "classes/Extension",
], function($, _, utils, tocSettingsBlocHTML) { "text!html/tocSettingsBlock.html",
], function($, _, utils, Extension, tocSettingsBlockHTML) {
var toc = { var toc = new Extension("toc", "Markdown Table of Content", true);
extensionId: "toc", toc.settingsBlock = tocSettingsBlockHTML;
extensionName: "Table of Content", toc.defaultConfig = {
optional: true, marker: "\\[(TOC|toc)\\]"
defaultConfig: {
marker: "\\[(TOC|toc)\\]"
},
settingsBloc: tocSettingsBlocHTML
}; };
toc.onLoadSettings = function() { toc.onLoadSettings = function() {
@ -21,7 +18,7 @@ define([
toc.onSaveSettings = function(newConfig, event) { toc.onSaveSettings = function(newConfig, event) {
newConfig.marker = utils.getInputRegExpValue("#input-toc-marker", event); newConfig.marker = utils.getInputRegExpValue("#input-toc-marker", event);
}; };
// TOC element description // TOC element description
function TocElement(tagName, anchor, text) { function TocElement(tagName, anchor, text) {

View File

@ -1,13 +1,11 @@
define([ define([
"jquery", "jquery",
"underscore" "underscore",
], function($, _) { "classes/Extension",
], function($, _, Extension) {
var workingIndicator = { var workingIndicator = new Extension("workingIndicator", "Working Indicator");
extensionId: "workingIndicator", workingIndicator.settingsBlock = '<p>Displays an animated image when a network operation is running.</p>';
extensionName: "Working Indicator",
settingsBloc: '<p>Displays an animated image when a network operation is running.</p>'
};
workingIndicator.onAsyncRunning = function(isRunning) { workingIndicator.onAsyncRunning = function(isRunning) {
if(isRunning === false) { if(isRunning === false) {

View File

@ -1,8 +1,9 @@
define([ define([
"jquery", "jquery",
"core", "core",
"settings",
"classes/AsyncTask" "classes/AsyncTask"
], function($, core, AsyncTask) { ], function($, core, settings, AsyncTask) {
var sshHelper = {}; var sshHelper = {};
@ -21,7 +22,7 @@ define([
var task = new AsyncTask(); var task = new AsyncTask();
connect(task); connect(task);
task.onRun(function() { task.onRun(function() {
var url = SSH_PROXY_URL + "upload"; var url = settings.sshProxy + "upload";
var data = { var data = {
host: host, host: host,
port: port, port: port,

View File

@ -0,0 +1,11 @@
<p>Adds a "HTML code" button over the preview.</p>
<div class="form-horizontal">
<div class="control-group">
<label class="control-label" for="textarea-html-code-template">Template
<a href="#" class="tooltip-template">(?)</a>
</label>
<div class="controls">
<textarea id="textarea-html-code-template"></textarea>
</div>
</div>
</div>

View File

@ -8,3 +8,4 @@
</div> </div>
</div> </div>
</div> </div>
<span class="help-block pull-right"><a target="_blank" href="https://github.com/jmcmanus/pagedown-extra">More info</a></span>

View File

@ -0,0 +1,18 @@
<p>Allows StackEdit to interpret LaTeX mathematical expressions.</p>
<div class="form-horizontal">
<div class="control-group">
<label class="control-label"
for="input-mathjax-config-tex">TeX configuration</label>
<div class="controls">
<input type="text" id="input-mathjax-config-tex">
</div>
</div>
<div class="control-group">
<label class="control-label"
for="input-mathjax-config-tex2jax">tex2jax configuration</label>
<div class="controls">
<input type="text" id="input-mathjax-config-tex2jax">
</div>
</div>
</div>
<span class="help-block pull-right"><a target="_blank" href="http://docs.mathjax.org/en/latest/options/">More info</a></span>

View File

@ -2,12 +2,12 @@
<div class="accordion-heading"> <div class="accordion-heading">
<label class="checkbox pull-right"> <input <label class="checkbox pull-right"> <input
id="input-enable-extension-<%= extensionId %>" type="checkbox"<% id="input-enable-extension-<%= extensionId %>" type="checkbox"<%
if(!optional) print('disabled') %>> enabled if(!isOptional) print('disabled') %>> enabled
</label> <a data-toggle="collapse" </label> <a data-toggle="collapse"
data-parent="#accordion-extensions" class="accordion-toggle" data-parent="#accordion-extensions" class="accordion-toggle"
href="#collapse-<%= extensionId %>"> <%= extensionName %> </a> href="#collapse-<%= extensionId %>"> <%= extensionName %> </a>
</div> </div>
<div id="collapse-<%= extensionId %>" class="accordion-body collapse"> <div id="collapse-<%= extensionId %>" class="accordion-body collapse">
<div class="accordion-inner"><%= settingsBloc %></div> <div class="accordion-inner"><%= settingsBlock %></div>
</div> </div>
</div> </div>

View File

@ -5,7 +5,7 @@ Available variables:
<li><b>documentMarkdown</b>: document in Markdown format</li> <li><b>documentMarkdown</b>: document in Markdown format</li>
<li><b>documentHTML</b>: document in HTML format</li> <li><b>documentHTML</b>: document in HTML format</li>
<li><b>publishAttributes</b>: attributes of the publish location <li><b>publishAttributes</b>: attributes of the publish location
(undefined when using "Save")</li> (undefined if not publishing)</li>
</ul> </ul>
Examples: Examples:
<br /> <br />
@ -13,8 +13,10 @@ Examples:
<br /> <br />
&lt;div&gt;&lt;%- documentHTML %&gt;&lt;&#x2F;div&gt; &lt;div&gt;&lt;%- documentHTML %&gt;&lt;&#x2F;div&gt;
<br /> <br />
&lt;% if(publishAttributes.provider == &quot;github&quot;) &lt;%<br />
print(documentMarkdown); %&gt; if(publishAttributes.provider.providerId == &quot;github&quot;)
print(documentMarkdown);<br />
%&gt;
<br /> <br />
<br /> <br />
<a target="_blank" href="http://underscorejs.org/#template">More <a target="_blank" href="http://underscorejs.org/#template">More

View File

@ -37,7 +37,7 @@
// Remove one level of indentation from text. Indent is 4 spaces. // Remove one level of indentation from text. Indent is 4 spaces.
function outdent(text) { function outdent(text) {
return text.replace(new RegExp('^(\\t|[ ]{1,4})', 'gm'), ''); return text.replace(new RegExp('^(\\t|[ ]{1,4})', 'gm'), '');
} }
function contains(str, substr) { function contains(str, substr) {
@ -115,15 +115,15 @@
function unescapeSpecialChars(text) { function unescapeSpecialChars(text) {
// Swap back in all the special characters we've hidden. // Swap back in all the special characters we've hidden.
text = text.replace(/~E(\d+)E/g, function(wholeMatch, m1) { text = text.replace(/~E(\d+)E/g, function(wholeMatch, m1) {
var charCodeToReplace = parseInt(m1); var charCodeToReplace = parseInt(m1);
return String.fromCharCode(charCodeToReplace); return String.fromCharCode(charCodeToReplace);
}); });
return text; return text;
} }
/***************************************************************************** /*****************************************************************************
* Markdown.Extra * * Markdown.Extra *
****************************************************************************/ ****************************************************************************/
Markdown.Extra = function() { Markdown.Extra = function() {
// For converting internal markdown (in tables for instance). // For converting internal markdown (in tables for instance).
@ -160,19 +160,19 @@
options = options || {}; options = options || {};
options.extensions = options.extensions || ["all"]; options.extensions = options.extensions || ["all"];
if (contains(options.extensions, "all")) { if (contains(options.extensions, "all")) {
options.extensions = ["tables", "fenced_code_gfm", "def_list", "attr_list"]; options.extensions = ["tables", "fenced_code_gfm", "def_list", "attr_list"];
} }
if (contains(options.extensions, "attr_list")) { if (contains(options.extensions, "attr_list")) {
postNormalizationTransformations.push("hashFcbAttributeBlocks"); postNormalizationTransformations.push("hashFcbAttributeBlocks");
preBlockGamutTransformations.push("hashHeaderAttributeBlocks"); preBlockGamutTransformations.push("hashHeaderAttributeBlocks");
postConversionTransformations.push("applyAttributeBlocks"); postConversionTransformations.push("applyAttributeBlocks");
extra.attributeBlocks = true; extra.attributeBlocks = true;
} }
if (contains(options.extensions, "tables")) { if (contains(options.extensions, "tables")) {
preBlockGamutTransformations.push("tables"); preBlockGamutTransformations.push("tables");
} }
if (contains(options.extensions, "fenced_code_gfm")) { if (contains(options.extensions, "fenced_code_gfm")) {
postNormalizationTransformations.push("fencedCodeBlocks"); postNormalizationTransformations.push("fencedCodeBlocks");
} }
if (contains(options.extensions, "def_list")) { if (contains(options.extensions, "def_list")) {
preBlockGamutTransformations.push("definitionLists"); preBlockGamutTransformations.push("definitionLists");
@ -183,14 +183,14 @@
}); });
converter.hooks.chain("preBlockGamut", function(text, blockGamutHookCallback) { converter.hooks.chain("preBlockGamut", function(text, blockGamutHookCallback) {
// Keep a reference to the block gamut callback to run recursively // Keep a reference to the block gamut callback to run recursively
extra.blockGamutHookCallback = blockGamutHookCallback; extra.blockGamutHookCallback = blockGamutHookCallback;
text = processEscapes(text); text = processEscapes(text);
return extra.doTransform(preBlockGamutTransformations, text) + '\n'; return extra.doTransform(preBlockGamutTransformations, text) + '\n';
}); });
// Keep a reference to the hook chain running before doPostConversion to apply on hashed extra blocks // Keep a reference to the hook chain running before doPostConversion to apply on hashed extra blocks
extra.previousPostConversion = converter.hooks.postConversion; extra.previousPostConversion = converter.hooks.postConversion;
converter.hooks.chain("postConversion", function(text) { converter.hooks.chain("postConversion", function(text) {
text = extra.doTransform(postConversionTransformations, text); text = extra.doTransform(postConversionTransformations, text);
// Clear state vars that may use unnecessary memory // Clear state vars that may use unnecessary memory
@ -215,9 +215,9 @@
// Do transformations // Do transformations
Markdown.Extra.prototype.doTransform = function(transformations, text) { Markdown.Extra.prototype.doTransform = function(transformations, text) {
for(var i = 0; i < transformations.length; i++) for(var i = 0; i < transformations.length; i++)
text = this[transformations[i]](text); text = this[transformations[i]](text);
return text; return text;
}; };
// Return a placeholder containing a key, which is the block's index in the // Return a placeholder containing a key, which is the block's index in the
@ -253,21 +253,21 @@
// Extract headers attribute blocks, move them above the element they will be // Extract headers attribute blocks, move them above the element they will be
// applied to, and hash them for later. // applied to, and hash them for later.
Markdown.Extra.prototype.hashHeaderAttributeBlocks = function(text) { Markdown.Extra.prototype.hashHeaderAttributeBlocks = function(text) {
// TODO: use sentinels. Should we just add/remove them in doConversion? // TODO: use sentinels. Should we just add/remove them in doConversion?
// TODO: better matches for id / class attributes // TODO: better matches for id / class attributes
var attrBlock = "\\{\\s*[.|#][^}]+\\}"; var attrBlock = "\\{\\s*[.|#][^}]+\\}";
var hdrAttributesA = new RegExp("^(#{1,6}.*#{0,6})\\s+(" + attrBlock + ")[ \\t]*(\\n|0x03)", "gm"); var hdrAttributesA = new RegExp("^(#{1,6}.*#{0,6})\\s+(" + attrBlock + ")[ \\t]*(\\n|0x03)", "gm");
var hdrAttributesB = new RegExp("^(.*)\\s+(" + attrBlock + ")[ \\t]*\\n" + var hdrAttributesB = new RegExp("^(.*)\\s+(" + attrBlock + ")[ \\t]*\\n" +
"(?=[\\-|=]+\\s*(\\n|0x03))", "gm"); // underline lookahead "(?=[\\-|=]+\\s*(\\n|0x03))", "gm"); // underline lookahead
var self = this; var self = this;
function attributeCallback(wholeMatch, pre, attr) { function attributeCallback(wholeMatch, pre, attr) {
return '<p>~XX' + (self.hashBlocks.push(attr) - 1) + 'XX</p>\n' + pre + "\n"; return '<p>~XX' + (self.hashBlocks.push(attr) - 1) + 'XX</p>\n' + pre + "\n";
} }
text = text.replace(hdrAttributesA, attributeCallback); // ## headers text = text.replace(hdrAttributesA, attributeCallback); // ## headers
text = text.replace(hdrAttributesB, attributeCallback); // underline headers text = text.replace(hdrAttributesB, attributeCallback); // underline headers
return text; return text;
}; };
// Extract FCB attribute blocks, move them above the element they will be // Extract FCB attribute blocks, move them above the element they will be
@ -275,14 +275,14 @@
Markdown.Extra.prototype.hashFcbAttributeBlocks = function(text) { Markdown.Extra.prototype.hashFcbAttributeBlocks = function(text) {
// TODO: use sentinels. Should we just add/remove them in doConversion? // TODO: use sentinels. Should we just add/remove them in doConversion?
// TODO: better matches for id / class attributes // TODO: better matches for id / class attributes
var attrBlock = "\\{\\s*[.|#][^}]+\\}"; var attrBlock = "\\{\\s*[.|#][^}]+\\}";
var fcbAttributes = new RegExp("^(```[^{]*)\\s+(" + attrBlock + ")[ \\t]*\\n" + var fcbAttributes = new RegExp("^(```[^{]*)\\s+(" + attrBlock + ")[ \\t]*\\n" +
"(?=([\\s\\S]*?)\\n```\\s*(\\n|0x03))", "gm"); "(?=([\\s\\S]*?)\\n```\\s*(\\n|0x03))", "gm");
var self = this; var self = this;
function attributeCallback(wholeMatch, pre, attr) { function attributeCallback(wholeMatch, pre, attr) {
return '<p>~XX' + (self.hashBlocks.push(attr) - 1) + 'XX</p>\n' + pre + "\n"; return '<p>~XX' + (self.hashBlocks.push(attr) - 1) + 'XX</p>\n' + pre + "\n";
} }
return text.replace(fcbAttributes, attributeCallback); return text.replace(fcbAttributes, attributeCallback);
}; };

View File

@ -1,15 +1,16 @@
define([ define([
"jquery", "jquery",
"underscore", "underscore",
"classes/Provider",
"core", "core",
"providers/gplusProvider" "providers/gplusProvider"
], function($, _, core) { ], function($, _, Provider, core) {
var mediaImporter = {}; var mediaImporter = {};
// Create a map with providerId: providerModule // Create a map with providerId: providerModule
var providerMap = _.chain(arguments).map(function(argument) { var providerMap = _.chain(arguments).map(function(argument) {
return argument && argument.providerId && [ return argument instanceof Provider && [
argument.providerId, argument.providerId,
argument argument
]; ];

View File

@ -1,19 +1,15 @@
define([ define([
"underscore", "underscore",
"utils", "utils",
"classes/Provider",
"helpers/googleHelper" "helpers/googleHelper"
], function(_, utils, googleHelper) { ], function(_, utils, Provider, googleHelper) {
var PROVIDER_BLOGGER = "blogger"; var bloggerProvider = new Provider("blogger", "Blogger");
bloggerProvider.defaultPublishFormat = "html";
var bloggerProvider = { bloggerProvider.publishPreferencesInputIds = [
providerId: PROVIDER_BLOGGER, "blogger-url"
providerName: "Blogger", ];
defaultPublishFormat: "html",
publishPreferencesInputIds: [
"blogger-url"
]
};
bloggerProvider.publish = function(publishAttributes, title, content, callback) { bloggerProvider.publish = function(publishAttributes, title, content, callback) {
googleHelper.uploadBlogger(publishAttributes.blogUrl, publishAttributes.blogId, publishAttributes.postId, publishAttributes.labelList, title, content, function(error, blogId, postId) { googleHelper.uploadBlogger(publishAttributes.blogUrl, publishAttributes.blogId, publishAttributes.postId, publishAttributes.labelList, title, content, function(error, blogId, postId) {

View File

@ -1,17 +1,14 @@
define([ define([
"jquery", "jquery",
"core", "core",
"classes/Provider",
"classes/AsyncTask" "classes/AsyncTask"
], function($, core, AsyncTask) { ], function($, core, Provider, AsyncTask) {
var PROVIDER_DOWNLOAD = "download"; var downloadProvider = new Provider("download");
downloadProvider.sharingAttributes = [
var downloadProvider = { "url"
providerId: PROVIDER_DOWNLOAD, ];
sharingAttributes: [
"url"
]
};
downloadProvider.importPublic = function(importParameters, callback) { downloadProvider.importPublic = function(importParameters, callback) {
var title = undefined; var title = undefined;

View File

@ -1,18 +1,16 @@
define([ define([
"underscore", "underscore",
"utils", "utils",
"classes/Provider",
"extensionMgr", "extensionMgr",
"fileMgr", "fileMgr",
"helpers/dropboxHelper" "helpers/dropboxHelper"
], function(_, utils, extensionMgr, fileMgr, dropboxHelper) { ], function(_, utils, Provider, extensionMgr, fileMgr, dropboxHelper) {
var PROVIDER_DROPBOX = "dropbox"; var PROVIDER_DROPBOX = "dropbox";
var dropboxProvider = { var dropboxProvider = new Provider(PROVIDER_DROPBOX, "Dropbox");
providerId: PROVIDER_DROPBOX, dropboxProvider.defaultPublishFormat = "template";
providerName: "Dropbox",
defaultPublishFormat: "template"
};
function checkPath(path) { function checkPath(path) {
if(path === undefined) { if(path === undefined) {

View File

@ -2,22 +2,20 @@ define([
"underscore", "underscore",
"core", "core",
"utils", "utils",
"classes/Provider",
"settings", "settings",
"extensionMgr", "extensionMgr",
"fileMgr", "fileMgr",
"helpers/googleHelper" "helpers/googleHelper"
], function(_, core, utils, settings, extensionMgr, fileMgr, googleHelper) { ], function(_, core, utils, Provider, settings, extensionMgr, fileMgr, googleHelper) {
var PROVIDER_GDRIVE = "gdrive"; var PROVIDER_GDRIVE = "gdrive";
var gdriveProvider = { var gdriveProvider = new Provider(PROVIDER_GDRIVE, "Google Drive");
providerId: PROVIDER_GDRIVE, gdriveProvider.defaultPublishFormat = "template";
providerName: "Google Drive", gdriveProvider.exportPreferencesInputIds = [
defaultPublishFormat: "template", "gdrive-parentid"
exportPreferencesInputIds: [ ];
"gdrive-parentid"
]
};
function createSyncIndex(id) { function createSyncIndex(id) {
return "sync." + PROVIDER_GDRIVE + "." + id; return "sync." + PROVIDER_GDRIVE + "." + id;

View File

@ -1,18 +1,14 @@
define([ define([
"utils", "utils",
"classes/Provider",
"helpers/githubHelper" "helpers/githubHelper"
], function(utils, githubHelper) { ], function(utils, Provider, githubHelper) {
var PROVIDER_GIST = "gist"; var gistProvider = new Provider("gist", "Gist");
gistProvider.sharingAttributes = [
var gistProvider = { "gistId",
providerId: PROVIDER_GIST, "filename"
providerName: "Gist", ];
sharingAttributes: [
"gistId",
"filename"
]
};
gistProvider.publish = function(publishAttributes, title, content, callback) { gistProvider.publish = function(publishAttributes, title, content, callback) {
githubHelper.uploadGist(publishAttributes.gistId, publishAttributes.filename, publishAttributes.isPublic, title, content, function(error, gistId) { githubHelper.uploadGist(publishAttributes.gistId, publishAttributes.filename, publishAttributes.isPublic, title, content, function(error, gistId) {

View File

@ -1,19 +1,15 @@
define([ define([
"utils", "utils",
"classes/Provider",
"settings", "settings",
"helpers/githubHelper" "helpers/githubHelper"
], function(utils, settings, githubHelper) { ], function(utils, Provider, settings, githubHelper) {
var PROVIDER_GITHUB = "github"; var githubProvider = new Provider("github", "GitHub");
githubProvider.publishPreferencesInputIds = [
var githubProvider = { "github-reponame",
providerId: PROVIDER_GITHUB, "github-branch"
providerName: "GitHub", ];
publishPreferencesInputIds: [
"github-reponame",
"github-branch"
]
};
githubProvider.publish = function(publishAttributes, title, content, callback) { githubProvider.publish = function(publishAttributes, title, content, callback) {
var commitMsg = settings.commitMsg; var commitMsg = settings.commitMsg;

View File

@ -2,16 +2,14 @@ define([
"underscore", "underscore",
"core", "core",
"utils", "utils",
"classes/Provider",
"extensionMgr", "extensionMgr",
"helpers/googleHelper" "helpers/googleHelper"
], function(_, core, utils, extensionMgr, googleHelper) { ], function(_, core, utils, Provider, extensionMgr, googleHelper) {
var PROVIDER_GPLUS = "gplus"; var PROVIDER_GPLUS = "gplus";
var gplusProvider = { var gplusProvider = new Provider(PROVIDER_GPLUS, "Google+");
providerId: PROVIDER_GPLUS,
providerName: "Google+"
};
function getThumbnailUrl(doc, size) { function getThumbnailUrl(doc, size) {
var result = undefined; var result = undefined;

View File

@ -1,20 +1,16 @@
define([ define([
"utils", "utils",
"classes/Provider",
"helpers/sshHelper" "helpers/sshHelper"
], function(utils, sshHelper) { ], function(utils, Provider, sshHelper) {
var PROVIDER_SSH = "ssh"; var sshProvider = new Provider("ssh", "SSH server");
sshProvider.publishPreferencesInputIds = [
var sshProvider = { "ssh-host",
providerId: PROVIDER_SSH, "ssh-port",
providerName: "SSH server", "ssh-username",
publishPreferencesInputIds: [ "ssh-password"
"ssh-host", ];
"ssh-port",
"ssh-username",
"ssh-password"
]
};
sshProvider.publish = function(publishAttributes, title, content, callback) { sshProvider.publish = function(publishAttributes, title, content, callback) {
sshHelper.upload(publishAttributes.host, publishAttributes.port, publishAttributes.username, publishAttributes.password, publishAttributes.path, title, content, callback); sshHelper.upload(publishAttributes.host, publishAttributes.port, publishAttributes.username, publishAttributes.password, publishAttributes.path, title, content, callback);

View File

@ -1,17 +1,13 @@
define([ define([
"utils", "utils",
"classes/Provider",
"helpers/tumblrHelper" "helpers/tumblrHelper"
], function(utils, tumblrHelper) { ], function(utils, Provider, tumblrHelper) {
var PROVIDER_TUMBLR = "tumblr"; var tumblrProvider = new Provider("tumblr", "Tumblr");
tumblrProvider.publishPreferencesInputIds = [
var tumblrProvider = { "tumblr-hostname"
providerId: PROVIDER_TUMBLR, ];
providerName: "Tumblr",
publishPreferencesInputIds: [
"tumblr-hostname"
]
};
tumblrProvider.publish = function(publishAttributes, title, content, callback) { tumblrProvider.publish = function(publishAttributes, title, content, callback) {
tumblrHelper.upload(publishAttributes.blogHostname, publishAttributes.postId, publishAttributes.tags, publishAttributes.format == "markdown" ? "markdown" : "html", title, content, function(error, postId) { tumblrHelper.upload(publishAttributes.blogHostname, publishAttributes.postId, publishAttributes.tags, publishAttributes.format == "markdown" ? "markdown" : "html", title, content, function(error, postId) {

View File

@ -1,18 +1,14 @@
define([ define([
"utils", "utils",
"classes/Provider",
"helpers/wordpressHelper" "helpers/wordpressHelper"
], function(utils, wordpressHelper) { ], function(utils, Provider, wordpressHelper) {
var PROVIDER_WORDPRESS = "wordpress"; var wordpressProvider = new Provider("wordpress", "WordPress");
wordpressProvider.defaultPublishFormat = "html";
var wordpressProvider = { wordpressProvider.publishPreferencesInputIds = [
providerId: PROVIDER_WORDPRESS, "wordpress-site"
providerName: "WordPress", ];
defaultPublishFormat: "html",
publishPreferencesInputIds: [
"wordpress-site"
]
};
wordpressProvider.publish = function(publishAttributes, title, content, callback) { wordpressProvider.publish = function(publishAttributes, title, content, callback) {
wordpressHelper.upload(publishAttributes.site, publishAttributes.postId, publishAttributes.tags, title, content, function(error, postId) { wordpressHelper.upload(publishAttributes.site, publishAttributes.postId, publishAttributes.tags, title, content, function(error, postId) {

View File

@ -8,6 +8,7 @@ define([
"fileSystem", "fileSystem",
"fileMgr", "fileMgr",
"sharing", "sharing",
"classes/Provider",
"providers/bloggerProvider", "providers/bloggerProvider",
"providers/dropboxProvider", "providers/dropboxProvider",
"providers/gistProvider", "providers/gistProvider",
@ -16,13 +17,13 @@ define([
"providers/sshProvider", "providers/sshProvider",
"providers/tumblrProvider", "providers/tumblrProvider",
"providers/wordpressProvider" "providers/wordpressProvider"
], function($, _, core, utils, settings, extensionMgr, fileSystem, fileMgr, sharing) { ], function($, _, core, utils, settings, extensionMgr, fileSystem, fileMgr, sharing, Provider) {
var publisher = {}; var publisher = {};
// Create a map with providerId: providerModule // Create a map with providerId: providerModule
var providerMap = _.chain(arguments).map(function(argument) { var providerMap = _.chain(arguments).map(function(argument) {
return argument && argument.providerId && [ return argument instanceof Provider && [
argument.providerId, argument.providerId,
argument argument
]; ];

View File

@ -6,15 +6,16 @@ define([
"extensionMgr", "extensionMgr",
"fileMgr", "fileMgr",
"classes/AsyncTask", "classes/AsyncTask",
"classes/Provider",
"providers/downloadProvider", "providers/downloadProvider",
"providers/gistProvider" "providers/gistProvider"
], function($, _, core, utils, extensionMgr, fileMgr, AsyncTask) { ], function($, _, core, utils, extensionMgr, fileMgr, AsyncTask, Provider) {
var sharing = {}; var sharing = {};
// Create a map with providerId: providerModule // Create a map with providerId: providerModule
var providerMap = _.chain(arguments).map(function(argument) { var providerMap = _.chain(arguments).map(function(argument) {
return argument && argument.providerId && [ return argument instanceof Provider && [
argument.providerId, argument.providerId,
argument argument
]; ];

View File

@ -6,15 +6,16 @@ define([
"extensionMgr", "extensionMgr",
"fileSystem", "fileSystem",
"fileMgr", "fileMgr",
"classes/Provider",
"providers/dropboxProvider", "providers/dropboxProvider",
"providers/gdriveProvider" "providers/gdriveProvider"
], function($, _, core, utils, extensionMgr, fileSystem, fileMgr) { ], function($, _, core, utils, extensionMgr, fileSystem, fileMgr, Provider) {
var synchronizer = {}; var synchronizer = {};
// Create a map with providerId: providerModule // Create a map with providerId: providerModule
var providerMap = _.chain(arguments).map(function(argument) { var providerMap = _.chain(arguments).map(function(argument) {
return argument && argument.providerId && [ return argument instanceof Provider && [
argument.providerId, argument.providerId,
argument argument
]; ];

View File

@ -95,6 +95,23 @@ define([
return value; return value;
}; };
// Return input value and check that it's a valid JavaScript object
utils.getInputJsValue = function(element, event) {
element = jqElt(element);
var value = utils.getInputTextValue(element, event);
if(value === undefined) {
return undefined;
}
try {
eval("var test=" + 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);