From 95ff8f58858c5a2e2f9f7f21bb9539d4c8f089bf Mon Sep 17 00:00:00 2001 From: avishon Date: Mon, 7 Oct 2019 07:41:23 +0300 Subject: [PATCH] Refactor and modularize `processSection.js` #71 --- spec/javascripts/replacement_spec.js | 16 ++++--- src/inlineMarkdownEditor.js | 6 +++ src/insertEditLink.js | 38 ++++++++------- src/insertFormIfMarkdown.js | 12 +++++ src/onComplete.js | 28 +++++------ src/onEdit.js | 25 ++++++++++ src/prepareAndSendSectionForm.js | 6 +++ src/processSection.js | 70 +++++----------------------- src/submitSectionForm.js | 21 +++++++++ 9 files changed, 127 insertions(+), 95 deletions(-) create mode 100644 src/insertFormIfMarkdown.js create mode 100644 src/onEdit.js create mode 100644 src/prepareAndSendSectionForm.js create mode 100644 src/submitSectionForm.js diff --git a/spec/javascripts/replacement_spec.js b/spec/javascripts/replacement_spec.js index 93537d9..3e6610b 100644 --- a/spec/javascripts/replacement_spec.js +++ b/spec/javascripts/replacement_spec.js @@ -32,6 +32,7 @@ describe("Replacement functions", function() { }); it("sends exactly matching original text and 'before' parameters", function(done) { + fixture = loadFixtures('index.html'); var html = "## Headings [with](/links)"; var new_html = "## Headings [with](/links) and other things"; @@ -42,23 +43,24 @@ describe("Replacement functions", function() { selector: '.markdown', submitSectionForm: submitSectionForm }); - - function submitSectionForm(e, before, after, o) { - expect(before).toBe(html); - expect(after).toBe(new_html); - expect(before).not.toBe(after); + + function submitSectionForm(e, props) { + expect(props.originalSectionMarkdown).toBe(html); + expect(props.changes).toBe(new_html); + expect(props.originalSectionMarkdown).not.toBe(props.changes); done(); } - + // generate an editor by clicking the pencil button $('.inline-edit-btn').click(); $('.inline-edit-form textarea').html(new_html); - + // trigger a section save: $('.inline-edit-form:last button.submit').click(); expect(editor.options.submitSectionForm).toBe(submitSectionForm); expect(editor.options.originalMarkdown).toBe(html); + }); }); diff --git a/src/inlineMarkdownEditor.js b/src/inlineMarkdownEditor.js index 9594891..945491d 100644 --- a/src/inlineMarkdownEditor.js +++ b/src/inlineMarkdownEditor.js @@ -6,6 +6,11 @@ inlineMarkdownEditor = function inlineMarkdownEditor(o) { o.onFail = o.onFail || require('./onFail.js'); o.isEditable = o.isEditable || require('./isEditable.js'); o.processSections = require('./processSections.js'); + o.onEdit = o.onEdit || require('./onEdit.js'); + o.prepareAndSendSectionForm = o.prepareAndSendSectionForm || require('./prepareAndSendSectionForm.js'); + o.submitSectionForm = o.submitSectionForm || require('./submitSectionForm.js'); + o.insertFormIfMarkdown = o.insertFormIfMarkdown || require('./insertFormIfMarkdown.js'); + var el = $(o.selector); o.originalMarkdown = el.html(); o.preProcessor = o.preProcessor || function(m) { return m; } @@ -29,3 +34,4 @@ inlineMarkdownEditor = function inlineMarkdownEditor(o) { }; } module.exports = inlineMarkdownEditor; + diff --git a/src/insertEditLink.js b/src/insertEditLink.js index 8772459..e203f35 100644 --- a/src/insertEditLink.js +++ b/src/insertEditLink.js @@ -1,23 +1,29 @@ -module.exports = function insertEditLink(uniqueId, el, form, onEdit, editor, o) { +module.exports = function insertEditLink(props) { + var uniqueId = props.uniqueId; + var options = props.options; var editBtns = ""; + editBtns += ""; - editBtns += ""; - if (o.extraButtons) { - Object.keys(o.extraButtons).forEach(function(key, index) { - editBtns += ""; - }); + editBtns += ""; + if (options.extraButtons) { + Object.keys(options.extraButtons).forEach(function(key, index) { + editBtns += ""; + }); } editBtns += ""; - el.append(editBtns); - if (o.extraButtons) { - Object.keys(o.extraButtons).forEach(function(key, index) { - // run respective functions and pass in the elements - o.extraButtons[key]($('.inline-edit-btn-' + uniqueId + '-' + key), uniqueId); - }); + props.el.append(editBtns); + if (options.extraButtons) { + Object.keys(options.extraButtons).forEach(function(key, index) { + // run respective functions and pass in the elements + options.extraButtons[key]($('.inline-edit-btn-' + uniqueId + '-' + key), uniqueId); + }); } $('.inline-edit-btn-editor-' + uniqueId).click(function inlineEditLinkClick(e) { - e.preventDefault(); - form.toggle(); - if (onEdit) onEdit(); // callback + e.preventDefault(); + props.form.toggle(); + if (props.useOnEdit) { + props.useOnEdit = false; // running once for each element + options.onEdit(props); // callback + } }); -} +} \ No newline at end of file diff --git a/src/insertFormIfMarkdown.js b/src/insertFormIfMarkdown.js new file mode 100644 index 0000000..33be8d0 --- /dev/null +++ b/src/insertFormIfMarkdown.js @@ -0,0 +1,12 @@ +module.exports = function insertFormIfMarkdown(props) { + var options = props.options; + + if (options.isEditable(props.filteredMarkdown, options.preProcessor(options.originalMarkdown))) { + var formHtml = options.buildSectionForm(props.uniqueId, props.filteredMarkdown); + props.el.after(formHtml); + + props.form = $('#' + props.uniqueId); + options.insertEditLink(props); + } + +} \ No newline at end of file diff --git a/src/onComplete.js b/src/onComplete.js index a229014..1176817 100644 --- a/src/onComplete.js +++ b/src/onComplete.js @@ -1,16 +1,16 @@ -module.exports = function onComplete(response, markdown, html, el, uniqueId, form, o) { - var message = form.find('.section-message'); - if (response === 200) { - message.html(''); - //markdown = changes; - $('#' + uniqueId + ' textarea').val(''); - form.hide(); - // replace the section but reset our html and markdown - html = o.defaultMarkdown(markdown); - el.html(html); - o.insertEditLink(uniqueId, el, form, false, false, o); - if (o.postProcessor) o.postProcessor(el); // add #hashtag and @callout links, extra CSS and deep links +module.exports = function onComplete(props) { + var message = props.form.find('.section-message'); + if (props.response === 200) { + message.html(''); + + props.form.hide(); + + // replace the section but reset our html and markdown + props.html = props.options.defaultMarkdown(props.changes); + props.el.html(props.html); + props.options.insertEditLink(props); + if (props.options.postProcessor) props.options.postProcessor(props.el); // add #hashtag and @callout links, extra CSS and deep links } else { - message.html('There was an error -- the wiki page may have changed while you were editing; save your content in the clipboard and try refreshing the page.'); + message.html('There was an error -- the wiki page may have changed while you were editing; save your content in the clipboard and try refreshing the page.'); } -} +} \ No newline at end of file diff --git a/src/onEdit.js b/src/onEdit.js new file mode 100644 index 0000000..eb115e3 --- /dev/null +++ b/src/onEdit.js @@ -0,0 +1,25 @@ +module.exports = function onEdit(props) { + var editor; + var options = props.options; + var uniqueId = props.uniqueId; + + if (options.wysiwyg && $('#' + props.uniqueId).find('.wk-container').length === 0) { + // insert rich editor + var editorOptions = options.editorOptions || {}; + editorOptions.textarea = $('#' + uniqueId + ' textarea')[0]; + editorOptions.tagsModule = (editorOptions.tagsModule === true); // disable this to not require Bloodhound, unless overridden + editor = new PL.Editor(editorOptions); + } + + var cancelBtn = props.form.find('.cancel'); + var submitBtn = props.form.find('button.submit'); + + cancelBtn.click(function inlineEditCancelClick(e) { + e.preventDefault(); + props.form.hide(); + }); + submitBtn.click(function(e) { + options.prepareAndSendSectionForm(props, editor, e); + }); + +} \ No newline at end of file diff --git a/src/prepareAndSendSectionForm.js b/src/prepareAndSendSectionForm.js new file mode 100644 index 0000000..84a114d --- /dev/null +++ b/src/prepareAndSendSectionForm.js @@ -0,0 +1,6 @@ +module.exports = function prepareAndSendSectionForm(props, editor, e) { + var message = $('#' + props.uniqueId + ' .section-message'); + message.html(''); + props.changes = editor ? editor.richTextModule.value() : props.form.find("textarea").val(); + props.options.submitSectionForm(e, props); +} \ No newline at end of file diff --git a/src/processSection.js b/src/processSection.js index 1895794..8594c44 100644 --- a/src/processSection.js +++ b/src/processSection.js @@ -1,7 +1,7 @@ module.exports = function processSection(markdown, o) { var html, - randomNum = parseInt(Math.random() * 10000), - uniqueId = "section-form-" + randomNum, + randomNum = parseInt(Math.random() * 10000), + uniqueId = "section-form-" + randomNum, filteredMarkdown = markdown; var originalSectionMarkdown = markdown; @@ -13,62 +13,16 @@ module.exports = function processSection(markdown, o) { el.append(html); if (o.postProcessor) o.postProcessor(el); - var form = insertFormIfMarkdown(filteredMarkdown, el, uniqueId); - var message = $('#' + uniqueId + ' .section-message'); - function insertFormIfMarkdown(_markdown, el, uniqueId) { - if (o.isEditable(_markdown, o.preProcessor(o.originalMarkdown))) { - var formHtml = o.buildSectionForm(uniqueId, _markdown); - el.after(formHtml); - var _form = $('#' + uniqueId); - o.insertEditLink(uniqueId, el, _form, onEdit, false, o); - // plan for swappable editors; will need to specify both constructor and onEditorSubmit - function onEdit() { - var editor; - if (o.wysiwyg && $('#' + uniqueId).find('.wk-container').length === 0) { - // insert rich editor - var editorOptions = o.editorOptions || {}; - editorOptions.textarea = $('#' + uniqueId + ' textarea')[0]; - editorOptions.tagsModule = (editorOptions.tagsModule === true); // disable this to not require Bloodhound, unless overridden - editor = new PL.Editor(editorOptions); - } - _form.find('.cancel').click(function inlineEditCancelClick(e) { - e.preventDefault(); - _form.hide(); - }); - _form.find('button.submit').click(function(e) { - prepareAndSendSectionForm(e, _form, editor, originalSectionMarkdown); - }); - } - } + o.insertFormIfMarkdown({ + uniqueId: uniqueId, + el: el, + filteredMarkdown: filteredMarkdown, + originalSectionMarkdown: originalSectionMarkdown, + useOnEdit: true, + html: html, + options: o + }); - function prepareAndSendSectionForm(e, __form, _editor, _markdown) { - message.html(''); - changes = _editor ? _editor.richTextModule.value() : __form.find("textarea").val(); - o.submitSectionForm(e, _markdown, changes, o, el, __form); - } - - // provide overridable default; though we have to explicitly pass in - // all this stuff so the section forms don't get crossed - o.submitSectionForm = o.submitSectionForm || function submitSectionForm(e, before, after, o, _el, __form) { - e.preventDefault(); - $.post(o.replaceUrl, { - before: before, // encodeURI(before) - after: after // encodeURI(after) - }) - .done(function onComplete(result, success, xhr) { - if (result == "false") { - o.onFail(result, uniqueId); - } else { - // we should need fewer things here: - o.onComplete(xhr.status, after, html, _el, uniqueId, __form, o); - } - }).fail(function onFail(response) { - o.onFail(response, uniqueId); - }); // these don't work? - } - - return _form; - } -} +} \ No newline at end of file diff --git a/src/submitSectionForm.js b/src/submitSectionForm.js new file mode 100644 index 0000000..28c6ad8 --- /dev/null +++ b/src/submitSectionForm.js @@ -0,0 +1,21 @@ +module.exports = function submitSectionForm(e, props) { + var options = props.options; + var uniqueId = props.uniqueId; + + e.preventDefault(); + $.post(options.replaceUrl, { + before: props.originalSectionMarkdown, // encodeURI(before) + after: props.changes // encodeURI(after) + }) + .done(function onComplete(result, success, xhr) { + if (result == "false") { + options.onFail(result, uniqueId); + } else { + // we should need fewer things here: + props.response = xhr.status; + options.onComplete(props); + } + }).fail(function onFail(response) { + options.onFail(response, uniqueId); + }); // these don't work? +} \ No newline at end of file