├── .gitignore ├── .travis.yml ├── Gruntfile.js ├── LICENSE ├── README.md ├── bower.json ├── dist ├── medium-editor-multi-placeholders-plugin.js └── medium-editor-multi-placeholders-plugin.min.js ├── examples ├── demo.png └── index.html ├── package.json └── src └── main.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | bower_components 3 | node_modules 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | 5 | before_script: 6 | - npm install -g grunt-cli 7 | 8 | script: 9 | - grunt 10 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | grunt.initConfig({ 3 | pkg: grunt.file.readJSON('package.json'), 4 | jshint: { 5 | all: ['Gruntfile.js', 'src/main.js'] 6 | }, 7 | concat: { 8 | dist: { 9 | src: ['src/main.js'], 10 | dest: 'dist/<%= pkg.name %>.js', 11 | nonull: true 12 | } 13 | }, 14 | uglify: { 15 | my_target: { 16 | files: { 17 | 'dist/<%= pkg.name %>.min.js': ['dist/<%= pkg.name %>.js'] 18 | } 19 | } 20 | } 21 | }); 22 | 23 | grunt.loadNpmTasks('grunt-contrib-jshint'); 24 | grunt.loadNpmTasks('grunt-contrib-concat'); 25 | grunt.loadNpmTasks('grunt-contrib-uglify'); 26 | grunt.registerTask('default', ['jshint', 'concat','uglify']); 27 | }; 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Kasi Chonpimai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MediumEditorMultiPlaceholders Plugin 2 | A plugin that allows you to setup multiple placeholders with [MediumEditor](https://github.com/yabwe/medium-editor) 3 | 4 | [![NPM](https://nodei.co/npm/medium-editor-multi-placeholders-plugin.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/medium-editor-multi-placeholders-plugin/) 5 | 6 | [![Travis Build Status](https://travis-ci.org/smiled0g/medium-editor-multi-placeholders-plugin.svg?branch=master)](https://travis-ci.org/smiled0g/medium-editor-multi-placeholders-plugin) 7 | [![Dependency Status](https://david-dm.org/smiled0g/medium-editor-multi-placeholders-plugin.svg)](https://david-dm.org/smiled0g/medium-editor-multi-placeholders-plugin) 8 | [![devDependency Status](https://david-dm.org/smiled0g/medium-editor-multi-placeholders-plugin/dev-status.svg)](https://david-dm.org/smiled0g/medium-editor-multi-placeholders-plugin#info=devDependencies) 9 | 10 | # Demo 11 | ![Demo](examples/demo.png) 12 | 13 | Try at [Demo page](http://smiled0g.github.io/medium-editor-multi-placeholders-plugin/) 14 | 15 | # Basic usage 16 | 17 | ### Installation 18 | **Via npm:** 19 | 20 | Run in your console: 21 | ```bash 22 | npm install medium-editor-multi-placeholders-plugin 23 | ``` 24 | Then build the project by running 25 | ```bash 26 | grunt 27 | ``` 28 | 29 | **Via bower:** 30 | 31 | ```bash 32 | bower install medium-editor-multi-placeholders-plugin 33 | ``` 34 | 35 | ### Usage 36 | 37 | First thing: don't forget to load the plugin **after** MediumEditor 38 | 39 | ```html 40 | 41 | ``` 42 | 43 | Now when you create MediumEditor instance, just disable normal placeholder and specify the extension and placeholder options: 44 | ```js 45 | var editor = new MediumEditor('#editor', { 46 | placeholder: false, 47 | extensions: { 48 | 'multi_placeholder': new MediumEditorMultiPlaceholders({ 49 | placeholders: [ 50 | { 51 | tag: 'h1', 52 | text: 'Title' 53 | }, 54 | { 55 | tag: 'p', 56 | text: 'Tell your story...' 57 | } 58 | ] 59 | }) 60 | } 61 | }); 62 | ``` 63 | 64 | ## Plugin Options 65 | 66 | The plugin itself only takes one option: ```placeholders``` which is an array of placeholder objects. Each placeholder object is in the format ```{ tag: 'HTMLTag', text: 'Placeholder Text' }```. 67 | 68 | ```js 69 | var multiPlaceholders = new MediumEditorMultiPlaceholders({ 70 | placeholders: [ 71 | /* Your place holders goes here 72 | You can have as many placeholders as you want! 73 | Example: { tag: 'h1', text: 'Title' } */ 74 | ] 75 | }); 76 | ``` 77 | 78 | ## Known Issues 79 | 80 | Conflicts with [MediumEditor Insert Plugin](https://github.com/orthes/medium-editor-insert-plugin), because `placeholder: false` doesn't work with the some version of the it. 81 | 82 | ## License 83 | 84 | MIT: https://github.com/smiled0g/medium-editor-multi-placeholders-plugin/blob/master/LICENSE 85 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "medium-editor-multi-placeholders-plugin", 3 | "version": "1.0.0", 4 | "homepage": "https://github.com/smiled0g/medium-editor-multi-placeholders-plugin", 5 | "authors": [ 6 | "Kasi Chonpimai " 7 | ], 8 | "description": "A plugin for adding multiple placeholders in MediumEditor", 9 | "main": "dist/medium-editor-multi-placeholders-plugin.js", 10 | "keywords": [ 11 | "MediumEditor", 12 | "Multiple", 13 | "Placeholders" 14 | ], 15 | "license": "MIT", 16 | "ignore": [ 17 | "**/.*", 18 | "node_modules", 19 | "bower_components", 20 | "test", 21 | "tests" 22 | ], 23 | "dependencies": { 24 | "medium-editor": "^4.0.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /dist/medium-editor-multi-placeholders-plugin.js: -------------------------------------------------------------------------------- 1 | var MediumEditorMultiPlaceholders = MediumEditor.Extension.extend({ 2 | name: 'multi_placeholder', 3 | init: function() { 4 | this.placeholderElements = []; 5 | this.initPlaceholders(this.placeholders, this.placeholderElements); 6 | this.watchChanges(); 7 | }, 8 | 9 | initPlaceholders: function (placeholders, elements) { 10 | this.getEditorElements().forEach(function (editor) { 11 | this.placeholders.map(function(placeholder) { 12 | // Create the placeholder element 13 | var el = document.createElement(placeholder.tag); 14 | el.appendChild(document.createElement('br')); 15 | el.setAttribute('data-placeholder', placeholder.text); 16 | elements.push(el); 17 | // Append it to Medium Editor element 18 | editor.appendChild(el); 19 | this.updatePlaceholder(el); 20 | }, this); 21 | }, this); 22 | }, 23 | 24 | destroy: function () { 25 | this.getEditorElements().forEach(function (editor) { 26 | editor.querySelectorAll('[data-placeholder]').map(function(el) { 27 | el.removeAttribute('data-placeholder'); 28 | }, this); 29 | }, this); 30 | }, 31 | 32 | showPlaceholder: function (el) { 33 | if (el) { 34 | el.classList.add('medium-editor-placeholder'); 35 | } 36 | }, 37 | 38 | hidePlaceholder: function (el) { 39 | if (el) { 40 | el.classList.remove('medium-editor-placeholder'); 41 | } 42 | }, 43 | 44 | updatePlaceholder: function (el) { 45 | // if one of these element ('img, blockquote, ul, ol') are found inside the given element, we won't display the placeholder 46 | if (el.textContent === '') { 47 | return this.showPlaceholder(el); 48 | } 49 | this.hidePlaceholder(el); 50 | }, 51 | 52 | updateAllPlaceholders: function() { 53 | this.placeholderElements.map(function(el){ 54 | this.updatePlaceholder(el); 55 | }, this); 56 | }, 57 | 58 | watchChanges: function() { 59 | this.subscribe('editableInput', this.updateAllPlaceholders.bind(this)); 60 | this.subscribe('externalInteraction', this.updateAllPlaceholders.bind(this)); 61 | } 62 | }); 63 | -------------------------------------------------------------------------------- /dist/medium-editor-multi-placeholders-plugin.min.js: -------------------------------------------------------------------------------- 1 | var MediumEditorMultiPlaceholders=MediumEditor.Extension.extend({name:"multi_placeholder",init:function(){this.placeholderElements=[],this.initPlaceholders(this.placeholders,this.placeholderElements),this.watchChanges()},initPlaceholders:function(a,b){this.getEditorElements().forEach(function(a){this.placeholders.map(function(c){var d=document.createElement(c.tag);d.appendChild(document.createElement("br")),d.setAttribute("data-placeholder",c.text),b.push(d),a.appendChild(d),this.updatePlaceholder(d)},this)},this)},destroy:function(){this.getEditorElements().forEach(function(a){a.querySelectorAll("[data-placeholder]").map(function(a){a.removeAttribute("data-placeholder")},this)},this)},showPlaceholder:function(a){a&&a.classList.add("medium-editor-placeholder")},hidePlaceholder:function(a){a&&a.classList.remove("medium-editor-placeholder")},updatePlaceholder:function(a){return""===a.textContent?this.showPlaceholder(a):void this.hidePlaceholder(a)},updateAllPlaceholders:function(){this.placeholderElements.map(function(a){this.updatePlaceholder(a)},this)},watchChanges:function(){this.subscribe("editableInput",this.updateAllPlaceholders.bind(this)),this.subscribe("externalInteraction",this.updateAllPlaceholders.bind(this))}}); -------------------------------------------------------------------------------- /examples/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smiled0g/medium-editor-multi-placeholders-plugin/96f2a50895b5fa00891de7fb4c1e8b6d5b881383/examples/demo.png -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Medium Editor Multi-placeholders Plugin Example 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "medium-editor-multi-placeholders-plugin", 3 | "version": "1.0.0", 4 | "description": "A plugin for adding multiple placeholders in MediumEditor", 5 | "main": "index.js", 6 | "directories": { 7 | "example": "examples" 8 | }, 9 | "scripts": { 10 | "test": "grunt --verbose" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/smiled0g/medium-editor-multi-placeholders-plugin.git" 15 | }, 16 | "keywords": [ 17 | "MediumEditor", 18 | "Multple", 19 | "Placeholders" 20 | ], 21 | "author": "Kasi Chonpimai", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/smiled0g/medium-editor-multi-placeholders-plugin/issues" 25 | }, 26 | "homepage": "https://github.com/smiled0g/medium-editor-multi-placeholders-plugin#readme", 27 | "devDependencies": { 28 | "grunt": "^0.4.5", 29 | "grunt-cli": "^0.1.13", 30 | "grunt-contrib-concat": "^0.5.1", 31 | "grunt-contrib-jshint": "^0.11.2", 32 | "grunt-contrib-uglify": "^0.9.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | var MediumEditorMultiPlaceholders = MediumEditor.Extension.extend({ 2 | name: 'multi_placeholder', 3 | init: function() { 4 | this.placeholderElements = []; 5 | this.initPlaceholders(this.placeholders, this.placeholderElements); 6 | this.watchChanges(); 7 | }, 8 | 9 | initPlaceholders: function (placeholders, elements) { 10 | this.getEditorElements().forEach(function (editor) { 11 | this.placeholders.map(function(placeholder) { 12 | // Create the placeholder element 13 | var el = document.createElement(placeholder.tag); 14 | el.appendChild(document.createElement('br')); 15 | el.setAttribute('data-placeholder', placeholder.text); 16 | elements.push(el); 17 | // Append it to Medium Editor element 18 | editor.appendChild(el); 19 | this.updatePlaceholder(el); 20 | }, this); 21 | }, this); 22 | }, 23 | 24 | destroy: function () { 25 | this.getEditorElements().forEach(function (editor) { 26 | editor.querySelectorAll('[data-placeholder]').map(function(el) { 27 | el.removeAttribute('data-placeholder'); 28 | }, this); 29 | }, this); 30 | }, 31 | 32 | showPlaceholder: function (el) { 33 | if (el) { 34 | el.classList.add('medium-editor-placeholder'); 35 | } 36 | }, 37 | 38 | hidePlaceholder: function (el) { 39 | if (el) { 40 | el.classList.remove('medium-editor-placeholder'); 41 | } 42 | }, 43 | 44 | updatePlaceholder: function (el) { 45 | if (el.textContent === '') { 46 | return this.showPlaceholder(el); 47 | } 48 | this.hidePlaceholder(el); 49 | }, 50 | 51 | updateAllPlaceholders: function() { 52 | this.placeholderElements.map(function(el){ 53 | this.updatePlaceholder(el); 54 | }, this); 55 | }, 56 | 57 | watchChanges: function() { 58 | this.subscribe('editableInput', this.updateAllPlaceholders.bind(this)); 59 | this.subscribe('externalInteraction', this.updateAllPlaceholders.bind(this)); 60 | } 61 | }); 62 | --------------------------------------------------------------------------------