diff --git a/README.md b/README.md
index d69b8c3..7b909d7 100644
--- a/README.md
+++ b/README.md
@@ -2,10 +2,19 @@
tinymce Editor 4.x / 5.x FootNotes Plugin.
> **JQuery is required (tinymce 4.x)**
+This is a fork of https://github.com/rainywalker/footNotes. Contrary to the original version, this one allows formatting footnotes with HTML (using tinyMCE) and it also supports using double quotes in footnotes. Note: the HTML formatting only works for tinyMCE 4.x, the 5.x plugin is unchanged from the original.
+
+The footnote plugin button in the menu bar of tinyMCE:
+
+
+
+The footnote plugin dialog:
+
+
## Principle
-The text entered in the insert contents window is stored in the 'data-content' attribute
+The text entered in the insert contents window is stored in the 'data-content' attribute. Double quotes and single quotes or apostrophes are replaced with their respective HTML entities. Double quotes in HTML attributes (e.g. the href for a link) will be replaced with single quotes so they don't break the data-content attribute in which they are contained.
````
//html of button inserted in editor
diff --git a/screenshot_dialog.png b/screenshot_dialog.png
new file mode 100644
index 0000000..d201aeb
Binary files /dev/null and b/screenshot_dialog.png differ
diff --git a/screenshot_menu.png b/screenshot_menu.png
new file mode 100644
index 0000000..0d35bb4
Binary files /dev/null and b/screenshot_menu.png differ
diff --git a/tinymce4.x/footnotes/img/footnotes.png b/tinymce4.x/footnotes/img/footnotes.png
index 7715744..25a5bb8 100644
Binary files a/tinymce4.x/footnotes/img/footnotes.png and b/tinymce4.x/footnotes/img/footnotes.png differ
diff --git a/tinymce4.x/footnotes/plugin.js b/tinymce4.x/footnotes/plugin.js
index 1e8dea7..769b232 100644
--- a/tinymce4.x/footnotes/plugin.js
+++ b/tinymce4.x/footnotes/plugin.js
@@ -1,5 +1,5 @@
tinymce.PluginManager.add('footnotes', function(editor) {
-
+ var footnoteText = null;
function replaceTmpl(str, data) {
var result = str;
for (var key in data) {
@@ -9,8 +9,10 @@ tinymce.PluginManager.add('footnotes', function(editor) {
}
function showDialog() {
- var selectedNode = editor.selection.getNode(), name = '',
- isFootNotes = selectedNode.tagName == 'SPAN' && editor.dom.getAttrib(selectedNode, 'class') === 'fnoteWrap';
+ var selectedNode = editor.selection.getNode();
+ var selectedRange = editor.selection.getRng().endContainer;
+ var name = '';
+ var isFootNotes = selectedNode.tagName == 'SPAN' && editor.dom.getAttrib(selectedNode, 'class') === 'fnoteWrap';
var selectIndex = (function(){
if (selectedNode.className == 'fnoteWrap') {
@@ -27,7 +29,7 @@ tinymce.PluginManager.add('footnotes', function(editor) {
}
editor.windowManager.open({
- title: "Insert a contents",
+ title: "Insert contents for footnote",
id: 'footnote-dialog',
body: {
type: 'textbox',
@@ -35,17 +37,18 @@ tinymce.PluginManager.add('footnotes', function(editor) {
multiline: true,
minWidth: 520,
minHeight: 100,
- value : name
+ value: name
},
onSubmit: function(e) {
- var newfootnoteContent = e.data.name,
+ var newfootnoteContent = footnoteText,
fixFootnoteContent = (function () {
- return encodeURIComponent(newfootnoteContent);
+ return newfootnoteContent;
}()),
- htmlTemplate = ' ',
- totalFootNote = editor.getDoc().querySelectorAll('.fnoteBtn'),
- totalCount = totalFootNote.length,
- html;
+ htmlTemplate = '';
+
+ var totalFootNote = editor.getDoc().querySelectorAll('.fnoteBtn');
+ var totalCount = totalFootNote.length;
+ var html;
function findNextFD($node)
{
@@ -97,8 +100,10 @@ tinymce.PluginManager.add('footnotes', function(editor) {
return currentClassNot_NextClass;
}
- var nextFD = findNextFD($(editor.selection.getRng().endContainer));
+ // destroy the embedded footnote HTML editor
+ tinymce.activeEditor.destroy();
+ var nextFD = findNextFD($(selectedRange));
if(nextFD.length) {
nextFD = nextFD[0];
var foundIdx;
@@ -110,6 +115,7 @@ tinymce.PluginManager.add('footnotes', function(editor) {
if (selectIndex < totalCount) {
// modify
html = replaceTmpl(htmlTemplate,{FOOTNOTE_INDEX : $(totalFootNote[selectIndex-1]).html()});
+ editor.selection.select(selectedNode);
}
else {
// anywhere add
@@ -132,12 +138,43 @@ tinymce.PluginManager.add('footnotes', function(editor) {
});
}
});
+ tinymce.init({
+ selector: '#footnote-dialog textarea',
+ content_css: '/css/frontend.css',
+ forced_root_block : 'div',
+ skin: false,
+ branding: false,
+ statusbar: true,
+ menubar: false,
+ plugins: ['link'],
+ toolbar: 'bold italic | link',
+ setup: function(editor) {
+ editor.on('init', function (e) {
+ editor.focus();
+ });
+ editor.on('keyup', function(e) {
+ footnoteText = sanitizeHtml(footnoteText = editor.getContent());
+ });
+ editor.on('change', function(e) {
+ footnoteText = sanitizeHtml(footnoteText = editor.getContent());
+ });
+ }
+ });
+
}
editor.addCommand('mceFootnotes', showDialog);
editor.addButton("footnotes", {
- title : 'footnote',
- image : tinyMCE.baseURL + '/plugins/footnotes/img/footnotes.png',
+ title : 'Insert footnote',
+ image : tinyMCE.baseURL + '/tinymce/plugins/footnotesHtml/img/footnotes.png',
onclick: showDialog,
stateSelector: 'span.fnoteWrap'
});
+
+ function sanitizeHtml(str) {
+ str = str.replaceAll('"', """); // first, replace all double quotes with entity – works for quotes in normal text
+ str = str.replaceAll("'", "'"); // also, replace all single quotes and apostrophes with entity
+ str = str.replace(/(\w+)\s*=\s*((")(.*?)\3|([^>\s]*)(?=\s|\/>))(?=[^<]*>)/g, "$1='$4'"); // now replace " with single quotes in attributes
+ return str;
+ }
});
+
\ No newline at end of file
diff --git a/tinymce4.x/footnotes/plugin.min.js b/tinymce4.x/footnotes/plugin.min.js
index f52c5ac..3929960 100644
--- a/tinymce4.x/footnotes/plugin.min.js
+++ b/tinymce4.x/footnotes/plugin.min.js
@@ -1 +1 @@
-tinymce.PluginManager.add("footnotes",function(t){function n(t,n){var e=t;for(var o in n)e=e.replace("{"+o+"}",n[o]);return e}function e(){var e=t.selection.getNode(),o="",a="SPAN"==e.tagName&&"fnoteWrap"===t.dom.getAttrib(e,"class"),i=function(){if("fnoteWrap"==e.className){var t=e.childNodes[0].firstChild.nodeValue.replace(/[^0-9]/g,"");return t}return e.childNodes[0]}();a&&(o=e.name||decodeURIComponent(e.childNodes[0].getAttribute("data-content"))||""),t.windowManager.open({title:"Insert a contents",id:"footnote-dialog",body:{type:"textbox",name:"name",multiline:!0,minWidth:520,minHeight:100,value:o},onSubmit:function(e){function o(t){function n(t,n){for(var a=e(n);0!==a.length;){var i=o(t,a);if(null!==i)return i;a=e(a)}return a}function e(t){return t.nextAll().find(".fnoteBtn").length>0?t.next().hasClass("fnoteBtn")?t.next().children().children():t.nextAll().find(".fnoteBtn"):"BODY"==t.prop("nodeName")?[]:e(t.parent())}function o(t,n){if(!n)return!1;if(n)return n;var e=null;return n.children().each(function(){n&&(e=o(t,$(this)))}),e}var a=n(".fnoteBtn",t);return a}var a,r=e.data.name,l=function(){return encodeURIComponent(r)}(),c=' ',f=t.getDoc().querySelectorAll(".fnoteBtn"),s=f.length,d=o($(t.selection.getRng().endContainer));if(d.length){d=d[0];var u;for(u=0;u