diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b9e7c3..c8b5d92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ #### [Current] + * [c949af6](../../commit/c949af6) - __(Ahmet Sezgin Duran)__ Update Medium Editor files + * [6e867bb](../../commit/6e867bb) - __(Ahmet Sezgin Duran)__ Add Gemnasium badge + * [618bf25](../../commit/618bf25) - __(Ahmet Sezgin Duran)__ Merge tag '0.10.0' into develop + +0.10.0 0.10.0 + +#### 0.10.0 + * [050b92b](../../commit/050b92b) - __(Ahmet Sezgin Duran)__ Bump versions 0.10.0 and 1.9.0 * [028abec](../../commit/028abec) - __(Ahmet Sezgin Duran)__ Update Medium Editor files * [9de9ca7](../../commit/9de9ca7) - __(Ahmet Sezgin Duran)__ Merge tag '0.9.4' into develop diff --git a/README.md b/README.md index 0215a17..2029d25 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,13 @@ [![Gem Version](https://badge.fury.io/rb/medium-editor-rails.png)](http://badge.fury.io/rb/medium-editor-rails) [![Code Climate](https://codeclimate.com/github/marjinal1st/medium-editor-rails.png)](https://codeclimate.com/github/marjinal1st/medium-editor-rails) +[![Dependency Status](https://gemnasium.com/marjinal1st/medium-editor-rails.svg)](https://gemnasium.com/marjinal1st/medium-editor-rails) This gem integrates [Medium Editor](https://github.com/daviferreira/medium-editor) with Rails asset pipeline. ## Version -The latest version of Medium Editor bundled by this gem is [1.9.0](https://github.com/daviferreira/medium-editor/releases) +The latest version of Medium Editor bundled by this gem is [1.9.4](https://github.com/daviferreira/medium-editor/releases) ## Installation @@ -63,4 +64,4 @@ https://github.com/daviferreira/medium-editor#initialization-options 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) -5. Create new Pull Request \ No newline at end of file +5. Create new Pull Request diff --git a/lib/medium-editor-rails/version.rb b/lib/medium-editor-rails/version.rb index 2c4f190..e6307e4 100644 --- a/lib/medium-editor-rails/version.rb +++ b/lib/medium-editor-rails/version.rb @@ -1,6 +1,6 @@ module MediumEditorRails module Rails - VERSION = '0.10.0' - MEDIUM_EDITOR_VERSION = '1.9.0' + VERSION = '0.11.0' + MEDIUM_EDITOR_VERSION = '1.9.4' end end diff --git a/vendor/assets/javascripts/medium-editor.js b/vendor/assets/javascripts/medium-editor.js index 3e865de..30f9f70 100644 --- a/vendor/assets/javascripts/medium-editor.js +++ b/vendor/assets/javascripts/medium-editor.js @@ -23,6 +23,17 @@ if (typeof module === 'object') { return b; } + function isDescendant(parent, child) { + var node = child.parentNode; + while (node !== null) { + if (node === parent) { + return true; + } + node = node.parentNode; + } + return false; + } + // http://stackoverflow.com/questions/5605401/insert-link-in-contenteditable-element // by Tim Down function saveSelection() { @@ -112,6 +123,9 @@ if (typeof module === 'object') { placeholder: 'Type your text', secondHeader: 'h4', targetBlank: false, + anchorTarget: false, + anchorButton: false, + anchorButtonClass: 'btn', extensions: {}, activeButtonClass: 'medium-editor-button-active', firstButtonClass: 'medium-editor-button-first', @@ -326,6 +340,18 @@ if (typeof module === 'object') { e.preventDefault(); document.execCommand('insertHtml', null, ' '); } + + // Tab to indent list structures! + if (tag === 'li') { + e.preventDefault(); + + // If Shift is down, outdent, otherwise indent + if (e.shiftKey) { + document.execCommand('outdent', e); + } else { + document.execCommand('indent', e); + } + } } }); return this; @@ -411,7 +437,9 @@ if (typeof module === 'object') { this.toolbar = this.createToolbar(); this.keepToolbarAlive = false; this.anchorForm = this.toolbar.querySelector('.medium-editor-toolbar-form-anchor'); - this.anchorInput = this.anchorForm.querySelector('input'); + this.anchorInput = this.anchorForm.querySelector('input.medium-editor-toolbar-anchor-input'); + this.anchorTarget = this.anchorForm.querySelector('input.medium-editor-toolbar-anchor-target'); + this.anchorButton = this.anchorForm.querySelector('input.medium-editor-toolbar-anchor-button'); this.toolbarActions = this.toolbar.querySelector('.medium-editor-toolbar-actions'); this.anchorPreview = this.createAnchorPreview(); @@ -465,18 +493,51 @@ if (typeof module === 'object') { toolbarFormAnchor: function () { var anchor = document.createElement('div'), input = document.createElement('input'), - a = document.createElement('a'); + target_label = document.createElement('label'), + target = document.createElement('input'), + button_label = document.createElement('label'), + button = document.createElement('input'), + close = document.createElement('a'), + save = document.createElement('a'); - a.setAttribute('href', '#'); - a.innerHTML = '×'; + close.setAttribute('href', '#'); + close.className = 'medium-editor-toobar-anchor-close'; + close.innerHTML = '×'; + + save.setAttribute('href', '#'); + save.className = 'medium-editor-toobar-anchor-save'; + save.innerHTML = '✓'; input.setAttribute('type', 'text'); + input.className = 'medium-editor-toolbar-anchor-input'; input.setAttribute('placeholder', this.options.anchorInputPlaceholder); + + target.setAttribute('type', 'checkbox'); + target.className = 'medium-editor-toolbar-anchor-target'; + target_label.innerHTML = "Open in New Window?"; + 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'; anchor.id = 'medium-editor-toolbar-form-anchor'; anchor.appendChild(input); - anchor.appendChild(a); + + anchor.appendChild(save); + anchor.appendChild(close); + + if (this.options.anchorTarget) { + anchor.appendChild(target_label); + } + + if (this.options.anchorButton) { + anchor.appendChild(button_label); + } return anchor; }, @@ -513,6 +574,7 @@ if (typeof module === 'object') { selectionElement; if (this.keepToolbarAlive !== true && !this.options.disableToolbar) { + newSelection = window.getSelection(); if (newSelection.toString().trim() === '' || (this.options.allowMultiParagraphSelection === false && this.hasMultiParagraphs()) || @@ -532,9 +594,11 @@ if (typeof module === 'object') { clickingIntoArchorForm: function (e) { var self = this; + if (e.type && e.type.toLowerCase() === 'blur' && e.relatedTarget && e.relatedTarget === self.anchorInput) { return true; } + return false; }, @@ -560,14 +624,14 @@ if (typeof module === 'object') { this.hideToolbarActions(); }, - findMatchingSelectionParent: function( testElementFunction ) { + findMatchingSelectionParent: function(testElementFunction) { var selection = window.getSelection(), range, current, parent, result, getElement = function (e) { var localParent = e; try { - while (!testElementFunction( localParent )) { + while (!testElementFunction(localParent)) { localParent = localParent.parentNode; } } catch (errb) { @@ -581,7 +645,7 @@ if (typeof module === 'object') { current = range.commonAncestorContainer; parent = current.parentNode; - if (testElementFunction( current )) { + if (testElementFunction(current)) { result = current; } else { result = getElement(parent); @@ -594,15 +658,15 @@ if (typeof module === 'object') { }, getSelectionElement: function () { - return this.findMatchingSelectionParent( function(el) { + return this.findMatchingSelectionParent(function(el) { return el.getAttribute('data-medium-element'); - } ); + }); }, selectionInContentEditableFalse: function () { - return this.findMatchingSelectionParent( function(el) { + return this.findMatchingSelectionParent(function(el) { return (el && el.nodeName !== '#text' && el.getAttribute('contenteditable') === 'false'); - } ); + }); }, setToolbarPosition: function () { @@ -838,32 +902,81 @@ if (typeof module === 'object') { this.toolbarActions.style.display = 'none'; this.saveSelection(); this.anchorForm.style.display = 'block'; + this.setToolbarPosition(); this.keepToolbarAlive = true; this.anchorInput.focus(); this.anchorInput.value = link_value || ''; }, bindAnchorForm: function () { - var linkCancel = this.anchorForm.querySelector('a'), + var linkCancel = this.anchorForm.querySelector('a.medium-editor-toobar-anchor-close'), + linkSave = this.anchorForm.querySelector('a.medium-editor-toobar-anchor-save'), self = this; + this.anchorForm.addEventListener('click', function (e) { e.stopPropagation(); + self.keepToolbarAlive = true; }); + this.anchorInput.addEventListener('keyup', function (e) { + var button = null, + target; + if (e.keyCode === 13) { e.preventDefault(); - self.createLink(this); + 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); } }); + + linkSave.addEventListener('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.anchorInput.addEventListener('click', function (e) { // make sure not to hide form when cliking into the input e.stopPropagation(); self.keepToolbarAlive = true; }); - this.anchorInput.addEventListener('blur', function () { - self.keepToolbarAlive = false; - self.checkSelection(); - }); + + // Hide the anchor form when focusing outside of it. + document.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) { + if (e.target !== self.anchorForm && !isDescendant(self.anchorForm, e.target) && !isDescendant(self.toolbarActions, e.target)) { + self.keepToolbarAlive = false; + self.checkSelection(); + } + }, true); + linkCancel.addEventListener('click', function (e) { e.preventDefault(); self.showToolbarActions(); @@ -879,7 +992,7 @@ if (typeof module === 'object') { // TODO: break method showAnchorPreview: function (anchorEl) { - if (this.anchorPreview.classList.contains('medium-editor-anchor-preview-active') + if (this.anchorPreview.classList.contains('medium-editor-anchor-preview-active') || anchorEl.getAttribute('data-disable-preview')) { return true; } @@ -1068,19 +1181,56 @@ if (typeof module === 'object') { } }, - createLink: function (input) { + setButtonClass: function (buttonClass) { + var el = getSelectionStart(), + classes = buttonClass.split(' '), + i, j; + if (el.tagName.toLowerCase() === 'a') { + for (j = 0; j < classes.length; j += 1) { + el.classList.add(classes[j]); + } + } else { + el = el.getElementsByTagName('a'); + for (i = 0; i < el.length; i += 1) { + for (j = 0; j < classes.length; j += 1) { + el[i].classList.add(classes[j]); + } + } + } + }, + + createLink: function (input, target, buttonClass) { + var i, event; + if (input.value.trim().length === 0) { this.hideToolbarActions(); return; } + restoreSelection(this.savedSelection); + if (this.options.checkLinkFormat) { input.value = this.checkLinkFormat(input.value); } + document.execCommand('createLink', false, input.value); - if (this.options.targetBlank) { + + if (this.options.targetBlank || target === "_blank") { this.setTargetBlank(); } + + if (buttonClass) { + this.setButtonClass(buttonClass); + } + + if (this.options.targetBlank || target === "_blank" || buttonClass) { + event = document.createEvent("HTMLEvents"); + event.initEvent("input", true, true, window); + for (i = 0; i < this.elements.length; i += 1) { + this.elements[i].dispatchEvent(event); + } + } + this.checkSelection(); this.showToolbarActions(); input.value = ''; diff --git a/vendor/assets/stylesheets/medium-editor/medium-editor.css b/vendor/assets/stylesheets/medium-editor/medium-editor.css index 6a95a34..8d3d104 100644 --- a/vendor/assets/stylesheets/medium-editor/medium-editor.css +++ b/vendor/assets/stylesheets/medium-editor/medium-editor.css @@ -58,6 +58,22 @@ 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%; @@ -134,7 +150,7 @@ display: none; } .medium-editor-toolbar-form-anchor input, .medium-editor-toolbar-form-anchor a { font-family: HelveticaNeue, Helvetica, Arial, sans-serif; } - .medium-editor-toolbar-form-anchor input { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input, .medium-editor-toolbar-form-anchor label { margin: 0; padding: 6px; width: 316px; @@ -142,12 +158,14 @@ font-size: 14px; -moz-box-sizing: border-box; box-sizing: border-box; } - .medium-editor-toolbar-form-anchor input:focus { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input:focus, .medium-editor-toolbar-form-anchor label:focus { outline: 0; border: none; box-shadow: none; -webkit-appearance: none; -moz-appearance: none; } + .medium-editor-toolbar-form-anchor label { + display: block; } .medium-editor-toolbar-form-anchor a { display: inline-block; margin: 0 10px; diff --git a/vendor/assets/stylesheets/medium-editor/themes/bootstrap.css b/vendor/assets/stylesheets/medium-editor/themes/bootstrap.css index afdb18f..6b67dea 100644 --- a/vendor/assets/stylesheets/medium-editor/themes/bootstrap.css +++ b/vendor/assets/stylesheets/medium-editor/themes/bootstrap.css @@ -40,22 +40,22 @@ background: #428bca; color: #fff; border-radius: 4px; } - .medium-editor-toolbar-form-anchor input { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input { height: 60px; background: #428bca; color: #fff; } - .medium-editor-toolbar-form-anchor input::-webkit-input-placeholder { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input::-webkit-input-placeholder { color: #fff; color: rgba(255, 255, 255, 0.8); } - .medium-editor-toolbar-form-anchor input:-moz-placeholder { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input:-moz-placeholder { /* Firefox 18- */ color: #fff; color: rgba(255, 255, 255, 0.8); } - .medium-editor-toolbar-form-anchor input::-moz-placeholder { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input::-moz-placeholder { /* Firefox 19+ */ color: #fff; color: rgba(255, 255, 255, 0.8); } - .medium-editor-toolbar-form-anchor input:-ms-input-placeholder { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input:-ms-input-placeholder { color: #fff; color: rgba(255, 255, 255, 0.8); } .medium-editor-toolbar-form-anchor a { diff --git a/vendor/assets/stylesheets/medium-editor/themes/default.css b/vendor/assets/stylesheets/medium-editor/themes/default.css old mode 100644 new mode 100755 index 65dcee7..e7d4917 --- a/vendor/assets/stylesheets/medium-editor/themes/default.css +++ b/vendor/assets/stylesheets/medium-editor/themes/default.css @@ -48,7 +48,7 @@ background: #242424; color: #999; border-radius: 5px; } - .medium-editor-toolbar-form-anchor input { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input { height: 50px; background: #242424; color: #ccc; diff --git a/vendor/assets/stylesheets/medium-editor/themes/flat.css b/vendor/assets/stylesheets/medium-editor/themes/flat.css index a842bf2..043740e 100644 --- a/vendor/assets/stylesheets/medium-editor/themes/flat.css +++ b/vendor/assets/stylesheets/medium-editor/themes/flat.css @@ -28,22 +28,22 @@ .medium-editor-toolbar li .medium-editor-button-last { border-right: none; } -.medium-editor-toolbar-form-anchor input { +.medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input { height: 60px; background: #57ad68; color: #fff; } - .medium-editor-toolbar-form-anchor input::-webkit-input-placeholder { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input::-webkit-input-placeholder { color: #fff; color: rgba(255, 255, 255, 0.8); } - .medium-editor-toolbar-form-anchor input:-moz-placeholder { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input:-moz-placeholder { /* Firefox 18- */ color: #fff; color: rgba(255, 255, 255, 0.8); } - .medium-editor-toolbar-form-anchor input::-moz-placeholder { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input::-moz-placeholder { /* Firefox 19+ */ color: #fff; color: rgba(255, 255, 255, 0.8); } - .medium-editor-toolbar-form-anchor input:-ms-input-placeholder { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input:-ms-input-placeholder { color: #fff; color: rgba(255, 255, 255, 0.8); } .medium-editor-toolbar-form-anchor a { diff --git a/vendor/assets/stylesheets/medium-editor/themes/mani.css b/vendor/assets/stylesheets/medium-editor/themes/mani.css index 9d84cca..b1ad382 100644 --- a/vendor/assets/stylesheets/medium-editor/themes/mani.css +++ b/vendor/assets/stylesheets/medium-editor/themes/mani.css @@ -39,7 +39,7 @@ background: #dee7f0; color: #999; border-radius: 2px; } - .medium-editor-toolbar-form-anchor input { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input { height: 50px; background: #dee7f0; color: #40648a; diff --git a/vendor/assets/stylesheets/medium-editor/themes/roman.css b/vendor/assets/stylesheets/medium-editor/themes/roman.css index 34461b9..96db881 100644 --- a/vendor/assets/stylesheets/medium-editor/themes/roman.css +++ b/vendor/assets/stylesheets/medium-editor/themes/roman.css @@ -40,7 +40,7 @@ background: #fff; color: #999; border-radius: 5px; } - .medium-editor-toolbar-form-anchor input { + .medium-editor-toolbar-form-anchor .medium-editor-toolbar-anchor-input { margin: 0; height: 50px; background: #fff;