UNPKG

medium-editor

Version:
129 lines (103 loc) 4.67 kB
(function () { 'use strict'; var Placeholder = MediumEditor.Extension.extend({ name: 'placeholder', /* Placeholder Options */ /* text: [string] * Text to display in the placeholder */ text: 'Type your text', /* hideOnClick: [boolean] * Should we hide the placeholder on click (true) or when user starts typing (false) */ hideOnClick: true, init: function () { MediumEditor.Extension.prototype.init.apply(this, arguments); this.initPlaceholders(); this.attachEventHandlers(); }, initPlaceholders: function () { this.getEditorElements().forEach(this.initElement, this); }, handleAddElement: function (event, editable) { this.initElement(editable); }, initElement: function (el) { if (!el.getAttribute('data-placeholder')) { el.setAttribute('data-placeholder', this.text); } this.updatePlaceholder(el); }, destroy: function () { this.getEditorElements().forEach(this.cleanupElement, this); }, handleRemoveElement: function (event, editable) { this.cleanupElement(editable); }, cleanupElement: function (el) { if (el.getAttribute('data-placeholder') === this.text) { el.removeAttribute('data-placeholder'); } }, showPlaceholder: function (el) { if (el) { // https://github.com/yabwe/medium-editor/issues/234 // In firefox, styling the placeholder with an absolutely positioned // pseudo element causes the cursor to appear in a bad location // when the element is completely empty, so apply a different class to // style it with a relatively positioned pseudo element if (MediumEditor.util.isFF && el.childNodes.length === 0) { el.classList.add('medium-editor-placeholder-relative'); el.classList.remove('medium-editor-placeholder'); } else { el.classList.add('medium-editor-placeholder'); el.classList.remove('medium-editor-placeholder-relative'); } } }, hidePlaceholder: function (el) { if (el) { el.classList.remove('medium-editor-placeholder'); el.classList.remove('medium-editor-placeholder-relative'); } }, updatePlaceholder: function (el, dontShow) { // If the element has content, hide the placeholder if (el.querySelector('img, blockquote, ul, ol, table') || (el.textContent.replace(/^\s+|\s+$/g, '') !== '')) { return this.hidePlaceholder(el); } if (!dontShow) { this.showPlaceholder(el); } }, attachEventHandlers: function () { if (this.hideOnClick) { // For the 'hideOnClick' option, the placeholder should always be hidden on focus this.subscribe('focus', this.handleFocus.bind(this)); } // If the editor has content, it should always hide the placeholder this.subscribe('editableInput', this.handleInput.bind(this)); // When the editor loses focus, check if the placeholder should be visible this.subscribe('blur', this.handleBlur.bind(this)); // Need to know when elements are added/removed from the editor this.subscribe('addElement', this.handleAddElement.bind(this)); this.subscribe('removeElement', this.handleRemoveElement.bind(this)); }, handleInput: function (event, element) { // If the placeholder should be hidden on focus and the // element has focus, don't show the placeholder var dontShow = this.hideOnClick && (element === this.base.getFocusedElement()); // Editor's content has changed, check if the placeholder should be hidden this.updatePlaceholder(element, dontShow); }, handleFocus: function (event, element) { // Editor has focus, hide the placeholder this.hidePlaceholder(element); }, handleBlur: function (event, element) { // Editor has lost focus, check if the placeholder should be shown this.updatePlaceholder(element); } }); MediumEditor.extensions.placeholder = Placeholder; }());