diff --git a/dist/js/medium.editor.js b/dist/js/medium.editor.js index 8bff9f371..eaa847319 100644 --- a/dist/js/medium.editor.js +++ b/dist/js/medium.editor.js @@ -19,11 +19,6 @@ function MediumEditor(selector, options) { return b; } - // https://developer.mozilla.org/en-US/docs/Web/API/window.scrollY?redirectlocale=en-US&redirectslug=DOM/window.scrollY - function getDocumentScrollY() { - return (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop; - } - // http://stackoverflow.com/questions/5605401/insert-link-in-contenteditable-element // by Tim Down function saveSelection() { @@ -53,45 +48,6 @@ function MediumEditor(selector, options) { } } - // http://stackoverflow.com/questions/6846230/javascript-text-selection-page-coordinates - // by Tim Down - function getSelectionCoords() { - var sel = window.getSelection(), - range, - rect, - x = 0, - y = 0; - if (sel.rangeCount) { - range = sel.getRangeAt(0).cloneRange(); - if (range.getClientRects) { - range.collapse(false); - rect = range.getClientRects()[0]; - x = rect.left; - y = rect.top; - } - } - return [x, y]; - } - - // http://stackoverflow.com/questions/12603397/calculate-width-height-of-the-selected-text-javascript - // by Tim Down - function getSelectionDimensions() { - var sel = window.getSelection(), - range, - rect, - width = 0, - height = 0; - if (sel.rangeCount) { - range = sel.getRangeAt(0).cloneRange(); - if (range.getBoundingClientRect) { - rect = range.getBoundingClientRect(); - width = rect.right - rect.left; - height = rect.bottom - rect.top; - } - } - return [width, height]; - } - // http://stackoverflow.com/questions/6139107/programatically-select-text-in-a-contenteditable-html-element // by Tim Down & yckart function selectElementContents(el) { @@ -126,7 +82,8 @@ function MediumEditor(selector, options) { .initToolbar() .bindSelect() .bindButtons() - .bindAnchorForm(); + .bindAnchorForm() + .bindWindowActions(); }, initElements: function (selector) { @@ -206,10 +163,11 @@ function MediumEditor(selector, options) { }, setToolbarPosition: function () { - var coords = getSelectionCoords(), - selDimensions = getSelectionDimensions(); - this.toolbar.style.left = (coords[0] - (this.toolbar.offsetWidth / 2) - (selDimensions[0] / 2) + this.options.diffLeft) + 'px'; - this.toolbar.style.top = (coords[1] + getDocumentScrollY() - this.toolbar.offsetHeight + this.options.diffTop) + 'px'; + var selection = window.getSelection(), + range = selection.getRangeAt(0), + boundary = range.getBoundingClientRect(); + this.toolbar.style.top = boundary.top - 5 + window.pageYOffset - this.toolbar.offsetHeight + 'px'; + this.toolbar.style.left = ((boundary.left + boundary.right) / 2) - (this.toolbar.offsetWidth / 2) + 'px'; return this; }, @@ -394,6 +352,8 @@ function MediumEditor(selector, options) { self.showToolbarActions(); restoreSelection(self.savedSelection); }; + + return this; }, createLink: function (input) { @@ -401,6 +361,20 @@ function MediumEditor(selector, options) { document.execCommand('CreateLink', false, input.value); this.showToolbarActions(); input.value = ''; + }, + + bindWindowActions: function () { + var timerResize, + self = this; + + window.addEventListener('resize', function(e) { + clearTimeout(timerResize); + timerResize = setTimeout(function () { + self.setToolbarPosition(); + }, 100); + }); + + return this; } }; }(window, document)); diff --git a/dist/js/medium.editor.min.js b/dist/js/medium.editor.min.js index e14160f44..18e4790fc 100644 --- a/dist/js/medium.editor.min.js +++ b/dist/js/medium.editor.min.js @@ -1 +1 @@ -function MediumEditor(a,b){"use strict";return this.init(a,b)}!function(a,b){"use strict";function c(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}function d(){return void 0!==a.pageYOffset?a.pageYOffset:(b.documentElement||b.body.parentNode||b.body).scrollTop}function e(){var b,c,d,e=a.getSelection();if(e.getRangeAt&&e.rangeCount){for(d=[],b=0,c=e.rangeCount;c>b;b+=1)d.push(e.getRangeAt(b));return d}return null}function f(b){var c,d,e=a.getSelection();if(b)for(e.removeAllRanges(),c=0,d=b.length;d>c;c+=1)e.addRange(b[c])}function g(){var b,c,d=a.getSelection(),e=0,f=0;return d.rangeCount&&(b=d.getRangeAt(0).cloneRange(),b.getClientRects&&(b.collapse(!1),c=b.getClientRects()[0],e=c.left,f=c.top)),[e,f]}function h(){var b,c,d=a.getSelection(),e=0,f=0;return d.rangeCount&&(b=d.getRangeAt(0).cloneRange(),b.getBoundingClientRect&&(c=b.getBoundingClientRect(),e=c.right-c.left,f=c.bottom-c.top)),[e,f]}function i(c){var d=a.getSelection(),e=b.createRange();e.selectNodeContents(c),d.removeAllRanges(),d.addRange(e)}MediumEditor.prototype={defaults:{excludedActions:[],anchorInputPlaceholder:"Paste or type a link",diffLeft:0,diffTop:-10,firstHeader:"h3",secondHeader:"h4",delay:0},init:function(a,d){return this.elements=b.querySelectorAll(a),0!==this.elements.length?(this.parentElements=["p","h1","h2","h3","h4","h5","h6","q"],this.id=b.querySelectorAll(".medium-editor-toolbar").length+1,this.options=c(d,this.defaults),this.initElements(a).initToolbar().bindSelect().bindButtons().bindAnchorForm()):void 0},initElements:function(){var a;for(a=0;a
  • '+'
  • '+'
  • '+""+'
    '+' ×'+"
    "},initToolbar:function(){return this.toolbar=this.createToolbar(),this.keepToolbarAlive=!1,this.anchorForm=this.toolbar.querySelector(".medium-editor-toolbar-form-anchor"),this.toolbarActions=this.toolbar.querySelector(".medium-editor-toolbar-actions"),this},createToolbar:function(){var a=b.createElement("div");return a.id="medium-editor-toolbar-"+this.id,a.className="medium-editor-toolbar",a.innerHTML=this.toolbarTemplate(),b.getElementsByTagName("body")[0].appendChild(a),a},bindSelect:function(){var a,b=this,c="",d=function(a){clearTimeout(c),setTimeout(function(){b.checkSelection(a)},b.options.delay)};for(a=0;a-1?"none":"block"},checkActiveButtons:function(){var a=this.selection.anchorNode;for(a.tagName||(a=this.selection.anchorNode.parentNode);void 0!==a.tagName&&-1===this.parentElements.indexOf(a.tagName);)this.activateButton(a.tagName.toLowerCase()),a=a.parentNode},activateButton:function(a){var b=this.toolbar.querySelector('[data-element="'+a+'"]');null!==b&&-1===b.className.indexOf("medium-editor-button-active")&&(b.className+=" medium-editor-button-active")},bindButtons:function(){var a,b=this.toolbar.querySelectorAll("button"),c=this,d=function(a){a.preventDefault(),a.stopPropagation(),void 0===c.selection&&c.checkSelection(a),this.className.indexOf("medium-editor-button-active")>-1?this.className=this.className.replace(/medium-editor-button-active/g,"").replace(/\s{2}/g," "):this.className+=" medium-editor-button-active",c.execAction(this.getAttribute("data-action"),a)};for(a=0;a-1?(this.appendEl(a.replace("append-","")),this.setToolbarButtonStates()):"anchor"===a?this.triggerAnchorAction(c):(b.execCommand(a,null,!1),this.setToolbarPosition())},triggerAnchorAction:function(){return"a"===this.selection.anchorNode.parentNode.tagName.toLowerCase()?b.execCommand("unlink",null,!1):"block"===this.anchorForm.style.display?this.showToolbarActions():this.showAnchorForm(),this},appendEl:function(a){var c,d=this.selection.anchorNode;for(d&&d.tagName&&(c=d.tagName.toLowerCase());-1===this.parentElements.indexOf(c);)d=d.parentNode,c=d.tagName.toLowerCase();c===a&&(a="p"),a=b.createElement(a),this.transferAttributes(d,a),a.innerHTML=d.innerHTML,d.parentNode.replaceChild(a,d),i(a),this.bindElementToolbarEvents(a)},transferAttributes:function(a,b){Array.prototype.slice.call(a.attributes).forEach(function(a){b.setAttribute(a.name,a.value)})},getFirstChild:function(a){for(var b=a.firstChild;null!==b&&1!==b.nodeType;)b=b.nextSibling;return b},bindElementToolbarEvents:function(a){var b=this;a.onmouseup=function(a){b.checkSelection(a)},a.onkeyup=function(a){b.checkSelection(a)}},showToolbarActions:function(){var a,c=this;this.anchorForm.style.display="none",this.toolbarActions.style.display="block",this.keepToolbarAlive=!1,clearTimeout(a),a=setTimeout(function(){b.onclick=function(){c.keepToolbarAlive=!1,c.toolbar.style.display="none",this.onclick=""}},300)},showAnchorForm:function(){var a=this.anchorForm.querySelector("input");this.toolbarActions.style.display="none",this.savedSelection=e(),this.anchorForm.style.display="block",this.keepToolbarAlive=!0,a.focus(),a.value=""},bindAnchorForm:function(){var a=this.anchorForm.querySelector("input"),b=this.anchorForm.querySelector("a"),c=this;this.anchorForm.onclick=function(a){a.stopPropagation()},a.onkeyup=function(a){13===a.keyCode&&(a.preventDefault(),c.createLink(this))},b.onclick=function(){c.showToolbarActions(),f(c.savedSelection)}},createLink:function(a){f(this.savedSelection),b.execCommand("CreateLink",!1,a.value),this.showToolbarActions(),a.value=""}}}(window,document); \ No newline at end of file +function MediumEditor(a,b){"use strict";return this.init(a,b)}!function(a,b){"use strict";function c(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}function d(){var b,c,d,e=a.getSelection();if(e.getRangeAt&&e.rangeCount){for(d=[],b=0,c=e.rangeCount;c>b;b+=1)d.push(e.getRangeAt(b));return d}return null}function e(b){var c,d,e=a.getSelection();if(b)for(e.removeAllRanges(),c=0,d=b.length;d>c;c+=1)e.addRange(b[c])}function f(c){var d=a.getSelection(),e=b.createRange();e.selectNodeContents(c),d.removeAllRanges(),d.addRange(e)}MediumEditor.prototype={defaults:{excludedActions:[],anchorInputPlaceholder:"Paste or type a link",diffLeft:0,diffTop:-10,firstHeader:"h3",secondHeader:"h4",delay:0},init:function(a,d){return this.elements=b.querySelectorAll(a),0!==this.elements.length?(this.parentElements=["p","h1","h2","h3","h4","h5","h6","q"],this.id=b.querySelectorAll(".medium-editor-toolbar").length+1,this.options=c(d,this.defaults),this.initElements(a).initToolbar().bindSelect().bindButtons().bindAnchorForm().bindWindowActions()):void 0},initElements:function(){var a;for(a=0;a
  • '+'
  • '+'
  • '+""+'
    '+' ×'+"
    "},initToolbar:function(){return this.toolbar=this.createToolbar(),this.keepToolbarAlive=!1,this.anchorForm=this.toolbar.querySelector(".medium-editor-toolbar-form-anchor"),this.toolbarActions=this.toolbar.querySelector(".medium-editor-toolbar-actions"),this},createToolbar:function(){var a=b.createElement("div");return a.id="medium-editor-toolbar-"+this.id,a.className="medium-editor-toolbar",a.innerHTML=this.toolbarTemplate(),b.getElementsByTagName("body")[0].appendChild(a),a},bindSelect:function(){var a,b=this,c="",d=function(a){clearTimeout(c),setTimeout(function(){b.checkSelection(a)},b.options.delay)};for(a=0;a-1?"none":"block"},checkActiveButtons:function(){var a=this.selection.anchorNode;for(a.tagName||(a=this.selection.anchorNode.parentNode);void 0!==a.tagName&&-1===this.parentElements.indexOf(a.tagName);)this.activateButton(a.tagName.toLowerCase()),a=a.parentNode},activateButton:function(a){var b=this.toolbar.querySelector('[data-element="'+a+'"]');null!==b&&-1===b.className.indexOf("medium-editor-button-active")&&(b.className+=" medium-editor-button-active")},bindButtons:function(){var a,b=this.toolbar.querySelectorAll("button"),c=this,d=function(a){a.preventDefault(),a.stopPropagation(),void 0===c.selection&&c.checkSelection(a),this.className.indexOf("medium-editor-button-active")>-1?this.className=this.className.replace(/medium-editor-button-active/g,"").replace(/\s{2}/g," "):this.className+=" medium-editor-button-active",c.execAction(this.getAttribute("data-action"),a)};for(a=0;a-1?(this.appendEl(a.replace("append-","")),this.setToolbarButtonStates()):"anchor"===a?this.triggerAnchorAction(c):(b.execCommand(a,null,!1),this.setToolbarPosition())},triggerAnchorAction:function(){return"a"===this.selection.anchorNode.parentNode.tagName.toLowerCase()?b.execCommand("unlink",null,!1):"block"===this.anchorForm.style.display?this.showToolbarActions():this.showAnchorForm(),this},appendEl:function(a){var c,d=this.selection.anchorNode;for(d&&d.tagName&&(c=d.tagName.toLowerCase());-1===this.parentElements.indexOf(c);)d=d.parentNode,c=d.tagName.toLowerCase();c===a&&(a="p"),a=b.createElement(a),this.transferAttributes(d,a),a.innerHTML=d.innerHTML,d.parentNode.replaceChild(a,d),f(a),this.bindElementToolbarEvents(a)},transferAttributes:function(a,b){Array.prototype.slice.call(a.attributes).forEach(function(a){b.setAttribute(a.name,a.value)})},getFirstChild:function(a){for(var b=a.firstChild;null!==b&&1!==b.nodeType;)b=b.nextSibling;return b},bindElementToolbarEvents:function(a){var b=this;a.onmouseup=function(a){b.checkSelection(a)},a.onkeyup=function(a){b.checkSelection(a)}},showToolbarActions:function(){var a,c=this;this.anchorForm.style.display="none",this.toolbarActions.style.display="block",this.keepToolbarAlive=!1,clearTimeout(a),a=setTimeout(function(){b.onclick=function(){c.keepToolbarAlive=!1,c.toolbar.style.display="none",this.onclick=""}},300)},showAnchorForm:function(){var a=this.anchorForm.querySelector("input");this.toolbarActions.style.display="none",this.savedSelection=d(),this.anchorForm.style.display="block",this.keepToolbarAlive=!0,a.focus(),a.value=""},bindAnchorForm:function(){var a=this.anchorForm.querySelector("input"),b=this.anchorForm.querySelector("a"),c=this;return this.anchorForm.onclick=function(a){a.stopPropagation()},a.onkeyup=function(a){13===a.keyCode&&(a.preventDefault(),c.createLink(this))},b.onclick=function(){c.showToolbarActions(),e(c.savedSelection)},this},createLink:function(a){e(this.savedSelection),b.execCommand("CreateLink",!1,a.value),this.showToolbarActions(),a.value=""},bindWindowActions:function(){var b,c=this;return a.addEventListener("resize",function(){clearTimeout(b),b=setTimeout(function(){c.setToolbarPosition()},100)}),this}}}(window,document); \ No newline at end of file diff --git a/src/js/medium.editor.js b/src/js/medium.editor.js index 96860bd0d..4df974f12 100644 --- a/src/js/medium.editor.js +++ b/src/js/medium.editor.js @@ -21,11 +21,6 @@ function MediumEditor(selector, options) { return b; } - // https://developer.mozilla.org/en-US/docs/Web/API/window.scrollY?redirectlocale=en-US&redirectslug=DOM/window.scrollY - function getDocumentScrollY() { - return (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop; - } - // http://stackoverflow.com/questions/5605401/insert-link-in-contenteditable-element // by Tim Down function saveSelection() { @@ -55,45 +50,6 @@ function MediumEditor(selector, options) { } } - // http://stackoverflow.com/questions/6846230/javascript-text-selection-page-coordinates - // by Tim Down - function getSelectionCoords() { - var sel = window.getSelection(), - range, - rect, - x = 0, - y = 0; - if (sel.rangeCount) { - range = sel.getRangeAt(0).cloneRange(); - if (range.getClientRects) { - range.collapse(false); - rect = range.getClientRects()[0]; - x = rect.left; - y = rect.top; - } - } - return [x, y]; - } - - // http://stackoverflow.com/questions/12603397/calculate-width-height-of-the-selected-text-javascript - // by Tim Down - function getSelectionDimensions() { - var sel = window.getSelection(), - range, - rect, - width = 0, - height = 0; - if (sel.rangeCount) { - range = sel.getRangeAt(0).cloneRange(); - if (range.getBoundingClientRect) { - rect = range.getBoundingClientRect(); - width = rect.right - rect.left; - height = rect.bottom - rect.top; - } - } - return [width, height]; - } - // http://stackoverflow.com/questions/6139107/programatically-select-text-in-a-contenteditable-html-element // by Tim Down & yckart function selectElementContents(el) { @@ -128,7 +84,8 @@ function MediumEditor(selector, options) { .initToolbar() .bindSelect() .bindButtons() - .bindAnchorForm(); + .bindAnchorForm() + .bindWindowActions(); }, initElements: function (selector) { @@ -208,10 +165,11 @@ function MediumEditor(selector, options) { }, setToolbarPosition: function () { - var coords = getSelectionCoords(), - selDimensions = getSelectionDimensions(); - this.toolbar.style.left = (coords[0] - (this.toolbar.offsetWidth / 2) - (selDimensions[0] / 2) + this.options.diffLeft) + 'px'; - this.toolbar.style.top = (coords[1] + getDocumentScrollY() - this.toolbar.offsetHeight + this.options.diffTop) + 'px'; + var selection = window.getSelection(), + range = selection.getRangeAt(0), + boundary = range.getBoundingClientRect(); + this.toolbar.style.top = boundary.top - 5 + window.pageYOffset - this.toolbar.offsetHeight + 'px'; + this.toolbar.style.left = ((boundary.left + boundary.right) / 2) - (this.toolbar.offsetWidth / 2) + 'px'; return this; }, @@ -396,6 +354,8 @@ function MediumEditor(selector, options) { self.showToolbarActions(); restoreSelection(self.savedSelection); }; + + return this; }, createLink: function (input) { @@ -403,6 +363,20 @@ function MediumEditor(selector, options) { document.execCommand('CreateLink', false, input.value); this.showToolbarActions(); input.value = ''; + }, + + bindWindowActions: function () { + var timerResize, + self = this; + + window.addEventListener('resize', function(e) { + clearTimeout(timerResize); + timerResize = setTimeout(function () { + self.setToolbarPosition(); + }, 100); + }); + + return this; } }; }(window, document));