├── .gitignore ├── index.php ├── languages └── acf-front-end-editor.pot ├── admin ├── index.php ├── css │ └── acf-front-end-editor-admin.css ├── partials │ └── acf-front-end-editor-admin-display.php ├── js │ └── acf-front-end-editor-admin.js └── class-acf-front-end-editor-admin.php ├── public ├── index.php ├── css │ ├── acf-front-end-editor-public.css │ ├── themes │ │ ├── mani.min.css │ │ ├── flat.min.css │ │ ├── roman.min.css │ │ ├── default.min.css │ │ ├── tim.min.css │ │ ├── bootstrap.min.css │ │ ├── flat.css │ │ ├── roman.css │ │ ├── mani.css │ │ ├── default.css │ │ ├── tim.css │ │ └── bootstrap.css │ └── medium-editor.min.css ├── partials │ └── acf-front-end-editor-public-display.php ├── js │ ├── acf-front-end-editor-public.js │ └── medium-editor.min.js └── class-acf-front-end-editor-public.php ├── includes ├── index.php ├── class-acf-front-end-editor-activator.php ├── class-acf-front-end-editor-deactivator.php ├── class-acf-front-end-editor-i18n.php ├── class-acf-front-end-editor-loader.php └── class-acf-front-end-editor.php ├── screenshot-1.gif ├── README.md ├── composer.json ├── uninstall.php ├── acf-front-end-editor.php ├── README.txt └── LICENSE.txt /.gitignore: -------------------------------------------------------------------------------- 1 | sftp-config.json 2 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | .ab-item:before{content: '\f464';top: 2px;} 3 | 4 | .hd-pop { 5 | position: fixed; 6 | min-width: 300px; 7 | background: rgba(0, 0, 0, 0.72); 8 | color: #FBFBFB; 9 | line-height: 50px; 10 | font-weight: 700; 11 | top: 20px; 12 | right: 20px; 13 | border-radius: 6px; 14 | padding: 10px 30px; 15 | font-size: 16px; 16 | z-index: 999; 17 | } -------------------------------------------------------------------------------- /public/partials/acf-front-end-editor-public-display.php: -------------------------------------------------------------------------------- 1 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /admin/partials/acf-front-end-editor-admin-display.php: -------------------------------------------------------------------------------- 1 | 15 | 16 |
17 |

18 | 19 |
20 |
21 | plugin_name ); 23 | do_settings_sections( $this->plugin_name ); 24 | submit_button(); 25 | ?> 26 |
27 |
-------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Advanced Custom Fields add-on: Front-end Editor v2.0 2 | 3 | [![ACF FRONT END EDITOR](http://horiondigital.com/hostedimages/acffront0.png)](http://www.youtube.com/watch?v=rb9rsLaDImc) 4 | 5 | This is an add-on for WordPress [Advanced Custom Fields plugin](https://wordpress.org/plugins/advanced-custom-fields/) 6 | 7 | The add-on allows admins to edit text fields, textareas and wysiwyg fields from front end simillary as you would edit a google doc. 8 | 9 | Have fun. 10 | 11 | P.S. it also works with OPTIONS page fields, in the LOOP, with repeaters and flexible content: 12 | 13 | [![ACF FRONT END EDITOR](http://horiondigital.com/hostedimages/acffront2.gif)](http://www.youtube.com/watch?v=rb9rsLaDImc) 14 | 15 | Add-on author: Audrius Rackauskas @ [Horion Digital, Ltd](http://www.horiondigital.com) 16 | 17 | ACF plugin author: [Elliot Condon](http://www.elliotcondon.com/) -------------------------------------------------------------------------------- /includes/class-acf-front-end-editor-activator.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class Acf_Front_End_Editor_Activator { 24 | 25 | /** 26 | * Short Description. (use period) 27 | * 28 | * Long Description. 29 | * 30 | * @since 1.0.0 31 | */ 32 | public static function activate() { 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /includes/class-acf-front-end-editor-deactivator.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class Acf_Front_End_Editor_Deactivator { 24 | 25 | /** 26 | * Short Description. (use period) 27 | * 28 | * Long Description. 29 | * 30 | * @since 1.0.0 31 | */ 32 | public static function deactivate() { 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "horiondigital/advanced-custom-fields-front-end-editor", 3 | "description": "Add on for advanced custom fields plugin which allow to edit text fields, text areas and wysiwyg fields via front end magically", 4 | "keywords": ["wordpress", "plugin", "acf", "advanced-custom-fields"], 5 | "homepage": "https://github.com/HorionDigital/advanced-custom-fields-front-end-editor", 6 | "license": "GPL-2.0+", 7 | "authors": [ 8 | { 9 | "name": "Audrius Rackauskas", 10 | "homepage": "http://www.horiondigital.com" 11 | } 12 | ], 13 | "support" : { 14 | "issues": "https://github.com/HorionDigital/advanced-custom-fields-front-end-editor/issues", 15 | "source": "https://github.com/HorionDigital/advanced-custom-fields-front-end-editor" 16 | }, 17 | "type": "wordpress-plugin", 18 | "require": { 19 | "composer/installers": "~1.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /admin/js/acf-front-end-editor-admin.js: -------------------------------------------------------------------------------- 1 | (function( $ ) { 2 | 'use strict'; 3 | 4 | /** 5 | * All of the code for your admin-facing JavaScript source 6 | * should reside in this file. 7 | * 8 | * Note: It has been assumed you will write jQuery code here, so the 9 | * $ function reference has been prepared for usage within the scope 10 | * of this function. 11 | * 12 | * This enables you to define handlers, for when the DOM is ready: 13 | * 14 | * $(function() { 15 | * 16 | * }); 17 | * 18 | * When the window is loaded: 19 | * 20 | * $( window ).load(function() { 21 | * 22 | * }); 23 | * 24 | * ...and/or other possibilities. 25 | * 26 | * Ideally, it is not considered best practise to attach more than a 27 | * single DOM-ready or window-load handler for a particular page. 28 | * Although scripts in the WordPress core, Plugins and Themes may be 29 | * practising this, we should strive to set a better example in our own work. 30 | */ 31 | 32 | })( jQuery ); 33 | -------------------------------------------------------------------------------- /uninstall.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | class Acf_Front_End_Editor_i18n { 28 | 29 | 30 | /** 31 | * Load the plugin text domain for translation. 32 | * 33 | * @since 1.0.0 34 | */ 35 | public function load_plugin_textdomain() { 36 | 37 | load_plugin_textdomain( 38 | 'acf-front-end-editor', 39 | false, 40 | dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/' 41 | ); 42 | 43 | } 44 | 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /public/css/themes/mani.min.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-over:before,.medium-toolbar-arrow-under:after{display:none}.medium-editor-toolbar{border:1px solid #cdd6e0;background:-webkit-linear-gradient(bottom,#dee7f0,#fff);background:linear-gradient(to top,#dee7f0,#fff);border-radius:2px;box-shadow:0 2px 6px rgba(0,0,0,.45)}.medium-editor-toolbar li button{min-width:50px;height:50px;border:none;border-right:1px solid #cdd6e0;background-color:transparent;color:#40648a;-webkit-transition:background-color .2s ease-in,color .2s ease-in;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#5c90c7;background-color:rgba(92,144,199,.45);color:#fff}.medium-editor-toolbar li .medium-editor-button-first{border-top-left-radius:2px;border-bottom-left-radius:2px}.medium-editor-toolbar li .medium-editor-button-last{border-top-right-radius:2px;border-bottom-right-radius:2px}.medium-editor-toolbar li .medium-editor-button-active{color:#000;background:-webkit-linear-gradient(top,#dee7f0,rgba(0,0,0,.1));background:linear-gradient(to bottom,#dee7f0,rgba(0,0,0,.1))}.medium-editor-toolbar-form{background:#dee7f0;color:#999;border-radius:2px}.medium-editor-toolbar-form .medium-editor-toolbar-input{height:50px;background:#dee7f0;color:#40648a;box-sizing:border-box}.medium-editor-toolbar-form a{color:#40648a}.medium-editor-toolbar-anchor-preview{background:#dee7f0;color:#40648a;border-radius:2px}.medium-editor-placeholder:after{color:#cdd6e0} -------------------------------------------------------------------------------- /public/css/themes/flat.min.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after{top:60px;border-color:#57ad68 transparent transparent}.medium-toolbar-arrow-over:before{top:-8px;border-color:transparent transparent #57ad68}.medium-editor-toolbar{background-color:#57ad68}.medium-editor-toolbar li{padding:0}.medium-editor-toolbar li button{min-width:60px;height:60px;border:none;border-right:1px solid #9ccea6;background-color:transparent;color:#fff;-webkit-transition:background-color .2s ease-in,color .2s ease-in;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#346a3f;color:#fff}.medium-editor-toolbar li .medium-editor-button-active{background-color:#23482a;color:#fff}.medium-editor-toolbar li .medium-editor-button-last{border-right:none}.medium-editor-toolbar-form .medium-editor-toolbar-input{height:60px;background:#57ad68;color:#fff}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form a{color:#fff}.medium-editor-toolbar-anchor-preview{background:#57ad68;color:#fff}.medium-editor-placeholder:after{color:#fff} -------------------------------------------------------------------------------- /public/css/themes/roman.min.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-over:before,.medium-toolbar-arrow-under:after{display:none}.medium-editor-toolbar{background-color:#fff;background-color:rgba(255,255,255,.95);border-radius:5px;box-shadow:0 2px 6px rgba(0,0,0,.45)}.medium-editor-toolbar li button{min-width:50px;height:50px;border:none;border-right:1px solid #a8a8a8;color:#889aac;box-shadow:inset 0 0 3px #f8f8e6;background:-webkit-linear-gradient(top,#fff,rgba(0,0,0,.2));background:linear-gradient(to bottom,#fff,rgba(0,0,0,.2));text-shadow:1px 4px 6px #def,0 0 0 #000,1px 4px 6px #def;-webkit-transition:background-color .2s ease-in;transition:background-color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#fff;color:#fff;color:rgba(0,0,0,.8)}.medium-editor-toolbar li .medium-editor-button-first{border-top-left-radius:5px;border-bottom-left-radius:5px}.medium-editor-toolbar li .medium-editor-button-last{border-top-right-radius:5px;border-bottom-right-radius:5px}.medium-editor-toolbar li .medium-editor-button-active{color:#000;color:rgba(0,0,0,.8);background:-webkit-linear-gradient(bottom,#fff,rgba(0,0,0,.1));background:linear-gradient(to top,#fff,rgba(0,0,0,.1))}.medium-editor-toolbar-form{background:#fff;color:#999;border-radius:5px}.medium-editor-toolbar-form .medium-editor-toolbar-input{margin:0;height:50px;background:#fff;color:#a8a8a8}.medium-editor-toolbar-form a{color:#889aac}.medium-editor-toolbar-anchor-preview{background:#fff;color:#889aac;border-radius:5px}.medium-editor-placeholder:after{color:#a8a8a8} -------------------------------------------------------------------------------- /public/css/themes/default.min.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after{border-color:#242424 transparent transparent;top:50px}.medium-toolbar-arrow-over:before{border-color:transparent transparent #242424;top:-8px}.medium-editor-toolbar{background:-webkit-linear-gradient(top,#242424,rgba(36,36,36,.75));background:linear-gradient(to bottom,#242424,rgba(36,36,36,.75));border:1px solid #000;border-radius:5px;box-shadow:0 0 3px #000}.medium-editor-toolbar li button{background:-webkit-linear-gradient(top,#242424,rgba(36,36,36,.89));background:linear-gradient(to bottom,#242424,rgba(36,36,36,.89));border:0;border-right:1px solid #000;border-left:1px solid #333;border-left:1px solid rgba(255,255,255,.1);box-shadow:0 2px 2px rgba(0,0,0,.3);color:#fff;height:50px;min-width:50px;-webkit-transition:background-color .2s ease-in;transition:background-color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#000;color:#ff0}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:5px;border-top-left-radius:5px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:5px;border-top-right-radius:5px}.medium-editor-toolbar li .medium-editor-button-active{background:-webkit-linear-gradient(top,#242424,rgba(0,0,0,.89));background:linear-gradient(to bottom,#242424,rgba(0,0,0,.89));color:#fff}.medium-editor-toolbar-form{background:#242424;border-radius:5px;color:#999}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#242424;box-sizing:border-box;color:#ccc;height:50px}.medium-editor-toolbar-form a{color:#fff}.medium-editor-toolbar-anchor-preview{background:#242424;border-radius:5px;color:#fff}.medium-editor-placeholder:after{color:#b3b3b1} -------------------------------------------------------------------------------- /public/css/themes/tim.min.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after{border-color:#2f1e07 transparent transparent;top:60px}.medium-toolbar-arrow-over:before{border-color:transparent transparent #2f1e07}.medium-editor-toolbar{background-color:#2f1e07;border:1px solid #5b3a0e;border-radius:4px}.medium-editor-toolbar li button{background-color:transparent;border:none;border-right:1px solid #5b3a0e;box-sizing:border-box;color:#fff;height:60px;min-width:60px;-webkit-transition:background-color .2s ease-in,color .2s ease-in;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li .medium-editor-button-active,.medium-editor-toolbar li button:hover{color:#fff;background-color:#030200}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:4px;border-top-left-radius:4px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:4px;border-right:none;border-top-right-radius:4px}.medium-editor-toolbar-form{background:#2f1e07;border-radius:4px;color:#fff}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#2f1e07;color:#fff;height:60px}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form a{color:#fff}.medium-editor-toolbar-anchor-preview{background:#2f1e07;border-radius:4px;color:#fff}.medium-editor-placeholder:after{color:#5b3a0e} -------------------------------------------------------------------------------- /public/css/themes/bootstrap.min.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after{border-color:#428bca transparent transparent;top:60px}.medium-toolbar-arrow-over:before{border-color:transparent transparent #428bca}.medium-editor-toolbar{background-color:#428bca;border:1px solid #357ebd;border-radius:4px}.medium-editor-toolbar li button{background-color:transparent;border:none;border-right:1px solid #357ebd;box-sizing:border-box;color:#fff;height:60px;min-width:60px;-webkit-transition:background-color .2s ease-in,color .2s ease-in;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li .medium-editor-button-active,.medium-editor-toolbar li button:hover{color:#fff;background-color:#3276b1}.medium-editor-toolbar li .medium-editor-button-first{border-bottom-left-radius:4px;border-top-left-radius:4px}.medium-editor-toolbar li .medium-editor-button-last{border-bottom-right-radius:4px;border-right:none;border-top-right-radius:4px}.medium-editor-toolbar-form{background:#428bca;border-radius:4px;color:#fff}.medium-editor-toolbar-form .medium-editor-toolbar-input{background:#428bca;color:#fff;height:60px}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form a{color:#fff}.medium-editor-toolbar-anchor-preview{background:#428bca;border-radius:4px;color:#fff}.medium-editor-placeholder:after{color:#357ebd} -------------------------------------------------------------------------------- /public/css/themes/flat.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after { 2 | top: 60px; 3 | border-color: #57ad68 transparent transparent transparent; } 4 | 5 | .medium-toolbar-arrow-over:before { 6 | top: -8px; 7 | border-color: transparent transparent #57ad68 transparent; } 8 | 9 | .medium-editor-toolbar { 10 | background-color: #57ad68; } 11 | .medium-editor-toolbar li { 12 | padding: 0; } 13 | .medium-editor-toolbar li button { 14 | min-width: 60px; 15 | height: 60px; 16 | border: none; 17 | border-right: 1px solid #9ccea6; 18 | background-color: transparent; 19 | color: #fff; 20 | -webkit-transition: background-color 0.2s ease-in, color 0.2s ease-in; 21 | transition: background-color 0.2s ease-in, color 0.2s ease-in; } 22 | .medium-editor-toolbar li button:hover { 23 | background-color: #346a3f; 24 | color: #fff; } 25 | .medium-editor-toolbar li .medium-editor-button-active { 26 | background-color: #23482a; 27 | color: #fff; } 28 | .medium-editor-toolbar li .medium-editor-button-last { 29 | border-right: none; } 30 | 31 | .medium-editor-toolbar-form .medium-editor-toolbar-input { 32 | height: 60px; 33 | background: #57ad68; 34 | color: #fff; } 35 | .medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder { 36 | color: #fff; 37 | color: rgba(255, 255, 255, 0.8); } 38 | .medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder { 39 | /* Firefox 18- */ 40 | color: #fff; 41 | color: rgba(255, 255, 255, 0.8); } 42 | .medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder { 43 | /* Firefox 19+ */ 44 | color: #fff; 45 | color: rgba(255, 255, 255, 0.8); } 46 | .medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder { 47 | color: #fff; 48 | color: rgba(255, 255, 255, 0.8); } 49 | 50 | .medium-editor-toolbar-form a { 51 | color: #fff; } 52 | 53 | .medium-editor-toolbar-anchor-preview { 54 | background: #57ad68; 55 | color: #fff; } 56 | 57 | .medium-editor-placeholder:after { 58 | color: #fff; } 59 | -------------------------------------------------------------------------------- /public/css/themes/roman.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after, 2 | .medium-toolbar-arrow-over:before { 3 | display: none; } 4 | 5 | .medium-editor-toolbar { 6 | background-color: #fff; 7 | background-color: rgba(255, 255, 255, 0.95); 8 | border-radius: 5px; 9 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45); } 10 | .medium-editor-toolbar li button { 11 | min-width: 50px; 12 | height: 50px; 13 | border: none; 14 | border-right: 1px solid #a8a8a8; 15 | background-color: transparent; 16 | color: #889aac; 17 | box-shadow: inset 0 0 3px #f8f8e6; 18 | background: -webkit-linear-gradient(top, #fff, rgba(0, 0, 0, 0.2)); 19 | background: linear-gradient(to bottom, #fff, rgba(0, 0, 0, 0.2)); 20 | text-shadow: 1px 4px 6px #def, 0 0 0 #000, 1px 4px 6px #def; 21 | -webkit-transition: background-color 0.2s ease-in; 22 | transition: background-color 0.2s ease-in; } 23 | .medium-editor-toolbar li button:hover { 24 | background-color: #fff; 25 | color: #fff; 26 | color: rgba(0, 0, 0, 0.8); } 27 | .medium-editor-toolbar li .medium-editor-button-first { 28 | border-top-left-radius: 5px; 29 | border-bottom-left-radius: 5px; } 30 | .medium-editor-toolbar li .medium-editor-button-last { 31 | border-top-right-radius: 5px; 32 | border-bottom-right-radius: 5px; } 33 | .medium-editor-toolbar li .medium-editor-button-active { 34 | background-color: #ccc; 35 | color: #000; 36 | color: rgba(0, 0, 0, 0.8); 37 | background: -webkit-linear-gradient(bottom, #fff, rgba(0, 0, 0, 0.1)); 38 | background: linear-gradient(to top, #fff, rgba(0, 0, 0, 0.1)); } 39 | 40 | .medium-editor-toolbar-form { 41 | background: #fff; 42 | color: #999; 43 | border-radius: 5px; } 44 | .medium-editor-toolbar-form .medium-editor-toolbar-input { 45 | margin: 0; 46 | height: 50px; 47 | background: #fff; 48 | color: #a8a8a8; } 49 | .medium-editor-toolbar-form a { 50 | color: #889aac; } 51 | 52 | .medium-editor-toolbar-anchor-preview { 53 | background: #fff; 54 | color: #889aac; 55 | border-radius: 5px; } 56 | 57 | .medium-editor-placeholder:after { 58 | color: #a8a8a8; } 59 | -------------------------------------------------------------------------------- /public/css/themes/mani.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after, 2 | .medium-toolbar-arrow-over:before { 3 | display: none; } 4 | 5 | .medium-editor-toolbar { 6 | border: 1px solid #cdd6e0; 7 | background-color: #dee7f0; 8 | background-color: rgba(222, 231, 240, 0.95); 9 | background: -webkit-linear-gradient(bottom, #dee7f0, white); 10 | background: linear-gradient(to top, #dee7f0, white); 11 | border-radius: 2px; 12 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45); } 13 | .medium-editor-toolbar li button { 14 | min-width: 50px; 15 | height: 50px; 16 | border: none; 17 | border-right: 1px solid #cdd6e0; 18 | background-color: transparent; 19 | color: #40648a; 20 | -webkit-transition: background-color 0.2s ease-in, color 0.2s ease-in; 21 | transition: background-color 0.2s ease-in, color 0.2s ease-in; } 22 | .medium-editor-toolbar li button:hover { 23 | background-color: #5c90c7; 24 | background-color: rgba(92, 144, 199, 0.45); 25 | color: #fff; } 26 | .medium-editor-toolbar li .medium-editor-button-first { 27 | border-top-left-radius: 2px; 28 | border-bottom-left-radius: 2px; } 29 | .medium-editor-toolbar li .medium-editor-button-last { 30 | border-top-right-radius: 2px; 31 | border-bottom-right-radius: 2px; } 32 | .medium-editor-toolbar li .medium-editor-button-active { 33 | background-color: #5c90c7; 34 | background-color: rgba(92, 144, 199, 0.45); 35 | color: #000; 36 | background: -webkit-linear-gradient(top, #dee7f0, rgba(0, 0, 0, 0.1)); 37 | background: linear-gradient(to bottom, #dee7f0, rgba(0, 0, 0, 0.1)); } 38 | 39 | .medium-editor-toolbar-form { 40 | background: #dee7f0; 41 | color: #999; 42 | border-radius: 2px; } 43 | .medium-editor-toolbar-form .medium-editor-toolbar-input { 44 | height: 50px; 45 | background: #dee7f0; 46 | color: #40648a; 47 | box-sizing: border-box; } 48 | .medium-editor-toolbar-form a { 49 | color: #40648a; } 50 | 51 | .medium-editor-toolbar-anchor-preview { 52 | background: #dee7f0; 53 | color: #40648a; 54 | border-radius: 2px; } 55 | 56 | .medium-editor-placeholder:after { 57 | color: #cdd6e0; } 58 | -------------------------------------------------------------------------------- /public/css/themes/default.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after { 2 | border-color: #242424 transparent transparent transparent; 3 | top: 50px; } 4 | 5 | .medium-toolbar-arrow-over:before { 6 | border-color: transparent transparent #242424 transparent; 7 | top: -8px; } 8 | 9 | .medium-editor-toolbar { 10 | background-color: #242424; 11 | background: -webkit-linear-gradient(top, #242424, rgba(36, 36, 36, 0.75)); 12 | background: linear-gradient(to bottom, #242424, rgba(36, 36, 36, 0.75)); 13 | border: 1px solid #000; 14 | border-radius: 5px; 15 | box-shadow: 0 0 3px #000; } 16 | .medium-editor-toolbar li button { 17 | background-color: #242424; 18 | background: -webkit-linear-gradient(top, #242424, rgba(36, 36, 36, 0.89)); 19 | background: linear-gradient(to bottom, #242424, rgba(36, 36, 36, 0.89)); 20 | border: 0; 21 | border-right: 1px solid #000; 22 | border-left: 1px solid #333; 23 | border-left: 1px solid rgba(255, 255, 255, 0.1); 24 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3); 25 | color: #fff; 26 | height: 50px; 27 | min-width: 50px; 28 | -webkit-transition: background-color 0.2s ease-in; 29 | transition: background-color 0.2s ease-in; } 30 | .medium-editor-toolbar li button:hover { 31 | background-color: #000; 32 | color: yellow; } 33 | .medium-editor-toolbar li .medium-editor-button-first { 34 | border-bottom-left-radius: 5px; 35 | border-top-left-radius: 5px; } 36 | .medium-editor-toolbar li .medium-editor-button-last { 37 | border-bottom-right-radius: 5px; 38 | border-top-right-radius: 5px; } 39 | .medium-editor-toolbar li .medium-editor-button-active { 40 | background-color: #000; 41 | background: -webkit-linear-gradient(top, #242424, rgba(0, 0, 0, 0.89)); 42 | background: linear-gradient(to bottom, #242424, rgba(0, 0, 0, 0.89)); 43 | color: #fff; } 44 | 45 | .medium-editor-toolbar-form { 46 | background: #242424; 47 | border-radius: 5px; 48 | color: #999; } 49 | .medium-editor-toolbar-form .medium-editor-toolbar-input { 50 | background: #242424; 51 | box-sizing: border-box; 52 | color: #ccc; 53 | height: 50px; } 54 | .medium-editor-toolbar-form a { 55 | color: #fff; } 56 | 57 | .medium-editor-toolbar-anchor-preview { 58 | background: #242424; 59 | border-radius: 5px; 60 | color: #fff; } 61 | 62 | .medium-editor-placeholder:after { 63 | color: #b3b3b1; } 64 | -------------------------------------------------------------------------------- /acf-front-end-editor.php: -------------------------------------------------------------------------------- 1 | run(); 66 | 67 | } 68 | run_acf_front_end_editor(); 69 | -------------------------------------------------------------------------------- /public/css/themes/tim.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after { 2 | border-color: #2f1e07 transparent transparent transparent; 3 | top: 60px; } 4 | 5 | .medium-toolbar-arrow-over:before { 6 | border-color: transparent transparent #2f1e07 transparent; } 7 | 8 | .medium-editor-toolbar { 9 | background-color: #2f1e07; 10 | border: 1px solid #5b3a0e; 11 | border-radius: 4px; } 12 | .medium-editor-toolbar li button { 13 | background-color: transparent; 14 | border: none; 15 | border-right: 1px solid #5b3a0e; 16 | box-sizing: border-box; 17 | color: #fff; 18 | height: 60px; 19 | min-width: 60px; 20 | -webkit-transition: background-color 0.2s ease-in, color 0.2s ease-in; 21 | transition: background-color 0.2s ease-in, color 0.2s ease-in; } 22 | .medium-editor-toolbar li button:hover { 23 | background-color: #030200; 24 | color: #fff; } 25 | .medium-editor-toolbar li .medium-editor-button-first { 26 | border-bottom-left-radius: 4px; 27 | border-top-left-radius: 4px; } 28 | .medium-editor-toolbar li .medium-editor-button-last { 29 | border-bottom-right-radius: 4px; 30 | border-right: none; 31 | border-top-right-radius: 4px; } 32 | .medium-editor-toolbar li .medium-editor-button-active { 33 | background-color: #030200; 34 | color: #fff; } 35 | 36 | .medium-editor-toolbar-form { 37 | background: #2f1e07; 38 | border-radius: 4px; 39 | color: #fff; } 40 | .medium-editor-toolbar-form .medium-editor-toolbar-input { 41 | background: #2f1e07; 42 | color: #fff; 43 | height: 60px; } 44 | .medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder { 45 | color: #fff; 46 | color: rgba(255, 255, 255, 0.8); } 47 | .medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder { 48 | /* Firefox 18- */ 49 | color: #fff; 50 | color: rgba(255, 255, 255, 0.8); } 51 | .medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder { 52 | /* Firefox 19+ */ 53 | color: #fff; 54 | color: rgba(255, 255, 255, 0.8); } 55 | .medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder { 56 | color: #fff; 57 | color: rgba(255, 255, 255, 0.8); } 58 | .medium-editor-toolbar-form a { 59 | color: #fff; } 60 | 61 | .medium-editor-toolbar-anchor-preview { 62 | background: #2f1e07; 63 | border-radius: 4px; 64 | color: #fff; } 65 | 66 | .medium-editor-placeholder:after { 67 | color: #5b3a0e; } 68 | -------------------------------------------------------------------------------- /public/css/themes/bootstrap.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after { 2 | border-color: #428bca transparent transparent transparent; 3 | top: 60px; } 4 | 5 | .medium-toolbar-arrow-over:before { 6 | border-color: transparent transparent #428bca transparent; } 7 | 8 | .medium-editor-toolbar { 9 | background-color: #428bca; 10 | border: 1px solid #357ebd; 11 | border-radius: 4px; } 12 | .medium-editor-toolbar li button { 13 | background-color: transparent; 14 | border: none; 15 | border-right: 1px solid #357ebd; 16 | box-sizing: border-box; 17 | color: #fff; 18 | height: 60px; 19 | min-width: 60px; 20 | -webkit-transition: background-color 0.2s ease-in, color 0.2s ease-in; 21 | transition: background-color 0.2s ease-in, color 0.2s ease-in; } 22 | .medium-editor-toolbar li button:hover { 23 | background-color: #3276b1; 24 | color: #fff; } 25 | .medium-editor-toolbar li .medium-editor-button-first { 26 | border-bottom-left-radius: 4px; 27 | border-top-left-radius: 4px; } 28 | .medium-editor-toolbar li .medium-editor-button-last { 29 | border-bottom-right-radius: 4px; 30 | border-right: none; 31 | border-top-right-radius: 4px; } 32 | .medium-editor-toolbar li .medium-editor-button-active { 33 | background-color: #3276b1; 34 | color: #fff; } 35 | 36 | .medium-editor-toolbar-form { 37 | background: #428bca; 38 | border-radius: 4px; 39 | color: #fff; } 40 | .medium-editor-toolbar-form .medium-editor-toolbar-input { 41 | background: #428bca; 42 | color: #fff; 43 | height: 60px; } 44 | .medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder { 45 | color: #fff; 46 | color: rgba(255, 255, 255, 0.8); } 47 | .medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder { 48 | /* Firefox 18- */ 49 | color: #fff; 50 | color: rgba(255, 255, 255, 0.8); } 51 | .medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder { 52 | /* Firefox 19+ */ 53 | color: #fff; 54 | color: rgba(255, 255, 255, 0.8); } 55 | .medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder { 56 | color: #fff; 57 | color: rgba(255, 255, 255, 0.8); } 58 | .medium-editor-toolbar-form a { 59 | color: #fff; } 60 | 61 | .medium-editor-toolbar-anchor-preview { 62 | background: #428bca; 63 | border-radius: 4px; 64 | color: #fff; } 65 | 66 | .medium-editor-placeholder:after { 67 | color: #357ebd; } 68 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | === Plugin Name === 2 | Contributors: horiondigital 3 | Donate link: http://www.horiondigital.com 4 | Tags: acf, front-end-editor 5 | Requires at least: 3.0.1 6 | Tested up to: 4.6.1 7 | Stable tag: 4.6.1 8 | License: GPLv2 9 | License URI: http://www.gnu.org/licenses/gpl-2.0.html 10 | 11 | The add-on allows admins to edit text fields, textareas and wysiwyg fields from front end simillary as you would edit a google doc. 12 | 13 | == Description == 14 | 15 | # Advanced Custom Fields add-on: Front-end Editor v2.0 16 | 17 | [![ACF FRONT END EDITOR](http://horiondigital.com/hostedimages/acffront0.png)](http://www.youtube.com/watch?v=rb9rsLaDImc) 18 | 19 | This is an add-on for WordPress [Advanced Custom Fields plugin](https://wordpress.org/plugins/advanced-custom-fields/) 20 | 21 | The add-on allows admins to edit text fields, textareas and wysiwyg fields from front end simillary as you would edit a google doc. 22 | 23 | Have fun. 24 | 25 | P.S. it also works with OPTIONS page fields, in the LOOP, with repeaters and flexible content: 26 | 27 | [![ACF FRONT END EDITOR](http://horiondigital.com/hostedimages/acffront2.gif)](http://www.youtube.com/watch?v=rb9rsLaDImc) 28 | 29 | Add-on author: Audrius Rackauskas @ [Horion Digital, Ltd](http://www.horiondigital.com) 30 | 31 | ACF plugin author: [Elliot Condon](http://www.elliotcondon.com/) 32 | 33 | == Installation == 34 | 35 | This section describes how to install the plugin and get it working. 36 | 37 | 1. Upload `acf-front-end-editor.php` to the `/wp-content/plugins/` directory 38 | 1. Activate the plugin through the 'Plugins' menu in WordPress 39 | 40 | == Frequently Asked Questions == 41 | 42 | = A question that someone might have = 43 | 44 | An answer to that question. 45 | 46 | = What about foo bar? = 47 | 48 | Answer to foo bar dilemma. 49 | 50 | == Screenshots == 51 | 52 | 1. This screen shot description corresponds to screenshot-1.(png|jpg|jpeg|gif). Note that the screenshot is taken from 53 | the /assets directory or the directory that contains the stable readme.txt (tags or trunk). Screenshots in the /assets 54 | directory take precedence. For example, `/assets/screenshot-1.png` would win over `/tags/4.3/screenshot-1.png` 55 | (or jpg, jpeg, gif). 56 | 2. This is the second screen shot 57 | 58 | == Changelog == 59 | 60 | = 2.0 = 61 | * major comapatbility update. 62 | 63 | = 1.0 = 64 | * initial build. 65 | 66 | * List versions from most recent at top to oldest at bottom. 67 | 68 | == Upgrade Notice == 69 | 70 | = 2.0 = 71 | Fixed compatability issues 72 | 73 | -------------------------------------------------------------------------------- /public/css/medium-editor.min.css: -------------------------------------------------------------------------------- 1 | .medium-editor-anchor-preview,.medium-editor-toolbar{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:16px;z-index:2000}@-webkit-keyframes medium-editor-image-loading{0%{-webkit-transform:scale(0);transform:scale(0)}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes medium-editor-image-loading{0%{-webkit-transform:scale(0);transform:scale(0)}100%{-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes medium-editor-pop-upwards{0%{opacity:0;-webkit-transform:matrix(.97,0,0,1,0,12);transform:matrix(.97,0,0,1,0,12)}20%{opacity:.7;-webkit-transform:matrix(.99,0,0,1,0,2);transform:matrix(.99,0,0,1,0,2)}40%{opacity:1;-webkit-transform:matrix(1,0,0,1,0,-1);transform:matrix(1,0,0,1,0,-1)}100%{-webkit-transform:matrix(1,0,0,1,0,0);transform:matrix(1,0,0,1,0,0)}}@keyframes medium-editor-pop-upwards{0%{opacity:0;-webkit-transform:matrix(.97,0,0,1,0,12);transform:matrix(.97,0,0,1,0,12)}20%{opacity:.7;-webkit-transform:matrix(.99,0,0,1,0,2);transform:matrix(.99,0,0,1,0,2)}40%{opacity:1;-webkit-transform:matrix(1,0,0,1,0,-1);transform:matrix(1,0,0,1,0,-1)}100%{-webkit-transform:matrix(1,0,0,1,0,0);transform:matrix(1,0,0,1,0,0)}}.medium-editor-anchor-preview{left:0;line-height:1.4;max-width:280px;position:absolute;text-align:center;top:0;word-break:break-all;word-wrap:break-word;visibility:hidden}.medium-editor-anchor-preview a{color:#fff;display:inline-block;margin:5px 5px 10px}.medium-editor-anchor-preview-active{visibility:visible}.medium-editor-dragover{background:#ddd}.medium-editor-image-loading{-webkit-animation:medium-editor-image-loading 1s infinite ease-in-out;animation:medium-editor-image-loading 1s infinite ease-in-out;background-color:#333;border-radius:100%;display:inline-block;height:40px;width:40px}.medium-editor-placeholder{position:relative}.medium-editor-placeholder:after{content:attr(data-placeholder)!important;font-style:italic;left:0;position:absolute;top:0;white-space:pre}.medium-toolbar-arrow-over:before,.medium-toolbar-arrow-under:after{border-style:solid;content:'';display:block;height:0;left:50%;margin-left:-8px;position:absolute;width:0}.medium-toolbar-arrow-under:after{border-width:8px 8px 0}.medium-toolbar-arrow-over:before{border-width:0 8px 8px;top:-8px}.medium-editor-toolbar{left:0;position:absolute;top:0;visibility:hidden}.medium-editor-toolbar ul{margin:0;padding:0}.medium-editor-toolbar li{float:left;list-style:none;margin:0;padding:0}.medium-editor-toolbar li button{box-sizing:border-box;cursor:pointer;display:block;font-size:14px;line-height:1.33;margin:0;padding:15px;text-decoration:none}.medium-editor-toolbar li button:focus{outline:0}.medium-editor-toolbar li .medium-editor-action-underline{text-decoration:underline}.medium-editor-toolbar li .medium-editor-action-pre{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px;font-weight:100;padding:15px 0}.medium-editor-toolbar-active{visibility:visible}.medium-editor-sticky-toolbar{position:fixed;top:1px}.medium-editor-toolbar-active.medium-editor-stalker-toolbar{-webkit-animation:medium-editor-pop-upwards 160ms forwards linear;animation:medium-editor-pop-upwards 160ms forwards linear}.medium-editor-action-bold{font-weight:bolder}.medium-editor-action-italic{font-style:italic}.medium-editor-toolbar-form{display:none}.medium-editor-toolbar-form a,.medium-editor-toolbar-form input{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}.medium-editor-toolbar-form .medium-editor-toolbar-form-row{line-height:14px;margin-left:5px;padding-bottom:5px}.medium-editor-toolbar-form .medium-editor-toolbar-input,.medium-editor-toolbar-form label{border:none;box-sizing:border-box;font-size:14px;margin:0;padding:6px;width:316px;display:inline-block}.medium-editor-toolbar-form .medium-editor-toolbar-input:focus,.medium-editor-toolbar-form label:focus{appearance:none;border:none;box-shadow:none;outline:0}.medium-editor-toolbar-form a{display:inline-block;font-size:24px;font-weight:bolder;margin:0 10px;text-decoration:none}.medium-editor-toolbar-actions:after{clear:both;content:"";display:table}[data-medium-editor-element] img{max-width:100%}[data-medium-editor-element] sub{vertical-align:sub}[data-medium-editor-element] sup{vertical-align:super}.medium-editor-hidden{display:none} -------------------------------------------------------------------------------- /includes/class-acf-front-end-editor-loader.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | class Acf_Front_End_Editor_Loader { 25 | 26 | /** 27 | * The array of actions registered with WordPress. 28 | * 29 | * @since 1.0.0 30 | * @access protected 31 | * @var array $actions The actions registered with WordPress to fire when the plugin loads. 32 | */ 33 | protected $actions; 34 | 35 | /** 36 | * The array of filters registered with WordPress. 37 | * 38 | * @since 1.0.0 39 | * @access protected 40 | * @var array $filters The filters registered with WordPress to fire when the plugin loads. 41 | */ 42 | protected $filters; 43 | 44 | /** 45 | * Initialize the collections used to maintain the actions and filters. 46 | * 47 | * @since 1.0.0 48 | */ 49 | public function __construct() { 50 | 51 | $this->actions = array(); 52 | $this->filters = array(); 53 | 54 | } 55 | 56 | /** 57 | * Add a new action to the collection to be registered with WordPress. 58 | * 59 | * @since 1.0.0 60 | * @param string $hook The name of the WordPress action that is being registered. 61 | * @param object $component A reference to the instance of the object on which the action is defined. 62 | * @param string $callback The name of the function definition on the $component. 63 | * @param int $priority Optional. he priority at which the function should be fired. Default is 10. 64 | * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1. 65 | */ 66 | public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) { 67 | $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args ); 68 | } 69 | 70 | /** 71 | * Add a new filter to the collection to be registered with WordPress. 72 | * 73 | * @since 1.0.0 74 | * @param string $hook The name of the WordPress filter that is being registered. 75 | * @param object $component A reference to the instance of the object on which the filter is defined. 76 | * @param string $callback The name of the function definition on the $component. 77 | * @param int $priority Optional. he priority at which the function should be fired. Default is 10. 78 | * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1 79 | */ 80 | public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) { 81 | $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args ); 82 | } 83 | 84 | /** 85 | * A utility function that is used to register the actions and hooks into a single 86 | * collection. 87 | * 88 | * @since 1.0.0 89 | * @access private 90 | * @param array $hooks The collection of hooks that is being registered (that is, actions or filters). 91 | * @param string $hook The name of the WordPress filter that is being registered. 92 | * @param object $component A reference to the instance of the object on which the filter is defined. 93 | * @param string $callback The name of the function definition on the $component. 94 | * @param int $priority The priority at which the function should be fired. 95 | * @param int $accepted_args The number of arguments that should be passed to the $callback. 96 | * @return array The collection of actions and filters registered with WordPress. 97 | */ 98 | private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) { 99 | 100 | $hooks[] = array( 101 | 'hook' => $hook, 102 | 'component' => $component, 103 | 'callback' => $callback, 104 | 'priority' => $priority, 105 | 'accepted_args' => $accepted_args 106 | ); 107 | 108 | return $hooks; 109 | 110 | } 111 | 112 | /** 113 | * Register the filters and actions with WordPress. 114 | * 115 | * @since 1.0.0 116 | */ 117 | public function run() { 118 | 119 | foreach ( $this->filters as $hook ) { 120 | add_filter( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] ); 121 | } 122 | 123 | foreach ( $this->actions as $hook ) { 124 | add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] ); 125 | } 126 | 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /admin/class-acf-front-end-editor-admin.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class Acf_Front_End_Editor_Admin { 24 | 25 | /** 26 | * The ID of this plugin. 27 | * 28 | * @since 1.0.0 29 | * @access private 30 | * @var string $plugin_name The ID of this plugin. 31 | */ 32 | private $plugin_name; 33 | 34 | /** 35 | * The version of this plugin. 36 | * 37 | * @since 1.0.0 38 | * @access private 39 | * @var string $version The current version of this plugin. 40 | */ 41 | private $version; 42 | 43 | /** 44 | * Initialize the class and set its properties. 45 | * 46 | * @since 1.0.0 47 | * @param string $plugin_name The name of this plugin. 48 | * @param string $version The version of this plugin. 49 | */ 50 | public function __construct( $plugin_name, $version ) { 51 | 52 | $this->plugin_name = $plugin_name; 53 | $this->version = $version; 54 | 55 | } 56 | 57 | /** 58 | * Register the stylesheets for the admin area. 59 | * 60 | * @since 1.0.0 61 | */ 62 | public function enqueue_styles() { 63 | 64 | /** 65 | * This function is provided for demonstration purposes only. 66 | * 67 | * An instance of this class should be passed to the run() function 68 | * defined in Acf_Front_End_Editor_Loader as all of the hooks are defined 69 | * in that particular class. 70 | * 71 | * The Acf_Front_End_Editor_Loader will then create the relationship 72 | * between the defined hooks and the functions defined in this 73 | * class. 74 | */ 75 | 76 | wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/acf-front-end-editor-admin.css', array(), $this->version, 'all' ); 77 | 78 | } 79 | 80 | /** 81 | * Register the JavaScript for the admin area. 82 | * 83 | * @since 1.0.0 84 | */ 85 | public function enqueue_scripts() { 86 | 87 | /** 88 | * This function is provided for demonstration purposes only. 89 | * 90 | * An instance of this class should be passed to the run() function 91 | * defined in Acf_Front_End_Editor_Loader as all of the hooks are defined 92 | * in that particular class. 93 | * 94 | * The Acf_Front_End_Editor_Loader will then create the relationship 95 | * between the defined hooks and the functions defined in this 96 | * class. 97 | */ 98 | 99 | wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/acf-front-end-editor-admin.js', array( 'jquery' ), $this->version, false ); 100 | 101 | } 102 | 103 | /** 104 | * Add an options page under the Settings submenu 105 | * 106 | * @since 2.0.1 107 | */ 108 | public function add_options_page() { 109 | 110 | $this->plugin_screen_hook_suffix = add_submenu_page( 111 | 'options-general.php', 112 | __( 'ACF Front end editor', 'acf-front-end-editor' ), 113 | __( 'ACF Front end editor', 'acf-front-end-editor' ), 114 | 'switch_themes', 115 | $this->plugin_name, 116 | array( $this, 'display_options_page' ) 117 | ); 118 | 119 | } 120 | 121 | /** 122 | * Render the options page for plugin 123 | * 124 | * @since 2.0.1 125 | */ 126 | public function display_options_page() { 127 | include_once 'partials/acf-front-end-editor-admin-display.php'; 128 | } 129 | 130 | /** 131 | * The options name to be used in this plugin 132 | * 133 | * @since 2.0.1 134 | * @access private 135 | * @var string $option_name Option name of this plugin 136 | */ 137 | private $option_name = 'acf_front_end_editor'; 138 | 139 | public function register_setting() { 140 | 141 | // Add a General section 142 | add_settings_section( 143 | $this->option_name . '_general', 144 | __( 'General', 'acf-front-end-editor' ), 145 | array( $this, $this->option_name . '_general_cb' ), 146 | $this->plugin_name 147 | ); 148 | 149 | add_settings_field( 150 | $this->option_name . '_capabilities', 151 | __( 'Enable front end editing for', 'acf-front-end-editor' ), 152 | array( $this, $this->option_name . '_capabilities_cb' ), 153 | $this->plugin_name, 154 | $this->option_name . '_general', 155 | array( 'label_for' => $this->option_name . '_capabilities' ) 156 | ); 157 | 158 | register_setting( $this->plugin_name, $this->option_name . '_capabilities'); 159 | } 160 | 161 | 162 | /** 163 | * Render the text for the vat section 164 | * 165 | * @since 2.0.1 166 | */ 167 | public function acf_front_end_editor_general_cb() { 168 | echo '

' . __( 'Manage Some Basic Settings Here', 'acf-front-end-editor' ) . '

'; 169 | } 170 | 171 | /** 172 | * Render capability list 173 | * 174 | * @since 2.0.1 175 | */ 176 | 177 | private function clean_up_capabilities($capabilities) { 178 | $caps = array(); 179 | foreach ($capabilities as $key => $cap): 180 | array_push($caps, $key); 181 | endforeach; 182 | 183 | return json_encode($caps); 184 | } 185 | 186 | 187 | /** 188 | * Render capability select for this plugin 189 | * 190 | * @since 2.0.1 191 | */ 192 | public function acf_front_end_editor_capabilities_cb() { 193 | global $wp_roles; 194 | $roles = $wp_roles->roles; 195 | $out = ''; 196 | $out.= ''; 201 | 202 | echo $out; 203 | } 204 | 205 | 206 | 207 | } 208 | -------------------------------------------------------------------------------- /public/js/acf-front-end-editor-public.js: -------------------------------------------------------------------------------- 1 | (function(window, $, undefined) { 2 | 'use strict'; 3 | 4 | // popup service 5 | var msg = { 6 | makeid: function(length) { 7 | var text = ""; 8 | var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 9 | for (var i = 0; i < length; i++) 10 | text += possible.charAt(Math.floor(Math.random() * possible.length)); 11 | return text; 12 | }, 13 | count: window.popCount = 0, 14 | pop: function(message) { 15 | console.log(message); 16 | this.count++; 17 | var $id = this.makeid(5); 18 | var pops = $('.hd-pop'); 19 | var gap = 10; 20 | var top = 20; 21 | var item = 70; 22 | if (pops.length === 0) this.count = 1; 23 | $('body').append('
' + message + '
'); 24 | $('#pop_' + $id).css('top', top + ((item + gap) * this.count)); 25 | 26 | $('#pop_' + $id).addClass('animated lightSpeedIn'); 27 | setTimeout( 28 | function() { 29 | $('#pop_' + $id).addClass('animated lightSpeedOut'); 30 | setTimeout( 31 | function() { 32 | $('#pop_' + $id).remove(); 33 | }, 1000 34 | ); 35 | }, 2000 36 | ); 37 | } 38 | }; 39 | 40 | var utils = { 41 | navButton: function(id, name) { 42 | var template = '
  • '+name+'
  • '; 43 | $('#wp-admin-bar-root-default').append(template); 44 | } 45 | }; 46 | 47 | var acfVars = { 48 | links : true, 49 | outline : false, 50 | textInputs : null, 51 | init: function() { 52 | var textInputs = $('[contenteditable]'); 53 | var elements = document.querySelectorAll('.editableHD'); 54 | var editor = new MediumEditor(elements); 55 | this.textInputs = textInputs; 56 | textInputs.each(function() { 57 | var contents = $(this).html(); 58 | $(this).on('focus', function() {}).on('blur', function() { 59 | if (contents != $(this).html()) { 60 | $(this).addClass('textChanged'); 61 | $('#wp-admin-bar-edit-live a').text('Save unsaved progress'); 62 | $('#wp-admin-bar-edit-live a').removeAttr('disabled'); 63 | contents = $(this).html(); 64 | } 65 | }); 66 | }); 67 | } 68 | }; 69 | 70 | var acfEditor = { 71 | initEdit : function () { 72 | utils.navButton('wp-admin-bar-edit-live', 'Save'); 73 | $('#wp-admin-bar-root-default').on('click', '#wp-admin-bar-edit-live', function() { 74 | var editableText = $('[contenteditable].textChanged'); 75 | var textString = []; 76 | editableText.each(function() { 77 | var text = $(this).html(); 78 | var key = $(this).data('key'); 79 | var name = $(this).data('name'); 80 | var postid = $(this).data('postid'); 81 | var textArr = [key, text, name, postid]; 82 | textString.push(textArr); 83 | }); 84 | 85 | if(editableText.length === 0) { 86 | msg.pop('Nothing to save'); 87 | return; 88 | } else { 89 | msg.pop('Saving your changes...'); 90 | } 91 | 92 | $.ajax({ 93 | url: meta.ajaxurl, 94 | data: { 95 | 'action': 'update_texts', 96 | 'textArr': textString 97 | }, 98 | success: function(data) { 99 | msg.pop('Changes have been saved!'); 100 | textString = []; 101 | $('#wp-admin-bar-edit-live a').text('Save'); 102 | $('[contenteditable].textChanged').removeClass('textChanged'); 103 | }, 104 | error: function(errorThrown) { 105 | msg.pop('Something went wrong!'); 106 | console.error('errorThrown'); 107 | } 108 | }); 109 | 110 | }); 111 | }, 112 | initToggle : function () { 113 | utils.navButton('wp-admin-bar-toggle-outline', 'Toggle outline'); 114 | $('#wp-admin-bar-root-default').on('click', '#wp-admin-bar-toggle-outline', function() { 115 | if(acfVars.outline) { 116 | acfVars.outline = false; 117 | acfVars.textInputs.parent().removeClass('hd-toggle-acf-outline').css('outline', 'none'); 118 | } else { 119 | acfVars.outline = true; 120 | acfVars.textInputs.parent().addClass('hd-toggle-acf-outline').css('outline', '1px solid red'); 121 | } 122 | }); 123 | }, 124 | initLinks : function () { 125 | utils.navButton('wp-admin-bar-toggle-actions', 'Disable links'); 126 | $('#wp-admin-bar-root-default').on('click', '#wp-admin-bar-toggle-actions', function() { 127 | if(acfVars.links) { 128 | $(this).find('a').text('Enable links'); 129 | acfVars.links = false; 130 | acfVars.textInputs.parent('a').addClass('hd-disable-acf-links').css('cursor', 'text'); 131 | acfVars.textInputs.parent('button').addClass('hd-disable-acf-links').css('cursor', 'text'); 132 | } else { 133 | $(this).find('a').text('Disable links'); 134 | acfVars.links = true; 135 | acfVars.textInputs.parent('a').removeClass('hd-disable-acf-links').css('cursor', 'auto'); 136 | acfVars.textInputs.parent('button').removeClass('hd-disable-acf-links').css('cursor', 'auto'); 137 | } 138 | }); 139 | 140 | $('body').on('click', '.hd-disable-acf-links', function(e) { 141 | console.log('a'); 142 | e.preventDefault(); 143 | }); 144 | } 145 | }; 146 | 147 | $(document).ready(function() { 148 | // register nav buttons 149 | acfVars.init(); 150 | acfEditor.initEdit(); 151 | acfEditor.initToggle(); 152 | acfEditor.initLinks(); 153 | 154 | }); 155 | 156 | 157 | })(window, window.jQuery); -------------------------------------------------------------------------------- /includes/class-acf-front-end-editor.php: -------------------------------------------------------------------------------- 1 | 29 | */ 30 | class Acf_Front_End_Editor { 31 | 32 | /** 33 | * The loader that's responsible for maintaining and registering all hooks that power 34 | * the plugin. 35 | * 36 | * @since 1.0.0 37 | * @access protected 38 | * @var Acf_Front_End_Editor_Loader $loader Maintains and registers all hooks for the plugin. 39 | */ 40 | protected $loader; 41 | 42 | /** 43 | * The unique identifier of this plugin. 44 | * 45 | * @since 1.0.0 46 | * @access protected 47 | * @var string $plugin_name The string used to uniquely identify this plugin. 48 | */ 49 | protected $plugin_name; 50 | 51 | /** 52 | * The current version of the plugin. 53 | * 54 | * @since 1.0.0 55 | * @access protected 56 | * @var string $version The current version of the plugin. 57 | */ 58 | protected $version; 59 | 60 | /** 61 | * Define the core functionality of the plugin. 62 | * 63 | * Set the plugin name and the plugin version that can be used throughout the plugin. 64 | * Load the dependencies, define the locale, and set the hooks for the admin area and 65 | * the public-facing side of the site. 66 | * 67 | * @since 1.0.0 68 | */ 69 | public function __construct() { 70 | 71 | $this->plugin_name = 'acf-front-end-editor'; 72 | $this->version = '1.0.0'; 73 | 74 | $this->load_dependencies(); 75 | $this->set_locale(); 76 | $this->define_admin_hooks(); 77 | $this->define_public_hooks(); 78 | 79 | } 80 | 81 | /** 82 | * Load the required dependencies for this plugin. 83 | * 84 | * Include the following files that make up the plugin: 85 | * 86 | * - Acf_Front_End_Editor_Loader. Orchestrates the hooks of the plugin. 87 | * - Acf_Front_End_Editor_i18n. Defines internationalization functionality. 88 | * - Acf_Front_End_Editor_Admin. Defines all hooks for the admin area. 89 | * - Acf_Front_End_Editor_Public. Defines all hooks for the public side of the site. 90 | * 91 | * Create an instance of the loader which will be used to register the hooks 92 | * with WordPress. 93 | * 94 | * @since 1.0.0 95 | * @access private 96 | */ 97 | private function load_dependencies() { 98 | 99 | /** 100 | * The class responsible for orchestrating the actions and filters of the 101 | * core plugin. 102 | */ 103 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-acf-front-end-editor-loader.php'; 104 | 105 | /** 106 | * The class responsible for defining internationalization functionality 107 | * of the plugin. 108 | */ 109 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-acf-front-end-editor-i18n.php'; 110 | 111 | /** 112 | * The class responsible for defining all actions that occur in the admin area. 113 | */ 114 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-acf-front-end-editor-admin.php'; 115 | 116 | /** 117 | * The class responsible for defining all actions that occur in the public-facing 118 | * side of the site. 119 | */ 120 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-acf-front-end-editor-public.php'; 121 | 122 | $this->loader = new Acf_Front_End_Editor_Loader(); 123 | 124 | } 125 | 126 | /** 127 | * Define the locale for this plugin for internationalization. 128 | * 129 | * Uses the Acf_Front_End_Editor_i18n class in order to set the domain and to register the hook 130 | * with WordPress. 131 | * 132 | * @since 1.0.0 133 | * @access private 134 | */ 135 | private function set_locale() { 136 | 137 | $plugin_i18n = new Acf_Front_End_Editor_i18n(); 138 | 139 | $this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' ); 140 | 141 | } 142 | 143 | /** 144 | * Register all of the hooks related to the admin area functionality 145 | * of the plugin. 146 | * 147 | * @since 1.0.0 148 | * @access private 149 | */ 150 | private function define_admin_hooks() { 151 | 152 | $plugin_admin = new Acf_Front_End_Editor_Admin( $this->get_plugin_name(), $this->get_version() ); 153 | 154 | $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_styles' ); 155 | $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts' ); 156 | $this->loader->add_action( 'admin_menu', $plugin_admin, 'add_options_page' ); 157 | $this->loader->add_action( 'admin_init', $plugin_admin, 'register_setting' ); 158 | 159 | } 160 | 161 | /** 162 | * Register all of the hooks related to the public-facing functionality 163 | * of the plugin. 164 | * 165 | * @since 1.0.0 166 | * @access private 167 | */ 168 | private function define_public_hooks() { 169 | 170 | $plugin_public = new Acf_Front_End_Editor_Public( $this->get_plugin_name(), $this->get_version() ); 171 | 172 | $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' ); 173 | $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' ); 174 | $this->loader->add_action( 'init', $plugin_public, 'register_filters' ); 175 | $this->loader->add_action( 'wp_ajax_nopriv_update_positions', $plugin_public, 'update_texts' ); 176 | $this->loader->add_action( 'wp_ajax_update_texts', $plugin_public, 'update_texts' ); 177 | 178 | } 179 | 180 | /** 181 | * Run the loader to execute all of the hooks with WordPress. 182 | * 183 | * @since 1.0.0 184 | */ 185 | public function run() { 186 | $this->loader->run(); 187 | } 188 | 189 | /** 190 | * The name of the plugin used to uniquely identify it within the context of 191 | * WordPress and to define internationalization functionality. 192 | * 193 | * @since 1.0.0 194 | * @return string The name of the plugin. 195 | */ 196 | public function get_plugin_name() { 197 | return $this->plugin_name; 198 | } 199 | 200 | /** 201 | * The reference to the class that orchestrates the hooks with the plugin. 202 | * 203 | * @since 1.0.0 204 | * @return Acf_Front_End_Editor_Loader Orchestrates the hooks of the plugin. 205 | */ 206 | public function get_loader() { 207 | return $this->loader; 208 | } 209 | 210 | /** 211 | * Retrieve the version number of the plugin. 212 | * 213 | * @since 1.0.0 214 | * @return string The version number of the plugin. 215 | */ 216 | public function get_version() { 217 | return $this->version; 218 | } 219 | 220 | } 221 | -------------------------------------------------------------------------------- /public/class-acf-front-end-editor-public.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | class Acf_Front_End_Editor_Public { 24 | 25 | /** 26 | * The ID of this plugin. 27 | * 28 | * @since 1.0.0 29 | * @access private 30 | * @var string $plugin_name The ID of this plugin. 31 | */ 32 | private $plugin_name; 33 | 34 | /** 35 | * The version of this plugin. 36 | * 37 | * @since 1.0.0 38 | * @access private 39 | * @var string $version The current version of this plugin. 40 | */ 41 | private $version; 42 | 43 | /** 44 | * Initialize the class and set its properties. 45 | * 46 | * @since 1.0.0 47 | * @param string $plugin_name The name of the plugin. 48 | * @param string $version The version of this plugin. 49 | */ 50 | public function __construct( $plugin_name, $version ) { 51 | 52 | $this->plugin_name = $plugin_name; 53 | $this->version = $version; 54 | 55 | } 56 | 57 | /** 58 | * Register the stylesheets for the public-facing side of the site. 59 | * 60 | * @since 1.0.0 61 | */ 62 | public function enqueue_styles() { 63 | if(is_user_logged_in()): 64 | wp_enqueue_style( $this->plugin_name.'-medium', plugin_dir_url( __FILE__ ) . 'css/medium-editor.min.css', array(), $this->version, 'all' ); 65 | wp_enqueue_style( $this->plugin_name.'-theme', plugin_dir_url( __FILE__ ) . 'css/themes/default.css', array(), $this->version, 'all' ); 66 | wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/acf-front-end-editor-public.css', array(), $this->version, 'all' ); 67 | endif; 68 | } 69 | 70 | /** 71 | * Register the JavaScript for the public-facing side of the site. 72 | * 73 | * @since 1.0.0 74 | */ 75 | public function enqueue_scripts() { 76 | 77 | if(is_user_logged_in()): 78 | wp_register_script( $this->plugin_name.'-medium', plugin_dir_url( __FILE__ ) . 'js/medium-editor.min.js', array( 'jquery' ), $this->version, false ); 79 | wp_register_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/acf-front-end-editor-public.js', array( 'jquery' ), $this->version, false ); 80 | wp_localize_script( $this->plugin_name, 'meta', array( 81 | 'ajaxurl' => admin_url( 'admin-ajax.php' ), 82 | 'page' => get_queried_object(), 83 | )); 84 | wp_enqueue_script( $this->plugin_name.'-medium'); 85 | wp_enqueue_script( $this->plugin_name); 86 | endif; 87 | } 88 | 89 | /** 90 | * Renders text fields and text areas with additional html that allows to target these areas via javascript 91 | * @param [String] $value 92 | * @param [Int] $post_id 93 | * @param [Object] $field 94 | * @return [String] returns edited value with additional html 95 | * 96 | * @since 1.0.0 97 | */ 98 | public function acf_targeter( $value, $post_id, $field ) { 99 | if(strpos($value, 'http') === 0 || $value == '#' || $value == '' || filter_var($value, FILTER_VALIDATE_EMAIL) || is_admin()) { 100 | $value = $value; 101 | } else { 102 | $key=$field['key']; 103 | $label=$field['name']; 104 | $type = 'labas'; 105 | $value = ''.$value.''; 106 | } 107 | return $value; 108 | } 109 | 110 | /** 111 | * Renders wysiwyg fields with additional html that allows to target these areas via javascript 112 | * @param [String] $value 113 | * @param [Int] $post_id 114 | * @param [Object] $field 115 | * @return [String] returns edited value with additional html 116 | * 117 | * @since 1.0.0 118 | */ 119 | public function acf_wysiwyg_targeter( $value, $post_id, $field ) { 120 | $key=$field['key']; 121 | $label=$field['name']; 122 | $value = '

    '.$value.'
    '; 123 | return $value; 124 | } 125 | 126 | /** 127 | * Formats field value to html if there is any 128 | * @param [String] $value 129 | * @param [Int] $post_id 130 | * @param [Object] $field 131 | * @return [String] returns edited value 132 | * 133 | * @since 1.0.0 134 | */ 135 | public function my_acf_format_value( $value, $post_id, $field ) { 136 | $value = html_entity_decode($value); 137 | return $value; 138 | } 139 | 140 | /** 141 | * Renders title fields with additional html that allows to target these aread via javascript 142 | * @param [String] $title 143 | * @param [Int] $id 144 | * @return [String] 145 | */ 146 | function wp_title_targeter($title, $id = null) { 147 | $value = ''.$title.''; 148 | return $value; 149 | } 150 | 151 | /** 152 | * Renders content fields with additional html that allows to target these aread via javascript 153 | * @param [String] $title 154 | * @param [Int] $id 155 | * @return [String] 156 | */ 157 | function wp_content_targeter($content) { 158 | $value = '
    '.$content.'
    '; 159 | return $value; 160 | } 161 | 162 | /** 163 | * Renders excerpt fields with additional html that allows to target these aread via javascript 164 | * @param [String] $title 165 | * @param [Int] $id 166 | * @return [String] 167 | */ 168 | function wp_excerpt_targeter($excerpt) { 169 | $value = ''.$excerpt.''; 170 | return $value; 171 | } 172 | 173 | /** 174 | * The options name to be used in this plugin 175 | * 176 | * @since 2.0.1 177 | * @access private 178 | * @var string $option_name Option name of this plugin 179 | */ 180 | private $option_name = 'acf_front_end_editor'; 181 | 182 | /** 183 | * Check if user has capabilities 184 | * 185 | * @since 2.0.1 186 | */ 187 | 188 | private function user_has_capabilities($capabilities) { 189 | if(!isset($capabilities) || empty($capabilities) || is_null($capabilities)) { 190 | return true; 191 | } 192 | $caps = json_decode($capabilities, true); 193 | $allow = true; 194 | if(!current_user_can( $caps[0] )) { 195 | $allow = false; 196 | } 197 | 198 | return $allow; 199 | } 200 | 201 | 202 | /** 203 | * Registers filters required for ACF field rendering 204 | * @since 2.0.0 205 | */ 206 | public function register_filters() { 207 | if(is_user_logged_in() && !is_admin() && $this->user_has_capabilities(get_option( $this->option_name . '_capabilities'))): 208 | add_filter('acf/load_value/type=text', array( $this, 'acf_targeter'), 10, 3); 209 | add_filter('acf/load_value/type=textarea', array( $this, 'acf_targeter'), 10, 3); 210 | add_filter('acf/load_value/type=wysiwyg', array( $this, 'acf_wysiwyg_targeter'), 10, 3); 211 | add_filter('acf/format_value/type=text', array( $this, 'my_acf_format_value'), 10, 3); 212 | add_filter('acf/format_value/type=textarea', array( $this, 'my_acf_format_value'), 10, 3); 213 | add_filter('acf/format_value/type=wysiwyg', array( $this, 'my_acf_format_value'), 10, 3); 214 | add_filter('the_title', array( $this, 'wp_title_targeter'), 10, 3); 215 | add_filter('the_content', array( $this, 'wp_content_targeter'), 10, 3); 216 | add_filter('get_the_excerpt', array( $this, 'wp_excerpt_targeter'), 10, 3); 217 | endif; 218 | } 219 | 220 | /** 221 | * Updates edited ACF fields in the database 222 | * 223 | * @since 1.0.0 224 | */ 225 | public function update_texts() { 226 | if ( isset($_REQUEST) ) { 227 | if(is_user_logged_in()): 228 | 229 | $textArr = $_REQUEST['textArr']; 230 | 231 | foreach ($textArr as $arr): 232 | $key = $arr[0]; 233 | $text = $arr[1]; 234 | $name = $arr[2]; 235 | $postid = $arr[3]; 236 | if($key == 'wp_core') { 237 | $hd_acf_post = array( 238 | 'ID' => $postid, 239 | ); 240 | 241 | switch ($name) { 242 | case 'wp_hd_title': 243 | $hd_acf_post['post_title'] = $text; 244 | break; 245 | case 'wp_hd_content': 246 | $hd_acf_post['post_content'] = $text; 247 | break; 248 | case 'wp_hd_excerpt': 249 | $hd_acf_post['post_excerpt'] = $text; 250 | break; 251 | } 252 | 253 | wp_update_post( $hd_acf_post ); 254 | } else { 255 | update_field($name, $text, $postid); 256 | } 257 | endforeach; 258 | endif; 259 | } 260 | die(); 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. -------------------------------------------------------------------------------- /public/js/medium-editor.min.js: -------------------------------------------------------------------------------- 1 | "classList"in document.createElement("_")||!function(a){"use strict";if("Element"in a){var b="classList",c="prototype",d=a.Element[c],e=Object,f=String[c].trim||function(){return this.replace(/^\s+|\s+$/g,"")},g=Array[c].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1},h=function(a,b){this.name=a,this.code=DOMException[a],this.message=b},i=function(a,b){if(""===b)throw new h("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(b))throw new h("INVALID_CHARACTER_ERR","String contains an invalid character");return g.call(a,b)},j=function(a){for(var b=f.call(a.getAttribute("class")||""),c=b?b.split(/\s+/):[],d=0,e=c.length;e>d;d++)this.push(c[d]);this._updateClassName=function(){a.setAttribute("class",this.toString())}},k=j[c]=[],l=function(){return new j(this)};if(h[c]=Error[c],k.item=function(a){return this[a]||null},k.contains=function(a){return a+="",-1!==i(this,a)},k.add=function(){var a,b=arguments,c=0,d=b.length,e=!1;do a=b[c]+"",-1===i(this,a)&&(this.push(a),e=!0);while(++ci;i++)e+=String.fromCharCode(f[i]);c.push(e)}else if("Blob"===b(a)||"File"===b(a)){if(!g)throw new h("NOT_READABLE_ERR");var k=new g;c.push(k.readAsBinaryString(a))}else a instanceof d?"base64"===a.encoding&&p?c.push(p(a.data)):"URI"===a.encoding?c.push(decodeURIComponent(a.data)):"raw"===a.encoding&&c.push(a.data):("string"!=typeof a&&(a+=""),c.push(unescape(encodeURIComponent(a))))},e.getBlob=function(a){return arguments.length||(a=null),new d(this.data.join(""),a,"raw")},e.toString=function(){return"[object BlobBuilder]"},f.slice=function(a,b,c){var e=arguments.length;return 3>e&&(c=null),new d(this.data.slice(a,e>1?b:this.data.length),c,this.encoding)},f.toString=function(){return"[object Blob]"},f.close=function(){this.size=0,delete this.data},c}(a);a.Blob=function(a,b){var d=b?b.type||"":"",e=new c;if(a)for(var f=0,g=a.length;g>f;f++)e.append(Uint8Array&&a[f]instanceof Uint8Array?a[f].buffer:a[f]);var h=e.getBlob(d);return!h.slice&&h.webkitSlice&&(h.slice=h.webkitSlice),h};var d=Object.getPrototypeOf||function(a){return a.__proto__};a.Blob.prototype=d(new a.Blob)}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content||this),function(a,b){"use strict";"object"==typeof module?module.exports=b:"function"==typeof define&&define.amd?define(function(){return b}):a.MediumEditor=b}(this,function(){"use strict";function a(a,b){return this.init(a,b)}a.extensions={},function(b){function c(a,b){var c,d=Array.prototype.slice.call(arguments,2);b=b||{};for(var e=0;e=0,keyCode:{BACKSPACE:8,TAB:9,ENTER:13,ESCAPE:27,SPACE:32,DELETE:46,K:75,M:77},isMetaCtrlKey:function(a){return d.isMac&&a.metaKey||!d.isMac&&a.ctrlKey?!0:!1},isKey:function(a,b){var c=d.getKeyCode(a);return!1===Array.isArray(b)?c===b:-1===b.indexOf(c)?!1:!0},getKeyCode:function(a){var b=a.which;return null===b&&(b=null!==a.charCode?a.charCode:a.keyCode),b},blockContainerElementNames:["p","h1","h2","h3","h4","h5","h6","blockquote","pre","ul","li","ol","address","article","aside","audio","canvas","dd","dl","dt","fieldset","figcaption","figure","footer","form","header","hgroup","main","nav","noscript","output","section","table","tbody","tfoot","video"],emptyElementNames:["br","col","colgroup","hr","img","input","source","wbr"],extend:function(){var a=[!0].concat(Array.prototype.slice.call(arguments));return c.apply(this,a)},defaults:function(){var a=[!1].concat(Array.prototype.slice.call(arguments));return c.apply(this,a)},createLink:function(a,b,c,e){var f=a.createElement("a");return d.moveTextRangeIntoElement(b[0],b[b.length-1],f),f.setAttribute("href",c),e&&f.setAttribute("target",e),f},findOrCreateMatchingTextNodes:function(a,b,c){for(var e=a.createTreeWalker(b,NodeFilter.SHOW_TEXT,null,!1),f=[],g=0,h=!1,i=null,j=null;null!==(i=e.nextNode())&&(!h&&c.startc.end+1)throw new Error("PerformLinking overshot the target!");h&&f.push(j||i),g+=i.nodeValue.length,null!==j&&(g+=j.nodeValue.length,e.nextNode()),j=null}return f},splitStartNodeIfNeeded:function(a,b,c){return b!==c?a.splitText(b-c):null},splitEndNodeIfNeeded:function(a,b,c,d){var e,f;e=d+(b||a).nodeValue.length+(b?a.nodeValue.length:0)-1,f=(b||a).nodeValue.length-(e+1-c),e>=c&&d!==e&&0!==f&&(b||a).splitText(f)},findAdjacentTextNodeWithContent:function(a,b,c){var d,e=!1,f=c.createNodeIterator(a,NodeFilter.SHOW_TEXT,null,!1);for(d=f.nextNode();d;){if(d===b)e=!0;else if(e&&3===d.nodeType&&d.nodeValue&&d.nodeValue.trim().length>0)break;d=f.nextNode()}return d},isDescendant:function(a,b,c){if(!a||!b)return!1;if(c&&a===b)return!0;for(var d=b.parentNode;null!==d;){if(d===a)return!0;d=d.parentNode}return!1},isElement:function(a){return!(!a||1!==a.nodeType)},throttle:function(a,b){var c,d,e,f=50,g=null,h=0,i=function(){h=Date.now(),g=null,e=a.apply(c,d),g||(c=d=null)};return b||0===b||(b=f),function(){var f=Date.now(),j=b-(f-h);return c=this,d=arguments,0>=j||j>b?(g&&(clearTimeout(g),g=null),h=f,e=a.apply(c,d),g||(c=d=null)):g||(g=setTimeout(i,j)),e}},traverseUp:function(a,b){if(!a)return!1;do{if(1===a.nodeType){if(b(a))return a;if(d.isMediumEditorElement(a))return!1}a=a.parentNode}while(a);return!1},htmlEntities:function(a){return String(a).replace(/&/g,"&").replace(//g,">").replace(/"/g,""")},insertHTMLCommand:function(a,b){var c,e,f,g,h,i,j;if(a.queryCommandSupported("insertHTML"))try{return a.execCommand("insertHTML",!1,b)}catch(k){}if(c=a.getSelection(),c.rangeCount){if(e=c.getRangeAt(0),j=e.commonAncestorContainer,d.isMediumEditorElement(j)&&!j.firstChild)e.selectNode(j.appendChild(a.createTextNode("")));else if(3===j.nodeType&&0===e.startOffset&&e.endOffset===j.nodeValue.length||3!==j.nodeType&&j.innerHTML===e.toString()){for(;!d.isMediumEditorElement(j)&&j.parentNode&&1===j.parentNode.childNodes.length&&!d.isMediumEditorElement(j.parentNode);)j=j.parentNode;e.selectNode(j)}for(e.deleteContents(),f=a.createElement("div"),f.innerHTML=b,g=a.createDocumentFragment();f.firstChild;)h=f.firstChild,i=g.appendChild(h);e.insertNode(g),i&&(e=e.cloneRange(),e.setStartAfter(i),e.collapse(!0),c.removeAllRanges(),c.addRange(e))}},execFormatBlock:function(b,c){var e=d.getTopBlockContainer(a.selection.getSelectionStart(b));if("blockquote"===c){if(e){var f=Array.prototype.slice.call(e.childNodes);if(f.some(function(a){return d.isBlockContainer(a)}))return b.execCommand("outdent",!1,null)}if(d.isIE)return b.execCommand("indent",!1,c)}return e&&c===e.nodeName.toLowerCase()&&(c="p"),d.isIE&&(c="<"+c+">"),b.execCommand("formatBlock",!1,c)},setTargetBlank:function(a,b){var c,d=b||!1;if("a"===a.nodeName.toLowerCase())a.target="_blank";else for(a=a.getElementsByTagName("a"),c=0;ce?(f=f.parentNode,c-=1):(g=g.parentNode,e-=1);for(;f!==g;)f=f.parentNode,g=g.parentNode;return f},isElementAtBeginningOfBlock:function(a){for(var b,c;!d.isBlockContainer(a)&&!d.isMediumEditorElement(a);){for(c=a;c=c.previousSibling;)if(b=3===c.nodeType?c.nodeValue:c.textContent,b.length>0)return!1;a=a.parentNode}return!0},isMediumEditorElement:function(a){return a&&a.getAttribute&&!!a.getAttribute("data-medium-editor-element")},getContainerEditorElement:function(a){return d.traverseUp(a,function(a){return d.isMediumEditorElement(a)})},isBlockContainer:function(a){return a&&3!==a.nodeType&&-1!==d.blockContainerElementNames.indexOf(a.nodeName.toLowerCase())},getClosestBlockContainer:function(a){return d.traverseUp(a,function(a){return d.isBlockContainer(a)})},getTopBlockContainer:function(a){var b=a;return d.traverseUp(a,function(a){return d.isBlockContainer(a)&&(b=a),!1}),b},getFirstSelectableLeafNode:function(a){for(;a&&a.firstChild;)a=a.firstChild;if(a=d.traverseUp(a,function(a){return-1===d.emptyElementNames.indexOf(a.nodeName.toLowerCase())}),"table"===a.nodeName.toLowerCase()){var b=a.querySelector("th, td");b&&(a=b)}return a},getFirstTextNode:function(a){if(3===a.nodeType)return a;for(var b=0;b0){var e,f=d.getRangeAt(0),g=f.cloneRange();if(g.selectNodeContents(a),g.setEnd(f.startContainer,f.startOffset),e=g.toString().length,c={start:e,end:e+f.toString().length},0!==e){var h=this.getIndexRelativeToAdjacentEmptyBlocks(b,a,f.startContainer,f.startOffset);-1!==h&&(c.emptyBlocksIndex=h)}}return c},importSelection:function(a,b,c,d){if(a&&b){var e=c.createRange();e.setStart(b,0),e.collapse(!0);for(var f,g=b,h=[],i=0,j=!1,k=!1;!k&&g;){if(3===g.nodeType)f=i+g.length,!j&&a.start>=i&&a.start<=f&&(e.setStart(g,a.start-i),j=!0),j&&a.end>=i&&a.end<=f&&(e.setEnd(g,a.end-i),k=!0),i=f;else for(var l=g.childNodes.length-1;l>=0;)h.push(g.childNodes[l]),l-=1;k||(g=h.pop())}"undefined"!=typeof a.emptyBlocksIndex&&(e=this.importSelectionMoveCursorPastBlocks(c,b,a.emptyBlocksIndex,e)),d&&(e=this.importSelectionMoveCursorPastAnchor(a,e));var m=c.getSelection();m.removeAllRanges(),m.addRange(e)}},importSelectionMoveCursorPastAnchor:function(b,c){var d=function(a){return"a"===a.nodeName.toLowerCase()};if(b.start===b.end&&3===c.startContainer.nodeType&&c.startOffset===c.startContainer.nodeValue.length&&a.util.traverseUp(c.startContainer,d)){for(var e=c.startContainer,f=c.startContainer.parentNode;null!==f&&"a"!==f.nodeName.toLowerCase();)f.childNodes[f.childNodes.length-1]!==e?f=null:(e=f,f=f.parentNode);if(null!==f&&"a"===f.nodeName.toLowerCase()){for(var g=null,h=0;null===g&&h0)break}else g===i.currentNode&&(h=i.currentNode);return f.setStart(a.util.getFirstSelectableLeafNode(h),0),f},getIndexRelativeToAdjacentEmptyBlocks:function(c,d,e,f){if(e.textContent.length>0&&f>0)return-1;var g=e;if(3!==g.nodeType&&(g=e.childNodes[f]),g&&!a.util.isElementAtBeginningOfBlock(g))return-1;for(var h=a.util.getClosestBlockContainer(e),i=c.createTreeWalker(d,NodeFilter.SHOW_ELEMENT,b,!1),j=0;i.nextNode();){var k=""===i.currentNode.textContent;if((k||j>0)&&(j+=1),i.currentNode===h)return j;k||(j=0)}return j},selectionInContentEditableFalse:function(a){var b,c=this.findMatchingSelectionParent(function(a){var c=a&&a.getAttribute("contenteditable");return"true"===c&&(b=!0),"#text"!==a.nodeName&&"false"===c},a);return!b&&c},getSelectionHtml:function(a){var b,c,d,e="",f=a.getSelection();if(f.rangeCount){for(d=a.createElement("div"),b=0,c=f.rangeCount;c>b;b+=1)d.appendChild(f.getRangeAt(b).cloneContents());e=d.innerHTML}return e},getCaretOffsets:function(a,b){var c,d;return b||(b=window.getSelection().getRangeAt(0)),c=b.cloneRange(),d=b.cloneRange(),c.selectNodeContents(a),c.setEnd(b.endContainer,b.endOffset),d.selectNodeContents(a),d.setStart(b.endContainer,b.endOffset),{left:c.toString().length,right:d.toString().length}},rangeSelectsSingleNode:function(a){var b=a.startContainer;return b===a.endContainer&&b.hasChildNodes()&&a.endOffset===a.startOffset+1},getSelectedParentElement:function(a){return a?this.rangeSelectsSingleNode(a)&&3!==a.startContainer.childNodes[a.startOffset].nodeType?a.startContainer.childNodes[a.startOffset]:3===a.startContainer.nodeType?a.startContainer.parentNode:a.startContainer:null},getSelectedElements:function(a){var b,c,d,e=a.getSelection();if(!e.rangeCount||e.isCollapsed||!e.getRangeAt(0).commonAncestorContainer)return[];if(b=e.getRangeAt(0),3===b.commonAncestorContainer.nodeType){for(c=[],d=b.commonAncestorContainer;d.parentNode&&1===d.parentNode.childNodes.length;)c.push(d.parentNode),d=d.parentNode;return c}return[].filter.call(b.commonAncestorContainer.getElementsByTagName("*"),function(a){return"function"==typeof e.containsNode?e.containsNode(a,!0):!0})},selectNode:function(a,b){var c=b.createRange(),d=b.getSelection();c.selectNodeContents(a),d.removeAllRanges(),d.addRange(c)},select:function(a,b,c,d,e){a.getSelection().removeAllRanges();var f=a.createRange();return f.setStart(b,c),d?f.setEnd(d,e):f.collapse(!0),a.getSelection().addRange(f),f},moveCursor:function(a,b,c){this.select(a,b,c)},getSelectionRange:function(a){var b=a.getSelection();return 0===b.rangeCount?null:b.getRangeAt(0)},getSelectionStart:function(a){var b=a.getSelection().anchorNode,c=b&&3===b.nodeType?b.parentNode:b;return c}};a.selection=c}(),function(){var b=function(a){this.base=a,this.options=this.base.options,this.events=[],this.disabledEvents={},this.customEvents={},this.listeners={}};b.prototype={InputEventOnContenteditableSupported:!a.util.isIE,attachDOMEvent:function(a,b,c,d){a.addEventListener(b,c,d),this.events.push([a,b,c,d])},detachDOMEvent:function(a,b,c,d){var e,f=this.indexOfListener(a,b,c,d);-1!==f&&(e=this.events.splice(f,1)[0],e[0].removeEventListener(e[1],e[2],e[3]))},indexOfListener:function(a,b,c,d){var e,f,g;for(e=0,f=this.events.length;f>e;e+=1)if(g=this.events[e],g[0]===a&&g[1]===b&&g[2]===c&&g[3]===d)return e;return-1},detachAllDOMEvents:function(){for(var a=this.events.pop();a;)a[0].removeEventListener(a[1],a[2],a[3]),a=this.events.pop()},enableCustomEvent:function(a){void 0!==this.disabledEvents[a]&&delete this.disabledEvents[a]},disableCustomEvent:function(a){this.disabledEvents[a]=!0},attachCustomEvent:function(a,b){this.setupListener(a),this.customEvents[a]||(this.customEvents[a]=[]),this.customEvents[a].push(b)},detachCustomEvent:function(a,b){var c=this.indexOfCustomListener(a,b);-1!==c&&this.customEvents[a].splice(c,1)},indexOfCustomListener:function(a,b){return this.customEvents[a]&&this.customEvents[a].length?this.customEvents[a].indexOf(b):-1},detachAllCustomEvents:function(){this.customEvents={}},triggerCustomEvent:function(a,b,c){this.customEvents[a]&&!this.disabledEvents[a]&&this.customEvents[a].forEach(function(a){a(b,c)})},destroy:function(){this.detachAllDOMEvents(),this.detachAllCustomEvents(),this.detachExecCommand(),this.base.elements&&this.base.elements.forEach(function(a){a.removeAttribute("data-medium-focused")})},attachToExecCommand:function(){this.execCommandListener||(this.execCommandListener=function(a){this.handleDocumentExecCommand(a)}.bind(this),this.wrapExecCommand(),this.options.ownerDocument.execCommand.listeners.push(this.execCommandListener))},detachExecCommand:function(){var a=this.options.ownerDocument;if(this.execCommandListener&&a.execCommand.listeners){var b=a.execCommand.listeners.indexOf(this.execCommandListener);-1!==b&&a.execCommand.listeners.splice(b,1),a.execCommand.listeners.length||this.unwrapExecCommand()}},wrapExecCommand:function(){var a=this.options.ownerDocument;if(!a.execCommand.listeners){var b=function(b,c,d){var e=a.execCommand.orig.apply(this,arguments);if(!a.execCommand.listeners)return e;var f=Array.prototype.slice.call(arguments);return a.execCommand.listeners.forEach(function(a){a({command:b,value:d,args:f,result:e})}),e};b.orig=a.execCommand,b.listeners=[],a.execCommand=b}},unwrapExecCommand:function(){var a=this.options.ownerDocument;a.execCommand.orig&&(a.execCommand=a.execCommand.orig)},setupListener:function(a){if(!this.listeners[a]){switch(a){case"externalInteraction":this.attachDOMEvent(this.options.ownerDocument.body,"mousedown",this.handleBodyMousedown.bind(this),!0),this.attachDOMEvent(this.options.ownerDocument.body,"click",this.handleBodyClick.bind(this),!0),this.attachDOMEvent(this.options.ownerDocument.body,"focus",this.handleBodyFocus.bind(this),!0);break;case"blur":this.setupListener("externalInteraction");break;case"focus":this.setupListener("externalInteraction");break;case"editableInput":this.contentCache=[],this.base.elements.forEach(function(a){this.contentCache[a.getAttribute("medium-editor-index")]=a.innerHTML,this.InputEventOnContenteditableSupported&&this.attachDOMEvent(a,"input",this.handleInput.bind(this))}.bind(this)),this.InputEventOnContenteditableSupported||(this.setupListener("editableKeypress"),this.keypressUpdateInput=!0,this.attachDOMEvent(document,"selectionchange",this.handleDocumentSelectionChange.bind(this)),this.attachToExecCommand());break;case"editableClick":this.attachToEachElement("click",this.handleClick);break;case"editableBlur":this.attachToEachElement("blur",this.handleBlur);break;case"editableKeypress":this.attachToEachElement("keypress",this.handleKeypress);break;case"editableKeyup":this.attachToEachElement("keyup",this.handleKeyup);break;case"editableKeydown":this.attachToEachElement("keydown",this.handleKeydown);break;case"editableKeydownEnter":this.setupListener("editableKeydown");break;case"editableKeydownTab":this.setupListener("editableKeydown");break;case"editableKeydownDelete":this.setupListener("editableKeydown");break;case"editableMouseover":this.attachToEachElement("mouseover",this.handleMouseover);break;case"editableDrag":this.attachToEachElement("dragover",this.handleDragging),this.attachToEachElement("dragleave",this.handleDragging);break;case"editableDrop":this.attachToEachElement("drop",this.handleDrop);break;case"editablePaste":this.attachToEachElement("paste",this.handlePaste)}this.listeners[a]=!0}},attachToEachElement:function(a,b){this.base.elements.forEach(function(c){this.attachDOMEvent(c,a,b.bind(this))},this)},focusElement:function(a){a.focus(),this.updateFocus(a,{target:a,type:"focus"})},updateFocus:function(b,c){var d,e=this.base.getExtensionByName("toolbar"),f=e?e.getToolbarElement():null,g=this.base.getExtensionByName("anchor-preview"),h=g&&g.getPreviewElement?g.getPreviewElement():null,i=this.base.getFocusedElement();i&&"click"===c.type&&this.lastMousedownTarget&&(a.util.isDescendant(i,this.lastMousedownTarget,!0)||a.util.isDescendant(f,this.lastMousedownTarget,!0)||a.util.isDescendant(h,this.lastMousedownTarget,!0))&&(d=i),d||this.base.elements.some(function(c){return!d&&a.util.isDescendant(c,b,!0)&&(d=c),!!d},this);var j=!a.util.isDescendant(i,b,!0)&&!a.util.isDescendant(f,b,!0)&&!a.util.isDescendant(h,b,!0);d!==i&&(i&&j&&(i.removeAttribute("data-medium-focused"),this.triggerCustomEvent("blur",c,i)),d&&(d.setAttribute("data-medium-focused",!0),this.triggerCustomEvent("focus",c,d))),j&&this.triggerCustomEvent("externalInteraction",c)},updateInput:function(a,b){if(this.contentCache){var c=a.getAttribute("medium-editor-index");a.innerHTML!==this.contentCache[c]&&this.triggerCustomEvent("editableInput",b,a),this.contentCache[c]=a.innerHTML}},handleDocumentSelectionChange:function(b){if(b.currentTarget&&b.currentTarget.activeElement){var c,d=b.currentTarget.activeElement;this.base.elements.some(function(b){return a.util.isDescendant(b,d,!0)?(c=b,!0):!1},this),c&&this.updateInput(c,{target:d,currentTarget:c})}},handleDocumentExecCommand:function(){var a=this.base.getFocusedElement();a&&this.updateInput(a,{target:a,currentTarget:a})},handleBodyClick:function(a){this.updateFocus(a.target,a)},handleBodyFocus:function(a){this.updateFocus(a.target,a)},handleBodyMousedown:function(a){this.lastMousedownTarget=a.target},handleInput:function(a){this.updateInput(a.currentTarget,a)},handleClick:function(a){this.triggerCustomEvent("editableClick",a,a.currentTarget)},handleBlur:function(a){this.triggerCustomEvent("editableBlur",a,a.currentTarget)},handleKeypress:function(a){if(this.triggerCustomEvent("editableKeypress",a,a.currentTarget),this.keypressUpdateInput){var b={target:a.target,currentTarget:a.currentTarget};setTimeout(function(){this.updateInput(b.currentTarget,b)}.bind(this),0)}},handleKeyup:function(a){this.triggerCustomEvent("editableKeyup",a,a.currentTarget)},handleMouseover:function(a){this.triggerCustomEvent("editableMouseover",a,a.currentTarget)},handleDragging:function(a){this.triggerCustomEvent("editableDrag",a,a.currentTarget)},handleDrop:function(a){this.triggerCustomEvent("editableDrop",a,a.currentTarget)},handlePaste:function(a){this.triggerCustomEvent("editablePaste",a,a.currentTarget)},handleKeydown:function(b){return this.triggerCustomEvent("editableKeydown",b,b.currentTarget),a.util.isKey(b,a.util.keyCode.ENTER)||b.ctrlKey&&a.util.isKey(b,a.util.keyCode.M)?this.triggerCustomEvent("editableKeydownEnter",b,b.currentTarget):a.util.isKey(b,a.util.keyCode.TAB)?this.triggerCustomEvent("editableKeydownTab",b,b.currentTarget):a.util.isKey(b,[a.util.keyCode.DELETE,a.util.keyCode.BACKSPACE])?this.triggerCustomEvent("editableKeydownDelete",b,b.currentTarget):void 0}},a.Events=b}(),function(){var b=a.Extension.extend({action:void 0,aria:void 0,tagNames:void 0,style:void 0,useQueryState:void 0,contentDefault:void 0,contentFA:void 0,classList:void 0,attrs:void 0,constructor:function(c){b.isBuiltInButton(c)?a.Extension.call(this,this.defaults[c]):a.Extension.call(this,c)},init:function(){a.Extension.prototype.init.apply(this,arguments),this.button=this.createButton(),this.on(this.button,"click",this.handleClick.bind(this))},getButton:function(){return this.button},getAction:function(){return"function"==typeof this.action?this.action(this.base.options):this.action},getAria:function(){return"function"==typeof this.aria?this.aria(this.base.options):this.aria},getTagNames:function(){return"function"==typeof this.tagNames?this.tagNames(this.base.options):this.tagNames},createButton:function(){var a=this.document.createElement("button"),b=this.contentDefault,c=this.getAria(),d=this.getEditorOption("buttonLabels");return a.classList.add("medium-editor-action"),a.classList.add("medium-editor-action-"+this.name),this.classList&&this.classList.forEach(function(b){a.classList.add(b)}),a.setAttribute("data-action",this.getAction()),c&&(a.setAttribute("title",c),a.setAttribute("aria-label",c)),this.attrs&&Object.keys(this.attrs).forEach(function(b){a.setAttribute(b,this.attrs[b])},this),"fontawesome"===d&&this.contentFA&&(b=this.contentFA),a.innerHTML=b,a},handleClick:function(a){a.preventDefault(),a.stopPropagation();var b=this.getAction();b&&this.execAction(b)},isActive:function(){return this.button.classList.contains(this.getEditorOption("activeButtonClass"))},setInactive:function(){this.button.classList.remove(this.getEditorOption("activeButtonClass")),delete this.knownState},setActive:function(){this.button.classList.add(this.getEditorOption("activeButtonClass")),delete this.knownState},queryCommandState:function(){var a=null;return this.useQueryState&&(a=this.base.queryCommandState(this.getAction())),a},isAlreadyApplied:function(a){var b,c,d=!1,e=this.getTagNames();return this.knownState===!1||this.knownState===!0?this.knownState:(e&&e.length>0&&(d=-1!==e.indexOf(a.nodeName.toLowerCase())),!d&&this.style&&(b=this.style.value.split("|"),c=this.window.getComputedStyle(a,null).getPropertyValue(this.style.prop),b.forEach(function(a){this.knownState||(d=-1!==c.indexOf(a),(d||"text-decoration"!==this.style.prop)&&(this.knownState=d))},this)),d)}});b.isBuiltInButton=function(b){return"string"==typeof b&&a.extensions.button.prototype.defaults.hasOwnProperty(b)},a.extensions.button=b}(),function(){a.extensions.button.prototype.defaults={bold:{name:"bold",action:"bold",aria:"bold",tagNames:["b","strong"],style:{prop:"font-weight",value:"700|bold"},useQueryState:!0,contentDefault:"B",contentFA:''},italic:{name:"italic",action:"italic",aria:"italic",tagNames:["i","em"],style:{prop:"font-style",value:"italic"},useQueryState:!0,contentDefault:"I",contentFA:''},underline:{name:"underline",action:"underline",aria:"underline",tagNames:["u"],style:{prop:"text-decoration",value:"underline"},useQueryState:!0,contentDefault:"U",contentFA:''},strikethrough:{name:"strikethrough",action:"strikethrough",aria:"strike through",tagNames:["strike"],style:{prop:"text-decoration",value:"line-through"},useQueryState:!0,contentDefault:"A",contentFA:''},superscript:{name:"superscript",action:"superscript",aria:"superscript",tagNames:["sup"],contentDefault:"x1",contentFA:''},subscript:{name:"subscript",action:"subscript",aria:"subscript",tagNames:["sub"],contentDefault:"x1",contentFA:''},image:{name:"image",action:"image",aria:"image",tagNames:["img"],contentDefault:"image",contentFA:''},orderedlist:{name:"orderedlist",action:"insertorderedlist",aria:"ordered list",tagNames:["ol"],useQueryState:!0,contentDefault:"1.",contentFA:''},unorderedlist:{name:"unorderedlist",action:"insertunorderedlist",aria:"unordered list",tagNames:["ul"],useQueryState:!0,contentDefault:"", 2 | contentFA:''},indent:{name:"indent",action:"indent",aria:"indent",tagNames:[],contentDefault:"",contentFA:''},outdent:{name:"outdent",action:"outdent",aria:"outdent",tagNames:[],contentDefault:"",contentFA:''},justifyCenter:{name:"justifyCenter",action:"justifyCenter",aria:"center justify",tagNames:[],style:{prop:"text-align",value:"center"},contentDefault:"C",contentFA:''},justifyFull:{name:"justifyFull",action:"justifyFull",aria:"full justify",tagNames:[],style:{prop:"text-align",value:"justify"},contentDefault:"J",contentFA:''},justifyLeft:{name:"justifyLeft",action:"justifyLeft",aria:"left justify",tagNames:[],style:{prop:"text-align",value:"left"},contentDefault:"L",contentFA:''},justifyRight:{name:"justifyRight",action:"justifyRight",aria:"right justify",tagNames:[],style:{prop:"text-align",value:"right"},contentDefault:"R",contentFA:''},removeFormat:{name:"removeFormat",aria:"remove formatting",action:"removeFormat",contentDefault:"X",contentFA:''},quote:{name:"quote",action:"append-blockquote",aria:"blockquote",tagNames:["blockquote"],contentDefault:"",contentFA:''},pre:{name:"pre",action:"append-pre",aria:"preformatted text",tagNames:["pre"],contentDefault:"0101",contentFA:''},h1:{name:"h1",action:"append-h1",aria:"header type one",tagNames:["h1"],contentDefault:"H1",contentFA:'1'},h2:{name:"h2",action:"append-h2",aria:"header type two",tagNames:["h2"],contentDefault:"H2",contentFA:'2'},h3:{name:"h3",action:"append-h3",aria:"header type three",tagNames:["h3"],contentDefault:"H3",contentFA:'3'},h4:{name:"h4",action:"append-h4",aria:"header type four",tagNames:["h4"],contentDefault:"H4",contentFA:'4'},h5:{name:"h5",action:"append-h5",aria:"header type five",tagNames:["h5"],contentDefault:"H5",contentFA:'5'},h6:{name:"h6",action:"append-h6",aria:"header type six",tagNames:["h6"],contentDefault:"H6",contentFA:'6'}}}(),function(){var b=a.extensions.button.extend({init:function(){a.extensions.button.prototype.init.apply(this,arguments)},formSaveLabel:"✓",formCloseLabel:"×",hasForm:!0,getForm:function(){},isDisplayed:function(){},hideForm:function(){},showToolbarDefaultActions:function(){var a=this.base.getExtensionByName("toolbar");a&&a.showToolbarDefaultActions()},hideToolbarDefaultActions:function(){var a=this.base.getExtensionByName("toolbar");a&&a.hideToolbarDefaultActions()},setToolbarPosition:function(){var a=this.base.getExtensionByName("toolbar");a&&a.setToolbarPosition()}});a.extensions.form=b}(),function(){var b=a.extensions.form.extend({customClassOption:null,customClassOptionText:"Button",linkValidation:!1,placeholderText:"Paste or type a link",targetCheckbox:!1,targetCheckboxText:"Open in new window",name:"anchor",action:"createLink",aria:"link",tagNames:["a"],contentDefault:"#",contentFA:'',init:function(){a.extensions.form.prototype.init.apply(this,arguments),this.subscribe("editableKeydown",this.handleKeydown.bind(this))},handleClick:function(b){b.preventDefault(),b.stopPropagation();var c=a.selection.getSelectionRange(this.document);return"a"===c.startContainer.nodeName.toLowerCase()||"a"===c.endContainer.nodeName.toLowerCase()||a.util.getClosestTag(a.selection.getSelectedParentElement(c),"a")?this.execAction("unlink"):(this.isDisplayed()||this.showForm(),!1)},handleKeydown:function(b){a.util.isKey(b,a.util.keyCode.K)&&a.util.isMetaCtrlKey(b)&&!b.shiftKey&&this.handleClick(b)},getForm:function(){return this.form||(this.form=this.createForm()),this.form},getTemplate:function(){var a=[''];return a.push('',"fontawesome"===this.getEditorOption("buttonLabels")?'':this.formSaveLabel,""),a.push('',"fontawesome"===this.getEditorOption("buttonLabels")?'':this.formCloseLabel,""),this.targetCheckbox&&a.push('
    ','',"","
    "),this.customClassOption&&a.push('
    ','',"","
    "),a.join("")},isDisplayed:function(){return"block"===this.getForm().style.display},hideForm:function(){this.getForm().style.display="none",this.getInput().value=""},showForm:function(a){var b=this.getInput(),c=this.getAnchorTargetCheckbox(),d=this.getAnchorButtonCheckbox();if(a=a||{url:""},"string"==typeof a&&(a={url:a}),this.base.saveSelection(),this.hideToolbarDefaultActions(),this.getForm().style.display="block",this.setToolbarPosition(),b.value=a.url,b.focus(),c&&(c.checked="_blank"===a.target),d){var e=a.buttonClass?a.buttonClass.split(" "):[];d.checked=-1!==e.indexOf(this.customClassOption)}},destroy:function(){return this.form?(this.form.parentNode&&this.form.parentNode.removeChild(this.form),void delete this.form):!1},getFormOpts:function(){var a=this.getAnchorTargetCheckbox(),b=this.getAnchorButtonCheckbox(),c={url:this.getInput().value};return this.linkValidation&&(c.url=this.checkLinkFormat(c.url)),c.target="_self",a&&a.checked&&(c.target="_blank"),b&&b.checked&&(c.buttonClass=this.customClassOption),c},doFormSave:function(){var a=this.getFormOpts();this.completeFormSave(a)},completeFormSave:function(a){this.base.restoreSelection(),this.execAction(this.action,a),this.base.checkSelection()},checkLinkFormat:function(a){var b=/^(https?|ftps?|rtmpt?):\/\/|mailto:/;return(b.test(a)?"":"http://")+a},doFormCancel:function(){this.base.restoreSelection(),this.base.checkSelection()},attachFormEvents:function(a){var b=a.querySelector(".medium-editor-toolbar-close"),c=a.querySelector(".medium-editor-toolbar-save"),d=a.querySelector(".medium-editor-toolbar-input");this.on(a,"click",this.handleFormClick.bind(this)),this.on(d,"keyup",this.handleTextboxKeyup.bind(this)),this.on(b,"click",this.handleCloseClick.bind(this)),this.on(c,"click",this.handleSaveClick.bind(this),!0)},createForm:function(){var a=this.document,b=a.createElement("div");return b.className="medium-editor-toolbar-form",b.id="medium-editor-toolbar-form-anchor-"+this.getEditorId(),b.innerHTML=this.getTemplate(),this.attachFormEvents(b),b},getInput:function(){return this.getForm().querySelector("input.medium-editor-toolbar-input")},getAnchorTargetCheckbox:function(){return this.getForm().querySelector(".medium-editor-toolbar-anchor-target")},getAnchorButtonCheckbox:function(){return this.getForm().querySelector(".medium-editor-toolbar-anchor-button")},handleTextboxKeyup:function(b){return b.keyCode===a.util.keyCode.ENTER?(b.preventDefault(),void this.doFormSave()):void(b.keyCode===a.util.keyCode.ESCAPE&&(b.preventDefault(),this.doFormCancel()))},handleFormClick:function(a){a.stopPropagation()},handleSaveClick:function(a){a.preventDefault(),this.doFormSave()},handleCloseClick:function(a){a.preventDefault(),this.doFormCancel()}});a.extensions.anchor=b}(),function(){var b=a.Extension.extend({name:"anchor-preview",hideDelay:500,previewValueSelector:"a",init:function(){this.anchorPreview=this.createPreview(),this.getEditorOption("elementsContainer").appendChild(this.anchorPreview),this.attachToEditables()},getPreviewElement:function(){return this.anchorPreview},createPreview:function(){var a=this.document.createElement("div");return a.id="medium-editor-anchor-preview-"+this.getEditorId(),a.className="medium-editor-anchor-preview",a.innerHTML=this.getTemplate(),this.on(a,"click",this.handleClick.bind(this)),a},getTemplate:function(){return'
    '},destroy:function(){this.anchorPreview&&(this.anchorPreview.parentNode&&this.anchorPreview.parentNode.removeChild(this.anchorPreview),delete this.anchorPreview)},hidePreview:function(){this.anchorPreview.classList.remove("medium-editor-anchor-preview-active"),this.activeAnchor=null},showPreview:function(a){return this.anchorPreview.classList.contains("medium-editor-anchor-preview-active")||a.getAttribute("data-disable-preview")?!0:(this.previewValueSelector&&(this.anchorPreview.querySelector(this.previewValueSelector).textContent=a.attributes.href.value,this.anchorPreview.querySelector(this.previewValueSelector).href=a.attributes.href.value),this.anchorPreview.classList.add("medium-toolbar-arrow-over"),this.anchorPreview.classList.remove("medium-toolbar-arrow-under"),this.anchorPreview.classList.contains("medium-editor-anchor-preview-active")||this.anchorPreview.classList.add("medium-editor-anchor-preview-active"),this.activeAnchor=a,this.positionPreview(),this.attachPreviewHandlers(),this)},positionPreview:function(a){a=a||this.activeAnchor;var b,c,d=this.anchorPreview.offsetHeight,e=a.getBoundingClientRect(),f=(e.left+e.right)/2,g=this.diffLeft,h=this.diffTop;b=this.anchorPreview.offsetWidth/2;var i=this.base.getExtensionByName("toolbar");i&&(g=i.diffLeft,h=i.diffTop),c=g-b,this.anchorPreview.style.top=Math.round(d+e.bottom-h+this.window.pageYOffset-this.anchorPreview.offsetHeight)+"px",b>f?this.anchorPreview.style.left=c+b+"px":this.window.innerWidth-fthis.hideDelay&&this.detachPreviewHandlers()},detachPreviewHandlers:function(){clearInterval(this.intervalTimer),this.instanceHandlePreviewMouseover&&(this.off(this.anchorPreview,"mouseover",this.instanceHandlePreviewMouseover),this.off(this.anchorPreview,"mouseout",this.instanceHandlePreviewMouseout),this.activeAnchor&&(this.off(this.activeAnchor,"mouseover",this.instanceHandlePreviewMouseover),this.off(this.activeAnchor,"mouseout",this.instanceHandlePreviewMouseout))),this.hidePreview(),this.hovering=this.instanceHandlePreviewMouseover=this.instanceHandlePreviewMouseout=null},attachPreviewHandlers:function(){this.lastOver=(new Date).getTime(),this.hovering=!0,this.instanceHandlePreviewMouseover=this.handlePreviewMouseover.bind(this),this.instanceHandlePreviewMouseout=this.handlePreviewMouseout.bind(this),this.intervalTimer=setInterval(this.updatePreview.bind(this),200),this.on(this.anchorPreview,"mouseover",this.instanceHandlePreviewMouseover),this.on(this.anchorPreview,"mouseout",this.instanceHandlePreviewMouseout),this.on(this.activeAnchor,"mouseover",this.instanceHandlePreviewMouseover),this.on(this.activeAnchor,"mouseout",this.instanceHandlePreviewMouseout)}});a.extensions.anchorPreview=b}();var b,c,d;return b=[" "," ","\n","\r"," "," "," "," "," ","\u2028","\u2029"],c="com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw",d="(((?:(https?://|ftps?://|nntp://)|www\\d{0,3}[.]|[a-z0-9.\\-]+[.]("+c+")\\/)\\S+(?:[^\\s`!\\[\\]{};:'\".,?«»“”‘’])))|(([a-z0-9\\-]+\\.)?[a-z0-9\\-]+\\.("+c+"))",function(){function e(b){return!a.util.getClosestTag(b,"a")}var f=new RegExp("^("+c+")$","i"),g=a.Extension.extend({init:function(){a.Extension.prototype.init.apply(this,arguments),this.disableEventHandling=!1,this.subscribe("editableKeypress",this.onKeypress.bind(this)),this.subscribe("editableBlur",this.onBlur.bind(this)),this.document.execCommand("AutoUrlDetect",!1,!1)},destroy:function(){this.document.queryCommandSupported("AutoUrlDetect")&&this.document.execCommand("AutoUrlDetect",!1,!0)},onBlur:function(a,b){this.performLinking(b)},onKeypress:function(b){this.disableEventHandling||a.util.isKey(b,[a.util.keyCode.SPACE,a.util.keyCode.ENTER])&&(clearTimeout(this.performLinkingTimeout),this.performLinkingTimeout=setTimeout(function(){try{var a=this.base.exportSelection();this.performLinking(b.target)&&this.base.importSelection(a,!0)}catch(c){window.console&&window.console.error("Failed to perform linking",c),this.disableEventHandling=!0}}.bind(this),0))},performLinking:function(b){var c=b.querySelectorAll(a.util.blockContainerElementNames.join(",")),d=!1;0===c.length&&(c=[b]);for(var e=0;e0&&null!==g;)e=c.currentNode,f=e.nodeValue,f.length>b?(g=e.splitText(f.length-b),b=0):(g=c.previousNode(),b-=f.length);return g},performLinkingWithinElement:function(b){for(var c=this.findLinkableText(b),d=!1,e=0;e1;)e.appendChild(d.childNodes[1])}});a.extensions.autoLink=g}(),function(){function b(b){var d=a.util.getContainerEditorElement(b),e=Array.prototype.slice.call(d.parentElement.querySelectorAll("."+c));e.forEach(function(a){a.classList.remove(c)})}var c="medium-editor-dragover",d=a.Extension.extend({name:"fileDragging",allowedTypes:["image"],init:function(){a.Extension.prototype.init.apply(this,arguments),this.subscribe("editableDrag",this.handleDrag.bind(this)),this.subscribe("editableDrop",this.handleDrop.bind(this))},handleDrag:function(a){a.preventDefault(),a.dataTransfer.dropEffect="copy";var d=a.target.classList?a.target:a.target.parentElement;b(d),"dragover"===a.type&&d.classList.add(c)},handleDrop:function(a){a.preventDefault(),a.stopPropagation(),a.dataTransfer.files&&Array.prototype.slice.call(a.dataTransfer.files).forEach(function(a){this.isAllowedFile(a)&&a.type.match("image")&&this.insertImageFile(a)},this),b(a.target)},isAllowedFile:function(a){return this.allowedTypes.some(function(b){return!!a.type.match(b)})},insertImageFile:function(b){var c=new FileReader;c.readAsDataURL(b);var d="medium-img-"+ +new Date;a.util.insertHTMLCommand(this.document,''),c.onload=function(){var a=this.document.getElementById(d);a&&(a.removeAttribute("id"),a.removeAttribute("class"),a.src=c.result)}.bind(this)}});a.extensions.fileDragging=d}(),function(){var b=a.Extension.extend({name:"keyboard-commands",commands:[{command:"bold",key:"B",meta:!0,shift:!1,alt:!1},{command:"italic",key:"I",meta:!0,shift:!1,alt:!1},{command:"underline",key:"U",meta:!0,shift:!1,alt:!1}],init:function(){a.Extension.prototype.init.apply(this,arguments),this.subscribe("editableKeydown",this.handleKeydown.bind(this)),this.keys={},this.commands.forEach(function(a){var b=a.key.charCodeAt(0);this.keys[b]||(this.keys[b]=[]),this.keys[b].push(a)},this)},handleKeydown:function(b){var c=a.util.getKeyCode(b);if(this.keys[c]){var d=a.util.isMetaCtrlKey(b),e=!!b.shiftKey,f=!!b.altKey;this.keys[c].forEach(function(a){a.meta!==d||a.shift!==e||a.alt!==f&&void 0!==a.alt||(b.preventDefault(),b.stopPropagation(),!1!==a.command&&this.execAction(a.command))},this)}}});a.extensions.keyboardCommands=b}(),function(){var b=a.extensions.form.extend({name:"fontsize",action:"fontSize",aria:"increase/decrease font size",contentDefault:"±",contentFA:'',init:function(){a.extensions.form.prototype.init.apply(this,arguments)},handleClick:function(a){if(a.preventDefault(),a.stopPropagation(),!this.isDisplayed()){var b=this.document.queryCommandValue("fontSize")+"";this.showForm(b)}return!1},getForm:function(){return this.form||(this.form=this.createForm()),this.form},isDisplayed:function(){return"block"===this.getForm().style.display},hideForm:function(){this.getForm().style.display="none",this.getInput().value=""},showForm:function(a){var b=this.getInput();this.base.saveSelection(),this.hideToolbarDefaultActions(),this.getForm().style.display="block",this.setToolbarPosition(),b.value=a||"",b.focus()},destroy:function(){return this.form?(this.form.parentNode&&this.form.parentNode.removeChild(this.form),void delete this.form):!1},doFormSave:function(){this.base.restoreSelection(),this.base.checkSelection()},doFormCancel:function(){this.base.restoreSelection(),this.clearFontSize(),this.base.checkSelection()},createForm:function(){var a=this.document,b=a.createElement("div"),c=a.createElement("input"),d=a.createElement("a"),e=a.createElement("a");return b.className="medium-editor-toolbar-form",b.id="medium-editor-toolbar-form-fontsize-"+this.getEditorId(),this.on(b,"click",this.handleFormClick.bind(this)),c.setAttribute("type","range"),c.setAttribute("min","1"),c.setAttribute("max","7"),c.className="medium-editor-toolbar-input",b.appendChild(c),this.on(c,"change",this.handleSliderChange.bind(this)),e.setAttribute("href","#"),e.className="medium-editor-toobar-save",e.innerHTML="fontawesome"===this.getEditorOption("buttonLabels")?'':"✓",b.appendChild(e),this.on(e,"click",this.handleSaveClick.bind(this),!0),d.setAttribute("href","#"),d.className="medium-editor-toobar-close",d.innerHTML="fontawesome"===this.getEditorOption("buttonLabels")?'':"×",b.appendChild(d),this.on(d,"click",this.handleCloseClick.bind(this)),b},getInput:function(){return this.getForm().querySelector("input.medium-editor-toolbar-input")},clearFontSize:function(){a.selection.getSelectedElements(this.document).forEach(function(a){"font"===a.nodeName.toLowerCase()&&a.hasAttribute("size")&&a.removeAttribute("size")})},handleSliderChange:function(){var a=this.getInput().value;"4"===a?this.clearFontSize():this.execAction("fontSize",{size:a})},handleFormClick:function(a){a.stopPropagation()},handleSaveClick:function(a){a.preventDefault(),this.doFormSave()},handleCloseClick:function(a){a.preventDefault(),this.doFormCancel()}});a.extensions.fontSize=b}(),function(){function b(){return[[new RegExp(/<[^>]*docs-internal-guid[^>]*>/gi),""],[new RegExp(/<\/b>(]*>)?$/gi),""],[new RegExp(/\s+<\/span>/g)," "],[new RegExp(/
    /g),"
    "],[new RegExp(/]*(font-style:italic;font-weight:bold|font-weight:bold;font-style:italic)[^>]*>/gi),''],[new RegExp(/]*font-style:italic[^>]*>/gi),''],[new RegExp(/]*font-weight:bold[^>]*>/gi),''],[new RegExp(/<(\/?)(i|b|a)>/gi),"<$1$2>"],[new RegExp(/<a(?:(?!href).)+href=(?:"|”|“|"|“|”)(((?!"|”|“|"|“|”).)*)(?:"|”|“|"|“|”)(?:(?!>).)*>/gi),''],[new RegExp(/<\/p>\n+/gi),"

    "],[new RegExp(/\n+

    /gi),""],["",""],["",""]]}var c=a.Extension.extend({forcePlainText:!0,cleanPastedHTML:!1,cleanReplacements:[],cleanAttrs:["class","style","dir"],cleanTags:["meta"],init:function(){a.Extension.prototype.init.apply(this,arguments),(this.forcePlainText||this.cleanPastedHTML)&&this.subscribe("editablePaste",this.handlePaste.bind(this))},handlePaste:function(b,c){var d,e,f,g,h="",i="text/html",j="text/plain";if(this.window.clipboardData&&void 0===b.clipboardData&&(b.clipboardData=this.window.clipboardData,i="Text",j="Text"),b.clipboardData&&b.clipboardData.getData&&!b.defaultPrevented){if(b.preventDefault(),f=b.clipboardData.getData(i),g=b.clipboardData.getData(j),this.cleanPastedHTML&&f)return this.cleanPaste(f);if(this.getEditorOption("disableReturn")||c.getAttribute("data-disable-return"))h=a.util.htmlEntities(g);else if(d=g.split(/[\r\n]+/g),d.length>1)for(e=0;e"+a.util.htmlEntities(d[e])+"

    ");else h=a.util.htmlEntities(d[0]);a.util.insertHTMLCommand(this.document,h)}},cleanPaste:function(a){var c,d,e,f,g=/"+a.split("

    ").join("

    ")+"

    ",d=e.querySelectorAll("a,p,div,br"),c=0;c"+d.innerHTML+"
    ":e.innerHTML=d.innerHTML,d.parentNode.replaceChild(e,d);for(f=b.querySelectorAll("span"),c=0;c0&&(d[0].classList.add(this.firstButtonClass),d[d.length-1].classList.add(this.lastButtonClass)),h},destroy:function(){this.toolbar&&(this.toolbar.parentNode&&this.toolbar.parentNode.removeChild(this.toolbar),delete this.toolbar)},getToolbarElement:function(){return this.toolbar||(this.toolbar=this.createToolbar()),this.toolbar},getToolbarActionsElement:function(){return this.getToolbarElement().querySelector(".medium-editor-toolbar-actions")},initThrottledMethods:function(){this.throttledPositionToolbar=a.util.throttle(function(){this.base.isActive&&this.positionToolbarIfShown()}.bind(this))},attachEventHandlers:function(){this.subscribe("blur",this.handleBlur.bind(this)),this.subscribe("focus",this.handleFocus.bind(this)),this.subscribe("editableClick",this.handleEditableClick.bind(this)),this.subscribe("editableKeyup",this.handleEditableKeyup.bind(this)),this.on(this.document.documentElement,"mouseup",this.handleDocumentMouseup.bind(this)),this["static"]&&this.sticky&&this.on(this.window,"scroll",this.handleWindowScroll.bind(this),!0),this.on(this.window,"resize",this.handleWindowResize.bind(this))},handleWindowScroll:function(){this.positionToolbarIfShown()},handleWindowResize:function(){this.throttledPositionToolbar()},handleDocumentMouseup:function(b){return b&&b.target&&a.util.isDescendant(this.getToolbarElement(),b.target)?!1:void this.checkState()},handleEditableClick:function(){setTimeout(function(){this.checkState()}.bind(this),0)},handleEditableKeyup:function(){this.checkState()},handleBlur:function(){clearTimeout(this.hideTimeout),clearTimeout(this.delayShowTimeout),this.hideTimeout=setTimeout(function(){this.hideToolbar()}.bind(this),1)},handleFocus:function(){this.checkState()},isDisplayed:function(){return this.getToolbarElement().classList.contains("medium-editor-toolbar-active")},showToolbar:function(){clearTimeout(this.hideTimeout),this.isDisplayed()||(this.getToolbarElement().classList.add("medium-editor-toolbar-active"),this.trigger("showToolbar",{},this.base.getFocusedElement()))},hideToolbar:function(){this.isDisplayed()&&(this.getToolbarElement().classList.remove("medium-editor-toolbar-active"),this.trigger("hideToolbar",{},this.base.getFocusedElement()))},isToolbarDefaultActionsDisplayed:function(){return"block"===this.getToolbarActionsElement().style.display},hideToolbarDefaultActions:function(){this.isToolbarDefaultActionsDisplayed()&&(this.getToolbarActionsElement().style.display="none")},showToolbarDefaultActions:function(){this.hideExtensionForms(),this.isToolbarDefaultActionsDisplayed()||(this.getToolbarActionsElement().style.display="block"), 3 | this.delayShowTimeout=this.base.delay(function(){this.showToolbar()}.bind(this))},hideExtensionForms:function(){this.forEachExtension(function(a){a.hasForm&&a.isDisplayed()&&a.hideForm()})},multipleBlockElementsSelected:function(){var b=/<[^\/>][^>]*><\/[^>]+>/gim,c=new RegExp("<("+a.util.blockContainerElementNames.join("|")+")[^>]*>","g"),d=a.selection.getSelectionHtml(this.document).replace(b,""),e=d.match(c);return!!e&&e.length>1},modifySelection:function(){var b=this.window.getSelection(),c=b.getRangeAt(0);if(this.standardizeSelectionStart&&c.startContainer.nodeValue&&c.startOffset===c.startContainer.nodeValue.length){var d=a.util.findAdjacentTextNodeWithContent(a.selection.getSelectionElement(this.window),c.startContainer,this.document);if(d){for(var e=0;0===d.nodeValue.substr(e,1).trim().length;)e+=1;c=a.selection.select(this.document,d,e,c.endContainer,c.endOffset)}}},checkState:function(){if(!this.base.preventSelectionUpdates){if(!this.base.getFocusedElement()||a.selection.selectionInContentEditableFalse(this.window))return this.hideToolbar();var b=a.selection.getSelectionElement(this.window);return!b||-1===this.getEditorElements().indexOf(b)||b.getAttribute("data-disable-toolbar")?this.hideToolbar():this.updateOnEmptySelection&&this["static"]?this.showAndUpdateToolbar():""===this.window.getSelection().toString().trim()||this.allowMultiParagraphSelection===!1&&this.multipleBlockElementsSelected()?this.hideToolbar():void this.showAndUpdateToolbar()}},showAndUpdateToolbar:function(){this.modifySelection(),this.setToolbarButtonStates(),this.trigger("positionToolbar",{},this.base.getFocusedElement()),this.showToolbarDefaultActions(),this.setToolbarPosition()},setToolbarButtonStates:function(){this.forEachExtension(function(a){"function"==typeof a.isActive&&"function"==typeof a.setInactive&&a.setInactive()}),this.checkActiveButtons()},checkActiveButtons:function(){var b,c=[],d=null,e=a.selection.getSelectionRange(this.document),f=function(a){"function"==typeof a.checkState?a.checkState(b):"function"==typeof a.isActive&&"function"==typeof a.isAlreadyApplied&&"function"==typeof a.setActive&&!a.isActive()&&a.isAlreadyApplied(b)&&a.setActive()};if(e&&(this.forEachExtension(function(a){return"function"==typeof a.queryCommandState&&(d=a.queryCommandState(),null!==d)?void(d&&"function"==typeof a.setActive&&a.setActive()):void c.push(a)}),b=a.selection.getSelectedParentElement(e),this.getEditorElements().some(function(c){return a.util.isDescendant(c,b,!0)})))for(;b&&(c.forEach(f),!a.util.isMediumEditorElement(b));)b=b.parentNode},positionToolbarIfShown:function(){this.isDisplayed()&&this.setToolbarPosition()},setToolbarPosition:function(){var a,b=this.base.getFocusedElement(),c=this.window.getSelection();return b?(this["static"]?(this.showToolbar(),this.positionStaticToolbar(b)):c.isCollapsed||(this.showToolbar(),this.positionToolbar(c)),a=this.base.getExtensionByName("anchor-preview"),void(a&&"function"==typeof a.hidePreview&&a.hidePreview())):this},positionStaticToolbar:function(a){this.getToolbarElement().style.left="0";var b,c=this.document.documentElement&&this.document.documentElement.scrollTop||this.document.body.scrollTop,d=this.window.innerWidth,e=this.getToolbarElement(),f=a.getBoundingClientRect(),g=f.top+c,h=f.left+f.width/2,i=e.offsetHeight,j=e.offsetWidth,k=j/2;switch(this.sticky?c>g+a.offsetHeight-i?(e.style.top=g+a.offsetHeight-i+"px",e.classList.remove("medium-editor-sticky-toolbar")):c>g-i?(e.classList.add("medium-editor-sticky-toolbar"),e.style.top="0px"):(e.classList.remove("medium-editor-sticky-toolbar"),e.style.top=g-i+"px"):e.style.top=g-i+"px",this.align){case"left":b=f.left;break;case"right":b=f.right-j;break;case"center":b=h-k}0>b?b=0:b+j>d&&(b=d-Math.ceil(j)-1),e.style.left=b+"px"},positionToolbar:function(a){this.getToolbarElement().style.left="0";var b=this.window.innerWidth,c=a.getRangeAt(0),d=c.getBoundingClientRect(),e=(d.left+d.right)/2,f=this.getToolbarElement(),g=f.offsetHeight,h=f.offsetWidth,i=h/2,j=50,k=this.diffLeft-i;d.tope?f.style.left=k+i+"px":i>b-e?f.style.left=b+k-i+"px":f.style.left=k+e+"px"}});a.extensions.toolbar=b}(),function(){var b=a.Extension.extend({init:function(){a.Extension.prototype.init.apply(this,arguments),this.subscribe("editableDrag",this.handleDrag.bind(this)),this.subscribe("editableDrop",this.handleDrop.bind(this))},handleDrag:function(a){var b="medium-editor-dragover";a.preventDefault(),a.dataTransfer.dropEffect="copy","dragover"===a.type?a.target.classList.add(b):"dragleave"===a.type&&a.target.classList.remove(b)},handleDrop:function(b){var c,d="medium-editor-dragover";b.preventDefault(),b.stopPropagation(),b.dataTransfer.files&&(c=Array.prototype.slice.call(b.dataTransfer.files,0),c.some(function(b){if(b.type.match("image")){var c,d;c=new FileReader,c.readAsDataURL(b),d="medium-img-"+ +new Date,a.util.insertHTMLCommand(this.document,''),c.onload=function(){var a=this.document.getElementById(d);a&&(a.removeAttribute("id"),a.removeAttribute("class"),a.src=c.result)}.bind(this)}}.bind(this))),b.target.classList.remove(d)}});a.extensions.imageDragging=b}(),function(){function b(b,c){if(this.options.disableReturn||c.getAttribute("data-disable-return"))b.preventDefault();else if(this.options.disableDoubleReturn||c.getAttribute("data-disable-double-return")){var d=a.selection.getSelectionStart(this.options.ownerDocument);(d&&""===d.textContent.trim()||d.previousElementSibling&&""===d.previousElementSibling.textContent.trim())&&b.preventDefault()}}function c(b){var c=a.selection.getSelectionStart(this.options.ownerDocument),d=c&&c.nodeName.toLowerCase();"pre"===d&&(b.preventDefault(),a.util.insertHTMLCommand(this.options.ownerDocument," ")),a.util.isListItem(c)&&(b.preventDefault(),b.shiftKey?this.options.ownerDocument.execCommand("outdent",!1,null):this.options.ownerDocument.execCommand("indent",!1,null))}function d(b){var c,d=a.selection.getSelectionStart(this.options.ownerDocument),e=d.nodeName.toLowerCase(),f=/^(\s+|)?$/i,g=/h\d/i;a.util.isKey(b,[a.util.keyCode.BACKSPACE,a.util.keyCode.ENTER])&&d.previousElementSibling&&g.test(e)&&0===a.selection.getCaretOffsets(d).left?a.util.isKey(b,a.util.keyCode.BACKSPACE)&&f.test(d.previousElementSibling.innerHTML)?(d.previousElementSibling.parentNode.removeChild(d.previousElementSibling),b.preventDefault()):a.util.isKey(b,a.util.keyCode.ENTER)&&(c=this.options.ownerDocument.createElement("p"),c.innerHTML="
    ",d.previousElementSibling.parentNode.insertBefore(c,d),b.preventDefault()):a.util.isKey(b,a.util.keyCode.DELETE)&&d.nextElementSibling&&d.previousElementSibling&&!g.test(e)&&f.test(d.innerHTML)&&g.test(d.nextElementSibling.nodeName.toLowerCase())?(a.selection.moveCursor(this.options.ownerDocument,d.nextElementSibling),d.previousElementSibling.parentNode.removeChild(d),b.preventDefault()):a.util.isKey(b,a.util.keyCode.BACKSPACE)&&"li"===e&&f.test(d.innerHTML)&&!d.previousElementSibling&&!d.parentElement.previousElementSibling&&d.nextElementSibling&&"li"===d.nextElementSibling.nodeName.toLowerCase()&&(c=this.options.ownerDocument.createElement("p"),c.innerHTML="
    ",d.parentElement.parentElement.insertBefore(c,d.parentElement),a.selection.moveCursor(this.options.ownerDocument,c),d.parentElement.removeChild(d),b.preventDefault())}function e(b){var c,d=a.selection.getSelectionStart(this.options.ownerDocument);d&&(a.util.isMediumEditorElement(d)&&0===d.children.length&&this.options.ownerDocument.execCommand("formatBlock",!1,"p"),a.util.isKey(b,a.util.keyCode.ENTER)&&!a.util.isListItem(d)&&(c=d.nodeName.toLowerCase(),"a"===c?this.options.ownerDocument.execCommand("unlink",!1,null):b.shiftKey||b.ctrlKey||/h\d/.test(c)||this.options.ownerDocument.execCommand("formatBlock",!1,"p")))}function f(a){a._mediumEditors||(a._mediumEditors=[null]),this.id||(this.id=a._mediumEditors.length),a._mediumEditors[this.id]=this}function g(a){a._mediumEditors&&a._mediumEditors[this.id]&&(a._mediumEditors[this.id]=null)}function h(b){b||(b=[]),"string"==typeof b&&(b=this.options.ownerDocument.querySelectorAll(b)),a.util.isElement(b)&&(b=[b]);var c=Array.prototype.slice.apply(b);this.elements=[],c.forEach(function(a,b){this.elements.push("textarea"===a.nodeName.toLowerCase()?r.call(this,a,b):a)},this)}function i(a,b){return Object.keys(b).forEach(function(c){void 0===a[c]&&(a[c]=b[c])}),a}function j(a,b,c){var d={window:c.options.contentWindow,document:c.options.ownerDocument,base:c};return a=i(a,d),"function"==typeof a.init&&a.init(),a.name||(a.name=b),a}function k(){return this.elements.every(function(a){return!!a.getAttribute("data-disable-toolbar")})?!1:this.options.toolbar!==!1}function l(){return k.call(this)?this.options.anchorPreview!==!1:!1}function m(){return this.options.placeholder!==!1}function n(){return this.options.autoLink!==!1}function o(){return this.options.imageDragging!==!1}function p(){return this.options.keyboardCommands!==!1}function q(){return!this.options.extensions.imageDragging}function r(a,b){for(var c=this.options.ownerDocument.createElement("div"),d=Date.now(),e="medium-editor-"+d+"-"+b,f=a.attributes;this.options.ownerDocument.getElementById(e);)d++,e="medium-editor-"+d+"-"+b;c.className=a.className,c.id=e,c.innerHTML=a.value,a.setAttribute("medium-editor-textarea-id",e);for(var g=0,h=f.length;h>g;g++)c.hasAttribute(f[g].nodeName)||c.setAttribute(f[g].nodeName,f[g].nodeValue);return a.classList.add("medium-editor-hidden"),a.parentNode.insertBefore(c,a),c}function s(){this.elements.forEach(function(a,b){this.options.disableEditing||a.getAttribute("data-disable-editing")||(a.setAttribute("contentEditable",!0),a.setAttribute("spellcheck",this.options.spellcheck)),a.setAttribute("data-medium-editor-element",!0),a.setAttribute("role","textbox"),a.setAttribute("aria-multiline",!0),a.setAttribute("medium-editor-index",b),a.hasAttribute("medium-editor-textarea-id")&&this.on(a,"input",function(a){var b=a.target,c=b.parentNode.querySelector('textarea[medium-editor-textarea-id="'+b.getAttribute("medium-editor-textarea-id")+'"]');c&&(c.value=this.serialize()[b.id].value)}.bind(this))},this)}function t(){var a;if(this.subscribe("editableKeydownTab",c.bind(this)),this.subscribe("editableKeydownDelete",d.bind(this)),this.subscribe("editableKeydownEnter",d.bind(this)),this.options.disableReturn||this.options.disableDoubleReturn)this.subscribe("editableKeydownEnter",b.bind(this));else for(a=0;a=0&&(d=a.selection.exportSelection(b,this.options.ownerDocument)),null!==d&&0!==c&&(d.editableElementIndex=c),d},saveSelection:function(){this.selectionState=this.exportSelection()},importSelection:function(b,c){if(b){var d=this.elements[b.editableElementIndex||0];a.selection.importSelection(b,d,this.options.ownerDocument,c)}},restoreSelection:function(){this.importSelection(this.selectionState)},createLink:function(b){var c=a.selection.getSelectionElement(this.options.contentWindow),d={};if(-1!==this.elements.indexOf(c)){try{if(this.events.disableCustomEvent("editableInput"),b.url&&b.url.trim().length>0){var e=this.options.contentWindow.getSelection();if(e){var f,g,h,i,j=e.getRangeAt(0),k=j.commonAncestorContainer;if(3===j.endContainer.nodeType&&3!==j.startContainer.nodeType&&0===j.startOffset&&j.startContainer.firstChild===j.endContainer&&(k=j.endContainer),g=a.util.getClosestBlockContainer(j.startContainer),h=a.util.getClosestBlockContainer(j.endContainer),3!==k.nodeType&&g===h){var l=g||c,m=this.options.ownerDocument.createDocumentFragment();this.execAction("unlink"),f=this.exportSelection(),m.appendChild(l.cloneNode(!0)),c===l?a.selection.select(this.options.ownerDocument,l.firstChild,0,l.lastChild,3===l.lastChild.nodeType?l.lastChild.nodeValue.length:l.lastChild.childNodes.length):a.selection.select(this.options.ownerDocument,l,0,l,l.childNodes.length);var n=this.exportSelection();i=a.util.findOrCreateMatchingTextNodes(this.options.ownerDocument,m,{start:f.start-n.start,end:f.end-n.start,editableElementIndex:f.editableElementIndex}),a.util.createLink(this.options.ownerDocument,i,b.url.trim());var o=(m.firstChild.innerHTML.match(/^\s+/)||[""])[0].length;a.util.insertHTMLCommand(this.options.ownerDocument,m.firstChild.innerHTML.replace(/^\s+/,"")),f.start-=o,f.end-=o,this.importSelection(f)}else this.options.ownerDocument.execCommand("createLink",!1,b.url);(this.options.targetBlank||"_blank"===b.target)&&a.util.setTargetBlank(a.selection.getSelectionStart(this.options.ownerDocument),b.url),b.buttonClass&&a.util.addClassToAnchors(a.selection.getSelectionStart(this.options.ownerDocument),b.buttonClass)}}if(this.options.targetBlank||"_blank"===b.target||b.buttonClass){d=this.options.ownerDocument.createEvent("HTMLEvents"),d.initEvent("input",!0,!0,this.options.contentWindow);for(var p=0;p1?b[1]:"";return{major:parseInt(c[0],10),minor:parseInt(c[1],10),revision:parseInt(c[2],10),preRelease:d,toString:function(){return[c[0],c[1],c[2]].join(".")+(d?"-"+d:"")}}},a.version=a.parseVersionString.call(this,{version:"5.7.0"}.version),a}()); --------------------------------------------------------------------------------