New extension pattern

This commit is contained in:
benweet 2013-05-29 20:55:23 +01:00
parent c6c06373da
commit d7304444a1
44 changed files with 5801 additions and 5349 deletions

View File

@ -327,7 +327,6 @@ hr {
div.dropdown-menu { div.dropdown-menu {
padding: 5px 20px; padding: 5px 20px;
white-space: normal;
} }
div.dropdown-menu p, div.dropdown-menu p,
@ -335,12 +334,17 @@ div.dropdown-menu blockquote {
margin: 10px 0; margin: 10px 0;
} }
div.dropdown-menu .stat {
margin-bottom: 10px;
}
div.dropdown-menu i { div.dropdown-menu i {
margin-right: 0; margin-right: 0;
} }
#link-container { #link-container {
min-width: 210px; min-width: 210px;
white-space: normal;
} }
#link-container .link-list { #link-container .link-list {
@ -518,6 +522,10 @@ div.dropdown-menu i {
text-align: left; text-align: left;
} }
#modal-settings .accordion-inner .form-inline .label-text {
margin: 0 10px;
}
.accordion-toggle { .accordion-toggle {
cursor: help; cursor: help;
} }

BIN
doc/img/architecture.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -50,8 +50,8 @@ define([
}; };
/** /**
* chain() calls the next onRun callback or the onSuccess callbacks when * chain() calls the next onRun callback or the onSuccess callbacks when
* finished. The optional callback parameter can be used to pass an onRun * finished. The optional callback parameter can be used to pass an
* callback during execution. * onRun callback during execution.
*/ */
task.chain = function(callback) { task.chain = function(callback) {
if(task.finished === true) { if(task.finished === true) {
@ -78,8 +78,8 @@ define([
runCallback(); runCallback();
}; };
/** /**
* error() calls the onError callbacks passing the error parameter and ends * error() calls the onError callbacks passing the error parameter and
* the task by throwing an exception. * ends the task by throwing an exception.
*/ */
task.error = function(error) { task.error = function(error) {
if(task.finished === true) { if(task.finished === true) {
@ -169,7 +169,8 @@ define([
if(taskQueue.length === 0) { if(taskQueue.length === 0) {
asyncRunning = false; asyncRunning = false;
extensionMgr.onAsyncRunning(false); extensionMgr.onAsyncRunning(false);
} else { }
else {
asyncRunner.runTask(); asyncRunner.runTask();
} }
} }

View File

@ -10,18 +10,13 @@ define([
providerId: PROVIDER_BLOGGER, providerId: PROVIDER_BLOGGER,
providerName: "Blogger", providerName: "Blogger",
defaultPublishFormat: "html", defaultPublishFormat: "html",
publishPreferencesInputIds: ["blogger-url"] publishPreferencesInputIds: [
"blogger-url"
]
}; };
bloggerProvider.publish = function(publishAttributes, title, content, callback) { bloggerProvider.publish = function(publishAttributes, title, content, callback) {
googleHelper.uploadBlogger( googleHelper.uploadBlogger(publishAttributes.blogUrl, publishAttributes.blogId, publishAttributes.postId, publishAttributes.labelList, title, content, function(error, blogId, postId) {
publishAttributes.blogUrl,
publishAttributes.blogId,
publishAttributes.postId,
publishAttributes.labelList,
title,
content,
function(error, blogId, postId) {
if(error) { if(error) {
callback(error); callback(error);
return; return;
@ -29,8 +24,7 @@ define([
publishAttributes.blogId = blogId; publishAttributes.blogId = blogId;
publishAttributes.postId = postId; publishAttributes.postId = postId;
callback(); callback();
} });
);
}; };
bloggerProvider.newPublishAttributes = function(event) { bloggerProvider.newPublishAttributes = function(event) {
@ -43,9 +37,7 @@ define([
publishAttributes.labelList = []; publishAttributes.labelList = [];
var labels = utils.getInputTextValue("#input-publish-labels"); var labels = utils.getInputTextValue("#input-publish-labels");
if(labels !== undefined) { if(labels !== undefined) {
publishAttributes.labelList = _.chain( publishAttributes.labelList = _.chain(labels.split(",")).map(function(label) {
labels.split(",")
).map(function(label) {
return utils.trim(label); return utils.trim(label);
}).compact().value(); }).compact().value();
} }

View File

@ -1,8 +1,10 @@
var MAIN_URL = "http://benweet.github.io/stackedit/"; var MAIN_URL = "http://benweet.github.io/stackedit/";
var GOOGLE_API_KEY = "AIzaSyAeCU8CGcSkn0z9js6iocHuPBX4f_mMWkw"; var GOOGLE_API_KEY = "AIzaSyAeCU8CGcSkn0z9js6iocHuPBX4f_mMWkw";
var GOOGLE_SCOPES = [ "https://www.googleapis.com/auth/drive.install", var GOOGLE_SCOPES = [
"https://www.googleapis.com/auth/drive.install",
"https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/blogger" ]; "https://www.googleapis.com/auth/blogger"
];
var GOOGLE_DRIVE_APP_ID = "241271498917"; var GOOGLE_DRIVE_APP_ID = "241271498917";
var DROPBOX_APP_KEY = "lq6mwopab8wskas"; var DROPBOX_APP_KEY = "lq6mwopab8wskas";
var DROPBOX_APP_SECRET = "851fgnucpezy84t"; var DROPBOX_APP_SECRET = "851fgnucpezy84t";

View File

@ -29,10 +29,10 @@ define([
userReal = true; userReal = true;
userActive = true; userActive = true;
userLastActivity = utils.currentTime; userLastActivity = utils.currentTime;
}; }
function isUserActive() { function isUserActive() {
if(userActive === true if(userActive === true && utils.currentTime - userLastActivity > USER_IDLE_THRESHOLD) {
&& utils.currentTime - userLastActivity > USER_IDLE_THRESHOLD) {
userActive = false; userActive = false;
} }
return userActive && windowUnique; return userActive && windowUnique;
@ -80,13 +80,13 @@ define([
} }
function checkOnline() { function checkOnline() {
// Try to reconnect if we are offline but we have some network // Try to reconnect if we are offline but we have some network
if (core.isOffline === true && navigator.onLine === true if(core.isOffline === true && navigator.onLine === true && offlineTime + CHECK_ONLINE_PERIOD < utils.currentTime) {
&& offlineTime + CHECK_ONLINE_PERIOD < utils.currentTime) {
offlineTime = utils.currentTime; offlineTime = utils.currentTime;
// Try to download anything to test the connection // Try to download anything to test the connection
$.ajax({ $.ajax({
url: "//www.google.com/jsapi", url: "//www.google.com/jsapi",
timeout : AJAX_TIMEOUT, dataType : "script" timeout: AJAX_TIMEOUT,
dataType: "script"
}).done(function() { }).done(function() {
setOnline(); setOnline();
}); });
@ -173,30 +173,24 @@ define([
if(settings.layoutOrientation == "horizontal") { if(settings.layoutOrientation == "horizontal") {
$(".ui-layout-south").remove(); $(".ui-layout-south").remove();
$(".ui-layout-east").addClass("well").prop("id", "wmd-preview"); $(".ui-layout-east").addClass("well").prop("id", "wmd-preview");
layout = $('body').layout( layout = $('body').layout($.extend(layoutGlobalConfig, {
$.extend(layoutGlobalConfig, {
east__resizable: true, east__resizable: true,
east__size: .5, east__size: .5,
east__minSize: 200 east__minSize: 200
}) }));
); }
} else if (settings.layoutOrientation == "vertical") { else if(settings.layoutOrientation == "vertical") {
$(".ui-layout-east").remove(); $(".ui-layout-east").remove();
$(".ui-layout-south").addClass("well").prop("id", "wmd-preview"); $(".ui-layout-south").addClass("well").prop("id", "wmd-preview");
layout = $('body').layout( layout = $('body').layout($.extend(layoutGlobalConfig, {
$.extend(layoutGlobalConfig, {
south__resizable: true, south__resizable: true,
south__size: .5, south__size: .5,
south__minSize: 200 south__minSize: 200
}) }));
);
} }
$(".ui-layout-toggler-north").addClass("btn").append( $(".ui-layout-toggler-north").addClass("btn").append($("<b>").addClass("caret"));
$("<b>").addClass("caret")); $(".ui-layout-toggler-south").addClass("btn").append($("<b>").addClass("caret"));
$(".ui-layout-toggler-south").addClass("btn").append( $(".ui-layout-toggler-east").addClass("btn").append($("<b>").addClass("caret"));
$("<b>").addClass("caret"));
$(".ui-layout-toggler-east").addClass("btn").append(
$("<b>").addClass("caret"));
$("#navbar").click(function() { $("#navbar").click(function() {
layout.allowOverflow('north'); layout.allowOverflow('north');
}); });
@ -270,8 +264,7 @@ define([
firstChange = false; firstChange = false;
// Hide default buttons // Hide default buttons
$(".wmd-button-row").addClass("btn-group").find("li:not(.wmd-spacer)") $(".wmd-button-row").addClass("btn-group").find("li:not(.wmd-spacer)").addClass("btn").css("left", 0).find("span").hide();
.addClass("btn").css("left", 0).find("span").hide();
// Add customized buttons // Add customized buttons
$("#wmd-bold-button").append($("<i>").addClass("icon-bold")); $("#wmd-bold-button").append($("<i>").addClass("icon-bold"));
@ -398,17 +391,6 @@ define([
}); });
// Tooltips // Tooltips
$(".tooltip-scroll-link").tooltip({
html: true,
container: '#modal-settings',
placement: 'right',
title: ['Scroll Link is a feature that binds together editor and preview scrollbars. ',
'It allows you to keep an eye on the preview while scrolling the editor and vice versa. ',
'<br><br>',
'The mapping between Markdown and HTML is based on the position of the title elements (h1, h2, ...) in the page. ',
'Therefore, if your document does not contain any title, the mapping will be linear and consequently less efficient.',
].join("")
});
$(".tooltip-lazy-rendering").tooltip({ $(".tooltip-lazy-rendering").tooltip({
container: '#modal-settings', container: '#modal-settings',
placement: 'right', placement: 'right',
@ -425,18 +407,22 @@ define([
container: '#modal-settings', container: '#modal-settings',
placement: 'right', placement: 'right',
trigger: 'manual', trigger: 'manual',
title: ['Available variables:<br>', title: [
'<ul><li><b>documentTitle</b>: document title</li>', 'Available variables:<br>',
'<ul>',
' <li><b>documentTitle</b>: document title</li>',
' <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 (undefined when using "Save")</li></ul>', ' <li><b>publishAttributes</b>: attributes of the publish location (undefined when using "Save")</li>',
'Examples:<br>', '</ul>',
'Examples:<br />',
_.escape('<title><%= documentTitle %></title>'), _.escape('<title><%= documentTitle %></title>'),
'<br>', '<br />',
_.escape('<div><%- documentHTML %></div>'), _.escape('<div><%- documentHTML %></div>'),
'<br>', '<br />',
_.escape('<% if(publishAttributes.provider == "github") print(documentMarkdown); %>'), _.escape('<% if(publishAttributes.provider == "github") print(documentMarkdown); %>'),
'<br><br><a target="_blank" href="http://underscorejs.org/#template">More info</a>', '<br /><br />',
'<a target="_blank" href="http://underscorejs.org/#template">More info</a>',
].join("") ].join("")
}).click(function(e) { }).click(function(e) {
$(this).tooltip('show'); $(this).tooltip('show');
@ -467,4 +453,3 @@ define([
return core; return core;
}); });

View File

@ -8,7 +8,9 @@ define([
var downloadProvider = { var downloadProvider = {
providerId: PROVIDER_DOWNLOAD, providerId: PROVIDER_DOWNLOAD,
sharingAttributes: ["url"] sharingAttributes: [
"url"
]
}; };
downloadProvider.importPublic = function(importParameters, callback) { downloadProvider.importPublic = function(importParameters, callback) {

View File

@ -25,7 +25,8 @@ define([
} }
$.ajax({ $.ajax({
url: "lib/dropbox.min.js", url: "lib/dropbox.min.js",
dataType : "script", timeout : AJAX_TIMEOUT dataType: "script",
timeout: AJAX_TIMEOUT
}).done(function() { }).done(function() {
client = new Dropbox.Client({ client = new Dropbox.Client({
key: DROPBOX_APP_KEY, key: DROPBOX_APP_KEY,
@ -57,11 +58,14 @@ define([
function localAuthenticate() { function localAuthenticate() {
if(immediate === false) { if(immediate === false) {
extensionMgr.onMessage("Please make sure the Dropbox authorization popup is not blocked by your browser."); extensionMgr.onMessage("Please make sure the Dropbox authorization popup is not blocked by your browser.");
// If not immediate we add time for user to enter his credentials // If not immediate we add time for user to enter his
// credentials
task.timeout = ASYNC_TASK_LONG_TIMEOUT; task.timeout = ASYNC_TASK_LONG_TIMEOUT;
} }
client.reset(); client.reset();
client.authenticate({interactive: !immediate}, function(error, client) { client.authenticate({
interactive: !immediate
}, function(error, client) {
// Success // Success
if(client.authState === Dropbox.Client.DONE) { if(client.authState === Dropbox.Client.DONE) {
authenticated = true; authenticated = true;
@ -130,7 +134,8 @@ define([
} }
if(pullChanges.shouldPullAgain) { if(pullChanges.shouldPullAgain) {
task.chain(retrievePageOfChanges); task.chain(retrievePageOfChanges);
} else { }
else {
task.chain(); task.chain();
} }
}); });
@ -236,19 +241,19 @@ define([
errorMsg = error; errorMsg = error;
} }
else { else {
errorMsg = "Dropbox error (" errorMsg = "Dropbox error (" + error.status + ": " + error.responseText + ").";
+ error.status + ": " + error.responseText + ").";
if(error.status === 401 || error.status === 403) { if(error.status === 401 || error.status === 403) {
authenticated = false; authenticated = false;
errorMsg = "Access to Dropbox account is not authorized."; errorMsg = "Access to Dropbox account is not authorized.";
task.retry(new Error(errorMsg), 1); task.retry(new Error(errorMsg), 1);
return; return;
} else if(error.status === 400 && error.responseText }
.indexOf("oauth_nonce") !== -1) { else if(error.status === 400 && error.responseText.indexOf("oauth_nonce") !== -1) {
// A bug I guess... // A bug I guess...
_.each(_.keys(localStorage), function(key) { _.each(_.keys(localStorage), function(key) {
// We have to remove the Oauth cache from the localStorage // We have to remove the Oauth cache from the
// localStorage
if(key.indexOf("dropbox-auth") === 0) { if(key.indexOf("dropbox-auth") === 0) {
localStorage.removeItem(key); localStorage.removeItem(key);
} }
@ -256,7 +261,8 @@ define([
authenticated = false; authenticated = false;
task.retry(new Error(errorMsg), 1); task.retry(new Error(errorMsg), 1);
return; return;
} else if (error.status <= 0) { }
else if(error.status <= 0) {
client = undefined; client = undefined;
authenticated = false; authenticated = false;
core.setOffline(); core.setOffline();
@ -276,7 +282,8 @@ define([
} }
$.ajax({ $.ajax({
url: "https://www.dropbox.com/static/api/1/dropbox.js", url: "https://www.dropbox.com/static/api/1/dropbox.js",
dataType : "script", timeout : AJAX_TIMEOUT dataType: "script",
timeout: AJAX_TIMEOUT
}).done(function() { }).done(function() {
pickerLoaded = true; pickerLoaded = true;
task.chain(); task.chain();

View File

@ -173,7 +173,8 @@ define([
var syncAttributes = change.syncAttributes; var syncAttributes = change.syncAttributes;
var syncIndex = syncAttributes.syncIndex; var syncIndex = syncAttributes.syncIndex;
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex); var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
// No file corresponding (file may have been deleted locally) // No file corresponding (file may have been deleted
// locally)
if(fileDesc === undefined) { if(fileDesc === undefined) {
return; return;
} }
@ -184,7 +185,7 @@ define([
fileMgr.removeSync(syncAttributes); fileMgr.removeSync(syncAttributes);
return; return;
} }
var localContent = fileDesc.getContent(); var localContent = fileDesc.content;
var localContentChanged = syncAttributes.contentCRC != utils.crc32(localContent); var localContentChanged = syncAttributes.contentCRC != utils.crc32(localContent);
var file = change.stat; var file = change.stat;
var remoteContentCRC = utils.crc32(file.content); var remoteContentCRC = utils.crc32(file.content);
@ -197,7 +198,7 @@ define([
} }
// If file content changed // If file content changed
if(fileContentChanged && remoteContentChanged === true) { if(fileContentChanged && remoteContentChanged === true) {
fileDesc.setContent(file.content); fileDesc.content = file.content;
extensionMgr.onMessage('"' + localTitle + '" has been updated from Dropbox.'); extensionMgr.onMessage('"' + localTitle + '" has been updated from Dropbox.');
if(fileMgr.isCurrentFile(fileDesc)) { if(fileMgr.isCurrentFile(fileDesc)) {
fileMgr.selectFile(); // Refresh editor fileMgr.selectFile(); // Refresh editor

View File

@ -24,17 +24,13 @@ define( [
var extensionMgr = {}; var extensionMgr = {};
// Create a list of extensions // Create a list of extensions
var extensionList = _.chain( var extensionList = _.chain(arguments).map(function(argument) {
arguments
).map(function(argument) {
return _.isObject(argument) && argument.extensionId && argument; return _.isObject(argument) && argument.extensionId && argument;
}).compact().value(); }).compact().value();
// Return every named callbacks implemented in extensions // Return every named callbacks implemented in extensions
function getExtensionCallbackList(hookName) { function getExtensionCallbackList(hookName) {
return _.chain( return _.chain(extensionList).map(function(extension) {
extensionList
).map(function(extension) {
return extension.config.enabled && extension[hookName]; return extension.config.enabled && extension[hookName];
}).compact().value(); }).compact().value();
} }
@ -75,7 +71,7 @@ define( [
extensionMgr["onSaveSettings"] = function(newExtensionSettings, event) { extensionMgr["onSaveSettings"] = function(newExtensionSettings, event) {
logger.debug("onSaveSettings"); logger.debug("onSaveSettings");
_.each(extensionList, function(extension) { _.each(extensionList, function(extension) {
var newExtensionConfig = extension.defaultConfig || {}; var newExtensionConfig = _.extend({}, extension.defaultConfig);
newExtensionConfig.enabled = utils.getInputChecked("#input-enable-extension-" + extension.extensionId); newExtensionConfig.enabled = utils.getInputChecked("#input-enable-extension-" + extension.extensionId);
var onSaveSettingsCallback = extension.onSaveSettings; var onSaveSettingsCallback = extension.onSaveSettings;
onSaveSettingsCallback && onSaveSettingsCallback(newExtensionConfig, event); onSaveSettingsCallback && onSaveSettingsCallback(newExtensionConfig, event);
@ -154,7 +150,8 @@ define( [
' <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"><%= settingsBloc %></div>',
' </div>', ' </div>',
'</div>'].join(""); '</div>'
].join("");
function createSettings(extension) { function createSettings(extension) {
$("#accordion-extensions").append($(_.template(accordionTmpl, { $("#accordion-extensions").append($(_.template(accordionTmpl, {
@ -167,9 +164,7 @@ define( [
$(function() { $(function() {
// Create accordion in settings dialog // Create accordion in settings dialog
_.chain( _.chain(extensionList).sortBy(function(extension) {
extensionList
).sortBy(function(extension) {
return extension.extensionName.toLowerCase(); return extension.extensionName.toLowerCase();
}).each(createSettings); }).each(createSettings);

View File

@ -25,7 +25,8 @@ define([
else { else {
button.removeClass("disabled"); button.removeClass("disabled");
} }
}; }
;
var publisher = undefined; var publisher = undefined;
buttonPublish.onPublisherCreated = function(publisherParameter) { buttonPublish.onPublisherCreated = function(publisherParameter) {
@ -36,8 +37,8 @@ define([
button = $([ button = $([
'<button class="btn" title="Publish this document">', '<button class="btn" title="Publish this document">',
' <i class="icon-share"></i>', ' <i class="icon-share"></i>',
'</button>'].join("") '</button>'
).click(function() { ].join("")).click(function() {
if(!$(this).hasClass("disabled")) { if(!$(this).hasClass("disabled")) {
publisher.publish(); publisher.publish();
} }

View File

@ -16,6 +16,7 @@ define([
' <i class="icon-link"></i>', ' <i class="icon-link"></i>',
'</button>', '</button>',
'<div id="link-container" class="dropdown-menu pull-right">', '<div id="link-container" class="dropdown-menu pull-right">',
' <h3 class="muted">Sharing</h3>',
' <div class="link-list"></div>', ' <div class="link-list"></div>',
' <p class="no-link">To share this document you need first to ', ' <p class="no-link">To share this document you need first to ',
' <a href="#" class="action-publish-gist">publish it as a Gist</a>', ' <a href="#" class="action-publish-gist">publish it as a Gist</a>',
@ -26,8 +27,8 @@ define([
' <a href="viewer.html?url=https://raw.github.com/benweet/stackedit/master/README.md"', ' <a href="viewer.html?url=https://raw.github.com/benweet/stackedit/master/README.md"',
' title="Sharing example">viewer.html?url=...</a>', ' title="Sharing example">viewer.html?url=...</a>',
' </blockquote>', ' </blockquote>',
'</div>'].join("") '</div>'
); ].join(""));
}; };
var fileDesc = undefined; var fileDesc = undefined;
@ -35,7 +36,8 @@ define([
'<div class="input-prepend">', '<div class="input-prepend">',
' <a href="<%= link %>" class="add-on" title="Sharing location"><i class="icon-link"></i></a>', ' <a href="<%= link %>" class="add-on" title="Sharing location"><i class="icon-link"></i></a>',
' <input class="span2" type="text" value="<%= link %>" readonly />', ' <input class="span2" type="text" value="<%= link %>" readonly />',
'</div>'].join(""); '</div>'
].join("");
var refreshDocumentSharing = function(fileDescParameter) { var refreshDocumentSharing = function(fileDescParameter) {
if(fileDescParameter !== undefined && fileDescParameter !== fileDesc) { if(fileDescParameter !== undefined && fileDescParameter !== fileDesc) {
return; return;

View File

@ -1,13 +1,53 @@
define([ define([
"jquery", "jquery",
"underscore" "underscore",
], function($, _) { "utils"
], function($, _, utils) {
var buttonStat = { var buttonStat = {
extensionId: "buttonStat", extensionId: "buttonStat",
extensionName: 'Button "Statistics"', extensionName: 'Button "Statistics"',
optional: true, optional: true,
settingsBloc: '<p>Adds a "Document statistics" button in the navigation bar.</p>' defaultConfig: {
name1: "Words",
value1: "\\S+",
name2: "Characters",
value2: "\\S",
name3: "Paragraphs",
value3: ".+",
},
settingsBloc: [
'<p>Adds a "Document statistics" button in the navigation bar.</p>',
'<p><div class="form-inline">',
' <label class="label-text" for="input-stat-name1">Title</label>',
' <input id="input-stat-name1" type="text" class="input-small">',
' <label class="label-text" for="input-stat-value1">RegExp</label>',
' <input id="input-stat-value1" type="text" class="span2">',
'</div></p>',
'<p><div class="form-inline">',
' <label class="label-text" for="input-stat-name2">Title</label>',
' <input id="input-stat-name2" type="text" class="input-small">',
' <label class="label-text" for="input-stat-value2">RegExp</label>',
' <input id="input-stat-value2" type="text" class="span2">',
'</div></p>',
'<p><div class="form-inline">',
' <label class="label-text" for="input-stat-name3">Title</label>',
' <input id="input-stat-name3" type="text" class="input-small">',
' <label class="label-text" for="input-stat-value3">RegExp</label>',
' <input id="input-stat-value3" type="text" class="span2">',
'</div></p>'].join("")
};
buttonStat.onLoadSettings = function() {
_.each(buttonStat.defaultConfig, function(value, key) {
utils.setInputValue("#input-stat-" + key, buttonStat.config[key]);
});
};
buttonStat.onSaveSettings = function(newConfig, event) {
_.each(buttonStat.defaultConfig, function(value, key) {
newConfig[key] = utils.getInputTextValue("#input-stat-" + key, event);
});
}; };
buttonStat.onCreateButton = function() { buttonStat.onCreateButton = function() {
@ -16,57 +56,23 @@ define([
' <i class="icon-stat"></i>', ' <i class="icon-stat"></i>',
'</button>', '</button>',
'<div id="statistics-container" class="dropdown-menu pull-right">', '<div id="statistics-container" class="dropdown-menu pull-right">',
'<div class="link-list"></div>', ' <h3 class="muted">Statistics</h3>',
'<p class="no-link">To share this document you need first to <a', ' <div class="stat">',
'href="#" class="action-publish-gist">publish it as a Gist</a> in', ' <div>' + buttonStat.config.name1 + ': <span id="span-stat-value1"></span></div>',
'Markdown format.', ' <div>' + buttonStat.config.name2 + ': <span id="span-stat-value2"></span></div>',
'</p>', ' <div>' + buttonStat.config.name3 + ': <span id="span-stat-value3"></span></div>',
'<blockquote class="muted">', ' </div>',
'<b>NOTE:</b> You can open any URL within StackEdit using <a', '</div>'
'href="viewer.html?url=https://raw.github.com/benweet/stackedit/master/README.md"', ].join(""));
'title="Sharing example">viewer.html?url=...</a>',
'</blockquote>',
'</div>'].join("")
);
}; };
var fileDesc = undefined; buttonStat.onPreviewFinished = function() {
var lineTemplate = [ var text = $("#wmd-preview").text();
'<div class="input-prepend">', $("#span-stat-value1").text(text.match(new RegExp(buttonStat.config.value1, "g")).length);
'<a href="<%= link %>" class="add-on" title="Sharing location"><i class="icon-link"></i></a>', $("#span-stat-value2").text(text.match(new RegExp(buttonStat.config.value2, "g")).length);
'<input class="span2" type="text" value="<%= link %>" readonly />', $("#span-stat-value3").text(text.match(new RegExp(buttonStat.config.value3, "g")).length);
'</div>'].join("");
var refreshDocumentSharing = function(fileDescParameter) {
if(fileDescParameter !== undefined && fileDescParameter !== fileDesc) {
return;
}
var linkList = $("#link-container .link-list").empty();
$("#link-container .no-link").show();
var attributesList = _.values(fileDesc.publishLocations);
_.each(attributesList, function(attributes) {
if(attributes.sharingLink) {
var lineElement = $(_.template(lineTemplate, {
link: attributes.sharingLink
}));
lineElement.click(function(event) {
event.stopPropagation();
});
linkList.append(lineElement);
$("#link-container .no-link").hide();
}
});
}; };
buttonStat.onFileSelected = function(fileDescParameter) {
fileDesc = fileDescParameter;
refreshDocumentSharing(fileDescParameter);
};
buttonStat.onNewPublishSuccess = refreshDocumentSharing;
buttonStat.onPublishRemoved = refreshDocumentSharing;
return buttonStat; return buttonStat;
}); });

View File

@ -35,8 +35,8 @@ define([
button = $([ button = $([
'<button class="btn" title="Synchronize all documents">', '<button class="btn" title="Synchronize all documents">',
' <i class="icon-refresh"></i>', ' <i class="icon-refresh"></i>',
'</button>'].join("") '</button>'
).click(function() { ].join("")).click(function() {
if(!$(this).hasClass("disabled")) { if(!$(this).hasClass("disabled")) {
synchronizer.forceSync(); synchronizer.forceSync();
} }

View File

@ -35,9 +35,7 @@ define([
liMap = {}; liMap = {};
$("#file-selector li:not(.stick)").empty(); $("#file-selector li:not(.stick)").empty();
_.chain( _.chain(fileSystem).sortBy(function(fileDesc) {
fileSystem
).sortBy(function(fileDesc) {
return fileDesc.title.toLowerCase(); return fileDesc.title.toLowerCase();
}).each(function(fileDesc) { }).each(function(fileDesc) {
var a = $('<a href="#">').html(composeTitle(fileDesc)).click(function() { var a = $('<a href="#">').html(composeTitle(fileDesc)).click(function() {
@ -67,6 +65,37 @@ define([
documentSelector.onNewPublishSuccess = buildSelector; documentSelector.onNewPublishSuccess = buildSelector;
documentSelector.onPublishRemoved = buildSelector; documentSelector.onPublishRemoved = buildSelector;
// Filter for search input in file selector
function filterFileSelector(filter) {
var liList = $("#file-selector li:not(.stick)");
liList.show();
if(filter) {
var words = filter.toLowerCase().split(/\s+/);
liList.each(function() {
var fileTitle = $(this).text().toLowerCase();
if(_.some(words, function(word) {
return fileTitle.indexOf(word) === -1;
})) {
$(this).hide();
}
});
}
}
documentSelector.onReady = function() {
$(".action-open-file").click(function() {
filterFileSelector();
_.defer(function() {
$("#file-search").val("").focus();
});
});
$("#file-search").keyup(function() {
filterFileSelector($(this).val());
}).click(function(event) {
event.stopPropagation();
});
};
return documentSelector; return documentSelector;
}); });

View File

@ -17,4 +17,3 @@ define(function() {
return emailConverter; return emailConverter;
}); });

View File

@ -21,7 +21,8 @@ define([
' <i class="icon-<%= provider.providerId %>"></i>', ' <i class="icon-<%= provider.providerId %>"></i>',
' </span>', ' </span>',
' <input class="span5" type="text" value="<%= publishDesc %>" disabled />', ' <input class="span5" type="text" value="<%= publishDesc %>" disabled />',
'</div>'].join(""); '</div>'
].join("");
var removeButtonTemplate = '<a class="btn" title="Remove this location"><i class="icon-trash"></i></a>'; var removeButtonTemplate = '<a class="btn" title="Remove this location"><i class="icon-trash"></i></a>';
var refreshDialog = function(fileDescParameter) { var refreshDialog = function(fileDescParameter) {
if(fileDescParameter !== undefined && fileDescParameter !== fileDesc) { if(fileDescParameter !== undefined && fileDescParameter !== fileDesc) {
@ -33,7 +34,8 @@ define([
var publishList = $("#manage-publish-list").empty(); var publishList = $("#manage-publish-list").empty();
if(publishAttributesList.length > 0) { if(publishAttributesList.length > 0) {
$(".msg-publish-list").removeClass("hide"); $(".msg-publish-list").removeClass("hide");
} else { }
else {
$(".msg-no-publish").removeClass("hide"); $(".msg-no-publish").removeClass("hide");
} }
_.each(publishAttributesList, function(publishAttributes) { _.each(publishAttributesList, function(publishAttributes) {

View File

@ -21,7 +21,8 @@ define([
' <i class="icon-<%= provider.providerId %>"></i>', ' <i class="icon-<%= provider.providerId %>"></i>',
' </span>', ' </span>',
' <input class="span5" type="text" value="<%= syncDesc %>" disabled />', ' <input class="span5" type="text" value="<%= syncDesc %>" disabled />',
'</div>'].join(""); '</div>'
].join("");
var removeButtonTemplate = '<a class="btn" title="Remove this location"><i class="icon-trash"></i></a>'; var removeButtonTemplate = '<a class="btn" title="Remove this location"><i class="icon-trash"></i></a>';
var refreshDialog = function(fileDescParameter) { var refreshDialog = function(fileDescParameter) {
if(fileDescParameter !== undefined && fileDescParameter !== fileDesc) { if(fileDescParameter !== undefined && fileDescParameter !== fileDesc) {
@ -33,7 +34,8 @@ define([
var syncList = $("#manage-sync-list").empty(); var syncList = $("#manage-sync-list").empty();
if(syncAttributesList.length > 0) { if(syncAttributesList.length > 0) {
$(".msg-sync-list").removeClass("hide"); $(".msg-sync-list").removeClass("hide");
} else { }
else {
$(".msg-no-sync").removeClass("hide"); $(".msg-no-sync").removeClass("hide");
} }
_.each(syncAttributesList, function(syncAttributes) { _.each(syncAttributesList, function(syncAttributes) {

View File

@ -80,9 +80,9 @@ define([
showMessage("You are back online!", "icon-signal"); showMessage("You are back online!", "icon-signal");
} }
}); });
} else { }
$(".msg-offline").parents(".jGrowl-notification").trigger( else {
'jGrowl.beforeClose'); $(".msg-offline").parents(".jGrowl-notification").trigger('jGrowl.beforeClose');
} }
}; };

View File

@ -51,8 +51,7 @@ define([
} }
// Create MD sections by finding title patterns (excluding gfm blocs) // Create MD sections by finding title patterns (excluding gfm blocs)
var text = editorElt.val() + "\n\n"; var text = editorElt.val() + "\n\n";
text.replace(/^```.*\n[\s\S]*?\n```|(^.+[ \t]*\n=+[ \t]*\n+|^.+[ \t]*\n-+[ \t]*\n+|^\#{1,6}[ \t]*.+?[ \t]*\#*\n+)/gm, text.replace(/^```.*\n[\s\S]*?\n```|(^.+[ \t]*\n=+[ \t]*\n+|^.+[ \t]*\n-+[ \t]*\n+|^\#{1,6}[ \t]*.+?[ \t]*\#*\n+)/gm, function(match, title, matchOffset) {
function(match, title, matchOffset) {
if(title) { if(title) {
// We just found a title which means end of the previous section // We just found a title which means end of the previous section
// Exclude last \n of the section // Exclude last \n of the section
@ -64,8 +63,7 @@ define([
offset = matchOffset; offset = matchOffset;
} }
return ""; return "";
} });
);
// Last section // Last section
// Consider wmd-input bottom padding and exclude \n\n previously added // Consider wmd-input bottom padding and exclude \n\n previously added
padding += pxToFloat(editorElt.css('padding-bottom')); padding += pxToFloat(editorElt.css('padding-bottom'));
@ -129,12 +127,17 @@ define([
var posInSection = (srcScrollTop - srcSection.startOffset) / srcSection.height; var posInSection = (srcScrollTop - srcSection.startOffset) / srcSection.height;
var destSection = destSectionList[sectionIndex]; var destSection = destSectionList[sectionIndex];
var destScrollTop = destSection.startOffset + destSection.height * posInSection; var destScrollTop = destSection.startOffset + destSection.height * posInSection;
destScrollTop = _.min([destScrollTop, destElt.prop('scrollHeight') - destElt.outerHeight()]); destScrollTop = _.min([
destScrollTop,
destElt.prop('scrollHeight') - destElt.outerHeight()
]);
if(Math.abs(destScrollTop - lastDestScrollTop) < 5) { if(Math.abs(destScrollTop - lastDestScrollTop) < 5) {
// Skip the animation in case it's not necessary // Skip the animation in case it's not necessary
return; return;
} }
destElt.animate({scrollTop: destScrollTop}, 600, function() { destElt.animate({
scrollTop: destScrollTop
}, 600, function() {
callback(destScrollTop); callback(destScrollTop);
}); });
} }

View File

@ -87,17 +87,8 @@ define([
} }
var elementList = []; var elementList = [];
$("#wmd-preview > h1," + $("#wmd-preview > h1," + "#wmd-preview > h2," + "#wmd-preview > h3," + "#wmd-preview > h4," + "#wmd-preview > h5," + "#wmd-preview > h6").each(function() {
"#wmd-preview > h2," + elementList.push(new TocElement($(this).prop("tagName"), createAnchor($(this)), $(this).text()));
"#wmd-preview > h3," +
"#wmd-preview > h4," +
"#wmd-preview > h5," +
"#wmd-preview > h6").each(function() {
elementList.push(new TocElement(
$(this).prop("tagName"),
createAnchor($(this)),
$(this).text()
));
}); });
elementList = groupTags(elementList); elementList = groupTags(elementList);
return '<div class="toc"><ul>' + elementList.toString() + '</ul></div>'; return '<div class="toc"><ul>' + elementList.toString() + '</ul></div>';
@ -115,4 +106,3 @@ define([
return toc; return toc;
}); });

View File

@ -13,7 +13,8 @@ define([
if(isRunning === false) { if(isRunning === false) {
$(".working-indicator").removeClass("show"); $(".working-indicator").removeClass("show");
$("body").removeClass("working"); $("body").removeClass("working");
} else { }
else {
$(".working-indicator").addClass("show"); $(".working-indicator").addClass("show");
$("body").addClass("working"); $("body").addClass("working");
} }

View File

@ -14,27 +14,28 @@ define([
// Defines a file descriptor in the file system (fileDesc objects) // Defines a file descriptor in the file system (fileDesc objects)
function FileDescriptor(fileIndex, title, syncLocations, publishLocations) { function FileDescriptor(fileIndex, title, syncLocations, publishLocations) {
this.fileIndex = fileIndex; this.fileIndex = fileIndex;
this.title = title; this._title = title;
this.__defineGetter__("title", function() {
return this._title;
});
this.__defineSetter__("title", function(title) {
this._title = title;
localStorage[this.fileIndex + ".title"] = title;
extensionMgr.onTitleChanged(this);
});
this.__defineGetter__("content", function() {
return localStorage[this.fileIndex + ".content"];
});
this.__defineSetter__("content", function(content) {
localStorage[this.fileIndex + ".content"] = content;
extensionMgr.onContentChanged(this);
});
this.syncLocations = syncLocations || {}; this.syncLocations = syncLocations || {};
this.publishLocations = publishLocations || {}; this.publishLocations = publishLocations || {};
} }
FileDescriptor.prototype.getContent = function() {
return localStorage[this.fileIndex + ".content"];
};
FileDescriptor.prototype.setContent = function(content) {
localStorage[this.fileIndex + ".content"] = content;
extensionMgr.onContentChanged(this);
};
FileDescriptor.prototype.setTitle = function(title) {
this.title = title;
localStorage[this.fileIndex + ".title"] = title;
extensionMgr.onTitleChanged(this);
};
// Load file descriptors from localStorage // Load file descriptors from localStorage
_.chain( _.chain(localStorage["file.list"].split(";")).compact().each(function(fileIndex) {
localStorage["file.list"].split(";")
).compact().each(function(fileIndex) {
fileSystem[fileIndex] = new FileDescriptor(fileIndex, localStorage[fileIndex + ".title"]); fileSystem[fileIndex] = new FileDescriptor(fileIndex, localStorage[fileIndex + ".title"]);
}); });
@ -92,7 +93,7 @@ define([
} }
// Recreate the editor // Recreate the editor
$("#wmd-input").val(fileDesc.getContent()); $("#wmd-input").val(fileDesc.content);
core.createEditor(function() { core.createEditor(function() {
// Callback to save content when textarea changes // Callback to save content when textarea changes
fileMgr.saveFile(); fileMgr.saveFile();
@ -164,8 +165,7 @@ define([
// Remove the index from the file list // Remove the index from the file list
var fileIndex = fileDesc.fileIndex; var fileIndex = fileDesc.fileIndex;
localStorage["file.list"] = localStorage["file.list"].replace(";" localStorage["file.list"] = localStorage["file.list"].replace(";" + fileIndex + ";", ";");
+ fileIndex + ";", ";");
localStorage.removeItem(fileIndex + ".title"); localStorage.removeItem(fileIndex + ".title");
localStorage.removeItem(fileIndex + ".content"); localStorage.removeItem(fileIndex + ".content");
@ -178,9 +178,8 @@ define([
// Save current file in localStorage // Save current file in localStorage
fileMgr.saveFile = function() { fileMgr.saveFile = function() {
var content = $("#wmd-input").val();
var fileDesc = fileMgr.getCurrentFile(); var fileDesc = fileMgr.getCurrentFile();
fileDesc.setContent(content); fileDesc.content = $("#wmd-input").val();
}; };
// Add a synchronized location to a file // Add a synchronized location to a file
@ -195,8 +194,7 @@ define([
fileMgr.removeSync = function(syncAttributes, skipExtensions) { fileMgr.removeSync = function(syncAttributes, skipExtensions) {
var fileDesc = fileMgr.getFileFromSyncIndex(syncAttributes.syncIndex); var fileDesc = fileMgr.getFileFromSyncIndex(syncAttributes.syncIndex);
if(fileDesc !== undefined) { if(fileDesc !== undefined) {
localStorage[fileDesc.fileIndex + ".sync"] = localStorage[fileDesc.fileIndex + ".sync"].replace(";" localStorage[fileDesc.fileIndex + ".sync"] = localStorage[fileDesc.fileIndex + ".sync"].replace(";" + syncAttributes.syncIndex + ";", ";");
+ syncAttributes.syncIndex + ";", ";");
} }
// Remove sync attributes // Remove sync attributes
localStorage.removeItem(syncAttributes.syncIndex); localStorage.removeItem(syncAttributes.syncIndex);
@ -239,8 +237,7 @@ define([
fileMgr.removePublish = function(publishAttributes, skipExtensions) { fileMgr.removePublish = function(publishAttributes, skipExtensions) {
var fileDesc = fileMgr.getFileFromPublishIndex(publishAttributes.publishIndex); var fileDesc = fileMgr.getFileFromPublishIndex(publishAttributes.publishIndex);
if(fileDesc !== undefined) { if(fileDesc !== undefined) {
localStorage[fileDesc.fileIndex + ".publish"] = localStorage[fileDesc.fileIndex + ".publish"].replace(";" localStorage[fileDesc.fileIndex + ".publish"] = localStorage[fileDesc.fileIndex + ".publish"].replace(";" + publishAttributes.publishIndex + ";", ";");
+ publishAttributes.publishIndex + ";", ";");
} }
// Remove publish attributes // Remove publish attributes
localStorage.removeItem(publishAttributes.publishIndex); localStorage.removeItem(publishAttributes.publishIndex);
@ -257,23 +254,6 @@ define([
}); });
}; };
// Filter for search input in file selector
function filterFileSelector(filter) {
var liList = $("#file-selector li:not(.stick)");
liList.show();
if(filter) {
var words = filter.toLowerCase().split(/\s+/);
liList.each(function() {
var fileTitle = $(this).text().toLowerCase();
if(_.some(words, function(word) {
return fileTitle.indexOf(word) === -1;
})) {
$(this).hide();
}
});
}
}
core.onReady(function() { core.onReady(function() {
fileMgr.selectFile(); fileMgr.selectFile();
@ -306,7 +286,7 @@ define([
var title = $.trim(input.val()); var title = $.trim(input.val());
var fileDesc = fileMgr.getCurrentFile(); var fileDesc = fileMgr.getCurrentFile();
if(title && title != fileDesc.title) { if(title && title != fileDesc.title) {
fileDesc.setTitle(title); fileDesc.title = title;
} }
input.val(fileDesc.title); input.val(fileDesc.title);
$("#wmd-input").focus(); $("#wmd-input").focus();
@ -322,17 +302,6 @@ define([
applyTitle($(this)); applyTitle($(this));
} }
}); });
$(".action-open-file").click(function() {
filterFileSelector();
_.defer(function() {
$("#file-search").val("").focus();
});
});
$("#file-search").keyup(function() {
filterFileSelector($(this).val());
}).click(function(event) {
event.stopPropagation();
});
$(".action-open-stackedit").click(function() { $(".action-open-stackedit").click(function() {
window.location.href = "."; window.location.href = ".";
}); });

View File

@ -13,7 +13,9 @@ define([
providerId: PROVIDER_GDRIVE, providerId: PROVIDER_GDRIVE,
providerName: "Google Drive", providerName: "Google Drive",
defaultPublishFormat: "template", defaultPublishFormat: "template",
exportPreferencesInputIds: ["gdrive-parentid"] exportPreferencesInputIds: [
"gdrive-parentid"
]
}; };
function createSyncIndex(id) { function createSyncIndex(id) {
@ -53,7 +55,8 @@ define([
extensionMgr.onSyncImportSuccess(fileDescList, gdriveProvider); extensionMgr.onSyncImportSuccess(fileDescList, gdriveProvider);
}); });
}); });
}; }
;
gdriveProvider.importFiles = function() { gdriveProvider.importFiles = function() {
googleHelper.picker(function(error, ids) { googleHelper.picker(function(error, ids) {
@ -164,7 +167,8 @@ define([
var syncAttributes = change.syncAttributes; var syncAttributes = change.syncAttributes;
var syncIndex = syncAttributes.syncIndex; var syncIndex = syncAttributes.syncIndex;
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex); var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
// No file corresponding (file may have been deleted locally) // No file corresponding (file may have been deleted
// locally)
if(fileDesc === undefined) { if(fileDesc === undefined) {
return; return;
} }
@ -176,7 +180,7 @@ define([
return; return;
} }
var localTitleChanged = syncAttributes.titleCRC != utils.crc32(localTitle); var localTitleChanged = syncAttributes.titleCRC != utils.crc32(localTitle);
var localContent = fileDesc.getContent(); var localContent = fileDesc.content;
var localContentChanged = syncAttributes.contentCRC != utils.crc32(localContent); var localContentChanged = syncAttributes.contentCRC != utils.crc32(localContent);
var file = change.file; var file = change.file;
var remoteTitleCRC = utils.crc32(file.title); var remoteTitleCRC = utils.crc32(file.title);
@ -186,19 +190,18 @@ define([
var remoteContentChanged = syncAttributes.contentCRC != remoteContentCRC; var remoteContentChanged = syncAttributes.contentCRC != remoteContentCRC;
var fileContentChanged = localContent != file.content; var fileContentChanged = localContent != file.content;
// Conflict detection // Conflict detection
if ((fileTitleChanged === true && localTitleChanged === true && remoteTitleChanged === true) if((fileTitleChanged === true && localTitleChanged === true && remoteTitleChanged === true) || (fileContentChanged === true && localContentChanged === true && remoteContentChanged === true)) {
|| (fileContentChanged === true && localContentChanged === true && remoteContentChanged === true)) {
fileMgr.createFile(localTitle + " (backup)", localContent); fileMgr.createFile(localTitle + " (backup)", localContent);
extensionMgr.onMessage('Conflict detected on "' + localTitle + '". A backup has been created locally.'); extensionMgr.onMessage('Conflict detected on "' + localTitle + '". A backup has been created locally.');
} }
// If file title changed // If file title changed
if(fileTitleChanged && remoteTitleChanged === true) { if(fileTitleChanged && remoteTitleChanged === true) {
fileDesc.setTitle(file.title); fileDesc.title = file.title;
extensionMgr.onMessage('"' + localTitle + '" has been renamed to "' + file.title + '" on Google Drive.'); extensionMgr.onMessage('"' + localTitle + '" has been renamed to "' + file.title + '" on Google Drive.');
} }
// If file content changed // If file content changed
if(fileContentChanged && remoteContentChanged === true) { if(fileContentChanged && remoteContentChanged === true) {
fileDesc.setContent(file.content); fileDesc.content = file.content;
extensionMgr.onMessage('"' + file.title + '" has been updated from Google Drive.'); extensionMgr.onMessage('"' + file.title + '" has been updated from Google Drive.');
if(fileMgr.isCurrentFile(fileDesc)) { if(fileMgr.isCurrentFile(fileDesc)) {
fileMgr.selectFile(); // Refresh editor fileMgr.selectFile(); // Refresh editor
@ -217,21 +220,14 @@ define([
}; };
gdriveProvider.publish = function(publishAttributes, title, content, callback) { gdriveProvider.publish = function(publishAttributes, title, content, callback) {
googleHelper.upload( googleHelper.upload(publishAttributes.id, undefined, publishAttributes.fileName || title, content, undefined, function(error, result) {
publishAttributes.id,
undefined,
publishAttributes.fileName || title,
content,
undefined,
function(error, result) {
if(error) { if(error) {
callback(error); callback(error);
return; return;
} }
publishAttributes.id = result.id; publishAttributes.id = result.id;
callback(); callback();
} });
);
}; };
gdriveProvider.newPublishAttributes = function(event) { gdriveProvider.newPublishAttributes = function(event) {
@ -252,8 +248,7 @@ define([
localStorage.removeItem(PROVIDER_GDRIVE + ".state"); localStorage.removeItem(PROVIDER_GDRIVE + ".state");
state = JSON.parse(state); state = JSON.parse(state);
if(state.action == "create") { if(state.action == "create") {
googleHelper.upload(undefined, state.folderId, GDRIVE_DEFAULT_FILE_TITLE, googleHelper.upload(undefined, state.folderId, GDRIVE_DEFAULT_FILE_TITLE, "", undefined, function(error, file) {
"", undefined, function(error, file) {
if(error) { if(error) {
return; return;
} }

View File

@ -8,20 +8,21 @@ define([
var gistProvider = { var gistProvider = {
providerId: PROVIDER_GIST, providerId: PROVIDER_GIST,
providerName: "Gist", providerName: "Gist",
sharingAttributes: ["gistId", "filename"] 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, githubHelper.uploadGist(publishAttributes.gistId, publishAttributes.filename, publishAttributes.isPublic, title, content, function(error, gistId) {
title, content, function(error, gistId) {
if(error) { if(error) {
callback(error); callback(error);
return; return;
} }
publishAttributes.gistId = gistId; publishAttributes.gistId = gistId;
callback(); callback();
} });
);
}; };
gistProvider.newPublishAttributes = function(event) { gistProvider.newPublishAttributes = function(event) {

View File

@ -25,7 +25,8 @@ define([
} }
$.ajax({ $.ajax({
url: "lib/github.js", url: "lib/github.js",
dataType : "script", timeout : AJAX_TIMEOUT dataType: "script",
timeout: AJAX_TIMEOUT
}).done(function() { }).done(function() {
connected = true; connected = true;
task.chain(); task.chain();
@ -64,9 +65,7 @@ define([
var code = undefined; var code = undefined;
function getCode() { function getCode() {
localStorage.removeItem("githubCode"); localStorage.removeItem("githubCode");
authWindow = utils.popupWindow( authWindow = utils.popupWindow('github-oauth-client.html?client_id=' + GITHUB_CLIENT_ID, 'stackedit-github-oauth', 960, 600);
'github-oauth-client.html?client_id=' + GITHUB_CLIENT_ID,
'stackedit-github-oauth', 960, 600);
authWindow.focus(); authWindow.focus();
intervalId = setInterval(function() { intervalId = setInterval(function() {
if(authWindow.closed === true) { if(authWindow.closed === true) {
@ -156,7 +155,9 @@ define([
task.onRun(function() { task.onRun(function() {
var gist = github.getGist(gistId); var gist = github.getGist(gistId);
var files = {}; var files = {};
files[filename] = {content: content}; files[filename] = {
content: content
};
githubFunction = gist.update; githubFunction = gist.update;
if(gistId === undefined) { if(gistId === undefined) {
githubFunction = gist.create; githubFunction = gist.create;
@ -237,7 +238,8 @@ define([
errorMsg = "Access to GitHub account is not authorized."; errorMsg = "Access to GitHub account is not authorized.";
task.retry(new Error(errorMsg), 1); task.retry(new Error(errorMsg), 1);
return; return;
} else if (error.error <= 0) { }
else if(error.error <= 0) {
connected = false; connected = false;
github = undefined; github = undefined;
core.setOffline(); core.setOffline();

View File

@ -9,13 +9,15 @@ define([
var githubProvider = { var githubProvider = {
providerId: PROVIDER_GITHUB, providerId: PROVIDER_GITHUB,
providerName: "GitHub", providerName: "GitHub",
publishPreferencesInputIds: ["github-reponame", "github-branch"] 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;
githubHelper.upload(publishAttributes.repository, publishAttributes.branch, githubHelper.upload(publishAttributes.repository, publishAttributes.branch, publishAttributes.path, content, commitMsg, callback);
publishAttributes.path, content, commitMsg, callback);
}; };
githubProvider.newPublishAttributes = function(event) { githubProvider.newPublishAttributes = function(event) {

View File

@ -29,7 +29,8 @@ define([
}; };
$.ajax({ $.ajax({
url: "https://apis.google.com/js/client.js?onload=runDelayedFunction", url: "https://apis.google.com/js/client.js?onload=runDelayedFunction",
dataType : "script", timeout : AJAX_TIMEOUT dataType: "script",
timeout: AJAX_TIMEOUT
}).fail(function(jqXHR) { }).fail(function(jqXHR) {
var error = { var error = {
code: jqXHR.status, code: jqXHR.status,
@ -51,15 +52,19 @@ define([
function localAuthenticate() { function localAuthenticate() {
if(immediate === false) { if(immediate === false) {
extensionMgr.onMessage("Please make sure the Google authorization popup is not blocked by your browser."); extensionMgr.onMessage("Please make sure the Google authorization popup is not blocked by your browser.");
// If not immediate we add time for user to enter his credentials // If not immediate we add time for user to enter his
// credentials
task.timeout = ASYNC_TASK_LONG_TIMEOUT; task.timeout = ASYNC_TASK_LONG_TIMEOUT;
} }
gapi.auth.authorize({ 'client_id' : GOOGLE_CLIENT_ID, gapi.auth.authorize({
'scope' : GOOGLE_SCOPES, 'immediate' : immediate }, function( 'client_id': GOOGLE_CLIENT_ID,
authResult) { 'scope': GOOGLE_SCOPES,
'immediate': immediate
}, function(authResult) {
gapi.client.load('drive', 'v2', function() { gapi.client.load('drive', 'v2', function() {
if(!authResult || authResult.error) { if(!authResult || authResult.error) {
// If immediate did not work retry without immediate flag // If immediate did not work retry without immediate
// flag
if(connected === true && immediate === true) { if(connected === true && immediate === true) {
immediate = false; immediate = false;
task.chain(localAuthenticate); task.chain(localAuthenticate);
@ -89,11 +94,18 @@ define([
var delimiter = "\r\n--" + boundary + "\r\n"; var delimiter = "\r\n--" + boundary + "\r\n";
var close_delim = "\r\n--" + boundary + "--"; var close_delim = "\r\n--" + boundary + "--";
var contentType = 'text/x-markdown'; var contentType = 'text/x-markdown';
var metadata = { title : title, mimeType : contentType }; var metadata = {
title: title,
mimeType: contentType
};
if(parentId !== undefined) { if(parentId !== undefined) {
// Specify the directory // Specify the directory
metadata.parents = [ { kind : 'drive#fileLink', metadata.parents = [
id : parentId } ]; {
kind: 'drive#fileLink',
id: parentId
}
];
} }
var path = '/upload/drive/v2/files'; var path = '/upload/drive/v2/files';
var method = 'POST'; var method = 'POST';
@ -102,28 +114,27 @@ define([
path += "/" + fileId; path += "/" + fileId;
method = 'PUT'; method = 'PUT';
} }
var headers = { 'Content-Type' : 'multipart/mixed; boundary="' var headers = {
+ boundary + '"', }; 'Content-Type': 'multipart/mixed; boundary="' + boundary + '"',
};
if(etag !== undefined) { if(etag !== undefined) {
// Sometimes we have error 412 from Google even with the correct etag // Sometimes we have error 412 from Google even with the correct
// etag
// headers["If-Match"] = etag; // headers["If-Match"] = etag;
} }
var base64Data = utils.encodeBase64(content); var base64Data = utils.encodeBase64(content);
var multipartRequestBody = delimiter var multipartRequestBody = delimiter + 'Content-Type: application/json\r\n\r\n' + JSON.stringify(metadata) + delimiter + 'Content-Type: ' + contentType + '\r\n' + 'Content-Transfer-Encoding: base64\r\n' + '\r\n' + base64Data + close_delim;
+ 'Content-Type: application/json\r\n\r\n'
+ JSON.stringify(metadata) + delimiter + 'Content-Type: '
+ contentType + '\r\n'
+ 'Content-Transfer-Encoding: base64\r\n' + '\r\n'
+ base64Data + close_delim;
var request = gapi.client var request = gapi.client.request({
.request({
'path': path, 'path': path,
'method': method, 'method': method,
'params' : { 'uploadType' : 'multipart', }, 'params': {
'uploadType': 'multipart',
},
'headers': headers, 'headers': headers,
'body' : multipartRequestBody, }); 'body': multipartRequestBody,
});
request.execute(function(response) { request.execute(function(response) {
if(response && response.id) { if(response && response.id) {
// Upload success // Upload success
@ -166,12 +177,14 @@ define([
function retrievePageOfChanges() { function retrievePageOfChanges() {
var request = undefined; var request = undefined;
if(nextPageToken === undefined) { if(nextPageToken === undefined) {
request = gapi.client.drive.changes request = gapi.client.drive.changes.list({
.list({ 'startChangeId' : newChangeId + 1 }); 'startChangeId': newChangeId + 1
});
} }
else { else {
request = gapi.client.drive.changes request = gapi.client.drive.changes.list({
.list({ 'pageToken' : nextPageToken }); 'pageToken': nextPageToken
});
} }
request.execute(function(response) { request.execute(function(response) {
@ -227,7 +240,9 @@ define([
$.ajax({ $.ajax({
url: "https://www.googleapis.com/drive/v2/files/" + id, url: "https://www.googleapis.com/drive/v2/files/" + id,
headers: headers, headers: headers,
data : {key: GOOGLE_API_KEY}, data: {
key: GOOGLE_API_KEY
},
dataType: "json", dataType: "json",
timeout: AJAX_TIMEOUT timeout: AJAX_TIMEOUT
}).done(function(data, textStatus, jqXHR) { }).done(function(data, textStatus, jqXHR) {
@ -296,7 +311,9 @@ define([
$.ajax({ $.ajax({
url: file.downloadUrl, url: file.downloadUrl,
headers: headers, headers: headers,
data : {key: GOOGLE_API_KEY}, data: {
key: GOOGLE_API_KEY
},
dataType: "text", dataType: "text",
timeout: AJAX_TIMEOUT timeout: AJAX_TIMEOUT
}).done(function(data, textStatus, jqXHR) { }).done(function(data, textStatus, jqXHR) {
@ -332,18 +349,19 @@ define([
errorMsg = error; errorMsg = error;
} }
else { else {
errorMsg = "Google error (" + error.code + ": " errorMsg = "Google error (" + error.code + ": " + error.message + ").";
+ error.message + ").";
if(error.code >= 500 && error.code < 600) { if(error.code >= 500 && error.code < 600) {
// Retry as described in Google's best practices // Retry as described in Google's best practices
task.retry(new Error(errorMsg)); task.retry(new Error(errorMsg));
return; return;
} else if (error.code === 401 || error.code === 403) { }
else if(error.code === 401 || error.code === 403) {
authenticated = false; authenticated = false;
errorMsg = "Access to Google account is not authorized."; errorMsg = "Access to Google account is not authorized.";
task.retry(new Error(errorMsg), 1); task.retry(new Error(errorMsg), 1);
return; return;
} else if (error.code <= 0) { }
else if(error.code <= 0) {
connected = false; connected = false;
authenticated = false; authenticated = false;
core.setOffline(); core.setOffline();
@ -363,11 +381,15 @@ define([
} }
$.ajax({ $.ajax({
url: "//www.google.com/jsapi", url: "//www.google.com/jsapi",
data : {key: GOOGLE_API_KEY}, data: {
key: GOOGLE_API_KEY
},
dataType: "script", dataType: "script",
timeout: AJAX_TIMEOUT timeout: AJAX_TIMEOUT
}).done(function() { }).done(function() {
google.load('picker', '1', {callback: task.chain}); google.load('picker', '1', {
callback: task.chain
});
pickerLoaded = true; pickerLoaded = true;
}).fail(function(jqXHR) { }).fail(function(jqXHR) {
var error = { var error = {
@ -405,8 +427,7 @@ define([
pickerBuilder.addView(view); pickerBuilder.addView(view);
pickerBuilder.addView(new google.picker.DocsUploadView()); pickerBuilder.addView(new google.picker.DocsUploadView());
pickerBuilder.setCallback(function(data) { pickerBuilder.setCallback(function(data) {
if (data.action == google.picker.Action.PICKED || if(data.action == google.picker.Action.PICKED || data.action == google.picker.Action.CANCEL) {
data.action == google.picker.Action.CANCEL) {
if(data.action == google.picker.Action.PICKED) { if(data.action == google.picker.Action.PICKED) {
for ( var i = 0; i < data.docs.length; i++) { for ( var i = 0; i < data.docs.length; i++) {
ids.push(data.docs[i].id); ids.push(data.docs[i].id);
@ -447,7 +468,9 @@ define([
var url = "https://www.googleapis.com/blogger/v3/blogs/" + blogId + "/posts/"; var url = "https://www.googleapis.com/blogger/v3/blogs/" + blogId + "/posts/";
var data = { var data = {
kind: "blogger#post", kind: "blogger#post",
blog: { id: blogId }, blog: {
id: blogId
},
labels: labelList, labels: labelList,
title: title, title: title,
content: content content: content
@ -489,7 +512,9 @@ define([
} }
$.ajax({ $.ajax({
url: "https://www.googleapis.com/blogger/v3/blogs/byurl", url: "https://www.googleapis.com/blogger/v3/blogs/byurl",
data: { url: blogUrl }, data: {
url: blogUrl
},
headers: headers, headers: headers,
dataType: "json", dataType: "json",
timeout: AJAX_TIMEOUT timeout: AJAX_TIMEOUT

View File

@ -21,17 +21,16 @@ define([
var publisher = {}; var publisher = {};
// Create a map with providerId: providerModule // Create a map with providerId: providerModule
var providerMap = _.chain( var providerMap = _.chain(arguments).map(function(argument) {
arguments return argument && argument.providerId && [
).map(function(argument) { argument.providerId,
return argument && argument.providerId && [argument.providerId, argument]; argument
];
}).compact().object().value(); }).compact().object().value();
// Retrieve publish locations from localStorage // Retrieve publish locations from localStorage
_.each(fileSystem, function(fileDesc) { _.each(fileSystem, function(fileDesc) {
_.chain( _.chain(localStorage[fileDesc.fileIndex + ".publish"].split(";")).compact().each(function(publishIndex) {
localStorage[fileDesc.fileIndex + ".publish"].split(";")
).compact().each(function(publishIndex) {
var publishAttributes = JSON.parse(localStorage[publishIndex]); var publishAttributes = JSON.parse(localStorage[publishIndex]);
// Store publishIndex // Store publishIndex
publishAttributes.publishIndex = publishIndex; publishAttributes.publishIndex = publishIndex;
@ -51,7 +50,8 @@ define([
documentHTML: $("#wmd-preview").html(), documentHTML: $("#wmd-preview").html(),
publishAttributes: publishAttributes publishAttributes: publishAttributes
}); });
} catch(e) { }
catch (e) {
extensionMgr.onError(e); extensionMgr.onError(e);
throw e; throw e;
} }
@ -185,7 +185,8 @@ define([
} }
}); });
// Store input values as preferences for next time we open the publish dialog // Store input values as preferences for next time we open the publish
// dialog
var publishPreferences = {}; var publishPreferences = {};
_.each(provider.publishPreferencesInputIds, function(inputId) { _.each(provider.publishPreferencesInputIds, function(inputId) {
publishPreferences[inputId] = $("#input-publish-" + inputId).val(); publishPreferences[inputId] = $("#input-publish-" + inputId).val();
@ -196,9 +197,7 @@ define([
// Retrieve file's publish locations from localStorage // Retrieve file's publish locations from localStorage
publisher.populatePublishLocations = function(fileDesc) { publisher.populatePublishLocations = function(fileDesc) {
_.chain( _.chain(localStorage[fileDesc.fileIndex + ".publish"].split(";")).compact().each(function(publishIndex) {
localStorage[fileDesc.fileIndex + ".publish"].split(";")
).compact().each(function(publishIndex) {
var publishAttributes = JSON.parse(localStorage[publishIndex]); var publishAttributes = JSON.parse(localStorage[publishIndex]);
// Store publishIndex // Store publishIndex
publishAttributes.publishIndex = publishIndex; publishAttributes.publishIndex = publishIndex;
@ -213,15 +212,9 @@ define([
var publishMenu = $("#publish-menu"); var publishMenu = $("#publish-menu");
_.each(providerMap, function(provider) { _.each(providerMap, function(provider) {
// Provider's publish button // Provider's publish button
publishMenu.append( publishMenu.append($("<li>").append($('<a href="#"><i class="icon-' + provider.providerId + '"></i> ' + provider.providerName + '</a>').click(function() {
$("<li>").append(
$('<a href="#"><i class="icon-' + provider.providerId + '"></i> ' + provider.providerName + '</a>')
.click(function() {
initNewLocation(provider); initNewLocation(provider);
} })));
)
)
);
// Action links (if any) // Action links (if any)
$(".action-publish-" + provider.providerId).click(function() { $(".action-publish-" + provider.providerId).click(function() {
initNewLocation(provider); initNewLocation(provider);

View File

@ -16,7 +16,8 @@ define([
'<title><%= documentTitle %></title>\n', '<title><%= documentTitle %></title>\n',
'</head>\n', '</head>\n',
'<body><%= documentHTML %></body>\n', '<body><%= documentHTML %></body>\n',
'</html>'].join(""), '</html>'
].join(""),
sshProxy: SSH_PROXY_URL, sshProxy: SSH_PROXY_URL,
extensionSettings: {} extensionSettings: {}
}; };

View File

@ -14,17 +14,20 @@ define([
var sharing = {}; var sharing = {};
// Create a map with providerId: providerModule // Create a map with providerId: providerModule
var providerMap = _.chain( var providerMap = _.chain(arguments).map(function(argument) {
arguments return argument && argument.providerId && [
).map(function(argument) { argument.providerId,
return argument && argument.providerId && [argument.providerId, argument]; argument
];
}).compact().object().value(); }).compact().object().value();
// Used to populate the "Sharing" dropdown box // Used to populate the "Sharing" dropdown box
var lineTemplate = ['<div class="input-prepend">', var lineTemplate = [
'<div class="input-prepend">',
' <a href="<%= link %>" class="add-on" title="Sharing location"><i class="icon-link"></i></a>', ' <a href="<%= link %>" class="add-on" title="Sharing location"><i class="icon-link"></i></a>',
' <input class="span2" type="text" value="<%= link %>" readonly />', ' <input class="span2" type="text" value="<%= link %>" readonly />',
'</div>'].join(""); '</div>'
].join("");
sharing.refreshDocumentSharing = function(attributesList) { sharing.refreshDocumentSharing = function(attributesList) {
var linkList = $("#link-container .link-list").empty(); var linkList = $("#link-container .link-list").empty();
$("#link-container .no-link").show(); $("#link-container .no-link").show();
@ -44,7 +47,8 @@ define([
sharing.createLink = function(attributes, callback) { sharing.createLink = function(attributes, callback) {
var provider = providerMap[attributes.provider]; var provider = providerMap[attributes.provider];
// Don't create link if link already exists or provider is not compatible for sharing // Don't create link if link already exists or provider is not
// compatible for sharing
if(attributes.sharingLink !== undefined || provider === undefined if(attributes.sharingLink !== undefined || provider === undefined
// Or document is not published in markdown format // Or document is not published in markdown format
|| attributes.format != "markdown") { || attributes.format != "markdown") {
@ -58,7 +62,11 @@ define([
task.chain(); task.chain();
return; return;
} }
var url = [MAIN_URL, 'viewer.html?provider=', attributes.provider]; var url = [
MAIN_URL,
'viewer.html?provider=',
attributes.provider
];
_.each(provider.sharingAttributes, function(attributeName) { _.each(provider.sharingAttributes, function(attributeName) {
url.push('&'); url.push('&');
url.push(attributeName); url.push(attributeName);
@ -66,14 +74,10 @@ define([
url.push(encodeURIComponent(attributes[attributeName])); url.push(encodeURIComponent(attributes[attributeName]));
}); });
url = url.join(""); url = url.join("");
$.getJSON( $.getJSON("https://api-ssl.bitly.com/v3/shorten", {
"https://api-ssl.bitly.com/v3/shorten",
{
"access_token": BITLY_ACCESS_TOKEN, "access_token": BITLY_ACCESS_TOKEN,
"longUrl": url "longUrl": url
}, }, function(response) {
function(response)
{
if(response.data) { if(response.data) {
shortUrl = response.data.url; shortUrl = response.data.url;
attributes.sharingLink = shortUrl; attributes.sharingLink = shortUrl;
@ -83,8 +87,7 @@ define([
attributes.sharingLink = url; attributes.sharingLink = url;
} }
task.chain(); task.chain();
} });
);
}); });
function onFinish() { function onFinish() {
callback(); callback();

View File

@ -8,36 +8,25 @@ define([
var sshProvider = { var sshProvider = {
providerId: PROVIDER_SSH, providerId: PROVIDER_SSH,
providerName: "SSH server", providerName: "SSH server",
publishPreferencesInputIds: ["ssh-host", "ssh-port", "ssh-username", "ssh-password"] publishPreferencesInputIds: [
"ssh-host",
"ssh-port",
"ssh-username",
"ssh-password"
]
}; };
sshProvider.publish = function(publishAttributes, title, content, callback) { sshProvider.publish = function(publishAttributes, title, content, callback) {
sshHelper.upload( sshHelper.upload(publishAttributes.host, publishAttributes.port, publishAttributes.username, publishAttributes.password, publishAttributes.path, title, content, callback);
publishAttributes.host,
publishAttributes.port,
publishAttributes.username,
publishAttributes.password,
publishAttributes.path,
title,
content,
callback);
}; };
sshProvider.newPublishAttributes = function(event) { sshProvider.newPublishAttributes = function(event) {
var publishAttributes = {}; var publishAttributes = {};
publishAttributes.host = utils publishAttributes.host = utils.getInputTextValue("#input-publish-ssh-host", event, /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/);
.getInputTextValue( publishAttributes.port = utils.getInputIntValue("#input-publish-ssh-port", undefined, 0);
"#input-publish-ssh-host", publishAttributes.username = utils.getInputTextValue("#input-publish-ssh-username", event);
event, publishAttributes.password = utils.getInputTextValue("#input-publish-ssh-password", event);
/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/); publishAttributes.path = utils.getInputTextValue("#input-publish-file-path", event);
publishAttributes.port = utils.getInputIntValue(
"#input-publish-ssh-port", undefined, 0);
publishAttributes.username = utils.getInputTextValue(
"#input-publish-ssh-username", event);
publishAttributes.password = utils.getInputTextValue(
"#input-publish-ssh-password", event);
publishAttributes.path = utils.getInputTextValue(
"#input-publish-file-path", event);
if(event.isPropagationStopped()) { if(event.isPropagationStopped()) {
return undefined; return undefined;
} }

View File

@ -85,8 +85,7 @@ define([
localStorage.removeItem(fileIndex + ".title"); localStorage.removeItem(fileIndex + ".title");
localStorage.removeItem(fileIndex + ".publish"); localStorage.removeItem(fileIndex + ".publish");
localStorage.removeItem(fileIndex + ".content"); localStorage.removeItem(fileIndex + ".content");
localStorage["file.list"] = localStorage["file.list"].replace(";" localStorage["file.list"] = localStorage["file.list"].replace(";" + fileIndex + ";", ";");
+ fileIndex + ";", ";");
} }
}); });
version = "v3"; version = "v3";
@ -95,9 +94,7 @@ define([
// Upgrade from v3 to v4 // Upgrade from v3 to v4
if(version == "v3") { if(version == "v3") {
var currentFileIndex = localStorage["file.current"]; var currentFileIndex = localStorage["file.current"];
if(currentFileIndex !== undefined && if(currentFileIndex !== undefined && localStorage["file.list"].indexOf(";" + currentFileIndex + ";") === -1) {
localStorage["file.list"].indexOf(";" + currentFileIndex + ";") === -1)
{
localStorage.removeItem("file.current"); localStorage.removeItem("file.current");
} }
version = "v4"; version = "v4";

View File

@ -13,17 +13,16 @@ define([
var synchronizer = {}; var synchronizer = {};
// Create a map with providerId: providerModule // Create a map with providerId: providerModule
var providerMap = _.chain( var providerMap = _.chain(arguments).map(function(argument) {
arguments return argument && argument.providerId && [
).map(function(argument) { argument.providerId,
return argument && argument.providerId && [argument.providerId, argument]; argument
];
}).compact().object().value(); }).compact().object().value();
// Retrieve sync locations from localStorage // Retrieve sync locations from localStorage
_.each(fileSystem, function(fileDesc) { _.each(fileSystem, function(fileDesc) {
_.chain( _.chain(localStorage[fileDesc.fileIndex + ".sync"].split(";")).compact().each(function(syncIndex) {
localStorage[fileDesc.fileIndex + ".sync"].split(";")
).compact().each(function(syncIndex) {
var syncAttributes = JSON.parse(localStorage[syncIndex]); var syncAttributes = JSON.parse(localStorage[syncIndex]);
// Store syncIndex // Store syncIndex
syncAttributes.syncIndex = syncIndex; syncAttributes.syncIndex = syncIndex;
@ -56,13 +55,7 @@ define([
// Dequeue a synchronized location // Dequeue a synchronized location
var syncAttributes = uploadSyncAttributesList.pop(); var syncAttributes = uploadSyncAttributesList.pop();
// Use the specified provider to perform the upload // Use the specified provider to perform the upload
syncAttributes.provider.syncUp( syncAttributes.provider.syncUp(uploadContent, uploadContentCRC, uploadTitle, uploadTitleCRC, syncAttributes, function(error, uploadFlag) {
uploadContent,
uploadContentCRC,
uploadTitle,
uploadTitleCRC,
syncAttributes,
function(error, uploadFlag) {
if(uploadFlag === true) { if(uploadFlag === true) {
// If uploadFlag is true, request another upload cycle // If uploadFlag is true, request another upload cycle
uploadCycle = true; uploadCycle = true;
@ -76,8 +69,7 @@ define([
utils.storeAttributes(syncAttributes); utils.storeAttributes(syncAttributes);
} }
locationUp(callback); locationUp(callback);
} });
);
} }
// Recursive function to upload multiple files // Recursive function to upload multiple files
@ -99,7 +91,7 @@ define([
} }
// Get document title/content // Get document title/content
uploadContent = fileDesc.getContent(); uploadContent = fileDesc.content;
uploadContentCRC = utils.crc32(uploadContent); uploadContentCRC = utils.crc32(uploadContent);
uploadTitle = fileDesc.title; uploadTitle = fileDesc.title;
uploadTitleCRC = utils.crc32(uploadTitle); uploadTitleCRC = utils.crc32(uploadTitle);
@ -149,7 +141,8 @@ define([
function syncDown(callback) { function syncDown(callback) {
providerList = _.values(providerMap); providerList = _.values(providerMap);
providerDown(callback); providerDown(callback);
}; }
;
// Main entry point for synchronization // Main entry point for synchronization
var syncRunning = false; var syncRunning = false;
@ -226,14 +219,15 @@ define([
// Perform the provider's export // Perform the provider's export
var fileDesc = fileMgr.getCurrentFile(); var fileDesc = fileMgr.getCurrentFile();
provider.exportFile(event, fileDesc.title, fileDesc.getContent(), function(error, syncAttributes) { provider.exportFile(event, fileDesc.title, fileDesc.content, function(error, syncAttributes) {
if(error) { if(error) {
return; return;
} }
fileMgr.addSync(fileDesc, syncAttributes); fileMgr.addSync(fileDesc, syncAttributes);
}); });
// Store input values as preferences for next time we open the export dialog // Store input values as preferences for next time we open the
// export dialog
var exportPreferences = {}; var exportPreferences = {};
_.each(provider.exportPreferencesInputIds, function(inputId) { _.each(provider.exportPreferencesInputIds, function(inputId) {
exportPreferences[inputId] = $("#input-sync-export-" + inputId).val(); exportPreferences[inputId] = $("#input-sync-export-" + inputId).val();
@ -243,7 +237,7 @@ define([
// Provider's manual export button // Provider's manual export button
$(".action-sync-manual-" + provider.providerId).click(function(event) { $(".action-sync-manual-" + provider.providerId).click(function(event) {
var fileDesc = fileMgr.getCurrentFile(); var fileDesc = fileMgr.getCurrentFile();
provider.exportManual(event, fileDesc.title, fileDesc.getContent(), function(error, syncAttributes) { provider.exportManual(event, fileDesc.title, fileDesc.content, function(error, syncAttributes) {
if(error) { if(error) {
return; return;
} }

View File

@ -54,9 +54,7 @@ define([
} }
function getVerifier() { function getVerifier() {
localStorage.removeItem("tumblrVerifier"); localStorage.removeItem("tumblrVerifier");
authWindow = utils.popupWindow( authWindow = utils.popupWindow('tumblr-oauth-client.html?oauth_token=' + oauth_object.oauth_token, 'stackedit-tumblr-oauth', 800, 600);
'tumblr-oauth-client.html?oauth_token=' + oauth_object.oauth_token,
'stackedit-tumblr-oauth', 800, 600);
authWindow.focus(); authWindow.focus();
intervalId = setInterval(function() { intervalId = setInterval(function() {
if(authWindow.closed === true) { if(authWindow.closed === true) {
@ -156,7 +154,8 @@ define([
errorMsg = "Access to Tumblr account is not authorized."; errorMsg = "Access to Tumblr account is not authorized.";
task.retry(new Error(errorMsg), 1); task.retry(new Error(errorMsg), 1);
return; return;
} else if (error.code <= 0) { }
else if(error.code <= 0) {
core.setOffline(); core.setOffline();
errorMsg = "|stopPublish"; errorMsg = "|stopPublish";
} }

View File

@ -8,35 +8,25 @@ define([
var tumblrProvider = { var tumblrProvider = {
providerId: PROVIDER_TUMBLR, providerId: PROVIDER_TUMBLR,
providerName: "Tumblr", providerName: "Tumblr",
publishPreferencesInputIds: ["tumblr-hostname"] publishPreferencesInputIds: [
"tumblr-hostname"
]
}; };
tumblrProvider.publish = function(publishAttributes, title, content, callback) { tumblrProvider.publish = function(publishAttributes, title, content, callback) {
tumblrHelper.upload( tumblrHelper.upload(publishAttributes.blogHostname, publishAttributes.postId, publishAttributes.tags, publishAttributes.format == "markdown" ? "markdown" : "html", title, content, function(error, postId) {
publishAttributes.blogHostname,
publishAttributes.postId,
publishAttributes.tags,
publishAttributes.format == "markdown" ? "markdown" : "html",
title,
content,
function(error, postId) {
if(error) { if(error) {
callback(error); callback(error);
return; return;
} }
publishAttributes.postId = postId; publishAttributes.postId = postId;
callback(); callback();
} });
);
}; };
tumblrProvider.newPublishAttributes = function(event) { tumblrProvider.newPublishAttributes = function(event) {
var publishAttributes = {}; var publishAttributes = {};
publishAttributes.blogHostname = utils publishAttributes.blogHostname = utils.getInputTextValue("#input-publish-tumblr-hostname", event, /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/);
.getInputTextValue(
"#input-publish-tumblr-hostname",
event,
/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/);
publishAttributes.postId = utils.getInputTextValue("#input-publish-postid"); publishAttributes.postId = utils.getInputTextValue("#input-publish-postid");
publishAttributes.tags = utils.getInputTextValue("#input-publish-tags"); publishAttributes.tags = utils.getInputTextValue("#input-publish-tags");
if(event.isPropagationStopped()) { if(event.isPropagationStopped()) {

View File

@ -11,7 +11,8 @@ define([
var regex = new RegExp(name + "=(.+?)(&|$)"); var regex = new RegExp(name + "=(.+?)(&|$)");
try { try {
return decodeURIComponent(regex.exec(location.search)[1]); return decodeURIComponent(regex.exec(location.search)[1]);
} catch (e) { }
catch (e) {
return undefined; return undefined;
} }
}; };
@ -54,8 +55,7 @@ define([
} }
// trim // trim
value = utils.trim(value); value = utils.trim(value);
if((value.length === 0) if((value.length === 0) || (validationRegex !== undefined && !value.match(validationRegex))) {
|| (validationRegex !== undefined && !value.match(validationRegex))) {
inputError(element, event); inputError(element, event);
return undefined; return undefined;
} }
@ -70,9 +70,7 @@ define([
return undefined; return undefined;
} }
value = parseInt(value); value = parseInt(value);
if((value === NaN) if((value === NaN) || (min !== undefined && value < min) || (max !== undefined && value > max)) {
|| (min !== undefined && value < min)
|| (max !== undefined && value > max)) {
inputError(element, event); inputError(element, event);
return undefined; return undefined;
} }
@ -113,8 +111,7 @@ define([
// Slug function // Slug function
utils.slugify = function(text) { utils.slugify = function(text) {
return text.toLowerCase() return text.toLowerCase().replace(/\s+/g, '-') // Replace spaces with -
.replace(/\s+/g, '-') // Replace spaces with -
.replace(/[^\w\-]+/g, '') // Remove all non-word chars .replace(/[^\w\-]+/g, '') // Remove all non-word chars
.replace(/\-\-+/g, '-') // Replace multiple - with single - .replace(/\-\-+/g, '-') // Replace multiple - with single -
.replace(/^-+/, '') // Trim - from start of text .replace(/^-+/, '') // Trim - from start of text
@ -135,6 +132,63 @@ define([
return url; return url;
}; };
// Create an centered popup window
utils.popupWindow = function(url, title, width, height) {
var left = (screen.width / 2) - (width / 2);
var top = (screen.height / 2) - (height / 2);
return window.open(url, title, [
'toolbar=no, ',
'location=no, ',
'directories=no, ',
'status=no, ',
'menubar=no, ',
'scrollbars=no, ',
'resizable=no, ',
'copyhistory=no, ',
'width=' + width + ', ',
'height=' + height + ', ',
'top=' + top + ', ',
'left=' + left
].join(""));
};
// Export data on disk
utils.saveAs = function(content, filename) {
if(saveAs !== undefined) {
var blob = new Blob([
content
], {
type: "text/plain;charset=utf-8"
});
saveAs(blob, filename);
}
else {
var uriContent = "data:application/octet-stream;base64," + utils.encodeBase64(content);
window.open(uriContent, 'file');
}
};
// Generates a random string
utils.randomString = function() {
return _.random(4294967296).toString(36);
};
// Time shared by others modules
utils.updateCurrentTime = function() {
utils.currentTime = new Date().getTime();
};
utils.updateCurrentTime();
// Serialize sync/publish attributes and store it in the fileStorage
utils.storeAttributes = function(attributes) {
var storeIndex = attributes.syncIndex || attributes.publishIndex;
// Don't store sync/publish index
attributes = _.omit(attributes, "syncIndex", "publishIndex");
// Store providerId instead of provider
attributes.provider = attributes.provider.providerId;
localStorage[storeIndex] = JSON.stringify(attributes);
};
// Base64 conversion // Base64 conversion
utils.encodeBase64 = function(str) { utils.encodeBase64 = function(str) {
if(str.length === 0) { if(str.length === 0) {
@ -153,7 +207,8 @@ define([
if('%' !== char) { if('%' !== char) {
bytes.push(char.charCodeAt(0)); bytes.push(char.charCodeAt(0));
} else { }
else {
char = str[offset] + str[offset + 1]; char = str[offset] + str[offset + 1];
bytes.push(parseInt(char, 16)); bytes.push(parseInt(char, 16));
offset += 2; offset += 2;
@ -179,70 +234,275 @@ define([
switch (bytes.length - imax) { switch (bytes.length - imax) {
case 1: case 1:
b10 = bytes[i] << 16; b10 = bytes[i] << 16;
x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + padchar + padchar);
padchar + padchar);
break; break;
case 2: case 2:
b10 = (bytes[i] << 16) | (bytes[i + 1] << 8); b10 = (bytes[i] << 16) | (bytes[i + 1] << 8);
x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + alpha.charAt((b10 >> 6) & 0x3f) + padchar);
alpha.charAt((b10 >> 6) & 0x3f) + padchar);
break; break;
} }
return x.join(''); return x.join('');
}; };
// CRC32 algorithm // CRC32 algorithm
var mHash = [ 0, 1996959894, 3993919788, 2567524794, 124634137, var mHash = [
1886057615, 3915621685, 2657392035, 249268274, 2044508324, 0,
3772115230, 2547177864, 162941995, 2125561021, 3887607047, 1996959894,
2428444049, 498536548, 1789927666, 4089016648, 2227061214, 3993919788,
450548861, 1843258603, 4107580753, 2211677639, 325883990, 2567524794,
1684777152, 4251122042, 2321926636, 335633487, 1661365465, 124634137,
4195302755, 2366115317, 997073096, 1281953886, 3579855332, 1886057615,
2724688242, 1006888145, 1258607687, 3524101629, 2768942443, 3915621685,
901097722, 1119000684, 3686517206, 2898065728, 853044451, 2657392035,
1172266101, 3705015759, 2882616665, 651767980, 1373503546, 249268274,
3369554304, 3218104598, 565507253, 1454621731, 3485111705, 2044508324,
3099436303, 671266974, 1594198024, 3322730930, 2970347812, 3772115230,
795835527, 1483230225, 3244367275, 3060149565, 1994146192, 2547177864,
31158534, 2563907772, 4023717930, 1907459465, 112637215, 162941995,
2680153253, 3904427059, 2013776290, 251722036, 2517215374, 2125561021,
3775830040, 2137656763, 141376813, 2439277719, 3865271297, 3887607047,
1802195444, 476864866, 2238001368, 4066508878, 1812370925, 2428444049,
453092731, 2181625025, 4111451223, 1706088902, 314042704, 498536548,
2344532202, 4240017532, 1658658271, 366619977, 2362670323, 1789927666,
4224994405, 1303535960, 984961486, 2747007092, 3569037538, 4089016648,
1256170817, 1037604311, 2765210733, 3554079995, 1131014506, 2227061214,
879679996, 2909243462, 3663771856, 1141124467, 855842277, 450548861,
2852801631, 3708648649, 1342533948, 654459306, 3188396048, 1843258603,
3373015174, 1466479909, 544179635, 3110523913, 3462522015, 4107580753,
1591671054, 702138776, 2966460450, 3352799412, 1504918807, 2211677639,
783551873, 3082640443, 3233442989, 3988292384, 2596254646, 325883990,
62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523, 1684777152,
3814918930, 2489596804, 225274430, 2053790376, 3826175755, 4251122042,
2466906013, 167816743, 2097651377, 4027552580, 2265490386, 2321926636,
503444072, 1762050814, 4150417245, 2154129355, 426522225, 335633487,
1852507879, 4275313526, 2312317920, 282753626, 1742555852, 1661365465,
4189708143, 2394877945, 397917763, 1622183637, 3604390888, 4195302755,
2714866558, 953729732, 1340076626, 3518719985, 2797360999, 2366115317,
1068828381, 1219638859, 3624741850, 2936675148, 906185462, 997073096,
1090812512, 3747672003, 2825379669, 829329135, 1181335161, 1281953886,
3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3579855332,
3138078467, 570562233, 1426400815, 3317316542, 2998733608, 2724688242,
733239954, 1555261956, 3268935591, 3050360625, 752459403, 1006888145,
1541320221, 2607071920, 3965973030, 1969922972, 40735498, 1258607687,
2617837225, 3943577151, 1913087877, 83908371, 2512341634, 3524101629,
3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2768942443,
2094854071, 198958881, 2262029012, 4057260610, 1759359992, 901097722,
534414190, 2176718541, 4139329115, 1873836001, 414664567, 1119000684,
2282248934, 4279200368, 1711684554, 285281116, 2405801727, 3686517206,
4167216745, 1634467795, 376229701, 2685067896, 3608007406, 2898065728,
1308918612, 956543938, 2808555105, 3495958263, 1231636301, 853044451,
1047427035, 2932959818, 3654703836, 1088359270, 936918000, 1172266101,
2847714899, 3736837829, 1202900863, 817233897, 3183342108, 3705015759,
3401237130, 1404277552, 615818150, 3134207493, 3453421203, 2882616665,
1423857449, 601450431, 3009837614, 3294710456, 1567103746, 651767980,
711928724, 3020668471, 3272380065, 1510334235, 755167117 ]; 1373503546,
3369554304,
3218104598,
565507253,
1454621731,
3485111705,
3099436303,
671266974,
1594198024,
3322730930,
2970347812,
795835527,
1483230225,
3244367275,
3060149565,
1994146192,
31158534,
2563907772,
4023717930,
1907459465,
112637215,
2680153253,
3904427059,
2013776290,
251722036,
2517215374,
3775830040,
2137656763,
141376813,
2439277719,
3865271297,
1802195444,
476864866,
2238001368,
4066508878,
1812370925,
453092731,
2181625025,
4111451223,
1706088902,
314042704,
2344532202,
4240017532,
1658658271,
366619977,
2362670323,
4224994405,
1303535960,
984961486,
2747007092,
3569037538,
1256170817,
1037604311,
2765210733,
3554079995,
1131014506,
879679996,
2909243462,
3663771856,
1141124467,
855842277,
2852801631,
3708648649,
1342533948,
654459306,
3188396048,
3373015174,
1466479909,
544179635,
3110523913,
3462522015,
1591671054,
702138776,
2966460450,
3352799412,
1504918807,
783551873,
3082640443,
3233442989,
3988292384,
2596254646,
62317068,
1957810842,
3939845945,
2647816111,
81470997,
1943803523,
3814918930,
2489596804,
225274430,
2053790376,
3826175755,
2466906013,
167816743,
2097651377,
4027552580,
2265490386,
503444072,
1762050814,
4150417245,
2154129355,
426522225,
1852507879,
4275313526,
2312317920,
282753626,
1742555852,
4189708143,
2394877945,
397917763,
1622183637,
3604390888,
2714866558,
953729732,
1340076626,
3518719985,
2797360999,
1068828381,
1219638859,
3624741850,
2936675148,
906185462,
1090812512,
3747672003,
2825379669,
829329135,
1181335161,
3412177804,
3160834842,
628085408,
1382605366,
3423369109,
3138078467,
570562233,
1426400815,
3317316542,
2998733608,
733239954,
1555261956,
3268935591,
3050360625,
752459403,
1541320221,
2607071920,
3965973030,
1969922972,
40735498,
2617837225,
3943577151,
1913087877,
83908371,
2512341634,
3803740692,
2075208622,
213261112,
2463272603,
3855990285,
2094854071,
198958881,
2262029012,
4057260610,
1759359992,
534414190,
2176718541,
4139329115,
1873836001,
414664567,
2282248934,
4279200368,
1711684554,
285281116,
2405801727,
4167216745,
1634467795,
376229701,
2685067896,
3608007406,
1308918612,
956543938,
2808555105,
3495958263,
1231636301,
1047427035,
2932959818,
3654703836,
1088359270,
936918000,
2847714899,
3736837829,
1202900863,
817233897,
3183342108,
3401237130,
1404277552,
615818150,
3134207493,
3453421203,
1423857449,
601450431,
3009837614,
3294710456,
1567103746,
711928724,
3020668471,
3272380065,
1510334235,
755167117
];
utils.crc32 = function(str) { utils.crc32 = function(str) {
var n = 0, crc = -1; var n = 0, crc = -1;
for ( var i = 0; i < str.length; i++) { for ( var i = 0; i < str.length; i++) {
@ -256,58 +516,5 @@ define([
return crc.toString(16); return crc.toString(16);
}; };
// Create an centered popup window
utils.popupWindow = function(url, title, width, height) {
var left = (screen.width / 2) - (width / 2);
var top = (screen.height / 2) - (height / 2);
return window.open(
url,
title,
'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='
+ width
+ ', height='
+ height
+ ', top='
+ top
+ ', left='
+ left);
};
// Export data on disk
utils.saveAs = function(content, filename) {
if(saveAs !== undefined) {
var blob = new Blob([content], {type: "text/plain;charset=utf-8"});
saveAs(blob, filename);
}
else {
var uriContent = "data:application/octet-stream;base64,"
+ utils.encodeBase64(content);
window.open(uriContent, 'file');
}
};
// Generates a random string
utils.randomString = function() {
return _.random(4294967296).toString(36);
};
// Time shared by others modules
utils.updateCurrentTime = function() {
utils.currentTime = new Date().getTime();
};
utils.updateCurrentTime();
// Serialize sync/publish attributes and store it in the fileStorage
utils.storeAttributes = function(attributes) {
var storeIndex = attributes.syncIndex || attributes.publishIndex;
// Don't store sync/publish index
attributes = _.omit(attributes, "syncIndex", "publishIndex");
// Store providerId instead of provider
attributes.provider = attributes.provider.providerId;
localStorage[storeIndex] = JSON.stringify(attributes);
};
return utils; return utils;
}); });

View File

@ -38,9 +38,7 @@ define([
var code = undefined; var code = undefined;
function getCode() { function getCode() {
localStorage.removeItem("wordpressCode"); localStorage.removeItem("wordpressCode");
authWindow = utils.popupWindow( authWindow = utils.popupWindow('wordpress-oauth-client.html?client_id=' + WORDPRESS_CLIENT_ID, 'stackedit-wordpress-oauth', 960, 600);
'wordpress-oauth-client.html?client_id=' + WORDPRESS_CLIENT_ID,
'stackedit-wordpress-oauth', 960, 600);
authWindow.focus(); authWindow.focus();
intervalId = setInterval(function() { intervalId = setInterval(function() {
if(authWindow.closed === true) { if(authWindow.closed === true) {
@ -153,7 +151,8 @@ define([
errorMsg = "Access to WordPress account is not authorized."; errorMsg = "Access to WordPress account is not authorized.";
task.retry(new Error(errorMsg), 1); task.retry(new Error(errorMsg), 1);
return; return;
} else if (error.code <= 0) { }
else if(error.code <= 0) {
core.setOffline(); core.setOffline();
errorMsg = "|stopPublish"; errorMsg = "|stopPublish";
} }

View File

@ -9,34 +9,25 @@ define([
providerId: PROVIDER_WORDPRESS, providerId: PROVIDER_WORDPRESS,
providerName: "WordPress", providerName: "WordPress",
defaultPublishFormat: "html", defaultPublishFormat: "html",
publishPreferencesInputIds: ["wordpress-site"] publishPreferencesInputIds: [
"wordpress-site"
]
}; };
wordpressProvider.publish = function(publishAttributes, title, content, callback) { wordpressProvider.publish = function(publishAttributes, title, content, callback) {
wordpressHelper.upload( wordpressHelper.upload(publishAttributes.site, publishAttributes.postId, publishAttributes.tags, title, content, function(error, postId) {
publishAttributes.site,
publishAttributes.postId,
publishAttributes.tags,
title,
content,
function(error, postId) {
if(error) { if(error) {
callback(error); callback(error);
return; return;
} }
publishAttributes.postId = postId; publishAttributes.postId = postId;
callback(); callback();
} });
);
}; };
wordpressProvider.newPublishAttributes = function(event) { wordpressProvider.newPublishAttributes = function(event) {
var publishAttributes = {}; var publishAttributes = {};
publishAttributes.site = utils publishAttributes.site = utils.getInputTextValue("#input-publish-wordpress-site", event, /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/);
.getInputTextValue(
"#input-publish-wordpress-site",
event,
/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/);
publishAttributes.postId = utils.getInputTextValue("#input-publish-postid"); publishAttributes.postId = utils.getInputTextValue("#input-publish-postid");
publishAttributes.tags = utils.getInputTextValue("#input-publish-tags"); publishAttributes.tags = utils.getInputTextValue("#input-publish-tags");
if(event.isPropagationStopped()) { if(event.isPropagationStopped()) {

View File

@ -0,0 +1,267 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="11">
<profile kind="CodeFormatterProfile" name="JsFormatter" version="11">
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_annotation" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.format_header" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_object_initializer" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_between_type_declarations" value="0"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_assignment" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.continuation_indentation_for_objlit_initializer" value="1"/>
<setting id="org.eclipse.wst.jsdt.core.compiler.compliance" value="1.5"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_closing_brace_in_objlit_initializer" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.wrap_before_binary_operator" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.continuation_indentation_for_array_initializer" value="1"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_expressions_in_array_initializer" value="49"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_comma_in_objlit_initializer" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_objlit_initializer" value="end_of_line"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.compiler.source" value="1.5"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.continuation_indentation" value="1"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_conditional_expression" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.indent_parameter_description" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_member_type" value="1"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_enum_constants" value="0"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_binary_expression" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.lineSplit" value="999"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.compiler.codegen.targetPlatform" value="1.5"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.keep_empty_objlit_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.wst.jsdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_colon_in_object_initializer" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.line_length" value="80"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_after_opening_brace_in_objlit_initializer" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
<setting id="org.eclipse.wst.jsdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
</profile>
</profiles>