From fdb732bbd257742e77307df415f6b492f80ca81a Mon Sep 17 00:00:00 2001 From: Ahmet Sezgin Duran Date: Wed, 19 Nov 2014 19:45:41 +0200 Subject: [PATCH] Update Medium Editor files --- vendor/assets/javascripts/medium-editor.js | 139 ++++++++++-------- .../medium-editor/medium-editor.css | 16 -- 2 files changed, 77 insertions(+), 78 deletions(-) diff --git a/vendor/assets/javascripts/medium-editor.js b/vendor/assets/javascripts/medium-editor.js index 47a54dc..8d6f35c 100644 --- a/vendor/assets/javascripts/medium-editor.js +++ b/vendor/assets/javascripts/medium-editor.js @@ -6,6 +6,13 @@ function MediumEditor(elements, options) { if (typeof module === 'object') { module.exports = MediumEditor; } +// AMD support +else if (typeof define === 'function' && define.amd) { + define(function () { + 'use strict'; + return MediumEditor; + }); +} (function (window, document) { 'use strict'; @@ -40,7 +47,7 @@ if (typeof module === 'object') { var i, len, ranges, - sel = window.getSelection(); + sel = this.options.contentWindow.getSelection(); if (sel.getRangeAt && sel.rangeCount) { ranges = []; for (i = 0, len = sel.rangeCount; i < len; i += 1) { @@ -54,7 +61,7 @@ if (typeof module === 'object') { function restoreSelection(savedSel) { var i, len, - sel = window.getSelection(); + sel = this.options.contentWindow.getSelection(); if (savedSel) { sel.removeAllRanges(); for (i = 0, len = savedSel.length; i < len; i += 1) { @@ -66,7 +73,7 @@ if (typeof module === 'object') { // http://stackoverflow.com/questions/1197401/how-can-i-get-the-element-the-caret-is-in-with-javascript-when-using-contentedi // by You function getSelectionStart() { - var node = document.getSelection().anchorNode, + var node = this.options.ownerDocument.getSelection().anchorNode, startNode = (node && node.nodeType === 3 ? node.parentNode : node); return startNode; } @@ -79,18 +86,18 @@ if (typeof module === 'object') { sel, len, container; - if (window.getSelection !== undefined) { - sel = window.getSelection(); + if (this.options.contentWindow.getSelection !== undefined) { + sel = this.options.contentWindow.getSelection(); if (sel.rangeCount) { - container = document.createElement('div'); + container = this.options.ownerDocument.createElement('div'); for (i = 0, len = sel.rangeCount; i < len; i += 1) { container.appendChild(sel.getRangeAt(i).cloneContents()); } html = container.innerHTML; } - } else if (document.selection !== undefined) { - if (document.selection.type === 'Text') { - html = document.selection.createRange().htmlText; + } else if (this.options.ownerDocument.selection !== undefined) { + if (this.options.ownerDocument.selection.type === 'Text') { + html = this.options.ownerDocument.selection.createRange().htmlText; } } return html; @@ -118,6 +125,8 @@ if (typeof module === 'object') { disableToolbar: false, disableEditing: false, elementsContainer: false, + contentWindow: window, + ownerDocument: document, firstHeader: 'h3', forcePlainText: true, placeholder: 'Type your text', @@ -137,13 +146,13 @@ if (typeof module === 'object') { isIE: ((navigator.appName === 'Microsoft Internet Explorer') || ((navigator.appName === 'Netscape') && (new RegExp('Trident/.*rv:([0-9]{1,}[.0-9]{0,})').exec(navigator.userAgent) !== null))), init: function (elements, options) { + this.options = extend(options, this.defaults); this.setElementSelection(elements); if (this.elements.length === 0) { return; } this.parentElements = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'pre']; this.id = document.querySelectorAll('.medium-editor-toolbar').length + 1; - this.options = extend(options, this.defaults); return this.setup(); }, @@ -193,7 +202,7 @@ if (typeof module === 'object') { }, updateElementList: function () { - this.elements = typeof this.elementSelection === 'string' ? document.querySelectorAll(this.elementSelection) : this.elementSelection; + this.elements = typeof this.elementSelection === 'string' ? this.options.ownerDocument.querySelectorAll(this.elementSelection) : this.elementSelection; if (this.elements.nodeType === 1) { this.elements = [this.elements]; } @@ -264,7 +273,7 @@ if (typeof module === 'object') { bindParagraphCreation: function (index) { var self = this; this.elements[index].addEventListener('keypress', function (e) { - var node = getSelectionStart(), + var node = getSelectionStart.call(self), tagName; if (e.which === 32) { tagName = node.tagName.toLowerCase(); @@ -275,15 +284,15 @@ if (typeof module === 'object') { }); this.elements[index].addEventListener('keyup', function (e) { - var node = getSelectionStart(), + var node = getSelectionStart.call(self), tagName, editorElement; - + if (node && node.getAttribute('data-medium-element') && node.children.length === 0 && !(self.options.disableReturn || node.getAttribute('data-disable-return'))) { document.execCommand('formatBlock', false, 'p'); } if (e.which === 13) { - node = getSelectionStart(); + node = getSelectionStart.call(self); tagName = node.tagName.toLowerCase(); editorElement = self.getSelectionElement(); @@ -325,7 +334,7 @@ if (typeof module === 'object') { if (self.options.disableReturn || this.getAttribute('data-disable-return')) { e.preventDefault(); } else if (self.options.disableDoubleReturn || this.getAttribute('data-disable-double-return')) { - var node = getSelectionStart(); + var node = getSelectionStart.call(self); if (node && node.innerText === '\n') { e.preventDefault(); } @@ -336,10 +345,11 @@ if (typeof module === 'object') { }, bindTab: function (index) { + var self = this; this.elements[index].addEventListener('keydown', function (e) { if (e.which === 9) { // Override tab only for pre nodes - var tag = getSelectionStart().tagName.toLowerCase(); + var tag = getSelectionStart.call(self).tagName.toLowerCase(); if (tag === 'pre') { e.preventDefault(); document.execCommand('insertHtml', null, ' '); @@ -591,7 +601,7 @@ if (typeof module === 'object') { if (this.keepToolbarAlive !== true && !this.options.disableToolbar) { - newSelection = window.getSelection(); + newSelection = this.options.contentWindow.getSelection(); if (newSelection.toString().trim() === '' || (this.options.allowMultiParagraphSelection === false && this.hasMultiParagraphs()) || this.selectionInContentEditableFalse()) { @@ -619,7 +629,7 @@ if (typeof module === 'object') { }, hasMultiParagraphs: function () { - var selectionHtml = getSelectionHtml().replace(/<[\S]+><\/[\S]+>/gim, ''), + var selectionHtml = getSelectionHtml.call(this).replace(/<[\S]+><\/[\S]+>/gim, ''), hasMultiParagraphs = selectionHtml.match(/<(p|h[0-6]|blockquote)>([\s\S]*?)<\/(p|h[0-6]|blockquote)>/g); return (hasMultiParagraphs ? hasMultiParagraphs.length : 0); @@ -641,7 +651,7 @@ if (typeof module === 'object') { }, findMatchingSelectionParent: function(testElementFunction) { - var selection = window.getSelection(), range, current; + var selection = this.options.contentWindow.getSelection(), range, current; if (selection.rangeCount === 0) { return false; @@ -682,7 +692,7 @@ if (typeof module === 'object') { setToolbarPosition: function () { var buttonHeight = 50, - selection = window.getSelection(), + selection = this.options.contentWindow.getSelection(), range = selection.getRangeAt(0), boundary = range.getBoundingClientRect(), defaultLeft = (this.options.diffLeft) - (this.toolbar.offsetWidth / 2), @@ -691,16 +701,16 @@ if (typeof module === 'object') { if (boundary.top < buttonHeight) { this.toolbar.classList.add('medium-toolbar-arrow-over'); this.toolbar.classList.remove('medium-toolbar-arrow-under'); - this.toolbar.style.top = buttonHeight + boundary.bottom - this.options.diffTop + window.pageYOffset - this.toolbar.offsetHeight + 'px'; + this.toolbar.style.top = buttonHeight + boundary.bottom - this.options.diffTop + this.options.contentWindow.pageYOffset - this.toolbar.offsetHeight + 'px'; } else { this.toolbar.classList.add('medium-toolbar-arrow-under'); this.toolbar.classList.remove('medium-toolbar-arrow-over'); - this.toolbar.style.top = boundary.top + this.options.diffTop + window.pageYOffset - this.toolbar.offsetHeight + 'px'; + this.toolbar.style.top = boundary.top + this.options.diffTop + this.options.contentWindow.pageYOffset - this.toolbar.offsetHeight + 'px'; } if (middleBoundary < halfOffsetWidth) { this.toolbar.style.left = defaultLeft + halfOffsetWidth + 'px'; - } else if ((window.innerWidth - middleBoundary) < halfOffsetWidth) { - this.toolbar.style.left = window.innerWidth + defaultLeft - halfOffsetWidth + 'px'; + } else if ((this.options.contentWindow.innerWidth - middleBoundary) < halfOffsetWidth) { + this.toolbar.style.left = this.options.contentWindow.innerWidth + defaultLeft - halfOffsetWidth + 'px'; } else { this.toolbar.style.left = defaultLeft + middleBoundary + 'px'; } @@ -784,9 +794,9 @@ if (typeof module === 'object') { } else if (action === 'anchor') { this.triggerAnchorAction(e); } else if (action === 'image') { - document.execCommand('insertImage', false, window.getSelection()); + this.options.ownerDocument.execCommand('insertImage', false, this.options.contentWindow.getSelection()); } else { - document.execCommand(action, false, null); + this.options.ownerDocument.execCommand(action, false, null); this.setToolbarPosition(); } }, @@ -816,7 +826,7 @@ if (typeof module === 'object') { var selectedParentElement = this.getSelectedParentElement(); if (selectedParentElement.tagName && selectedParentElement.tagName.toLowerCase() === 'a') { - document.execCommand('unlink', false, null); + this.options.ownerDocument.execCommand('unlink', false, null); } else { if (this.anchorForm.style.display === 'block') { this.showToolbarActions(); @@ -834,7 +844,7 @@ if (typeof module === 'object') { // https://developer.mozilla.org/en-US/docs/Rich-Text_Editing_in_Mozilla if (el === 'blockquote' && selectionData.el && selectionData.el.parentNode.tagName.toLowerCase() === 'blockquote') { - return document.execCommand('outdent', false, null); + return this.options.ownerDocument.execCommand('outdent', false, null); } if (selectionData.tagName === el) { el = 'p'; @@ -845,11 +855,11 @@ if (typeof module === 'object') { // http://stackoverflow.com/questions/1816223/rich-text-editor-with-blockquote-function/1821777#1821777 if (this.isIE) { if (el === 'blockquote') { - return document.execCommand('indent', false, el); + return this.options.ownerDocument.execCommand('indent', false, el); } el = '<' + el + '>'; } - return document.execCommand('formatBlock', false, el); + return this.options.ownerDocument.execCommand('formatBlock', false, el); }, getSelectionData: function (el) { @@ -902,11 +912,11 @@ if (typeof module === 'object') { }, saveSelection: function() { - this.savedSelection = saveSelection(); + this.savedSelection = saveSelection.call(this); }, restoreSelection: function() { - restoreSelection(this.savedSelection); + restoreSelection.call(this, this.savedSelection); }, showAnchorForm: function (link_value) { @@ -975,13 +985,13 @@ if (typeof module === 'object') { }); // Hide the anchor form when focusing outside of it. - document.body.addEventListener('click', function (e) { + this.options.ownerDocument.body.addEventListener('click', function (e) { if (e.target !== self.anchorForm && !isDescendant(self.anchorForm, e.target) && !isDescendant(self.toolbarActions, e.target)) { self.keepToolbarAlive = false; self.checkSelection(); } }, true); - document.body.addEventListener('focus', function (e) { + this.options.ownerDocument.body.addEventListener('focus', function (e) { if (e.target !== self.anchorForm && !isDescendant(self.anchorForm, e.target) && !isDescendant(self.toolbarActions, e.target)) { self.keepToolbarAlive = false; self.checkSelection(); @@ -991,7 +1001,7 @@ if (typeof module === 'object') { linkCancel.addEventListener('click', function (e) { e.preventDefault(); self.showToolbarActions(); - restoreSelection(self.savedSelection); + restoreSelection.call(self, self.savedSelection); }); return this; }, @@ -1031,11 +1041,11 @@ if (typeof module === 'object') { self.anchorPreview.classList.add('medium-toolbar-arrow-over'); self.anchorPreview.classList.remove('medium-toolbar-arrow-under'); - self.anchorPreview.style.top = Math.round(buttonHeight + boundary.bottom - self.options.diffTop + window.pageYOffset - self.anchorPreview.offsetHeight) + 'px'; + self.anchorPreview.style.top = Math.round(buttonHeight + boundary.bottom - self.options.diffTop + this.options.contentWindow.pageYOffset - self.anchorPreview.offsetHeight) + 'px'; if (middleBoundary < halfOffsetWidth) { self.anchorPreview.style.left = defaultLeft + halfOffsetWidth + 'px'; - } else if ((window.innerWidth - middleBoundary) < halfOffsetWidth) { - self.anchorPreview.style.left = window.innerWidth + defaultLeft - halfOffsetWidth + 'px'; + } else if ((this.options.contentWindow.innerWidth - middleBoundary) < halfOffsetWidth) { + self.anchorPreview.style.left = this.options.contentWindow.innerWidth + defaultLeft - halfOffsetWidth + 'px'; } else { self.anchorPreview.style.left = defaultLeft + middleBoundary + 'px'; } @@ -1084,7 +1094,7 @@ if (typeof module === 'object') { createAnchorPreview: function () { var self = this, - anchorPreview = document.createElement('div'); + anchorPreview = this.options.ownerDocument.createElement('div'); anchorPreview.id = 'medium-editor-anchor-preview-' + this.id; anchorPreview.className = 'medium-editor-anchor-preview'; @@ -1108,8 +1118,8 @@ if (typeof module === 'object') { if (this.activeAnchor) { var self = this, - range = document.createRange(), - sel = window.getSelection(); + range = this.options.ownerDocument.createRange(), + sel = this.options.contentWindow.getSelection(); range.selectNodeContents(self.activeAnchor); sel.removeAllRanges(); @@ -1179,9 +1189,9 @@ if (typeof module === 'object') { return (re.test(value) ? '' : 'http://') + value; }, - setTargetBlank: function () { - var el = getSelectionStart(), - i; + setTargetBlank: function (el) { + var i; + el = el || getSelectionStart.call(this); if (el.tagName.toLowerCase() === 'a') { el.target = '_blank'; } else { @@ -1193,7 +1203,7 @@ if (typeof module === 'object') { }, setButtonClass: function (buttonClass) { - var el = getSelectionStart(), + var el = getSelectionStart.call(this), classes = buttonClass.split(' '), i, j; if (el.tagName.toLowerCase() === 'a') { @@ -1218,13 +1228,13 @@ if (typeof module === 'object') { return; } - restoreSelection(this.savedSelection); + restoreSelection.call(this, this.savedSelection); if (this.options.checkLinkFormat) { input.value = this.checkLinkFormat(input.value); } - document.execCommand('createLink', false, input.value); + this.options.ownerDocument.execCommand('createLink', false, input.value); if (this.options.targetBlank || target === "_blank") { this.setTargetBlank(); @@ -1235,8 +1245,8 @@ if (typeof module === 'object') { } if (this.options.targetBlank || target === "_blank" || buttonClass) { - event = document.createEvent("HTMLEvents"); - event.initEvent("input", true, true, window); + event = this.options.ownerDocument.createEvent("HTMLEvents"); + event.initEvent("input", true, true, this.options.contentWindow); for (i = 0; i < this.elements.length; i += 1) { this.elements[i].dispatchEvent(event); } @@ -1258,7 +1268,7 @@ if (typeof module === 'object') { } }, 100); }; - window.addEventListener('resize', this.windowResizeHandler); + this.options.contentWindow.addEventListener('resize', this.windowResizeHandler); return this; }, @@ -1285,8 +1295,8 @@ if (typeof module === 'object') { delete this.anchorPreview; } - document.documentElement.removeEventListener('mouseup', this.checkSelectionWrapper); - window.removeEventListener('resize', this.windowResizeHandler); + this.options.ownerDocument.documentElement.removeEventListener('mouseup', this.checkSelectionWrapper); + this.options.contentWindow.removeEventListener('resize', this.windowResizeHandler); for (i = 0; i < this.elements.length; i += 1) { this.elements[i].removeEventListener('mouseover', this.editorAnchorObserverWrapper); @@ -1334,10 +1344,10 @@ if (typeof module === 'object') { } } } - document.execCommand('insertHTML', false, html); + self.options.ownerDocument.execCommand('insertHTML', false, html); } else { html = self.htmlEntities(e.clipboardData.getData('text/plain')); - document.execCommand('insertHTML', false, html); + self.options.ownerDocument.execCommand('insertHTML', false, html); } } }; @@ -1420,15 +1430,20 @@ if (typeof module === 'object') { elList = text.split('

'); this.pasteHTML('

' + elList.join('

') + '

'); - document.execCommand('insertText', false, "\n"); + this.options.ownerDocument.execCommand('insertText', false, "\n"); // block element cleanup - elList = el.querySelectorAll('p,div,br'); + elList = el.querySelectorAll('a,p,div,br'); for (i = 0; i < elList.length; i += 1) { workEl = elList[i]; switch (workEl.tagName.toLowerCase()) { + case 'a': + if (this.options.targetBlank){ + this.setTargetBlank(workEl); + } + break; case 'p': case 'div': this.filterCommonBlocks(workEl); @@ -1450,9 +1465,9 @@ if (typeof module === 'object') { }, pasteHTML: function (html) { - var elList, workEl, i, fragmentBody, pasteBlock = document.createDocumentFragment(); + var elList, workEl, i, fragmentBody, pasteBlock = this.options.ownerDocument.createDocumentFragment(); - pasteBlock.appendChild(document.createElement('body')); + pasteBlock.appendChild(this.options.ownerDocument.createElement('body')); fragmentBody = pasteBlock.querySelector('body'); fragmentBody.innerHTML = html; @@ -1474,7 +1489,7 @@ if (typeof module === 'object') { } } - document.execCommand('insertHTML', false, fragmentBody.innerHTML.replace(/ /g, ' ')); + this.options.ownerDocument.execCommand('insertHTML', false, fragmentBody.innerHTML.replace(/ /g, ' ')); }, isCommonBlock: function (el) { return (el && (el.tagName.toLowerCase() === 'p' || el.tagName.toLowerCase() === 'div')); @@ -1525,7 +1540,7 @@ if (typeof module === 'object') { for (i = 0; i < spans.length; i += 1) { el = spans[i]; - new_el = document.createElement(el.classList.contains('bold') ? 'b' : 'i'); + new_el = this.options.ownerDocument.createElement(el.classList.contains('bold') ? 'b' : 'i'); if (el.classList.contains('bold') && el.classList.contains('italic')) { @@ -1550,7 +1565,7 @@ if (typeof module === 'object') { if (/^\s*$/.test()) { el.parentNode.removeChild(el); } else { - el.parentNode.replaceChild(document.createTextNode(el.innerText), el); + el.parentNode.replaceChild(this.options.ownerDocument.createTextNode(el.innerText), el); } } diff --git a/vendor/assets/stylesheets/medium-editor/medium-editor.css b/vendor/assets/stylesheets/medium-editor/medium-editor.css index 8d3d104..6244319 100644 --- a/vendor/assets/stylesheets/medium-editor/medium-editor.css +++ b/vendor/assets/stylesheets/medium-editor/medium-editor.css @@ -58,22 +58,6 @@ transform: matrix(1, 0, 0, 1, 0, 0); opacity: 1; } } -.btn { - display: inline-block; - margin-bottom: 0; - font-weight: normal; - text-align: center; - vertical-align: middle; - background: #efefef; - border: 1px solid #ccc; - white-space: nowrap; - padding: 6px 12px; - border-radius: 4px; - color: #333; - text-decoration: none; } - .btn:hover { - text-decoration: underline; } - .medium-toolbar-arrow-under:after, .medium-toolbar-arrow-over:before { position: absolute; left: 50%;