├── .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 | [](https://nodei.co/npm/medium-editor-multi-placeholders-plugin/)
5 |
6 | [](https://travis-ci.org/smiled0g/medium-editor-multi-placeholders-plugin)
7 | [](https://david-dm.org/smiled0g/medium-editor-multi-placeholders-plugin)
8 | [](https://david-dm.org/smiled0g/medium-editor-multi-placeholders-plugin#info=devDependencies)
9 |
10 | # Demo
11 | 
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 |
--------------------------------------------------------------------------------