diff --git a/Gruntfile.js b/Gruntfile.js
index 2b3d4941e..3cadb09b0 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -17,6 +17,7 @@ module.exports = function (grunt) {
'src/js/selection.js',
'src/js/button.js',
'src/js/paste.js',
+ 'src/js/extension-anchor.js',
'src/js/core.js'
];
diff --git a/dist/js/medium-editor.js b/dist/js/medium-editor.js
index 92211b7da..c5e990b04 100644
--- a/dist/js/medium-editor.js
+++ b/dist/js/medium-editor.js
@@ -406,6 +406,10 @@ var DefaultButton,
action: 'underline',
aria: 'underline',
tagNames: ['u'],
+ style: {
+ prop: 'text-decoration',
+ value: 'underline'
+ },
useQueryState: true,
contentDefault: 'U',
contentFA: ''
@@ -415,6 +419,10 @@ var DefaultButton,
action: 'strikethrough',
aria: 'strike through',
tagNames: ['strike'],
+ style: {
+ prop: 'text-decoration',
+ value: 'line-through'
+ },
useQueryState: true,
contentDefault: 'A',
contentFA: ''
@@ -675,7 +683,8 @@ var DefaultButton,
shouldActivate: function (node) {
var isMatch = false,
tagNames = this.getTagNames(),
- styleVals;
+ styleVals,
+ computedStyle;
if (this.knownState === false || this.knownState === true) {
return this.knownState;
}
@@ -686,10 +695,10 @@ var DefaultButton,
if (!isMatch && this.options.style) {
styleVals = this.options.style.value.split('|');
+ computedStyle = this.base.options.contentWindow.getComputedStyle(node, null).getPropertyValue(this.options.style.prop);
styleVals.forEach(function (val) {
- this.knownState = isMatch = (this.base.options.contentWindow.getComputedStyle(node, null).getPropertyValue(this.options.style.prop).indexOf(val) !== -1);
- if (this.knownState) {
- return false;
+ if (!this.knownState) {
+ this.knownState = isMatch = (computedStyle.indexOf(val) !== -1);
}
}.bind(this));
}
@@ -926,6 +935,209 @@ var pasteHandler;
};
}(window, document));
+var AnchorExtension;
+
+(function (window, document) {
+ 'use strict';
+
+ AnchorExtension = function (instance) {
+ this.base = instance;
+ };
+
+ AnchorExtension.prototype = {
+
+ getForm: function () {
+ if (!this.anchorForm) {
+ this.anchorForm = this.createForm();
+ }
+ return this.anchorForm;
+ },
+
+ getInput: function () {
+ return this.getForm().querySelector('input.medium-editor-toolbar-input');
+ },
+
+ deactivate: function () {
+ if (!this.anchorForm) {
+ return false;
+ }
+
+ if (this.anchorForm.parentNode) {
+ this.anchorForm.parentNode.removeChild(this.anchorForm);
+ }
+
+ delete this.anchorForm;
+ },
+
+ doLinkCreation: function () {
+ var button = null,
+ target,
+ targetCheckbox = this.getForm().querySelector('.medium-editor-toolbar-anchor-target'),
+ buttonCheckbox = this.getForm().querySelector('.medium-editor-toolbar-anchor-button');
+
+ if (targetCheckbox && targetCheckbox.checked) {
+ target = "_blank";
+ } else {
+ target = "_self";
+ }
+
+ if (buttonCheckbox && buttonCheckbox.checked) {
+ button = this.base.options.anchorButtonClass;
+ }
+
+ this.base.createLink(this.getInput(), target, button);
+ },
+
+ doFormCancel: function () {
+ this.base.showToolbarActions();
+ this.base.restoreSelection();
+ },
+
+ handleOutsideInteraction: function (event) {
+ if (event.target !== this.getForm() &&
+ !mediumEditorUtil.isDescendant(this.getForm(), event.target) &&
+ !mediumEditorUtil.isDescendant(this.base.toolbarActions, event.target)) {
+ this.base.keepToolbarAlive = false;
+ this.base.checkSelection();
+ }
+ },
+
+ createForm: function () {
+ var doc = this.base.options.ownerDocument,
+ form = doc.createElement('div'),
+ input = doc.createElement('input'),
+ close = doc.createElement('a'),
+ save = doc.createElement('a'),
+ target,
+ target_label,
+ button,
+ button_label;
+
+ // Anchor Form (div)
+ form.className = 'medium-editor-toolbar-form';
+ form.id = 'medium-editor-toolbar-form-anchor-' + this.base.id;
+
+ // Handle clicks on the form itself
+ this.base.on(form, 'click', function (event) {
+ event.stopPropagation();
+ this.base.keepToolbarAlive = true;
+ }.bind(this));
+
+ // Add url textbox
+ input.setAttribute('type', 'text');
+ input.className = 'medium-editor-toolbar-input';
+ input.setAttribute('placeholder', this.base.options.anchorInputPlaceholder);
+ form.appendChild(input);
+
+ // Handle typing in the textbox
+ this.base.on(input, 'keyup', function (event) {
+ // For ENTER -> create the anchor
+ if (event.keyCode === mediumEditorUtil.keyCode.ENTER) {
+ event.preventDefault();
+ this.doLinkCreation();
+ return;
+ }
+
+ // For ESCAPE -> close the form
+ if (event.keyCode === mediumEditorUtil.keyCode.ESCAPE) {
+ event.preventDefault();
+ this.doFormCancel();
+ }
+ }.bind(this));
+
+ // Handle clicks into the textbox
+ this.base.on(input, 'click', function (event) {
+ // make sure not to hide form when cliking into the input
+ event.stopPropagation();
+ this.base.keepToolbarAlive = true;
+ }.bind(this));
+
+ // Add save buton
+ save.setAttribute('href', '#');
+ save.className = 'medium-editor-toobar-save';
+ save.innerHTML = '✓';
+ form.appendChild(save);
+
+ // Handle save button clicks (capture)
+ this.base.on(save, 'click', function (event) {
+ // Clicking Save -> create the anchor
+ event.preventDefault();
+ this.doLinkCreation();
+ }.bind(this), true);
+
+ // Add close button
+ close.setAttribute('href', '#');
+ close.className = 'medium-editor-toobar-close';
+ close.innerHTML = '×';
+ form.appendChild(close);
+
+ // Handle close button clicks
+ this.base.on(close, 'click', function (event) {
+ // Click Close -> close the form
+ event.preventDefault();
+ this.doFormCancel();
+ }.bind(this));
+
+ // (Optional) Add 'open in new window' checkbox
+ if (this.base.options.anchorTarget) {
+ target = doc.createElement('input');
+ target.setAttribute('type', 'checkbox');
+ target.className = 'medium-editor-toolbar-anchor-target';
+
+ target_label = doc.createElement('label');
+ target_label.innerHTML = this.base.options.anchorInputCheckboxLabel;
+ target_label.insertBefore(target, target_label.firstChild);
+
+ form.appendChild(target_label);
+ }
+
+ // (Optional) Add 'add button class to anchor' checkbox
+ if (this.base.options.anchorButton) {
+ button = doc.createElement('input');
+ button.setAttribute('type', 'checkbox');
+ button.className = 'medium-editor-toolbar-anchor-button';
+
+ button_label = doc.createElement('label');
+ button_label.innerHTML = "Button";
+ button_label.insertBefore(button, button_label.firstChild);
+
+ form.appendChild(button_label);
+ }
+
+ // Handle click (capture) & focus (capture) outside of the form
+ this.base.on(doc.body, 'click', this.handleOutsideInteraction.bind(this), true);
+ this.base.on(doc.body, 'focus', this.handleOutsideInteraction.bind(this), true);
+
+ return form;
+ },
+
+ focus: function (value) {
+ var input = this.getInput();
+ input.focus();
+ input.value = value || '';
+ },
+
+ hideForm: function () {
+ this.getForm().style.display = 'none';
+ },
+
+ showForm: function () {
+ this.getForm().style.display = 'block';
+ },
+
+ isDisplayed: function () {
+ return this.getForm().style.display === 'block';
+ },
+
+ isClickIntoForm: function (event) {
+ return (event &&
+ event.type &&
+ event.type.toLowerCase() === 'blur' &&
+ event.relatedTarget &&
+ event.relatedTarget === this.getInput());
+ }
+ };
+}(window, document));
function MediumEditor(elements, options) {
'use strict';
return this.init(elements, options);
@@ -936,7 +1148,8 @@ function MediumEditor(elements, options) {
MediumEditor.statics = {
ButtonsData: ButtonsData,
- DefaultButton: DefaultButton
+ DefaultButton: DefaultButton,
+ AnchorExtension: AnchorExtension
};
MediumEditor.prototype = {
@@ -1102,7 +1315,6 @@ function MediumEditor(elements, options) {
if (addToolbar) {
this.initToolbar()
.bindButtons()
- .bindAnchorForm()
.bindAnchorPreview();
}
return this;
@@ -1457,13 +1669,6 @@ function MediumEditor(elements, options) {
this.toolbarActions = this.toolbar.querySelector('.medium-editor-toolbar-actions');
this.anchorPreview = this.createAnchorPreview();
- if (!this.options.disableAnchorForm) {
- this.anchorForm = this.toolbar.querySelector('.medium-editor-toolbar-form');
- this.anchorInput = this.anchorForm.querySelector('input.medium-editor-toolbar-input');
- this.anchorTarget = this.anchorForm.querySelector('input.medium-editor-toolbar-anchor-target');
- this.anchorButton = this.anchorForm.querySelector('input.medium-editor-toolbar-anchor-button');
- }
-
this.addExtensionForms();
return this;
@@ -1482,7 +1687,8 @@ function MediumEditor(elements, options) {
toolbar.appendChild(this.toolbarButtons());
if (!this.options.disableAnchorForm) {
- toolbar.appendChild(this.toolbarFormAnchor());
+ this.anchorExtension = new AnchorExtension(this);
+ toolbar.appendChild(this.anchorExtension.getForm());
}
this.options.elementsContainer.appendChild(toolbar);
return toolbar;
@@ -1530,58 +1736,6 @@ function MediumEditor(elements, options) {
}.bind(this));
},
- toolbarFormAnchor: function () {
- var anchor = this.options.ownerDocument.createElement('div'),
- input = this.options.ownerDocument.createElement('input'),
- target_label = this.options.ownerDocument.createElement('label'),
- target = this.options.ownerDocument.createElement('input'),
- button_label = this.options.ownerDocument.createElement('label'),
- button = this.options.ownerDocument.createElement('input'),
- close = this.options.ownerDocument.createElement('a'),
- save = this.options.ownerDocument.createElement('a');
-
- close.setAttribute('href', '#');
- close.className = 'medium-editor-toobar-close';
- close.innerHTML = '×';
-
- save.setAttribute('href', '#');
- save.className = 'medium-editor-toobar-save';
- save.innerHTML = '✓';
-
- input.setAttribute('type', 'text');
- input.className = 'medium-editor-toolbar-input';
- input.setAttribute('placeholder', this.options.anchorInputPlaceholder);
-
-
- target.setAttribute('type', 'checkbox');
- target.className = 'medium-editor-toolbar-anchor-target';
- target_label.innerHTML = this.options.anchorInputCheckboxLabel;
- target_label.insertBefore(target, target_label.firstChild);
-
- button.setAttribute('type', 'checkbox');
- button.className = 'medium-editor-toolbar-anchor-button';
- button_label.innerHTML = "Button";
- button_label.insertBefore(button, button_label.firstChild);
-
-
- anchor.className = 'medium-editor-toolbar-form';
- anchor.id = 'medium-editor-toolbar-form-anchor-' + this.id;
- anchor.appendChild(input);
-
- anchor.appendChild(save);
- anchor.appendChild(close);
-
- if (this.options.anchorTarget) {
- anchor.appendChild(target_label);
- }
-
- if (this.options.anchorButton) {
- anchor.appendChild(button_label);
- }
-
- return anchor;
- },
-
bindSelect: function () {
var self = this,
i,
@@ -1589,7 +1743,7 @@ function MediumEditor(elements, options) {
this.checkSelectionWrapper = function (e) {
// Do not close the toolbar when bluring the editable area and clicking into the anchor form
- if (!self.options.disableAnchorForm && e && self.clickingIntoArchorForm(e)) {
+ if (e && this.anchorExtension && this.anchorExtension.isClickIntoForm(e)) {
return false;
}
@@ -1730,7 +1884,7 @@ function MediumEditor(elements, options) {
if (!this.options.staticToolbar) {
this.hideToolbarActions();
- } else if (this.anchorForm && this.anchorForm.style.display === 'block') {
+ } else if (this.anchorExtension && this.anchorExtension.isDisplayed()) {
this.setToolbarButtonStates();
this.showToolbarActions();
}
@@ -1749,16 +1903,6 @@ function MediumEditor(elements, options) {
return this;
},
- clickingIntoArchorForm: function (e) {
- var self = this;
-
- if (e.type && e.type.toLowerCase() === 'blur' && e.relatedTarget && e.relatedTarget === self.anchorInput) {
- return true;
- }
-
- return false;
- },
-
hasMultiParagraphs: function () {
var selectionHtml = meSelection.getSelectionHtml.call(this).replace(/<[\S]+><\/[\S]+>/gim, ''),
hasMultiParagraphs = selectionHtml.match(/<(p|h[0-6]|blockquote)>([\s\S]*?)<\/(p|h[0-6]|blockquote)>/g);
@@ -2050,8 +2194,8 @@ function MediumEditor(elements, options) {
if (selectedParentElement.tagName &&
selectedParentElement.tagName.toLowerCase() === 'a') {
this.options.ownerDocument.execCommand('unlink', false, null);
- } else if (this.anchorForm) {
- if (this.anchorForm.style.display === 'block') {
+ } else if (this.anchorExtension) {
+ if (this.anchorExtension.isDisplayed()) {
this.showToolbarActions();
} else {
this.showAnchorForm();
@@ -2120,8 +2264,8 @@ function MediumEditor(elements, options) {
showToolbarActions: function () {
var self = this;
- if (this.anchorForm) {
- this.anchorForm.style.display = 'none';
+ if (this.anchorExtension) {
+ this.anchorExtension.hideForm();
}
this.toolbarActions.style.display = 'block';
this.keepToolbarAlive = false;
@@ -2223,100 +2367,16 @@ function MediumEditor(elements, options) {
},
showAnchorForm: function (link_value) {
- if (!this.anchorForm) {
+ if (!this.anchorExtension) {
return;
}
this.toolbarActions.style.display = 'none';
this.saveSelection();
- this.anchorForm.style.display = 'block';
+ this.anchorExtension.showForm();
this.setToolbarPosition();
this.keepToolbarAlive = true;
- this.anchorInput.focus();
- this.anchorInput.value = link_value || '';
- },
-
- bindAnchorForm: function () {
- if (!this.anchorForm) {
- return this;
- }
-
- var linkCancel = this.anchorForm.querySelector('a.medium-editor-toobar-close'),
- linkSave = this.anchorForm.querySelector('a.medium-editor-toobar-save'),
- self = this;
-
- this.on(this.anchorForm, 'click', function (e) {
- e.stopPropagation();
- self.keepToolbarAlive = true;
- });
-
- this.on(this.anchorInput, 'keyup', function (e) {
- var button = null,
- target;
-
- if (e.keyCode === mediumEditorUtil.keyCode.ENTER) {
- e.preventDefault();
- if (self.options.anchorTarget && self.anchorTarget.checked) {
- target = "_blank";
- } else {
- target = "_self";
- }
-
- if (self.options.anchorButton && self.anchorButton.checked) {
- button = self.options.anchorButtonClass;
- }
-
- self.createLink(this, target, button);
- } else if (e.keyCode === mediumEditorUtil.keyCode.ESCAPE) {
- e.preventDefault();
- self.showToolbarActions();
- self.restoreSelection();
- }
- });
-
- this.on(linkSave, 'click', function (e) {
- var button = null,
- target;
- e.preventDefault();
- if (self.options.anchorTarget && self.anchorTarget.checked) {
- target = "_blank";
- } else {
- target = "_self";
- }
-
- if (self.options.anchorButton && self.anchorButton.checked) {
- button = self.options.anchorButtonClass;
- }
-
- self.createLink(self.anchorInput, target, button);
- }, true);
-
- this.on(this.anchorInput, 'click', function (e) {
- // make sure not to hide form when cliking into the input
- e.stopPropagation();
- self.keepToolbarAlive = true;
- });
-
- // Hide the anchor form when focusing outside of it.
- this.on(this.options.ownerDocument.body, 'click', function (e) {
- if (e.target !== self.anchorForm && !mediumEditorUtil.isDescendant(self.anchorForm, e.target) && !mediumEditorUtil.isDescendant(self.toolbarActions, e.target)) {
- self.keepToolbarAlive = false;
- self.checkSelection();
- }
- }, true);
- this.on(this.options.ownerDocument.body, 'focus', function (e) {
- if (e.target !== self.anchorForm && !mediumEditorUtil.isDescendant(self.anchorForm, e.target) && !mediumEditorUtil.isDescendant(self.toolbarActions, e.target)) {
- self.keepToolbarAlive = false;
- self.checkSelection();
- }
- }, true);
-
- this.on(linkCancel, 'click', function (e) {
- e.preventDefault();
- self.showToolbarActions();
- self.restoreSelection();
- });
- return this;
+ this.anchorExtension.focus(link_value);
},
hideAnchorPreview: function () {
@@ -2433,7 +2493,7 @@ function MediumEditor(elements, options) {
sel.removeAllRanges();
sel.addRange(range);
// Using setTimeout + options.delay because:
- // We may actually be displaying the anchor preview, which should be controlled by options.delay
+ // We may actually be displaying the anchor form, which should be controlled by options.delay
this.delay(function () {
if (self.activeAnchor) {
self.showAnchorForm(self.activeAnchor.attributes.href.value);
@@ -2619,6 +2679,10 @@ function MediumEditor(elements, options) {
}
}.bind(this));
+ if (this.anchorExtension) {
+ this.anchorExtension.deactivate();
+ }
+
this.removeAllEvents();
},
diff --git a/dist/js/medium-editor.min.js b/dist/js/medium-editor.min.js
index 7d1630b78..dc10b789f 100644
--- a/dist/js/medium-editor.min.js
+++ b/dist/js/medium-editor.min.js
@@ -1,2 +1,2 @@
-!function(a,b){"use strict";"object"==typeof module?module.exports=b:"function"==typeof define&&define.amd?define(b):a.MediumEditor=b}(this,function(){"use strict";function a(a,b){return this.init(a,b)}var b;!function(a){b={isIE:"Microsoft Internet Explorer"===navigator.appName||"Netscape"===navigator.appName&&null!==new RegExp("Trident/.*rv:([0-9]{1,}[.0-9]{0,})").exec(navigator.userAgent),keyCode:{BACKSPACE:8,TAB:9,ENTER:13,ESCAPE:27,SPACE:32,DELETE:46},parentElements:["p","h1","h2","h3","h4","h5","h6","blockquote","pre"],extend:function(a,b){var c;if(void 0===a)return b;for(c in b)b.hasOwnProperty(c)&&a.hasOwnProperty(c)===!1&&(a[c]=b[c]);return a},findAdjacentTextNodeWithContent:function(a,b,c){var d,e=!1,f=c.createNodeIterator(a,NodeFilter.SHOW_TEXT,null,!1);for(d=f.nextNode();d;){if(d===b)e=!0;else if(e&&3===d.nodeType&&d.nodeValue&&d.nodeValue.trim().length>0)break;d=f.nextNode()}return d},isDescendant:function(a,b){for(var c=b.parentNode;null!==c;){if(c===a)return!0;c=c.parentNode}return!1},isElement:function(a){return!(!a||1!==a.nodeType)},now:function(){return Date.now||(new Date).getTime()},throttle:function(a,c){var d,e,f,g,h=50,i=null,j=0;return c||0===c||(c=h),g=function(){j=b.now(),i=null,f=a.apply(d,e),i||(d=e=null)},function(){var h=b.now(),k=c-(h-j);return d=this,e=arguments,0>=k||k>c?(clearTimeout(i),i=null,j=h,f=a.apply(d,e),i||(d=e=null)):i||(i=setTimeout(g,k)),f}},traverseUp:function(a,b){do{if(1===a.nodeType){if(b(a))return a;if(a.getAttribute("data-medium-element"))return!1}a=a.parentNode}while(a);return!1},htmlEntities:function(a){return String(a).replace(/&/g,"&").replace(//g,">").replace(/"/g,""")},insertHTMLCommand:function(b,c){var d,e,f,g,h,i;if(b.queryCommandSupported("insertHTML"))try{return b.execCommand("insertHTML",!1,c)}catch(j){}if(d=a.getSelection(),d.getRangeAt&&d.rangeCount){for(e=d.getRangeAt(0),e.deleteContents(),f=b.createElement("div"),f.innerHTML=c,g=b.createDocumentFragment();f.firstChild;)h=f.firstChild,i=g.appendChild(h);e.insertNode(g),i&&(e=e.cloneRange(),e.setStartAfter(i),e.collapse(!0),d.removeAllRanges(),d.addRange(e))}},setTargetBlank:function(a){var b;if("a"===a.tagName.toLowerCase())a.target="_blank";else for(a=a.getElementsByTagName("a"),b=0;ba;a+=1)d.appendChild(b.getRangeAt(a).cloneContents());e=d.innerHTML}}else void 0!==this.options.ownerDocument.selection&&"Text"===this.options.ownerDocument.selection.type&&(e=this.options.ownerDocument.selection.createRange().htmlText);return e},getCaretOffsets:function(b,c){var d,e;return c||(c=a.getSelection().getRangeAt(0)),d=c.cloneRange(),e=c.cloneRange(),d.selectNodeContents(b),d.setEnd(c.endContainer,c.endOffset),e.selectNodeContents(b),e.setStart(c.endContainer,c.endOffset),{left:d.toString().length,right:e.toString().length}},rangeSelectsSingleNode:function(a){var b=a.startContainer;return b===a.endContainer&&b.hasChildNodes()&&a.endOffset===a.startOffset+1},getSelectedParentElement:function(a){var b=null;return b=this.rangeSelectsSingleNode(a)&&3!==a.startContainer.childNodes[a.startOffset].nodeType?a.startContainer.childNodes[a.startOffset]:3===a.startContainer.nodeType?a.startContainer.parentNode:a.startContainer},getSelectionData:function(a){var c;for(a&&a.tagName&&(c=a.tagName.toLowerCase());a&&-1===b.parentElements.indexOf(c);)a=a.parentNode,a&&a.tagName&&(c=a.tagName.toLowerCase());return{el:a,tagName:c}}}}(document,window);var d,e;!function(){e={bold:{name:"bold",action:"bold",aria:"bold",tagNames:["b","strong"],style:{prop:"font-weight",value:"700|bold"},useQueryState:!0,contentDefault:"B",contentFA:''},italic:{name:"italic",action:"italic",aria:"italic",tagNames:["i","em"],style:{prop:"font-style",value:"italic"},useQueryState:!0,contentDefault:"I",contentFA:''},underline:{name:"underline",action:"underline",aria:"underline",tagNames:["u"],useQueryState:!0,contentDefault:"U",contentFA:''},strikethrough:{name:"strikethrough",action:"strikethrough",aria:"strike through",tagNames:["strike"],useQueryState:!0,contentDefault:"A",contentFA:''},superscript:{name:"superscript",action:"superscript",aria:"superscript",tagNames:["sup"],contentDefault:"x1",contentFA:''},subscript:{name:"subscript",action:"subscript",aria:"subscript",tagNames:["sub"],contentDefault:"x1",contentFA:''},anchor:{name:"anchor",action:"anchor",aria:"link",tagNames:["a"],contentDefault:"#",contentFA:''},image:{name:"image",action:"image",aria:"image",tagNames:["img"],contentDefault:"image",contentFA:''},quote:{name:"quote",action:"append-blockquote",aria:"blockquote",tagNames:["blockquote"],contentDefault:"“",contentFA:''},orderedlist:{name:"orderedlist",action:"insertorderedlist",aria:"ordered list",tagNames:["ol"],useQueryState:!0,contentDefault:"1.",contentFA:''},unorderedlist:{name:"unorderedlist",action:"insertunorderedlist",aria:"unordered list",tagNames:["ul"],useQueryState:!0,contentDefault:"•",contentFA:''},pre:{name:"pre",action:"append-pre",aria:"preformatted text",tagNames:["pre"],contentDefault:"0101",contentFA:''},indent:{name:"indent",action:"indent",aria:"indent",tagNames:[],contentDefault:"→",contentFA:''},outdent:{name:"outdent",action:"outdent",aria:"outdent",tagNames:[],contentDefault:"←",contentFA:''},justifyCenter:{name:"justifyCenter",action:"justifyCenter",aria:"center justify",tagNames:[],style:{prop:"text-align",value:"center"},useQueryState:!0,contentDefault:"C",contentFA:''},justifyFull:{name:"justifyFull",action:"justifyFull",aria:"full justify",tagNames:[],style:{prop:"text-align",value:"justify"},useQueryState:!0,contentDefault:"J",contentFA:''},justifyLeft:{name:"justifyLeft",action:"justifyLeft",aria:"left justify",tagNames:[],style:{prop:"text-align",value:"left"},useQueryState:!0,contentDefault:"L",contentFA:''},justifyRight:{name:"justifyRight",action:"justifyRight",aria:"right justify",tagNames:[],style:{prop:"text-align",value:"right"},useQueryState:!0,contentDefault:"R",contentFA:''},header1:{name:"header1",action:function(a){return"append-"+a.firstHeader},aria:function(a){return a.firstHeader},tagNames:function(a){return[a.firstHeader]},contentDefault:"H1"},header2:{name:"header2",action:function(a){return"append-"+a.secondHeader},aria:function(a){return a.secondHeader},tagNames:function(a){return[a.secondHeader]},contentDefault:"H2"}},d=function(a,b){this.options=a,this.name=a.name,this.init(b)},d.prototype={init:function(a){this.base=a,this.button=this.createButton(),this.base.on(this.button,"click",this.handleClick.bind(this))},getButton:function(){return this.button},getAction:function(){return"function"==typeof this.options.action?this.options.action(this.base.options):this.options.action},getAria:function(){return"function"==typeof this.options.aria?this.options.aria(this.base.options):this.options.aria},getTagNames:function(){return"function"==typeof this.options.tagNames?this.options.tagNames(this.base.options):this.options.tagNames},createButton:function(){var a=this.base.options.ownerDocument.createElement("button"),b=this.options.contentDefault;return a.classList.add("medium-editor-action"),a.classList.add("medium-editor-action-"+this.name),a.setAttribute("data-action",this.getAction()),a.setAttribute("aria-label",this.getAria()),this.base.options.buttonLabels&&("fontawesome"===this.base.options.buttonLabels&&this.options.contentFA?b=this.options.contentFA:"object"==typeof this.base.options.buttonLabels&&this.base.options.buttonLabels[this.name]&&(b=this.base.options.buttonLabels[this.options.name])),a.innerHTML=b,a},handleClick:function(a){a.preventDefault(),a.stopPropagation();var b=this.getAction();this.base.selection||this.base.checkSelection(),this.isActive()?this.deactivate():this.activate(),b&&this.base.execAction(b,a)},isActive:function(){return this.button.classList.contains(this.base.options.activeButtonClass)},deactivate:function(){this.button.classList.remove(this.base.options.activeButtonClass),delete this.knownState},activate:function(){this.button.classList.add(this.base.options.activeButtonClass),delete this.knownState},queryCommandState:function(){var a=null;if(this.options.useQueryState)try{a=this.base.options.ownerDocument.queryCommandState(this.getAction())}catch(b){a=null}return a},shouldActivate:function(a){var b,c=!1,d=this.getTagNames();return this.knownState===!1||this.knownState===!0?this.knownState:(d&&d.length>0&&a.tagName&&(c=-1!==d.indexOf(a.tagName.toLowerCase())),!c&&this.options.style&&(b=this.options.style.value.split("|"),b.forEach(function(b){return this.knownState=c=-1!==this.base.options.contentWindow.getComputedStyle(a,null).getPropertyValue(this.options.style.prop).indexOf(b),this.knownState?!1:void 0}.bind(this))),c)}}}(window,document);var f;return function(){function a(){return[[new RegExp(/<[^>]*docs-internal-guid[^>]*>/gi),""],[new RegExp(/<\/b>(
]*>)?$/gi),""],[new RegExp(/\s+<\/span>/g)," "],[new RegExp(/
/g),"
"],[new RegExp(/]*(font-style:italic;font-weight:bold|font-weight:bold;font-style:italic)[^>]*>/gi),''],[new RegExp(/]*font-style:italic[^>]*>/gi),''],[new RegExp(/]*font-weight:bold[^>]*>/gi),''],[new RegExp(/<(\/?)(i|b|a)>/gi),"<$1$2>"],[new RegExp(/<a\s+href=("|”|“|“|”)([^&]+)("|”|“|“|”)>/gi),'']]}f={handlePaste:function(a,c,d){var e,f,g="",h="text/html",i="text/plain";if(a.classList.remove("medium-editor-placeholder"),!d.forcePlainText&&!d.cleanPastedHTML)return a;if(d.contentWindow.clipboardData&&void 0===c.clipboardData&&(c.clipboardData=d.contentWindow.clipboardData,h="Text",i="Text"),c.clipboardData&&c.clipboardData.getData&&!c.defaultPrevented){if(c.preventDefault(),d.cleanPastedHTML&&c.clipboardData.getData(h))return this.cleanPaste(c.clipboardData.getData(h),d);if(d.disableReturn||a.getAttribute("data-disable-return"))g=b.htmlEntities(c.clipboardData.getData(i)),b.insertHTMLCommand(d.ownerDocument,g);else{for(e=c.clipboardData.getData(i).split(/[\r\n]/g),f=0;f"+b.htmlEntities(e[f])+"
");b.insertHTMLCommand(d.ownerDocument,g)}}},cleanPaste:function(d,e){var f,g,h,i=c.getSelectionElement(e.contentWindow),j=/
"),this.pasteHTML("
"+g.join("
")+"
",e.ownerDocument),e.ownerDocument.execCommand("insertText",!1,"\n"),g=i.querySelectorAll("a,p,div,br"),f=0;f"+e.innerHTML+"":e.innerHTML,e.parentNode.replaceChild(f,e);for(g=a.querySelectorAll("span"),d=0;de;e+=1)if(g=this.events[e],g[0]===a&&g[1]===b&&g[2]===c&&g[3]===d)return e;return-1},delay:function(a){var b=this;setTimeout(function(){b.isActive&&a()},this.options.delay)},removeAllEvents:function(){for(var a=this.events.pop();a;)a[0].removeEventListener(a[1],a[2],a[3]),a=this.events.pop()},initThrottledMethods:function(){var a=this;return this.handleResize=b.throttle(function(){a.isActive&&a.positionToolbarIfShown()}),this.handleBlur=b.throttle(function(){a.isActive&&!a.keepToolbarAlive&&a.hideToolbarActions()}),this},initElements:function(){var a,b=!1;for(a=0;a)?$/i,j=/h\d/i;(a.which===b.keyCode.BACKSPACE||a.which===b.keyCode.ENTER)&&g.previousElementSibling&&j.test(h)&&0===c.getCaretOffsets(g).left?a.which===b.keyCode.BACKSPACE&&i.test(g.previousElementSibling.innerHTML)?(g.previousElementSibling.parentNode.removeChild(g.previousElementSibling),a.preventDefault()):a.which===b.keyCode.ENTER&&(f=this.options.ownerDocument.createElement("p"),f.innerHTML="
",g.previousElementSibling.parentNode.insertBefore(f,g),a.preventDefault()):a.which===b.keyCode.DELETE&&g.nextElementSibling&&g.previousElementSibling&&!j.test(h)&&i.test(g.innerHTML)&&j.test(g.nextElementSibling.tagName)&&(d=document.createRange(),e=window.getSelection(),d.setStart(g.nextElementSibling,0),d.collapse(!0),e.removeAllRanges(),e.addRange(d),g.previousElementSibling.parentNode.removeChild(g),a.preventDefault())},initToolbar:function(){return this.toolbar?this:(this.toolbar=this.createToolbar(),this.keepToolbarAlive=!1,this.toolbarActions=this.toolbar.querySelector(".medium-editor-toolbar-actions"),this.anchorPreview=this.createAnchorPreview(),this.options.disableAnchorForm||(this.anchorForm=this.toolbar.querySelector(".medium-editor-toolbar-form"),this.anchorInput=this.anchorForm.querySelector("input.medium-editor-toolbar-input"),this.anchorTarget=this.anchorForm.querySelector("input.medium-editor-toolbar-anchor-target"),this.anchorButton=this.anchorForm.querySelector("input.medium-editor-toolbar-anchor-button")),this.addExtensionForms(),this)},createToolbar:function(){var a=this.options.ownerDocument.createElement("div");return a.id="medium-editor-toolbar-"+this.id,a.className="medium-editor-toolbar",a.className+=this.options.staticToolbar?" static-toolbar":" stalker-toolbar",a.appendChild(this.toolbarButtons()),this.options.disableAnchorForm||a.appendChild(this.toolbarFormAnchor()),this.options.elementsContainer.appendChild(a),a},toolbarButtons:function(){var a,c,d=this.options.ownerDocument.createElement("ul");return d.id="medium-editor-toolbar-actions"+this.id,d.className="medium-editor-toolbar-actions clearfix",this.commands.forEach(function(e){"function"==typeof e.getButton&&(c=e.getButton(this),a=this.options.ownerDocument.createElement("li"),b.isElement(c)?a.appendChild(c):a.innerHTML=c,d.appendChild(a))}.bind(this)),d},addExtensionForms:function(){var a,b;this.commands.forEach(function(c){c.hasForm&&(a="function"==typeof c.getForm?c.getForm():null),a&&(b="medium-editor-toolbar-form-"+c.name+"-"+this.id,a.className+=" medium-editor-toolbar-form",a.id=b,this.toolbar.appendChild(a))}.bind(this))},toolbarFormAnchor:function(){var a=this.options.ownerDocument.createElement("div"),b=this.options.ownerDocument.createElement("input"),c=this.options.ownerDocument.createElement("label"),d=this.options.ownerDocument.createElement("input"),e=this.options.ownerDocument.createElement("label"),f=this.options.ownerDocument.createElement("input"),g=this.options.ownerDocument.createElement("a"),h=this.options.ownerDocument.createElement("a");return g.setAttribute("href","#"),g.className="medium-editor-toobar-close",g.innerHTML="×",h.setAttribute("href","#"),h.className="medium-editor-toobar-save",h.innerHTML="✓",b.setAttribute("type","text"),b.className="medium-editor-toolbar-input",b.setAttribute("placeholder",this.options.anchorInputPlaceholder),d.setAttribute("type","checkbox"),d.className="medium-editor-toolbar-anchor-target",c.innerHTML=this.options.anchorInputCheckboxLabel,c.insertBefore(d,c.firstChild),f.setAttribute("type","checkbox"),f.className="medium-editor-toolbar-anchor-button",e.innerHTML="Button",e.insertBefore(f,e.firstChild),a.className="medium-editor-toolbar-form",a.id="medium-editor-toolbar-form-anchor-"+this.id,a.appendChild(b),a.appendChild(h),a.appendChild(g),this.options.anchorTarget&&a.appendChild(c),this.options.anchorButton&&a.appendChild(e),a},bindSelect:function(){var a,b,c=this;for(this.checkSelectionWrapper=function(a){return!c.options.disableAnchorForm&&a&&c.clickingIntoArchorForm(a)?!1:void c.checkSelection()},b=function(a){setTimeout(function(){this.checkSelectionWrapper(a)}.bind(this),0)}.bind(this),this.on(this.options.ownerDocument.documentElement,"mouseup",this.checkSelectionWrapper),a=0;a'),c.onload=function(){var a=document.getElementById(d);a&&(a.removeAttribute("id"),a.removeAttribute("class"),a.src=c.result)}}}),this.classList.remove(c)},a=0;a<\/[\S]+>/gim,""),b=a.match(/<(p|h[0-6]|blockquote)>([\s\S]*?)<\/(p|h[0-6]|blockquote)>/g);return b?b.length:0},checkSelectionElement:function(a,d){var e,f,g,h=0;if(this.selection=a,this.selectionRange=this.selection.getRangeAt(0),this.options.standardizeSelectionStart&&this.selectionRange.startContainer.nodeValue&&this.selectionRange.startOffset===this.selectionRange.startContainer.nodeValue.length&&(f=b.findAdjacentTextNodeWithContent(c.getSelectionElement(this.options.contentWindow),this.selectionRange.startContainer,this.options.ownerDocument))){for(h=0;0===f.nodeValue.substr(h,1).trim().length;)h+=1;g=this.options.ownerDocument.createRange(),g.setStart(f,h),g.setEnd(this.selectionRange.endContainer,this.selectionRange.endOffset),this.selection.removeAllRanges(),this.selection.addRange(g),this.selectionRange=g}for(e=0;eg+this.elements[0].offsetHeight-this.toolbar.offsetHeight?this.toolbar.style.top=g+this.elements[0].offsetHeight+"px":d>g-this.toolbar.offsetHeight?(this.toolbar.classList.add("sticky-toolbar"),this.toolbar.style.top="0px"):(this.toolbar.classList.remove("sticky-toolbar"),this.toolbar.style.top=g-this.toolbar.offsetHeight+"px"):this.toolbar.style.top=g-this.toolbar.offsetHeight+"px",this.toolbar.style.left=this.options.toolbarAlign?"left"===this.options.toolbarAlign?f.left+"px":"center"===this.options.toolbarAlign?l-k+"px":f.right-this.toolbar.offsetWidth+"px":l-k+"px"):i.isCollapsed||(a=i.getRangeAt(0),b=a.getBoundingClientRect(),c=(b.left+b.right)/2,b.topc?j+k+"px":this.options.contentWindow.innerWidth-c0&&(a[0].className+=" "+this.options.firstButtonClass,a[a.length-1].className+=" "+this.options.lastButtonClass),this},execAction:function(a,b){a.indexOf("append-")>-1?(this.execFormatBlock(a.replace("append-","")),this.setToolbarPosition(),this.setToolbarButtonStates()):"anchor"===a?this.options.disableAnchorForm||this.triggerAnchorAction(b):"image"===a?this.options.ownerDocument.execCommand("insertImage",!1,this.options.contentWindow.getSelection()):(this.options.ownerDocument.execCommand(a,!1,null),this.setToolbarPosition(),0===a.indexOf("justify")&&this.setToolbarButtonStates())},showForm:function(a){this.toolbarActions.style.display="none",this.saveSelection();var b=document.getElementById(a);b.style.display="block",this.setToolbarPosition(),this.keepToolbarAlive=!0},hideForm:function(a){var b=document.getElementById(a.id);b.style.display="none",this.showToolbarActions(),this.setToolbarPosition(),this.restoreSelection()},rangeSelectsSingleNode:function(a){var b=a.startContainer;return b===a.endContainer&&b.hasChildNodes()&&a.endOffset===a.startOffset+1},getSelectedParentElement:function(){var a=null,b=this.selectionRange;return a=this.rangeSelectsSingleNode(b)&&3!==b.startContainer.childNodes[b.startOffset].nodeType?b.startContainer.childNodes[b.startOffset]:3===b.startContainer.nodeType?b.startContainer.parentNode:b.startContainer},triggerAnchorAction:function(){var a=c.getSelectedParentElement(this.selectionRange);return a.tagName&&"a"===a.tagName.toLowerCase()?this.options.ownerDocument.execCommand("unlink",!1,null):this.anchorForm&&("block"===this.anchorForm.style.display?this.showToolbarActions():this.showAnchorForm()),this},execFormatBlock:function(a){var d=c.getSelectionData(this.selection.anchorNode);if("blockquote"===a&&d.el&&"blockquote"===d.el.parentNode.tagName.toLowerCase())return this.options.ownerDocument.execCommand("outdent",!1,null);if(d.tagName===a&&(a="p"),b.isIE){if("blockquote"===a)return this.options.ownerDocument.execCommand("indent",!1,a);a="<"+a+">"}return this.options.ownerDocument.execCommand("formatBlock",!1,a)},isToolbarShown:function(){return this.toolbar&&this.toolbar.classList.contains("medium-editor-toolbar-active")},showToolbar:function(){this.toolbar&&!this.isToolbarShown()&&(this.toolbar.classList.add("medium-editor-toolbar-active"),this.onShowToolbar&&this.onShowToolbar())},hideToolbar:function(){this.isToolbarShown()&&(this.toolbar.classList.remove("medium-editor-toolbar-active"),this.onHideToolbar&&this.onHideToolbar())},hideToolbarActions:function(){this.commands.forEach(function(a){a.onHide&&"function"==typeof a.onHide&&a.onHide()}),this.keepToolbarAlive=!1,this.hideToolbar()},showToolbarActions:function(){var a=this;this.anchorForm&&(this.anchorForm.style.display="none"),this.toolbarActions.style.display="block",this.keepToolbarAlive=!1,this.delay(function(){a.showToolbar()})},saveSelection:function(){this.selectionState=null;var a,c,d,e=this.options.contentWindow.getSelection(),f=-1;e.rangeCount>0&&(a=e.getRangeAt(0),c=a.cloneRange(),this.elements.forEach(function(c,d){return c===a.startContainer||b.isDescendant(c,a.startContainer)?(f=d,!1):void 0}),f>-1&&(c.selectNodeContents(this.elements[f]),c.setEnd(a.startContainer,a.startOffset),d=c.toString().length,this.selectionState={start:d,end:d+a.toString().length,editableElementIndex:f}))},restoreSelection:function(){if(this.selectionState){var a,b,c,d,e=this.elements[this.selectionState.editableElementIndex],f=0,g=this.options.ownerDocument.createRange(),h=[e],i=!1,j=!1;for(g.setStart(e,0),g.collapse(!0),a=h.pop();!j&&a;){if(3===a.nodeType)d=f+a.length,!i&&this.selectionState.start>=f&&this.selectionState.start<=d&&(g.setStart(a,this.selectionState.start-f),i=!0),i&&this.selectionState.end>=f&&this.selectionState.end<=d&&(g.setEnd(a,this.selectionState.end-f),j=!0),f=d;else for(b=a.childNodes.length-1;b>=0;)h.push(a.childNodes[b]),b-=1;j||(a=h.pop())}c=this.options.contentWindow.getSelection(),c.removeAllRanges(),c.addRange(g)}},showAnchorForm:function(a){this.anchorForm&&(this.toolbarActions.style.display="none",this.saveSelection(),this.anchorForm.style.display="block",this.setToolbarPosition(),this.keepToolbarAlive=!0,this.anchorInput.focus(),this.anchorInput.value=a||"")},bindAnchorForm:function(){if(!this.anchorForm)return this;var a=this.anchorForm.querySelector("a.medium-editor-toobar-close"),c=this.anchorForm.querySelector("a.medium-editor-toobar-save"),d=this;return this.on(this.anchorForm,"click",function(a){a.stopPropagation(),d.keepToolbarAlive=!0}),this.on(this.anchorInput,"keyup",function(a){var c,e=null;a.keyCode===b.keyCode.ENTER?(a.preventDefault(),c=d.options.anchorTarget&&d.anchorTarget.checked?"_blank":"_self",d.options.anchorButton&&d.anchorButton.checked&&(e=d.options.anchorButtonClass),d.createLink(this,c,e)):a.keyCode===b.keyCode.ESCAPE&&(a.preventDefault(),d.showToolbarActions(),d.restoreSelection())}),this.on(c,"click",function(a){var b,c=null;a.preventDefault(),b=d.options.anchorTarget&&d.anchorTarget.checked?"_blank":"_self",d.options.anchorButton&&d.anchorButton.checked&&(c=d.options.anchorButtonClass),d.createLink(d.anchorInput,b,c)},!0),this.on(this.anchorInput,"click",function(a){a.stopPropagation(),d.keepToolbarAlive=!0}),this.on(this.options.ownerDocument.body,"click",function(a){a.target===d.anchorForm||b.isDescendant(d.anchorForm,a.target)||b.isDescendant(d.toolbarActions,a.target)||(d.keepToolbarAlive=!1,d.checkSelection())},!0),this.on(this.options.ownerDocument.body,"focus",function(a){a.target===d.anchorForm||b.isDescendant(d.anchorForm,a.target)||b.isDescendant(d.toolbarActions,a.target)||(d.keepToolbarAlive=!1,d.checkSelection())},!0),this.on(a,"click",function(a){a.preventDefault(),d.showToolbarActions(),d.restoreSelection()}),this},hideAnchorPreview:function(){this.anchorPreview.classList.remove("medium-editor-anchor-preview-active")},showAnchorPreview:function(a){if(this.anchorPreview.classList.contains("medium-editor-anchor-preview-active")||a.getAttribute("data-disable-preview"))return!0;var b,c,d=this,e=40,f=a.getBoundingClientRect(),g=(f.left+f.right)/2;return d.anchorPreview.querySelector("i").textContent=a.attributes.href.value,b=d.anchorPreview.offsetWidth/2,c=d.options.diffLeft-b,d.observeAnchorPreview(a),d.anchorPreview.classList.add("medium-toolbar-arrow-over"),d.anchorPreview.classList.remove("medium-toolbar-arrow-under"),d.anchorPreview.style.top=Math.round(e+f.bottom-d.options.diffTop+this.options.contentWindow.pageYOffset-d.anchorPreview.offsetHeight)+"px",d.anchorPreview.style.left=b>g?c+b+"px":this.options.contentWindow.innerWidth-gb.options.anchorPreviewHideDelay&&(b.hideAnchorPreview(),clearInterval(g),b.off(b.anchorPreview,"mouseover",e),b.off(b.anchorPreview,"mouseout",f),b.off(a,"mouseover",e),b.off(a,"mouseout",f))},200);this.on(b.anchorPreview,"mouseover",e),this.on(b.anchorPreview,"mouseout",f),this.on(a,"mouseover",e),this.on(a,"mouseout",f)},createAnchorPreview:function(){var a=this,b=this.options.ownerDocument.createElement("div");return b.id="medium-editor-anchor-preview-"+this.id,b.className="medium-editor-anchor-preview",b.innerHTML=this.anchorPreviewTemplate(),this.options.elementsContainer.appendChild(b),this.on(b,"click",function(){a.anchorPreviewClickHandler()}),b},anchorPreviewTemplate:function(){return'
'},anchorPreviewClickHandler:function(){if(!this.options.disableAnchorForm&&this.activeAnchor){var a=this,b=this.options.ownerDocument.createRange(),c=this.options.contentWindow.getSelection();b.selectNodeContents(a.activeAnchor),c.removeAllRanges(),c.addRange(b),this.delay(function(){a.activeAnchor&&a.showAnchorForm(a.activeAnchor.attributes.href.value),a.keepToolbarAlive=!1})}this.hideAnchorPreview()},editorAnchorObserver:function(a){var b=this,c=!0,d=function(){c=!1,b.off(b.activeAnchor,"mouseout",d)};if(a.target&&"a"===a.target.tagName.toLowerCase()){if(!/href=["']\S+["']/.test(a.target.outerHTML)||/href=["']#\S+["']/.test(a.target.outerHTML))return!0;if(this.isToolbarShown())return!0;this.activeAnchor=a.target,this.on(this.activeAnchor,"mouseout",d),this.delay(function(){c&&b.showAnchorPreview(a.target)})}},bindAnchorPreview:function(){var a,b=this;for(this.editorAnchorObserverWrapper=function(a){b.editorAnchorObserver(a)},a=0;a0)break;d=f.nextNode()}return d},isDescendant:function(a,b){for(var c=b.parentNode;null!==c;){if(c===a)return!0;c=c.parentNode}return!1},isElement:function(a){return!(!a||1!==a.nodeType)},now:function(){return Date.now||(new Date).getTime()},throttle:function(a,c){var d,e,f,g,h=50,i=null,j=0;return c||0===c||(c=h),g=function(){j=b.now(),i=null,f=a.apply(d,e),i||(d=e=null)},function(){var h=b.now(),k=c-(h-j);return d=this,e=arguments,0>=k||k>c?(clearTimeout(i),i=null,j=h,f=a.apply(d,e),i||(d=e=null)):i||(i=setTimeout(g,k)),f}},traverseUp:function(a,b){do{if(1===a.nodeType){if(b(a))return a;if(a.getAttribute("data-medium-element"))return!1}a=a.parentNode}while(a);return!1},htmlEntities:function(a){return String(a).replace(/&/g,"&").replace(//g,">").replace(/"/g,""")},insertHTMLCommand:function(b,c){var d,e,f,g,h,i;if(b.queryCommandSupported("insertHTML"))try{return b.execCommand("insertHTML",!1,c)}catch(j){}if(d=a.getSelection(),d.getRangeAt&&d.rangeCount){for(e=d.getRangeAt(0),e.deleteContents(),f=b.createElement("div"),f.innerHTML=c,g=b.createDocumentFragment();f.firstChild;)h=f.firstChild,i=g.appendChild(h);e.insertNode(g),i&&(e=e.cloneRange(),e.setStartAfter(i),e.collapse(!0),d.removeAllRanges(),d.addRange(e))}},setTargetBlank:function(a){var b;if("a"===a.tagName.toLowerCase())a.target="_blank";else for(a=a.getElementsByTagName("a"),b=0;ba;a+=1)d.appendChild(b.getRangeAt(a).cloneContents());e=d.innerHTML}}else void 0!==this.options.ownerDocument.selection&&"Text"===this.options.ownerDocument.selection.type&&(e=this.options.ownerDocument.selection.createRange().htmlText);return e},getCaretOffsets:function(b,c){var d,e;return c||(c=a.getSelection().getRangeAt(0)),d=c.cloneRange(),e=c.cloneRange(),d.selectNodeContents(b),d.setEnd(c.endContainer,c.endOffset),e.selectNodeContents(b),e.setStart(c.endContainer,c.endOffset),{left:d.toString().length,right:e.toString().length}},rangeSelectsSingleNode:function(a){var b=a.startContainer;return b===a.endContainer&&b.hasChildNodes()&&a.endOffset===a.startOffset+1},getSelectedParentElement:function(a){var b=null;return b=this.rangeSelectsSingleNode(a)&&3!==a.startContainer.childNodes[a.startOffset].nodeType?a.startContainer.childNodes[a.startOffset]:3===a.startContainer.nodeType?a.startContainer.parentNode:a.startContainer},getSelectionData:function(a){var c;for(a&&a.tagName&&(c=a.tagName.toLowerCase());a&&-1===b.parentElements.indexOf(c);)a=a.parentNode,a&&a.tagName&&(c=a.tagName.toLowerCase());return{el:a,tagName:c}}}}(document,window);var d,e;!function(){e={bold:{name:"bold",action:"bold",aria:"bold",tagNames:["b","strong"],style:{prop:"font-weight",value:"700|bold"},useQueryState:!0,contentDefault:"B",contentFA:''},italic:{name:"italic",action:"italic",aria:"italic",tagNames:["i","em"],style:{prop:"font-style",value:"italic"},useQueryState:!0,contentDefault:"I",contentFA:''},underline:{name:"underline",action:"underline",aria:"underline",tagNames:["u"],style:{prop:"text-decoration",value:"underline"},useQueryState:!0,contentDefault:"U",contentFA:''},strikethrough:{name:"strikethrough",action:"strikethrough",aria:"strike through",tagNames:["strike"],style:{prop:"text-decoration",value:"line-through"},useQueryState:!0,contentDefault:"A",contentFA:''},superscript:{name:"superscript",action:"superscript",aria:"superscript",tagNames:["sup"],contentDefault:"x1",contentFA:''},subscript:{name:"subscript",action:"subscript",aria:"subscript",tagNames:["sub"],contentDefault:"x1",contentFA:''},anchor:{name:"anchor",action:"anchor",aria:"link",tagNames:["a"],contentDefault:"#",contentFA:''},image:{name:"image",action:"image",aria:"image",tagNames:["img"],contentDefault:"image",contentFA:''},quote:{name:"quote",action:"append-blockquote",aria:"blockquote",tagNames:["blockquote"],contentDefault:"“",contentFA:''},orderedlist:{name:"orderedlist",action:"insertorderedlist",aria:"ordered list",tagNames:["ol"],useQueryState:!0,contentDefault:"1.",contentFA:''},unorderedlist:{name:"unorderedlist",action:"insertunorderedlist",aria:"unordered list",tagNames:["ul"],useQueryState:!0,contentDefault:"•",contentFA:''},pre:{name:"pre",action:"append-pre",aria:"preformatted text",tagNames:["pre"],contentDefault:"0101",contentFA:''},indent:{name:"indent",action:"indent",aria:"indent",tagNames:[],contentDefault:"→",contentFA:''},outdent:{name:"outdent",action:"outdent",aria:"outdent",tagNames:[],contentDefault:"←",contentFA:''},justifyCenter:{name:"justifyCenter",action:"justifyCenter",aria:"center justify",tagNames:[],style:{prop:"text-align",value:"center"},useQueryState:!0,contentDefault:"C",contentFA:''},justifyFull:{name:"justifyFull",action:"justifyFull",aria:"full justify",tagNames:[],style:{prop:"text-align",value:"justify"},useQueryState:!0,contentDefault:"J",contentFA:''},justifyLeft:{name:"justifyLeft",action:"justifyLeft",aria:"left justify",tagNames:[],style:{prop:"text-align",value:"left"},useQueryState:!0,contentDefault:"L",contentFA:''},justifyRight:{name:"justifyRight",action:"justifyRight",aria:"right justify",tagNames:[],style:{prop:"text-align",value:"right"},useQueryState:!0,contentDefault:"R",contentFA:''},header1:{name:"header1",action:function(a){return"append-"+a.firstHeader},aria:function(a){return a.firstHeader},tagNames:function(a){return[a.firstHeader]},contentDefault:"H1"},header2:{name:"header2",action:function(a){return"append-"+a.secondHeader},aria:function(a){return a.secondHeader},tagNames:function(a){return[a.secondHeader]},contentDefault:"H2"}},d=function(a,b){this.options=a,this.name=a.name,this.init(b)},d.prototype={init:function(a){this.base=a,this.button=this.createButton(),this.base.on(this.button,"click",this.handleClick.bind(this))},getButton:function(){return this.button},getAction:function(){return"function"==typeof this.options.action?this.options.action(this.base.options):this.options.action},getAria:function(){return"function"==typeof this.options.aria?this.options.aria(this.base.options):this.options.aria},getTagNames:function(){return"function"==typeof this.options.tagNames?this.options.tagNames(this.base.options):this.options.tagNames},createButton:function(){var a=this.base.options.ownerDocument.createElement("button"),b=this.options.contentDefault;return a.classList.add("medium-editor-action"),a.classList.add("medium-editor-action-"+this.name),a.setAttribute("data-action",this.getAction()),a.setAttribute("aria-label",this.getAria()),this.base.options.buttonLabels&&("fontawesome"===this.base.options.buttonLabels&&this.options.contentFA?b=this.options.contentFA:"object"==typeof this.base.options.buttonLabels&&this.base.options.buttonLabels[this.name]&&(b=this.base.options.buttonLabels[this.options.name])),a.innerHTML=b,a},handleClick:function(a){a.preventDefault(),a.stopPropagation();var b=this.getAction();this.base.selection||this.base.checkSelection(),this.isActive()?this.deactivate():this.activate(),b&&this.base.execAction(b,a)},isActive:function(){return this.button.classList.contains(this.base.options.activeButtonClass)},deactivate:function(){this.button.classList.remove(this.base.options.activeButtonClass),delete this.knownState},activate:function(){this.button.classList.add(this.base.options.activeButtonClass),delete this.knownState},queryCommandState:function(){var a=null;if(this.options.useQueryState)try{a=this.base.options.ownerDocument.queryCommandState(this.getAction())}catch(b){a=null}return a},shouldActivate:function(a){var b,c,d=!1,e=this.getTagNames();return this.knownState===!1||this.knownState===!0?this.knownState:(e&&e.length>0&&a.tagName&&(d=-1!==e.indexOf(a.tagName.toLowerCase())),!d&&this.options.style&&(b=this.options.style.value.split("|"),c=this.base.options.contentWindow.getComputedStyle(a,null).getPropertyValue(this.options.style.prop),b.forEach(function(a){this.knownState||(this.knownState=d=-1!==c.indexOf(a))}.bind(this))),d)}}}(window,document);var f;!function(){function a(){return[[new RegExp(/<[^>]*docs-internal-guid[^>]*>/gi),""],[new RegExp(/<\/b>(
]*>)?$/gi),""],[new RegExp(/\s+<\/span>/g)," "],[new RegExp(/
/g),"
"],[new RegExp(/]*(font-style:italic;font-weight:bold|font-weight:bold;font-style:italic)[^>]*>/gi),''],[new RegExp(/]*font-style:italic[^>]*>/gi),''],[new RegExp(/]*font-weight:bold[^>]*>/gi),''],[new RegExp(/<(\/?)(i|b|a)>/gi),"<$1$2>"],[new RegExp(/<a\s+href=("|”|“|“|”)([^&]+)("|”|“|“|”)>/gi),'']]}f={handlePaste:function(a,c,d){var e,f,g="",h="text/html",i="text/plain";if(a.classList.remove("medium-editor-placeholder"),!d.forcePlainText&&!d.cleanPastedHTML)return a;if(d.contentWindow.clipboardData&&void 0===c.clipboardData&&(c.clipboardData=d.contentWindow.clipboardData,h="Text",i="Text"),c.clipboardData&&c.clipboardData.getData&&!c.defaultPrevented){if(c.preventDefault(),d.cleanPastedHTML&&c.clipboardData.getData(h))return this.cleanPaste(c.clipboardData.getData(h),d);if(d.disableReturn||a.getAttribute("data-disable-return"))g=b.htmlEntities(c.clipboardData.getData(i)),b.insertHTMLCommand(d.ownerDocument,g);else{for(e=c.clipboardData.getData(i).split(/[\r\n]/g),f=0;f"+b.htmlEntities(e[f])+"");b.insertHTMLCommand(d.ownerDocument,g)}}},cleanPaste:function(d,e){var f,g,h,i=c.getSelectionElement(e.contentWindow),j=/
"),this.pasteHTML("
"+g.join("
")+"
",e.ownerDocument),e.ownerDocument.execCommand("insertText",!1,"\n"),g=i.querySelectorAll("a,p,div,br"),f=0;f"+e.innerHTML+"":e.innerHTML,e.parentNode.replaceChild(f,e);for(g=a.querySelectorAll("span"),d=0;de;e+=1)if(g=this.events[e],g[0]===a&&g[1]===b&&g[2]===c&&g[3]===d)return e;return-1},delay:function(a){var b=this;setTimeout(function(){b.isActive&&a()},this.options.delay)},removeAllEvents:function(){for(var a=this.events.pop();a;)a[0].removeEventListener(a[1],a[2],a[3]),a=this.events.pop()},initThrottledMethods:function(){var a=this;return this.handleResize=b.throttle(function(){a.isActive&&a.positionToolbarIfShown()}),this.handleBlur=b.throttle(function(){a.isActive&&!a.keepToolbarAlive&&a.hideToolbarActions()}),this},initElements:function(){var a,b=!1;for(a=0;a)?$/i,j=/h\d/i;(a.which===b.keyCode.BACKSPACE||a.which===b.keyCode.ENTER)&&g.previousElementSibling&&j.test(h)&&0===c.getCaretOffsets(g).left?a.which===b.keyCode.BACKSPACE&&i.test(g.previousElementSibling.innerHTML)?(g.previousElementSibling.parentNode.removeChild(g.previousElementSibling),a.preventDefault()):a.which===b.keyCode.ENTER&&(f=this.options.ownerDocument.createElement("p"),f.innerHTML="
",g.previousElementSibling.parentNode.insertBefore(f,g),a.preventDefault()):a.which===b.keyCode.DELETE&&g.nextElementSibling&&g.previousElementSibling&&!j.test(h)&&i.test(g.innerHTML)&&j.test(g.nextElementSibling.tagName)&&(d=document.createRange(),e=window.getSelection(),d.setStart(g.nextElementSibling,0),d.collapse(!0),e.removeAllRanges(),e.addRange(d),g.previousElementSibling.parentNode.removeChild(g),a.preventDefault())},initToolbar:function(){return this.toolbar?this:(this.toolbar=this.createToolbar(),this.keepToolbarAlive=!1,this.toolbarActions=this.toolbar.querySelector(".medium-editor-toolbar-actions"),this.anchorPreview=this.createAnchorPreview(),this.addExtensionForms(),this)},createToolbar:function(){var a=this.options.ownerDocument.createElement("div");return a.id="medium-editor-toolbar-"+this.id,a.className="medium-editor-toolbar",a.className+=this.options.staticToolbar?" static-toolbar":" stalker-toolbar",a.appendChild(this.toolbarButtons()),this.options.disableAnchorForm||(this.anchorExtension=new g(this),a.appendChild(this.anchorExtension.getForm())),this.options.elementsContainer.appendChild(a),a},toolbarButtons:function(){var a,c,d=this.options.ownerDocument.createElement("ul");return d.id="medium-editor-toolbar-actions"+this.id,d.className="medium-editor-toolbar-actions clearfix",this.commands.forEach(function(e){"function"==typeof e.getButton&&(c=e.getButton(this),a=this.options.ownerDocument.createElement("li"),b.isElement(c)?a.appendChild(c):a.innerHTML=c,d.appendChild(a))}.bind(this)),d},addExtensionForms:function(){var a,b;this.commands.forEach(function(c){c.hasForm&&(a="function"==typeof c.getForm?c.getForm():null),a&&(b="medium-editor-toolbar-form-"+c.name+"-"+this.id,a.className+=" medium-editor-toolbar-form",a.id=b,this.toolbar.appendChild(a))}.bind(this))},bindSelect:function(){var a,b,c=this;for(this.checkSelectionWrapper=function(a){return a&&this.anchorExtension&&this.anchorExtension.isClickIntoForm(a)?!1:void c.checkSelection()},b=function(a){setTimeout(function(){this.checkSelectionWrapper(a)}.bind(this),0)}.bind(this),this.on(this.options.ownerDocument.documentElement,"mouseup",this.checkSelectionWrapper),a=0;a'),c.onload=function(){var a=document.getElementById(d);a&&(a.removeAttribute("id"),a.removeAttribute("class"),a.src=c.result)}}}),this.classList.remove(c)},a=0;a<\/[\S]+>/gim,""),b=a.match(/<(p|h[0-6]|blockquote)>([\s\S]*?)<\/(p|h[0-6]|blockquote)>/g);return b?b.length:0},checkSelectionElement:function(a,d){var e,f,g,h=0;if(this.selection=a,this.selectionRange=this.selection.getRangeAt(0),this.options.standardizeSelectionStart&&this.selectionRange.startContainer.nodeValue&&this.selectionRange.startOffset===this.selectionRange.startContainer.nodeValue.length&&(f=b.findAdjacentTextNodeWithContent(c.getSelectionElement(this.options.contentWindow),this.selectionRange.startContainer,this.options.ownerDocument))){for(h=0;0===f.nodeValue.substr(h,1).trim().length;)h+=1;g=this.options.ownerDocument.createRange(),g.setStart(f,h),g.setEnd(this.selectionRange.endContainer,this.selectionRange.endOffset),this.selection.removeAllRanges(),this.selection.addRange(g),this.selectionRange=g}for(e=0;eg+this.elements[0].offsetHeight-this.toolbar.offsetHeight?this.toolbar.style.top=g+this.elements[0].offsetHeight+"px":d>g-this.toolbar.offsetHeight?(this.toolbar.classList.add("sticky-toolbar"),this.toolbar.style.top="0px"):(this.toolbar.classList.remove("sticky-toolbar"),this.toolbar.style.top=g-this.toolbar.offsetHeight+"px"):this.toolbar.style.top=g-this.toolbar.offsetHeight+"px",this.toolbar.style.left=this.options.toolbarAlign?"left"===this.options.toolbarAlign?f.left+"px":"center"===this.options.toolbarAlign?l-k+"px":f.right-this.toolbar.offsetWidth+"px":l-k+"px"):i.isCollapsed||(a=i.getRangeAt(0),b=a.getBoundingClientRect(),c=(b.left+b.right)/2,b.topc?j+k+"px":this.options.contentWindow.innerWidth-c0&&(a[0].className+=" "+this.options.firstButtonClass,a[a.length-1].className+=" "+this.options.lastButtonClass),this},execAction:function(a,b){a.indexOf("append-")>-1?(this.execFormatBlock(a.replace("append-","")),this.setToolbarPosition(),this.setToolbarButtonStates()):"anchor"===a?this.options.disableAnchorForm||this.triggerAnchorAction(b):"image"===a?this.options.ownerDocument.execCommand("insertImage",!1,this.options.contentWindow.getSelection()):(this.options.ownerDocument.execCommand(a,!1,null),this.setToolbarPosition(),0===a.indexOf("justify")&&this.setToolbarButtonStates())},showForm:function(a){this.toolbarActions.style.display="none",this.saveSelection();var b=document.getElementById(a);b.style.display="block",this.setToolbarPosition(),this.keepToolbarAlive=!0},hideForm:function(a){var b=document.getElementById(a.id);b.style.display="none",this.showToolbarActions(),this.setToolbarPosition(),this.restoreSelection()},rangeSelectsSingleNode:function(a){var b=a.startContainer;return b===a.endContainer&&b.hasChildNodes()&&a.endOffset===a.startOffset+1},getSelectedParentElement:function(){var a=null,b=this.selectionRange;return a=this.rangeSelectsSingleNode(b)&&3!==b.startContainer.childNodes[b.startOffset].nodeType?b.startContainer.childNodes[b.startOffset]:3===b.startContainer.nodeType?b.startContainer.parentNode:b.startContainer},triggerAnchorAction:function(){var a=c.getSelectedParentElement(this.selectionRange);return a.tagName&&"a"===a.tagName.toLowerCase()?this.options.ownerDocument.execCommand("unlink",!1,null):this.anchorExtension&&(this.anchorExtension.isDisplayed()?this.showToolbarActions():this.showAnchorForm()),this},execFormatBlock:function(a){var d=c.getSelectionData(this.selection.anchorNode);if("blockquote"===a&&d.el&&"blockquote"===d.el.parentNode.tagName.toLowerCase())return this.options.ownerDocument.execCommand("outdent",!1,null);if(d.tagName===a&&(a="p"),b.isIE){if("blockquote"===a)return this.options.ownerDocument.execCommand("indent",!1,a);a="<"+a+">"}return this.options.ownerDocument.execCommand("formatBlock",!1,a)},isToolbarShown:function(){return this.toolbar&&this.toolbar.classList.contains("medium-editor-toolbar-active")},showToolbar:function(){this.toolbar&&!this.isToolbarShown()&&(this.toolbar.classList.add("medium-editor-toolbar-active"),this.onShowToolbar&&this.onShowToolbar())},hideToolbar:function(){this.isToolbarShown()&&(this.toolbar.classList.remove("medium-editor-toolbar-active"),this.onHideToolbar&&this.onHideToolbar())},hideToolbarActions:function(){this.commands.forEach(function(a){a.onHide&&"function"==typeof a.onHide&&a.onHide()}),this.keepToolbarAlive=!1,this.hideToolbar()},showToolbarActions:function(){var a=this;this.anchorExtension&&this.anchorExtension.hideForm(),this.toolbarActions.style.display="block",this.keepToolbarAlive=!1,this.delay(function(){a.showToolbar()})},saveSelection:function(){this.selectionState=null;var a,c,d,e=this.options.contentWindow.getSelection(),f=-1;e.rangeCount>0&&(a=e.getRangeAt(0),c=a.cloneRange(),this.elements.forEach(function(c,d){return c===a.startContainer||b.isDescendant(c,a.startContainer)?(f=d,!1):void 0}),f>-1&&(c.selectNodeContents(this.elements[f]),c.setEnd(a.startContainer,a.startOffset),d=c.toString().length,this.selectionState={start:d,end:d+a.toString().length,editableElementIndex:f}))},restoreSelection:function(){if(this.selectionState){var a,b,c,d,e=this.elements[this.selectionState.editableElementIndex],f=0,g=this.options.ownerDocument.createRange(),h=[e],i=!1,j=!1;for(g.setStart(e,0),g.collapse(!0),a=h.pop();!j&&a;){if(3===a.nodeType)d=f+a.length,!i&&this.selectionState.start>=f&&this.selectionState.start<=d&&(g.setStart(a,this.selectionState.start-f),i=!0),i&&this.selectionState.end>=f&&this.selectionState.end<=d&&(g.setEnd(a,this.selectionState.end-f),j=!0),f=d;else for(b=a.childNodes.length-1;b>=0;)h.push(a.childNodes[b]),b-=1;j||(a=h.pop())}c=this.options.contentWindow.getSelection(),c.removeAllRanges(),c.addRange(g)}},showAnchorForm:function(a){this.anchorExtension&&(this.toolbarActions.style.display="none",this.saveSelection(),this.anchorExtension.showForm(),this.setToolbarPosition(),this.keepToolbarAlive=!0,this.anchorExtension.focus(a))},hideAnchorPreview:function(){this.anchorPreview.classList.remove("medium-editor-anchor-preview-active")},showAnchorPreview:function(a){if(this.anchorPreview.classList.contains("medium-editor-anchor-preview-active")||a.getAttribute("data-disable-preview"))return!0;var b,c,d=this,e=40,f=a.getBoundingClientRect(),g=(f.left+f.right)/2;return d.anchorPreview.querySelector("i").textContent=a.attributes.href.value,b=d.anchorPreview.offsetWidth/2,c=d.options.diffLeft-b,d.observeAnchorPreview(a),d.anchorPreview.classList.add("medium-toolbar-arrow-over"),d.anchorPreview.classList.remove("medium-toolbar-arrow-under"),d.anchorPreview.style.top=Math.round(e+f.bottom-d.options.diffTop+this.options.contentWindow.pageYOffset-d.anchorPreview.offsetHeight)+"px",d.anchorPreview.style.left=b>g?c+b+"px":this.options.contentWindow.innerWidth-gb.options.anchorPreviewHideDelay&&(b.hideAnchorPreview(),clearInterval(g),b.off(b.anchorPreview,"mouseover",e),b.off(b.anchorPreview,"mouseout",f),b.off(a,"mouseover",e),b.off(a,"mouseout",f))},200);this.on(b.anchorPreview,"mouseover",e),this.on(b.anchorPreview,"mouseout",f),this.on(a,"mouseover",e),this.on(a,"mouseout",f)},createAnchorPreview:function(){var a=this,b=this.options.ownerDocument.createElement("div");return b.id="medium-editor-anchor-preview-"+this.id,b.className="medium-editor-anchor-preview",b.innerHTML=this.anchorPreviewTemplate(),this.options.elementsContainer.appendChild(b),this.on(b,"click",function(){a.anchorPreviewClickHandler()}),b},anchorPreviewTemplate:function(){return'
'},anchorPreviewClickHandler:function(){if(!this.options.disableAnchorForm&&this.activeAnchor){var a=this,b=this.options.ownerDocument.createRange(),c=this.options.contentWindow.getSelection();b.selectNodeContents(a.activeAnchor),c.removeAllRanges(),c.addRange(b),this.delay(function(){a.activeAnchor&&a.showAnchorForm(a.activeAnchor.attributes.href.value),a.keepToolbarAlive=!1})}this.hideAnchorPreview()},editorAnchorObserver:function(a){var b=this,c=!0,d=function(){c=!1,b.off(b.activeAnchor,"mouseout",d)};if(a.target&&"a"===a.target.tagName.toLowerCase()){if(!/href=["']\S+["']/.test(a.target.outerHTML)||/href=["']#\S+["']/.test(a.target.outerHTML))return!0;if(this.isToolbarShown())return!0;this.activeAnchor=a.target,this.on(this.activeAnchor,"mouseout",d),this.delay(function(){c&&b.showAnchorPreview(a.target)})}},bindAnchorPreview:function(){var a,b=this;for(this.editorAnchorObserverWrapper=function(a){b.editorAnchorObserver(a)},a=0;aU',
contentFA: ''
@@ -47,6 +51,10 @@ var DefaultButton,
action: 'strikethrough',
aria: 'strike through',
tagNames: ['strike'],
+ style: {
+ prop: 'text-decoration',
+ value: 'line-through'
+ },
useQueryState: true,
contentDefault: 'A',
contentFA: ''
@@ -307,7 +315,8 @@ var DefaultButton,
shouldActivate: function (node) {
var isMatch = false,
tagNames = this.getTagNames(),
- styleVals;
+ styleVals,
+ computedStyle;
if (this.knownState === false || this.knownState === true) {
return this.knownState;
}
@@ -318,10 +327,10 @@ var DefaultButton,
if (!isMatch && this.options.style) {
styleVals = this.options.style.value.split('|');
+ computedStyle = this.base.options.contentWindow.getComputedStyle(node, null).getPropertyValue(this.options.style.prop);
styleVals.forEach(function (val) {
- this.knownState = isMatch = (this.base.options.contentWindow.getComputedStyle(node, null).getPropertyValue(this.options.style.prop).indexOf(val) !== -1);
- if (this.knownState) {
- return false;
+ if (!this.knownState) {
+ this.knownState = isMatch = (computedStyle.indexOf(val) !== -1);
}
}.bind(this));
}
diff --git a/src/js/core.js b/src/js/core.js
index 1070cc304..0a3a048bf 100644
--- a/src/js/core.js
+++ b/src/js/core.js
@@ -1,6 +1,6 @@
/*global module, console, define, FileReader,
mediumEditorUtil, ButtonsData, DefaultButton,
- pasteHandler, meSelection*/
+ pasteHandler, meSelection, AnchorExtension */
function MediumEditor(elements, options) {
'use strict';
@@ -12,7 +12,8 @@ function MediumEditor(elements, options) {
MediumEditor.statics = {
ButtonsData: ButtonsData,
- DefaultButton: DefaultButton
+ DefaultButton: DefaultButton,
+ AnchorExtension: AnchorExtension
};
MediumEditor.prototype = {
@@ -178,7 +179,6 @@ function MediumEditor(elements, options) {
if (addToolbar) {
this.initToolbar()
.bindButtons()
- .bindAnchorForm()
.bindAnchorPreview();
}
return this;
@@ -533,13 +533,6 @@ function MediumEditor(elements, options) {
this.toolbarActions = this.toolbar.querySelector('.medium-editor-toolbar-actions');
this.anchorPreview = this.createAnchorPreview();
- if (!this.options.disableAnchorForm) {
- this.anchorForm = this.toolbar.querySelector('.medium-editor-toolbar-form');
- this.anchorInput = this.anchorForm.querySelector('input.medium-editor-toolbar-input');
- this.anchorTarget = this.anchorForm.querySelector('input.medium-editor-toolbar-anchor-target');
- this.anchorButton = this.anchorForm.querySelector('input.medium-editor-toolbar-anchor-button');
- }
-
this.addExtensionForms();
return this;
@@ -558,7 +551,8 @@ function MediumEditor(elements, options) {
toolbar.appendChild(this.toolbarButtons());
if (!this.options.disableAnchorForm) {
- toolbar.appendChild(this.toolbarFormAnchor());
+ this.anchorExtension = new AnchorExtension(this);
+ toolbar.appendChild(this.anchorExtension.getForm());
}
this.options.elementsContainer.appendChild(toolbar);
return toolbar;
@@ -606,58 +600,6 @@ function MediumEditor(elements, options) {
}.bind(this));
},
- toolbarFormAnchor: function () {
- var anchor = this.options.ownerDocument.createElement('div'),
- input = this.options.ownerDocument.createElement('input'),
- target_label = this.options.ownerDocument.createElement('label'),
- target = this.options.ownerDocument.createElement('input'),
- button_label = this.options.ownerDocument.createElement('label'),
- button = this.options.ownerDocument.createElement('input'),
- close = this.options.ownerDocument.createElement('a'),
- save = this.options.ownerDocument.createElement('a');
-
- close.setAttribute('href', '#');
- close.className = 'medium-editor-toobar-close';
- close.innerHTML = '×';
-
- save.setAttribute('href', '#');
- save.className = 'medium-editor-toobar-save';
- save.innerHTML = '✓';
-
- input.setAttribute('type', 'text');
- input.className = 'medium-editor-toolbar-input';
- input.setAttribute('placeholder', this.options.anchorInputPlaceholder);
-
-
- target.setAttribute('type', 'checkbox');
- target.className = 'medium-editor-toolbar-anchor-target';
- target_label.innerHTML = this.options.anchorInputCheckboxLabel;
- target_label.insertBefore(target, target_label.firstChild);
-
- button.setAttribute('type', 'checkbox');
- button.className = 'medium-editor-toolbar-anchor-button';
- button_label.innerHTML = "Button";
- button_label.insertBefore(button, button_label.firstChild);
-
-
- anchor.className = 'medium-editor-toolbar-form';
- anchor.id = 'medium-editor-toolbar-form-anchor-' + this.id;
- anchor.appendChild(input);
-
- anchor.appendChild(save);
- anchor.appendChild(close);
-
- if (this.options.anchorTarget) {
- anchor.appendChild(target_label);
- }
-
- if (this.options.anchorButton) {
- anchor.appendChild(button_label);
- }
-
- return anchor;
- },
-
bindSelect: function () {
var self = this,
i,
@@ -665,7 +607,7 @@ function MediumEditor(elements, options) {
this.checkSelectionWrapper = function (e) {
// Do not close the toolbar when bluring the editable area and clicking into the anchor form
- if (!self.options.disableAnchorForm && e && self.clickingIntoArchorForm(e)) {
+ if (e && this.anchorExtension && this.anchorExtension.isClickIntoForm(e)) {
return false;
}
@@ -806,7 +748,7 @@ function MediumEditor(elements, options) {
if (!this.options.staticToolbar) {
this.hideToolbarActions();
- } else if (this.anchorForm && this.anchorForm.style.display === 'block') {
+ } else if (this.anchorExtension && this.anchorExtension.isDisplayed()) {
this.setToolbarButtonStates();
this.showToolbarActions();
}
@@ -825,16 +767,6 @@ function MediumEditor(elements, options) {
return this;
},
- clickingIntoArchorForm: function (e) {
- var self = this;
-
- if (e.type && e.type.toLowerCase() === 'blur' && e.relatedTarget && e.relatedTarget === self.anchorInput) {
- return true;
- }
-
- return false;
- },
-
hasMultiParagraphs: function () {
var selectionHtml = meSelection.getSelectionHtml.call(this).replace(/<[\S]+><\/[\S]+>/gim, ''),
hasMultiParagraphs = selectionHtml.match(/<(p|h[0-6]|blockquote)>([\s\S]*?)<\/(p|h[0-6]|blockquote)>/g);
@@ -1126,8 +1058,8 @@ function MediumEditor(elements, options) {
if (selectedParentElement.tagName &&
selectedParentElement.tagName.toLowerCase() === 'a') {
this.options.ownerDocument.execCommand('unlink', false, null);
- } else if (this.anchorForm) {
- if (this.anchorForm.style.display === 'block') {
+ } else if (this.anchorExtension) {
+ if (this.anchorExtension.isDisplayed()) {
this.showToolbarActions();
} else {
this.showAnchorForm();
@@ -1196,8 +1128,8 @@ function MediumEditor(elements, options) {
showToolbarActions: function () {
var self = this;
- if (this.anchorForm) {
- this.anchorForm.style.display = 'none';
+ if (this.anchorExtension) {
+ this.anchorExtension.hideForm();
}
this.toolbarActions.style.display = 'block';
this.keepToolbarAlive = false;
@@ -1299,100 +1231,16 @@ function MediumEditor(elements, options) {
},
showAnchorForm: function (link_value) {
- if (!this.anchorForm) {
+ if (!this.anchorExtension) {
return;
}
this.toolbarActions.style.display = 'none';
this.saveSelection();
- this.anchorForm.style.display = 'block';
+ this.anchorExtension.showForm();
this.setToolbarPosition();
this.keepToolbarAlive = true;
- this.anchorInput.focus();
- this.anchorInput.value = link_value || '';
- },
-
- bindAnchorForm: function () {
- if (!this.anchorForm) {
- return this;
- }
-
- var linkCancel = this.anchorForm.querySelector('a.medium-editor-toobar-close'),
- linkSave = this.anchorForm.querySelector('a.medium-editor-toobar-save'),
- self = this;
-
- this.on(this.anchorForm, 'click', function (e) {
- e.stopPropagation();
- self.keepToolbarAlive = true;
- });
-
- this.on(this.anchorInput, 'keyup', function (e) {
- var button = null,
- target;
-
- if (e.keyCode === mediumEditorUtil.keyCode.ENTER) {
- e.preventDefault();
- if (self.options.anchorTarget && self.anchorTarget.checked) {
- target = "_blank";
- } else {
- target = "_self";
- }
-
- if (self.options.anchorButton && self.anchorButton.checked) {
- button = self.options.anchorButtonClass;
- }
-
- self.createLink(this, target, button);
- } else if (e.keyCode === mediumEditorUtil.keyCode.ESCAPE) {
- e.preventDefault();
- self.showToolbarActions();
- self.restoreSelection();
- }
- });
-
- this.on(linkSave, 'click', function (e) {
- var button = null,
- target;
- e.preventDefault();
- if (self.options.anchorTarget && self.anchorTarget.checked) {
- target = "_blank";
- } else {
- target = "_self";
- }
-
- if (self.options.anchorButton && self.anchorButton.checked) {
- button = self.options.anchorButtonClass;
- }
-
- self.createLink(self.anchorInput, target, button);
- }, true);
-
- this.on(this.anchorInput, 'click', function (e) {
- // make sure not to hide form when cliking into the input
- e.stopPropagation();
- self.keepToolbarAlive = true;
- });
-
- // Hide the anchor form when focusing outside of it.
- this.on(this.options.ownerDocument.body, 'click', function (e) {
- if (e.target !== self.anchorForm && !mediumEditorUtil.isDescendant(self.anchorForm, e.target) && !mediumEditorUtil.isDescendant(self.toolbarActions, e.target)) {
- self.keepToolbarAlive = false;
- self.checkSelection();
- }
- }, true);
- this.on(this.options.ownerDocument.body, 'focus', function (e) {
- if (e.target !== self.anchorForm && !mediumEditorUtil.isDescendant(self.anchorForm, e.target) && !mediumEditorUtil.isDescendant(self.toolbarActions, e.target)) {
- self.keepToolbarAlive = false;
- self.checkSelection();
- }
- }, true);
-
- this.on(linkCancel, 'click', function (e) {
- e.preventDefault();
- self.showToolbarActions();
- self.restoreSelection();
- });
- return this;
+ this.anchorExtension.focus(link_value);
},
hideAnchorPreview: function () {
@@ -1509,7 +1357,7 @@ function MediumEditor(elements, options) {
sel.removeAllRanges();
sel.addRange(range);
// Using setTimeout + options.delay because:
- // We may actually be displaying the anchor preview, which should be controlled by options.delay
+ // We may actually be displaying the anchor form, which should be controlled by options.delay
this.delay(function () {
if (self.activeAnchor) {
self.showAnchorForm(self.activeAnchor.attributes.href.value);
@@ -1695,6 +1543,10 @@ function MediumEditor(elements, options) {
}
}.bind(this));
+ if (this.anchorExtension) {
+ this.anchorExtension.deactivate();
+ }
+
this.removeAllEvents();
},
diff --git a/src/js/extension-anchor.js b/src/js/extension-anchor.js
new file mode 100644
index 000000000..6772ab256
--- /dev/null
+++ b/src/js/extension-anchor.js
@@ -0,0 +1,205 @@
+/*global mediumEditorUtil, console */
+
+var AnchorExtension;
+
+(function (window, document) {
+ 'use strict';
+
+ AnchorExtension = function (instance) {
+ this.base = instance;
+ };
+
+ AnchorExtension.prototype = {
+
+ getForm: function () {
+ if (!this.anchorForm) {
+ this.anchorForm = this.createForm();
+ }
+ return this.anchorForm;
+ },
+
+ getInput: function () {
+ return this.getForm().querySelector('input.medium-editor-toolbar-input');
+ },
+
+ deactivate: function () {
+ if (!this.anchorForm) {
+ return false;
+ }
+
+ if (this.anchorForm.parentNode) {
+ this.anchorForm.parentNode.removeChild(this.anchorForm);
+ }
+
+ delete this.anchorForm;
+ },
+
+ doLinkCreation: function () {
+ var button = null,
+ target,
+ targetCheckbox = this.getForm().querySelector('.medium-editor-toolbar-anchor-target'),
+ buttonCheckbox = this.getForm().querySelector('.medium-editor-toolbar-anchor-button');
+
+ if (targetCheckbox && targetCheckbox.checked) {
+ target = "_blank";
+ } else {
+ target = "_self";
+ }
+
+ if (buttonCheckbox && buttonCheckbox.checked) {
+ button = this.base.options.anchorButtonClass;
+ }
+
+ this.base.createLink(this.getInput(), target, button);
+ },
+
+ doFormCancel: function () {
+ this.base.showToolbarActions();
+ this.base.restoreSelection();
+ },
+
+ handleOutsideInteraction: function (event) {
+ if (event.target !== this.getForm() &&
+ !mediumEditorUtil.isDescendant(this.getForm(), event.target) &&
+ !mediumEditorUtil.isDescendant(this.base.toolbarActions, event.target)) {
+ this.base.keepToolbarAlive = false;
+ this.base.checkSelection();
+ }
+ },
+
+ createForm: function () {
+ var doc = this.base.options.ownerDocument,
+ form = doc.createElement('div'),
+ input = doc.createElement('input'),
+ close = doc.createElement('a'),
+ save = doc.createElement('a'),
+ target,
+ target_label,
+ button,
+ button_label;
+
+ // Anchor Form (div)
+ form.className = 'medium-editor-toolbar-form';
+ form.id = 'medium-editor-toolbar-form-anchor-' + this.base.id;
+
+ // Handle clicks on the form itself
+ this.base.on(form, 'click', function (event) {
+ event.stopPropagation();
+ this.base.keepToolbarAlive = true;
+ }.bind(this));
+
+ // Add url textbox
+ input.setAttribute('type', 'text');
+ input.className = 'medium-editor-toolbar-input';
+ input.setAttribute('placeholder', this.base.options.anchorInputPlaceholder);
+ form.appendChild(input);
+
+ // Handle typing in the textbox
+ this.base.on(input, 'keyup', function (event) {
+ // For ENTER -> create the anchor
+ if (event.keyCode === mediumEditorUtil.keyCode.ENTER) {
+ event.preventDefault();
+ this.doLinkCreation();
+ return;
+ }
+
+ // For ESCAPE -> close the form
+ if (event.keyCode === mediumEditorUtil.keyCode.ESCAPE) {
+ event.preventDefault();
+ this.doFormCancel();
+ }
+ }.bind(this));
+
+ // Handle clicks into the textbox
+ this.base.on(input, 'click', function (event) {
+ // make sure not to hide form when cliking into the input
+ event.stopPropagation();
+ this.base.keepToolbarAlive = true;
+ }.bind(this));
+
+ // Add save buton
+ save.setAttribute('href', '#');
+ save.className = 'medium-editor-toobar-save';
+ save.innerHTML = '✓';
+ form.appendChild(save);
+
+ // Handle save button clicks (capture)
+ this.base.on(save, 'click', function (event) {
+ // Clicking Save -> create the anchor
+ event.preventDefault();
+ this.doLinkCreation();
+ }.bind(this), true);
+
+ // Add close button
+ close.setAttribute('href', '#');
+ close.className = 'medium-editor-toobar-close';
+ close.innerHTML = '×';
+ form.appendChild(close);
+
+ // Handle close button clicks
+ this.base.on(close, 'click', function (event) {
+ // Click Close -> close the form
+ event.preventDefault();
+ this.doFormCancel();
+ }.bind(this));
+
+ // (Optional) Add 'open in new window' checkbox
+ if (this.base.options.anchorTarget) {
+ target = doc.createElement('input');
+ target.setAttribute('type', 'checkbox');
+ target.className = 'medium-editor-toolbar-anchor-target';
+
+ target_label = doc.createElement('label');
+ target_label.innerHTML = this.base.options.anchorInputCheckboxLabel;
+ target_label.insertBefore(target, target_label.firstChild);
+
+ form.appendChild(target_label);
+ }
+
+ // (Optional) Add 'add button class to anchor' checkbox
+ if (this.base.options.anchorButton) {
+ button = doc.createElement('input');
+ button.setAttribute('type', 'checkbox');
+ button.className = 'medium-editor-toolbar-anchor-button';
+
+ button_label = doc.createElement('label');
+ button_label.innerHTML = "Button";
+ button_label.insertBefore(button, button_label.firstChild);
+
+ form.appendChild(button_label);
+ }
+
+ // Handle click (capture) & focus (capture) outside of the form
+ this.base.on(doc.body, 'click', this.handleOutsideInteraction.bind(this), true);
+ this.base.on(doc.body, 'focus', this.handleOutsideInteraction.bind(this), true);
+
+ return form;
+ },
+
+ focus: function (value) {
+ var input = this.getInput();
+ input.focus();
+ input.value = value || '';
+ },
+
+ hideForm: function () {
+ this.getForm().style.display = 'none';
+ },
+
+ showForm: function () {
+ this.getForm().style.display = 'block';
+ },
+
+ isDisplayed: function () {
+ return this.getForm().style.display === 'block';
+ },
+
+ isClickIntoForm: function (event) {
+ return (event &&
+ event.type &&
+ event.type.toLowerCase() === 'blur' &&
+ event.relatedTarget &&
+ event.relatedTarget === this.getInput());
+ }
+ };
+}(window, document));
\ No newline at end of file