Repository: AesopInteractive/lasso Branch: master Commit: f9ede4873bc4 Files: 127 Total size: 2.1 MB Directory structure: gitextract_5b5hx62o/ ├── .gitattributes ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── Gruntfile.js ├── LICENSE.txt ├── README.md ├── README.txt ├── admin/ │ ├── assets/ │ │ ├── css/ │ │ │ └── lasso-editor-settings.css │ │ ├── js/ │ │ │ └── lasso-editor-settings.js │ │ └── less/ │ │ ├── style.less │ │ └── welcome.less │ └── includes/ │ ├── EDD_SL_Plugin_Updater.php │ ├── class-tgm-plugin-activation.php │ ├── load_admin.php │ └── menus/ │ ├── license.php │ ├── settings.php │ └── welcome.php ├── bootstrap.php ├── composer.json ├── includes/ │ ├── lasso_autoloader.php │ ├── process/ │ │ ├── delete.php │ │ ├── gallery.php │ │ ├── map.php │ │ ├── meta.php │ │ ├── new_object.php │ │ ├── revision.php │ │ ├── save.php │ │ ├── title_update.php │ │ ├── tour.php │ │ ├── update_object.php │ │ └── upload_image.php │ ├── sanatize.php │ └── save_gallery.php ├── internal-api/ │ ├── api_action.php │ ├── auth.php │ ├── docs.md │ ├── end_points.php │ ├── find_data.php │ └── route.php ├── languages/ │ ├── lasso-de_DE.mo │ ├── lasso-de_DE.po │ ├── lasso-es_ES.mo │ ├── lasso-es_ES.po │ ├── lasso-ko_KR.mo │ ├── lasso-ko_KR.po │ └── lasso.pot ├── lasso.php ├── package.json ├── public/ │ ├── assets/ │ │ ├── css/ │ │ │ ├── editus-table-edit-public.css │ │ │ ├── lasso.css │ │ │ └── style.css │ │ ├── js/ │ │ │ ├── editus-table-edit-public.js │ │ │ ├── lasso.js │ │ │ ├── source/ │ │ │ │ ├── all-posts.js │ │ │ │ ├── enter-editor.js │ │ │ │ ├── modal-sizing.js │ │ │ │ ├── post-settings.js │ │ │ │ ├── process-gallery-opts.js │ │ │ │ ├── process-gallery.js │ │ │ │ ├── process-image-upload.js │ │ │ │ ├── process-map.js │ │ │ │ ├── process-new-post.js │ │ │ │ ├── process-save-component.js │ │ │ │ ├── process-save-meta.js │ │ │ │ ├── process-save-title.js │ │ │ │ ├── process-save.js │ │ │ │ ├── process-wpimg.js │ │ │ │ ├── revisions.js │ │ │ │ ├── settings-live-editing.js │ │ │ │ ├── settings-panel.js │ │ │ │ ├── toolbar.js │ │ │ │ ├── tour.js │ │ │ │ ├── util--color-picker.js │ │ │ │ ├── util--content-editable.js │ │ │ │ ├── util--geo-complete.js │ │ │ │ ├── util--imagesloaded.js │ │ │ │ ├── util--rangy-classapplier.js │ │ │ │ ├── util--rangy-core.js │ │ │ │ ├── util--scrollbar.js │ │ │ │ ├── util--slider.js │ │ │ │ ├── util--sweet-alert.js │ │ │ │ ├── util--tagit.js │ │ │ │ ├── util--touch-punch.js │ │ │ │ ├── util--undo.js │ │ │ │ └── util--wp-api.js │ │ │ └── tour.js │ │ └── less/ │ │ ├── source/ │ │ │ ├── all-posts.less │ │ │ ├── animations.less │ │ │ ├── component-controls.less │ │ │ ├── component-settings--gallery.less │ │ │ ├── component-settings--map.less │ │ │ ├── component-settings.less │ │ │ ├── editor-controls.less │ │ │ ├── editor.less │ │ │ ├── featimg-controls.less │ │ │ ├── fonts.css │ │ │ ├── fonts.less │ │ │ ├── form-controls.less │ │ │ ├── mixins.css │ │ │ ├── mixins.less │ │ │ ├── mobile.less │ │ │ ├── post-settings.less │ │ │ ├── revisions.less │ │ │ ├── scrollbar.less │ │ │ ├── sidebar.less │ │ │ ├── sweet-alert.less │ │ │ ├── toolbar.less │ │ │ ├── tour.less │ │ │ ├── util--tags.less │ │ │ ├── util--tooltips.less │ │ │ ├── variables.css │ │ │ ├── variables.less │ │ │ └── wpimg-controls.less │ │ └── style.less │ └── includes/ │ ├── assets.php │ ├── components.php │ ├── editor-modules--gallery.php │ ├── editor-modules.php │ ├── helpers.php │ ├── lasso.php │ ├── option-engine.php │ ├── register_meta_field.php │ ├── tour.php │ ├── underscore-templates.php │ └── wrap-shortcodes.php └── uninstall.php ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ .gitattributes export-ignore .gitignore export-ignore .travis.yml export-ignore composer.json export-ignore CONTRIBUTING.md export-ignore Gruntfile.js export-ignore package.json export-ignore README.md export-ignore tests/ export-ignore ================================================ FILE: .gitignore ================================================ .DS_Store node_modules .sass-cache ================================================ FILE: .travis.yml ================================================ language: php sudo: false php: - 5.4 - 5.5 - 5.6 - hhvm - nightly # Specify versions of WordPress to test against env: - WP_VERSION=latest WP_MULTISITE=0 - WP_VERSION=latest WP_MULTISITE=1 - WP_VERSION=4.1 WP_MULTISITE=0 - WP_VERSION=4.0 WP_MULTISITE=0 - WP_VERSION=3.9.2 WP_MULTISITE=0 matrix: include: - php: 5.3 env: WP_VERSION=latest WP_MULTISITE=1 exclude: - php: hhvm env: WP_VERSION=3.9.2 WP_MULTISITE=0 - php: hhvm env: WP_VERSION=4.0 WP_MULTISITE=0 notifications: slack: aesop:GGeOu8QQeUGTkLvO1zTblBZv ================================================ FILE: CONTRIBUTING.md ================================================ This repository is for reporting Editus bugs only. This is not a support forum. If you need any help with Editus please email help@lasso.is with the same email that you purchased Editus with so that our system will identify you. When submitting a pull request, test Editus with [Aesop Story Theme](https://github.com/AesopInteractive/aesop-story-theme), and make any pull requests against our latest release branch. ================================================ FILE: Gruntfile.js ================================================ 'use strict'; module.exports = function(grunt) { require('load-grunt-tasks')(grunt); grunt.initConfig({ // watch our project for changes watch: { concat: { files: ['public/assets/js/source/*'], tasks:['concat:dist', 'uglify' ] }, less: { files: ['public/assets/less/**/*','admin/assets/less/**/*'], tasks: ['less:coreLess','less:settingsLess'] }, livereload: { options: { livereload: true }, files: ['public/assets/**/*','admin/assets/**/*', '**/*.html', '**/*.php', 'public/assets/img/**/*.{png,jpg,jpeg,gif,webp,svg}'] }, }, less: { coreLess: { options: { paths: ['public/assets/less/*'], cleancss:true }, files: { 'public/assets/css/lasso.css': 'public/assets/less/style.less' } }, settingsLess: { options: { paths: ['admin/assets/less/*'], cleancss:true }, files: { 'admin/assets/css/lasso-editor-settings.css': 'admin/assets/less/style.less' } } }, concat: { dist: { src: [ 'public/assets/js/source/util--undo.js', 'public/assets/js/source/util--rangy-core.js', 'public/assets/js/source/util--rangy-classapplier.js', 'public/assets/js/source/util--content-editable.js', 'public/assets/js/source/util--scrollbar.js', 'public/assets/js/source/util--sweet-alert.js', 'public/assets/js/source/util--geo-complete.js', 'public/assets/js/source/util--imagesloaded.js', 'public/assets/js/source/util--slider.js', 'public/assets/js/source/util--touch-punch.js', 'public/assets/js/source/util--tagit.js', 'public/assets/js/source/enter-editor.js', 'public/assets/js/source/post-settings.js', 'public/assets/js/source/settings-panel.js', 'public/assets/js/source/settings-live-editing.js', 'public/assets/js/source/toolbar.js', 'public/assets/js/source/process-save.js', 'public/assets/js/source/process-gallery.js', 'public/assets/js/source/process-gallery-opts.js', 'public/assets/js/source/process-map.js', 'public/assets/js/source/process-image-upload.js', 'public/assets/js/source/process-save-component.js', 'public/assets/js/source/process-new-post.js', 'public/assets/js/source/process-save-title.js', 'public/assets/js/source/process-wpimg.js', 'public/assets/js/source/process-save-meta.js', 'public/assets/js/source/modal-sizing.js', 'public/assets/js/source/all-posts.js', 'public/assets/js/source/tour.js', 'public/assets/js/source/revisions.js' ], dest: 'public/assets/js/lasso.js' } }, uglify: { scripts: { options: { sourceMap: 'public/assets/js/lasso.js.map', sourceMappingURL: 'lasso.js.map' }, files: { 'public/assets/js/lasso.min.js': [ 'public/assets/js/lasso.js' ] } } }, makepot: { target: { options: { domainPath: '/languages/', // Where to save the POT file. exclude: ['build/.*'], mainFile: 'lasso.php', // Main project file. potFilename: 'lasso.pot', // Name of the POT file. potHeaders: { poedit: true, // Includes common Poedit headers. 'x-poedit-keywordslist': true // Include a list of all possible gettext functions. }, type: 'wp-plugin', // Type of project (wp-plugin or wp-theme). updateTimestamp: true, // Whether the POT-Creation-Date should be updated without other changes. processPot: function( pot, options ) { pot.headers['report-msgid-bugs-to'] = 'http://edituswp.com'; pot.headers['language'] = 'en_US'; return pot; } } } } }); // register task grunt.registerTask('default', ['watch']); }; ================================================ FILE: LICENSE.txt ================================================ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. ================================================ FILE: README.md ================================================
Editus
Content creation and editing made simple
Build status
Editus is a commercial plugin available from https://edituswp.com. The plugin is hosted here on a public GitHub repository in order to better faciliate community contributions from developers and users alike. If you have a suggestion, a bug report, or a patch for an issue, feel free to submit it [here](https://github.com/AesopInteractive/lasso/issues). When submitting a pull request, test Editus with [Aesop Story Theme](https://github.com/AesopInteractive/aesop-story-theme), and make any pull requests against our latest release branch. We do ask, however, that if you are using the plugin on a live site that you please purchase a valid license from the website. We cannot provide support to anyone who does not hold a valid license key. Developer documentation can be found [here](https://github.com/AesopInteractive/lasso-documentation). Pull requests for our documentation are [welcome](https://github.com/AesopInteractive/lasso-documentation/pulls). ## Requirements Editus requires PHP 5.4 or above. ================================================ FILE: README.txt ================================================ === Editus === Contributors: nphaskins, hyunster, michaelbeil Plugin URI: https://edituswp.com Requires at least: 3.5 Tested up to: 5.9 Stable tag: 1.5.1 Front-end editing and creation suite. == Description == Front-end editing and creation suite. == Changelog == = 1.5.1 * Support for Gutenberg list blocks = 1.5.0 * Allowing the component pop up when using a keyboard without a mouse = 1.4.9 * Improved compatibility with standard WP blocks = 1.4.5 * NEW: Optional Paragraph component * Further changes for the popup menu option * Timeline Component Fix = 1.4.3 * NEW: Text popup menu option * A fix for custom post types = 1.4.1 * A bug fix for simple image component * NEW: Setting to change the placeholder text for new posts = 1.4.0 * NEW: Custom Taxonomy Support Option = 1.3.10 * Partial support for Gutenberg Cover Block * Fixed the issue where the component controls were disappearing after saving = 1.3.8 * Support for Gutenberg Image Block * Fixed the issue that custom post types could not save custom fields = 1.3.6 * The table component component right click menu now supports deleting the table * Minor bug fixes = 1.3.5 * Fix for simple image components * New option to auto-prefix links with http:// = 1.3.4 * More non-Aesop image component options = 1.3.3 * More non-Aesop image component options * Support for More Tag * Bug fixes = 1.3.0 * NEW option to edit excerpts * NEW new options for non-Aesop image components = 1.2.9 * Bug fix for custom fields = 1.2.8 * New optional table component = 1.2.6 * UI customization fixes = 1.2.5 * Fix for gallery create/update * Allow component icon color customization * Further Gutenberg compatibility work = 1.2.4 * Fix for post settings * Further Gutenberg compatibility work = 1.2.3 * Fix for Aesop Image component = 1.2.2 * PHP error fix = 1.2.1 * Some JS fixes = 1.2.0 * Support for multi-page posts = 1.1.11 * Fix for multiple users trying to edit the same post at the same time * Changed the behavior when the user deletes all text while using the editor. = 1.1.10 * Styles fixes for mobile = 1.1.9 * Now you can use Ctrl+SPACE to remove formatting from selected text. = 1.1.8 * A bug fix in the component editor = 1.1.7 * Support for WP Column and Spacer blocks. = 1.1.6 * Fix for the map component. = 1.1.5 * Fix for searching and auto save. = 1.1.4 * Added a filter for the table html codes = 1.1.3 * Fix for the "Click" UI setting * Fix for custom fields = 1.1.2 * Fix for multi-sites = 1.1.1 * Added Icons for OL and UL for the toolbar * German translation update = 1.1.0 * NEW: OL and UL buttons to create lists. = 1.0.9.2 * Fix for post locking * Further AJAX changes = 1.0.8 * Added the delete post button to mobile = 1.0.7 * Fix for meta information saving = 1.0.6 * Fix for Status saving and component insertion = 1.0.5 * Fix for Aesop Gallery component = 1.0.4 * Fix for draft posts when preview setting is required = 1.0.3 = * Added the delete post button * Option to disable "Pending" status * More changes for custom fields = 1.0.2 = * Changes for custom fields = 1.0.1 = * A new option setting to make links editable under the Edit mode * Fixed a bug with multiple custom field entries = 1.0.0 = * Added new UI color customization options * The Post Settings button is now available under the edit mode * Fixed a bug with automatically entering the edit mode * Copy and paste from MS Word strips the formatting * Fixed a bug with the new post dialog = 0.10.2.2 = * Fixed a bug for non-English installation = 0.10.2.1 = * A "Contributor" can now create posts, just not publish = 0.10.2.0 = * Posts can be now set to "Pending" = 0.10.1.1 = * Some style fixes and internal changes = 0.10.1.0 = * Fixed some issues with BR tags = 0.10.0.3 = * UI and language file adjustment = 0.10.0.0 = * NEW UI option to automatically add a Component button to an empty paragraph * Now Insert HTML box can accept a URL to embed, such as Youtube, Twitter etc. = 0.9.18.4 = * NEW UI option to switch from Drag-Drop to simple click for inserting components * Fix for shortcode features on the insert HTML button = 0.9.18.1 = * A bug fix for Quote when ASE is not installed * Some mobile fixes = 0.9.18.0 = * Post setting dialog fix for mobile = 0.9.17.9 = * An error fix for tags/categories = 0.9.17.8 = * Improved the Aesop Component properties handling * Fixed some compatibility issues with certain themes. = 0.9.17.6 = * Fixed a style bug with the category editing. = 0.9.17.5 = * Fixed a bug with the Set Date codes. * Changed the way PASTE works when the source is an HTML code. = 0.9.17.4 = * Fixed a bug that happens when the "Post" type is not selected under the "Enable for" options * Added an option allow users to create new categories for posts. = 0.9.17.3 = * Changed the code to obtain the REST API root = 0.9.17.2 = * A JS bug fix. = 0.9.17.1 = * Added support for subtitle editing, for Aesop themes and the Subtitle (https://wordpress.org/plugins/subtitles/) plugin. * Added an option to enable changing post dates using the Post Setting dialog * Changed the AJAX code to hide the tour dialog = 0.9.16.8 = * Added Twitter handling codes * Tour dialog uses REST API to save settings * More social share plugins supported. = 0.9.16.4 = * Added lasso_wrap_shortcode_exceptions filter * Fixed a bug where you could delete readonly elements by selecting and hitting a key other than BS and DEL. = 0.9.16.3 = * Adjusted the content filter so it can filter shortcode content = 0.9.16.2 = * Added lasso_required_plugins filter = 0.9.16.1 = * A bug fix for multisite installation. * A bug fix for page list. * Added a way to add a filter to the save operation. = 0.9.16.0 = * Option to work with custom fields from frontend: (https://edituswp.com/editing-and-updating-custom-fields-from-frontend/) * Improvement to the Undo behavior. * A bug fix for shortcode handling * Aesop event support = 0.9.15.3 = * More fix for custom post types * New option to set the tag for the "Italic" style = 0.9.15.2 = * Fix for post delete * Settings page update. New option to set the tag for the "Bold" style * Added style to hide controls from printing = 0.9.15.1 = * Insert HTML button can now process 3rd party shortcodes = 0.9.15.0 = * The Post List dialog now displays draft posts * The Post List dialog now displays custom post types properly. = 0.9.14.2 = * Editus tag classes now removed when saving * Fixed support email = 0.9.14.1 = * Fixed a bug involving an empty post * Fixed the icon file missing. = 0.9.14.0 = * Inserting H2 and H3 now also inserts p tags * Fixed the tour dialog getting stuck at loading * Fixed an issue where a component somtimes goes invisible after editing * All contenteditable attributes removed before being saved = 0.9.13.9 = * Fixed a bug where shortcodes were not properly restored while saving using REST API * Links are now always clickable. = 0.9.13.7 = * Aesop Video Component is now updated using AJAX * Fix for the publish button = 0.9.13.6 = * Fixed an issue with saving post titles * Aesop Content Component is now updated using AJAX * UI fixes for small mobile devices = 0.9.13.5 = * Now Editus uses REST API to save posts when it can. * REST API saving can also be disabled from the options. * Addressed the issue where cursor jumps when pasting texts. * Filters \' in components when edited. Filters it back to single apostrophe = 0.9.13.3 = * Fixed an issue with REST API codes causing an error during the loading of javascripts. * Fixes for dialog text colors on certain themes. * Dialog behaviors improved for mobile platforms. = 0.9.13.2 = * Fixed some styling issues for mobile. * Fixed an issue in third party shortcode handling. = 0.9.13.1 = * Save removes html comments = 0.9.13.0 = * Added REST API v2 support * Added codes to check if someone else is editing the post/page. * Fixed a bug automatically entering Edit Mode when it shouldn't. = 0.9.12.2 = * Fixed some issues with "Read Only" item options * Added an option to show the "Ignored Items" and keep them read only = 0.9.12.0 = * Aesop Hero Gallery has been added * Fixed several issues with Gallery AJAX update * When a new post is created Editus automatically enters Edit Mode = 0.9.11.1 = * Added an option to open a link a new browser tab. = 0.9.11.0 = * Now Gallery components update without having to reload the page, using AJAX. * Also fixed a bug in gallery image update. = 0.9.10.5 = * Major new features in Beta: * Added Color Text Button Options. * Added Text Alignment Button Options. = 0.9.10.2 = * Added a new option to set non-editable elements that are parts of the post. * Live update improvement for Video Component. = 0.9.10.1 = * Restored mobile support, for both phones and tablets * A few more style fixes = 0.9.10.0 = * Fixed a FireFox bug where links could not be inserted * Fixed a bug involving texts without any tags, resulting in the first lines disappearing * Further style fixes * New components shows setting dialogs when inserted for more intuitive user interface * Added Auto Save option * Disabled for mobile devices for now. * Added Aesop Gallery Pop support = 0.9.9.10 = * Fixed the error reporting for AJAX calls * Fixed the short code wrapping for non core Aesop components * Fixed a bug with creating gallery = 0.9.9.9 = * replaced the deprecated JQuery calls to live() = 0.9.9.8 = * fixed a bug in the shortcode saving codes * some form style and color adjustments = 0.9.9.7 = * added the following filter: lasso_user_can_filter * fixed a bug in adding a custom type post = 0.9.9.6 = * added the following hooks: lasso_title_class lasso_content_class lasso_featured_image_class lasso_dont_save * Tour dialog loading code has been changed. = 0.9.9.5 = * multi-site menu restored * added an option to specify gallery name while creating a new gallery. = 0.9.9.3 = * fixed unsaved data check * swapping gallery updates the images in the gallery sidebar * added button to create gallery to the gallery sidebar. = 0.9.9.1 = * fixed some styling issues where edit boxes and some buttons were not readable under certain themes * fixed the issue where featured images were not updated in the post settings dialog box * Editus now auto-detects article class if it's .entry-content * Editus now auto-detects title class if it's .entry-header * most short codes are now preserved (props Rouven Hurling) * multi-site menu has been changed (props Philipp Stracker) * post type issue with non-english sites fixed (props Philipp Stracker) = 0.9.8.2 = * fixed references to lasso.is = 0.9.8.1 = Oct 8 2015 = * fixed a capability issue that was allowing contributors to edit other users posts = 0.9.8 = Aug 14 2015 * renamed Lasso to Editus = 0.9.7 = July 30 2015 * updated TGM Plugin Activation to latest (props Ahmad Awais) * improved live editing video source switching in Video Component * added dismissible license notices if license is not supplied, expired, or invalid * fixed a capability issue with saving that was introduced with WordPress 4.2.3 (props Josh Polluck) = 0.9.6 = June 30 2015 * added the ability to access and restore post and page revisions * fixed a bug introduced on the last update with new posts/pages being duplicated when created * fixed authors not being able to publish posts * fixed a bug with Lasso Meta API not saving = 0.9.5 = June 17 2015 * added ability to search posts and pages within the all posts modal * added abilty to choose post type to create within new post creation modal * component now slides into view on settings click * fixed bug with video component not switching providers * fixed bug with galleries not saving gallery images properly * improved Meta API for developers wishing to integrate within Lassos post settings * mobile style improvement - props @peiche = 0.9.4.1 = May 28th 2015 * fixed bug with automatic updates - props @pippinsplugins * fixed bug with admins not seeing all posts in addition to their own = 0.9.4 = May 26 2015 * WARNING - PHP 5.4 or higher required!! * added ability to access and delete posts and pages (and custom post types with a filter) from the front-end (requires the WP REST API plugin). If the user is an Author or Contributor they will only be shown their posts or pages. * added ability to add a post from anywhere on the site * added ability to set featured image within settings modal if current theme supports post thumbnails * added ability to add categories and tags within settings modal * added CMD + S hot key to save post while in editor * added a close button to exit the editor * added a new API to allow third-party addons to add new settings modals (beta). They appear as a tab and work with only a filter. This is in preparation for releasing ACF, CMB2, and Ninja Forms integration addons. * added Canvas and Exposure themes to automatic theme support * fixed bug with tour hide not calculating correctly * fixed bug with Author or Contributor roles not being able to put a post in draft * fixed options not being cleaned up on uninstall * improved automatic theme support means supported themes work out of the box with no setup * improved user interface colors to better match WordPress design patterns * improved drag and drop detection between paragraphs * improved toolbar width logic - props @peiche * improved CSS selector performance * replaced tour GIFs with images = 0.9.3 = April 26th 2015 * fixed .entry-content being applied as a default Article CSS Class * allow escaping the warning modal that warns users if no Article CSS class is present * fixed image control setting with images inserted without Aesop Story Engine active * fixed featured image not being saved = 0.9.2 = April 14th 2015 * fixed links not working if editor was active but not in use * massive internal rewrite to use a custom API for processing requests instead of hitting admin-ajax. This increases the saving speed and ensures compatibility for very large WordPress installations and Enterprise users. Tested and working on WordPress MU, Apache, Nginx , and HHVM. = 0.9.1.1 = March 28th 2015 * fixed a js error that happened if an uploaded media item wasn't large enough to be resized to large = 0.9.1 = March 27th 2015 * added ability to insert standard WordPress images and blockquote. If Aesop Story Engine is activated, it replaces these with Aesop Story Engine's story components. * fixed css class names in toolbar components not being namespaced * better iOS compatibility with editing toolbar * removed H2 and H3 buttons from the insert HTML area if Extended Toolbar is selected as its redundant(Extended Toolbar puts H2, and H3 buttons into the toolbar) * clarified in the instructions that the article class name in the settings should include the preceding dot * if an embedded Tweet is in the content, we now remove it when you enter the editor so it's not save as HTML. In a future update, we plan to actually have some type of live ombed parsing system. This is a good fix for the time being. * prepended a ul class to ul.editor-controls and ul.editor-component-controls as well as set letter-spacing to 0 in hopes of clearing up theme CSS conflicting with Lasso CSS. Normally this is bad practice (ul.this), but it's better than applying !important. = 0.9 = March 21st 2015 * fixed a capability issue where contributors were allowed to publish posts * class visibility methods = 0.8.8 = March 19th 2015 * added an alert that pops up if the user tries to use the editor but hasn't added the required Article Class in order to use Lasso * added all Aesop built themes to automatically supported themes list * updated pot file = 0.8.7 = March 16th 2015 * added a new option that lets you list CSS classes of items to ignore on save. This makes Lasso compatible wity 99.99% of all WordPress themes = 0.8.6 = March 12th 2015 * new pre-flight function to check to ensure plugin settings are configured * added automatic theme support for WordPress core themes and UpThemes * added a new define define('LASSO_AGENCY_MODE') which removes the license page and links out to Lasso website * added a new tab for Lasso to hold the status page, license page, and settings * added new license menu page in preperation of the public launch of this plugin * fixed an issue with the height in the Tour slider sometimes not calculating correctly * fixed a permission issue where a user was allowed to edit another users posts. we were using edit_posts and switched to edit_post = 0.8.5 = March 8th 2015 * misc bug fixes * removed the "url helper" field for creating new posts as it was confusing some users * added helper text to the field for creating new posts as a better visual guide * new activation welcome screen in WordPress * fixed the content component from not correctly saving * added two actions: lasso_editor_controls_before && lasso_editor_controls_after * added two css classes that get applied to the body when a featured thumbnail is added or removed : lasso-post-thumb-added && lasso-post-thumb-removed ================================================ FILE: admin/assets/css/lasso-editor-settings.css ================================================ .lasso--animate__spin{-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}.not-visible{opacity:0;filter:alpha(opacity=0);display:none;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;transition:opacity .2s ease}.lasso--welcome{max-width:600px;margin:20px auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lasso--welcome *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.lasso--welcome p{font-size:15px}.lasso--welcome .lasso--welcome__steps{padding:0;list-style-type:none;margin:0 auto}.lasso--welcome .lasso--welcome__steps li{padding:25px;background:#fff;border:1px solid #d9d9d9;border-radius:5px;text-align:center;position:relative;margin-top:-25px;margin-bottom:100px}.lasso--welcome .lasso--welcome__steps li:before{font-family:Dashicons;color:#fff;padding:14px 27px 15px 14px;width:22px;font-size:36px;border-radius:100%;text-align:center;position:absolute;top:-33px;left:0;right:0;margin:0 auto;height:34px;line-height:37px}.lasso--welcome .lasso--welcome__steps li.info:before{content:'\f348';background:#2bc2ff}.lasso--welcome .lasso--welcome__steps li.success:before{content:'\f147';background:#4da34d}.lasso--welcome .lasso--welcome__steps li.error:before{content:'\f227';background:#d9534f}.lasso--welcome .lasso--welcome__steps li p{margin-bottom:0}.lasso--welcome .lasso--welcome__steps li h3{margin-bottom:5px}.lasso--welcome .lasso--welcome__top{text-align:center;margin-bottom:100px}.lasso--welcome .lasso--welcome__top:before,.lasso--welcome .lasso--welcome__top:after{content:" ";display:table}.lasso--welcome .lasso--welcome__top:after{clear:both}.lasso--welcome .lasso--welcome__top img{max-width:150px;margin:0 auto;border-radius:3px}.lasso--welcome .lasso--welcome__top h1+p{font-style:italic}.lasso--welcome .lasso--welcome__social{list-style:none;margin:0;padding:7px 0;border-top:1px solid #d9d9d9;border-bottom:1px solid #d9d9d9}.lasso--welcome .lasso--welcome__social:before,.lasso--welcome .lasso--welcome__social:after{content:" ";display:table}.lasso--welcome .lasso--welcome__social:after{clear:both}.lasso--welcome .lasso--welcome__social li{display:inline-block;line-height:1;margin:0}.lasso--welcome .lasso--welcome__social a{padding:2px 6px;display:block;text-decoration:none;color:inherit;line-height:1.5;font-weight:700}.lasso--welcome .lasso--welcome__social a:hover{color:#007aab;text-decoration:none}.lasso--welcome .lasso--welcome__social a i{font-size:16px;top:2px;line-height:19px;color:#007aab}.lasso--form-settings{max-width:500px;padding:20px;background:#fff;border-radius:5px;border:1px solid #cdcdcd;position:relative}.lasso--form-settings *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.lasso--form-settings:before,.lasso--form-settings:after{content:" ";display:table}.lasso--form-settings:after{clear:both}.lasso--form-settings .iris-picker{box-sizing:initial}.lasso--form-settings .iris-picker *{box-sizing:inherit}.lasso--form-settings .lasso-editor-settings--option-wrap{margin-bottom:25px;margin-left:15px}.lasso--form-settings .lasso-editor-settings--option-wrap.last .lasso-editor-settings--option-inner{border-bottom:0;padding-bottom:0}.lasso--form-settings .lasso-editor-settings--option-inner{border-bottom:1px solid #e7e7e7;padding-bottom:25px}.lasso--form-settings label{font-weight:700;font-size:110%;display:block}.lasso--form-settings textarea,.lasso--form-settings input[type=text]{border-radius:3px;width:240px;background-color:#f8f8f8;color:#000;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.1);box-shadow:inset 1px 1px 1px rgba(0,0,0,.1)}.lasso--form-settings input[type=checkbox]{float:left}.lasso--form-settings input[type=checkbox]~label{float:left;position:relative;top:-4px;left:4px}.lasso--form-settings input[type=submit]:active{outline:0}.lasso--form-settings input[type=submit]:disabled{opacity:.4;filter:alpha(opacity=40)}.lasso--form-settings .lasso--setting-description{display:block;margin:5px 0 10px;max-width:400px;color:#888;line-height:1.3;clear:left}.lasso--form-settings .lasso-editor-settings--submit{position:fixed;top:88px;left:760px}.lasso--form-settings .lasso-editor-settings--confirm{background:#fff;border:1px solid #cdcdcd;border-radius:3px;padding:10px 20px 14px 12px;margin-top:10px;-webkit-transition:all .2s linear;-moz-transition:all .2s linear;transition:all .2s linear}.lasso--form-settings .lasso-editor-settings--confirm.success:before,.lasso--form-settings .lasso-editor-settings--confirm.error:before{font-family:Dashicons;speak:none;font-size:18px;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;position:relative;top:4px;right:3px}.lasso--form-settings .lasso-editor-settings--confirm.success:before{content:'\f147';color:#5CB85C}.lasso--form-settings .lasso-editor-settings--confirm.error:before{content:'\f158';color:#d9534f}#wpbody #lasso-editor-settings-form .button-primary.saved{background:#5CB85C!important} ================================================ FILE: admin/assets/js/lasso-editor-settings.js ================================================ jQuery(document).ready(function($){ // entry handler $('#lasso-editor-settings-form').submit(function(e) { var $this = $(this); e.preventDefault(); $this.find(':submit').attr( 'disabled','disabled' ); var data = $this.serialize(); $.post( ajaxurl, data, function(response) { if ( response.success ) { $this.find(':submit').addClass('saved'); $this.find('.lasso-editor-settings--submit').append('
Settings Saved!
'); setTimeout( function(){ $this.find(':submit').removeClass('saved'); $this.find('.lasso-editor-settings--confirm').remove(); $this.find(':submit').attr( 'disabled',false ); }, 2000 ); } else { $this.find('.lasso-editor-settings--submit').append('
Something went wrong! :(
'); } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); $this.find('.lasso-editor-settings--submit').append('
Something went wrong! :(
'); }); }); $('.color-picker').wpColorPicker(); // initialize color pickers with default values $('#lasso-editor-settings--default-colors').click(function() { $($(".color-picker")[0]).wpColorPicker('color', "#0000ff"); $($(".color-picker")[1]).wpColorPicker('color', "#000030"); $($(".color-picker")[2]).wpColorPicker('color', "#000055"); $($(".color-picker")[3]).wpColorPicker('color', "#ffffff"); }); $('#lasso_editor_use_old_ui').change(function() { if(this.checked) { $('#lasso-editor-settings--colors').slideUp(); } else { $('#lasso-editor-settings--colors').slideDown(); } }); }); ================================================ FILE: admin/assets/less/style.less ================================================ @import '../../../public/assets/less/source/mixins.less'; @import 'welcome.less'; @main: #fff; @border: #cdcdcd; @desc-color: #888; @main-width: 500px; @admin-bar-width: 160px; .lasso--form-settings{ * { .box-sizing(border-box); } max-width:@main-width; padding:20px; background:@main; border-radius:5px; border:1px solid @border; position: relative; .clearfix(); .iris-picker { box-sizing: initial; * { box-sizing: inherit; } } .lasso-editor-settings--option-wrap { margin-bottom:25px; margin-left:15px; &.last .lasso-editor-settings--option-inner{ border-bottom: none; padding-bottom:0; } } .lasso-editor-settings--option-inner { border-bottom:1px solid lighten(@border,10); padding-bottom:25px; } label { font-weight:bold; font-size:110%; display:block; } textarea, input[type="text"] { border-radius:3px; width:240px; background-color: #f8f8f8; color: #000; .box-shadow(inset 1px 1px 1px rgba(0,0,0,0.1)); } input[type="checkbox"] { float: left; & ~ label { float: left; position: relative; top:-4px; left:4px; } } input[type="submit"]{ &:active { outline:none; } &:disabled { .opacity(0.4); } } .lasso--setting-description { display:block; margin:5px 0 10px; max-width:400px; color:@desc-color; line-height: 1.3; clear:left; } // sunmit .lasso-editor-settings--submit { position: fixed; top:88px; left: @main-width + @admin-bar-width + 100; } .lasso-editor-settings--confirm { background: @main; border:1px solid @border; border-radius:3px; padding:10px 20px 14px 12px; margin-top:10px; .transition(all .2s linear); &.success:before, &.error:before { font-family: 'Dashicons'; speak: none; font-size:18px; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; position: relative; top:4px; right:3px; } &.success:before { content:'\f147'; color:#5CB85C; } &.error:before { content: '\f158'; color:#d9534f; } } } #wpbody #lasso-editor-settings-form .button-primary.saved { background: #5CB85C !important; } ================================================ FILE: admin/assets/less/welcome.less ================================================ .lasso--welcome { * { .box-sizing(border-box); } max-width:600px; margin:20px auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; @bg: white; @accent: darken(@bg,5); @border: darken(@bg, 15); @link: #007aab; @success: #4DA34D; @error: #d9534f; @info: lighten(@link,25); p { font-size:15px; } // initial welcome steps .lasso--welcome__steps { padding:0; list-style-type:none; margin:0 auto; li { padding:25px; background: @bg; border:1px solid @border; border-radius:5px; text-align: center; position: relative; margin-top:-25px; margin-bottom: 100px; &:before { font-family: Dashicons; color:white; padding: 14px 27px 15px 14px; width: 22px; font-size: 36px; border-radius: 100%; text-align: center; position: absolute; top: -33px; left: 0; right: 0; margin: 0 auto; height: 34px; line-height: 37px; } &.info:before { content: '\f348'; background: @info; } &.success:before { content: '\f147'; background: @success; } &.error:before { content: '\f227'; background:@error; } p{ margin-bottom: 0; } h3 { margin-bottom: 5px; } } } .lasso--welcome__top{ .clearfix(); text-align: center; img { max-width:150px; margin:0 auto; border-radius:3px; } h1 + p { font-style: italic; } margin-bottom:100px; } // social .lasso--welcome__social { list-style: none; margin:0; padding:7px 0; .clearfix(); border-top:1px solid @border; border-bottom:1px solid @border; li { display: inline-block; line-height: 1; margin:0; } a { padding:2px 6px; display: block; text-decoration: none; color:inherit; line-height: 1.5; font-weight: bold; &:hover { color:@link; text-decoration: none; } i { font-size:16px; top:2px; line-height: 19px; color:@link; } } } } ================================================ FILE: admin/includes/EDD_SL_Plugin_Updater.php ================================================ api_url = trailingslashit( $_api_url ); $this->api_data = $_api_data; $this->name = plugin_basename( $_plugin_file ); $this->slug = basename( $_plugin_file, '.php' ); $this->version = $_api_data['version']; // Set up hooks. $this->init(); add_action( 'admin_init', array( $this, 'show_changelog' ) ); } /** * Set up WordPress filters to hook into WP's update process. * * @uses add_filter() * * @return void */ public function init() { add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) ); add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 ); add_action( 'after_plugin_row_' . $this->name, array( $this, 'show_update_notification' ), 10, 2 ); } /** * Check for Updates at the defined API endpoint and modify the update array. * * This function dives into the update API just when WordPress creates its update array, * then adds a custom API call and injects the custom plugin data retrieved from the API. * It is reassembled from parts of the native WordPress plugin update code. * See wp-includes/update.php line 121 for the original wp_update_plugins() function. * * @uses api_request() * * @param array $_transient_data Update array build by WordPress. * @return array Modified update array with custom plugin data. */ function check_update( $_transient_data ) { global $pagenow; if ( ! is_object( $_transient_data ) ) { $_transient_data = new stdClass; } if ( 'plugins.php' == $pagenow && is_multisite() ) { return $_transient_data; } if ( empty( $_transient_data->response ) || empty( $_transient_data->response[ $this->name ] ) ) { $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) ); if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) { $this->did_check = true; if ( version_compare( $this->version, $version_info->new_version, '<' ) ) { $_transient_data->response[ $this->name ] = $version_info; } $_transient_data->last_checked = time(); $_transient_data->checked[ $this->name ] = $this->version; } } return $_transient_data; } /** * show update nofication row -- needed for multisite subsites, because WP won't tell you otherwise! * * @param string $file * @param array $plugin */ public function show_update_notification( $file, $plugin ) { if ( ! current_user_can( 'update_plugins' ) ) { return; } if ( ! is_multisite() ) { return; } if ( $this->name != $file ) { return; } // Remove our filter on the site transient remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 10 ); $update_cache = get_site_transient( 'update_plugins' ); if ( ! is_object( $update_cache ) || empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) { $cache_key = md5( 'edd_plugin_' .sanitize_key( $this->name ) . '_version_info' ); $version_info = get_transient( $cache_key ); if ( false === $version_info ) { $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) ); set_transient( $cache_key, $version_info, 3600 ); } if ( ! is_object( $version_info ) ) { return; } if ( version_compare( $this->version, $version_info->new_version, '<' ) ) { $update_cache->response[ $this->name ] = $version_info; } $update_cache->last_checked = time(); $update_cache->checked[ $this->name ] = $this->version; set_site_transient( 'update_plugins', $update_cache ); } else { $version_info = $update_cache->response[ $this->name ]; } // Restore our filter add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) ); if ( ! empty( $update_cache->response[ $this->name ] ) && version_compare( $this->version, $version_info->new_version, '<' ) ) { // build a plugin list row, with update notification $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' ); echo '
'; $changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' ); if ( empty( $version_info->download_link ) ) { printf( __( 'There is a new version of %1$s available. View version %3$s details.', 'lasso' ), esc_html( $version_info->name ), esc_url( $changelog_link ), esc_html( $version_info->new_version ) ); } else { printf( __( 'There is a new version of %1$s available. View version %3$s details or update now.', 'lasso' ), esc_html( $version_info->name ), esc_url( $changelog_link ), esc_html( $version_info->new_version ), esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) ) ); } echo '
'; } } /** * Updates information on the "View version x.x details" page with custom data. * * @uses api_request() * * @param mixed $_data * @param string $_action * @param object $_args * @return object $_data */ function plugins_api_filter( $_data, $_action = '', $_args = null ) { if ( $_action != 'plugin_information' ) { return $_data; } if ( ! isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) { return $_data; } $to_send = array( 'slug' => $this->slug, 'is_ssl' => is_ssl(), 'fields' => array( 'banners' => false, // These will be supported soon hopefully 'reviews' => false ) ); $api_response = $this->api_request( 'plugin_information', $to_send ); if ( false !== $api_response ) { $_data = $api_response; } return $_data; } /** * Disable SSL verification in order to prevent download update failures * * @param array $args * @param string $url * @return object $array */ function http_request_args( $args, $url ) { // If it is an https request and we are performing a package download, disable ssl verification if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) { $args['sslverify'] = false; } return $args; } /** * Calls the API and, if successfull, returns the object delivered by the API. * * @uses get_bloginfo() * @uses wp_remote_post() * @uses is_wp_error() * * @param string $_action The requested action. * @param array $_data Parameters for the API action. * @return false||object */ private function api_request( $_action, $_data ) { global $wp_version; $data = array_merge( $this->api_data, $_data ); if ( $data['slug'] != $this->slug ) return; if ( empty( $data['license'] ) ) return; if ( $this->api_url == home_url() ) { return false; // Don't allow a plugin to ping itself } $api_params = array( 'edd_action' => 'get_version', 'license' => $data['license'], 'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false, 'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false, 'slug' => $data['slug'], 'author' => $data['author'], 'url' => home_url() ); $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) ); if ( ! is_wp_error( $request ) ) { $request = json_decode( wp_remote_retrieve_body( $request ) ); } if ( $request && isset( $request->sections ) ) { $request->sections = maybe_unserialize( $request->sections ); } else { $request = false; } return $request; } public function show_changelog() { if ( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) { return; } if ( empty( $_REQUEST['plugin'] ) ) { return; } if ( empty( $_REQUEST['slug'] ) ) { return; } if ( ! current_user_can( 'update_plugins' ) ) { wp_die( __( 'You do not have permission to install plugin updates', 'lasso' ), __( 'Error', 'lasso' ), array( 'response' => 403 ) ); } $response = $this->api_request( 'plugin_latest_version', array( 'slug' => $_REQUEST['slug'] ) ); if ( $response && isset( $response->sections['changelog'] ) ) { echo '
' . $response->sections['changelog'] . '
'; } exit; } } ================================================ FILE: admin/includes/class-tgm-plugin-activation.php ================================================ wp_version = $GLOBALS['wp_version']; // Announce that the class is ready, and pass the object (for advanced use). do_action_ref_array( 'tgmpa_init', array( $this ) ); // When the rest of WP has loaded, kick-start the rest of the class. add_action( 'init', array( $this, 'init' ) ); } /** * Magic method to (not) set protected properties from outside of this class. * * @internal hackedihack... There is a serious bug in v2.3.2 - 2.3.6 where the `menu` property * is being assigned rather than tested in a conditional, effectively rendering it useless. * This 'hack' prevents this from happening. * * @see https://github.com/TGMPA/TGM-Plugin-Activation/blob/2.3.6/tgm-plugin-activation/class-tgm-plugin-activation.php#L1593 * * @param string $name Name of an inaccessible property. * @param mixed $value Value to assign to the property. * @return void Silently fail to set the property when this is tried from outside of this class context. * (Inside this class context, the __set() method if not used as there is direct access.) */ public function __set( $name, $value ) { return; } /** * Magic method to get the value of a protected property outside of this class context. * * @param string $name Name of an inaccessible property. * @return mixed The property value. */ public function __get( $name ) { return $this->{$name}; } /** * Initialise the interactions between this class and WordPress. * * Hooks in three new methods for the class: admin_menu, notices and styles. * * @since 2.0.0 * * @see TGM_Plugin_Activation::admin_menu() * @see TGM_Plugin_Activation::notices() * @see TGM_Plugin_Activation::styles() */ public function init() { /** * By default TGMPA only loads on the WP back-end and not in an Ajax call. Using this filter * you can overrule that behaviour. * * @since 2.5.0 * * @param bool $load Whether or not TGMPA should load. * Defaults to the return of `is_admin() && ! defined( 'DOING_AJAX' )`. */ if ( true !== apply_filters( 'tgmpa_load', ( is_admin() && ! defined( 'DOING_AJAX' ) ) ) ) { return; } // Load class strings. $this->strings = array( 'page_title' => __( 'Install Required Plugins', 'tgmpa' ), 'menu_title' => __( 'Install Plugins', 'tgmpa' ), 'installing' => __( 'Installing Plugin: %s', 'tgmpa' ), 'oops' => __( 'Something went wrong with the plugin API.', 'tgmpa' ), 'notice_can_install_required' => _n_noop( 'This theme requires the following plugin: %1$s.', 'This theme requires the following plugins: %1$s.', 'tgmpa' ), 'notice_can_install_recommended' => _n_noop( 'This theme recommends the following plugin: %1$s.', 'This theme recommends the following plugins: %1$s.', 'tgmpa' ), 'notice_cannot_install' => _n_noop( 'Sorry, but you do not have the correct permissions to install the %1$s plugin.', 'Sorry, but you do not have the correct permissions to install the %1$s plugins.', 'tgmpa' ), 'notice_ask_to_update' => _n_noop( 'The following plugin needs to be updated to its latest version to ensure maximum compatibility with this theme: %1$s.', 'The following plugins need to be updated to their latest version to ensure maximum compatibility with this theme: %1$s.', 'tgmpa' ), 'notice_ask_to_update_maybe' => _n_noop( 'There is an update available for: %1$s.', 'There are updates available for the following plugins: %1$s.', 'tgmpa' ), 'notice_cannot_update' => _n_noop( 'Sorry, but you do not have the correct permissions to update the %1$s plugin.', 'Sorry, but you do not have the correct permissions to update the %1$s plugins.', 'tgmpa' ), 'notice_can_activate_required' => _n_noop( 'The following required plugin is currently inactive: %1$s.', 'The following required plugins are currently inactive: %1$s.', 'tgmpa' ), 'notice_can_activate_recommended' => _n_noop( 'The following recommended plugin is currently inactive: %1$s.', 'The following recommended plugins are currently inactive: %1$s.', 'tgmpa' ), 'notice_cannot_activate' => _n_noop( 'Sorry, but you do not have the correct permissions to activate the %1$s plugin.', 'Sorry, but you do not have the correct permissions to activate the %1$s plugins.', 'tgmpa' ), 'install_link' => _n_noop( 'Begin installing plugin', 'Begin installing plugins', 'tgmpa' ), 'update_link' => _n_noop( 'Begin updating plugin', 'Begin updating plugins', 'tgmpa' ), 'activate_link' => _n_noop( 'Begin activating plugin', 'Begin activating plugins', 'tgmpa' ), 'return' => __( 'Return to Required Plugins Installer', 'tgmpa' ), 'dashboard' => __( 'Return to the dashboard', 'tgmpa' ), 'plugin_activated' => __( 'Plugin activated successfully.', 'tgmpa' ), 'activated_successfully' => __( 'The following plugin was activated successfully:', 'tgmpa' ), 'plugin_already_active' => __( 'No action taken. Plugin %1$s was already active.', 'tgmpa' ), 'plugin_needs_higher_version' => __( 'Plugin not activated. A higher version of %s is needed for this theme. Please update the plugin.', 'tgmpa' ), 'complete' => __( 'All plugins installed and activated successfully. %1$s', 'tgmpa' ), 'dismiss' => __( 'Dismiss this notice', 'tgmpa' ), 'contact_admin' => __( 'Please contact the administrator of this site for help.', 'tgmpa' ), ); do_action( 'tgmpa_register' ); /* After this point, the plugins should be registered and the configuration set. */ // Proceed only if we have plugins to handle. if ( empty( $this->plugins ) || ! is_array( $this->plugins ) ) { return; } // Set up the menu and notices if we still have outstanding actions. if ( true !== $this->is_tgmpa_complete() ) { // Sort the plugins. array_multisort( $this->sort_order, SORT_ASC, $this->plugins ); add_action( 'admin_menu', array( $this, 'admin_menu' ) ); add_action( 'admin_head', array( $this, 'dismiss' ) ); // Prevent the normal links from showing underneath a single install/update page. add_filter( 'install_plugin_complete_actions', array( $this, 'actions' ) ); add_filter( 'update_plugin_complete_actions', array( $this, 'actions' ) ); if ( $this->has_notices ) { add_action( 'admin_notices', array( $this, 'notices' ) ); add_action( 'admin_init', array( $this, 'admin_init' ), 1 ); add_action( 'admin_enqueue_scripts', array( $this, 'thickbox' ) ); } add_action( 'load-plugins.php', array( $this, 'add_plugin_action_link_filters' ), 1 ); } // Make sure things get reset on switch theme. add_action( 'switch_theme', array( $this, 'flush_plugins_cache' ) ); if ( $this->has_notices ) { add_action( 'switch_theme', array( $this, 'update_dismiss' ) ); } // Setup the force activation hook. if ( true === $this->has_forced_activation ) { add_action( 'admin_init', array( $this, 'force_activation' ) ); } // Setup the force deactivation hook. if ( true === $this->has_forced_deactivation ) { add_action( 'switch_theme', array( $this, 'force_deactivation' ) ); } } /** * Prevent activation of plugins which don't meet the minimum version requirement from the * WP native plugins page. * * @since 2.5.0 */ public function add_plugin_action_link_filters() { foreach ( $this->plugins as $slug => $plugin ) { if ( false === $this->can_plugin_activate( $slug ) ) { add_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_activate' ), 20 ); } if ( true === $plugin['force_activation'] ) { add_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_deactivate' ), 20 ); } if ( false !== $this->does_plugin_require_update( $slug ) ) { add_filter( 'plugin_action_links_' . $plugin['file_path'], array( $this, 'filter_plugin_action_links_update' ), 20 ); } } } /** * Remove the 'Activate' link on the WP native plugins page if the plugin does not meet the * minimum version requirements. * * @since 2.5.0 * * @param array $actions Action links. * @return array */ public function filter_plugin_action_links_activate( $actions ) { unset( $actions['activate'] ); return $actions; } /** * Remove the 'Deactivate' link on the WP native plugins page if the plugin has been set to force activate. * * @since 2.5.0 * * @param array $actions Action links. * @return array */ public function filter_plugin_action_links_deactivate( $actions ) { unset( $actions['deactivate'] ); return $actions; } /** * Add a 'Requires update' link on the WP native plugins page if the plugin does not meet the * minimum version requirements. * * @since 2.5.0 * * @param array $actions Action links. * @return array */ public function filter_plugin_action_links_update( $actions ) { $actions['update'] = sprintf( '%3$s', esc_url( $this->get_tgmpa_status_url( 'update' ) ), esc_attr__( 'This plugin needs to be updated to be compatible with your theme.', 'tgmpa' ), esc_html__( 'Update Required', 'tgmpa' ) ); return $actions; } /** * Handles calls to show plugin information via links in the notices. * * We get the links in the admin notices to point to the TGMPA page, rather * than the typical plugin-install.php file, so we can prepare everything * beforehand. * * WP does not make it easy to show the plugin information in the thickbox - * here we have to require a file that includes a function that does the * main work of displaying it, enqueue some styles, set up some globals and * finally call that function before exiting. * * Down right easy once you know how... * * Returns early if not the TGMPA page. * * @since 2.1.0 * * @global string $tab Used as iframe div class names, helps with styling * @global string $body_id Used as the iframe body ID, helps with styling * * @return null Returns early if not the TGMPA page. */ public function admin_init() { if ( ! $this->is_tgmpa_page() ) { return; } if ( isset( $_REQUEST['tab'] ) && 'plugin-information' === $_REQUEST['tab'] ) { // Needed for install_plugin_information(). require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; wp_enqueue_style( 'plugin-install' ); global $tab, $body_id; $body_id = 'plugin-information'; // @codingStandardsIgnoreStart $tab = 'plugin-information'; // @codingStandardsIgnoreEnd install_plugin_information(); exit; } } /** * Enqueue thickbox scripts/styles for plugin info. * * Thickbox is not automatically included on all admin pages, so we must * manually enqueue it for those pages. * * Thickbox is only loaded if the user has not dismissed the admin * notice or if there are any plugins left to install and activate. * * @since 2.1.0 */ public function thickbox() { if ( ! get_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, true ) ) { add_thickbox(); } } /** * Adds submenu page if there are plugin actions to take. * * This method adds the submenu page letting users know that a required * plugin needs to be installed. * * This page disappears once the plugin has been installed and activated. * * @since 1.0.0 * * @see TGM_Plugin_Activation::init() * @see TGM_Plugin_Activation::install_plugins_page() * * @return null Return early if user lacks capability to install a plugin. */ public function admin_menu() { // Make sure privileges are correct to see the page. if ( ! current_user_can( 'install_plugins' ) ) { return; } $args = apply_filters( 'tgmpa_admin_menu_args', array( 'parent_slug' => $this->parent_slug, // Parent Menu slug. 'page_title' => $this->strings['page_title'], // Page title. 'menu_title' => $this->strings['menu_title'], // Menu title. 'capability' => $this->capability, // Capability. 'menu_slug' => $this->menu, // Menu slug. 'function' => array( $this, 'install_plugins_page' ), // Callback. ) ); $this->add_admin_menu( $args ); } /** * Add the menu item. * * @since 2.5.0 * * @param array $args Menu item configuration. */ protected function add_admin_menu( array $args ) { if ( has_filter( 'tgmpa_admin_menu_use_add_theme_page' ) ) { _deprecated_function( 'The "tgmpa_admin_menu_use_add_theme_page" filter', '2.5.0', esc_html__( 'Set the parent_slug config variable instead.', 'tgmpa' ) ); } if ( 'themes.php' === $this->parent_slug ) { $this->page_hook = call_user_func( 'add_theme_page', $args['page_title'], $args['menu_title'], $args['capability'], $args['menu_slug'], $args['function'] ); } else { $this->page_hook = call_user_func( 'add_submenu_page', $args['parent_slug'], $args['page_title'], $args['menu_title'], $args['capability'], $args['menu_slug'], $args['function'] ); } } /** * Echoes plugin installation form. * * This method is the callback for the admin_menu method function. * This displays the admin page and form area where the user can select to install and activate the plugin. * Aborts early if we're processing a plugin installation action. * * @since 1.0.0 * * @return null Aborts early if we're processing a plugin installation action. */ public function install_plugins_page() { // Store new instance of plugin table in object. $plugin_table = new TGMPA_List_Table; // Return early if processing a plugin installation action. if ( ( ( 'tgmpa-bulk-install' === $plugin_table->current_action() || 'tgmpa-bulk-update' === $plugin_table->current_action() ) && $plugin_table->process_bulk_actions() ) || $this->do_plugin_install() ) { return; } // Force refresh of available plugin information so we'll know about manual updates/deletes. wp_clean_plugins_cache( false ); ?>

prepare_items(); ?> message ) && is_string( $this->message ) ) { echo wp_kses_post( $this->message ); } ?> views(); ?>
display(); ?>
sanitize_key( urldecode( $_GET['plugin'] ) ); if ( ! isset( $this->plugins[ $slug ] ) ) { return false; } // Was an install or upgrade action link clicked? if ( ( isset( $_GET['tgmpa-install'] ) && 'install-plugin' === $_GET['tgmpa-install'] ) || ( isset( $_GET['tgmpa-update'] ) && 'update-plugin' === $_GET['tgmpa-update'] ) ) { $install_type = 'install'; if ( isset( $_GET['tgmpa-update'] ) && 'update-plugin' === $_GET['tgmpa-update'] ) { $install_type = 'update'; } check_admin_referer( 'tgmpa-' . $install_type, 'tgmpa-nonce' ); // Pass necessary information via URL if WP_Filesystem is needed. $url = wp_nonce_url( add_query_arg( array( 'plugin' => urlencode( $slug ), 'tgmpa-' . $install_type => $install_type . '-plugin', ), $this->get_tgmpa_url() ), 'tgmpa-' . $install_type, 'tgmpa-nonce' ); $method = ''; // Leave blank so WP_Filesystem can populate it as necessary. if ( false === ( $creds = request_filesystem_credentials( esc_url_raw( $url ), $method, false, false, array() ) ) ) { return true; } if ( ! WP_Filesystem( $creds ) ) { request_filesystem_credentials( esc_url_raw( $url ), $method, true, false, array() ); // Setup WP_Filesystem. return true; } /* If we arrive here, we have the filesystem. */ // Prep variables for Plugin_Installer_Skin class. $extra = array(); $extra['slug'] = $slug; // Needed for potentially renaming of directory name. $source = $this->get_download_url( $slug ); $api = ( 'repo' === $this->plugins[ $slug ]['source_type'] ) ? $this->get_plugins_api( $slug ) : null; $api = ( false !== $api ) ? $api : null; $url = add_query_arg( array( 'action' => $install_type . '-plugin', 'plugin' => urlencode( $slug ), ), 'update.php' ); if ( ! class_exists( 'Plugin_Upgrader', false ) ) { require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; } $skin_args = array( 'type' => ( 'bundled' !== $this->plugins[ $slug ]['source_type'] ) ? 'web' : 'upload', 'title' => sprintf( $this->strings['installing'], $this->plugins[ $slug ]['name'] ), 'url' => esc_url_raw( $url ), 'nonce' => $install_type . '-plugin_' . $slug, 'plugin' => '', 'api' => $api, 'extra' => $extra, ); if ( 'update' === $install_type ) { $skin_args['plugin'] = $this->plugins[ $slug ]['file_path']; $skin = new Plugin_Upgrader_Skin( $skin_args ); } else { $skin = new Plugin_Installer_Skin( $skin_args ); } // Create a new instance of Plugin_Upgrader. $upgrader = new Plugin_Upgrader( $skin ); // Perform the action and install the plugin from the $source urldecode(). add_filter( 'upgrader_source_selection', array( $this, 'maybe_adjust_source_dir' ), 1, 3 ); if ( 'update' === $install_type ) { // Inject our info into the update transient. $to_inject = array( $slug => $this->plugins[ $slug ] ); $to_inject[ $slug ]['source'] = $source; $this->inject_update_info( $to_inject ); $upgrader->upgrade( $this->plugins[ $slug ]['file_path'] ); } else { $upgrader->install( $source ); } remove_filter( 'upgrader_source_selection', array( $this, 'maybe_adjust_source_dir' ), 1, 3 ); // Make sure we have the correct file path now the plugin is installed/updated. $this->populate_file_path( $slug ); // Only activate plugins if the config option is set to true and the plugin isn't // already active (upgrade). if ( $this->is_automatic && ! $this->is_plugin_active( $slug ) ) { $plugin_activate = $upgrader->plugin_info(); // Grab the plugin info from the Plugin_Upgrader method. if ( false === $this->activate_single_plugin( $plugin_activate, $slug, true ) ) { return true; // Finish execution of the function early as we encountered an error. } } $this->show_tgmpa_version(); // Display message based on if all plugins are now active or not. if ( $this->is_tgmpa_complete() ) { echo '

', sprintf( esc_html( $this->strings['complete'] ), '' . esc_html__( 'Return to the Dashboard', 'tgmpa' ) . '' ), '

'; echo ''; } else { echo '

', esc_html( $this->strings['return'] ), '

'; } return true; } elseif ( isset( $this->plugins[ $slug ]['file_path'], $_GET['tgmpa-activate'] ) && 'activate-plugin' === $_GET['tgmpa-activate'] ) { // Activate action link was clicked. check_admin_referer( 'tgmpa-activate', 'tgmpa-nonce' ); if ( false === $this->activate_single_plugin( $this->plugins[ $slug ]['file_path'], $slug ) ) { return true; // Finish execution of the function early as we encountered an error. } } return false; } /** * Inject information into the 'update_plugins' site transient as WP checks that before running an update. * * @since 2.5.0 * * @param array $plugins The plugin information for the plugins which are to be updated. */ public function inject_update_info( $plugins ) { $repo_updates = get_site_transient( 'update_plugins' ); if ( ! is_object( $repo_updates ) ) { $repo_updates = new stdClass; } foreach ( $plugins as $slug => $plugin ) { $file_path = $plugin['file_path']; if ( empty( $repo_updates->response[ $file_path ] ) ) { $repo_updates->response[ $file_path ] = new stdClass; } // We only really need to set package, but let's do all we can in case WP changes something. $repo_updates->response[ $file_path ]->slug = $slug; $repo_updates->response[ $file_path ]->plugin = $file_path; $repo_updates->response[ $file_path ]->new_version = $plugin['version']; $repo_updates->response[ $file_path ]->package = $plugin['source']; if ( empty( $repo_updates->response[ $file_path ]->url ) && ! empty( $plugin['external_url'] ) ) { $repo_updates->response[ $file_path ]->url = $plugin['external_url']; } } set_site_transient( 'update_plugins', $repo_updates ); } /** * Adjust the plugin directory name if necessary. * * The final destination directory of a plugin is based on the subdirectory name found in the * (un)zipped source. In some cases - most notably GitHub repository plugin downloads -, this * subdirectory name is not the same as the expected slug and the plugin will not be recognized * as installed. This is fixed by adjusting the temporary unzipped source subdirectory name to * the expected plugin slug. * * @since 2.5.0 * * @param string $source Path to upgrade/zip-file-name.tmp/subdirectory/. * @param string $remote_source Path to upgrade/zip-file-name.tmp. * @param \WP_Upgrader $upgrader Instance of the upgrader which installs the plugin. * @return string $source */ public function maybe_adjust_source_dir( $source, $remote_source, $upgrader ) { if ( ! $this->is_tgmpa_page() || ! is_object( $GLOBALS['wp_filesystem'] ) ) { return $source; } // Check for single file plugins. $source_files = array_keys( $GLOBALS['wp_filesystem']->dirlist( $remote_source ) ); if ( 1 === count( $source_files ) && false === $GLOBALS['wp_filesystem']->is_dir( $source ) ) { return $source; } // Multi-file plugin, let's see if the directory is correctly named. $desired_slug = ''; // Figure out what the slug is supposed to be. if ( false === $upgrader->bulk && ! empty( $upgrader->skin->options['extra']['slug'] ) ) { $desired_slug = $upgrader->skin->options['extra']['slug']; } else { // Bulk installer contains less info, so fall back on the info registered here. foreach ( $this->plugins as $slug => $plugin ) { if ( ! empty( $upgrader->skin->plugin_names[ $upgrader->skin->i ] ) && $plugin['name'] === $upgrader->skin->plugin_names[ $upgrader->skin->i ] ) { $desired_slug = $slug; break; } } unset( $slug, $plugin ); } if ( ! empty( $desired_slug ) ) { $subdir_name = untrailingslashit( str_replace( trailingslashit( $remote_source ), '', $source ) ); if ( ! empty( $subdir_name ) && $subdir_name !== $desired_slug ) { $from = untrailingslashit( $source ); $to = trailingslashit( $remote_source ) . $desired_slug; if ( true === $GLOBALS['wp_filesystem']->move( $from, $to ) ) { return trailingslashit( $to ); } else { return new WP_Error( 'rename_failed', esc_html__( 'The remote plugin package does not contain a folder with the desired slug and renaming did not work.', 'tgmpa' ) . ' ' . esc_html__( 'Please contact the plugin provider and ask them to package their plugin according to the WordPress guidelines.', 'tgmpa' ), array( 'found' => $subdir_name, 'expected' => $desired_slug ) ); } } elseif ( empty( $subdir_name ) ) { return new WP_Error( 'packaged_wrong', esc_html__( 'The remote plugin package consists of more than one file, but the files are not packaged in a folder.', 'tgmpa' ) . ' ' . esc_html__( 'Please contact the plugin provider and ask them to package their plugin according to the WordPress guidelines.', 'tgmpa' ), array( 'found' => $subdir_name, 'expected' => $desired_slug ) ); } } return $source; } /** * Activate a single plugin and send feedback about the result to the screen. * * @since 2.5.0 * * @param string $file_path Path within wp-plugins/ to main plugin file. * @param string $slug Plugin slug. * @param bool $automatic Whether this is an automatic activation after an install. Defaults to false. * This determines the styling of the output messages. * @return bool False if an error was encountered, true otherwise. */ protected function activate_single_plugin( $file_path, $slug, $automatic = false ) { if ( $this->can_plugin_activate( $slug ) ) { $activate = activate_plugin( $file_path ); if ( is_wp_error( $activate ) ) { echo '

', wp_kses_post( $activate->get_error_message() ), '

', '

', esc_html( $this->strings['return'] ), '

'; return false; // End it here if there is an error with activation. } else { if ( ! $automatic ) { // Make sure message doesn't display again if bulk activation is performed // immediately after a single activation. if ( ! isset( $_POST['action'] ) ) { // WPCS: CSRF OK. echo '

', esc_html( $this->strings['activated_successfully'] ), ' ', esc_html( $this->plugins[ $slug ]['name'] ), '.

'; } } else { // Simpler message layout for use on the plugin install page. echo '

', esc_html( $this->strings['plugin_activated'] ), '

'; } } } elseif ( $this->is_plugin_active( $slug ) ) { // No simpler message format provided as this message should never be encountered // on the plugin install page. echo '

', sprintf( esc_html( $this->strings['plugin_already_active'] ), '' . esc_html( $this->plugins[ $slug ]['name'] ) . '' ), '

'; } elseif ( $this->does_plugin_require_update( $slug ) ) { if ( ! $automatic ) { // Make sure message doesn't display again if bulk activation is performed // immediately after a single activation. if ( ! isset( $_POST['action'] ) ) { // WPCS: CSRF OK. echo '

', sprintf( esc_html( $this->strings['plugin_needs_higher_version'] ), '' . esc_html( $this->plugins[ $slug ]['name'] ) . '' ), '

'; } } else { // Simpler message layout for use on the plugin install page. echo '

', sprintf( esc_html( $this->strings['plugin_needs_higher_version'] ), esc_html( $this->plugins[ $slug ]['name'] ) ), '

'; } } return true; } /** * Echoes required plugin notice. * * Outputs a message telling users that a specific plugin is required for * their theme. If appropriate, it includes a link to the form page where * users can install and activate the plugin. * * Returns early if we're on the Install page. * * @since 1.0.0 * * @global object $current_screen * * @return null Returns early if we're on the Install page. */ public function notices() { // Remove nag on the install page / Return early if the nag message has been dismissed. if ( $this->is_tgmpa_page() || get_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, true ) ) { return; } // Store for the plugin slugs by message type. $message = array(); // Initialize counters used to determine plurality of action link texts. $install_link_count = 0; $update_link_count = 0; $activate_link_count = 0; foreach ( $this->plugins as $slug => $plugin ) { if ( $this->is_plugin_active( $slug ) && false === $this->does_plugin_have_update( $slug ) ) { continue; } if ( ! $this->is_plugin_installed( $slug ) ) { if ( current_user_can( 'install_plugins' ) ) { $install_link_count++; if ( true === $plugin['required'] ) { $message['notice_can_install_required'][] = $slug; } else { $message['notice_can_install_recommended'][] = $slug; } } else { // Need higher privileges to install the plugin. $message['notice_cannot_install'][] = $slug; } } else { if ( ! $this->is_plugin_active( $slug ) && $this->can_plugin_activate( $slug ) ) { if ( current_user_can( 'activate_plugins' ) ) { $activate_link_count++; if ( true === $plugin['required'] ) { $message['notice_can_activate_required'][] = $slug; } else { $message['notice_can_activate_recommended'][] = $slug; } } else { // Need higher privileges to activate the plugin. $message['notice_cannot_activate'][] = $slug; } } if ( $this->does_plugin_require_update( $slug ) || false !== $this->does_plugin_have_update( $slug ) ) { if ( current_user_can( 'install_plugins' ) ) { $update_link_count++; if ( $this->does_plugin_require_update( $slug ) ) { $message['notice_ask_to_update'][] = $slug; } elseif ( false !== $this->does_plugin_have_update( $slug ) ) { $message['notice_ask_to_update_maybe'][] = $slug; } } else { // Need higher privileges to update the plugin. $message['notice_cannot_update'][] = $slug; } } } } unset( $slug, $plugin ); // If we have notices to display, we move forward. if ( ! empty( $message ) ) { krsort( $message ); // Sort messages. $rendered = ''; // As add_settings_error() wraps the final message in a

and as the final message can't be // filtered, using

's in our html would render invalid html output. $line_template = '%s' . "\n"; // If dismissable is false and a message is set, output it now. if ( ! $this->dismissable && ! empty( $this->dismiss_msg ) ) { $rendered .= sprintf( $line_template, wp_kses_post( $this->dismiss_msg ) ); } // Render the individual message lines for the notice. foreach ( $message as $type => $plugin_group ) { $linked_plugins = array(); // Get the external info link for a plugin if one is available. foreach ( $plugin_group as $plugin_slug ) { $linked_plugins[] = $this->get_info_link( $plugin_slug ); } unset( $plugin_slug ); $count = count( $plugin_group ); $linked_plugins = array_map( array( 'TGMPA_Utils', 'wrap_in_em' ), $linked_plugins ); $last_plugin = array_pop( $linked_plugins ); // Pop off last name to prep for readability. $imploded = empty( $linked_plugins ) ? $last_plugin : ( implode( ', ', $linked_plugins ) . ' ' . esc_html_x( 'and', 'plugin A *and* plugin B', 'tgmpa' ) . ' ' . $last_plugin ); $rendered .= sprintf( $line_template, sprintf( translate_nooped_plural( $this->strings[ $type ], $count, 'tgmpa' ), $imploded, $count ) ); if ( 0 === strpos( $type, 'notice_cannot' ) ) { $rendered .= $this->strings['contact_admin']; } } unset( $type, $plugin_group, $linked_plugins, $count, $last_plugin, $imploded ); // Setup action links. $action_links = array( 'install' => '', 'update' => '', 'activate' => '', 'dismiss' => $this->dismissable ? '' . esc_html( $this->strings['dismiss'] ) . '' : '', ); $link_template = '%1$s'; if ( current_user_can( 'install_plugins' ) ) { if ( $install_link_count > 0 ) { $action_links['install'] = sprintf( $link_template, translate_nooped_plural( $this->strings['install_link'], $install_link_count, 'tgmpa' ), esc_url( $this->get_tgmpa_status_url( 'install' ) ) ); } if ( $update_link_count > 0 ) { $action_links['update'] = sprintf( $link_template, translate_nooped_plural( $this->strings['update_link'], $update_link_count, 'tgmpa' ), esc_url( $this->get_tgmpa_status_url( 'update' ) ) ); } } if ( current_user_can( 'activate_plugins' ) && $activate_link_count > 0 ) { $action_links['activate'] = sprintf( $link_template, translate_nooped_plural( $this->strings['activate_link'], $activate_link_count, 'tgmpa' ), esc_url( $this->get_tgmpa_status_url( 'activate' ) ) ); } $action_links = apply_filters( 'tgmpa_notice_action_links', $action_links ); $action_links = array_filter( (array) $action_links ); // Remove any empty array items. if ( ! empty( $action_links ) && is_array( $action_links ) ) { $action_links = sprintf( $line_template, implode( ' | ', $action_links ) ); $rendered .= apply_filters( 'tgmpa_notice_rendered_action_links', $action_links ); } // Register the nag messages and prepare them to be processed. if ( ! empty( $this->strings['nag_type'] ) ) { add_settings_error( 'tgmpa', 'tgmpa', $rendered, sanitize_html_class( strtolower( $this->strings['nag_type'] ) ) ); } else { $nag_class = version_compare( $this->wp_version, '3.8', '<' ) ? 'updated' : 'update-nag'; add_settings_error( 'tgmpa', 'tgmpa', $rendered, $nag_class ); } } // Admin options pages already output settings_errors, so this is to avoid duplication. if ( 'options-general' !== $GLOBALS['current_screen']->parent_base ) { $this->display_settings_errors(); } } /** * Display settings errors and remove those which have been displayed to avoid duplicate messages showing * * @since 2.5.0 */ protected function display_settings_errors() { global $wp_settings_errors; settings_errors( 'tgmpa' ); foreach ( (array) $wp_settings_errors as $key => $details ) { if ( 'tgmpa' === $details['setting'] ) { unset( $wp_settings_errors[ $key ] ); break; } } } /** * Add dismissable admin notices. * * Appends a link to the admin nag messages. If clicked, the admin notice disappears and no longer is visible to users. * * @since 2.1.0 */ public function dismiss() { if ( isset( $_GET['tgmpa-dismiss'] ) ) { update_user_meta( get_current_user_id(), 'tgmpa_dismissed_notice_' . $this->id, 1 ); } } /** * Add individual plugin to our collection of plugins. * * If the required keys are not set or the plugin has already * been registered, the plugin is not added. * * @since 2.0.0 * * @param array|null $plugin Array of plugin arguments or null if invalid argument. * @return null Return early if incorrect argument. */ public function register( $plugin ) { if ( empty( $plugin['slug'] ) || empty( $plugin['name'] ) ) { return; } if ( empty( $plugin['slug'] ) || ! is_string( $plugin['slug'] ) || isset( $this->plugins[ $plugin['slug'] ] ) ) { return; } $defaults = array( 'name' => '', // String 'slug' => '', // String 'source' => 'repo', // String 'required' => false, // Boolean 'version' => '', // String 'force_activation' => false, // Boolean 'force_deactivation' => false, // Boolean 'external_url' => '', // String 'is_callable' => '', // String|Array. ); // Prepare the received data. $plugin = wp_parse_args( $plugin, $defaults ); // Standardize the received slug. $plugin['slug'] = $this->sanitize_key( $plugin['slug'] ); // Forgive users for using string versions of booleans or floats for version number. $plugin['version'] = (string) $plugin['version']; $plugin['source'] = empty( $plugin['source'] ) ? 'repo' : $plugin['source']; $plugin['required'] = TGMPA_Utils::validate_bool( $plugin['required'] ); $plugin['force_activation'] = TGMPA_Utils::validate_bool( $plugin['force_activation'] ); $plugin['force_deactivation'] = TGMPA_Utils::validate_bool( $plugin['force_deactivation'] ); // Enrich the received data. $plugin['file_path'] = $this->_get_plugin_basename_from_slug( $plugin['slug'] ); $plugin['source_type'] = $this->get_plugin_source_type( $plugin['source'] ); // Set the class properties. $this->plugins[ $plugin['slug'] ] = $plugin; $this->sort_order[ $plugin['slug'] ] = $plugin['name']; // Should we add the force activation hook ? if ( true === $plugin['force_activation'] ) { $this->has_forced_activation = true; } // Should we add the force deactivation hook ? if ( true === $plugin['force_deactivation'] ) { $this->has_forced_deactivation = true; } } /** * Determine what type of source the plugin comes from. * * @since 2.5.0 * * @param string $source The source of the plugin as provided, either empty (= WP repo), a file path * (= bundled) or an external URL. * @return string 'repo', 'external', or 'bundled' */ protected function get_plugin_source_type( $source ) { if ( 'repo' === $source || preg_match( self::WP_REPO_REGEX, $source ) ) { return 'repo'; } elseif ( preg_match( self::IS_URL_REGEX, $source ) ) { return 'external'; } else { return 'bundled'; } } /** * Sanitizes a string key. * * Near duplicate of WP Core `sanitize_key()`. The difference is that uppercase characters *are* * allowed, so as not to break upgrade paths from non-standard bundled plugins using uppercase * characters in the plugin directory path/slug. Silly them. * * @see https://developer.wordpress.org/reference/hooks/sanitize_key/ * * @since 2.5.0 * * @param string $key String key. * @return string Sanitized key */ public function sanitize_key( $key ) { $raw_key = $key; $key = preg_replace( '`[^A-Za-z0-9_-]`', '', $key ); /** * Filter a sanitized key string. * * @since 3.0.0 * * @param string $key Sanitized key. * @param string $raw_key The key prior to sanitization. */ return apply_filters( 'tgmpa_sanitize_key', $key, $raw_key ); } /** * Amend default configuration settings. * * @since 2.0.0 * * @param array $config Array of config options to pass as class properties. */ public function config( $config ) { $keys = array( 'id', 'default_path', 'has_notices', 'dismissable', 'dismiss_msg', 'menu', 'parent_slug', 'capability', 'is_automatic', 'message', 'strings', ); foreach ( $keys as $key ) { if ( isset( $config[ $key ] ) ) { if ( is_array( $config[ $key ] ) ) { $this->$key = array_merge( $this->$key, $config[ $key ] ); } else { $this->$key = $config[ $key ]; } } } } /** * Amend action link after plugin installation. * * @since 2.0.0 * * @param array $install_actions Existing array of actions. * @return array Amended array of actions. */ public function actions( $install_actions ) { // Remove action links on the TGMPA install page. if ( $this->is_tgmpa_page() ) { return false; } return $install_actions; } /** * Flushes the plugins cache on theme switch to prevent stale entries * from remaining in the plugin table. * * @since 2.4.0 * * @param bool $clear_update_cache Optional. Whether to clear the Plugin updates cache. * Parameter added in v2.5.0. */ public function flush_plugins_cache( $clear_update_cache = true ) { wp_clean_plugins_cache( $clear_update_cache ); } /** * Set file_path key for each installed plugin. * * @since 2.1.0 * * @param string $plugin_slug Optional. If set, only (re-)populates the file path for that specific plugin. * Parameter added in v2.5.0. */ public function populate_file_path( $plugin_slug = '' ) { if ( ! empty( $plugin_slug ) && is_string( $plugin_slug ) && isset( $this->plugins[ $plugin_slug ] ) ) { $this->plugins[ $plugin_slug ]['file_path'] = $this->_get_plugin_basename_from_slug( $plugin_slug ); } else { // Add file_path key for all plugins. foreach ( $this->plugins as $slug => $values ) { $this->plugins[ $slug ]['file_path'] = $this->_get_plugin_basename_from_slug( $slug ); } } } /** * Helper function to extract the file path of the plugin file from the * plugin slug, if the plugin is installed. * * @since 2.0.0 * * @param string $slug Plugin slug (typically folder name) as provided by the developer. * @return string Either file path for plugin if installed, or just the plugin slug. */ protected function _get_plugin_basename_from_slug( $slug ) { $keys = array_keys( $this->get_plugins() ); foreach ( $keys as $key ) { if ( preg_match( '|^' . $slug . '/|', $key ) ) { return $key; } } return $slug; } /** * Retrieve plugin data, given the plugin name. * * Loops through the registered plugins looking for $name. If it finds it, * it returns the $data from that plugin. Otherwise, returns false. * * @since 2.1.0 * * @param string $name Name of the plugin, as it was registered. * @param string $data Optional. Array key of plugin data to return. Default is slug. * @return string|boolean Plugin slug if found, false otherwise. */ public function _get_plugin_data_from_name( $name, $data = 'slug' ) { foreach ( $this->plugins as $values ) { if ( $name === $values['name'] && isset( $values[ $data ] ) ) { return $values[ $data ]; } } return false; } /** * Retrieve the download URL for a package. * * @since 2.5.0 * * @param string $slug Plugin slug. * @return string Plugin download URL or path to local file or empty string if undetermined. */ public function get_download_url( $slug ) { $dl_source = ''; switch ( $this->plugins[ $slug ]['source_type'] ) { case 'repo': return $this->get_wp_repo_download_url( $slug ); case 'external': return $this->plugins[ $slug ]['source']; case 'bundled': return $this->default_path . $this->plugins[ $slug ]['source']; } return $dl_source; // Should never happen. } /** * Retrieve the download URL for a WP repo package. * * @since 2.5.0 * * @param string $slug Plugin slug. * @return string Plugin download URL. */ protected function get_wp_repo_download_url( $slug ) { $source = ''; $api = $this->get_plugins_api( $slug ); if ( false !== $api && isset( $api->download_link ) ) { $source = $api->download_link; } return $source; } /** * Try to grab information from WordPress API. * * @since 2.5.0 * * @param string $slug Plugin slug. * @return object Plugins_api response object on success, WP_Error on failure. */ protected function get_plugins_api( $slug ) { static $api = array(); // Cache received responses. if ( ! isset( $api[ $slug ] ) ) { if ( ! function_exists( 'plugins_api' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; } $response = plugins_api( 'plugin_information', array( 'slug' => $slug, 'fields' => array( 'sections' => false ) ) ); $api[ $slug ] = false; if ( is_wp_error( $response ) ) { wp_die( esc_html( $this->strings['oops'] ) ); } else { $api[ $slug ] = $response; } } return $api[ $slug ]; } /** * Retrieve a link to a plugin information page. * * @since 2.5.0 * * @param string $slug Plugin slug. * @return string Fully formed html link to a plugin information page if available * or the plugin name if not. */ public function get_info_link( $slug ) { if ( ! empty( $this->plugins[ $slug ]['external_url'] ) && preg_match( self::IS_URL_REGEX, $this->plugins[ $slug ]['external_url'] ) ) { $link = sprintf( '%2$s', esc_url( $this->plugins[ $slug ]['external_url'] ), esc_html( $this->plugins[ $slug ]['name'] ) ); } elseif ( 'repo' === $this->plugins[ $slug ]['source_type'] ) { $url = add_query_arg( array( 'tab' => 'plugin-information', 'plugin' => urlencode( $slug ), 'TB_iframe' => 'true', 'width' => '640', 'height' => '500', ), self_admin_url( 'plugin-install.php' ) ); $link = sprintf( '%2$s', esc_url( $url ), esc_html( $this->plugins[ $slug ]['name'] ) ); } else { $link = esc_html( $this->plugins[ $slug ]['name'] ); // No hyperlink. } return $link; } /** * Determine if we're on the TGMPA Install page. * * @since 2.1.0 * * @return boolean True when on the TGMPA page, false otherwise. */ protected function is_tgmpa_page() { return isset( $_GET['page'] ) && $this->menu === $_GET['page']; } /** * Retrieve the URL to the TGMPA Install page. * * I.e. depending on the config settings passed something along the lines of: * http://example.com/wp-admin/themes.php?page=tgmpa-install-plugins * * @since 2.5.0 * * @return string Properly encoded URL (not escaped). */ public function get_tgmpa_url() { static $url; if ( ! isset( $url ) ) { $parent = $this->parent_slug; if ( false === strpos( $parent, '.php' ) ) { $parent = 'admin.php'; } $url = add_query_arg( array( 'page' => urlencode( $this->menu ), ), self_admin_url( $parent ) ); } return $url; } /** * Retrieve the URL to the TGMPA Install page for a specific plugin status (view). * * I.e. depending on the config settings passed something along the lines of: * http://example.com/wp-admin/themes.php?page=tgmpa-install-plugins&plugin_status=install * * @since 2.5.0 * * @param string $status Plugin status - either 'install', 'update' or 'activate'. * @return string Properly encoded URL (not escaped). */ public function get_tgmpa_status_url( $status ) { return add_query_arg( array( 'plugin_status' => urlencode( $status ), ), $this->get_tgmpa_url() ); } /** * Determine whether there are open actions for plugins registered with TGMPA. * * @since 2.5.0 * * @return bool True if complete, i.e. no outstanding actions. False otherwise. */ public function is_tgmpa_complete() { $complete = true; foreach ( $this->plugins as $slug => $plugin ) { if ( ! $this->is_plugin_active( $slug ) || false !== $this->does_plugin_have_update( $slug ) ) { $complete = false; break; } } return $complete; } /** * Check if a plugin is installed. Does not take must-use plugins into account. * * @since 2.5.0 * * @param string $slug Plugin slug. * @return bool True if installed, false otherwise. */ public function is_plugin_installed( $slug ) { $installed_plugins = $this->get_plugins(); // Retrieve a list of all installed plugins (WP cached). return ( ! empty( $installed_plugins[ $this->plugins[ $slug ]['file_path'] ] ) ); } /** * Check if a plugin is active. * * @since 2.5.0 * * @param string $slug Plugin slug. * @return bool True if active, false otherwise. */ public function is_plugin_active( $slug ) { return ( ( ! empty( $this->plugins[ $slug ]['is_callable'] ) && is_callable( $this->plugins[ $slug ]['is_callable'] ) ) || is_plugin_active( $this->plugins[ $slug ]['file_path'] ) ); } /** * Check if a plugin can be updated, i.e. if we have information on the minimum WP version required * available, check whether the current install meets them. * * @since 2.5.0 * * @param string $slug Plugin slug. * @return bool True if OK to update, false otherwise. */ public function can_plugin_update( $slug ) { // We currently can't get reliable info on non-WP-repo plugins - issue #380. if ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) { return true; } $api = $this->get_plugins_api( $slug ); if ( false !== $api && isset( $api->requires ) ) { return version_compare( $GLOBALS['wp_version'], $api->requires, '>=' ); } // No usable info received from the plugins API, presume we can update. return true; } /** * Check if a plugin can be activated, i.e. is not currently active and meets the minimum * plugin version requirements set in TGMPA (if any). * * @since 2.5.0 * * @param string $slug Plugin slug. * @return bool True if OK to activate, false otherwise. */ public function can_plugin_activate( $slug ) { return ( ! $this->is_plugin_active( $slug ) && ! $this->does_plugin_require_update( $slug ) ); } /** * Retrieve the version number of an installed plugin. * * @since 2.5.0 * * @param string $slug Plugin slug. * @return string Version number as string or an empty string if the plugin is not installed * or version unknown (plugins which don't comply with the plugin header standard). */ public function get_installed_version( $slug ) { $installed_plugins = $this->get_plugins(); // Retrieve a list of all installed plugins (WP cached). if ( ! empty( $installed_plugins[ $this->plugins[ $slug ]['file_path'] ]['Version'] ) ) { return $installed_plugins[ $this->plugins[ $slug ]['file_path'] ]['Version']; } return ''; } /** * Check whether a plugin complies with the minimum version requirements. * * @since 2.5.0 * * @param string $slug Plugin slug. * @return bool True when a plugin needs to be updated, otherwise false. */ public function does_plugin_require_update( $slug ) { $installed_version = $this->get_installed_version( $slug ); $minimum_version = $this->plugins[ $slug ]['version']; return version_compare( $minimum_version, $installed_version, '>' ); } /** * Check whether there is an update available for a plugin. * * @since 2.5.0 * * @param string $slug Plugin slug. * @return false|string Version number string of the available update or false if no update available. */ public function does_plugin_have_update( $slug ) { // Presume bundled and external plugins will point to a package which meets the minimum required version. if ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) { if ( $this->does_plugin_require_update( $slug ) ) { return $this->plugins[ $slug ]['version']; } return false; } $repo_updates = get_site_transient( 'update_plugins' ); if ( isset( $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->new_version ) ) { return $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->new_version; } return false; } /** * Retrieve potential upgrade notice for a plugin. * * @since 2.5.0 * * @param string $slug Plugin slug. * @return string The upgrade notice or an empty string if no message was available or provided. */ public function get_upgrade_notice( $slug ) { // We currently can't get reliable info on non-WP-repo plugins - issue #380. if ( 'repo' !== $this->plugins[ $slug ]['source_type'] ) { return ''; } $repo_updates = get_site_transient( 'update_plugins' ); if ( ! empty( $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->upgrade_notice ) ) { return $repo_updates->response[ $this->plugins[ $slug ]['file_path'] ]->upgrade_notice; } return ''; } /** * Wrapper around the core WP get_plugins function, making sure it's actually available. * * @since 2.5.0 * * @param string $plugin_folder Optional. Relative path to single plugin folder. * @return array Array of installed plugins with plugin information. */ public function get_plugins( $plugin_folder = '' ) { if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } return get_plugins( $plugin_folder ); } /** * Delete dismissable nag option when theme is switched. * * This ensures that the user(s) is/are again reminded via nag of required * and/or recommended plugins if they re-activate the theme. * * @since 2.1.1 */ public function update_dismiss() { delete_metadata( 'user', null, 'tgmpa_dismissed_notice_' . $this->id, null, true ); } /** * Forces plugin activation if the parameter 'force_activation' is * set to true. * * This allows theme authors to specify certain plugins that must be * active at all times while using the current theme. * * Please take special care when using this parameter as it has the * potential to be harmful if not used correctly. Setting this parameter * to true will not allow the specified plugin to be deactivated unless * the user switches themes. * * @since 2.2.0 */ public function force_activation() { foreach ( $this->plugins as $slug => $plugin ) { if ( true === $plugin['force_activation'] ) { if ( ! $this->is_plugin_installed( $slug ) ) { // Oops, plugin isn't there so iterate to next condition. continue; } elseif ( $this->can_plugin_activate( $slug ) ) { // There we go, activate the plugin. activate_plugin( $plugin['file_path'] ); } } } } /** * Forces plugin deactivation if the parameter 'force_deactivation' * is set to true. * * This allows theme authors to specify certain plugins that must be * deactivated upon switching from the current theme to another. * * Please take special care when using this parameter as it has the * potential to be harmful if not used correctly. * * @since 2.2.0 */ public function force_deactivation() { foreach ( $this->plugins as $slug => $plugin ) { // Only proceed forward if the parameter is set to true and plugin is active. if ( true === $plugin['force_deactivation'] && $this->is_plugin_active( $slug ) ) { deactivate_plugins( $plugin['file_path'] ); } } } /** * Echo the current TGMPA version number to the page. */ public function show_tgmpa_version() { echo '

', esc_html( sprintf( _x( 'TGMPA v%s', '%s = version number', 'tgmpa' ), self::TGMPA_VERSION ) ), '

'; } /** * Returns the singleton instance of the class. * * @since 2.4.0 * * @return object The TGM_Plugin_Activation object. */ public static function get_instance() { if ( ! isset( self::$instance ) && ! ( self::$instance instanceof self ) ) { self::$instance = new self(); } return self::$instance; } } if ( ! function_exists( 'load_tgm_plugin_activation' ) ) { /** * Ensure only one instance of the class is ever invoked. */ function load_tgm_plugin_activation() { $GLOBALS['tgmpa'] = TGM_Plugin_Activation::get_instance(); } } if ( did_action( 'plugins_loaded' ) ) { load_tgm_plugin_activation(); } else { add_action( 'plugins_loaded', 'load_tgm_plugin_activation' ); } } if ( ! function_exists( 'tgmpa' ) ) { /** * Helper function to register a collection of required plugins. * * @since 2.0.0 * @api * * @param array $plugins An array of plugin arrays. * @param array $config Optional. An array of configuration values. */ function tgmpa( $plugins, $config = array() ) { $instance = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); foreach ( $plugins as $plugin ) { call_user_func( array( $instance, 'register' ), $plugin ); } if ( ! empty( $config ) && is_array( $config ) ) { // Send out notices for deprecated arguments passed. if ( isset( $config['notices'] ) ) { _deprecated_argument( __FUNCTION__, '2.2.0', 'The `notices` config parameter was renamed to `has_notices` in TGMPA 2.2.0. Please adjust your configuration.' ); if ( ! isset( $config['has_notices'] ) ) { $config['has_notices'] = $config['notices']; } } if ( isset( $config['parent_menu_slug'] ) ) { _deprecated_argument( __FUNCTION__, '2.4.0', 'The `parent_menu_slug` config parameter was removed in TGMPA 2.4.0. In TGMPA 2.5.0 an alternative was (re-)introduced. Please adjust your configuration. For more information visit the website: http://tgmpluginactivation.com/configuration/#h-configuration-options.' ); } if ( isset( $config['parent_url_slug'] ) ) { _deprecated_argument( __FUNCTION__, '2.4.0', 'The `parent_url_slug` config parameter was removed in TGMPA 2.4.0. In TGMPA 2.5.0 an alternative was (re-)introduced. Please adjust your configuration. For more information visit the website: http://tgmpluginactivation.com/configuration/#h-configuration-options.' ); } call_user_func( array( $instance, 'config' ), $config ); } } } /** * WP_List_Table isn't always available. If it isn't available, * we load it here. * * @since 2.2.0 */ if ( ! class_exists( 'WP_List_Table' ) ) { require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; } if ( ! class_exists( 'TGMPA_List_Table' ) ) { /** * List table class for handling plugins. * * Extends the WP_List_Table class to provide a future-compatible * way of listing out all required/recommended plugins. * * Gives users an interface similar to the Plugin Administration * area with similar (albeit stripped down) capabilities. * * This class also allows for the bulk install of plugins. * * @since 2.2.0 * * @package TGM-Plugin-Activation * @author Thomas Griffin * @author Gary Jones */ class TGMPA_List_Table extends WP_List_Table { /** * TGMPA instance. * * @since 2.5.0 * * @var object */ protected $tgmpa; /** * The currently chosen view. * * @since 2.5.0 * * @var string One of: 'all', 'install', 'update', 'activate' */ public $view_context = 'all'; /** * The plugin counts for the various views. * * @since 2.5.0 * * @var array */ protected $view_totals = array( 'all' => 0, 'install' => 0, 'update' => 0, 'activate' => 0, ); /** * References parent constructor and sets defaults for class. * * @since 2.2.0 */ public function __construct() { $this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); parent::__construct( array( 'singular' => 'plugin', 'plural' => 'plugins', 'ajax' => false, ) ); if ( isset( $_REQUEST['plugin_status'] ) && in_array( $_REQUEST['plugin_status'], array( 'install', 'update', 'activate' ), true ) ) { $this->view_context = sanitize_key( $_REQUEST['plugin_status'] ); } add_filter( 'tgmpa_table_data_items', array( $this, 'sort_table_items' ) ); } /** * Get a list of CSS classes for the tag. * * Overruled to prevent the 'plural' argument from being added. * * @since 2.5.0 * * @return array CSS classnames. */ public function get_table_classes() { return array( 'widefat', 'fixed' ); } /** * Gathers and renames all of our plugin information to be used by WP_List_Table to create our table. * * @since 2.2.0 * * @return array $table_data Information for use in table. */ protected function _gather_plugin_data() { // Load thickbox for plugin links. $this->tgmpa->admin_init(); $this->tgmpa->thickbox(); // Categorize the plugins which have open actions. $plugins = $this->categorize_plugins_to_views(); // Set the counts for the view links. $this->set_view_totals( $plugins ); // Prep variables for use and grab list of all installed plugins. $table_data = array(); $i = 0; // Redirect to the 'all' view if no plugins were found for the selected view context. if ( empty( $plugins[ $this->view_context ] ) ) { $this->view_context = 'all'; } foreach ( $plugins[ $this->view_context ] as $slug => $plugin ) { $table_data[ $i ]['sanitized_plugin'] = $plugin['name']; $table_data[ $i ]['slug'] = $slug; $table_data[ $i ]['plugin'] = '' . $this->tgmpa->get_info_link( $slug ) . ''; $table_data[ $i ]['source'] = $this->get_plugin_source_type_text( $plugin['source_type'] ); $table_data[ $i ]['type'] = $this->get_plugin_advise_type_text( $plugin['required'] ); $table_data[ $i ]['status'] = $this->get_plugin_status_text( $slug ); $table_data[ $i ]['installed_version'] = $this->tgmpa->get_installed_version( $slug ); $table_data[ $i ]['minimum_version'] = $plugin['version']; $table_data[ $i ]['available_version'] = $this->tgmpa->does_plugin_have_update( $slug ); // Prep the upgrade notice info. $upgrade_notice = $this->tgmpa->get_upgrade_notice( $slug ); if ( ! empty( $upgrade_notice ) ) { $table_data[ $i ]['upgrade_notice'] = $upgrade_notice; add_action( "tgmpa_after_plugin_row_$slug", array( $this, 'wp_plugin_update_row' ), 10, 2 ); } $table_data[ $i ] = apply_filters( 'tgmpa_table_data_item', $table_data[ $i ], $plugin ); $i++; } return $table_data; } /** * Categorize the plugins which have open actions into views for the TGMPA page. * * @since 2.5.0 */ protected function categorize_plugins_to_views() { $plugins = array( 'all' => array(), // Meaning: all plugins which still have open actions. 'install' => array(), 'update' => array(), 'activate' => array(), ); foreach ( $this->tgmpa->plugins as $slug => $plugin ) { if ( $this->tgmpa->is_plugin_active( $slug ) && false === $this->tgmpa->does_plugin_have_update( $slug ) ) { // No need to display plugins if they are installed, up-to-date and active. continue; } else { $plugins['all'][ $slug ] = $plugin; if ( ! $this->tgmpa->is_plugin_installed( $slug ) ) { $plugins['install'][ $slug ] = $plugin; } else { if ( false !== $this->tgmpa->does_plugin_have_update( $slug ) ) { $plugins['update'][ $slug ] = $plugin; } if ( $this->tgmpa->can_plugin_activate( $slug ) ) { $plugins['activate'][ $slug ] = $plugin; } } } } return $plugins; } /** * Set the counts for the view links. * * @since 2.5.0 * * @param array $plugins Plugins order by view. */ protected function set_view_totals( $plugins ) { foreach ( $plugins as $type => $list ) { $this->view_totals[ $type ] = count( $list ); } } /** * Get the plugin required/recommended text string. * * @since 2.5.0 * * @param string $required Plugin required setting. * @return string */ protected function get_plugin_advise_type_text( $required ) { if ( true === $required ) { return __( 'Required', 'tgmpa' ); } return __( 'Recommended', 'tgmpa' ); } /** * Get the plugin source type text string. * * @since 2.5.0 * * @param string $type Plugin type. * @return string */ protected function get_plugin_source_type_text( $type ) { $string = ''; switch ( $type ) { case 'repo': $string = __( 'WordPress Repository', 'tgmpa' ); break; case 'external': $string = __( 'External Source', 'tgmpa' ); break; case 'bundled': $string = __( 'Pre-Packaged', 'tgmpa' ); break; } return $string; } /** * Determine the plugin status message. * * @since 2.5.0 * * @param string $slug Plugin slug. * @return string */ protected function get_plugin_status_text( $slug ) { if ( ! $this->tgmpa->is_plugin_installed( $slug ) ) { return __( 'Not Installed', 'tgmpa' ); } if ( ! $this->tgmpa->is_plugin_active( $slug ) ) { $install_status = __( 'Installed But Not Activated', 'tgmpa' ); } else { $install_status = __( 'Active', 'tgmpa' ); } $update_status = ''; if ( $this->tgmpa->does_plugin_require_update( $slug ) && false === $this->tgmpa->does_plugin_have_update( $slug ) ) { $update_status = __( 'Required Update not Available', 'tgmpa' ); } elseif ( $this->tgmpa->does_plugin_require_update( $slug ) ) { $update_status = __( 'Requires Update', 'tgmpa' ); } elseif ( false !== $this->tgmpa->does_plugin_have_update( $slug ) ) { $update_status = __( 'Update recommended', 'tgmpa' ); } if ( '' === $update_status ) { return $install_status; } return sprintf( _x( '%1$s, %2$s', '%1$s = install status, %2$s = update status', 'tgmpa' ), $install_status, $update_status ); } /** * Sort plugins by Required/Recommended type and by alphabetical plugin name within each type. * * @since 2.5.0 * * @param array $items Prepared table items. * @return array Sorted table items. */ public function sort_table_items( $items ) { $type = array(); $name = array(); foreach ( $items as $i => $plugin ) { $type[ $i ] = $plugin['type']; // Required / recommended. $name[ $i ] = $plugin['sanitized_plugin']; } array_multisort( $type, SORT_DESC, $name, SORT_ASC, $items ); return $items; } /** * Get an associative array ( id => link ) of the views available on this table. * * @since 2.5.0 * * @return array */ public function get_views() { $status_links = array(); foreach ( $this->view_totals as $type => $count ) { if ( $count < 1 ) { continue; } switch ( $type ) { case 'all': $text = _nx( 'All (%s)', 'All (%s)', $count, 'plugins', 'tgmpa' ); break; case 'install': $text = _n( 'To Install (%s)', 'To Install (%s)', $count, 'tgmpa' ); break; case 'update': $text = _n( 'Update Available (%s)', 'Update Available (%s)', $count, 'tgmpa' ); break; case 'activate': $text = _n( 'To Activate (%s)', 'To Activate (%s)', $count, 'tgmpa' ); break; default: $text = ''; break; } if ( ! empty( $text ) ) { $status_links[ $type ] = sprintf( '%s', esc_url( $this->tgmpa->get_tgmpa_status_url( $type ) ), ( $type === $this->view_context ) ? ' class="current"' : '', sprintf( $text, number_format_i18n( $count ) ) ); } } return $status_links; } /** * Create default columns to display important plugin information * like type, action and status. * * @since 2.2.0 * * @param array $item Array of item data. * @param string $column_name The name of the column. * @return string */ public function column_default( $item, $column_name ) { return $item[ $column_name ]; } /** * Required for bulk installing. * * Adds a checkbox for each plugin. * * @since 2.2.0 * * @param array $item Array of item data. * @return string The input checkbox with all necessary info. */ public function column_cb( $item ) { return sprintf( '', esc_attr( $this->_args['singular'] ), esc_attr( $item['slug'] ), esc_attr( $item['sanitized_plugin'] ) ); } /** * Create default title column along with the action links. * * @since 2.2.0 * * @param array $item Array of item data. * @return string The plugin name and action links. */ public function column_plugin( $item ) { return sprintf( '%1$s %2$s', $item['plugin'], $this->row_actions( $this->get_row_actions( $item ), true ) ); } /** * Create version information column. * * @since 2.5.0 * * @param array $item Array of item data. * @return string HTML-formatted version information. */ public function column_version( $item ) { $output = array(); if ( $this->tgmpa->is_plugin_installed( $item['slug'] ) ) { $installed = ! empty( $item['installed_version'] ) ? $item['installed_version'] : _x( 'unknown', 'as in: "version nr unknown"', 'tgmpa' ); $color = ''; if ( ! empty( $item['minimum_version'] ) && $this->tgmpa->does_plugin_require_update( $item['slug'] ) ) { $color = ' color: #ff0000; font-weight: bold;'; } $output[] = sprintf( '

%2$s' . __( 'Installed version:', 'tgmpa' ) . '

', $color, $installed ); } if ( ! empty( $item['minimum_version'] ) ) { $output[] = sprintf( '

%1$s' . __( 'Minimum required version:', 'tgmpa' ) . '

', $item['minimum_version'] ); } if ( ! empty( $item['available_version'] ) ) { $color = ''; if ( ! empty( $item['minimum_version'] ) && version_compare( $item['available_version'], $item['minimum_version'], '>=' ) ) { $color = ' color: #71C671; font-weight: bold;'; } $output[] = sprintf( '

%2$s' . __( 'Available version:', 'tgmpa' ) . '

', $color, $item['available_version'] ); } if ( empty( $output ) ) { return ' '; // Let's not break the table layout. } else { return implode( "\n", $output ); } } /** * Sets default message within the plugins table if no plugins * are left for interaction. * * Hides the menu item to prevent the user from clicking and * getting a permissions error. * * @since 2.2.0 */ public function no_items() { printf( wp_kses_post( __( 'No plugins to install, update or activate. Return to the Dashboard', 'tgmpa' ) ), esc_url( self_admin_url() ) ); echo ''; } /** * Output all the column information within the table. * * @since 2.2.0 * * @return array $columns The column names. */ public function get_columns() { $columns = array( 'cb' => '', 'plugin' => __( 'Plugin', 'tgmpa' ), 'source' => __( 'Source', 'tgmpa' ), 'type' => __( 'Type', 'tgmpa' ), ); if ( 'all' === $this->view_context || 'update' === $this->view_context ) { $columns['version'] = __( 'Version', 'tgmpa' ); $columns['status'] = __( 'Status', 'tgmpa' ); } return apply_filters( 'tgmpa_table_columns', $columns ); } /** * Get name of default primary column * * @since 2.5.0 / WP 4.3+ compatibility * @access protected * * @return string */ protected function get_default_primary_column_name() { return 'plugin'; } /** * Get the name of the primary column. * * @since 2.5.0 / WP 4.3+ compatibility * @access protected * * @return string The name of the primary column. */ protected function get_primary_column_name() { if ( method_exists( 'WP_List_Table', 'get_primary_column_name' ) ) { return parent::get_primary_column_name(); } else { return $this->get_default_primary_column_name(); } } /** * Get the actions which are relevant for a specific plugin row. * * @since 2.5.0 * * @param array $item Array of item data. * @return array Array with relevant action links. */ protected function get_row_actions( $item ) { $actions = array(); $action_links = array(); // Display the 'Install' action link if the plugin is not yet available. if ( ! $this->tgmpa->is_plugin_installed( $item['slug'] ) ) { $actions['install'] = _x( 'Install %2$s', '%2$s = plugin name in screen reader markup', 'tgmpa' ); } else { // Display the 'Update' action link if an update is available and WP complies with plugin minimum. if ( false !== $this->tgmpa->does_plugin_have_update( $item['slug'] ) && $this->tgmpa->can_plugin_update( $item['slug'] ) ) { $actions['update'] = _x( 'Update %2$s', '%2$s = plugin name in screen reader markup', 'tgmpa' ); } // Display the 'Activate' action link, but only if the plugin meets the minimum version. if ( $this->tgmpa->can_plugin_activate( $item['slug'] ) ) { $actions['activate'] = _x( 'Activate %2$s', '%2$s = plugin name in screen reader markup', 'tgmpa' ); } } // Create the actual links. foreach ( $actions as $action => $text ) { $nonce_url = wp_nonce_url( add_query_arg( array( 'plugin' => urlencode( $item['slug'] ), 'tgmpa-' . $action => $action . '-plugin', ), $this->tgmpa->get_tgmpa_url() ), 'tgmpa-' . $action, 'tgmpa-nonce' ); $action_links[ $action ] = sprintf( '' . esc_html( $text ) . '', esc_url( $nonce_url ), '' . esc_html( $item['sanitized_plugin'] ) . '' ); } $prefix = ( defined( 'WP_NETWORK_ADMIN' ) && WP_NETWORK_ADMIN ) ? 'network_admin_' : ''; return apply_filters( "tgmpa_{$prefix}plugin_action_links", array_filter( $action_links ), $item['slug'], $item, $this->view_context ); } /** * Generates content for a single row of the table. * * @since 2.5.0 * * @param object $item The current item. */ public function single_row( $item ) { parent::single_row( $item ); /** * Fires after each specific row in the TGMPA Plugins list table. * * The dynamic portion of the hook name, `$item['slug']`, refers to the slug * for the plugin. * * @since 2.5.0 */ do_action( "tgmpa_after_plugin_row_{$item['slug']}", $item['slug'], $item, $this->view_context ); } /** * Show the upgrade notice below a plugin row if there is one. * * @since 2.5.0 * * @see /wp-admin/includes/update.php * * @param string $slug Plugin slug. * @param array $item The information available in this table row. * @return null Return early if upgrade notice is empty. */ public function wp_plugin_update_row( $slug, $item ) { if ( empty( $item['upgrade_notice'] ) ) { return; } echo ' '; } /** * Extra controls to be displayed between bulk actions and pagination. * * @since 2.5.0 * * @param string $which 'top' or 'bottom' table navigation. */ public function extra_tablenav( $which ) { if ( 'bottom' === $which ) { $this->tgmpa->show_tgmpa_version(); } } /** * Defines the bulk actions for handling registered plugins. * * @since 2.2.0 * * @return array $actions The bulk actions for the plugin install table. */ public function get_bulk_actions() { $actions = array(); if ( 'update' !== $this->view_context && 'activate' !== $this->view_context ) { if ( current_user_can( 'install_plugins' ) ) { $actions['tgmpa-bulk-install'] = __( 'Install', 'tgmpa' ); } } if ( 'install' !== $this->view_context ) { if ( current_user_can( 'update_plugins' ) ) { $actions['tgmpa-bulk-update'] = __( 'Update', 'tgmpa' ); } if ( current_user_can( 'activate_plugins' ) ) { $actions['tgmpa-bulk-activate'] = __( 'Activate', 'tgmpa' ); } } return $actions; } /** * Processes bulk installation and activation actions. * * The bulk installation process looks for the $_POST information and passes that * through if a user has to use WP_Filesystem to enter their credentials. * * @since 2.2.0 */ public function process_bulk_actions() { // Bulk installation process. if ( 'tgmpa-bulk-install' === $this->current_action() || 'tgmpa-bulk-update' === $this->current_action() ) { check_admin_referer( 'bulk-' . $this->_args['plural'] ); $install_type = 'install'; if ( 'tgmpa-bulk-update' === $this->current_action() ) { $install_type = 'update'; } $plugins_to_install = array(); // Did user actually select any plugins to install/update ? if ( empty( $_POST['plugin'] ) ) { if ( 'install' === $install_type ) { $message = __( 'No plugins were selected to be installed. No action taken.', 'tgmpa' ); } else { $message = __( 'No plugins were selected to be updated. No action taken.', 'tgmpa' ); } echo '

', esc_html( $message ), '

'; return false; } if ( is_array( $_POST['plugin'] ) ) { $plugins_to_install = (array) $_POST['plugin']; } elseif ( is_string( $_POST['plugin'] ) ) { // Received via Filesystem page - un-flatten array (WP bug #19643). $plugins_to_install = explode( ',', $_POST['plugin'] ); } // Sanitize the received input. $plugins_to_install = array_map( 'urldecode', $plugins_to_install ); $plugins_to_install = array_map( array( $this->tgmpa, 'sanitize_key' ), $plugins_to_install ); // Validate the received input. foreach ( $plugins_to_install as $key => $slug ) { // Check if the plugin was registered with TGMPA and remove if not. if ( ! isset( $this->tgmpa->plugins[ $slug ] ) ) { unset( $plugins_to_install[ $key ] ); continue; } // For updates: make sure this is a plugin we *can* update (update available and WP version ok). if ( 'update' === $install_type && ( $this->tgmpa->is_plugin_installed( $slug ) && ( false === $this->tgmpa->does_plugin_have_update( $slug ) || ! $this->tgmpa->can_plugin_update( $slug ) ) ) ) { unset( $plugins_to_install[ $key ] ); } } // No need to proceed further if we have no plugins to handle. if ( empty( $plugins_to_install ) ) { if ( 'install' === $install_type ) { $message = __( 'No plugins are available to be installed at this time.', 'tgmpa' ); } else { $message = __( 'No plugins are available to be updated at this time.', 'tgmpa' ); } echo '

', esc_html( $message ), '

'; return false; } // Pass all necessary information if WP_Filesystem is needed. $url = wp_nonce_url( $this->tgmpa->get_tgmpa_url(), 'bulk-' . $this->_args['plural'] ); // Give validated data back to $_POST which is the only place the filesystem looks for extra fields. $_POST['plugin'] = implode( ',', $plugins_to_install ); // Work around for WP bug #19643. $method = ''; // Leave blank so WP_Filesystem can populate it as necessary. $fields = array_keys( $_POST ); // Extra fields to pass to WP_Filesystem. if ( false === ( $creds = request_filesystem_credentials( esc_url_raw( $url ), $method, false, false, $fields ) ) ) { return true; // Stop the normal page form from displaying, credential request form will be shown. } // Now we have some credentials, setup WP_Filesystem. if ( ! WP_Filesystem( $creds ) ) { // Our credentials were no good, ask the user for them again. request_filesystem_credentials( esc_url_raw( $url ), $method, true, false, $fields ); return true; } /* If we arrive here, we have the filesystem */ // Store all information in arrays since we are processing a bulk installation. $names = array(); $sources = array(); // Needed for installs. $file_paths = array(); // Needed for upgrades. $to_inject = array(); // Information to inject into the update_plugins transient. // Prepare the data for validated plugins for the install/upgrade. foreach ( $plugins_to_install as $slug ) { $name = $this->tgmpa->plugins[ $slug ]['name']; $source = $this->tgmpa->get_download_url( $slug ); if ( ! empty( $name ) && ! empty( $source ) ) { $names[] = $name; switch ( $install_type ) { case 'install': $sources[] = $source; break; case 'update': $file_paths[] = $this->tgmpa->plugins[ $slug ]['file_path']; $to_inject[ $slug ] = $this->tgmpa->plugins[ $slug ]; $to_inject[ $slug ]['source'] = $source; break; } } } unset( $slug, $name, $source ); // Create a new instance of TGMPA_Bulk_Installer. $installer = new TGMPA_Bulk_Installer( new TGMPA_Bulk_Installer_Skin( array( 'url' => esc_url_raw( $this->tgmpa->get_tgmpa_url() ), 'nonce' => 'bulk-' . $this->_args['plural'], 'names' => $names, 'install_type' => $install_type, ) ) ); // Wrap the install process with the appropriate HTML. echo '
', '

', esc_html( get_admin_page_title() ), '

'; // Process the bulk installation submissions. add_filter( 'upgrader_source_selection', array( $this->tgmpa, 'maybe_adjust_source_dir' ), 1, 3 ); if ( 'tgmpa-bulk-update' === $this->current_action() ) { // Inject our info into the update transient. $this->tgmpa->inject_update_info( $to_inject ); $installer->bulk_upgrade( $file_paths ); } else { $installer->bulk_install( $sources ); } remove_filter( 'upgrader_source_selection', array( $this->tgmpa, 'maybe_adjust_source_dir' ), 1, 3 ); echo '
'; return true; } // Bulk activation process. if ( 'tgmpa-bulk-activate' === $this->current_action() ) { check_admin_referer( 'bulk-' . $this->_args['plural'] ); // Did user actually select any plugins to activate ? if ( empty( $_POST['plugin'] ) ) { echo '

', esc_html__( 'No plugins were selected to be activated. No action taken.', 'tgmpa' ), '

'; return false; } // Grab plugin data from $_POST. $plugins = array(); if ( isset( $_POST['plugin'] ) ) { $plugins = array_map( 'urldecode', (array) $_POST['plugin'] ); $plugins = array_map( array( $this->tgmpa, 'sanitize_key' ), $plugins ); } $plugins_to_activate = array(); $plugin_names = array(); // Grab the file paths for the selected & inactive plugins from the registration array. foreach ( $plugins as $slug ) { if ( $this->tgmpa->can_plugin_activate( $slug ) ) { $plugins_to_activate[] = $this->tgmpa->plugins[ $slug ]['file_path']; $plugin_names[] = $this->tgmpa->plugins[ $slug ]['name']; } } unset( $slug ); // Return early if there are no plugins to activate. if ( empty( $plugins_to_activate ) ) { echo '

', esc_html__( 'No plugins are available to be activated at this time.', 'tgmpa' ), '

'; return false; } // Now we are good to go - let's start activating plugins. $activate = activate_plugins( $plugins_to_activate ); if ( is_wp_error( $activate ) ) { echo '

', wp_kses_post( $activate->get_error_message() ), '

'; } else { $count = count( $plugin_names ); // Count so we can use _n function. $plugin_names = array_map( array( 'TGMPA_Utils', 'wrap_in_strong' ), $plugin_names ); $last_plugin = array_pop( $plugin_names ); // Pop off last name to prep for readability. $imploded = empty( $plugin_names ) ? $last_plugin : ( implode( ', ', $plugin_names ) . ' ' . esc_html_x( 'and', 'plugin A *and* plugin B', 'tgmpa' ) . ' ' . $last_plugin ); printf( // WPCS: xss ok. '

%1$s %2$s.

', esc_html( _n( 'The following plugin was activated successfully:', 'The following plugins were activated successfully:', $count, 'tgmpa' ) ), $imploded ); // Update recently activated plugins option. $recent = (array) get_option( 'recently_activated' ); foreach ( $plugins_to_activate as $plugin => $time ) { if ( isset( $recent[ $plugin ] ) ) { unset( $recent[ $plugin ] ); } } update_option( 'recently_activated', $recent ); } unset( $_POST ); // Reset the $_POST variable in case user wants to perform one action after another. return true; } return false; } /** * Prepares all of our information to be outputted into a usable table. * * @since 2.2.0 */ public function prepare_items() { $columns = $this->get_columns(); // Get all necessary column information. $hidden = array(); // No columns to hide, but we must set as an array. $sortable = array(); // No reason to make sortable columns. $primary = $this->get_primary_column_name(); // Column which has the row actions. $this->_column_headers = array( $columns, $hidden, $sortable, $primary ); // Get all necessary column headers. // Process our bulk activations here. if ( 'tgmpa-bulk-activate' === $this->current_action() ) { $this->process_bulk_actions(); } // Store all of our plugin data into $items array so WP_List_Table can use it. $this->items = apply_filters( 'tgmpa_table_data_items', $this->_gather_plugin_data() ); } /* *********** DEPRECATED METHODS *********** */ /** * Retrieve plugin data, given the plugin name. * * @since 2.2.0 * @deprecated 2.5.0 use {@see TGM_Plugin_Activation::_get_plugin_data_from_name()} instead. * @see TGM_Plugin_Activation::_get_plugin_data_from_name() * * @param string $name Name of the plugin, as it was registered. * @param string $data Optional. Array key of plugin data to return. Default is slug. * @return string|boolean Plugin slug if found, false otherwise. */ protected function _get_plugin_data_from_name( $name, $data = 'slug' ) { _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'TGM_Plugin_Activation::_get_plugin_data_from_name()' ); return $this->tgmpa->_get_plugin_data_from_name( $name, $data ); } } } if ( ! class_exists( 'TGM_Bulk_Installer' ) ) { /** * Hack: Prevent TGMPA v2.4.1- bulk installer class from being loaded if 2.4.1- is loaded after 2.5+. */ class TGM_Bulk_Installer { } } if ( ! class_exists( 'TGM_Bulk_Installer_Skin' ) ) { /** * Hack: Prevent TGMPA v2.4.1- bulk installer skin class from being loaded if 2.4.1- is loaded after 2.5+. */ class TGM_Bulk_Installer_Skin { } } /** * The WP_Upgrader file isn't always available. If it isn't available, * we load it here. * * We check to make sure no action or activation keys are set so that WordPress * does not try to re-include the class when processing upgrades or installs outside * of the class. * * @since 2.2.0 */ add_action( 'admin_init', 'tgmpa_load_bulk_installer' ); if ( ! function_exists( 'tgmpa_load_bulk_installer' ) ) { /** * Load bulk installer */ function tgmpa_load_bulk_installer() { // Silently fail if 2.5+ is loaded *after* an older version. if ( ! isset( $GLOBALS['tgmpa'] ) ) { return; } // Get TGMPA class instance. $tgmpa_instance = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); if ( isset( $_GET['page'] ) && $tgmpa_instance->menu === $_GET['page'] ) { if ( ! class_exists( 'Plugin_Upgrader', false ) ) { require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; } if ( ! class_exists( 'TGMPA_Bulk_Installer' ) ) { /** * Installer class to handle bulk plugin installations. * * Extends WP_Upgrader and customizes to suit the installation of multiple * plugins. * * @since 2.2.0 * * @internal Since 2.5.0 the class is an extension of Plugin_Upgrader rather than WP_Upgrader * @internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer to TGMPA_Bulk_Installer. * This was done to prevent backward compatibility issues with v2.3.6. * * @package TGM-Plugin-Activation * @author Thomas Griffin * @author Gary Jones */ class TGMPA_Bulk_Installer extends Plugin_Upgrader { /** * Holds result of bulk plugin installation. * * @since 2.2.0 * * @var string */ public $result; /** * Flag to check if bulk installation is occurring or not. * * @since 2.2.0 * * @var boolean */ public $bulk = false; /** * TGMPA instance * * @since 2.5.0 * * @var object */ protected $tgmpa; /** * Whether or not the destination directory needs to be cleared ( = on update). * * @since 2.5.0 * * @var bool */ protected $clear_destination = false; /** * References parent constructor and sets defaults for class. * * @since 2.2.0 * * @param \Bulk_Upgrader_Skin|null $skin Installer skin. */ public function __construct( $skin = null ) { // Get TGMPA class instance. $this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); parent::__construct( $skin ); if ( isset( $this->skin->options['install_type'] ) && 'update' === $this->skin->options['install_type'] ) { $this->clear_destination = true; } if ( $this->tgmpa->is_automatic ) { $this->activate_strings(); } add_action( 'upgrader_process_complete', array( $this->tgmpa, 'populate_file_path' ) ); } /** * Sets the correct activation strings for the installer skin to use. * * @since 2.2.0 */ public function activate_strings() { $this->strings['activation_failed'] = __( 'Plugin activation failed.', 'tgmpa' ); $this->strings['activation_success'] = __( 'Plugin activated successfully.', 'tgmpa' ); } /** * Performs the actual installation of each plugin. * * @since 2.2.0 * * @see WP_Upgrader::run() * * @param array $options The installation config options. * @return null|array Return early if error, array of installation data on success. */ public function run( $options ) { $result = parent::run( $options ); // Reset the strings in case we changed one during automatic activation. if ( $this->tgmpa->is_automatic ) { if ( 'update' === $this->skin->options['install_type'] ) { $this->upgrade_strings(); } else { $this->install_strings(); } } return $result; } /** * Processes the bulk installation of plugins. * * @since 2.2.0 * * @internal This is basically a near identical copy of the WP Core Plugin_Upgrader::bulk_upgrade() * method, with minor adjustments to deal with new installs instead of upgrades. * For ease of future synchronizations, the adjustments are clearly commented, but no other * comments are added. Code style has been made to comply. * * @see Plugin_Upgrader::bulk_upgrade() * @see https://core.trac.wordpress.org/browser/tags/4.2.1/src/wp-admin/includes/class-wp-upgrader.php#L838 * * @param array $plugins The plugin sources needed for installation. * @param array $args Arbitrary passed extra arguments. * @return string|bool Install confirmation messages on success, false on failure. */ public function bulk_install( $plugins, $args = array() ) { // [TGMPA + ] Hook auto-activation in. add_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); $defaults = array( 'clear_update_cache' => true, ); $parsed_args = wp_parse_args( $args, $defaults ); $this->init(); $this->bulk = true; $this->install_strings(); // [TGMPA + ] adjusted. /* [TGMPA - ] $current = get_site_transient( 'update_plugins' ); */ /* [TGMPA - ] add_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'), 10, 4); */ $this->skin->header(); // Connect to the Filesystem first. $res = $this->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) ); if ( ! $res ) { $this->skin->footer(); return false; } $this->skin->bulk_header(); // Only start maintenance mode if: // - running Multisite and there are one or more plugins specified, OR // - a plugin with an update available is currently active. // @TODO: For multisite, maintenance mode should only kick in for individual sites if at all possible. $maintenance = ( is_multisite() && ! empty( $plugins ) ); /* [TGMPA - ] foreach ( $plugins as $plugin ) $maintenance = $maintenance || ( is_plugin_active( $plugin ) && isset( $current->response[ $plugin] ) ); */ if ( $maintenance ) { $this->maintenance_mode( true ); } $results = array(); $this->update_count = count( $plugins ); $this->update_current = 0; foreach ( $plugins as $plugin ) { $this->update_current++; /* [TGMPA - ] $this->skin->plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin, false, true); if ( !isset( $current->response[ $plugin ] ) ) { $this->skin->set_result('up_to_date'); $this->skin->before(); $this->skin->feedback('up_to_date'); $this->skin->after(); $results[$plugin] = true; continue; } // Get the URL to the zip file $r = $current->response[ $plugin ]; $this->skin->plugin_active = is_plugin_active($plugin); */ $result = $this->run( array( 'package' => $plugin, // [TGMPA + ] adjusted. 'destination' => WP_PLUGIN_DIR, 'clear_destination' => false, // [TGMPA + ] adjusted. 'clear_working' => true, 'is_multi' => true, 'hook_extra' => array( 'plugin' => $plugin, ), ) ); $results[ $plugin ] = $this->result; // Prevent credentials auth screen from displaying multiple times. if ( false === $result ) { break; } } //end foreach $plugins $this->maintenance_mode( false ); /** * Fires when the bulk upgrader process is complete. * * @since WP 3.6.0 / TGMPA 2.5.0 * * @param Plugin_Upgrader $this Plugin_Upgrader instance. In other contexts, $this, might * be a Theme_Upgrader or Core_Upgrade instance. * @param array $data { * Array of bulk item update data. * * @type string $action Type of action. Default 'update'. * @type string $type Type of update process. Accepts 'plugin', 'theme', or 'core'. * @type bool $bulk Whether the update process is a bulk update. Default true. * @type array $packages Array of plugin, theme, or core packages to update. * } */ do_action( 'upgrader_process_complete', $this, array( 'action' => 'install', // [TGMPA + ] adjusted. 'type' => 'plugin', 'bulk' => true, 'plugins' => $plugins, ) ); $this->skin->bulk_footer(); $this->skin->footer(); // Cleanup our hooks, in case something else does a upgrade on this connection. /* [TGMPA - ] remove_filter('upgrader_clear_destination', array($this, 'delete_old_plugin')); */ // [TGMPA + ] Remove our auto-activation hook. remove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); // Force refresh of plugin update information. wp_clean_plugins_cache( $parsed_args['clear_update_cache'] ); return $results; } /** * Handle a bulk upgrade request. * * @since 2.5.0 * * @see Plugin_Upgrader::bulk_upgrade() * * @param array $plugins The local WP file_path's of the plugins which should be upgraded. * @param array $args Arbitrary passed extra arguments. * @return string|bool Install confirmation messages on success, false on failure. */ public function bulk_upgrade( $plugins, $args = array() ) { add_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); $result = parent::bulk_upgrade( $plugins, $args ); remove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); return $result; } /** * Abuse a filter to auto-activate plugins after installation. * * Hooked into the 'upgrader_post_install' filter hook. * * @since 2.5.0 * * @param bool $bool The value we need to give back (true). * @return bool */ public function auto_activate( $bool ) { // Only process the activation of installed plugins if the automatic flag is set to true. if ( $this->tgmpa->is_automatic ) { // Flush plugins cache so the headers of the newly installed plugins will be read correctly. wp_clean_plugins_cache(); // Get the installed plugin file. $plugin_info = $this->plugin_info(); // Don't try to activate on upgrade of active plugin as WP will do this already. if ( ! is_plugin_active( $plugin_info ) ) { $activate = activate_plugin( $plugin_info ); // Adjust the success string based on the activation result. $this->strings['process_success'] = $this->strings['process_success'] . "
\n"; if ( is_wp_error( $activate ) ) { $this->skin->error( $activate ); $this->strings['process_success'] .= $this->strings['activation_failed']; } else { $this->strings['process_success'] .= $this->strings['activation_success']; } } } return $bool; } } } if ( ! class_exists( 'TGMPA_Bulk_Installer_Skin' ) ) { /** * Installer skin to set strings for the bulk plugin installations.. * * Extends Bulk_Upgrader_Skin and customizes to suit the installation of multiple * plugins. * * @since 2.2.0 * * @internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer_Skin to * TGMPA_Bulk_Installer_Skin. * This was done to prevent backward compatibility issues with v2.3.6. * * @see https://core.trac.wordpress.org/browser/trunk/src/wp-admin/includes/class-wp-upgrader-skins.php * * @package TGM-Plugin-Activation * @author Thomas Griffin * @author Gary Jones */ class TGMPA_Bulk_Installer_Skin extends Bulk_Upgrader_Skin { /** * Holds plugin info for each individual plugin installation. * * @since 2.2.0 * * @var array */ public $plugin_info = array(); /** * Holds names of plugins that are undergoing bulk installations. * * @since 2.2.0 * * @var array */ public $plugin_names = array(); /** * Integer to use for iteration through each plugin installation. * * @since 2.2.0 * * @var integer */ public $i = 0; /** * TGMPA instance * * @since 2.5.0 * * @var object */ protected $tgmpa; /** * Constructor. Parses default args with new ones and extracts them for use. * * @since 2.2.0 * * @param array $args Arguments to pass for use within the class. */ public function __construct( $args = array() ) { // Get TGMPA class instance. $this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); // Parse default and new args. $defaults = array( 'url' => '', 'nonce' => '', 'names' => array(), 'install_type' => 'install', ); $args = wp_parse_args( $args, $defaults ); // Set plugin names to $this->plugin_names property. $this->plugin_names = $args['names']; // Extract the new args. parent::__construct( $args ); } /** * Sets install skin strings for each individual plugin. * * Checks to see if the automatic activation flag is set and uses the * the proper strings accordingly. * * @since 2.2.0 */ public function add_strings() { if ( 'update' === $this->options['install_type'] ) { parent::add_strings(); $this->upgrader->strings['skin_before_update_header'] = __( 'Updating Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); } else { $this->upgrader->strings['skin_update_failed_error'] = __( 'An error occurred while installing %1$s: %2$s.', 'tgmpa' ); $this->upgrader->strings['skin_update_failed'] = __( 'The installation of %1$s failed.', 'tgmpa' ); if ( $this->tgmpa->is_automatic ) { // Automatic activation strings. $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation and activation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' ); $this->upgrader->strings['skin_update_successful'] = __( '%1$s installed and activated successfully.', 'tgmpa' ) . ' ' . esc_html__( 'Show Details', 'tgmpa' ) . '.'; $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations and activations have been completed.', 'tgmpa' ); $this->upgrader->strings['skin_before_update_header'] = __( 'Installing and Activating Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); } else { // Default installation strings. $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' ); $this->upgrader->strings['skin_update_successful'] = esc_html__( '%1$s installed successfully.', 'tgmpa' ) . ' ' . esc_html__( 'Show Details', 'tgmpa' ) . '.'; $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations have been completed.', 'tgmpa' ); $this->upgrader->strings['skin_before_update_header'] = __( 'Installing Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); } } } /** * Outputs the header strings and necessary JS before each plugin installation. * * @since 2.2.0 * * @param string $title Unused in this implementation. */ public function before( $title = '' ) { if ( empty( $title ) ) { $title = esc_html( $this->plugin_names[ $this->i ] ); } parent::before( $title ); } /** * Outputs the footer strings and necessary JS after each plugin installation. * * Checks for any errors and outputs them if they exist, else output * success strings. * * @since 2.2.0 * * @param string $title Unused in this implementation. */ public function after( $title = '' ) { if ( empty( $title ) ) { $title = esc_html( $this->plugin_names[ $this->i ] ); } parent::after( $title ); $this->i++; } /** * Outputs links after bulk plugin installation is complete. * * @since 2.2.0 */ public function bulk_footer() { // Serve up the string to say installations (and possibly activations) are complete. parent::bulk_footer(); // Flush plugins cache so we can make sure that the installed plugins list is always up to date. wp_clean_plugins_cache(); $this->tgmpa->show_tgmpa_version(); // Display message based on if all plugins are now active or not. $update_actions = array(); if ( $this->tgmpa->is_tgmpa_complete() ) { // All plugins are active, so we display the complete string and hide the menu to protect users. echo ''; $update_actions['dashboard'] = sprintf( esc_html( $this->tgmpa->strings['complete'] ), '' . esc_html__( 'Return to the Dashboard', 'tgmpa' ) . '' ); } else { $update_actions['tgmpa_page'] = '' . esc_html( $this->tgmpa->strings['return'] ) . ''; } /** * Filter the list of action links available following bulk plugin installs/updates. * * @since 2.5.0 * * @param array $update_actions Array of plugin action links. * @param array $plugin_info Array of information for the last-handled plugin. */ $update_actions = apply_filters( 'tgmpa_update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info ); if ( ! empty( $update_actions ) ) { $this->feedback( implode( ' | ', (array) $update_actions ) ); } } /* *********** DEPRECATED METHODS *********** */ /** * Flush header output buffer. * * @since 2.2.0 * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead * @see Bulk_Upgrader_Skin::flush_output() */ public function before_flush_output() { _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' ); $this->flush_output(); } /** * Flush footer output buffer and iterate $this->i to make sure the * installation strings reference the correct plugin. * * @since 2.2.0 * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead * @see Bulk_Upgrader_Skin::flush_output() */ public function after_flush_output() { _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' ); $this->flush_output(); $this->i++; } } } } } } if ( ! class_exists( 'TGMPA_Utils' ) ) { /** * Generic utilities for TGMPA. * * All methods are static, poor-dev name-spacing class wrapper. * * Class was called TGM_Utils in 2.5.0 but renamed TGMPA_Utils in 2.5.1 as this was conflicting with Soliloquy. * * @since 2.5.0 * * @package TGM-Plugin-Activation * @author Juliette Reinders Folmer */ class TGMPA_Utils { /** * Whether the PHP filter extension is enabled. * * @see http://php.net/book.filter * * @since 2.5.0 * * @static * * @var bool $has_filters True is the extension is enabled. */ public static $has_filters; /** * Wrap an arbitrary string in tags. Meant to be used in combination with array_map(). * * @since 2.5.0 * * @static * * @param string $string Text to be wrapped. * @return string */ public static function wrap_in_em( $string ) { return '' . wp_kses_post( $string ) . ''; } /** * Wrap an arbitrary string in tags. Meant to be used in combination with array_map(). * * @since 2.5.0 * * @static * * @param string $string Text to be wrapped. * @return string */ public static function wrap_in_strong( $string ) { return '' . wp_kses_post( $string ) . ''; } /** * Helper function: Validate a value as boolean * * @since 2.5.0 * * @static * * @param mixed $value Arbitrary value. * @return bool */ public static function validate_bool( $value ) { if ( ! isset( self::$has_filters ) ) { self::$has_filters = extension_loaded( 'filter' ); } if ( self::$has_filters ) { return filter_var( $value, FILTER_VALIDATE_BOOLEAN ); } else { return self::emulate_filter_bool( $value ); } } /** * Helper function: Cast a value to bool * * @since 2.5.0 * * @static * * @param mixed $value Value to cast. * @return bool */ protected static function emulate_filter_bool( $value ) { // @codingStandardsIgnoreStart static $true = array( '1', 'true', 'True', 'TRUE', 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', ); static $false = array( '0', 'false', 'False', 'FALSE', 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF', ); // @codingStandardsIgnoreEnd if ( is_bool( $value ) ) { return $value; } else if ( is_int( $value ) && ( 0 === $value || 1 === $value ) ) { return (bool) $value; } else if ( ( is_float( $value ) && ! is_nan( $value ) ) && ( (float) 0 === $value || (float) 1 === $value ) ) { return (bool) $value; } else if ( is_string( $value ) ) { $value = trim( $value ); if ( in_array( $value, $true, true ) ) { return true; } else if ( in_array( $value, $false, true ) ) { return false; } else { return false; } } return false; } } // End of class TGMPA_Utils } // End of class_exists wrapper ================================================ FILE: admin/includes/load_admin.php ================================================ * @license GPL-2.0+ * @link http://aesopinteractive.com * @copyright 2015 Aesopinteractive LLC */ namespace lasso_admin; use lasso_public_facing\lasso; class load_admin { /** * Instance of this class. * * @since 0.0.1 * * @var object */ protected static $instance = null; /** * Slug of the plugin screen. * * @since 0.0.1 * * @var string */ protected $plugin_screen_hook_suffix = null; /** * Initialize the plugin by loading admin scripts & styles and adding a * settings page and menu. * * @since 0.0.1 */ private function __construct() { $plugin = lasso::get_instance(); $this->plugin_slug = $plugin->get_plugin_slug(); add_action( 'admin_head', array( $this, 'admin_assets' ) ); add_action( 'admin_notices', array( $this, 'license_nag' ) ); add_action( 'admin_head', array( $this, 'dismiss_nag' ) ); add_filter( 'plugin_row_meta', array( $this, 'plugin_meta' ), 10, 2 ); if ( !class_exists( 'EDD_SL_Plugin_Updater' ) ) { include LASSO_DIR.'admin/includes/EDD_SL_Plugin_Updater.php'; } if ( !class_exists( 'TGM_Plugin_Activation' ) ) { include LASSO_DIR.'admin/includes/class-tgm-plugin-activation.php'; } new menus\welcome(); new menus\settings(); if ( !defined( 'LASSO_AGENCY_MODE' ) ) { new menus\license(); } } /** * Return an instance of this class. * * @since 0.0.1 * * @return object A single instance of this class. */ public static function get_instance() { // If the single instance hasn't been set, set it now. if ( null == self::$instance ) { self::$instance = new self; } return self::$instance; } /** * Load some assets for the appropriate pages in admin * * @since 1.0 */ public function admin_assets() { $screen = get_current_screen(); $pages = array( 'settings_page_lasso-editor-settings', 'settings_page_lasso-editor-settings-network', 'dashboard_page_lasso-welcome-screen' ); foreach ( $pages as $page ) { wp_enqueue_media(); wp_enqueue_style( 'wp-color-picker'); wp_enqueue_script( 'wp-color-picker'); wp_enqueue_script( 'lasso-editor-settings-script', LASSO_URL.'/admin/assets/js/lasso-editor-settings.js', array( 'jquery','wp-color-picker' ), LASSO_VERSION, true ); wp_enqueue_style( 'lasso-editor-settings-style', LASSO_URL.'/admin/assets/css/lasso-editor-settings.css', LASSO_VERSION ); } } /** * Add some custom links to the plugins.php page * * @since 0.8.8 * @param unknown $links array array of new links * @param unknown $file * * @return array new array of links for our plugin listing on plugins.php */ public function plugin_meta( $links, $file ) { if ( strpos( $file, 'lasso.php' ) !== false && !defined( 'LASSO_AGENCY_MODE' ) ) { $new_links = array( 'Help' ); $links = array_merge( $links, $new_links ); } return $links; } /** * Adds an admin notice reminding the user if their license key has not been saved * * @since 0.9.7 * @todo make dismissible */ public function license_nag(){ $screen = get_current_screen(); $welcome = 'toplevel_page_lasso-editor' == $screen->id; $license = get_option( 'lasso_license_key' ); $status = get_option( 'lasso_license_status' ); $message_empty = apply_filters('lasso_empty_license_message','Your license key for support and automatic updates for Editus is missing!'); $message_invalid = apply_filters('lasso_invalid_license_message','Oh snap! It looks like your Editus license key is invalid. Might check here to see if its been added correctly.'); $message_inactive = apply_filters('lasso_inactive_license_message','It looks like your license key has not yet been activated.'); $license_link = sprintf('Update License', esc_url( add_query_arg( array( 'page' => 'lasso-license' ), admin_url('admin.php') ) ) ); $dismiss_link = sprintf('%s', esc_url( add_query_arg( 'lasso-notice', 'dismiss' ) ), __('Dismiss this notice.','lasso') ); $not_hidden = get_user_meta( get_current_user_ID(), 'lasso_license_nag_dismissed', true ); if ( current_user_can('manage_options') && !$welcome && !defined( 'LASSO_AGENCY_MODE') && !$not_hidden ) { if ( empty( $license ) ) { printf('

%s %s

%s
', $message_empty, $license_link, $dismiss_link ); } else if ( 'invalid' == $status ){ // license key entered wrong or something printf('

%s %s

%s
', $message_invalid, $license_link , $dismiss_link ); } else if ( empty( $status ) ){ // license key saved but not activated printf('

%s %s

%s
', $message_inactive, $license_link, $dismiss_link ); } } } /** * Process hiding the dimiss * * @since 0.9.7 */ public function dismiss_nag() { if ( isset( $_GET['lasso-notice'] ) && 'dismiss' == $_GET['lasso-notice'] && current_user_can('manage_options') ) { update_user_meta( get_current_user_id(), 'lasso_license_nag_dismissed', 1 ); } } } ================================================ FILE: admin/includes/menus/license.php ================================================ LASSO_VERSION, 'license' => $license_key, 'item_name' => LASSO_STORE_ITEM_NAME, 'author' => __( 'Aesopinteractive LLC', 'lasso' ) ) ); } function license_menu() { // CHANGED Removed condition. add_submenu_page( 'lasso-editor', __( 'License Key', 'lasso' ), __( 'License', 'lasso' ), 'manage_options', 'lasso-license', array( $this, 'license_page' ) ); } function license_page() { $license = get_option( 'lasso_license_key' ); $status = get_option( 'lasso_license_status' ); ?>

', esc_html__( 'Upgrade message from the plugin author:', 'tgmpa' ), ' ', wp_kses_data( $item['upgrade_notice'] ), '
'activate_license', 'license' => $license, 'item_name' => urlencode( LASSO_STORE_ITEM_NAME ), // the name of our product in EDD 'url' => home_url() ); // Call the custom API. $response = wp_remote_post( LASSO_STORE_URL, array( 'body' => $api_params, 'timeout' => 15, 'sslverify' => false ) ); // make sure the response came back okay if ( is_wp_error( $response ) ) return false; // decode the license data $license_data = json_decode( wp_remote_retrieve_body( $response ) ); // $license_data->license will be either "valid" or "invalid" update_option( 'lasso_license_status', $license_data->license ); } } function deactivate_license() { // listen for our activate button to be clicked if ( isset( $_POST['edd_license_deactivate'] ) ) { // run a quick security check if ( ! check_admin_referer( 'lasso_license_nonce', 'lasso_license_nonce' ) ) return; // get out if we didn't click the Activate button // retrieve the license from the database $license = trim( get_option( 'lasso_license_key' ) ); // data to send in our API request $api_params = array( 'edd_action'=> 'deactivate_license', 'license' => $license, 'item_name' => urlencode( LASSO_STORE_ITEM_NAME ), // the name of our product in EDD 'url' => home_url() ); // Call the custom API. $response = wp_remote_post( LASSO_STORE_URL, array( 'body' => $api_params, 'timeout' => 15, 'sslverify' => false ) ); // make sure the response came back okay if ( is_wp_error( $response ) ) return false; // decode the license data $license_data = json_decode( wp_remote_retrieve_body( $response ) ); // $license_data->license will be either "deactivated" or "failed" if ( $license_data->license == 'deactivated' ) delete_option( 'lasso_license_status' ); } } // check status of license function check_license() { global $wp_version; $license = trim( get_option( 'lasso_license_key' ) ); $api_params = array( 'edd_action' => 'check_license', 'license' => $license, 'item_name' => urlencode( LASSO_STORE_ITEM_NAME ), 'url' => home_url() ); // Call the custom API. $response = wp_remote_post( LASSO_STORE_URL, array( 'body' => $api_params, 'timeout' => 15, 'sslverify' => false ) ); if ( is_wp_error( $response ) ) return false; $license_data = json_decode( wp_remote_retrieve_body( $response ) ); if ( $license_data->license == 'valid' ) { echo 'valid'; exit; // this license is still valid } else { echo 'invalid'; exit; // this license is no longer valid } } } ================================================ FILE: admin/includes/menus/settings.php ================================================ '."\n"; echo ''; echo ''; echo "\n"; } /** * Draw the settings form * * @since 1.0 */ function lasso_editor_settings_form() { if ( !is_user_logged_in() ) return; // check for lasso story engine and add a class doniting this $ase_status = class_exists( 'Aesop_Core' ) || defined( 'LASSO_CUSTOM' ) ? 'ase-active' : 'ase-not-active'; $article_object = lasso_editor_get_option( 'article_class', 'lasso_editor' ); $featImgClass = lasso_editor_get_option( 'featimg_class', 'lasso_editor' ); $titleClass = lasso_editor_get_option( 'title_class', 'lasso_editor' ); $post_new_disabled = lasso_editor_get_option( 'post_adding_disabled', 'lasso_editor' ); $save_to_post_disabled = lasso_editor_get_option( 'post_save_disabled', 'lasso_editor' ); $edit_post_disabled = lasso_editor_get_option( 'post_edit_disabled', 'lasso_editor' ); $post_settings_disabled = lasso_editor_get_option( 'post_settings_disabled', 'lasso_editor' ); $allow_change_date = lasso_editor_get_option( 'allow_change_date', 'lasso_editor' ); $allow_edit_excerpt = lasso_editor_get_option( 'allow_edit_excerpt', 'lasso_editor' ); $allow_new_category = lasso_editor_get_option( 'allow_new_category', 'lasso_editor' ); $shortcodify_disabled = lasso_editor_get_option( 'shortcodify_disabled', 'lasso_editor' ); $enable_autosave = lasso_editor_get_option( 'enable_autosave', 'lasso_editor' ); $disable_shortcode_editing = lasso_editor_get_option('disable_shortcode_editing', 'lasso_editor'); $use_old_ui = lasso_editor_get_option( 'use_old_ui', 'lasso_editor' ); $toolbar_headings = lasso_editor_get_option( 'toolbar_headings', 'lasso_editor' ); $toolbar_headings_h4 = lasso_editor_get_option( 'toolbar_headings_h4', 'lasso_editor' ); $toolbar_list = lasso_editor_get_option( 'toolbar_list', 'lasso_editor' ); $toolbar_show_color = lasso_editor_get_option( 'toolbar_show_color', 'lasso_editor' ); $toolbar_show_alignment = lasso_editor_get_option( 'toolbar_show_alignment', 'lasso_editor' ); $text_select_popup = lasso_editor_get_option('text_select_popup', 'lasso_editor', false); $objectsNoSave = lasso_editor_get_option('dont_save', 'lasso_editor'); $objectsNonEditable = lasso_editor_get_option('non_editable', 'lasso_editor'); $disable_tour = lasso_editor_get_option('disable_tour', 'lasso_editor'); $show_ignored_items = lasso_editor_get_option('show_ignored_items', 'lasso_editor'); $save_using_rest_disabled = lasso_editor_get_option('save_using_rest_disabled', 'lasso_editor'); $default_post_types = apply_filters( 'lasso_allowed_post_types', array( 'post', 'page')); $allowed_post_types = lasso_editor_get_option( 'allowed_post_types', 'lasso_editor', $default_post_types); $links_editable = lasso_editor_get_option('links_editable', 'lasso_editor', false); $bold_tag = lasso_editor_get_option( 'bold_tag', 'lasso_editor', "b"); $i_tag = lasso_editor_get_option( 'i_tag', 'lasso_editor', "i"); $add_table = lasso_editor_get_option('add_table', 'lasso_editor', false); $add_paragraph = lasso_editor_get_option('add_paragraph', 'lasso_editor', false); // do we support pending status $no_pending_status = lasso_editor_get_option('no_pending_status', 'lasso_editor'); $no_url_setting = lasso_editor_get_option('no_url_setting', 'lasso_editor'); $insert_comp_ui = lasso_editor_get_option('insert_comp_ui', 'lasso_editor'); if (!$insert_comp_ui) { $insert_comp_ui = 'drag'; } $link_prefix_http = lasso_editor_get_option('link_prefix_http', 'lasso_editor'); $inherit_categories = lasso_editor_get_option('inherit_categories', 'lasso_editor'); $use_old_wpimg = lasso_editor_get_option('use_old_wpimg', 'lasso_editor','off'); $use_wp_block_image = lasso_editor_get_option('use_wp_block_image', 'lasso_editor','off'); $support_custom_taxonomy = lasso_editor_get_option( 'support_custom_taxonomy', 'lasso_editor' ); $new_post_text = lasso_editor_get_option( 'new_post_text', 'lasso_editor' ); $no_wrap_shortcode = lasso_editor_get_option( 'no_wrap_shortcode', 'lasso_editor'); ?>

true ); $allowed_post_types = apply_filters( 'lasso_allowed_post_types', $allowed_post_types ); $post_types = get_post_types( $args, 'objects' ); foreach ( $post_types as $post_type ) { if ($post_type->name == 'attachment') continue; $checked =""; if ( in_array( $post_type->name, $allowed_post_types ) ) { $checked = 'checked="checked"'; } echo ''; } ?>

>

>
>
>
>
>
>
>
>
>
>
>

>
>
>
>

>
>
>
>
>
>
>
>

>
>
> b > strong
> i > em
>
>

>
>
>
> here for more information. The custom fields you specify will be still editable under the editing mode.', 'lasso' );?>
>
>
'lasso-editor' ), admin_url( 'admin.php' ) ) ) ); } /** * Add dashboard pages for welcome and welcome back * * @since 0.8 */ function lasso_welcome() { // CHANGED Removed condition. add_menu_page( __( 'Editus', 'lasso' ), __( 'Editus', 'lasso' ), 'manage_options', 'lasso-editor', '', LASSO_URL.'/admin/assets/img/menu-icon.png' ); add_submenu_page( 'lasso-editor', __( 'Welcome', 'lasso' ), __( 'Status', 'lasso' ), 'manage_options', 'lasso-editor', array( $this, 'welcome' ) ); } /** * Callback for the intial welcome screen for new users * * @since 0.8.2 */ function welcome() { ?>
  • $check ) { echo $check; } else: // pre-flight is go for flight ?>

'.LASSO_VERSION.'';?>

get('Name'); $theme_class = lasso_get_supported_theme_class(); $license = get_option( 'lasso_license_key' ); $status = get_option( 'lasso_license_status' ); // if the required CSS class has not been saved if ( empty( $article_object ) && false == $theme_class ) { // we dont automatically support this theme so show them otherwise $notices[] = sprintf('
  • '.__( 'Article CSS Class Needed!', 'lasso' ).'

    '.__( 'Before using Editus,', 'lasso' ).' '.__( 'enter and save', 'lasso' ).' '.__( 'the CSS class of the container that holds your post and page content. You can use a tool like inspector in Chrome or Firefox to find this CSS class, or ', 'lasso' ).' '.__( 'email us.', 'lasso' ).' '.__( 'with a link to a public URL with the theme and we\'ll find it for you.', 'lasso' ).'

  • ', admin_url( 'admin.php?page=lasso-editor-settings' ) ); } // WP REST API not active if ( !function_exists( 'json_get_url_prefix' ) && !function_exists( 'rest_url' )) { $notices[] = '
  • WP REST API not Activated!

    '.__( 'Just a heads up that the WP REST API isn\'t activated. This is required to list the posts and pages on the front-end.', 'lasso' ).'

  • '; } // aesop story engine isnt active if ( !class_exists( 'Aesop_Core' ) ) { $notices[] = sprintf( '
  • Aesop Story Engine not Activated!

    '.__( 'Just a heads up that ', 'lasso' ).''.__( 'Aesop Story Engine', 'lasso' ).' '.__( 'isn\'t activated. It\'s not required to use Editus, but you won\'t get the cool drag and drop components without it activated. It\'s free!', 'lasso' ).'

  • ', admin_url('plugin-install.php?tab=search&s=aesop+story+engine') ); } // we dont really get along with wp side comments because of the section ids that get applied dynamically. since we save our html, it'll get saved along with the post as HTML if ( class_exists( 'WP_Side_Comments' ) ) { $notices[] = '
  • '.__( 'WP Side Comments Compatibility Warning!', 'lasso' ).'

    '.__( 'Since Editus saves the HTML of a post, this may cause undesired issues. We\'re working to resolve incompatibilities faster than a jack rabbit in a hot greasy griddle in the middle of August.', 'lasso' ).'

  • '; } // if the license key isnt activated if ( empty( $license ) ) { $notices[] = '
  • '.__( 'License Key Not Activated', 'lasso' ).'

    '.__( 'Just a heads up, your license key isn\'t activated. Enter your license key into the License tab on the left in order to receive plugin update notifications.', 'lasso' ).'

  • '; } if ( !empty( $license ) && 'invalid' == $status ) { $notices[] = '
  • '.__( 'License Key Invalid', 'lasso' ).'

    '.__( 'The license key that you entered is ', 'lasso' ).''.__( 'invalid', 'lasso' ).''.__( '. It may have been entered incorreclty, or may have expired.', 'lasso' ).'

  • '; } return apply_filters( 'lasso_preflight_notices', $notices ); } /** * Register the required plugins for this theme. * * @since 0.9.3 */ function required_plugins() { $plugins = array( array( 'name' => __('Aesop Story Engine','lasso'), 'slug' => 'aesop-story-engine', 'required' => false, ), ); $config = array( 'default_path' => '', // Default absolute path to pre-packaged plugins. 'menu' => 'lasso-install-plugins', // Menu slug. 'has_notices' => true, // Show admin notices or not. 'dismissable' => true, // If false, a user cannot dismiss the nag message. 'dismiss_msg' => '', // If 'dismissable' is false, this message will be output at top of nag. 'is_automatic' => false, // Automatically activate plugins after installation or not. 'message' => '', // Message to output right before the plugins table. 'strings' => array( 'page_title' => __( 'Install Required Plugins', 'lasso' ), 'menu_title' => __( 'Install Plugins', 'lasso' ), 'installing' => __( 'Installing Plugin: %s', 'lasso' ), // %s = plugin name. 'oops' => __( 'Something went wrong with the plugin API.', 'lasso' ), 'notice_can_install_required' => _n_noop( 'This plugin requires the following plugin: %1$s.', 'This plugin requires the following plugins: %1$s.' ), // %1$s = plugin name(s). 'notice_can_install_recommended' => _n_noop( 'This plugin recommends the following plugin: %1$s.', 'This plugin recommends the following plugins: %1$s.' ), // %1$s = plugin name(s). 'notice_cannot_install' => _n_noop( 'Sorry, but you do not have the correct permissions to install the %s plugin. Contact the administrator of this site for help on getting the plugin installed.', 'Sorry, but you do not have the correct permissions to install the %s plugins. Contact the administrator of this site for help on getting the plugins installed.' ), // %1$s = plugin name(s). 'notice_can_activate_required' => _n_noop( 'The following required plugin is currently inactive: %1$s.', 'The following required plugins are currently inactive: %1$s.' ), // %1$s = plugin name(s). 'notice_can_activate_recommended' => _n_noop( 'The following recommended plugin is currently inactive: %1$s.', 'The following recommended plugins are currently inactive: %1$s.' ), // %1$s = plugin name(s). 'notice_cannot_activate' => _n_noop( 'Sorry, but you do not have the correct permissions to activate the %s plugin. Contact the administrator of this site for help on getting the plugin activated.', 'Sorry, but you do not have the correct permissions to activate the %s plugins. Contact the administrator of this site for help on getting the plugins activated.' ), // %1$s = plugin name(s). 'notice_ask_to_update' => _n_noop( 'The following plugin needs to be updated to its latest version to ensure maximum compatibility with this plugin: %1$s.', 'The following plugins need to be updated to their latest version to ensure maximum compatibility with this plugin: %1$s.' ), // %1$s = plugin name(s). 'notice_cannot_update' => _n_noop( 'Sorry, but you do not have the correct permissions to update the %s plugin. Contact the administrator of this site for help on getting the plugin updated.', 'Sorry, but you do not have the correct permissions to update the %s plugins. Contact the administrator of this site for help on getting the plugins updated.' ), // %1$s = plugin name(s). 'install_link' => _n_noop( 'Begin installing plugin', 'Begin installing plugins' ), 'activate_link' => _n_noop( 'Begin activating plugin', 'Begin activating plugins' ), 'return' => __( 'Return to Required Plugins Installer', 'lasso' ), 'plugin_activated' => __( 'Plugin activated successfully.', 'lasso' ), 'complete' => __( 'All plugins installed and activated successfully. %s', 'lasso' ), // %s = dashboard link. 'nag_type' => 'updated' // Determines admin notice type - can only be 'updated', 'update-nag' or 'error'. ) ); $plugins = apply_filters( 'lasso_required_plugins', $plugins ); tgmpa( $plugins, $config ); } } ================================================ FILE: bootstrap.php ================================================ * @license GPL-2.0+ */ /*----------------------------------------------------------------------------* * Register Autoloader *----------------------------------------------------------------------------*/ include_once( LASSO_DIR . '/includes/lasso_autoloader.php' ); $loader = new lasso_autoloader(); $loader->register(); /*----------------------------------------------------------------------------* * Public-Facing Functionality *----------------------------------------------------------------------------*/ //require_once plugin_dir_path( __FILE__ ) . 'public/class-lasso.php'; $loader->addNamespace('lasso', LASSO_DIR . 'includes' ); $loader->addNamespace('lasso_public_facing', LASSO_DIR . 'public/includes' ); $loader->addNamespace('lasso\internal_api', LASSO_DIR . 'internal-api' ); new lasso\internal_api\end_points(); register_activation_hook( __FILE__, array( 'lasso_public_facing\lasso', 'activate' ) ); register_deactivation_hook( __FILE__, array( 'lasso_public_facing\lasso', 'deactivate' ) ); add_action( 'plugins_loaded', array( 'lasso_public_facing\lasso', 'get_instance' ) ); //load tour add_action( 'init', function() { if (! is_admin() && is_user_logged_in() ) { new \lasso_public_facing\tour(); } }); /*----------------------------------------------------------------------------* * Dashboard and Administrative Functionality *----------------------------------------------------------------------------*/ if ( is_admin() ) { $loader->addNamespace('lasso_admin', LASSO_DIR . 'admin/includes' ); add_action( 'plugins_loaded', array( 'lasso_admin\load_admin', 'get_instance' ) ); } ================================================ FILE: composer.json ================================================ { "name": "aesop/lasso", "type": "wordpress-plugin", "description": "Lasso Front-end Creator", "homepage": "http://edituswp.com", "license": "GPL-2.0+", "keywords": ["plugin","wordpress","lasso","editor","hosted"], "support": { "issues": "https://github.com/AesopInteractive/lasso/issues" }, "require": { "composer/installers": "~1.0.6" } } ================================================ FILE: includes/lasso_autoloader.php ================================================ * @license GPL-2.0+ */ class lasso_autoloader { /** * An associative array where the key is a namespace prefix and the value * is an array of base directories for classes in that namespace. * * @var array */ protected $prefixes = array(); /** * Register loader with SPL autoloader stack. * * @return void */ public function register() { spl_autoload_register(array($this, 'loadClass')); } /** * Adds a base directory for a namespace prefix. * * @param string $prefix The namespace prefix. * @param string $base_dir A base directory for class files in the * namespace. * @param bool $prepend If true, prepend the base directory to the stack * instead of appending it; this causes it to be searched first rather * than last. * @return void */ public function addNamespace($prefix, $base_dir, $prepend = false) { // normalize namespace prefix $prefix = trim($prefix, '\\') . '\\'; // normalize the base directory with a trailing separator $base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/'; // initialize the namespace prefix array if (isset($this->prefixes[$prefix]) === false) { $this->prefixes[$prefix] = array(); } // retain the base directory for the namespace prefix if ($prepend) { array_unshift($this->prefixes[$prefix], $base_dir); } else { array_push($this->prefixes[$prefix], $base_dir); } } /** * Loads the class file for a given class name. * * @param string $class The fully-qualified class name. * @return mixed The mapped file name on success, or boolean false on * failure. */ public function loadClass($class) { // the current namespace prefix $prefix = $class; // work backwards through the namespace names of the fully-qualified // class name to find a mapped file name while (false !== $pos = strrpos($prefix, '\\')) { // retain the trailing namespace separator in the prefix $prefix = substr($class, 0, $pos + 1); // the rest is the relative class name $relative_class = substr($class, $pos + 1); // try to load a mapped file for the prefix and relative class $mapped_file = $this->loadMappedFile($prefix, $relative_class); if ($mapped_file) { return $mapped_file; } // remove the trailing namespace separator for the next iteration // of strrpos() $prefix = rtrim($prefix, '\\'); } // never found a mapped file return false; } /** * Load the mapped file for a namespace prefix and relative class. * * @param string $prefix The namespace prefix. * @param string $relative_class The relative class name. * @return mixed Boolean false if no mapped file can be loaded, or the * name of the mapped file that was loaded. */ protected function loadMappedFile($prefix, $relative_class) { // are there any base directories for this namespace prefix? if (isset($this->prefixes[$prefix]) === false) { return false; } // look through base directories for this namespace prefix foreach ($this->prefixes[$prefix] as $base_dir) { // replace the namespace prefix with the base directory, // replace namespace separators with directory separators // in the relative class name, append with .php $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; // if the mapped file exists, require it if ($this->requireFile($file)) { // yes, we're done return $file; } } // never found it return false; } /** * If a file exists, require it from the file system. * * @param string $file The file to require. * @return bool True if the file exists, false if not. */ protected function requireFile($file) { if (file_exists($file)) { require $file; return true; } return false; } } ================================================ FILE: includes/process/delete.php ================================================ (int) $postid, 'post_status' => 'trash' ); wp_update_post( apply_filters( 'lasso_object_deleted_args', $args ) ); do_action( 'lasso_object_deleted', $postid, get_current_user_ID() ); return true; } /** * The keys required for the actions of this class. * * @since 0.9.2 * * @return array Array of keys to pull from $_POST per action and their sanitization callback */ public static function params(){ $params[ 'process_delete_post' ] = array( 'postid' => 'absint', ); return $params; } /** * Additional auth callbacks to check. * * @since 0.9.2 * * @return array Array of additional functions to use to authorize action. */ public static function auth_callbacks() { $params[ 'process_delete_post' ] = array( 'lasso_user_can' ); return $params; } } ================================================ FILE: includes/process/gallery.php ================================================ %s', $id, __( 'Save and refresh to view gallery.','lasso' ) ); return array( 'gallery' => $markup ); } /** * Creates a gallery * * @since 0.9.2 * * @param array $data Sanitized data to use for saving. * * @return array|bool On success an array containing "message" or on failure false. */ public function create( $data ) { //@todo adapt auth callbacks to work with args. if ( ! lasso_user_can( 'publish_posts' ) ) { return false; } $gallery_ids = isset( $data['gallery_ids'] ) ? $data['gallery_ids'] : false; // bail if no gallery ids if ( empty( $gallery_ids ) ) { return false; } $postid = isset( $data['postid'] ) ? (int) $data['postid'] : false; $type = isset( $data['gallery_type'] ) ? $data['gallery_type'] : false; $edgallerytitle = isset( $data['edgallerytitle'] ) ? $data['edgallerytitle'] : $postid.'-'.rand(); // insert a new gallery $args = array( 'post_title' => $edgallerytitle , 'post_status' => 'publish', 'post_type' => 'ai_galleries' ); $postid = wp_insert_post( apply_filters( 'lasso_insert_gallery_args', $args ) ); // update gallery ids if ( $gallery_ids ) { update_post_meta( $postid, '_ase_gallery_images', $gallery_ids ); } // update the gallery type if ( !empty( $type ) ) { update_post_meta( $postid, 'aesop_gallery_type', $type ); } do_action( 'lasso_gallery_published', $postid, $gallery_ids, get_current_user_ID() ); return array( 'message' => 'gallery-created', 'id' => $postid ); } /** * Update an existing gallery * * @since 0.9.2 * * @param array $data Sanitized data to use for saving. * * @return array "message" key has the message. */ public function update( $data ) { $options = isset( $data['fields'] ) ? $data['fields'] : false; $postid = !empty( $options ) ? (int) $options['id'] : false; $gallery_ids = isset( $data['gallery_ids'] ) ? $data['gallery_ids'] : false; if ( ! empty( $data ) && $data[ 'gallery_type' ] ) { $type = $data[ 'gallery_type' ]; }elseif ( ! empty( $options ) && $options[ 'galleryType' ] ) { $type = $options[ 'galleryType' ]; }else{ $type = false; } save_gallery::save_gallery_options( $postid, $gallery_ids, $options, $type ); return array( 'message' => 'gallery-updated' ); } /** * When the user clicks the settings icon in the gallery component it * opens the panel, gets the gallery unique, then makes a call to get the gallery images * * @since 0.12 * * @param array $data Sanitized data to use for saving. * * @return bool */ public function get_images( $data ) { //check caps if ( !current_user_can( 'edit_posts' ) ) { return false; } // bail if no id specified like on new galleries if ( is_null( $data['post_id'] ) || empty( $data['post_id'] ) ) { return false; } $postid = isset( $data['post_id'] ) ? $data['post_id'] : false; // fetch image ids from cache $image_ids = get_post_meta( $postid, '_ase_gallery_images', true ); // send ids to return images return self::get_the_images( $image_ids ); } /** * Return images for a specific gallery when the user goes to edit a gallery * * @param $image_ids array array of image ids * @since 0.1 */ private function get_the_images( $image_ids = '' ) { if ( empty( $image_ids ) ) return; $image_ids = array_map( 'intval', explode( ',', $image_ids ) ); $out[] = ''; return array( 'html' => implode( '', $out ) ); } /** * The keys required for the actions of this class. * * @since 0.9.2 * * @return array Array of keys to pull from $data per action and their sanitization callback */ public static function params(){ $params[ 'process_gallery_swap' ] = array( 'gallery_id' => 'absint', ); $params[ 'process_gallery_create' ] = array( 'postid' => 'absint', 'content' => 'wp_kses_post', 'edgallerytitle' =>'sanitize_text_field', 'gallery_type' => array( 'sanitize_text_field', 'trim' ), 'gallery_ids' => 'lasso_sanitize_data', ); $params[ 'process_gallery_update' ] = array( 'postid' => 'absint', 'gallery_ids' => 'lasso_sanitize_data', 'fields' => 'lasso_sanitize_data', 'gallery_type' => array( 'sanitize_text_field', 'trim' ) ); $params[ 'process_gallery_get_images' ] = array( 'post_id' => 'absint' ); return $params; } /** * Additional auth callbacks to check. * * @since 0.9.2 * * @return array Array of additional functions to use to authorize action. */ public static function auth_callbacks() { $params[ 'process_gallery_swap' ] = array( 'lasso_user_can' ); $params[ 'process_gallery_create' ] = array( 'is_user_logged_in' ); $params[ 'process_gallery_update' ] = array( 'lasso_user_can' ); $params[ 'process_gallery_get_images' ] = array(); return $params; } } ================================================ FILE: includes/process/map.php ================================================ 'absint', 'ase-map-component-locations' => 'lasso_sanitize_data', 'ase-map-component-start-point' => array( 'json_decode', 'urldecode' ), 'ase-map-component-zoom' => array( 'json_decode', 'urldecode' ) ); return $params; } /** * Additional auth callbacks to check. * * @since 0.9.2 * * @return array Array of additional functions to use to authorize action. */ public static function auth_callbacks() { $params[ 'process_map_save' ] = array( 'lasso_user_can' ); return $params; } } ================================================ FILE: includes/process/meta.php ================================================ 'absint', 'tab_name' => 'trim' ); return $params; } /** * Additional auth callbacks to check. * * @since 0.9.5 * * @return array Array of additional functions to use to authorize action. */ public static function auth_callbacks() { $params[ 'process_meta_update' ] = array( 'lasso_user_can' ); return $params; } } ================================================ FILE: includes/process/new_object.php ================================================ $title, 'post_status' => 'draft', 'post_type' => $object, 'post_content' =>'

    ' ); $postid = wp_insert_post( apply_filters( 'lasso_insert_object_args', $args ) ); do_action( 'lasso_new_object', $postid, $object, $title, get_current_user_ID() ); return array( 'postlink' => get_permalink( $postid ) ); } /** * The keys required for the actions of this class. * * @since 0.9.2 * * @return array Array of keys to pull from $_POST per action and their sanitization callback */ public static function params() { $params[ 'process_new_object_post' ] = array( 'story_title' => array( 'wp_strip_all_tags', 'trim' ), 'object' => 'trim' ); return $params; } /** * Additional auth callbacks to check. * * @since 0.9.2 * * @return array Array of additional functions to use to authorize action. */ public static function auth_callbacks() { $params[ 'process_new_object_post' ] = array(); return $params; } } ================================================ FILE: includes/process/revision.php ================================================ $post->post_content, 'post_title' => $post->post_title, 'modified_time' => mysql2date('g:i a', $post->post_modified), 'modified_date' => mysql2date('F j, Y', $post->post_modified) ); } ); } /** * The keys required for the actions of this class. * * @since 0.9.5 * * @return array Array of keys to pull from $_POST per action and their sanitization callback */ public static function params(){ $params[ 'process_revision_get' ] = array( 'postid' => 'absint', 'limit' => 'absint' ); return $params; } /** * Additional auth callbacks to check. * * @since 0.9.5 * * @return array Array of additional functions to use to authorize action. */ public static function auth_callbacks() { $params[ 'process_revision_get' ] = array( 'lasso_user_can' ); return $params; } } ================================================ FILE: includes/process/save.php ================================================ save_to_post_disables(); $postid = (int) $data[ 'post_id' ]; $content = $this->replace_rendered_shortcodes( $data[ 'content' ] ); $content = $this->remove_comments( $content ); if ( 'off' == $save_to_post_disabled || empty( $save_to_post_disabled ) ) { $args = array( 'ID' => (int) $postid, 'post_content' => $content ); wp_update_post( apply_filters( 'lasso_object_save_args', $args ) ); } // run save action do_action( 'lasso_post_saved', $postid, $content, get_current_user_ID() ); return true; } /** * Process the post save * * @since 0.9.2 * * @param array $data Sanitized data to use for saving. * * @return bool Always returns true. */ public function publish_content( $data ) { $save_to_post_disabled = $this->save_to_post_disables(); $postid = (int) $data[ 'post_id' ]; $content = $this->replace_rendered_shortcodes( $data[ 'content' ] ); $content = $this->remove_comments( $content ); if ( 'off' == $save_to_post_disabled || empty( $save_to_post_disabled ) ) { $args = array ( 'ID' => $postid, 'post_content' => $content, 'post_status' => 'publish' ); wp_update_post( apply_filters( 'lasso_object_publish_args', $args ) ); } do_action( 'lasso_post_published', $postid, $content, get_current_user_ID() ); return true; } /** * The keys required for the actions of this class. * * @since 0.9.2 * * @return array Array of keys to pull from $_POST per action and their sanitization callback */ public static function params(){ $params[ 'process_save_content' ] = array( 'post_id' => 'absint', 'content' => 'wp_kses_post' ); $params[ 'process_save_publish_content' ] = array( 'post_id' => 'absint', 'content' => 'wp_kses_post' ); return $params; } /** * Additional auth callbacks to check. * * @since 0.9.2 * * @return array Array of additional functions to use to authorize action. */ public static function auth_callbacks() { $params[ 'process_save_content' ] = array( 'lasso_user_can' ); $params[ 'process_save_publish_content' ] = array(); return $params; } /** * Check if saving post is disabled. * * @since 0.9.2 * * @access protected * * @return bool */ protected function save_to_post_disables() { $save_to_post_disabled = lasso_editor_get_option( 'post_save_disabled', 'lasso_editor' ); return $save_to_post_disabled; } /** * Replace shortcodes from other plugins with shortcode tags. * * @since 0.9.9 * * @access protected * * @param string $content * * @return string */ protected function replace_rendered_shortcodes( $content ) { //debug line //file_put_contents(WP_PLUGIN_DIR."/file1.txt", $content); if ( false === strpos( $content, '--EDITUS_OTHER_SHORTCODE_START|' ) ) { return $content; } $content = htmlspecialchars_decode ($content); $content = preg_replace( '/(.*?)/s', '$1', $content ); return $content; } protected function remove_comments($content) { return preg_replace('//Uis', '', $content); } } ================================================ FILE: includes/process/title_update.php ================================================ (int) $postid, 'post_title' => wp_strip_all_tags( $title ) ); wp_update_post( apply_filters( 'lasso_title_updated_args', $args ) ); do_action( 'lasso_title_updated', $postid, $title, get_current_user_ID() ); return true; } /** * The keys required for the actions of this class. * * @since 0.9.2 * * @return array Array of keys to pull from $data per action and their sanitization callback */ public static function params(){ $params[ 'process_title_update_post' ] = array( 'postid' => 'absint', 'title' => 'strip_tags' ); return $params; } /** * Additional auth callbacks to check. * * @since 0.9.2 * * @return array Array of additional functions to use to authorize action. */ public static function auth_callbacks() { $params[ 'process_title_update_post' ] = array( 'lasso_user_can' ); return $params; } } ================================================ FILE: includes/process/tour.php ================================================ (int) $postid, 'post_name' => $slug, 'post_status' => $status ); wp_update_post( apply_filters( 'lasso_object_status_update_args', $args ) ); // update categories $cats = isset( $data['story_cats'] ) ? $data['story_cats'] : false; self::set_post_terms( $postid, $cats, 'category' ); // update tags $tags = isset( $data['story_tags'] ) ? $data['story_tags'] : false; self::set_post_terms( $postid, $tags, 'post_tag' ); // update custom taxonomy $taxs = isset( $data['story_custom_taxonomy'] ) ? $data['story_custom_taxonomy'] : false; self::set_custom_taxonomy( $postid, $taxs ); //update date $date = isset( $data['post_date'] ) ? $data['post_date'] : false; self::set_date( $postid, $date ); do_action( 'lasso_post_updated', $postid, $slug, $status, get_current_user_ID() ); return true; } /** * The keys required for the actions of this class. * * @since 0.9.2 * * @return array Array of keys to pull from $_POST per action and their sanitization callback */ public static function params(){ $params[ 'process_update_object_post' ] = array( 'postid' => 'absint', 'status' => 'strip_tags', 'story_slug' => array( 'trim', 'sanitize_title' ), 'story_cats' => array( 'trim', 'strip_tags', ), 'story_tags' => array( 'trim', 'strip_tags', ), 'story_custom_taxonomy' => array( 'trim', 'strip_tags', ), 'post_date' => array( 'trim', 'strip_tags', ), ); return $params; } /** * Additional auth callbacks to check. * * @since 0.9.2 * * @return array Array of additional functions to use to authorize action. */ public static function auth_callbacks() { $params[ 'process_update_object_post' ] = array( 'lasso_user_can' ); return $params; } /** * Update terms for post. * * @since 0.9.3 * * @param int $postid The current postid * @param string|bool $value The term slug, or a comma separated list of slugs. Or false to remove all terms set for post. * @param string $taxonomy The name of the taxonomy to which the term belongs. * * @return bool True if update was successful, false if not. */ public function set_post_terms( $postid, $value, $taxonomy ) { if( $value ) { // first check if multiple, make array if so. if ( self::has_multiple_objects( $value ) ) { $value = explode( ',', $value ); } if ($taxonomy =='category') { // convert from names to category ids $cats = array(); if (is_array($value)) { foreach ($value as $cat) { $cats [] = get_cat_ID($cat); } $value = $cats; } else { $value = get_cat_ID($value); } } $result = wp_set_object_terms( $postid, $value, $taxonomy ); } else { //remove all terms from post $result = wp_set_object_terms( $postid, null, $taxonomy ); } if ( ! is_wp_error( $result ) ) { return true; }else{ return false; } } /** * Update terms for post. * * * @param int $postid The current postid * @param string|bool $value The term slug, or a comma separated list of slugs. Or false to remove all terms set for post. * The first item is the name of taxonomy * * @return bool True if update was successful, false if not. */ public function set_custom_taxonomy( $postid, $value) { if( $value ) { // first check if multiple, make array if so. if ( self::has_multiple_objects( $value ) ) { $value = explode( ',', $value ); } // Deleting first array item $taxonomy = array_shift($value); $cats = array(); foreach ($value as $cat) { $cats [] = get_cat_ID($cat); } $value = $cats; $result = wp_set_object_terms( $postid, $cats, $taxonomy ); if ( ! is_wp_error( $result ) ) { return true; }else{ return false; } } } public function set_date( $postid, $value) { if( $value ) { $time = current_time('mysql'); wp_update_post( array ( 'ID' => $postid, // ID of the post to update 'post_date' => date( 'Y-m-d H:i:s', strtotime($value) ), 'post_date_gmt' => gmdate( 'Y-m-d H:i:s', strtotime($value) ), ) ); } } /** * Determines if the given value has multiple terms by checking to see * if a comma exists in the value. * * @param string $value The value to evaluate for multiple terms. * @return bool True if there are multiple terms; otherwise, false. * @since 0.9.3 */ public function has_multiple_objects( $value ) { return 0 < strpos( $value, ',' ); } } ================================================ FILE: includes/process/upload_image.php ================================================ 'absint', 'image_id' => 'absint' ); $params[ 'process_upload_image_delete' ] = array( 'postid' => 'absint', ); return $params; } /** * Additional auth callbacks to check. * * @since 0.9.2 * * @return array Array of additional functions to use to authorize action. */ public static function auth_callbacks() { $params['process_image_upload']['process_image_delete'] = array( 'lasso_user_can' ); return $params; } } ================================================ FILE: includes/sanatize.php ================================================ * @license GPL-2.0+ * @link * @copyright 2014 Josh Pollock */ namespace lasso; class sanatize { /** * Filter input and return sanitized output * * @param mixed $input The string, array, or object to sanitize * @param array $params Additional options * * @return array|mixed|object|string|void * * @since 1.1.10 * */ public static function do_sanitize( $input, $params = array() ) { $input = stripslashes_deep( $input ); if ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) { return $input; } $output = array(); $defaults = array( 'nested' => false, 'type' => null // %s %d %f etc ); if ( !is_array( $params ) ) { $defaults[ 'type' ] = $params; $params = $defaults; } else { $params = array_merge( $defaults, (array) $params ); } if ( is_object( $input ) ) { $input = get_object_vars( $input ); $n_params = $params; $n_params[ 'nested' ] = true; foreach ( $input as $key => $val ) { $output[ self::do_sanitize( $key ) ] = self::do_sanitize( $val, $n_params ); } $output = (object) $output; } elseif ( is_array( $input ) ) { $n_params = $params; $n_params[ 'nested' ] = true; foreach ( $input as $key => $val ) { $output[ self::do_sanitize( $key ) ] = self::do_sanitize( $val, $n_params ); } } elseif ( !empty( $params[ 'type' ] ) && false !== strpos( $params[ 'type' ], '%' ) ) { /** * @var $wpdb wpdb */ global $wpdb; $output = $wpdb->prepare( $params[ 'type' ], $output ); } else { $output = wp_slash( $input ); } return $output; } /** * Filter input and return sanitized SQL LIKE output * * @param mixed $input The string, array, or object to sanitize * * @return array|mixed|object|string|void * * @since 1.1.10 * * @see like_escape */ public static function sanitize_like( $input ) { if ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) { return $input; } $output = array(); if ( is_object( $input ) ) { $input = get_object_vars( $input ); foreach ( $input as $key => $val ) { $output[ $key ] = self::sanitize_like( $val ); } $output = (object) $output; } elseif ( is_array( $input ) ) { foreach ( $input as $key => $val ) { $output[ $key ] = self::sanitize_like( $val ); } } else { global $wpdb; //backwords-compat check for pre WP4.0 if ( method_exists( 'wpdb', 'esc_like' ) ) { $output = $wpdb->esc_like( self::do_sanitize( $input ) ); } else { // like_escape is deprecated in WordPress 4.0 $output = like_escape( self::do_sanitize( $input ) ); } } return $output; } /** * Filter input and return unslashed output * * @param mixed $input The string, array, or object to unsanitize * * @return array|mixed|object|string|void * * @since 1.1.10 * * @see wp_unslash */ public static function unslash( $input ) { if ( '' === $input || is_int( $input ) || is_float( $input ) || empty( $input ) ) { return $input; } $output = array(); if ( empty( $input ) ) { $output = $input; } elseif ( is_object( $input ) ) { $input = get_object_vars( $input ); foreach ( $input as $key => $val ) { $output[ $key ] = self::unslash( $val ); } $output = (object) $output; } elseif ( is_array( $input ) ) { foreach ( $input as $key => $val ) { $output[ $key ] = self::unslash( $val ); } } else { $output = wp_unslash( $input ); } return $output; } } ================================================ FILE: includes/save_gallery.php ================================================ * @license GPL-2.0+ */ namespace lasso\internal_api; interface api_action { /** * An array, keyed by action name, of params (IE keys of $_POST) and their sanitization callback to pass back to callback. * * Function should return an array fo arrays in the form of 'POST_var' => 'sanitization_callback'. For example $params[ 'process_save_post' ] = array( 'post_id' => 'absint', 'content' => 'wp_kses_post' ); * * @since 0.9.2 * * @return array Array of keys to pull from $_POST per action */ public static function params(); /** * An array, keyed by action name, of callback functions, in addition to the nonce check, to run. * * Function should return an array of additional callback functions. For example, '$cb[ 'process_save_post' ] = array( 'lasso_user_can' ); * * @since 0.9.2 * * @return array Array of additional functions to use to authorize action. Or an empty array. */ public static function auth_callbacks(); } ================================================ FILE: internal-api/auth.php ================================================ * @license GPL-2.0+ */ namespace lasso\internal_api; class auth { /** * Instance of callback class * * @since 0.9.2 * * @access protected * * @var object|string */ protected $callback_instance; /** * Status code set based on auth checks. * * @since 0.9.2 * * @var int */ public $status_code; /** * An error message. * * @since 0.9.2 * * @var string */ public $error_message; /** * Constructor for this class * * @since 0.9.2 * * @param string $action The AJAX action we are processing. * @param string|object $callback_class The class to use for the callback. Either the name of the class or an instance of that class. * @param string $method The name of the callback method. */ public function __construct( $action, $callback_class) { if ( ! is_object( $callback_class ) ) { $this->callback_instance = new $callback_class; }else{ $this->callback_instance = $callback_class; } if ( $this->check_nonce() ) { if ( is_object( $this->callback_instance ) && $this->if_implements() ) { if ( $this->other_auth_checks( $action ) ) { $this->status_code = 200; } else { $this->error_message = __( 'Unauthorized action', 'lasso' ); $this->status_code = 401; } } else { $this->error_message = __( 'All callback classes used for processing the Editus Internal API must implement the lasso\internal_api\api_action interface.', 'lasso' ); $this->status_code = 401; } } else { $this->status_code = 401; $this->error_message = __( 'Nonce invalid', 'lasso' ); } } /** * Run other auth checks, besides nonce check as defined by the auth_callbacks() method of callback class * * @since 0.9.2 * * @access protected * * @param string $action The AJAX action we are processing. * * @return bool True if auth checks were all postive. */ protected function other_auth_checks( $action ) { $auth_callbacks = $this->callback_instance->auth_callbacks(); if ( is_array( $auth_callbacks ) && isset( $auth_callbacks[ $action ] ) && is_array( $auth_callbacks[ $action ] ) ) { $checks = $auth_callbacks[ $action ]; if ( is_array( $checks ) ) { foreach ( $checks as $check ) { if ( is_array( $check ) ) { $check = call_user_func( array( $check[0], $check[1] ) ); } else { $check = call_user_func( $check ); } if ( false === $check ) { return false; } } } } return true; } /** * Check if callback class implements the lasso\internal_api\api_action interface * * @since 0.9.2 * * @access protected * * @return bool */ protected function if_implements() { $implements = class_implements( $this->callback_instance ); if ( is_array( $implements ) && in_array( 'lasso\internal_api\api_action', $implements ) ) { return true; } } /** * Verify that the nonce is valid * * @since 0.0.1 * * @access protected * * @return bool */ protected function check_nonce() { if ( isset( $this->callback_instance->nonce_action ) ) { $nonce = $this->callback_instance->nonce_action; }else{ $nonce = 'lasso_editor'; } return wp_verify_nonce( $_POST[ 'nonce' ], $nonce ); } } ================================================ FILE: internal-api/docs.md ================================================ # How Internal API Works * All requests must be sent to the URL `home_url( 'internal-api' );`. * All requests must use the POST transport method. * Callback class and method is determined by the action (e.g. `_$POST[ 'action' ]` ). * The action must be in the form of `'namespace_class_method'`: * namespace is a subnamespace of the lasso namespace. For example, if the action is `'foo_bar_hats'`, then the class used will be `\lasso\foo\bar`, * class refers to the class used to process request, * method refers to the method in that class used to process request, or * if the class or method names have underscores (_) in them, then a single dash (-) should be used instead. * For example, if the class is `lasso\hats\foo_bar`, and the callback method is `bar_foo` then the action would be `hats_foo-bar_bar-foo`. * The class used to process the request must implement the `lasso\internal_api\api_action` interface. The inline docs of that interface make the requirements clear. * The class used to process may optionally specify a nonce action to be used as the second param of `wp_verify_nonce()`, by declaring a public property called `nonce_action`. If this property is not set then the nonce action will be assumed to "lasso_editor". * All nonces must be transmitted in $_POST[ 'nonce' ] * The method used to process the request must return an array or true on success. * The method used to process the request must return false or null on failure. ================================================ FILE: internal-api/end_points.php ================================================ * @license GPL-2.0+ */ namespace lasso\internal_api; class end_points { /** * Constructor for this class. * * Adds our API endpoint and hooks it in at template_redirect */ public function __construct() { add_action( 'init', array( $this, 'add_endpoints' ) ); add_action( 'template_redirect', array( route::init(), 'do_api' ) ); } /** * Add endpoints for the API * * @uses "init" action */ public function add_endpoints() { //add "action" as a rewrite tag add_rewrite_tag( '%action%', '^[a-z0-9_\-]+$' ); //add the endpoint add_rewrite_rule( 'lasso-internal-api/^[a-z0-9_\-]+$/?', 'index.php?action=$matches[1]', 'top' ); } } ================================================ FILE: internal-api/find_data.php ================================================ * @license GPL-2.0+ */ namespace lasso\internal_api; class find_data { /** * Sanatized data for this request. * * @since 0.9.2 * * @var array */ public $data; /** * * @since 0.9.2 * * @param object $callback_instance Callback class. * @param string $action The name of the action we are processing for. */ public function __construct( $callback_instance, $action ) { if ( is_object( $callback_instance ) ) { $this->get_data( $callback_instance, $action ); } } /** * Get necessary data from $_POST and sanatizes it. * * Sets $this->data; * * @since 0.9.2 * * @access protected * * @param object $callback_instance Callback class. * @param string $action The name of the action we are processing for. */ protected function get_data( $callback_instance, $action ) { $data = array(); if ( is_array( $_POST ) ) { $params = $callback_instance::params(); /** * Add fields that can be saved. * * @since 0.9.5 * * @param array $params Array of params in form of $params[ 'action_name' ][ 'POST_field' ] = 'callback_function_for_sanatizing' ] */ $params = apply_filters( 'lasso_api_params', $params ); if ( is_array( $params ) && isset( $params[ $action ] ) && is_array( $params[ $action ] ) ) { $params = $params[ $action ]; foreach( $params as $key => $callback ) { $_data = null; if ( is_array( $callback ) ) { foreach( $callback as $cb ) { $_data = $this->sanitize( $key, $cb ); } }else{ $_data = $this->sanitize( $key, $callback ); } $data[ $key ] = $_data; } } } $this->data = $data; } /** * Sanitize a $_POST key * * @since 0.9.2 * * @access protected * * @param string $key The key of _$POST to sanitize. * @param string|array $cb The name of callback functions, or an array fo callback functions to do Sanitization. * * @return string|null Sanitized data or null. */ protected function sanitize( $key, $cb ) { $_data = null; if ( isset( $_POST[ $key ] ) ) { if ( function_exists( $cb ) ) { $_data = call_user_func( $cb, $_POST[ $key ] ); return $_data; } return $_data; } return $_data; } } ================================================ FILE: internal-api/route.php ================================================ * @license GPL-2.0+ */ namespace lasso\internal_api; class route { /** * Run API if possible * * @since 0.9.2 * * @uses "template_redirect" action */ public static function do_api() { global $wp_query; //get action, and if set, possibly act $action = $wp_query->get( 'action' ); if ( $action && strpos( $_SERVER['REQUEST_URI'], 'lasso-internal-api' ) ) { $response = __( 'Editus API Error.', 'lasso' ); $code = 400; //see if have a nonce. Will verify it in auth class. if ( isset( $_POST[ 'nonce' ] ) ) { $callback = self::find_callback( strip_tags( $action ) ); if ( is_int( $callback ) ) { $code = $callback; }elseif( ! class_exists( $callback['class'] ) ) { $code = 415; }else { $action = str_replace( '-', '_', $action ); $callback_instance = new $callback['class']; $auth = self::auth( $action, $callback_instance, $callback['method'] ); if ( 200 == $auth->status_code && is_array( $callback ) ) { $code = 200; $data = new find_data( $callback_instance, $action ); if ( is_array( $data->data ) && ! empty( $data->data ) ) { $response = self::route( $action, $callback_instance, $callback['method'], $data->data ); } else { $code = 500; } } else { if ( isset( $auth->error_message ) && is_string( $auth->error_message ) ) { $response = $auth->error_message; } $code = $auth->status_code; } } }else{ $code = 401; $response = __( 'Nonce not set.', 'lasso' ); } self::respond( $response, $code ); } } /** * Run the auth checks besides nonce * * @since 0.9.2 * * @access protected * * @param string $action The AJAX action we are processing. * @param string|object $callback The class to use for the callback. Either the name of the class or an instance of that class. * * @return \lasso\internal_api\auth */ protected static function auth( $action, $callback ) { return new auth( $action, $callback ); } /** * Find callback class and method * * @since 0.9.2 * * @access protected * * @return array */ protected static function find_callback( $action ) { if ( $action ) { $parts = explode( '_', $action ); if ( isset( $parts[0] ) && isset( $parts[1] ) && isset( $parts[2] ) ) { $class = str_replace( '-', '_', $parts[1] ); $class = "\\lasso\\{$parts[0]}\\{$class}"; $callback = str_replace( '-', '_', $parts[2] ); return array( 'class' => $class, 'method' => $callback, ); } } return 405; } /** * Route the data to the right callback. * * @since 0.9.2 * * @access protected * * @param string $action The AJAX action we are processing. * @param string|object $callback The class to use for the callback. Either the name of the class or an instance of that class. * @param string $method The name of the callback method. * @param array $data The sanatized data for processing the request. * * @return mixed */ protected static function route( $action, $callback, $method, $data ) { if ( method_exists( $callback, $method ) ) { $response = call_user_func( array( $callback, $method ), $data ); return $response; } } /** * Respond to request. * * @since 0.9.2 * * @access protected * * @param array|string $response The response message to send. * @param bool|int $code Response code or bool. If is bool, response code will be 200 or 401 */ protected static function respond( $response, $code ) { if ( true === $code ) { $code = 200; } if ( false == $code ) { $code = 401; } if ( is_string( $response ) ) { $data[] = $response; }elseif( is_array( $response ) ) { $data = $response; }else{ $data[] = $code; } status_header( $code ); nocache_headers(); if ( 200 == $code ) { wp_send_json_success( $data ); }else{ wp_send_json_error( $data ); } } /** * Holds the instance of this class. * * @access private * @var object */ private static $instance; /** * Returns an instance of this class. * * @access public * * @return route|object */ public static function init() { if ( ! self::$instance ) { self::$instance = new self; } return self::$instance; } } ================================================ FILE: languages/lasso-de_DE.po ================================================ msgid "" msgstr "" "Project-Id-Version: Editus\n" "POT-Creation-Date: 2022-08-02 15:40-0400\n" "PO-Revision-Date: 2022-08-02 15:50-0400\n" "Last-Translator: \n" "Language-Team: \n" "Language: de_DE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 3.1.1\n" "X-Poedit-Basepath: ..\n" "X-Poedit-KeywordsList: __;_e;esc_attr_e\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPathExcluded-0: node_modules\n" #: admin/includes/EDD_SL_Plugin_Updater.php:177 #, php-format msgid "" "There is a new version of %1$s available. View version %3$s details." msgstr "" "Eine neue Version von %1$s ist verfügbar. Details zu Version %3$s ansehen." #: admin/includes/EDD_SL_Plugin_Updater.php:184 #, php-format msgid "" "There is a new version of %1$s available. View version %3$s details or update now." msgstr "" "Es ist eine neue Version von %1$s verfügbar. Zeige Details zur Version %3$s oder aktualisiere jetzt.." #: admin/includes/EDD_SL_Plugin_Updater.php:324 msgid "You do not have permission to install plugin updates" msgstr "Du hast nicht die Rechte um Plugin-Updates zu installieren" #: admin/includes/EDD_SL_Plugin_Updater.php:324 msgid "Error" msgstr "Fehler" #: admin/includes/class-tgm-plugin-activation.php:333 #: admin/includes/menus/welcome.php:227 msgid "Install Required Plugins" msgstr "Erforderliche Plugins installieren" #: admin/includes/class-tgm-plugin-activation.php:334 #: admin/includes/menus/welcome.php:228 msgid "Install Plugins" msgstr "Plugins installieren" #: admin/includes/class-tgm-plugin-activation.php:335 #: admin/includes/menus/welcome.php:229 #, php-format msgid "Installing Plugin: %s" msgstr "Installieren von Plugin: %s" #: admin/includes/class-tgm-plugin-activation.php:336 #: admin/includes/menus/welcome.php:230 msgid "Something went wrong with the plugin API." msgstr "Irgendetwas ging schief mit der Plugin API." #: admin/includes/class-tgm-plugin-activation.php:397 #: admin/includes/menus/welcome.php:241 msgid "Return to Required Plugins Installer" msgstr "Zurück zur Installation der benötigten Plugins" #: admin/includes/class-tgm-plugin-activation.php:398 msgid "Return to the dashboard" msgstr "Zurück zum Dashboard" #: admin/includes/class-tgm-plugin-activation.php:399 #: admin/includes/class-tgm-plugin-activation.php:3029 #: admin/includes/menus/welcome.php:242 msgid "Plugin activated successfully." msgstr "Plugin erfolgreich aktiviert." #: admin/includes/class-tgm-plugin-activation.php:400 #, fuzzy #| msgid "The following plugin was activated successfully:" #| msgid_plural "The following plugins were activated successfully:" msgid "The following plugin was activated successfully:" msgstr "Das folgende Plugin wurde erfolgreich aktiviert:" #: admin/includes/class-tgm-plugin-activation.php:401 #, php-format msgid "No action taken. Plugin %1$s was already active." msgstr "Keine Aktion durchgeführt. Das Plugin %1$s war bereits aktiviert." #: admin/includes/class-tgm-plugin-activation.php:402 #, php-format msgid "" "Plugin not activated. A higher version of %s is needed for this theme. " "Please update the plugin." msgstr "" "Das Plugin wurde nicht aktiviert. Eine neuere Version von %s ist für dieses " "Theme erforderlich. Bitte aktualisiere das Plugin." #: admin/includes/class-tgm-plugin-activation.php:403 #, php-format msgid "All plugins installed and activated successfully. %1$s" msgstr "Alle Plugins wurden erfolgreich installiert und aktiviert. %1$s" #: admin/includes/class-tgm-plugin-activation.php:404 msgid "Dismiss this notice" msgstr "Nachricht verwerfen" #: admin/includes/class-tgm-plugin-activation.php:405 msgid "Please contact the administrator of this site for help." msgstr "Bitte wende dich an den Seitenadministrator für Hilfe." #: admin/includes/class-tgm-plugin-activation.php:2167 msgid "Required" msgstr "Erforderlich" #: admin/includes/class-tgm-plugin-activation.php:2170 msgid "Recommended" msgstr "Empfohlen" #: admin/includes/class-tgm-plugin-activation.php:2186 msgid "WordPress Repository" msgstr "WordPress Repository" #: admin/includes/class-tgm-plugin-activation.php:2189 msgid "External Source" msgstr "Externe Quelle" #: admin/includes/class-tgm-plugin-activation.php:2192 msgid "Pre-Packaged" msgstr "Vorgepackt" #: admin/includes/class-tgm-plugin-activation.php:2209 msgid "Not Installed" msgstr "Nicht installiert" #: admin/includes/class-tgm-plugin-activation.php:2213 msgid "Installed But Not Activated" msgstr "Installiert aber nicht aktiviert" #: admin/includes/class-tgm-plugin-activation.php:2215 msgid "Active" msgstr "Aktiv" #: admin/includes/class-tgm-plugin-activation.php:2221 msgid "Required Update not Available" msgstr "Erforderliche Aktualisierung nicht verfügbar" #: admin/includes/class-tgm-plugin-activation.php:2224 msgid "Requires Update" msgstr "Benötigt Update" #: admin/includes/class-tgm-plugin-activation.php:2227 msgid "Update recommended" msgstr "Update empfohlen" #: admin/includes/class-tgm-plugin-activation.php:2379 msgid "Installed version:" msgstr "Installierte Version:" #: admin/includes/class-tgm-plugin-activation.php:2387 msgid "Minimum required version:" msgstr "Minimal erforderliche Version:" #: admin/includes/class-tgm-plugin-activation.php:2399 msgid "Available version:" msgstr "Verfügbare Version:" #: admin/includes/class-tgm-plugin-activation.php:2422 #, php-format msgid "" "No plugins to install, update or activate. Return to the " "Dashboard" msgstr "" "Keine Plugins zu installieren, aktualisieren oder aktivieren. Zurück zum Dashboard" #: admin/includes/class-tgm-plugin-activation.php:2436 msgid "Plugin" msgstr "Plugin" #: admin/includes/class-tgm-plugin-activation.php:2437 msgid "Source" msgstr "Quelle" #: admin/includes/class-tgm-plugin-activation.php:2438 msgid "Type" msgstr "Typ" #: admin/includes/class-tgm-plugin-activation.php:2442 #: admin/includes/menus/welcome.php:118 msgid "Version" msgstr "Version" #: admin/includes/class-tgm-plugin-activation.php:2443 #: admin/includes/menus/welcome.php:49 public/includes/editor-modules.php:614 msgid "Status" msgstr "Status" #: admin/includes/class-tgm-plugin-activation.php:2603 msgid "Install" msgstr "Installieren" #: admin/includes/class-tgm-plugin-activation.php:2609 msgid "Update" msgstr "Aktualisieren" #: admin/includes/class-tgm-plugin-activation.php:2612 msgid "Activate" msgstr "Aktivieren" #: admin/includes/class-tgm-plugin-activation.php:2643 msgid "No plugins were selected to be installed. No action taken." msgstr "" "Es wurden keine Plugins zur Installation ausgewählt. Es wurde nichts " "unternommen." #: admin/includes/class-tgm-plugin-activation.php:2645 msgid "No plugins were selected to be updated. No action taken." msgstr "" "Es wurden keine Plugins zur Aktualisierung ausgewählt. Es wurde nichts " "unternommen." #: admin/includes/class-tgm-plugin-activation.php:2681 msgid "No plugins are available to be installed at this time." msgstr "Derzeit stehen keine Plugins zur Installation zur Verfügung." #: admin/includes/class-tgm-plugin-activation.php:2683 msgid "No plugins are available to be updated at this time." msgstr "Derzeit stehen keine Plugins zur Aktualisierung zur Verfügung." #: admin/includes/class-tgm-plugin-activation.php:3028 msgid "Plugin activation failed." msgstr "Plugin-Aktivierung fehlgeschlagen." #: admin/includes/class-tgm-plugin-activation.php:3362 #, php-format msgid "Updating Plugin %1$s (%2$d/%3$d)" msgstr "Aktualisiere Plugin %1$s (%2$d/%3$d)" #: admin/includes/class-tgm-plugin-activation.php:3364 #, php-format msgid "An error occurred while installing %1$s: %2$s." msgstr "" "Während der Installation von %1$s: %2$s ist ein Fehler " "aufgetreten." #: admin/includes/class-tgm-plugin-activation.php:3365 #, php-format msgid "The installation of %1$s failed." msgstr "Die Installation von %1$s ist fehlgeschlagen." #: admin/includes/class-tgm-plugin-activation.php:3369 msgid "" "The installation and activation process is starting. This process may take a " "while on some hosts, so please be patient." msgstr "" "Der Installations- und Aktivierungsprozess wird gestartet. Dieser Prozess " "kann auf manchen Servern etwas Zeit in Anspruch nehmen. Bitte habe etwas " "Geduld." #: admin/includes/class-tgm-plugin-activation.php:3370 #, php-format msgid "%1$s installed and activated successfully." msgstr "%1$s erfolgreich installiert und aktiviert." #: admin/includes/class-tgm-plugin-activation.php:3371 msgid "All installations and activations have been completed." msgstr "Alle Installationen und Aktivierungen wurden abgeschlossen." #: admin/includes/class-tgm-plugin-activation.php:3372 #, php-format msgid "Installing and Activating Plugin %1$s (%2$d/%3$d)" msgstr "Plugin installieren und aktivieren %1$s (%2$d/%3$d)" #: admin/includes/class-tgm-plugin-activation.php:3375 msgid "" "The installation process is starting. This process may take a while on some " "hosts, so please be patient." msgstr "" "Der Installationsprozess wird gestartet. Dieser Prozess kann auf manchen " "Servern etwas Zeit in Anspruch nehmen. Bitte habe etwas Geduld." #: admin/includes/class-tgm-plugin-activation.php:3377 msgid "All installations have been completed." msgstr "Alle Installationen wurden abgeschlossen." #: admin/includes/class-tgm-plugin-activation.php:3378 #, php-format msgid "Installing Plugin %1$s (%2$d/%3$d)" msgstr "Installiere Plugin %1$s (%2$d/%3$d)" #: admin/includes/load_admin.php:151 msgid "Dismiss this notice." msgstr "Diesen Hinweis ausblenden." #: admin/includes/menus/license.php:30 msgid "Aesopinteractive LLC" msgstr "Aesopinteractive LLC" #: admin/includes/menus/license.php:38 admin/includes/menus/license.php:57 msgid "License Key" msgstr "Lizenzschlüssel" #: admin/includes/menus/license.php:38 msgid "License" msgstr "Lizenz" #: admin/includes/menus/license.php:47 msgid "Editus License" msgstr "Editus-Lizenz" #: admin/includes/menus/license.php:48 msgid "" "Input the license key you recieved with your purchase to ensure your version " "of Editus stays updated." msgstr "" "Gib den Lizenzschlüssel ein, den du beim Kauf erhalten hast, um " "sicherzugehen dass Editus aktuell bleibt." #: admin/includes/menus/license.php:66 admin/includes/menus/license.php:75 msgid "Activate License" msgstr "Lizenz aktivieren" #: admin/includes/menus/license.php:70 msgid "active" msgstr "aktiviert" #: admin/includes/menus/license.php:72 msgid "Deactivate License" msgstr "Lizenz deaktivieren" #: admin/includes/menus/settings.php:26 public/includes/editor-modules.php:493 #: public/includes/editor-modules.php:892 #: public/includes/editor-modules.php:894 #: public/includes/editor-modules.php:909 #: public/includes/editor-modules.php:928 msgid "Settings" msgstr "Einstellungen" #: admin/includes/menus/settings.php:169 msgid "Editus Settings" msgstr "Editus-Einstellungen" #: admin/includes/menus/settings.php:177 msgid "Enable for:" msgstr "Aktivieren für:" #: admin/includes/menus/settings.php:181 msgid "Enable Editus for the following post types." msgstr "Editus für die folgende Post-Typen aktivieren." #: admin/includes/menus/settings.php:203 msgid "Internal Settings" msgstr "Interne Einstellungen" #: admin/includes/menus/settings.php:206 msgid "Article Class" msgstr "Artikel Klasse" #: admin/includes/menus/settings.php:207 msgid "" "Provide the CSS class (including the preceding dot) of container that holds " "the post. This should be the first parent container class that holds " "the_content." msgstr "" "Gib die CSS-Klasse (einschließlich des vorangehenden Punkts) des Containers " "an, der den Beitrag enthält. Dies sollte die erste übergeordnete " "Containerklasse sein, die the_content enthält." #: admin/includes/menus/settings.php:212 msgid "Featured Image Class" msgstr "Beitragsbild Klasse" #: admin/includes/menus/settings.php:213 msgid "" "Provide the CSS class that uses a featured image as a background image. This " "currently only supports themes that have the featured image set as " "background image." msgstr "" "Stelle die CSS-Klasse bereit, die ein Beitragsbild als Hintergrundbild " "verwendet. Derzeit werden nur Designs unterstützt, bei denen das " "Beitragsbild als Hintergrundbild festgelegt ist." #: admin/includes/menus/settings.php:218 msgid "Article Title Class" msgstr "Artikel Titel Klasse" #: admin/includes/menus/settings.php:219 msgid "" "Provide the CSS class for the post title. This will enable you to update the " "title of the post by clicking and typing." msgstr "" "Geib die CSS-Klasse für den Beitragstitel an. Auf diese Weise kannst du den " "Titel des Beitrags durch Klicken und Eingeben aktualisieren." #: admin/includes/menus/settings.php:224 msgid "Ignored Items to Save" msgstr "Ignorierte Elemente zum Speichern" #: admin/includes/menus/settings.php:225 msgid "" "If your post container holds additional markup, list the css class names " "(comma separated, including the dot) of those items. When you enter the " "editor, Editus will remove (NOT delete) these items so that it does not save " "them as HTML." msgstr "" "Wenn der Beitrags-Container zusätzliche Markierungen enthält, liste die CSS-" "Klassennamen (durch Kommas getrennt, einschließlich des Punktes) dieser " "Elemente auf. Wenn du den Editor startest, werden diese Elemente von Editus " "entfernt (NICHT gelöscht), sodass diese nicht als HTML gespeichert werden." #: admin/includes/menus/settings.php:230 msgid "Read Only Items" msgstr "Nur lesen" #: admin/includes/menus/settings.php:231 msgid "" "If your post has items that should not be editable, list the css class names " "(comma separated, including the dot) of those items." msgstr "" "Wenn dein Beitrag Elemente enthält, die nicht bearbeitet werden können, " "führe die CSS-Klassennamen (durch Kommas getrennt, einschließlich des " "Punktes) dieser Elemente an." #: admin/includes/menus/settings.php:237 msgid "Show Ignored Items" msgstr "Ignorierte Objekte anzeigen" #: admin/includes/menus/settings.php:238 msgid "" "By default the ignored items are hidden. Check this to show ignored items " "while keeping them uneditable." msgstr "" "Standardmäßig sind die ignorierten Elemente ausgeblendet. Aktiviere dieses " "Kontrollkästchen, um ignorierte Elemente anzuzeigen, die jedoch nicht " "bearbeitet werden können." #: admin/includes/menus/settings.php:242 msgid "Editor UI" msgstr "Editor UI" #: admin/includes/menus/settings.php:246 msgid "Use the Old Toolbar" msgstr "Verwende die alte Symbolleiste" #: admin/includes/menus/settings.php:247 msgid "" "Use this option to disable the new color options and use the pre-1.0 toolbar." msgstr "" "Verwende diese Option, um die neuen Farboptionen zu deaktivieren und die " "Symbolleiste vor 1.0 zu verwenden." #: admin/includes/menus/settings.php:251 msgid "Editor Bar Color Top" msgstr "Bearbeitungsleiste Farbe oben" #: admin/includes/menus/settings.php:252 msgid "Editor Bar Color Bottom" msgstr "Bearbeitungsleiste Farbe unten" #: admin/includes/menus/settings.php:253 msgid "Dialog Color" msgstr "Dialogfeld Farbe" #: admin/includes/menus/settings.php:254 msgid "Icon/Text Color" msgstr "Symbol und Textfarbe" #: admin/includes/menus/settings.php:256 msgid "Default Colors" msgstr "Standardfarben" #: admin/includes/menus/settings.php:261 msgid "Enable H2 and H3 Buttons" msgstr "Aktiviere H2/H3 Button" #: admin/includes/menus/settings.php:262 msgid "Show the buttons to set H2 and H3 settings." msgstr "Zeige Button für H2/H3-Einstellungen." #: admin/includes/menus/settings.php:267 msgid "Enable H4/H5/H6 Buttons" msgstr "Aktiviere H4/H5/H6 Button" #: admin/includes/menus/settings.php:268 msgid "Show the buttons to set H4/H5/H6 settings." msgstr "Zeige Button für H4/H5/H6-Einstellungen." #: admin/includes/menus/settings.php:274 msgid "Enable OL/UL Buttons" msgstr "Aktiviere Buttons für Nummerierte Liste und Aufzählung" #: admin/includes/menus/settings.php:275 msgid "" "Show the buttons to create Ordered and Unordered Lists from text selection." msgstr "" "Zeige die Buttons um Nummerierte Listen und Aufzählungen aus markiertem Text " "zu erstellen." #: admin/includes/menus/settings.php:280 msgid "Enable Text Color Buttons" msgstr "Aktiviere Button für Textfarben" #: admin/includes/menus/settings.php:281 msgid "Show the buttons to set text colors." msgstr "Zeige Buttons, um Textfarben anzupassen." #: admin/includes/menus/settings.php:286 msgid "Enable Text Align Buttons" msgstr "Textausrichtungs-Buttons aktivieren" #: admin/includes/menus/settings.php:287 msgid "Show the buttons to set text alignment." msgstr "Zeige Textausrichtungs-Schaltflächen an." #: admin/includes/menus/settings.php:293 msgid "Make links editable under the Editing Mode" msgstr "Mache Links im Bearbeitungsmodus bearbeitbar" #: admin/includes/menus/settings.php:294 msgid "" "Make links editable under the Editing Mode. Turning this on will make the " "links non-clickable while editing." msgstr "" "Mache Links im Bearbeitungsmodus bearbeitbar. Wenn diese Option aktiviert " "ist, können Links während der Bearbeitung nicht angeklickt werden." #: admin/includes/menus/settings.php:298 msgid "Insert Component UI" msgstr "Komponente einfügen" #: admin/includes/menus/settings.php:299 msgid "UI mechanism to insert components" msgstr "UI-Mechanismus zum Einfügen von Komponenten" #: admin/includes/menus/settings.php:301 msgid "Drag and Drop" msgstr "Drag & Drop" #: admin/includes/menus/settings.php:304 msgid "Click" msgstr "Klick" #: admin/includes/menus/settings.php:307 msgid "Auto Button on Empty Paragraph. medium.com-like UI." msgstr "Auto-Button bei leerem Absatz. medium.com-ähnliche Benutzeroberfläche." #: admin/includes/menus/settings.php:313 msgid "Popup When Text is Selected" msgstr "" #: admin/includes/menus/settings.php:314 msgid "" "Instead of using the bottom toolbar to format texts, use a popup box to " "format texts." msgstr "" #: admin/includes/menus/settings.php:320 #, fuzzy #| msgid "Insert Component" msgid "Component" msgstr "Komponente einfügen" #: admin/includes/menus/settings.php:324 msgid "Additional Component: Table" msgstr "" #: admin/includes/menus/settings.php:325 msgid "Allow user to add and edit tables." msgstr "" #: admin/includes/menus/settings.php:331 msgid "Additional Component: Paragraph" msgstr "" #: admin/includes/menus/settings.php:332 msgid "Plain HTML Paragraph." msgstr "" #: admin/includes/menus/settings.php:363 #, fuzzy #| msgid "Use Selected Images" msgid "Use Simple Image" msgstr "Ausgewählte Bilder verwenden" #: admin/includes/menus/settings.php:364 msgid "Use Simple Image Component without Extra Options." msgstr "" #: admin/includes/menus/settings.php:371 msgid "Use WP Image Block" msgstr "" #: admin/includes/menus/settings.php:372 msgid "" "Use WP Image Block as the image component. Gutenberg Block Editor needs to " "be enabled." msgstr "" #: admin/includes/menus/settings.php:379 msgid "Post Settings UI" msgstr "Benutzeroberfläche für Beitragseinstellungen" #: admin/includes/menus/settings.php:383 msgid "Disable Post Settings" msgstr "Beitragseinstellungen deaktivieren" #: admin/includes/menus/settings.php:384 msgid "" "Check this to disable users from being able to edit post settings from the " "front-end." msgstr "" "Aktiviere dieses Kontrollkästchen, um zu verhindern dass Benutzer " "Beitragseinstellungen im Frontend bearbeiten können." #: admin/includes/menus/settings.php:389 msgid "Allow Changing Post Date" msgstr "Ändern des Beitragsdatums zulassen" #: admin/includes/menus/settings.php:390 msgid "" "Add the date selector to change the post's date to the Post Setting dialog" msgstr "" "Füge Datumsauswahl hinzu, um das Beitragsdatum im Dialogfeld \"Einstellungen" "\" zu ändern" #: admin/includes/menus/settings.php:395 msgid "Allow Editing Excerpt" msgstr "" #: admin/includes/menus/settings.php:396 #, fuzzy #| msgid "" #| "Add the date selector to change the post's date to the Post Setting dialog" msgid "Allow the post's excerpt to be edited in the Post Setting dialog" msgstr "" "Füge Datumsauswahl hinzu, um das Beitragsdatum im Dialogfeld \"Einstellungen" "\" zu ändern" #: admin/includes/menus/settings.php:401 msgid "Allow Adding New Category" msgstr "Hinzufügen neuer Kategorien zulassen" #: admin/includes/menus/settings.php:402 msgid "" "Add the user to create new, previously non-existing categories for posts." msgstr "" "Erlaube Benutzern, neue (noch nicht existierende) Kategorien für Beiträge zu " "erstellen." #: admin/includes/menus/settings.php:407 msgid "Do Not Allow \"Pending\" Status" msgstr "Status \"Ausstehend\" verbieten" #: admin/includes/menus/settings.php:408 msgid "Remove the Option to Set the Status to Pending." msgstr "Entferne die Option, den Status auf Ausstehend zu setzen." #: admin/includes/menus/settings.php:413 msgid "Remove POST URL Option" msgstr "Entferne Beitrags-URL-Option" #: admin/includes/menus/settings.php:414 msgid "Remove the Option to Set the URL for the Post." msgstr "" "Entferne die Option, die URL-Titelform (slug) des Beitrags zu bearbeiten." #: admin/includes/menus/settings.php:419 msgid "Disable Post Adding" msgstr "Beitragserstellung deaktivieren" #: admin/includes/menus/settings.php:420 msgid "" "Check this box to disable users from being able to add new posts from the " "front-end." msgstr "" "Aktiviere dieses Kontrollkästchen, um zu verhindern dass Benutzer neue " "Beiträge aus dem Frontend hinzufügen können." #: admin/includes/menus/settings.php:425 msgid "Support Custom Taxonomy" msgstr "" #: admin/includes/menus/settings.php:426 msgid "Allow editing custom taxonomies." msgstr "" #: admin/includes/menus/settings.php:432 msgid "Misc" msgstr "Diverses" #: admin/includes/menus/settings.php:436 msgid "Do Not Show Tour Dialog" msgstr "Tour-Dialog nicht mehr anzeigen" #: admin/includes/menus/settings.php:437 msgid "Check this box to disable the tour dialog box for all users." msgstr "" "Aktiviere dieses Kontrollkästchen, um den Tour-Dialog für alle Benutzer zu " "deaktivieren." #: admin/includes/menus/settings.php:441 msgid "Placeholder Text for New Post" msgstr "" #: admin/includes/menus/settings.php:442 msgid "Placeholder text to be displayed when a new post is created." msgstr "" #: admin/includes/menus/settings.php:443 includes/process/new_object.php:38 #: public/includes/assets.php:248 msgid "Once upon a time..." msgstr "Schreib etwas..." #: admin/includes/menus/settings.php:448 #, fuzzy #| msgid "Do Not Allow \"Pending\" Status" msgid "Do Not Allow Shortcode Editing" msgstr "Status \"Ausstehend\" verbieten" #: admin/includes/menus/settings.php:449 #, fuzzy #| msgid "Check this box to disable the tour dialog box for all users." msgid "Check this box to disable frontend editing of shortcodes." msgstr "" "Aktiviere dieses Kontrollkästchen, um den Tour-Dialog für alle Benutzer zu " "deaktivieren." #: admin/includes/menus/settings.php:453 msgid "\"Bold\" Tag" msgstr "\"Fett\" Tag" #: admin/includes/menus/settings.php:454 msgid "Choose the HTML tag used for the \"Bold\" style." msgstr "Wähle das HTML-Tag für \"Fett\"." #: admin/includes/menus/settings.php:459 msgid "\"Italic\" Tag" msgstr "\"Kursiv\" Tag" #: admin/includes/menus/settings.php:460 msgid "Choose the HTML tag used for the \"Italic\" style." msgstr "Wähle das HTML-Tag für \"Kursiv\"." #: admin/includes/menus/settings.php:466 msgid "Auto Prefix HTTP to links" msgstr "" #: admin/includes/menus/settings.php:467 msgid "" "When user adds a hyperlink, automatically add http:// if the user does not " "specify it explicitly." msgstr "" #: admin/includes/menus/settings.php:471 #, fuzzy #| msgid "Advanced" msgid "Advanced Options" msgstr "Fortgeschritten" #: admin/includes/menus/settings.php:472 msgid "" "Suggested not to turn these options on without consulting the developer." msgstr "" #: admin/includes/menus/settings.php:477 msgid "Disable Aesop Component Conversion" msgstr "Aesop Komponente Konvertierung deaktivieren" #: admin/includes/menus/settings.php:478 msgid "" "Check this box to disable the conversion process used on Aesop Story Engine " "components." msgstr "" "Aktiviere dieses Kontrollkästchen, um den für die Aesop Story Engine-" "Komponenten verwendeten Konvertierungsprozess zu deaktivieren." #: admin/includes/menus/settings.php:483 msgid "Enable Auto Save" msgstr "Automatisches Speichern aktivieren" #: admin/includes/menus/settings.php:484 msgid "Check this box to enable auto save." msgstr "" "Aktiviere dieses Kontrollkästchen, um das automatische Speichern zu " "aktivieren." #: admin/includes/menus/settings.php:489 msgid "Disable Post Saving" msgstr "Speichern von Beiträgen deaktivieren" #: admin/includes/menus/settings.php:490 msgid "" "By default the editor will update the database with the post or page it is " "being used on. Check this box to disable this. If you check this box, it is " "assumed that you will be using the provided filters to save your own content." msgstr "" "Standardmäßig aktualisiert der Editor die Datenbank mit dem Beitrag oder der " "Seite, auf der er verwendet wird. Aktiviere dieses Kontrollkästchen, um dies " "zu deaktivieren. Wenn dieses Kontrollkästchen aktiviert ist, wird davon " "ausgegangen, dass die bereitgestellten Filter zum Speichern des eigenen " "Inhalts verwenden werden." #: admin/includes/menus/settings.php:496 msgid "Disable Post Editing" msgstr "Deaktiviere die Bearbeitung von Beiträgen" #: admin/includes/menus/settings.php:497 msgid "" "You may use this option if you only want to edit custom fields. Refer here for more information. The custom fields you specify will be " "still editable under the editing mode." msgstr "" "Du kannst diese Option verwenden, wenn du nur benutzerdefinierte Felder " "bearbeiten möchten. Weitere Informationen hier. Die " "ausgewählten benutzerdefinierten Felder können im Bearbeitungsmodus " "weiterhin bearbeitet werden." #: admin/includes/menus/settings.php:503 msgid "Don't Use REST API to Save" msgstr "REST-API zum Speichern nicht verwenden" #: admin/includes/menus/settings.php:504 msgid "" "By default the editor will use REST API to save posts. Check this box to use " "custom AJAX calls instead." msgstr "" "Standardmäßig verwendet der Editor die REST-API um Beiträge zu speichern. " "Aktiviere das Kontrollkästchen, um stattdessen benutzerdefinierte AJAX-Calls " "zu verwenden." #: admin/includes/menus/settings.php:510 #, fuzzy #| msgid "You can also use Shortcodes" msgid "Don't Wrap Shortcodes" msgstr "Du kannst auch Shortcodes verwenden" #: admin/includes/menus/settings.php:511 msgid "" "By default Editus wraps shortcodes so they can be preserved. Disable this " "behavior." msgstr "" #: admin/includes/menus/settings.php:521 msgid "Save Settings" msgstr "Einstellungen speichern" #: admin/includes/menus/welcome.php:48 msgid "Editus" msgstr "Editus" #: admin/includes/menus/welcome.php:49 msgid "Welcome" msgstr "Willkommen" #: admin/includes/menus/welcome.php:71 msgid "" "We will check the current theme on every site in your network and give you a " "quick status feedback here. You can see the status by visiting the Editus " "menu on each site." msgstr "" "Wir werden das aktuelle Theme auf jeder Seite in deinem Netzwerk überprüfen " "und dir hier ein rasches Feedback geben. Du kannst den Status abrufen, indem " "du das Editus-Menü auf jeder Seite besuchst." #: admin/includes/menus/welcome.php:90 msgid "You're Ready to Rock!" msgstr "Du bist bereit loszulegen!" #: admin/includes/menus/welcome.php:92 msgid "Your theme is automatically supported. No additional setup is needed." msgstr "" "Dein Theme wird automatisch unterstützt. Es sind keine zusätzlichen " "Einstellungen notwendig." #: admin/includes/menus/welcome.php:94 msgid "" "Editus will place a small menu on the bottom of your site. While on a single " "post or page, click the \"pen\" icon to go into edit mode. Press escape to " "get out of edit mode." msgstr "" "Editus wird ein kleines Menü unten auf deiner Webseite platzieren. Wenn du " "auf einem Beitrag oder einer Seite bist, klicke das „Stift“-Symbol, um in " "den Bearbeitungsmodus zu wechseln. Drücke „Esc“ um den Bearbeitungsmodus zu " "verlassen." #: admin/includes/menus/welcome.php:117 msgid "Welcome to Editus" msgstr "Willkommen bei Editus" #: admin/includes/menus/welcome.php:123 msgid "Help" msgstr "Hilfe" #: admin/includes/menus/welcome.php:124 msgid "Twitter" msgstr "Twitter" #: admin/includes/menus/welcome.php:125 msgid "Facebook" msgstr "Facebook" #: admin/includes/menus/welcome.php:158 msgid "Article CSS Class Needed!" msgstr "Beitrags CSS Klasse wird benötigt!" #: admin/includes/menus/welcome.php:159 msgid "Before using Editus," msgstr "" "Vor der Verwendung von Editus die CSS Klasse des Containers, der den Inhalt " "der Seiten und Beiträge enthält," #: admin/includes/menus/welcome.php:159 msgid "enter and save" msgstr "eingeben und speichern" #: admin/includes/menus/welcome.php:159 msgid "" "the CSS class of the container that holds your post and page content. You " "can use a tool like " "inspector in Chrome or Firefox to find this CSS class, or " msgstr "" ". Du kannst ein Tool wie " "den Inspektor in Chrome oder Firefox benutzen um die CSS Klasse zu " "finden oder " #: admin/includes/menus/welcome.php:159 msgid "email us." msgstr "sende uns eine E-Mail" #: admin/includes/menus/welcome.php:159 msgid "with a link to a public URL with the theme and we'll find it for you." msgstr "" "mit einem Link zu einer öffentlichen Seite mit dem Theme und wir werden sie " "für dich finden." #: admin/includes/menus/welcome.php:166 msgid "" "Just a heads up that the WP REST API isn't activated. This is required to " "list the posts and pages on the front-end." msgstr "" "Nur ein Hinweis, dass die WP REST API nicht aktiviert ist. Dies ist " "erforderlich, um die Beiträge und Seiten im Frontend aufzulisten." #: admin/includes/menus/welcome.php:173 msgid "Just a heads up that " msgstr "Nur ein Hinweis " #: admin/includes/menus/welcome.php:174 admin/includes/menus/welcome.php:211 msgid "Aesop Story Engine" msgstr "Aesop Story Engine" #: admin/includes/menus/welcome.php:174 msgid "" "isn't activated. It's not required to use Editus, but you won't get the cool " "drag and drop components without it activated. It's free!" msgstr "" "ist nicht aktiviert. Diese ist nicht erforderlich um Editus zu verwenden, " "aber dann sind die coolen Drag & Drop-Komponenten nicht verfügbar. Es ist " "kostenlos!" #: admin/includes/menus/welcome.php:180 msgid "WP Side Comments Compatibility Warning!" msgstr "WP Side Comments Kompatibilitätswarnung!" #: admin/includes/menus/welcome.php:181 msgid "" "Since Editus saves the HTML of a post, this may cause undesired issues. " "We're working to resolve incompatibilities faster than a jack rabbit in a " "hot greasy griddle in the middle of August." msgstr "" "Da Editus den HTML-Code eines Beitrags speichert, kann dies zu unerwünschten " "Problemen führen. Wir arbeiten daran, Inkompatibilitäten so schnell wie " "möglich zu lösen." #: admin/includes/menus/welcome.php:187 msgid "License Key Not Activated" msgstr "Lizenzschlüssel nicht aktiviert" #: admin/includes/menus/welcome.php:188 msgid "" "Just a heads up, your license key isn't activated. Enter your license key " "into the License tab on the left in order to receive plugin update " "notifications." msgstr "" "Nur ein Hinweis, dein Lizenzschlüssel ist nicht aktiviert. Gib deinen " "Lizenzschlüssel in der Registerkarte \"Lizenz\" links ein, um " "Benachrichtigungen zu Plugin-Updates zu erhalten." #: admin/includes/menus/welcome.php:192 msgid "License Key Invalid" msgstr "Lizenzschlüssel ungültig" #: admin/includes/menus/welcome.php:193 msgid "The license key that you entered is " msgstr "Der eingegebene Lizenzschlüssel ist " #: admin/includes/menus/welcome.php:193 msgid "invalid" msgstr "ungültig" #: admin/includes/menus/welcome.php:193 msgid ". It may have been entered incorreclty, or may have expired." msgstr "" ". Er wurde möglicherweise falsch eingegeben oder könnte abgelaufen sein." #: admin/includes/menus/welcome.php:243 #, php-format msgid "All plugins installed and activated successfully. %s" msgstr "Alle Plugins wurden installiert und erfolgreich aktiviert. %s" #: includes/process/gallery.php:40 msgid "Save and refresh to view gallery." msgstr "Speichern und aktualisieren um die Galerie anzuzeigen." #: includes/process/gallery.php:199 msgid "Delete From Gallery" msgstr "Aus der Galerie löschen" #: includes/process/gallery.php:200 msgid "Edit Image Caption" msgstr "Bildunterschrift bearbeiten" #: internal-api/auth.php:67 msgid "Unauthorized action" msgstr "Unberechtigte Aktion" #: internal-api/auth.php:71 msgid "" "All callback classes used for processing the Editus Internal API must " "implement the lasso\\internal_api\\api_action interface." msgstr "" "Alle Callback-Klassen, die zur Verarbeitung der internen API von Editus " "verwendet werden, müssen die Schnittstelle lasso \\ internal_api pi_action " "implementieren." #: internal-api/auth.php:76 msgid "Nonce invalid" msgstr "Nonce ungültig" #: internal-api/route.php:30 msgid "Editus API Error." msgstr "Editus API-Fehler." #: internal-api/route.php:66 msgid "Nonce not set." msgstr "Nonce nicht gesetzt." #: lasso.php:130 #, fuzzy #| msgid "Insert Component" msgid "Insert Column" msgstr "Komponente einfügen" #: lasso.php:131 #, fuzzy #| msgid "Insert" msgid "Insert Row" msgstr "Einfügen" #: lasso.php:132 #, fuzzy #| msgid "Delete Post" msgid "Delete Column" msgstr "Beitrag löschen" #: lasso.php:133 #, fuzzy #| msgid "Delete Post" msgid "Delete Row" msgstr "Beitrag löschen" #: lasso.php:134 #, fuzzy #| msgid "Delete Image" msgid "Delete Table" msgstr "Bild löschen" #: lasso.php:149 lasso.php:159 #, fuzzy #| msgid "Table" msgid "HTML Table" msgstr "Tabelle" #: lasso.php:192 lasso.php:220 msgid "HTML Paragraph" msgstr "" #: public/includes/assets.php:146 public/includes/editor-modules.php:713 #: public/includes/option-engine.php:132 msgid "Save" msgstr "Speichern" #: public/includes/assets.php:147 msgid "Please Select Text First." msgstr "Bitte zuerst Text auswählen." #: public/includes/assets.php:148 public/includes/editor-modules.php:439 #: public/includes/editor-modules.php:706 #: public/includes/editor-modules.php:788 #: public/includes/editor-modules.php:1329 msgid "Cancel" msgstr "Abbrechen" #: public/includes/assets.php:149 msgid "Exit Editor" msgstr "Editor verlassen" #: public/includes/assets.php:150 msgid "Saving..." msgstr "Speichere…" #: public/includes/assets.php:151 msgid "Saved!" msgstr "Gespeichert!" #: public/includes/assets.php:152 msgid "Adding..." msgstr "Füge hinzu…" #: public/includes/assets.php:153 msgid "Added!" msgstr "Hinzugefügt!" #: public/includes/assets.php:154 msgid "Loading..." msgstr "Lade..." #: public/includes/assets.php:155 msgid "Load More" msgstr "Weitere laden" #: public/includes/assets.php:156 public/includes/helpers.php:457 msgid "Close" msgstr "Schließen" #: public/includes/assets.php:157 msgid "No more posts found" msgstr "Keine weiteren Beiträge gefunden" #: public/includes/assets.php:158 msgid "Fetching failed." msgstr "Fehler beim Abrufen." #: public/includes/assets.php:159 msgid "Gallery Created!" msgstr "Galerie erstellt!" #: public/includes/assets.php:160 msgid "Gallery Updated!" msgstr "Galerie aktualisiert!" #: public/includes/assets.php:161 msgid "Just write..." msgstr "Einfach schreiben…" #: public/includes/assets.php:162 msgid "Choose an image" msgstr "Bild wählen" #: public/includes/assets.php:163 msgid "Update Image" msgstr "Bild aktualisieren" #: public/includes/assets.php:164 msgid "Insert Image" msgstr "Bild einfügen" #: public/includes/assets.php:165 msgid "Select Image" msgstr "Bild auswählen" #: public/includes/assets.php:166 msgid "Remove featured image?" msgstr "Beitragsbild entfernen?" #: public/includes/assets.php:167 msgid "Update Selected Image" msgstr "Ausgewähltes Bild aktualisieren" #: public/includes/assets.php:168 msgid "Choose images" msgstr "Bilder auswählen" #: public/includes/assets.php:169 msgid "Edit Image" msgstr "Bild bearbeiten" #: public/includes/assets.php:170 #: public/includes/editor-modules--gallery.php:28 msgid "Add Images" msgstr "Bilder hinzufügen" #: public/includes/assets.php:171 msgid "Add New Gallery" msgstr "Neue Galerie hinzufügen" #: public/includes/assets.php:172 msgid "Select Editus Gallery Image" msgstr "Eine Editus Galerie-Bild auswählen" #: public/includes/assets.php:173 msgid "Use Selected Images" msgstr "Ausgewählte Bilder verwenden" #: public/includes/assets.php:174 msgid "Publish Post?" msgstr "Beitrag veröffentlichen?" #: public/includes/assets.php:175 msgid "Yes, publish it!" msgstr "Ja, veröffentlichen!" #: public/includes/assets.php:176 msgid "Trash Post?" msgstr "Beitrag löschen?" #: public/includes/assets.php:177 msgid "Yes, trash it!" msgstr "Ja, löschen!" #: public/includes/assets.php:178 msgid "Oh snap!" msgstr "Oh Mist!" #: public/includes/assets.php:179 msgid "O.K. got it!" msgstr "OK, verstanden!" #: public/includes/assets.php:180 msgid "" "It looks like we are either missing the Article CSS class, or it is " "configured incorrectly. Editus will not function correctly without this CSS " "class." msgstr "" "Es scheint, dass entweder die Artikel-CSS-Klasse nicht vorhanden ist oder " "diese falsch konfiguriert wurde. Ohne diese CSS-Klasse wird Editus nicht " "einwandfrei funktionieren." #: public/includes/assets.php:181 msgid "Update Settings" msgstr "Einstellungen aktualisieren" #: public/includes/assets.php:182 msgid "one more letter" msgstr "ein weiterer Buchstabe" #: public/includes/assets.php:183 msgid "You are currently editing a backup copy of this post." msgstr "Du bearbeitest gerade eine Sicherungskopie dieses Beitrags." #: public/includes/assets.php:185 msgid "add categories..." msgstr "Kategorien hinzufügen..." #: public/includes/assets.php:186 msgid "add tags..." msgstr "Schlagwörter hinzufügen..." #: public/includes/assets.php:187 #, fuzzy #| msgid "add categories..." msgid "add taxonomy terms..." msgstr "Kategorien hinzufügen..." #: public/includes/assets.php:188 msgid "Edit Shortcode" msgstr "Shortcode bearbeiten" #: public/includes/components.php:19 public/includes/editor-modules.php:352 msgid "Quote" msgstr "Zitat" #: public/includes/components.php:23 public/includes/editor-modules.php:350 #: public/includes/editor-modules.php:1103 #: public/includes/editor-modules.php:1154 #: public/includes/editor-modules.php:1218 msgid "Image" msgstr "Bild" #: public/includes/components.php:27 #: public/includes/editor-modules--gallery.php:74 #: public/includes/editor-modules.php:355 msgid "Parallax" msgstr "Parallax" #: public/includes/components.php:31 public/includes/editor-modules.php:356 msgid "Audio" msgstr "Audio" #: public/includes/components.php:35 public/includes/editor-modules.php:353 #: public/includes/editor-modules.php:1080 msgid "Content" msgstr "Inhalt" #: public/includes/components.php:39 public/includes/editor-modules.php:351 msgid "Character" msgstr "Zeichen" #: public/includes/components.php:43 public/includes/editor-modules.php:361 msgid "Collection" msgstr "Sammlung" #: public/includes/components.php:47 public/includes/editor-modules.php:360 msgid "Document" msgstr "Dokument" #: public/includes/components.php:51 public/includes/editor-modules.php:362 msgid "Gallery" msgstr "Galerie" #: public/includes/components.php:55 public/includes/editor-modules.php:354 msgid "Chapter" msgstr "Kapitel" #: public/includes/components.php:59 public/includes/editor-modules.php:358 msgid "Map" msgstr "Karte" #: public/includes/components.php:63 public/includes/editor-modules.php:359 msgid "Timeline" msgstr "Zeitleiste" #: public/includes/components.php:67 public/includes/editor-modules.php:357 msgid "Video" msgstr "Video" #: public/includes/components.php:71 public/includes/components.php:91 #: public/includes/editor-modules.php:371 #: public/includes/editor-modules.php:373 msgid "WordPress Image" msgstr "WordPress Bild" #: public/includes/components.php:75 #, fuzzy #| msgid "WordPress Image" msgid "WordPress Image Block" msgstr "WordPress Bild" #: public/includes/components.php:79 public/includes/editor-modules.php:375 msgid "WordPress Quote" msgstr "WordPress Zitat" #: public/includes/components.php:83 public/includes/editor-modules.php:364 msgid "Gallery Pop" msgstr "Galerie Pop" #: public/includes/components.php:87 msgid "Events" msgstr "Veranstaltungen" #: public/includes/editor-modules--gallery.php:19 msgid "Create gallery" msgstr "Galerie erstellen" #: public/includes/editor-modules--gallery.php:27 msgid "Manage Images" msgstr "Bilder verwalten" #: public/includes/editor-modules--gallery.php:31 msgid "Rearrange or edit the images in this gallery." msgstr "Bilder in dieser Galerie anordnen oder bearbeiten." #: public/includes/editor-modules--gallery.php:47 msgid "Create a Gallery" msgstr "Galerie erstellen" #: public/includes/editor-modules--gallery.php:51 msgid "Select images to create a gallery." msgstr "Wähle Bilder aus um eine Galerie zu erstellen." #: public/includes/editor-modules--gallery.php:52 msgid "Select Images" msgstr "Bilder auswählen" #: public/includes/editor-modules--gallery.php:56 msgid "Create Gallery" msgstr "Galerie erstellen" #: public/includes/editor-modules--gallery.php:67 msgid "Gallery Type" msgstr "Galerie Typ" #: public/includes/editor-modules--gallery.php:68 msgid "Select the type of gallery." msgstr "Wähle die Galerie-Art." #: public/includes/editor-modules--gallery.php:70 msgid "Grid" msgstr "Raster" #: public/includes/editor-modules--gallery.php:71 msgid "Thumbnail" msgstr "Vorschaubild" #: public/includes/editor-modules--gallery.php:73 msgid "Photoset" msgstr "Bildauswahl" #: public/includes/editor-modules--gallery.php:84 msgid "Grid Item Width" msgstr "Rasterbreite" #: public/includes/editor-modules--gallery.php:85 msgid "" "Adjust the width of the individual grid items, only if using Grid gallery " "style. Default is 400." msgstr "" "Passe die Breite der einzelnen Rasterelemente an (nur wenn Grid-Galerie-Stil " "verwendet werden). Standardwert ist 400." #: public/includes/editor-modules--gallery.php:95 msgid "Gallery Transition" msgstr "Galerie-Übergang" #: public/includes/editor-modules--gallery.php:96 msgid "" "Adjust the transition effect for the Thumbnail gallery. Default is slide." msgstr "" "Passe den Übergangseffekt für die Vorschaubilder-Galerie an. Standardwert " "ist Slider." #: public/includes/editor-modules--gallery.php:98 msgid "Fade" msgstr "Einblenden" #: public/includes/editor-modules--gallery.php:99 msgid "Slide" msgstr "Slide" #: public/includes/editor-modules--gallery.php:100 msgid "Dissolve" msgstr "Auflösen" #: public/includes/editor-modules--gallery.php:105 msgid "Gallery Transition Speed" msgstr "Galerie Übergangsgeschwindigkeit" #: public/includes/editor-modules--gallery.php:106 msgid "" "Activate slideshow by setting a speed for the transition.5000 = 5 seconds." msgstr "" "Diashow aktivieren, durch Wahl einer Übergangsgeschwindigkeit. 5000 = 5 " "Sekunden." #: public/includes/editor-modules--gallery.php:112 msgid "Hide Gallery Thumbnails" msgstr "Galerie-Vorschaubilder ausblenden" #: public/includes/editor-modules--gallery.php:121 msgid "Gallery Layout" msgstr "Galerie-Layout" #: public/includes/editor-modules--gallery.php:122 msgid "" "Let's say you have 4 images in this gallery. If you enter 121 you will have " "one image on the top row, two images on the second row, and one image on the " "third row." msgstr "" "Angenommen, du hast 4 Bilder in dieser Galerie. Wenn du 121 eingibst, hast " "du ein Bild in der oberen Reihe, zwei Bilder in der zweiten Reihe und ein " "Bild in der dritten Reihe." #: public/includes/editor-modules--gallery.php:137 msgid "Main Gallery Height" msgstr "Haupt-Galerie Höhe" #: public/includes/editor-modules--gallery.php:138 #, php-format msgid "" "Adjust the overall height of the gallery. Acceptable values include 500px or " "50% etc." msgstr "" "Passen Sie die Höhe der Galerie an. Die zulässigen Werte sind 500px oder " "50% usw." #: public/includes/editor-modules--gallery.php:148 msgid "Main Gallery Width" msgstr "Haupt-Galerie Breite" #: public/includes/editor-modules--gallery.php:149 #, php-format msgid "" "Adjust the overall width of the gallery. Acceptable values include 500px or " "50% etc." msgstr "" "Passen Sie die Gesamtbreite der Galerie an. Die zulässigen Werte sind \"500px" "\" oder \"50 %\" usw." #: public/includes/editor-modules--gallery.php:153 msgid "Gallery Caption" msgstr "Galerie Bildunterschrift" #: public/includes/editor-modules--gallery.php:154 msgid "Add an optional caption for the gallery." msgstr "Füge eine optionale Bildunterschrift zur Galerie hinzu." #: public/includes/editor-modules.php:60 public/includes/editor-modules.php:437 msgid "Table" msgstr "Tabelle" #: public/includes/editor-modules.php:137 #: public/includes/underscore-templates.php:23 #: public/includes/underscore-templates.php:41 msgid "Edit Post" msgstr "Beitrag bearbeiten" #: public/includes/editor-modules.php:140 #: public/includes/editor-modules.php:164 #: public/includes/editor-modules.php:457 msgid "Post Settings" msgstr "Beitragseinstellungen" #: public/includes/editor-modules.php:145 msgid "All Posts" msgstr "Alle Beiträge" #: public/includes/editor-modules.php:148 #: public/includes/editor-modules.php:1323 msgid "Revisions" msgstr "Revisionen" #: public/includes/editor-modules.php:152 msgid "Add Post" msgstr "Neuen Beitrag erstellen" #: public/includes/editor-modules.php:163 #: public/includes/editor-modules.php:456 #: public/includes/underscore-templates.php:25 #: public/includes/underscore-templates.php:43 msgid "Delete Post" msgstr "Beitrag löschen" #: public/includes/editor-modules.php:167 #: public/includes/editor-modules.php:459 msgid "Save Post" msgstr "Beitrag speichern" #: public/includes/editor-modules.php:170 #: public/includes/editor-modules.php:462 msgid "Publish Post" msgstr "Beitrag veröffentlichen" #: public/includes/editor-modules.php:170 msgid "Submit For Review" msgstr "Zur Überprüfung einreichen" #: public/includes/editor-modules.php:249 #: public/includes/editor-modules.php:342 msgid "Bold" msgstr "Fett" #: public/includes/editor-modules.php:250 #: public/includes/editor-modules.php:343 msgid "Underline" msgstr "Unterstrichen" #: public/includes/editor-modules.php:251 #: public/includes/editor-modules.php:344 msgid "Italicize" msgstr "Kursiv" #: public/includes/editor-modules.php:252 #: public/includes/editor-modules.php:345 msgid "Strikethrough" msgstr "Durchgestrichen" #: public/includes/editor-modules.php:255 #: public/includes/editor-modules.php:384 #: public/includes/editor-modules.php:431 msgid "H2 Heading" msgstr "Überschrift H2" #: public/includes/editor-modules.php:256 #: public/includes/editor-modules.php:385 #: public/includes/editor-modules.php:432 msgid "H3 Heading" msgstr "Überschrift H3" #: public/includes/editor-modules.php:262 #: public/includes/editor-modules.php:391 msgid "H4 Heading" msgstr "Überschrift H4" #: public/includes/editor-modules.php:263 #: public/includes/editor-modules.php:392 msgid "H5 Heading" msgstr "Überschrift H5" #: public/includes/editor-modules.php:264 #: public/includes/editor-modules.php:393 msgid "H6 Heading" msgstr "Überschrift H6" #: public/includes/editor-modules.php:268 #: public/includes/editor-modules.php:397 msgid "Set Color for Selected Text" msgstr "Textfarbe für markierten Text festlegen" #: public/includes/editor-modules.php:269 #: public/includes/editor-modules.php:398 msgid "Choose Color" msgstr "Farbe wählen" #: public/includes/editor-modules.php:273 #: public/includes/editor-modules.php:402 #: public/includes/editor-modules.php:434 msgid "Ordered List" msgstr "Nummerierte Liste" #: public/includes/editor-modules.php:274 #: public/includes/editor-modules.php:403 #: public/includes/editor-modules.php:435 msgid "Unordered List" msgstr "Aufzählung" #: public/includes/editor-modules.php:278 #: public/includes/editor-modules.php:407 msgid "Anchor Link" msgstr "Link" #: public/includes/editor-modules.php:280 #: public/includes/editor-modules.php:409 msgid "http://url.com" msgstr "http://url.com" #: public/includes/editor-modules.php:281 #: public/includes/editor-modules.php:410 msgid "Create Link" msgstr "Link erstellen" #: public/includes/editor-modules.php:283 #: public/includes/editor-modules.php:412 msgid "Open in a New Tab" msgstr "In einem neuen Tab öffnen" #: public/includes/editor-modules.php:347 msgid "Insert Component" msgstr "Komponente einfügen" #: public/includes/editor-modules.php:367 msgid "Event" msgstr "Veranstaltung" #: public/includes/editor-modules.php:376 msgid "WordPress Video" msgstr "WordPress Video" #: public/includes/editor-modules.php:419 #: public/includes/editor-modules.php:440 msgid "Insert HTML or Code" msgstr "HTML oder Code einfügen" #: public/includes/editor-modules.php:421 #: public/includes/editor-modules.php:424 msgid "Enter HTML to insert" msgstr "HTML eingeben zum einfügen" #: public/includes/editor-modules.php:425 msgid "You can also use Shortcodes" msgstr "Du kannst auch Shortcodes verwenden" #: public/includes/editor-modules.php:426 msgid "" "You can also enter a URL to embed, such as Youtube, Vimeo and Twitter URLs." msgstr "Du kannst auch eine URL von YouTube, Vimeo oder Twitter eingeben." #: public/includes/editor-modules.php:440 msgid "Insert" msgstr "Einfügen" #: public/includes/editor-modules.php:446 msgid "Text Left Align" msgstr "Linksbündig" #: public/includes/editor-modules.php:447 msgid "Text Center Align" msgstr "Text zentrieren" #: public/includes/editor-modules.php:448 msgid "Text Right Align" msgstr "Rechtsbündig" #: public/includes/editor-modules.php:492 #: public/includes/editor-modules.php:890 #: public/includes/editor-modules.php:908 #: public/includes/editor-modules.php:927 msgid "Move" msgstr "Verschieben" #: public/includes/editor-modules.php:494 #: public/includes/editor-modules.php:896 #: public/includes/editor-modules.php:910 #: public/includes/editor-modules.php:929 msgid "Clone" msgstr "Duplizieren" #: public/includes/editor-modules.php:495 #: public/includes/editor-modules.php:897 #: public/includes/editor-modules.php:911 #: public/includes/editor-modules.php:930 msgid "Delete" msgstr "Löschen" #: public/includes/editor-modules.php:517 msgid "Replace Image" msgstr "Bild ersetzen" #: public/includes/editor-modules.php:518 msgid "Delete Image" msgstr "Bild löschen" #: public/includes/editor-modules.php:519 msgid "save" msgstr "speichern" #: public/includes/editor-modules.php:593 msgid "Featured Image" msgstr "Beitragsbild" #: public/includes/editor-modules.php:593 msgid "Change the featured image for this post." msgstr "Beitragsbild für diesen Beitrag ändern." #: public/includes/editor-modules.php:597 msgid "Change Featured Image" msgstr "Beitragsbild ändern" #: public/includes/editor-modules.php:598 msgid "Delete Featured Image" msgstr "Beitragsbild löschen" #: public/includes/editor-modules.php:614 msgid "Change the status of the post to draft or publish." msgstr "Beitragsstatus auf Entwurf oder Veröffentlicht ändern." #: public/includes/editor-modules.php:616 msgid "Draft" msgstr "Entwurf" #: public/includes/editor-modules.php:618 msgid "Pending" msgstr "Ausstehend" #: public/includes/editor-modules.php:620 msgid "Publish" msgstr "Veröffentlichen" #: public/includes/editor-modules.php:630 msgid "Post URL" msgstr "Beitrags-URL" #: public/includes/editor-modules.php:630 msgid "Change the URL (slug) of this post." msgstr "URL-Titelform (slug) dieses Beitrags ändern." #: public/includes/editor-modules.php:640 msgid "Categories" msgstr "Kategorien" #: public/includes/editor-modules.php:640 msgid "Type a category name and press enter." msgstr "Kategorie eingeben und mit Enter bestätigen." #: public/includes/editor-modules.php:645 msgid "Tags" msgstr "Schlagwörter" #: public/includes/editor-modules.php:645 msgid "Type a tag name and press enter." msgstr "Schlagwort eingeben und mit Enter bestätigen." #: public/includes/editor-modules.php:653 msgid "Custom Taxonomy" msgstr "" #: public/includes/editor-modules.php:653 msgid "Choose custom taxonomy." msgstr "" #: public/includes/editor-modules.php:670 msgid "Excerpt" msgstr "" #: public/includes/editor-modules.php:670 msgid "Edit excerpt" msgstr "" #: public/includes/editor-modules.php:679 msgid "Post Date" msgstr "Veröffentlichungsdatum" #: public/includes/editor-modules.php:681 msgid "Set to Now" msgstr "Auf Jetzt eingestellt" #: public/includes/editor-modules.php:762 msgid "New post title" msgstr "Titel des neuen Beitrags" #: public/includes/editor-modules.php:762 msgid "Specify title for new post, then save to edit." msgstr "Gib einen Titel für den neuen Beitrag an." #: public/includes/editor-modules.php:763 msgid "Type Your Title Here" msgstr "Titel hier eingeben" #: public/includes/editor-modules.php:800 msgid "Create" msgstr "Erstellen" #: public/includes/editor-modules.php:839 msgid "results found" msgstr "Ergebnisse gefunden" #: public/includes/editor-modules.php:952 msgid "Save Locations" msgstr "Locations speichern" #: public/includes/editor-modules.php:970 msgid "Save this post and refesh the page to see these changes." msgstr "" "Speichere diesen Beitrag und aktualisiere die Seite um die Änderungen zu " "sehen." #: public/includes/editor-modules.php:1109 #: public/includes/editor-modules.php:1224 #: public/includes/editor-modules.php:1289 #, fuzzy #| msgid "Image" msgid "Image URL" msgstr "Bild" #: public/includes/editor-modules.php:1110 #: public/includes/editor-modules.php:1225 #: public/includes/editor-modules.php:1290 msgid "" "URL for the image. Click Select Media to open the WordPress Media " "Library." msgstr "" #: public/includes/editor-modules.php:1117 #: public/includes/editor-modules.php:1232 msgid "Center" msgstr "" #: public/includes/editor-modules.php:1121 #: public/includes/editor-modules.php:1236 msgid "Left" msgstr "" #: public/includes/editor-modules.php:1125 #: public/includes/editor-modules.php:1240 msgid "Right" msgstr "" #: public/includes/editor-modules.php:1129 #: public/includes/editor-modules.php:1244 msgid "Alignment" msgstr "" #: public/includes/editor-modules.php:1136 #, fuzzy #| msgid "Image" msgid "Image Width" msgstr "Bild" #: public/includes/editor-modules.php:1137 msgid "" "Width of the image. You can enter the size in pixels or percentage such as " "40% or 500px." msgstr "" #: public/includes/editor-modules.php:1142 msgid "Image Height" msgstr "" #: public/includes/editor-modules.php:1143 msgid "" "Used only for the Panorama mode. Can be set using pixel values such as " "500px. If unspecified, the original height would be used. " msgstr "" #: public/includes/editor-modules.php:1150 msgid "None" msgstr "" #: public/includes/editor-modules.php:1158 msgid "URL" msgstr "" #: public/includes/editor-modules.php:1162 msgid "Link" msgstr "" #: public/includes/editor-modules.php:1163 msgid "Click leads to:" msgstr "" #: public/includes/editor-modules.php:1169 msgid "URL Link" msgstr "" #: public/includes/editor-modules.php:1170 msgid "URL link" msgstr "" #: public/includes/editor-modules.php:1175 #: public/includes/editor-modules.php:1250 #, fuzzy #| msgid "Image" msgid "Image ALT" msgstr "Bild" #: public/includes/editor-modules.php:1176 #: public/includes/editor-modules.php:1251 msgid "ALT tag used for the image. Primarily used for SEO purposes." msgstr "" #: public/includes/editor-modules.php:1182 #: public/includes/editor-modules.php:1256 #, fuzzy #| msgid "Gallery Caption" msgid "Caption" msgstr "Galerie Bildunterschrift" #: public/includes/editor-modules.php:1183 #: public/includes/editor-modules.php:1257 #, fuzzy #| msgid "Add an optional caption for the gallery." msgid "Optional caption for the image." msgstr "Füge eine optionale Bildunterschrift zur Galerie hinzu." #: public/includes/editor-modules.php:1188 #, fuzzy #| msgid "Add Images" msgid "An image." msgstr "Bilder hinzufügen" #: public/includes/editor-modules.php:1262 msgid "Link URL" msgstr "" #: public/includes/editor-modules.php:1263 msgid "Optional URL to link." msgstr "" #: public/includes/editor-modules.php:1268 msgid "A WP Image Block." msgstr "" #: public/includes/editor-modules.php:1283 msgid "Cover" msgstr "" #: public/includes/editor-modules.php:1294 msgid "A WP Cover Block." msgstr "" #: public/includes/editor-modules.php:1323 msgid "Use the slider to view the revision live on the page." msgstr "" "Verwende den Schieberegler um die Revision in Echtzeit auf der Seite " "anzuzeigen." #: public/includes/editor-modules.php:1330 msgid "Select" msgstr "Auswählen" #: public/includes/helpers.php:449 msgid "No posts to show" msgstr "Keine anzuzeigenden Beiträge" #: public/includes/helpers.php:455 msgid "No revisions found" msgstr "Keine Revisionen gefunden" #: public/includes/lasso.php:292 msgid "Post being edited by " msgstr "" #: public/includes/tour.php:67 msgid "Don't show this again" msgstr "Diese Meldung nicht wieder anzeigen" #: public/includes/tour.php:71 msgid "Okay, got it!" msgstr "OK, verstanden!" #: public/includes/tour.php:96 msgid "" "Access posts by clicking the list icon. Create a new post by clicking the " "new post icon." msgstr "" "Greife auf Beiträge zu indem Du auf das Listen-Symbol klickst. Erstelle " "einen neuen Beitrag indem Du auf das „Neuer Beitrag“-Symbol klickst." #: public/includes/tour.php:99 msgid "" "While on a single post, edit by clicking the Pen icon. Access post settings " "with the settings icon. Press escape to exit any modal." msgstr "" "Auf einer Beitragsseite klicke auf das Stift-Symbol um den Beitrag zu " "bearbeiten. Bearbeite die Beitrags-Einstellungen mit dem Zahnrad-Symbol. " "Drücke „Esc“ um jedes Fenster zu verlassen." #: public/includes/tour.php:102 msgid "" "Highlight a piece of text, and click on a formatting option to style it. " "Click the Disk icon or CMD-S to save. Click the orange \"X\" button to exit " "the editor." msgstr "" "Markiere einen Textabschnitt und klicke auf eine der Formatoptionen um ihn " "zu gestalten. Klicke das Disketten-Symbol oder drücke Strg+S um zu " "speichern. Klicke den orangen „X“-Button um den Editor zu verlassen." #: public/includes/tour.php:105 msgid "" "Story components can be added by clicking the plus icon, and dragging any " "component from the component tray into the story." msgstr "" "Beitragskomponenten (Aesop Story Engine-Komponenten) können durch klicken " "des Plus-Symbols hinzugefügt werden. Ziehen Sie eine beliebige Komponente in " "den Beitrag um sie zu verwenden." #~ msgid "" #~ "Currently Editus does not support Gutenberg. It will be disabled on " #~ "Gutenberg enabled posts." #~ msgstr "" #~ "Derzeit unterstützt Editus Gutenberg nicht. Es wird für Beiträge, die mit " #~ "Gutenberg bearbeitet werden, deaktiviert." #, fuzzy #~| msgid "Unordered List" #~ msgid "Unordered" #~ msgstr "Aufzählung" #~ msgid "This theme requires the following plugin: %1$s." #~ msgid_plural "This theme requires the following plugins: %1$s." #~ msgstr[0] "Dieses Thema benötigt das folgende Plugin: %1$s." #~ msgstr[1] "" #~ msgid "This theme recommends the following plugin: %1$s." #~ msgid_plural "This theme recommends the following plugins: %1$s." #~ msgstr[0] "Dieses Theme empfiehlt das folgende Plugin: %1$s." #~ msgstr[1] "" #~ msgid "" #~ "Sorry, but you do not have the correct permissions to install the %1$s " #~ "plugin." #~ msgid_plural "" #~ "Sorry, but you do not have the correct permissions to install the %1$s " #~ "plugins." #~ msgstr[0] "" #~ "Pardon, aber Sie haben nicht die erforderlichen Berechtigungen, um dieses " #~ "%1$s Plugin zu installieren." #~ msgstr[1] "" #~ msgid "" #~ "The following plugin needs to be updated to its latest version to ensure " #~ "maximum compatibility with this theme: %1$s." #~ msgid_plural "" #~ "The following plugins need to be updated to their latest version to " #~ "ensure maximum compatibility with this theme: %1$s." #~ msgstr[0] "" #~ "Das folgende Plugin muss auf die neueste Version aktualisiert werden, um " #~ "maximale Kompatibilität mit diesem Thema zu sicher zu stellen: %1$s." #~ msgstr[1] "" #~ msgid "There is an update available for: %1$s." #~ msgid_plural "There are updates available for the following plugins: %1$s." #~ msgstr[0] "Es ist ein Update verfügbar für:%1$s." #~ msgstr[1] "" #~ msgid "" #~ "Sorry, but you do not have the correct permissions to update the %1$s " #~ "plugin." #~ msgid_plural "" #~ "Sorry, but you do not have the correct permissions to update the %1$s " #~ "plugins." #~ msgstr[0] "" #~ "Sorry, aber Sie haben nicht die erforderlichen Berechtigungen, um das " #~ "%1$s Plugin zu aktualisieren." #~ msgstr[1] "" #~ msgid "The following required plugin is currently inactive: %1$s." #~ msgid_plural "The following required plugins are currently inactive: %1$s." #~ msgstr[0] "Das folgende erforderliche Plugin ist derzeit inaktiv: %1$s." #~ msgstr[1] "" #~ msgid "The following recommended plugin is currently inactive: %1$s." #~ msgid_plural "" #~ "The following recommended plugins are currently inactive: %1$s." #~ msgstr[0] "Das folgende empfohlene Plugin ist derzeit inaktiv: %1$s." #~ msgstr[1] "" #~ msgid "" #~ "Sorry, but you do not have the correct permissions to activate the %1$s " #~ "plugin." #~ msgid_plural "" #~ "Sorry, but you do not have the correct permissions to activate the %1$s " #~ "plugins." #~ msgstr[0] "" #~ "Pardon, aber Sie haben nicht die erforderlichen Berechtigungen, um dieses " #~ "%1$s Plugin zu aktivieren." #~ msgstr[1] "" #~ msgid "Begin installing plugin" #~ msgid_plural "Begin installing plugins" #~ msgstr[0] "Beginne mit der Installation des Plugins" #~ msgstr[1] "Beginne mit der Installation der Plugins" #~ msgid "Begin updating plugin" #~ msgid_plural "Begin updating plugins" #~ msgstr[0] "Beginne mit der Aktualisierung des Plugins" #~ msgstr[1] "Beginne mit der Aktualisierung der Plugins" #~ msgid "Begin activating plugin" #~ msgid_plural "Begin activating plugins" #~ msgstr[0] "Beginne mit der Aktivierung des Plugins" #~ msgstr[1] "Beginne mit der Aktivierung ders Plugins" #~ msgid "This plugin needs to be updated to be compatible with your theme." #~ msgstr "" #~ "Dieses Plugin muss aktualisiert werden, um mit Deinem Theme kompatibel zu " #~ "sein." #~ msgid "Update Required" #~ msgstr "Aktualisierung erforderlich" #~ msgid "Set the parent_slug config variable instead." #~ msgstr "Stattdessen die parent_slug-Konfigurationsvariable setzen." #~ msgid "Return to the Dashboard" #~ msgstr "Zurüch zum Dashboard" #~ msgid "" #~ "The remote plugin package does not contain a folder with the desired slug " #~ "and renaming did not work." #~ msgstr "" #~ "Das externe Plugin-Paket enthält keinen Ordner mit der erforderlichen " #~ "Bezeichnung und eine Umbenennung war nicht möglich." #~ msgid "" #~ "Please contact the plugin provider and ask them to package their plugin " #~ "according to the WordPress guidelines." #~ msgstr "" #~ "Bitte wende Dich an den Anbieter des Plugins, um eine Plugin-Version nach " #~ "den WordPress-Richtlinien zu erhalten." #~ msgid "" #~ "The remote plugin package consists of more than one file, but the files " #~ "are not packaged in a folder." #~ msgstr "" #~ "Das externe Plugin-Paket besteht aus mehreren Dateien, die jedoch nicht " #~ "in einem Ordner gepackt wurden." #~ msgctxt "plugin A *and* plugin B" #~ msgid "and" #~ msgstr "Plugin A*und* Plugin B und" #~ msgctxt "%s = version number" #~ msgid "TGMPA v%s" #~ msgstr "TGMPA v% s" #~ msgctxt "%1$s = install status, %2$s = update status" #~ msgid "%1$s, %2$s" #~ msgstr "%1$s, %2$s" #~ msgctxt "plugins" #~ msgid "All (%s)" #~ msgid_plural "All (%s)" #~ msgstr[0] "Alle (%s)" #~ msgstr[1] "" #~ msgid "To Install (%s)" #~ msgid_plural "To Install (%s)" #~ msgstr[0] "%s" #~ msgstr[1] "" #~ msgid "Update Available (%s)" #~ msgid_plural "Update Available (%s)" #~ msgstr[0] "Aktualisierung verfügbar (%s)" #~ msgstr[1] "" #~ msgid "To Activate (%s)" #~ msgid_plural "To Activate (%s)" #~ msgstr[0] "Zum Aktivieren (%s)" #~ msgstr[1] "" #~ msgctxt "as in: \"version nr unknown\"" #~ msgid "unknown" #~ msgstr "unbekannt" #~ msgctxt "%2$s = plugin name in screen reader markup" #~ msgid "Install %2$s" #~ msgstr "Installiere %2$s" #~ msgctxt "%2$s = plugin name in screen reader markup" #~ msgid "Update %2$s" #~ msgstr "Aktualisiere %2$s" #~ msgctxt "%2$s = plugin name in screen reader markup" #~ msgid "Activate %2$s" #~ msgstr "Aktiviere %2$s" #~ msgid "Upgrade message from the plugin author:" #~ msgstr "Upgrade-Nachricht vom Plugin Autor:" #~ msgid "No plugins were selected to be activated. No action taken." #~ msgstr "" #~ "Es wurden keine Plugins zur Aktivierung ausgewählt. Es wurde daher nichts " #~ "unternommen." #~ msgid "No plugins are available to be activated at this time." #~ msgstr "Derzeit stehen keine Plugins zur Aktivierung zur Verfügung." #~ msgid "Show Details" #~ msgstr "Weitere Details" #~ msgid "Hide Details" #~ msgstr "Details verbergen" #~ msgid "%1$s installed successfully." #~ msgstr "%1$s erfolgreich installiert." #~ msgid "This plugin requires the following plugin: %1$s." #~ msgid_plural "This plugin requires the following plugins: %1$s." #~ msgstr[0] "Dieses Plugin erfordert das folgende Plugin:%1$s." #~ msgstr[1] "Dieses Plugin erfordert die folgenden Plugin:%1$s." #~ msgid "This plugin recommends the following plugin: %1$s." #~ msgid_plural "This plugin recommends the following plugins: %1$s." #~ msgstr[0] "Dieses Plugin empfiehlt die folgende Plugin: %1$s." #~ msgstr[1] "Dieses Plugin empfiehlt die folgende Plugins: %1$s." #~ msgid "" #~ "Sorry, but you do not have the correct permissions to install the %s " #~ "plugin. Contact the administrator of this site for help on getting the " #~ "plugin installed." #~ msgid_plural "" #~ "Sorry, but you do not have the correct permissions to install the %s " #~ "plugins. Contact the administrator of this site for help on getting the " #~ "plugins installed." #~ msgstr[0] "" #~ "Sorry, aber Sie haben nicht die richtigen Berechtigungen, um das %s " #~ "Plugin zu installieren. Wenden Sie sich an den Administrator dieser " #~ "Website, um Hilfe bei der Installation des Plugins zu erhalten." #~ msgstr[1] "" #~ "Sorry, aber Sie haben nicht die richtigen Berechtigungen, um das %s " #~ "Plugin zu installieren. Wenden Sie sich an den Administrator dieser " #~ "Website, um Hilfe bei der Installation des Plugins zu erhalten." #~ msgid "" #~ "Sorry, but you do not have the correct permissions to activate the %s " #~ "plugin. Contact the administrator of this site for help on getting the " #~ "plugin activated." #~ msgid_plural "" #~ "Sorry, but you do not have the correct permissions to activate the %s " #~ "plugins. Contact the administrator of this site for help on getting the " #~ "plugins activated." #~ msgstr[0] "" #~ "Entschuldigung, aber Du hast nicht die Berechtigung zum Aktivieren des %s " #~ "Plugin. Wenden Sie sich an den Administrator dieser Website, um Hilfe bei " #~ "der Aktivierung der Plugins zu erhalten." #~ msgstr[1] "" #~ "Entschuldigung, aber Du hast nicht die Berechtigung zum Aktivieren der %s " #~ "Plugins. Wenden Sie sich an den Administrator dieser Website, um Hilfe " #~ "bei der Aktivierung der Plugins zu erhalten." #~ msgid "" #~ "The following plugin needs to be updated to its latest version to ensure " #~ "maximum compatibility with this plugin: %1$s." #~ msgid_plural "" #~ "The following plugins need to be updated to their latest version to " #~ "ensure maximum compatibility with this plugin: %1$s." #~ msgstr[0] "" #~ "Das folgende Plugin muss auf die neueste Version aktualisiert werden, um " #~ "maximale Kompatibilität mit diesem Theme sicher zu stellen: %1$s." #~ msgstr[1] "" #~ "Das folgenden Plugins müssen auf die neueste Version aktualisiert werden, " #~ "um maximale Kompatibilität mit diesem Theme sicher zu stellen: %1$s." #~ msgid "" #~ "Sorry, but you do not have the correct permissions to update the %s " #~ "plugin. Contact the administrator of this site for help on getting the " #~ "plugin updated." #~ msgid_plural "" #~ "Sorry, but you do not have the correct permissions to update the %s " #~ "plugins. Contact the administrator of this site for help on getting the " #~ "plugins updated." #~ msgstr[0] "" #~ "Entschuldigung, aber du hast nicht die richtigen Berechtigungen, um das " #~ "%s Plugin zu aktualisieren. Wende dich an den Administrator dieser " #~ "Website, um Hilfe zum Aktualisieren des Plugins zu erhalten." #~ msgstr[1] "" #~ "Entschuldigung, aber du hast nicht die richtigen Berechtigungen, um diese " #~ "%s Plugin zu aktualisieren. Wende dich an den Administrator dieser " #~ "Website, um Hilfe zum Aktualisieren des Plugins zu erhalten." ================================================ FILE: languages/lasso-es_ES.po ================================================ msgid "" msgstr "" "Project-Id-Version: Editus\n" "POT-Creation-Date: 2022-08-02 15:42-0400\n" "PO-Revision-Date: 2022-08-02 15:43-0400\n" "Last-Translator: \n" "Language-Team: \n" "Language: es_ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 3.1.1\n" "X-Poedit-Basepath: ..\n" "X-Poedit-KeywordsList: __;_e;esc_attr_e\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPathExcluded-0: node_modules\n" #: admin/includes/EDD_SL_Plugin_Updater.php:177 #, php-format msgid "" "There is a new version of %1$s available. View version %3$s details." msgstr "" #: admin/includes/EDD_SL_Plugin_Updater.php:184 #, php-format msgid "" "There is a new version of %1$s available. View version %3$s details or update now." msgstr "" #: admin/includes/EDD_SL_Plugin_Updater.php:324 msgid "You do not have permission to install plugin updates" msgstr "" #: admin/includes/EDD_SL_Plugin_Updater.php:324 msgid "Error" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:333 #: admin/includes/menus/welcome.php:227 msgid "Install Required Plugins" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:334 #: admin/includes/menus/welcome.php:228 msgid "Install Plugins" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:335 #: admin/includes/menus/welcome.php:229 #, php-format msgid "Installing Plugin: %s" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:336 #: admin/includes/menus/welcome.php:230 msgid "Something went wrong with the plugin API." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:397 #: admin/includes/menus/welcome.php:241 msgid "Return to Required Plugins Installer" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:398 msgid "Return to the dashboard" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:399 #: admin/includes/class-tgm-plugin-activation.php:3029 #: admin/includes/menus/welcome.php:242 msgid "Plugin activated successfully." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:400 msgid "The following plugin was activated successfully:" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:401 #, php-format msgid "No action taken. Plugin %1$s was already active." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:402 #, php-format msgid "" "Plugin not activated. A higher version of %s is needed for this theme. " "Please update the plugin." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:403 #, php-format msgid "All plugins installed and activated successfully. %1$s" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:404 msgid "Dismiss this notice" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:405 msgid "Please contact the administrator of this site for help." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2167 msgid "Required" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2170 msgid "Recommended" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2186 msgid "WordPress Repository" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2189 msgid "External Source" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2192 msgid "Pre-Packaged" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2209 msgid "Not Installed" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2213 msgid "Installed But Not Activated" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2215 msgid "Active" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2221 msgid "Required Update not Available" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2224 msgid "Requires Update" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2227 msgid "Update recommended" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2379 msgid "Installed version:" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2387 msgid "Minimum required version:" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2399 msgid "Available version:" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2422 #, php-format msgid "" "No plugins to install, update or activate. Return to the " "Dashboard" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2436 msgid "Plugin" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2437 msgid "Source" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2438 msgid "Type" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2442 #: admin/includes/menus/welcome.php:118 msgid "Version" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2443 #: admin/includes/menus/welcome.php:49 public/includes/editor-modules.php:614 msgid "Status" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2603 msgid "Install" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2609 msgid "Update" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2612 msgid "Activate" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2643 msgid "No plugins were selected to be installed. No action taken." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2645 msgid "No plugins were selected to be updated. No action taken." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2681 msgid "No plugins are available to be installed at this time." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2683 msgid "No plugins are available to be updated at this time." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3028 msgid "Plugin activation failed." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3362 #, php-format msgid "Updating Plugin %1$s (%2$d/%3$d)" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3364 #, php-format msgid "An error occurred while installing %1$s: %2$s." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3365 #, php-format msgid "The installation of %1$s failed." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3369 msgid "" "The installation and activation process is starting. This process may take a " "while on some hosts, so please be patient." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3370 #, php-format msgid "%1$s installed and activated successfully." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3371 msgid "All installations and activations have been completed." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3372 #, php-format msgid "Installing and Activating Plugin %1$s (%2$d/%3$d)" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3375 msgid "" "The installation process is starting. This process may take a while on some " "hosts, so please be patient." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3377 msgid "All installations have been completed." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3378 #, php-format msgid "Installing Plugin %1$s (%2$d/%3$d)" msgstr "" #: admin/includes/load_admin.php:151 msgid "Dismiss this notice." msgstr "" #: admin/includes/menus/license.php:30 msgid "Aesopinteractive LLC" msgstr "Aesopinteractive LLC" #: admin/includes/menus/license.php:38 admin/includes/menus/license.php:57 msgid "License Key" msgstr "" #: admin/includes/menus/license.php:38 msgid "License" msgstr "" #: admin/includes/menus/license.php:47 msgid "Editus License" msgstr "" #: admin/includes/menus/license.php:48 msgid "" "Input the license key you recieved with your purchase to ensure your version " "of Editus stays updated." msgstr "" #: admin/includes/menus/license.php:66 admin/includes/menus/license.php:75 msgid "Activate License" msgstr "" #: admin/includes/menus/license.php:70 msgid "active" msgstr "" #: admin/includes/menus/license.php:72 msgid "Deactivate License" msgstr "" #: admin/includes/menus/settings.php:26 public/includes/editor-modules.php:493 #: public/includes/editor-modules.php:892 #: public/includes/editor-modules.php:894 #: public/includes/editor-modules.php:909 #: public/includes/editor-modules.php:928 msgid "Settings" msgstr "" #: admin/includes/menus/settings.php:169 msgid "Editus Settings" msgstr "" #: admin/includes/menus/settings.php:177 msgid "Enable for:" msgstr "" #: admin/includes/menus/settings.php:181 msgid "Enable Editus for the following post types." msgstr "" #: admin/includes/menus/settings.php:203 msgid "Internal Settings" msgstr "" #: admin/includes/menus/settings.php:206 msgid "Article Class" msgstr "" #: admin/includes/menus/settings.php:207 msgid "" "Provide the CSS class (including the preceding dot) of container that holds " "the post. This should be the first parent container class that holds " "the_content." msgstr "" #: admin/includes/menus/settings.php:212 msgid "Featured Image Class" msgstr "" #: admin/includes/menus/settings.php:213 msgid "" "Provide the CSS class that uses a featured image as a background image. This " "currently only supports themes that have the featured image set as " "background image." msgstr "" #: admin/includes/menus/settings.php:218 msgid "Article Title Class" msgstr "" #: admin/includes/menus/settings.php:219 msgid "" "Provide the CSS class for the post title. This will enable you to update the " "title of the post by clicking and typing." msgstr "" #: admin/includes/menus/settings.php:224 msgid "Ignored Items to Save" msgstr "" #: admin/includes/menus/settings.php:225 msgid "" "If your post container holds additional markup, list the css class names " "(comma separated, including the dot) of those items. When you enter the " "editor, Editus will remove (NOT delete) these items so that it does not save " "them as HTML." msgstr "" #: admin/includes/menus/settings.php:230 msgid "Read Only Items" msgstr "" #: admin/includes/menus/settings.php:231 msgid "" "If your post has items that should not be editable, list the css class names " "(comma separated, including the dot) of those items." msgstr "" #: admin/includes/menus/settings.php:237 msgid "Show Ignored Items" msgstr "" #: admin/includes/menus/settings.php:238 msgid "" "By default the ignored items are hidden. Check this to show ignored items " "while keeping them uneditable." msgstr "" #: admin/includes/menus/settings.php:242 msgid "Editor UI" msgstr "" #: admin/includes/menus/settings.php:246 msgid "Use the Old Toolbar" msgstr "" #: admin/includes/menus/settings.php:247 msgid "" "Use this option to disable the new color options and use the pre-1.0 toolbar." msgstr "" #: admin/includes/menus/settings.php:251 msgid "Editor Bar Color Top" msgstr "" #: admin/includes/menus/settings.php:252 msgid "Editor Bar Color Bottom" msgstr "" #: admin/includes/menus/settings.php:253 msgid "Dialog Color" msgstr "" #: admin/includes/menus/settings.php:254 msgid "Icon/Text Color" msgstr "" #: admin/includes/menus/settings.php:256 msgid "Default Colors" msgstr "" #: admin/includes/menus/settings.php:261 msgid "Enable H2 and H3 Buttons" msgstr "" #: admin/includes/menus/settings.php:262 msgid "Show the buttons to set H2 and H3 settings." msgstr "" #: admin/includes/menus/settings.php:267 msgid "Enable H4/H5/H6 Buttons" msgstr "" #: admin/includes/menus/settings.php:268 msgid "Show the buttons to set H4/H5/H6 settings." msgstr "" #: admin/includes/menus/settings.php:274 msgid "Enable OL/UL Buttons" msgstr "" #: admin/includes/menus/settings.php:275 msgid "" "Show the buttons to create Ordered and Unordered Lists from text selection." msgstr "" #: admin/includes/menus/settings.php:280 msgid "Enable Text Color Buttons" msgstr "" #: admin/includes/menus/settings.php:281 msgid "Show the buttons to set text colors." msgstr "" #: admin/includes/menus/settings.php:286 msgid "Enable Text Align Buttons" msgstr "" #: admin/includes/menus/settings.php:287 msgid "Show the buttons to set text alignment." msgstr "" #: admin/includes/menus/settings.php:293 msgid "Make links editable under the Editing Mode" msgstr "" #: admin/includes/menus/settings.php:294 msgid "" "Make links editable under the Editing Mode. Turning this on will make the " "links non-clickable while editing." msgstr "" #: admin/includes/menus/settings.php:298 msgid "Insert Component UI" msgstr "" #: admin/includes/menus/settings.php:299 msgid "UI mechanism to insert components" msgstr "" #: admin/includes/menus/settings.php:301 msgid "Drag and Drop" msgstr "" #: admin/includes/menus/settings.php:304 msgid "Click" msgstr "" #: admin/includes/menus/settings.php:307 msgid "Auto Button on Empty Paragraph. medium.com-like UI." msgstr "" #: admin/includes/menus/settings.php:313 msgid "Popup When Text is Selected" msgstr "" #: admin/includes/menus/settings.php:314 msgid "" "Instead of using the bottom toolbar to format texts, use a popup box to " "format texts." msgstr "" #: admin/includes/menus/settings.php:320 msgid "Component" msgstr "" #: admin/includes/menus/settings.php:324 msgid "Additional Component: Table" msgstr "" #: admin/includes/menus/settings.php:325 msgid "Allow user to add and edit tables." msgstr "" #: admin/includes/menus/settings.php:331 msgid "Additional Component: Paragraph" msgstr "" #: admin/includes/menus/settings.php:332 msgid "Plain HTML Paragraph." msgstr "" #: admin/includes/menus/settings.php:363 msgid "Use Simple Image" msgstr "" #: admin/includes/menus/settings.php:364 msgid "Use Simple Image Component without Extra Options." msgstr "" #: admin/includes/menus/settings.php:371 msgid "Use WP Image Block" msgstr "" #: admin/includes/menus/settings.php:372 msgid "" "Use WP Image Block as the image component. Gutenberg Block Editor needs to " "be enabled." msgstr "" #: admin/includes/menus/settings.php:379 msgid "Post Settings UI" msgstr "" #: admin/includes/menus/settings.php:383 msgid "Disable Post Settings" msgstr "" #: admin/includes/menus/settings.php:384 msgid "" "Check this to disable users from being able to edit post settings from the " "front-end." msgstr "" #: admin/includes/menus/settings.php:389 msgid "Allow Changing Post Date" msgstr "" #: admin/includes/menus/settings.php:390 msgid "" "Add the date selector to change the post's date to the Post Setting dialog" msgstr "" #: admin/includes/menus/settings.php:395 msgid "Allow Editing Excerpt" msgstr "" #: admin/includes/menus/settings.php:396 msgid "Allow the post's excerpt to be edited in the Post Setting dialog" msgstr "" #: admin/includes/menus/settings.php:401 msgid "Allow Adding New Category" msgstr "" #: admin/includes/menus/settings.php:402 msgid "" "Add the user to create new, previously non-existing categories for posts." msgstr "" #: admin/includes/menus/settings.php:407 msgid "Do Not Allow \"Pending\" Status" msgstr "" #: admin/includes/menus/settings.php:408 msgid "Remove the Option to Set the Status to Pending." msgstr "" #: admin/includes/menus/settings.php:413 msgid "Remove POST URL Option" msgstr "" #: admin/includes/menus/settings.php:414 msgid "Remove the Option to Set the URL for the Post." msgstr "" #: admin/includes/menus/settings.php:419 msgid "Disable Post Adding" msgstr "" #: admin/includes/menus/settings.php:420 msgid "" "Check this box to disable users from being able to add new posts from the " "front-end." msgstr "" #: admin/includes/menus/settings.php:425 msgid "Support Custom Taxonomy" msgstr "" #: admin/includes/menus/settings.php:426 msgid "Allow editing custom taxonomies." msgstr "" #: admin/includes/menus/settings.php:432 msgid "Misc" msgstr "" #: admin/includes/menus/settings.php:436 msgid "Do Not Show Tour Dialog" msgstr "" #: admin/includes/menus/settings.php:437 msgid "Check this box to disable the tour dialog box for all users." msgstr "" #: admin/includes/menus/settings.php:441 msgid "Placeholder Text for New Post" msgstr "" #: admin/includes/menus/settings.php:442 msgid "Placeholder text to be displayed when a new post is created." msgstr "" #: admin/includes/menus/settings.php:443 includes/process/new_object.php:38 #: public/includes/assets.php:248 msgid "Once upon a time..." msgstr "" #: admin/includes/menus/settings.php:448 msgid "Do Not Allow Shortcode Editing" msgstr "" #: admin/includes/menus/settings.php:449 msgid "Check this box to disable frontend editing of shortcodes." msgstr "" #: admin/includes/menus/settings.php:453 msgid "\"Bold\" Tag" msgstr "" #: admin/includes/menus/settings.php:454 msgid "Choose the HTML tag used for the \"Bold\" style." msgstr "" #: admin/includes/menus/settings.php:459 msgid "\"Italic\" Tag" msgstr "" #: admin/includes/menus/settings.php:460 msgid "Choose the HTML tag used for the \"Italic\" style." msgstr "" #: admin/includes/menus/settings.php:466 msgid "Auto Prefix HTTP to links" msgstr "" #: admin/includes/menus/settings.php:467 msgid "" "When user adds a hyperlink, automatically add http:// if the user does not " "specify it explicitly." msgstr "" #: admin/includes/menus/settings.php:471 msgid "Advanced Options" msgstr "" #: admin/includes/menus/settings.php:472 msgid "" "Suggested not to turn these options on without consulting the developer." msgstr "" #: admin/includes/menus/settings.php:477 msgid "Disable Aesop Component Conversion" msgstr "" #: admin/includes/menus/settings.php:478 msgid "" "Check this box to disable the conversion process used on Aesop Story Engine " "components." msgstr "" #: admin/includes/menus/settings.php:483 msgid "Enable Auto Save" msgstr "" #: admin/includes/menus/settings.php:484 msgid "Check this box to enable auto save." msgstr "" #: admin/includes/menus/settings.php:489 msgid "Disable Post Saving" msgstr "" #: admin/includes/menus/settings.php:490 msgid "" "By default the editor will update the database with the post or page it is " "being used on. Check this box to disable this. If you check this box, it is " "assumed that you will be using the provided filters to save your own content." msgstr "" #: admin/includes/menus/settings.php:496 msgid "Disable Post Editing" msgstr "" #: admin/includes/menus/settings.php:497 msgid "" "You may use this option if you only want to edit custom fields. Refer here for more information. The custom fields you specify will be " "still editable under the editing mode." msgstr "" #: admin/includes/menus/settings.php:503 msgid "Don't Use REST API to Save" msgstr "" #: admin/includes/menus/settings.php:504 msgid "" "By default the editor will use REST API to save posts. Check this box to use " "custom AJAX calls instead." msgstr "" #: admin/includes/menus/settings.php:510 msgid "Don't Wrap Shortcodes" msgstr "" #: admin/includes/menus/settings.php:511 msgid "" "By default Editus wraps shortcodes so they can be preserved. Disable this " "behavior." msgstr "" #: admin/includes/menus/settings.php:521 msgid "Save Settings" msgstr "" #: admin/includes/menus/welcome.php:48 msgid "Editus" msgstr "" #: admin/includes/menus/welcome.php:49 msgid "Welcome" msgstr "" #: admin/includes/menus/welcome.php:71 msgid "" "We will check the current theme on every site in your network and give you a " "quick status feedback here. You can see the status by visiting the Editus " "menu on each site." msgstr "" #: admin/includes/menus/welcome.php:90 msgid "You're Ready to Rock!" msgstr "" #: admin/includes/menus/welcome.php:92 msgid "Your theme is automatically supported. No additional setup is needed." msgstr "" #: admin/includes/menus/welcome.php:94 msgid "" "Editus will place a small menu on the bottom of your site. While on a single " "post or page, click the \"pen\" icon to go into edit mode. Press escape to " "get out of edit mode." msgstr "" #: admin/includes/menus/welcome.php:117 msgid "Welcome to Editus" msgstr "" #: admin/includes/menus/welcome.php:123 msgid "Help" msgstr "" #: admin/includes/menus/welcome.php:124 msgid "Twitter" msgstr "" #: admin/includes/menus/welcome.php:125 msgid "Facebook" msgstr "" #: admin/includes/menus/welcome.php:158 msgid "Article CSS Class Needed!" msgstr "" #: admin/includes/menus/welcome.php:159 msgid "Before using Editus," msgstr "" #: admin/includes/menus/welcome.php:159 msgid "enter and save" msgstr "" #: admin/includes/menus/welcome.php:159 msgid "" "the CSS class of the container that holds your post and page content. You " "can use a tool like " "inspector in Chrome or Firefox to find this CSS class, or " msgstr "" #: admin/includes/menus/welcome.php:159 msgid "email us." msgstr "" #: admin/includes/menus/welcome.php:159 msgid "with a link to a public URL with the theme and we'll find it for you." msgstr "" #: admin/includes/menus/welcome.php:166 msgid "" "Just a heads up that the WP REST API isn't activated. This is required to " "list the posts and pages on the front-end." msgstr "" #: admin/includes/menus/welcome.php:173 msgid "Just a heads up that " msgstr "" #: admin/includes/menus/welcome.php:174 admin/includes/menus/welcome.php:211 msgid "Aesop Story Engine" msgstr "" #: admin/includes/menus/welcome.php:174 msgid "" "isn't activated. It's not required to use Editus, but you won't get the cool " "drag and drop components without it activated. It's free!" msgstr "" #: admin/includes/menus/welcome.php:180 msgid "WP Side Comments Compatibility Warning!" msgstr "" #: admin/includes/menus/welcome.php:181 msgid "" "Since Editus saves the HTML of a post, this may cause undesired issues. " "We're working to resolve incompatibilities faster than a jack rabbit in a " "hot greasy griddle in the middle of August." msgstr "" #: admin/includes/menus/welcome.php:187 msgid "License Key Not Activated" msgstr "" #: admin/includes/menus/welcome.php:188 msgid "" "Just a heads up, your license key isn't activated. Enter your license key " "into the License tab on the left in order to receive plugin update " "notifications." msgstr "" #: admin/includes/menus/welcome.php:192 msgid "License Key Invalid" msgstr "" #: admin/includes/menus/welcome.php:193 msgid "The license key that you entered is " msgstr "" #: admin/includes/menus/welcome.php:193 msgid "invalid" msgstr "" #: admin/includes/menus/welcome.php:193 msgid ". It may have been entered incorreclty, or may have expired." msgstr "" #: admin/includes/menus/welcome.php:243 #, php-format msgid "All plugins installed and activated successfully. %s" msgstr "" #: includes/process/gallery.php:40 msgid "Save and refresh to view gallery." msgstr "" #: includes/process/gallery.php:199 msgid "Delete From Gallery" msgstr "" #: includes/process/gallery.php:200 msgid "Edit Image Caption" msgstr "" #: internal-api/auth.php:67 msgid "Unauthorized action" msgstr "" #: internal-api/auth.php:71 msgid "" "All callback classes used for processing the Editus Internal API must " "implement the lasso\\internal_api\\api_action interface." msgstr "" #: internal-api/auth.php:76 msgid "Nonce invalid" msgstr "" #: internal-api/route.php:30 msgid "Editus API Error." msgstr "" #: internal-api/route.php:66 msgid "Nonce not set." msgstr "" #: lasso.php:130 msgid "Insert Column" msgstr "" #: lasso.php:131 msgid "Insert Row" msgstr "" #: lasso.php:132 msgid "Delete Column" msgstr "" #: lasso.php:133 msgid "Delete Row" msgstr "" #: lasso.php:134 msgid "Delete Table" msgstr "" #: lasso.php:149 lasso.php:159 msgid "HTML Table" msgstr "" #: lasso.php:192 lasso.php:220 msgid "HTML Paragraph" msgstr "" #: public/includes/assets.php:146 public/includes/editor-modules.php:713 #: public/includes/option-engine.php:132 msgid "Save" msgstr "" #: public/includes/assets.php:147 msgid "Please Select Text First." msgstr "" #: public/includes/assets.php:148 public/includes/editor-modules.php:439 #: public/includes/editor-modules.php:706 #: public/includes/editor-modules.php:788 #: public/includes/editor-modules.php:1329 msgid "Cancel" msgstr "Cancelar" #: public/includes/assets.php:149 msgid "Exit Editor" msgstr "" #: public/includes/assets.php:150 msgid "Saving..." msgstr "" #: public/includes/assets.php:151 msgid "Saved!" msgstr "" #: public/includes/assets.php:152 msgid "Adding..." msgstr "" #: public/includes/assets.php:153 msgid "Added!" msgstr "" #: public/includes/assets.php:154 msgid "Loading..." msgstr "" #: public/includes/assets.php:155 msgid "Load More" msgstr "" #: public/includes/assets.php:156 public/includes/helpers.php:457 msgid "Close" msgstr "Cerra" #: public/includes/assets.php:157 msgid "No more posts found" msgstr "" #: public/includes/assets.php:158 msgid "Fetching failed." msgstr "" #: public/includes/assets.php:159 msgid "Gallery Created!" msgstr "" #: public/includes/assets.php:160 msgid "Gallery Updated!" msgstr "" #: public/includes/assets.php:161 msgid "Just write..." msgstr "" #: public/includes/assets.php:162 msgid "Choose an image" msgstr "" #: public/includes/assets.php:163 msgid "Update Image" msgstr "" #: public/includes/assets.php:164 msgid "Insert Image" msgstr "" #: public/includes/assets.php:165 msgid "Select Image" msgstr "" #: public/includes/assets.php:166 msgid "Remove featured image?" msgstr "" #: public/includes/assets.php:167 msgid "Update Selected Image" msgstr "" #: public/includes/assets.php:168 msgid "Choose images" msgstr "" #: public/includes/assets.php:169 msgid "Edit Image" msgstr "" #: public/includes/assets.php:170 #: public/includes/editor-modules--gallery.php:28 msgid "Add Images" msgstr "" #: public/includes/assets.php:171 msgid "Add New Gallery" msgstr "" #: public/includes/assets.php:172 msgid "Select Editus Gallery Image" msgstr "" #: public/includes/assets.php:173 msgid "Use Selected Images" msgstr "" #: public/includes/assets.php:174 msgid "Publish Post?" msgstr "" #: public/includes/assets.php:175 msgid "Yes, publish it!" msgstr "" #: public/includes/assets.php:176 msgid "Trash Post?" msgstr "" #: public/includes/assets.php:177 msgid "Yes, trash it!" msgstr "" #: public/includes/assets.php:178 msgid "Oh snap!" msgstr "" #: public/includes/assets.php:179 msgid "O.K. got it!" msgstr "" #: public/includes/assets.php:180 msgid "" "It looks like we are either missing the Article CSS class, or it is " "configured incorrectly. Editus will not function correctly without this CSS " "class." msgstr "" #: public/includes/assets.php:181 msgid "Update Settings" msgstr "" #: public/includes/assets.php:182 msgid "one more letter" msgstr "" #: public/includes/assets.php:183 msgid "You are currently editing a backup copy of this post." msgstr "" #: public/includes/assets.php:185 msgid "add categories..." msgstr "" #: public/includes/assets.php:186 msgid "add tags..." msgstr "" #: public/includes/assets.php:187 msgid "add taxonomy terms..." msgstr "" #: public/includes/assets.php:188 msgid "Edit Shortcode" msgstr "" #: public/includes/components.php:19 public/includes/editor-modules.php:352 msgid "Quote" msgstr "" #: public/includes/components.php:23 public/includes/editor-modules.php:350 #: public/includes/editor-modules.php:1103 #: public/includes/editor-modules.php:1154 #: public/includes/editor-modules.php:1218 msgid "Image" msgstr "" #: public/includes/components.php:27 #: public/includes/editor-modules--gallery.php:74 #: public/includes/editor-modules.php:355 msgid "Parallax" msgstr "" #: public/includes/components.php:31 public/includes/editor-modules.php:356 msgid "Audio" msgstr "" #: public/includes/components.php:35 public/includes/editor-modules.php:353 #: public/includes/editor-modules.php:1080 msgid "Content" msgstr "" #: public/includes/components.php:39 public/includes/editor-modules.php:351 msgid "Character" msgstr "" #: public/includes/components.php:43 public/includes/editor-modules.php:361 msgid "Collection" msgstr "" #: public/includes/components.php:47 public/includes/editor-modules.php:360 msgid "Document" msgstr "" #: public/includes/components.php:51 public/includes/editor-modules.php:362 msgid "Gallery" msgstr "" #: public/includes/components.php:55 public/includes/editor-modules.php:354 msgid "Chapter" msgstr "" #: public/includes/components.php:59 public/includes/editor-modules.php:358 msgid "Map" msgstr "Mapa" #: public/includes/components.php:63 public/includes/editor-modules.php:359 msgid "Timeline" msgstr "" #: public/includes/components.php:67 public/includes/editor-modules.php:357 msgid "Video" msgstr "" #: public/includes/components.php:71 public/includes/components.php:91 #: public/includes/editor-modules.php:371 #: public/includes/editor-modules.php:373 msgid "WordPress Image" msgstr "" #: public/includes/components.php:75 msgid "WordPress Image Block" msgstr "" #: public/includes/components.php:79 public/includes/editor-modules.php:375 msgid "WordPress Quote" msgstr "" #: public/includes/components.php:83 public/includes/editor-modules.php:364 msgid "Gallery Pop" msgstr "" #: public/includes/components.php:87 msgid "Events" msgstr "" #: public/includes/editor-modules--gallery.php:19 msgid "Create gallery" msgstr "" #: public/includes/editor-modules--gallery.php:27 msgid "Manage Images" msgstr "" #: public/includes/editor-modules--gallery.php:31 msgid "Rearrange or edit the images in this gallery." msgstr "" #: public/includes/editor-modules--gallery.php:47 msgid "Create a Gallery" msgstr "" #: public/includes/editor-modules--gallery.php:51 msgid "Select images to create a gallery." msgstr "" #: public/includes/editor-modules--gallery.php:52 msgid "Select Images" msgstr "" #: public/includes/editor-modules--gallery.php:56 msgid "Create Gallery" msgstr "" #: public/includes/editor-modules--gallery.php:67 msgid "Gallery Type" msgstr "" #: public/includes/editor-modules--gallery.php:68 msgid "Select the type of gallery." msgstr "" #: public/includes/editor-modules--gallery.php:70 msgid "Grid" msgstr "" #: public/includes/editor-modules--gallery.php:71 msgid "Thumbnail" msgstr "" #: public/includes/editor-modules--gallery.php:73 msgid "Photoset" msgstr "" #: public/includes/editor-modules--gallery.php:84 msgid "Grid Item Width" msgstr "" #: public/includes/editor-modules--gallery.php:85 msgid "" "Adjust the width of the individual grid items, only if using Grid gallery " "style. Default is 400." msgstr "" #: public/includes/editor-modules--gallery.php:95 msgid "Gallery Transition" msgstr "" #: public/includes/editor-modules--gallery.php:96 msgid "" "Adjust the transition effect for the Thumbnail gallery. Default is slide." msgstr "" #: public/includes/editor-modules--gallery.php:98 msgid "Fade" msgstr "" #: public/includes/editor-modules--gallery.php:99 msgid "Slide" msgstr "" #: public/includes/editor-modules--gallery.php:100 msgid "Dissolve" msgstr "" #: public/includes/editor-modules--gallery.php:105 msgid "Gallery Transition Speed" msgstr "" #: public/includes/editor-modules--gallery.php:106 msgid "" "Activate slideshow by setting a speed for the transition.5000 = 5 seconds." msgstr "" #: public/includes/editor-modules--gallery.php:112 msgid "Hide Gallery Thumbnails" msgstr "" #: public/includes/editor-modules--gallery.php:121 msgid "Gallery Layout" msgstr "" #: public/includes/editor-modules--gallery.php:122 msgid "" "Let's say you have 4 images in this gallery. If you enter 121 you will have " "one image on the top row, two images on the second row, and one image on the " "third row." msgstr "" #: public/includes/editor-modules--gallery.php:137 msgid "Main Gallery Height" msgstr "" #: public/includes/editor-modules--gallery.php:138 #, php-format msgid "" "Adjust the overall height of the gallery. Acceptable values include 500px or " "50% etc." msgstr "" #: public/includes/editor-modules--gallery.php:148 msgid "Main Gallery Width" msgstr "" #: public/includes/editor-modules--gallery.php:149 #, php-format msgid "" "Adjust the overall width of the gallery. Acceptable values include 500px or " "50% etc." msgstr "" #: public/includes/editor-modules--gallery.php:153 msgid "Gallery Caption" msgstr "" #: public/includes/editor-modules--gallery.php:154 msgid "Add an optional caption for the gallery." msgstr "" #: public/includes/editor-modules.php:60 public/includes/editor-modules.php:437 msgid "Table" msgstr "" #: public/includes/editor-modules.php:137 #: public/includes/underscore-templates.php:23 #: public/includes/underscore-templates.php:41 msgid "Edit Post" msgstr "" #: public/includes/editor-modules.php:140 #: public/includes/editor-modules.php:164 #: public/includes/editor-modules.php:457 msgid "Post Settings" msgstr "" #: public/includes/editor-modules.php:145 msgid "All Posts" msgstr "" #: public/includes/editor-modules.php:148 #: public/includes/editor-modules.php:1323 msgid "Revisions" msgstr "" #: public/includes/editor-modules.php:152 msgid "Add Post" msgstr "" #: public/includes/editor-modules.php:163 #: public/includes/editor-modules.php:456 #: public/includes/underscore-templates.php:25 #: public/includes/underscore-templates.php:43 msgid "Delete Post" msgstr "" #: public/includes/editor-modules.php:167 #: public/includes/editor-modules.php:459 msgid "Save Post" msgstr "" #: public/includes/editor-modules.php:170 #: public/includes/editor-modules.php:462 msgid "Publish Post" msgstr "" #: public/includes/editor-modules.php:170 msgid "Submit For Review" msgstr "" #: public/includes/editor-modules.php:249 #: public/includes/editor-modules.php:342 msgid "Bold" msgstr "" #: public/includes/editor-modules.php:250 #: public/includes/editor-modules.php:343 msgid "Underline" msgstr "" #: public/includes/editor-modules.php:251 #: public/includes/editor-modules.php:344 msgid "Italicize" msgstr "" #: public/includes/editor-modules.php:252 #: public/includes/editor-modules.php:345 msgid "Strikethrough" msgstr "" #: public/includes/editor-modules.php:255 #: public/includes/editor-modules.php:384 #: public/includes/editor-modules.php:431 msgid "H2 Heading" msgstr "" #: public/includes/editor-modules.php:256 #: public/includes/editor-modules.php:385 #: public/includes/editor-modules.php:432 msgid "H3 Heading" msgstr "" #: public/includes/editor-modules.php:262 #: public/includes/editor-modules.php:391 msgid "H4 Heading" msgstr "" #: public/includes/editor-modules.php:263 #: public/includes/editor-modules.php:392 msgid "H5 Heading" msgstr "" #: public/includes/editor-modules.php:264 #: public/includes/editor-modules.php:393 msgid "H6 Heading" msgstr "" #: public/includes/editor-modules.php:268 #: public/includes/editor-modules.php:397 msgid "Set Color for Selected Text" msgstr "" #: public/includes/editor-modules.php:269 #: public/includes/editor-modules.php:398 msgid "Choose Color" msgstr "" #: public/includes/editor-modules.php:273 #: public/includes/editor-modules.php:402 #: public/includes/editor-modules.php:434 msgid "Ordered List" msgstr "" #: public/includes/editor-modules.php:274 #: public/includes/editor-modules.php:403 #: public/includes/editor-modules.php:435 msgid "Unordered List" msgstr "" #: public/includes/editor-modules.php:278 #: public/includes/editor-modules.php:407 msgid "Anchor Link" msgstr "" #: public/includes/editor-modules.php:280 #: public/includes/editor-modules.php:409 msgid "http://url.com" msgstr "" #: public/includes/editor-modules.php:281 #: public/includes/editor-modules.php:410 msgid "Create Link" msgstr "" #: public/includes/editor-modules.php:283 #: public/includes/editor-modules.php:412 msgid "Open in a New Tab" msgstr "" #: public/includes/editor-modules.php:347 msgid "Insert Component" msgstr "" #: public/includes/editor-modules.php:367 msgid "Event" msgstr "" #: public/includes/editor-modules.php:376 msgid "WordPress Video" msgstr "" #: public/includes/editor-modules.php:419 #: public/includes/editor-modules.php:440 msgid "Insert HTML or Code" msgstr "" #: public/includes/editor-modules.php:421 #: public/includes/editor-modules.php:424 msgid "Enter HTML to insert" msgstr "" #: public/includes/editor-modules.php:425 msgid "You can also use Shortcodes" msgstr "" #: public/includes/editor-modules.php:426 msgid "" "You can also enter a URL to embed, such as Youtube, Vimeo and Twitter URLs." msgstr "" #: public/includes/editor-modules.php:440 msgid "Insert" msgstr "" #: public/includes/editor-modules.php:446 msgid "Text Left Align" msgstr "" #: public/includes/editor-modules.php:447 msgid "Text Center Align" msgstr "" #: public/includes/editor-modules.php:448 msgid "Text Right Align" msgstr "" #: public/includes/editor-modules.php:492 #: public/includes/editor-modules.php:890 #: public/includes/editor-modules.php:908 #: public/includes/editor-modules.php:927 msgid "Move" msgstr "" #: public/includes/editor-modules.php:494 #: public/includes/editor-modules.php:896 #: public/includes/editor-modules.php:910 #: public/includes/editor-modules.php:929 msgid "Clone" msgstr "" #: public/includes/editor-modules.php:495 #: public/includes/editor-modules.php:897 #: public/includes/editor-modules.php:911 #: public/includes/editor-modules.php:930 msgid "Delete" msgstr "" #: public/includes/editor-modules.php:517 msgid "Replace Image" msgstr "" #: public/includes/editor-modules.php:518 msgid "Delete Image" msgstr "" #: public/includes/editor-modules.php:519 msgid "save" msgstr "" #: public/includes/editor-modules.php:593 msgid "Featured Image" msgstr "" #: public/includes/editor-modules.php:593 msgid "Change the featured image for this post." msgstr "" #: public/includes/editor-modules.php:597 msgid "Change Featured Image" msgstr "" #: public/includes/editor-modules.php:598 msgid "Delete Featured Image" msgstr "" #: public/includes/editor-modules.php:614 msgid "Change the status of the post to draft or publish." msgstr "" #: public/includes/editor-modules.php:616 msgid "Draft" msgstr "" #: public/includes/editor-modules.php:618 msgid "Pending" msgstr "" #: public/includes/editor-modules.php:620 msgid "Publish" msgstr "" #: public/includes/editor-modules.php:630 msgid "Post URL" msgstr "" #: public/includes/editor-modules.php:630 msgid "Change the URL (slug) of this post." msgstr "" #: public/includes/editor-modules.php:640 msgid "Categories" msgstr "" #: public/includes/editor-modules.php:640 msgid "Type a category name and press enter." msgstr "" #: public/includes/editor-modules.php:645 msgid "Tags" msgstr "" #: public/includes/editor-modules.php:645 msgid "Type a tag name and press enter." msgstr "" #: public/includes/editor-modules.php:653 msgid "Custom Taxonomy" msgstr "" #: public/includes/editor-modules.php:653 msgid "Choose custom taxonomy." msgstr "" #: public/includes/editor-modules.php:670 msgid "Excerpt" msgstr "" #: public/includes/editor-modules.php:670 msgid "Edit excerpt" msgstr "" #: public/includes/editor-modules.php:679 msgid "Post Date" msgstr "Fecha del Artículo" #: public/includes/editor-modules.php:681 msgid "Set to Now" msgstr "" #: public/includes/editor-modules.php:762 msgid "New post title" msgstr "Escribe el nombre de tu entrada/proyecto " #: public/includes/editor-modules.php:762 msgid "Specify title for new post, then save to edit." msgstr "" "Especificar el título de mensaje nuevo, a continuación, guardar editar." #: public/includes/editor-modules.php:763 msgid "Type Your Title Here" msgstr "Aquí titulo de tu entrada/proyecto" #: public/includes/editor-modules.php:800 msgid "Create" msgstr "Crear" #: public/includes/editor-modules.php:839 msgid "results found" msgstr "resultados encontrados" #: public/includes/editor-modules.php:952 msgid "Save Locations" msgstr "guardar ubicaciones" #: public/includes/editor-modules.php:970 msgid "Save this post and refesh the page to see these changes." msgstr "Guarde este post y refesh la página para ver los cambios." #: public/includes/editor-modules.php:1109 #: public/includes/editor-modules.php:1224 #: public/includes/editor-modules.php:1289 msgid "Image URL" msgstr "" #: public/includes/editor-modules.php:1110 #: public/includes/editor-modules.php:1225 #: public/includes/editor-modules.php:1290 msgid "" "URL for the image. Click Select Media to open the WordPress Media " "Library." msgstr "" #: public/includes/editor-modules.php:1117 #: public/includes/editor-modules.php:1232 msgid "Center" msgstr "" #: public/includes/editor-modules.php:1121 #: public/includes/editor-modules.php:1236 msgid "Left" msgstr "" #: public/includes/editor-modules.php:1125 #: public/includes/editor-modules.php:1240 msgid "Right" msgstr "" #: public/includes/editor-modules.php:1129 #: public/includes/editor-modules.php:1244 msgid "Alignment" msgstr "" #: public/includes/editor-modules.php:1136 msgid "Image Width" msgstr "" #: public/includes/editor-modules.php:1137 msgid "" "Width of the image. You can enter the size in pixels or percentage such as " "40% or 500px." msgstr "" #: public/includes/editor-modules.php:1142 msgid "Image Height" msgstr "" #: public/includes/editor-modules.php:1143 msgid "" "Used only for the Panorama mode. Can be set using pixel values such as " "500px. If unspecified, the original height would be used. " msgstr "" #: public/includes/editor-modules.php:1150 msgid "None" msgstr "" #: public/includes/editor-modules.php:1158 msgid "URL" msgstr "" #: public/includes/editor-modules.php:1162 msgid "Link" msgstr "" #: public/includes/editor-modules.php:1163 msgid "Click leads to:" msgstr "" #: public/includes/editor-modules.php:1169 msgid "URL Link" msgstr "" #: public/includes/editor-modules.php:1170 msgid "URL link" msgstr "" #: public/includes/editor-modules.php:1175 #: public/includes/editor-modules.php:1250 msgid "Image ALT" msgstr "" #: public/includes/editor-modules.php:1176 #: public/includes/editor-modules.php:1251 msgid "ALT tag used for the image. Primarily used for SEO purposes." msgstr "" #: public/includes/editor-modules.php:1182 #: public/includes/editor-modules.php:1256 msgid "Caption" msgstr "" #: public/includes/editor-modules.php:1183 #: public/includes/editor-modules.php:1257 msgid "Optional caption for the image." msgstr "" #: public/includes/editor-modules.php:1188 msgid "An image." msgstr "" #: public/includes/editor-modules.php:1262 msgid "Link URL" msgstr "" #: public/includes/editor-modules.php:1263 msgid "Optional URL to link." msgstr "" #: public/includes/editor-modules.php:1268 msgid "A WP Image Block." msgstr "" #: public/includes/editor-modules.php:1283 msgid "Cover" msgstr "" #: public/includes/editor-modules.php:1294 msgid "A WP Cover Block." msgstr "" #: public/includes/editor-modules.php:1323 msgid "Use the slider to view the revision live on the page." msgstr "" "Utilice el control deslizante para ver la revisión en vivo en la página." #: public/includes/editor-modules.php:1330 msgid "Select" msgstr "" #: public/includes/helpers.php:449 msgid "No posts to show" msgstr "No hay publicaciones para mostrar" #: public/includes/helpers.php:455 msgid "No revisions found" msgstr "No hay revisiones encontrados" #: public/includes/lasso.php:292 msgid "Post being edited by " msgstr "" #: public/includes/tour.php:67 msgid "Don't show this again" msgstr "No mostrar de nuevo." #: public/includes/tour.php:71 msgid "Okay, got it!" msgstr "OK. Entendido." #: public/includes/tour.php:96 msgid "" "Access posts by clicking the list icon. Create a new post by clicking the " "new post icon." msgstr "" "Puede crear una nueva entrada/proyecto clickando sobre el icono simbolizado " "con una hoja con un plus. Este botón lo puede encontrar en la parte inferior " "de su pantalla." #: public/includes/tour.php:99 msgid "" "While on a single post, edit by clicking the Pen icon. Access post settings " "with the settings icon. Press escape to exit any modal." msgstr "" "Clickando sobre el botón de la pluma, puede empezar a escribir o editar su " "entrada // proyecto." #: public/includes/tour.php:102 msgid "" "Highlight a piece of text, and click on a formatting option to style it. " "Click the Disk icon or CMD-S to save. Click the orange \"X\" button to exit " "the editor." msgstr "" "Esta será su barra de edición de textos, con ella podrá editar el formato de " "sus textos mientras escribe ( texto en negrita, subrayado, italic, tachado, " "añadir enlaces, codigo y mucho más..." #: public/includes/tour.php:105 msgid "" "Story components can be added by clicking the plus icon, and dragging any " "component from the component tray into the story." msgstr "" "Clickando sobre el botón más, podra arrastrar estos componentes a sus " "publicaciones (imágenes, audios, videos, galerias de imagenes, mapa con " "localización, citas de autor....)" #~ msgid "Grump Wizards Make Toxic Brew" #~ msgstr "Aquí titulo de tu entrada/proyecto" ================================================ FILE: languages/lasso-ko_KR.po ================================================ msgid "" msgstr "" "Project-Id-Version: Editus\n" "POT-Creation-Date: 2022-08-02 15:43-0400\n" "PO-Revision-Date: 2022-08-02 15:43-0400\n" "Last-Translator: \n" "Language-Team: \n" "Language: ko_KR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 3.1.1\n" "X-Poedit-Basepath: ..\n" "X-Poedit-KeywordsList: __;_e;esc_attr_e\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPathExcluded-0: node_modules\n" #: admin/includes/EDD_SL_Plugin_Updater.php:177 #, php-format msgid "" "There is a new version of %1$s available. View version %3$s details." msgstr "" #: admin/includes/EDD_SL_Plugin_Updater.php:184 #, php-format msgid "" "There is a new version of %1$s available. View version %3$s details or update now." msgstr "" #: admin/includes/EDD_SL_Plugin_Updater.php:324 msgid "You do not have permission to install plugin updates" msgstr "" #: admin/includes/EDD_SL_Plugin_Updater.php:324 msgid "Error" msgstr "에러" #: admin/includes/class-tgm-plugin-activation.php:333 #: admin/includes/menus/welcome.php:227 msgid "Install Required Plugins" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:334 #: admin/includes/menus/welcome.php:228 msgid "Install Plugins" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:335 #: admin/includes/menus/welcome.php:229 #, php-format msgid "Installing Plugin: %s" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:336 #: admin/includes/menus/welcome.php:230 msgid "Something went wrong with the plugin API." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:397 #: admin/includes/menus/welcome.php:241 msgid "Return to Required Plugins Installer" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:398 msgid "Return to the dashboard" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:399 #: admin/includes/class-tgm-plugin-activation.php:3029 #: admin/includes/menus/welcome.php:242 msgid "Plugin activated successfully." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:400 msgid "The following plugin was activated successfully:" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:401 #, php-format msgid "No action taken. Plugin %1$s was already active." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:402 #, php-format msgid "" "Plugin not activated. A higher version of %s is needed for this theme. " "Please update the plugin." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:403 #, php-format msgid "All plugins installed and activated successfully. %1$s" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:404 msgid "Dismiss this notice" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:405 msgid "Please contact the administrator of this site for help." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2167 msgid "Required" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2170 msgid "Recommended" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2186 msgid "WordPress Repository" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2189 msgid "External Source" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2192 msgid "Pre-Packaged" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2209 msgid "Not Installed" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2213 msgid "Installed But Not Activated" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2215 msgid "Active" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2221 msgid "Required Update not Available" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2224 msgid "Requires Update" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2227 msgid "Update recommended" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2379 msgid "Installed version:" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2387 msgid "Minimum required version:" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2399 msgid "Available version:" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2422 #, php-format msgid "" "No plugins to install, update or activate. Return to the " "Dashboard" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2436 msgid "Plugin" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2437 msgid "Source" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2438 msgid "Type" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2442 #: admin/includes/menus/welcome.php:118 msgid "Version" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2443 #: admin/includes/menus/welcome.php:49 public/includes/editor-modules.php:614 msgid "Status" msgstr "상태" #: admin/includes/class-tgm-plugin-activation.php:2603 msgid "Install" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2609 msgid "Update" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2612 msgid "Activate" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2643 msgid "No plugins were selected to be installed. No action taken." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2645 msgid "No plugins were selected to be updated. No action taken." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2681 msgid "No plugins are available to be installed at this time." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2683 msgid "No plugins are available to be updated at this time." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3028 msgid "Plugin activation failed." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3362 #, php-format msgid "Updating Plugin %1$s (%2$d/%3$d)" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3364 #, php-format msgid "An error occurred while installing %1$s: %2$s." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3365 #, php-format msgid "The installation of %1$s failed." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3369 msgid "" "The installation and activation process is starting. This process may take a " "while on some hosts, so please be patient." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3370 #, php-format msgid "%1$s installed and activated successfully." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3371 msgid "All installations and activations have been completed." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3372 #, php-format msgid "Installing and Activating Plugin %1$s (%2$d/%3$d)" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3375 msgid "" "The installation process is starting. This process may take a while on some " "hosts, so please be patient." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3377 msgid "All installations have been completed." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3378 #, php-format msgid "Installing Plugin %1$s (%2$d/%3$d)" msgstr "" #: admin/includes/load_admin.php:151 msgid "Dismiss this notice." msgstr "" #: admin/includes/menus/license.php:30 msgid "Aesopinteractive LLC" msgstr "Aesopinteractive LLC" #: admin/includes/menus/license.php:38 admin/includes/menus/license.php:57 msgid "License Key" msgstr "" #: admin/includes/menus/license.php:38 msgid "License" msgstr "" #: admin/includes/menus/license.php:47 msgid "Editus License" msgstr "" #: admin/includes/menus/license.php:48 msgid "" "Input the license key you recieved with your purchase to ensure your version " "of Editus stays updated." msgstr "" #: admin/includes/menus/license.php:66 admin/includes/menus/license.php:75 msgid "Activate License" msgstr "" #: admin/includes/menus/license.php:70 msgid "active" msgstr "" #: admin/includes/menus/license.php:72 msgid "Deactivate License" msgstr "" #: admin/includes/menus/settings.php:26 public/includes/editor-modules.php:493 #: public/includes/editor-modules.php:892 #: public/includes/editor-modules.php:894 #: public/includes/editor-modules.php:909 #: public/includes/editor-modules.php:928 msgid "Settings" msgstr "" #: admin/includes/menus/settings.php:169 msgid "Editus Settings" msgstr "" #: admin/includes/menus/settings.php:177 msgid "Enable for:" msgstr "" #: admin/includes/menus/settings.php:181 msgid "Enable Editus for the following post types." msgstr "" #: admin/includes/menus/settings.php:203 msgid "Internal Settings" msgstr "" #: admin/includes/menus/settings.php:206 msgid "Article Class" msgstr "" #: admin/includes/menus/settings.php:207 msgid "" "Provide the CSS class (including the preceding dot) of container that holds " "the post. This should be the first parent container class that holds " "the_content." msgstr "" #: admin/includes/menus/settings.php:212 msgid "Featured Image Class" msgstr "" #: admin/includes/menus/settings.php:213 msgid "" "Provide the CSS class that uses a featured image as a background image. This " "currently only supports themes that have the featured image set as " "background image." msgstr "" #: admin/includes/menus/settings.php:218 msgid "Article Title Class" msgstr "" #: admin/includes/menus/settings.php:219 msgid "" "Provide the CSS class for the post title. This will enable you to update the " "title of the post by clicking and typing." msgstr "" #: admin/includes/menus/settings.php:224 msgid "Ignored Items to Save" msgstr "" #: admin/includes/menus/settings.php:225 msgid "" "If your post container holds additional markup, list the css class names " "(comma separated, including the dot) of those items. When you enter the " "editor, Editus will remove (NOT delete) these items so that it does not save " "them as HTML." msgstr "" #: admin/includes/menus/settings.php:230 msgid "Read Only Items" msgstr "" #: admin/includes/menus/settings.php:231 msgid "" "If your post has items that should not be editable, list the css class names " "(comma separated, including the dot) of those items." msgstr "" #: admin/includes/menus/settings.php:237 msgid "Show Ignored Items" msgstr "" #: admin/includes/menus/settings.php:238 msgid "" "By default the ignored items are hidden. Check this to show ignored items " "while keeping them uneditable." msgstr "" #: admin/includes/menus/settings.php:242 msgid "Editor UI" msgstr "" #: admin/includes/menus/settings.php:246 msgid "Use the Old Toolbar" msgstr "" #: admin/includes/menus/settings.php:247 msgid "" "Use this option to disable the new color options and use the pre-1.0 toolbar." msgstr "" #: admin/includes/menus/settings.php:251 msgid "Editor Bar Color Top" msgstr "" #: admin/includes/menus/settings.php:252 msgid "Editor Bar Color Bottom" msgstr "" #: admin/includes/menus/settings.php:253 msgid "Dialog Color" msgstr "" #: admin/includes/menus/settings.php:254 msgid "Icon/Text Color" msgstr "" #: admin/includes/menus/settings.php:256 msgid "Default Colors" msgstr "" #: admin/includes/menus/settings.php:261 msgid "Enable H2 and H3 Buttons" msgstr "" #: admin/includes/menus/settings.php:262 msgid "Show the buttons to set H2 and H3 settings." msgstr "" #: admin/includes/menus/settings.php:267 msgid "Enable H4/H5/H6 Buttons" msgstr "" #: admin/includes/menus/settings.php:268 msgid "Show the buttons to set H4/H5/H6 settings." msgstr "" #: admin/includes/menus/settings.php:274 msgid "Enable OL/UL Buttons" msgstr "" #: admin/includes/menus/settings.php:275 msgid "" "Show the buttons to create Ordered and Unordered Lists from text selection." msgstr "" #: admin/includes/menus/settings.php:280 msgid "Enable Text Color Buttons" msgstr "" #: admin/includes/menus/settings.php:281 msgid "Show the buttons to set text colors." msgstr "" #: admin/includes/menus/settings.php:286 msgid "Enable Text Align Buttons" msgstr "" #: admin/includes/menus/settings.php:287 msgid "Show the buttons to set text alignment." msgstr "" #: admin/includes/menus/settings.php:293 msgid "Make links editable under the Editing Mode" msgstr "" #: admin/includes/menus/settings.php:294 msgid "" "Make links editable under the Editing Mode. Turning this on will make the " "links non-clickable while editing." msgstr "" #: admin/includes/menus/settings.php:298 msgid "Insert Component UI" msgstr "" #: admin/includes/menus/settings.php:299 msgid "UI mechanism to insert components" msgstr "" #: admin/includes/menus/settings.php:301 msgid "Drag and Drop" msgstr "" #: admin/includes/menus/settings.php:304 msgid "Click" msgstr "" #: admin/includes/menus/settings.php:307 msgid "Auto Button on Empty Paragraph. medium.com-like UI." msgstr "" #: admin/includes/menus/settings.php:313 msgid "Popup When Text is Selected" msgstr "" #: admin/includes/menus/settings.php:314 msgid "" "Instead of using the bottom toolbar to format texts, use a popup box to " "format texts." msgstr "" #: admin/includes/menus/settings.php:320 msgid "Component" msgstr "" #: admin/includes/menus/settings.php:324 msgid "Additional Component: Table" msgstr "" #: admin/includes/menus/settings.php:325 msgid "Allow user to add and edit tables." msgstr "" #: admin/includes/menus/settings.php:331 msgid "Additional Component: Paragraph" msgstr "" #: admin/includes/menus/settings.php:332 msgid "Plain HTML Paragraph." msgstr "" #: admin/includes/menus/settings.php:363 #, fuzzy #| msgid "Replace Image" msgid "Use Simple Image" msgstr "이미지변경" #: admin/includes/menus/settings.php:364 msgid "Use Simple Image Component without Extra Options." msgstr "" #: admin/includes/menus/settings.php:371 msgid "Use WP Image Block" msgstr "" #: admin/includes/menus/settings.php:372 msgid "" "Use WP Image Block as the image component. Gutenberg Block Editor needs to " "be enabled." msgstr "" #: admin/includes/menus/settings.php:379 msgid "Post Settings UI" msgstr "" #: admin/includes/menus/settings.php:383 msgid "Disable Post Settings" msgstr "" #: admin/includes/menus/settings.php:384 msgid "" "Check this to disable users from being able to edit post settings from the " "front-end." msgstr "" #: admin/includes/menus/settings.php:389 msgid "Allow Changing Post Date" msgstr "" #: admin/includes/menus/settings.php:390 msgid "" "Add the date selector to change the post's date to the Post Setting dialog" msgstr "" #: admin/includes/menus/settings.php:395 msgid "Allow Editing Excerpt" msgstr "" #: admin/includes/menus/settings.php:396 msgid "Allow the post's excerpt to be edited in the Post Setting dialog" msgstr "" #: admin/includes/menus/settings.php:401 msgid "Allow Adding New Category" msgstr "" #: admin/includes/menus/settings.php:402 msgid "" "Add the user to create new, previously non-existing categories for posts." msgstr "" #: admin/includes/menus/settings.php:407 msgid "Do Not Allow \"Pending\" Status" msgstr "" #: admin/includes/menus/settings.php:408 msgid "Remove the Option to Set the Status to Pending." msgstr "" #: admin/includes/menus/settings.php:413 msgid "Remove POST URL Option" msgstr "" #: admin/includes/menus/settings.php:414 msgid "Remove the Option to Set the URL for the Post." msgstr "" #: admin/includes/menus/settings.php:419 msgid "Disable Post Adding" msgstr "" #: admin/includes/menus/settings.php:420 msgid "" "Check this box to disable users from being able to add new posts from the " "front-end." msgstr "" #: admin/includes/menus/settings.php:425 msgid "Support Custom Taxonomy" msgstr "" #: admin/includes/menus/settings.php:426 msgid "Allow editing custom taxonomies." msgstr "" #: admin/includes/menus/settings.php:432 msgid "Misc" msgstr "" #: admin/includes/menus/settings.php:436 msgid "Do Not Show Tour Dialog" msgstr "" #: admin/includes/menus/settings.php:437 msgid "Check this box to disable the tour dialog box for all users." msgstr "" #: admin/includes/menus/settings.php:441 msgid "Placeholder Text for New Post" msgstr "" #: admin/includes/menus/settings.php:442 msgid "Placeholder text to be displayed when a new post is created." msgstr "" #: admin/includes/menus/settings.php:443 includes/process/new_object.php:38 #: public/includes/assets.php:248 msgid "Once upon a time..." msgstr "" #: admin/includes/menus/settings.php:448 msgid "Do Not Allow Shortcode Editing" msgstr "" #: admin/includes/menus/settings.php:449 msgid "Check this box to disable frontend editing of shortcodes." msgstr "" #: admin/includes/menus/settings.php:453 msgid "\"Bold\" Tag" msgstr "" #: admin/includes/menus/settings.php:454 msgid "Choose the HTML tag used for the \"Bold\" style." msgstr "" #: admin/includes/menus/settings.php:459 msgid "\"Italic\" Tag" msgstr "" #: admin/includes/menus/settings.php:460 msgid "Choose the HTML tag used for the \"Italic\" style." msgstr "" #: admin/includes/menus/settings.php:466 msgid "Auto Prefix HTTP to links" msgstr "" #: admin/includes/menus/settings.php:467 msgid "" "When user adds a hyperlink, automatically add http:// if the user does not " "specify it explicitly." msgstr "" #: admin/includes/menus/settings.php:471 msgid "Advanced Options" msgstr "" #: admin/includes/menus/settings.php:472 msgid "" "Suggested not to turn these options on without consulting the developer." msgstr "" #: admin/includes/menus/settings.php:477 msgid "Disable Aesop Component Conversion" msgstr "" #: admin/includes/menus/settings.php:478 msgid "" "Check this box to disable the conversion process used on Aesop Story Engine " "components." msgstr "" #: admin/includes/menus/settings.php:483 msgid "Enable Auto Save" msgstr "" #: admin/includes/menus/settings.php:484 msgid "Check this box to enable auto save." msgstr "" #: admin/includes/menus/settings.php:489 msgid "Disable Post Saving" msgstr "" #: admin/includes/menus/settings.php:490 msgid "" "By default the editor will update the database with the post or page it is " "being used on. Check this box to disable this. If you check this box, it is " "assumed that you will be using the provided filters to save your own content." msgstr "" #: admin/includes/menus/settings.php:496 msgid "Disable Post Editing" msgstr "" #: admin/includes/menus/settings.php:497 msgid "" "You may use this option if you only want to edit custom fields. Refer here for more information. The custom fields you specify will be " "still editable under the editing mode." msgstr "" #: admin/includes/menus/settings.php:503 msgid "Don't Use REST API to Save" msgstr "" #: admin/includes/menus/settings.php:504 msgid "" "By default the editor will use REST API to save posts. Check this box to use " "custom AJAX calls instead." msgstr "" #: admin/includes/menus/settings.php:510 #, fuzzy #| msgid "You can also use Shortcodes" msgid "Don't Wrap Shortcodes" msgstr "또는 워드프레스 숏코드" #: admin/includes/menus/settings.php:511 msgid "" "By default Editus wraps shortcodes so they can be preserved. Disable this " "behavior." msgstr "" #: admin/includes/menus/settings.php:521 msgid "Save Settings" msgstr "" #: admin/includes/menus/welcome.php:48 msgid "Editus" msgstr "" #: admin/includes/menus/welcome.php:49 msgid "Welcome" msgstr "" #: admin/includes/menus/welcome.php:71 msgid "" "We will check the current theme on every site in your network and give you a " "quick status feedback here. You can see the status by visiting the Editus " "menu on each site." msgstr "" #: admin/includes/menus/welcome.php:90 msgid "You're Ready to Rock!" msgstr "" #: admin/includes/menus/welcome.php:92 msgid "Your theme is automatically supported. No additional setup is needed." msgstr "" #: admin/includes/menus/welcome.php:94 msgid "" "Editus will place a small menu on the bottom of your site. While on a single " "post or page, click the \"pen\" icon to go into edit mode. Press escape to " "get out of edit mode." msgstr "" #: admin/includes/menus/welcome.php:117 msgid "Welcome to Editus" msgstr "" #: admin/includes/menus/welcome.php:123 msgid "Help" msgstr "" #: admin/includes/menus/welcome.php:124 msgid "Twitter" msgstr "" #: admin/includes/menus/welcome.php:125 msgid "Facebook" msgstr "" #: admin/includes/menus/welcome.php:158 msgid "Article CSS Class Needed!" msgstr "" #: admin/includes/menus/welcome.php:159 msgid "Before using Editus," msgstr "" #: admin/includes/menus/welcome.php:159 msgid "enter and save" msgstr "" #: admin/includes/menus/welcome.php:159 msgid "" "the CSS class of the container that holds your post and page content. You " "can use a tool like " "inspector in Chrome or Firefox to find this CSS class, or " msgstr "" #: admin/includes/menus/welcome.php:159 msgid "email us." msgstr "" #: admin/includes/menus/welcome.php:159 msgid "with a link to a public URL with the theme and we'll find it for you." msgstr "" #: admin/includes/menus/welcome.php:166 msgid "" "Just a heads up that the WP REST API isn't activated. This is required to " "list the posts and pages on the front-end." msgstr "" #: admin/includes/menus/welcome.php:173 msgid "Just a heads up that " msgstr "" #: admin/includes/menus/welcome.php:174 admin/includes/menus/welcome.php:211 msgid "Aesop Story Engine" msgstr "" #: admin/includes/menus/welcome.php:174 msgid "" "isn't activated. It's not required to use Editus, but you won't get the cool " "drag and drop components without it activated. It's free!" msgstr "" #: admin/includes/menus/welcome.php:180 msgid "WP Side Comments Compatibility Warning!" msgstr "" #: admin/includes/menus/welcome.php:181 msgid "" "Since Editus saves the HTML of a post, this may cause undesired issues. " "We're working to resolve incompatibilities faster than a jack rabbit in a " "hot greasy griddle in the middle of August." msgstr "" #: admin/includes/menus/welcome.php:187 msgid "License Key Not Activated" msgstr "" #: admin/includes/menus/welcome.php:188 msgid "" "Just a heads up, your license key isn't activated. Enter your license key " "into the License tab on the left in order to receive plugin update " "notifications." msgstr "" #: admin/includes/menus/welcome.php:192 msgid "License Key Invalid" msgstr "" #: admin/includes/menus/welcome.php:193 msgid "The license key that you entered is " msgstr "" #: admin/includes/menus/welcome.php:193 msgid "invalid" msgstr "" #: admin/includes/menus/welcome.php:193 msgid ". It may have been entered incorreclty, or may have expired." msgstr "" #: admin/includes/menus/welcome.php:243 #, php-format msgid "All plugins installed and activated successfully. %s" msgstr "" #: includes/process/gallery.php:40 msgid "Save and refresh to view gallery." msgstr "" #: includes/process/gallery.php:199 msgid "Delete From Gallery" msgstr "" #: includes/process/gallery.php:200 msgid "Edit Image Caption" msgstr "" #: internal-api/auth.php:67 msgid "Unauthorized action" msgstr "" #: internal-api/auth.php:71 msgid "" "All callback classes used for processing the Editus Internal API must " "implement the lasso\\internal_api\\api_action interface." msgstr "" #: internal-api/auth.php:76 msgid "Nonce invalid" msgstr "" #: internal-api/route.php:30 msgid "Editus API Error." msgstr "" #: internal-api/route.php:66 msgid "Nonce not set." msgstr "" #: lasso.php:130 #, fuzzy #| msgid "Insert" msgid "Insert Column" msgstr "삽입" #: lasso.php:131 #, fuzzy #| msgid "Insert" msgid "Insert Row" msgstr "삽입" #: lasso.php:132 #, fuzzy #| msgid "Delete Post" msgid "Delete Column" msgstr "글 삭제" #: lasso.php:133 #, fuzzy #| msgid "Delete Post" msgid "Delete Row" msgstr "글 삭제" #: lasso.php:134 #, fuzzy #| msgid "Delete Image" msgid "Delete Table" msgstr "이미지 삭제" #: lasso.php:149 lasso.php:159 msgid "HTML Table" msgstr "" #: lasso.php:192 lasso.php:220 msgid "HTML Paragraph" msgstr "" #: public/includes/assets.php:146 public/includes/editor-modules.php:713 #: public/includes/option-engine.php:132 msgid "Save" msgstr "저장" #: public/includes/assets.php:147 msgid "Please Select Text First." msgstr "텍스트를 먼저 선택하십시요." #: public/includes/assets.php:148 public/includes/editor-modules.php:439 #: public/includes/editor-modules.php:706 #: public/includes/editor-modules.php:788 #: public/includes/editor-modules.php:1329 msgid "Cancel" msgstr "취소" #: public/includes/assets.php:149 msgid "Exit Editor" msgstr "에디터 종료" #: public/includes/assets.php:150 msgid "Saving..." msgstr "저장중" #: public/includes/assets.php:151 msgid "Saved!" msgstr "저장완료" #: public/includes/assets.php:152 msgid "Adding..." msgstr "추가중" #: public/includes/assets.php:153 msgid "Added!" msgstr "추가완료" #: public/includes/assets.php:154 msgid "Loading..." msgstr "로딩" #: public/includes/assets.php:155 msgid "Load More" msgstr "더보기" #: public/includes/assets.php:156 public/includes/helpers.php:457 msgid "Close" msgstr "닫기" #: public/includes/assets.php:157 msgid "No more posts found" msgstr "더 글이 없습니다." #: public/includes/assets.php:158 msgid "Fetching failed." msgstr "" #: public/includes/assets.php:159 msgid "Gallery Created!" msgstr "" #: public/includes/assets.php:160 msgid "Gallery Updated!" msgstr "" #: public/includes/assets.php:161 msgid "Just write..." msgstr "" #: public/includes/assets.php:162 msgid "Choose an image" msgstr "" #: public/includes/assets.php:163 msgid "Update Image" msgstr "" #: public/includes/assets.php:164 msgid "Insert Image" msgstr "" #: public/includes/assets.php:165 msgid "Select Image" msgstr "" #: public/includes/assets.php:166 msgid "Remove featured image?" msgstr "대표 이미지를 뺄까요?" #: public/includes/assets.php:167 msgid "Update Selected Image" msgstr "" #: public/includes/assets.php:168 msgid "Choose images" msgstr "" #: public/includes/assets.php:169 msgid "Edit Image" msgstr "" #: public/includes/assets.php:170 #: public/includes/editor-modules--gallery.php:28 msgid "Add Images" msgstr "" #: public/includes/assets.php:171 msgid "Add New Gallery" msgstr "" #: public/includes/assets.php:172 msgid "Select Editus Gallery Image" msgstr "" #: public/includes/assets.php:173 msgid "Use Selected Images" msgstr "" #: public/includes/assets.php:174 msgid "Publish Post?" msgstr "글을 공개할까요?" #: public/includes/assets.php:175 msgid "Yes, publish it!" msgstr "예" #: public/includes/assets.php:176 msgid "Trash Post?" msgstr "글을 삭제할까요?" #: public/includes/assets.php:177 msgid "Yes, trash it!" msgstr "예" #: public/includes/assets.php:178 msgid "Oh snap!" msgstr "" #: public/includes/assets.php:179 msgid "O.K. got it!" msgstr "" #: public/includes/assets.php:180 msgid "" "It looks like we are either missing the Article CSS class, or it is " "configured incorrectly. Editus will not function correctly without this CSS " "class." msgstr "" #: public/includes/assets.php:181 msgid "Update Settings" msgstr "" #: public/includes/assets.php:182 msgid "one more letter" msgstr "" #: public/includes/assets.php:183 msgid "You are currently editing a backup copy of this post." msgstr "" #: public/includes/assets.php:185 #, fuzzy #| msgid "Categories" msgid "add categories..." msgstr "카테고리" #: public/includes/assets.php:186 msgid "add tags..." msgstr "" #: public/includes/assets.php:187 #, fuzzy #| msgid "Categories" msgid "add taxonomy terms..." msgstr "카테고리" #: public/includes/assets.php:188 #, fuzzy #| msgid "Edit Post" msgid "Edit Shortcode" msgstr "글 편집" #: public/includes/components.php:19 public/includes/editor-modules.php:352 msgid "Quote" msgstr "" #: public/includes/components.php:23 public/includes/editor-modules.php:350 #: public/includes/editor-modules.php:1103 #: public/includes/editor-modules.php:1154 #: public/includes/editor-modules.php:1218 msgid "Image" msgstr "이미지" #: public/includes/components.php:27 #: public/includes/editor-modules--gallery.php:74 #: public/includes/editor-modules.php:355 msgid "Parallax" msgstr "" #: public/includes/components.php:31 public/includes/editor-modules.php:356 msgid "Audio" msgstr "" #: public/includes/components.php:35 public/includes/editor-modules.php:353 #: public/includes/editor-modules.php:1080 msgid "Content" msgstr "" #: public/includes/components.php:39 public/includes/editor-modules.php:351 msgid "Character" msgstr "" #: public/includes/components.php:43 public/includes/editor-modules.php:361 msgid "Collection" msgstr "" #: public/includes/components.php:47 public/includes/editor-modules.php:360 msgid "Document" msgstr "" #: public/includes/components.php:51 public/includes/editor-modules.php:362 msgid "Gallery" msgstr "" #: public/includes/components.php:55 public/includes/editor-modules.php:354 msgid "Chapter" msgstr "" #: public/includes/components.php:59 public/includes/editor-modules.php:358 msgid "Map" msgstr "지도" #: public/includes/components.php:63 public/includes/editor-modules.php:359 msgid "Timeline" msgstr "" #: public/includes/components.php:67 public/includes/editor-modules.php:357 msgid "Video" msgstr "동영상" #: public/includes/components.php:71 public/includes/components.php:91 #: public/includes/editor-modules.php:371 #: public/includes/editor-modules.php:373 msgid "WordPress Image" msgstr "이미지" #: public/includes/components.php:75 #, fuzzy #| msgid "WordPress Image" msgid "WordPress Image Block" msgstr "이미지" #: public/includes/components.php:79 public/includes/editor-modules.php:375 msgid "WordPress Quote" msgstr "인용구" #: public/includes/components.php:83 public/includes/editor-modules.php:364 msgid "Gallery Pop" msgstr "" #: public/includes/components.php:87 msgid "Events" msgstr "" #: public/includes/editor-modules--gallery.php:19 msgid "Create gallery" msgstr "" #: public/includes/editor-modules--gallery.php:27 msgid "Manage Images" msgstr "" #: public/includes/editor-modules--gallery.php:31 msgid "Rearrange or edit the images in this gallery." msgstr "" #: public/includes/editor-modules--gallery.php:47 msgid "Create a Gallery" msgstr "" #: public/includes/editor-modules--gallery.php:51 msgid "Select images to create a gallery." msgstr "" #: public/includes/editor-modules--gallery.php:52 msgid "Select Images" msgstr "" #: public/includes/editor-modules--gallery.php:56 msgid "Create Gallery" msgstr "" #: public/includes/editor-modules--gallery.php:67 msgid "Gallery Type" msgstr "" #: public/includes/editor-modules--gallery.php:68 msgid "Select the type of gallery." msgstr "" #: public/includes/editor-modules--gallery.php:70 msgid "Grid" msgstr "" #: public/includes/editor-modules--gallery.php:71 msgid "Thumbnail" msgstr "" #: public/includes/editor-modules--gallery.php:73 msgid "Photoset" msgstr "" #: public/includes/editor-modules--gallery.php:84 msgid "Grid Item Width" msgstr "" #: public/includes/editor-modules--gallery.php:85 msgid "" "Adjust the width of the individual grid items, only if using Grid gallery " "style. Default is 400." msgstr "" #: public/includes/editor-modules--gallery.php:95 msgid "Gallery Transition" msgstr "" #: public/includes/editor-modules--gallery.php:96 msgid "" "Adjust the transition effect for the Thumbnail gallery. Default is slide." msgstr "" #: public/includes/editor-modules--gallery.php:98 msgid "Fade" msgstr "" #: public/includes/editor-modules--gallery.php:99 msgid "Slide" msgstr "" #: public/includes/editor-modules--gallery.php:100 msgid "Dissolve" msgstr "" #: public/includes/editor-modules--gallery.php:105 msgid "Gallery Transition Speed" msgstr "" #: public/includes/editor-modules--gallery.php:106 msgid "" "Activate slideshow by setting a speed for the transition.5000 = 5 seconds." msgstr "" #: public/includes/editor-modules--gallery.php:112 msgid "Hide Gallery Thumbnails" msgstr "" #: public/includes/editor-modules--gallery.php:121 msgid "Gallery Layout" msgstr "" #: public/includes/editor-modules--gallery.php:122 msgid "" "Let's say you have 4 images in this gallery. If you enter 121 you will have " "one image on the top row, two images on the second row, and one image on the " "third row." msgstr "" #: public/includes/editor-modules--gallery.php:137 msgid "Main Gallery Height" msgstr "" #: public/includes/editor-modules--gallery.php:138 #, php-format msgid "" "Adjust the overall height of the gallery. Acceptable values include 500px or " "50% etc." msgstr "" #: public/includes/editor-modules--gallery.php:148 msgid "Main Gallery Width" msgstr "" #: public/includes/editor-modules--gallery.php:149 #, php-format msgid "" "Adjust the overall width of the gallery. Acceptable values include 500px or " "50% etc." msgstr "" #: public/includes/editor-modules--gallery.php:153 msgid "Gallery Caption" msgstr "" #: public/includes/editor-modules--gallery.php:154 msgid "Add an optional caption for the gallery." msgstr "" #: public/includes/editor-modules.php:60 public/includes/editor-modules.php:437 msgid "Table" msgstr "" #: public/includes/editor-modules.php:137 #: public/includes/underscore-templates.php:23 #: public/includes/underscore-templates.php:41 msgid "Edit Post" msgstr "글 편집" #: public/includes/editor-modules.php:140 #: public/includes/editor-modules.php:164 #: public/includes/editor-modules.php:457 msgid "Post Settings" msgstr "글 세팅" #: public/includes/editor-modules.php:145 msgid "All Posts" msgstr "글 목록" #: public/includes/editor-modules.php:148 #: public/includes/editor-modules.php:1323 msgid "Revisions" msgstr "리비젼" #: public/includes/editor-modules.php:152 msgid "Add Post" msgstr "새글" #: public/includes/editor-modules.php:163 #: public/includes/editor-modules.php:456 #: public/includes/underscore-templates.php:25 #: public/includes/underscore-templates.php:43 msgid "Delete Post" msgstr "글 삭제" #: public/includes/editor-modules.php:167 #: public/includes/editor-modules.php:459 msgid "Save Post" msgstr "글저장" #: public/includes/editor-modules.php:170 #: public/includes/editor-modules.php:462 msgid "Publish Post" msgstr "글공개" #: public/includes/editor-modules.php:170 msgid "Submit For Review" msgstr "검토글로 저장" #: public/includes/editor-modules.php:249 #: public/includes/editor-modules.php:342 msgid "Bold" msgstr "" #: public/includes/editor-modules.php:250 #: public/includes/editor-modules.php:343 msgid "Underline" msgstr "" #: public/includes/editor-modules.php:251 #: public/includes/editor-modules.php:344 msgid "Italicize" msgstr "" #: public/includes/editor-modules.php:252 #: public/includes/editor-modules.php:345 msgid "Strikethrough" msgstr "" #: public/includes/editor-modules.php:255 #: public/includes/editor-modules.php:384 #: public/includes/editor-modules.php:431 msgid "H2 Heading" msgstr "" #: public/includes/editor-modules.php:256 #: public/includes/editor-modules.php:385 #: public/includes/editor-modules.php:432 msgid "H3 Heading" msgstr "" #: public/includes/editor-modules.php:262 #: public/includes/editor-modules.php:391 msgid "H4 Heading" msgstr "" #: public/includes/editor-modules.php:263 #: public/includes/editor-modules.php:392 msgid "H5 Heading" msgstr "" #: public/includes/editor-modules.php:264 #: public/includes/editor-modules.php:393 msgid "H6 Heading" msgstr "" #: public/includes/editor-modules.php:268 #: public/includes/editor-modules.php:397 msgid "Set Color for Selected Text" msgstr "선택된 텍스트색 설정" #: public/includes/editor-modules.php:269 #: public/includes/editor-modules.php:398 msgid "Choose Color" msgstr "색 변경" #: public/includes/editor-modules.php:273 #: public/includes/editor-modules.php:402 #: public/includes/editor-modules.php:434 msgid "Ordered List" msgstr "" #: public/includes/editor-modules.php:274 #: public/includes/editor-modules.php:403 #: public/includes/editor-modules.php:435 msgid "Unordered List" msgstr "" #: public/includes/editor-modules.php:278 #: public/includes/editor-modules.php:407 msgid "Anchor Link" msgstr "링크" #: public/includes/editor-modules.php:280 #: public/includes/editor-modules.php:409 msgid "http://url.com" msgstr "" #: public/includes/editor-modules.php:281 #: public/includes/editor-modules.php:410 msgid "Create Link" msgstr "링크" #: public/includes/editor-modules.php:283 #: public/includes/editor-modules.php:412 msgid "Open in a New Tab" msgstr "새 탭에서 열기" #: public/includes/editor-modules.php:347 msgid "Insert Component" msgstr "" #: public/includes/editor-modules.php:367 msgid "Event" msgstr "" #: public/includes/editor-modules.php:376 msgid "WordPress Video" msgstr "코드" #: public/includes/editor-modules.php:419 #: public/includes/editor-modules.php:440 msgid "Insert HTML or Code" msgstr "코드" #: public/includes/editor-modules.php:421 #: public/includes/editor-modules.php:424 msgid "Enter HTML to insert" msgstr "삽입할 HTML코드" #: public/includes/editor-modules.php:425 msgid "You can also use Shortcodes" msgstr "또는 워드프레스 숏코드" #: public/includes/editor-modules.php:426 msgid "" "You can also enter a URL to embed, such as Youtube, Vimeo and Twitter URLs." msgstr "아니면 삽입할 URL을 입력하세요. 유튜브나 트위터등을 지원합니다." #: public/includes/editor-modules.php:440 msgid "Insert" msgstr "삽입" #: public/includes/editor-modules.php:446 msgid "Text Left Align" msgstr "" #: public/includes/editor-modules.php:447 msgid "Text Center Align" msgstr "" #: public/includes/editor-modules.php:448 msgid "Text Right Align" msgstr "" #: public/includes/editor-modules.php:492 #: public/includes/editor-modules.php:890 #: public/includes/editor-modules.php:908 #: public/includes/editor-modules.php:927 msgid "Move" msgstr "" #: public/includes/editor-modules.php:494 #: public/includes/editor-modules.php:896 #: public/includes/editor-modules.php:910 #: public/includes/editor-modules.php:929 msgid "Clone" msgstr "" #: public/includes/editor-modules.php:495 #: public/includes/editor-modules.php:897 #: public/includes/editor-modules.php:911 #: public/includes/editor-modules.php:930 msgid "Delete" msgstr "삭제" #: public/includes/editor-modules.php:517 msgid "Replace Image" msgstr "이미지변경" #: public/includes/editor-modules.php:518 msgid "Delete Image" msgstr "이미지 삭제" #: public/includes/editor-modules.php:519 msgid "save" msgstr "저장" #: public/includes/editor-modules.php:593 msgid "Featured Image" msgstr "대표 이미지" #: public/includes/editor-modules.php:593 msgid "Change the featured image for this post." msgstr "" #: public/includes/editor-modules.php:597 msgid "Change Featured Image" msgstr "" #: public/includes/editor-modules.php:598 msgid "Delete Featured Image" msgstr "" #: public/includes/editor-modules.php:614 msgid "Change the status of the post to draft or publish." msgstr "" #: public/includes/editor-modules.php:616 msgid "Draft" msgstr "비공개" #: public/includes/editor-modules.php:618 msgid "Pending" msgstr "검토" #: public/includes/editor-modules.php:620 msgid "Publish" msgstr "공개" #: public/includes/editor-modules.php:630 msgid "Post URL" msgstr "글주소" #: public/includes/editor-modules.php:630 msgid "Change the URL (slug) of this post." msgstr "" #: public/includes/editor-modules.php:640 msgid "Categories" msgstr "카테고리" #: public/includes/editor-modules.php:640 msgid "Type a category name and press enter." msgstr "" #: public/includes/editor-modules.php:645 msgid "Tags" msgstr "태그" #: public/includes/editor-modules.php:645 msgid "Type a tag name and press enter." msgstr "" #: public/includes/editor-modules.php:653 msgid "Custom Taxonomy" msgstr "" #: public/includes/editor-modules.php:653 msgid "Choose custom taxonomy." msgstr "" #: public/includes/editor-modules.php:670 msgid "Excerpt" msgstr "" #: public/includes/editor-modules.php:670 msgid "Edit excerpt" msgstr "" #: public/includes/editor-modules.php:679 msgid "Post Date" msgstr "글쓴날짜" #: public/includes/editor-modules.php:681 msgid "Set to Now" msgstr "" #: public/includes/editor-modules.php:762 msgid "New post title" msgstr "새글 제목" #: public/includes/editor-modules.php:762 msgid "Specify title for new post, then save to edit." msgstr "" #: public/includes/editor-modules.php:763 msgid "Type Your Title Here" msgstr "" #: public/includes/editor-modules.php:800 msgid "Create" msgstr "만들기" #: public/includes/editor-modules.php:839 msgid "results found" msgstr "" #: public/includes/editor-modules.php:952 msgid "Save Locations" msgstr "" #: public/includes/editor-modules.php:970 msgid "Save this post and refesh the page to see these changes." msgstr "" #: public/includes/editor-modules.php:1109 #: public/includes/editor-modules.php:1224 #: public/includes/editor-modules.php:1289 #, fuzzy #| msgid "Image" msgid "Image URL" msgstr "이미지" #: public/includes/editor-modules.php:1110 #: public/includes/editor-modules.php:1225 #: public/includes/editor-modules.php:1290 msgid "" "URL for the image. Click Select Media to open the WordPress Media " "Library." msgstr "" #: public/includes/editor-modules.php:1117 #: public/includes/editor-modules.php:1232 msgid "Center" msgstr "" #: public/includes/editor-modules.php:1121 #: public/includes/editor-modules.php:1236 msgid "Left" msgstr "" #: public/includes/editor-modules.php:1125 #: public/includes/editor-modules.php:1240 msgid "Right" msgstr "" #: public/includes/editor-modules.php:1129 #: public/includes/editor-modules.php:1244 msgid "Alignment" msgstr "" #: public/includes/editor-modules.php:1136 #, fuzzy #| msgid "Image" msgid "Image Width" msgstr "이미지" #: public/includes/editor-modules.php:1137 msgid "" "Width of the image. You can enter the size in pixels or percentage such as " "40% or 500px." msgstr "" #: public/includes/editor-modules.php:1142 msgid "Image Height" msgstr "" #: public/includes/editor-modules.php:1143 msgid "" "Used only for the Panorama mode. Can be set using pixel values such as " "500px. If unspecified, the original height would be used. " msgstr "" #: public/includes/editor-modules.php:1150 msgid "None" msgstr "" #: public/includes/editor-modules.php:1158 msgid "URL" msgstr "" #: public/includes/editor-modules.php:1162 msgid "Link" msgstr "" #: public/includes/editor-modules.php:1163 msgid "Click leads to:" msgstr "" #: public/includes/editor-modules.php:1169 msgid "URL Link" msgstr "" #: public/includes/editor-modules.php:1170 msgid "URL link" msgstr "" #: public/includes/editor-modules.php:1175 #: public/includes/editor-modules.php:1250 #, fuzzy #| msgid "Image" msgid "Image ALT" msgstr "이미지" #: public/includes/editor-modules.php:1176 #: public/includes/editor-modules.php:1251 msgid "ALT tag used for the image. Primarily used for SEO purposes." msgstr "" #: public/includes/editor-modules.php:1182 #: public/includes/editor-modules.php:1256 msgid "Caption" msgstr "" #: public/includes/editor-modules.php:1183 #: public/includes/editor-modules.php:1257 msgid "Optional caption for the image." msgstr "" #: public/includes/editor-modules.php:1188 msgid "An image." msgstr "" #: public/includes/editor-modules.php:1262 msgid "Link URL" msgstr "" #: public/includes/editor-modules.php:1263 msgid "Optional URL to link." msgstr "" #: public/includes/editor-modules.php:1268 msgid "A WP Image Block." msgstr "" #: public/includes/editor-modules.php:1283 msgid "Cover" msgstr "" #: public/includes/editor-modules.php:1294 msgid "A WP Cover Block." msgstr "" #: public/includes/editor-modules.php:1323 msgid "Use the slider to view the revision live on the page." msgstr "" #: public/includes/editor-modules.php:1330 msgid "Select" msgstr "선택" #: public/includes/helpers.php:449 msgid "No posts to show" msgstr "" #: public/includes/helpers.php:455 msgid "No revisions found" msgstr "" #: public/includes/lasso.php:292 msgid "Post being edited by " msgstr "" #: public/includes/tour.php:67 msgid "Don't show this again" msgstr "다시보지 않기" #: public/includes/tour.php:71 msgid "Okay, got it!" msgstr "OK. " #: public/includes/tour.php:96 msgid "" "Access posts by clicking the list icon. Create a new post by clicking the " "new post icon." msgstr "" #: public/includes/tour.php:99 msgid "" "While on a single post, edit by clicking the Pen icon. Access post settings " "with the settings icon. Press escape to exit any modal." msgstr "" #: public/includes/tour.php:102 msgid "" "Highlight a piece of text, and click on a formatting option to style it. " "Click the Disk icon or CMD-S to save. Click the orange \"X\" button to exit " "the editor." msgstr "" #: public/includes/tour.php:105 msgid "" "Story components can be added by clicking the plus icon, and dragging any " "component from the component tray into the story." msgstr "" #~ msgid "Grump Wizards Make Toxic Brew" #~ msgstr "제목" ================================================ FILE: languages/lasso.pot ================================================ # Copyright (C) 2015 Aesopinteractive LLC # This file is distributed under the same license as the Lasso (beta) package. #, fuzzy msgid "" msgstr "" "Project-Id-Version: Lasso (beta) 0.9.3\n" "Report-Msgid-Bugs-To: http://lasso.is\n" "POT-Creation-Date: 2022-08-02 15:42-0400\n" "PO-Revision-Date: 2015-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: en_US\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 3.1.1\n" "X-Poedit-KeywordsList: __;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;" "_nx_noop:1,2,3c;esc_attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;" "esc_html_x:1,2c\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-Basepath: ..\n" "X-Textdomain-Support: yes\n" "X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPathExcluded-0: node_modules\n" #: admin/includes/EDD_SL_Plugin_Updater.php:177 #, php-format msgid "" "There is a new version of %1$s available. View version %3$s details." msgstr "" #: admin/includes/EDD_SL_Plugin_Updater.php:184 #, php-format msgid "" "There is a new version of %1$s available. View version %3$s details or update now." msgstr "" #: admin/includes/EDD_SL_Plugin_Updater.php:324 msgid "You do not have permission to install plugin updates" msgstr "" #: admin/includes/EDD_SL_Plugin_Updater.php:324 msgid "Error" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:333 #: admin/includes/menus/welcome.php:227 msgid "Install Required Plugins" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:334 #: admin/includes/menus/welcome.php:228 msgid "Install Plugins" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:335 #: admin/includes/menus/welcome.php:229 #, php-format msgid "Installing Plugin: %s" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:336 #: admin/includes/menus/welcome.php:230 msgid "Something went wrong with the plugin API." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:338 #, php-format msgid "This theme requires the following plugin: %1$s." msgid_plural "This theme requires the following plugins: %1$s." msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:343 #, php-format msgid "This theme recommends the following plugin: %1$s." msgid_plural "This theme recommends the following plugins: %1$s." msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:348 #, php-format msgid "" "Sorry, but you do not have the correct permissions to install the %1$s plugin." msgid_plural "" "Sorry, but you do not have the correct permissions to install the %1$s plugins." msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:353 #, php-format msgid "" "The following plugin needs to be updated to its latest version to ensure " "maximum compatibility with this theme: %1$s." msgid_plural "" "The following plugins need to be updated to their latest version to ensure " "maximum compatibility with this theme: %1$s." msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:358 #, php-format msgid "There is an update available for: %1$s." msgid_plural "There are updates available for the following plugins: %1$s." msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:363 #, php-format msgid "" "Sorry, but you do not have the correct permissions to update the %1$s plugin." msgid_plural "" "Sorry, but you do not have the correct permissions to update the %1$s plugins." msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:368 #: admin/includes/menus/welcome.php:234 #, php-format msgid "The following required plugin is currently inactive: %1$s." msgid_plural "The following required plugins are currently inactive: %1$s." msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:373 #: admin/includes/menus/welcome.php:235 #, php-format msgid "The following recommended plugin is currently inactive: %1$s." msgid_plural "The following recommended plugins are currently inactive: %1$s." msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:378 #, php-format msgid "" "Sorry, but you do not have the correct permissions to activate the %1$s plugin." msgid_plural "" "Sorry, but you do not have the correct permissions to activate the %1$s plugins." msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:383 #: admin/includes/menus/welcome.php:239 msgid "Begin installing plugin" msgid_plural "Begin installing plugins" msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:388 msgid "Begin updating plugin" msgid_plural "Begin updating plugins" msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:393 #: admin/includes/menus/welcome.php:240 msgid "Begin activating plugin" msgid_plural "Begin activating plugins" msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:397 #: admin/includes/menus/welcome.php:241 msgid "Return to Required Plugins Installer" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:398 msgid "Return to the dashboard" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:399 #: admin/includes/class-tgm-plugin-activation.php:3029 #: admin/includes/menus/welcome.php:242 msgid "Plugin activated successfully." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:400 #: admin/includes/class-tgm-plugin-activation.php:2832 msgid "The following plugin was activated successfully:" msgid_plural "The following plugins were activated successfully:" msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:401 #, php-format msgid "No action taken. Plugin %1$s was already active." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:402 #, php-format msgid "" "Plugin not activated. A higher version of %s is needed for this theme. Please " "update the plugin." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:403 #, php-format msgid "All plugins installed and activated successfully. %1$s" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:404 msgid "Dismiss this notice" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:405 msgid "Please contact the administrator of this site for help." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:520 msgid "This plugin needs to be updated to be compatible with your theme." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:521 msgid "Update Required" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:635 msgid "Set the parent_slug config variable instead." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:828 #: admin/includes/class-tgm-plugin-activation.php:3438 msgid "Return to the Dashboard" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:935 msgid "" "The remote plugin package does not contain a folder with the desired slug and " "renaming did not work." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:935 #: admin/includes/class-tgm-plugin-activation.php:938 msgid "" "Please contact the plugin provider and ask them to package their plugin " "according to the WordPress guidelines." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:938 msgid "" "The remote plugin package consists of more than one file, but the files are not " "packaged in a folder." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:1116 #: admin/includes/class-tgm-plugin-activation.php:2828 msgctxt "plugin A *and* plugin B" msgid "and" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:1881 #, php-format msgctxt "%s = version number" msgid "TGMPA v%s" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2167 msgid "Required" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2170 msgid "Recommended" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2186 msgid "WordPress Repository" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2189 msgid "External Source" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2192 msgid "Pre-Packaged" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2209 msgid "Not Installed" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2213 msgid "Installed But Not Activated" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2215 msgid "Active" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2221 msgid "Required Update not Available" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2224 msgid "Requires Update" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2227 msgid "Update recommended" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2235 #, php-format msgctxt "%1$s = install status, %2$s = update status" msgid "%1$s, %2$s" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2280 #, php-format msgctxt "plugins" msgid "All (%s)" msgid_plural "All (%s)" msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:2283 #, php-format msgid "To Install (%s)" msgid_plural "To Install (%s)" msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:2286 #, php-format msgid "Update Available (%s)" msgid_plural "Update Available (%s)" msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:2289 #, php-format msgid "To Activate (%s)" msgid_plural "To Activate (%s)" msgstr[0] "" msgstr[1] "" #: admin/includes/class-tgm-plugin-activation.php:2371 msgctxt "as in: \"version nr unknown\"" msgid "unknown" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2379 msgid "Installed version:" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2387 msgid "Minimum required version:" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2399 msgid "Available version:" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2422 #, php-format msgid "" "No plugins to install, update or activate. Return to the " "Dashboard" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2436 msgid "Plugin" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2437 msgid "Source" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2438 msgid "Type" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2442 #: admin/includes/menus/welcome.php:118 msgid "Version" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2443 #: admin/includes/menus/welcome.php:49 public/includes/editor-modules.php:614 msgid "Status" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2491 #, php-format msgctxt "%2$s = plugin name in screen reader markup" msgid "Install %2$s" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2495 #, php-format msgctxt "%2$s = plugin name in screen reader markup" msgid "Update %2$s" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2500 #, php-format msgctxt "%2$s = plugin name in screen reader markup" msgid "Activate %2$s" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2570 msgid "Upgrade message from the plugin author:" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2603 msgid "Install" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2609 msgid "Update" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2612 msgid "Activate" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2643 msgid "No plugins were selected to be installed. No action taken." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2645 msgid "No plugins were selected to be updated. No action taken." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2681 msgid "No plugins are available to be installed at this time." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2683 msgid "No plugins are available to be updated at this time." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2788 msgid "No plugins were selected to be activated. No action taken." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:2814 msgid "No plugins are available to be activated at this time." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3028 msgid "Plugin activation failed." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3362 #, php-format msgid "Updating Plugin %1$s (%2$d/%3$d)" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3364 #, php-format msgid "An error occurred while installing %1$s: %2$s." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3365 #, php-format msgid "The installation of %1$s failed." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3369 msgid "" "The installation and activation process is starting. This process may take a " "while on some hosts, so please be patient." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3370 #, php-format msgid "%1$s installed and activated successfully." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3370 #: admin/includes/class-tgm-plugin-activation.php:3376 msgid "Show Details" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3370 #: admin/includes/class-tgm-plugin-activation.php:3376 msgid "Hide Details" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3371 msgid "All installations and activations have been completed." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3372 #, php-format msgid "Installing and Activating Plugin %1$s (%2$d/%3$d)" msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3375 msgid "" "The installation process is starting. This process may take a while on some " "hosts, so please be patient." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3376 #, php-format msgid "%1$s installed successfully." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3377 msgid "All installations have been completed." msgstr "" #: admin/includes/class-tgm-plugin-activation.php:3378 #, php-format msgid "Installing Plugin %1$s (%2$d/%3$d)" msgstr "" #: admin/includes/load_admin.php:151 msgid "Dismiss this notice." msgstr "" #: admin/includes/menus/license.php:30 msgid "Aesopinteractive LLC" msgstr "" #: admin/includes/menus/license.php:38 admin/includes/menus/license.php:57 msgid "License Key" msgstr "" #: admin/includes/menus/license.php:38 msgid "License" msgstr "" #: admin/includes/menus/license.php:47 msgid "Editus License" msgstr "" #: admin/includes/menus/license.php:48 msgid "" "Input the license key you recieved with your purchase to ensure your version of " "Editus stays updated." msgstr "" #: admin/includes/menus/license.php:66 admin/includes/menus/license.php:75 msgid "Activate License" msgstr "" #: admin/includes/menus/license.php:70 msgid "active" msgstr "" #: admin/includes/menus/license.php:72 msgid "Deactivate License" msgstr "" #: admin/includes/menus/settings.php:26 public/includes/editor-modules.php:493 #: public/includes/editor-modules.php:892 public/includes/editor-modules.php:894 #: public/includes/editor-modules.php:909 public/includes/editor-modules.php:928 msgid "Settings" msgstr "" #: admin/includes/menus/settings.php:169 msgid "Editus Settings" msgstr "" #: admin/includes/menus/settings.php:177 msgid "Enable for:" msgstr "" #: admin/includes/menus/settings.php:181 msgid "Enable Editus for the following post types." msgstr "" #: admin/includes/menus/settings.php:203 msgid "Internal Settings" msgstr "" #: admin/includes/menus/settings.php:206 msgid "Article Class" msgstr "" #: admin/includes/menus/settings.php:207 msgid "" "Provide the CSS class (including the preceding dot) of container that holds the " "post. This should be the first parent container class that holds the_content." msgstr "" #: admin/includes/menus/settings.php:212 msgid "Featured Image Class" msgstr "" #: admin/includes/menus/settings.php:213 msgid "" "Provide the CSS class that uses a featured image as a background image. This " "currently only supports themes that have the featured image set as background " "image." msgstr "" #: admin/includes/menus/settings.php:218 msgid "Article Title Class" msgstr "" #: admin/includes/menus/settings.php:219 msgid "" "Provide the CSS class for the post title. This will enable you to update the " "title of the post by clicking and typing." msgstr "" #: admin/includes/menus/settings.php:224 msgid "Ignored Items to Save" msgstr "" #: admin/includes/menus/settings.php:225 msgid "" "If your post container holds additional markup, list the css class names (comma " "separated, including the dot) of those items. When you enter the editor, Editus " "will remove (NOT delete) these items so that it does not save them as HTML." msgstr "" #: admin/includes/menus/settings.php:230 msgid "Read Only Items" msgstr "" #: admin/includes/menus/settings.php:231 msgid "" "If your post has items that should not be editable, list the css class names " "(comma separated, including the dot) of those items." msgstr "" #: admin/includes/menus/settings.php:237 msgid "Show Ignored Items" msgstr "" #: admin/includes/menus/settings.php:238 msgid "" "By default the ignored items are hidden. Check this to show ignored items while " "keeping them uneditable." msgstr "" #: admin/includes/menus/settings.php:242 msgid "Editor UI" msgstr "" #: admin/includes/menus/settings.php:246 msgid "Use the Old Toolbar" msgstr "" #: admin/includes/menus/settings.php:247 msgid "" "Use this option to disable the new color options and use the pre-1.0 toolbar." msgstr "" #: admin/includes/menus/settings.php:251 msgid "Editor Bar Color Top" msgstr "" #: admin/includes/menus/settings.php:252 msgid "Editor Bar Color Bottom" msgstr "" #: admin/includes/menus/settings.php:253 msgid "Dialog Color" msgstr "" #: admin/includes/menus/settings.php:254 msgid "Icon/Text Color" msgstr "" #: admin/includes/menus/settings.php:256 msgid "Default Colors" msgstr "" #: admin/includes/menus/settings.php:261 msgid "Enable H2 and H3 Buttons" msgstr "" #: admin/includes/menus/settings.php:262 msgid "Show the buttons to set H2 and H3 settings." msgstr "" #: admin/includes/menus/settings.php:267 msgid "Enable H4/H5/H6 Buttons" msgstr "" #: admin/includes/menus/settings.php:268 msgid "Show the buttons to set H4/H5/H6 settings." msgstr "" #: admin/includes/menus/settings.php:274 msgid "Enable OL/UL Buttons" msgstr "" #: admin/includes/menus/settings.php:275 msgid "" "Show the buttons to create Ordered and Unordered Lists from text selection." msgstr "" #: admin/includes/menus/settings.php:280 msgid "Enable Text Color Buttons" msgstr "" #: admin/includes/menus/settings.php:281 msgid "Show the buttons to set text colors." msgstr "" #: admin/includes/menus/settings.php:286 msgid "Enable Text Align Buttons" msgstr "" #: admin/includes/menus/settings.php:287 msgid "Show the buttons to set text alignment." msgstr "" #: admin/includes/menus/settings.php:293 msgid "Make links editable under the Editing Mode" msgstr "" #: admin/includes/menus/settings.php:294 msgid "" "Make links editable under the Editing Mode. Turning this on will make the links " "non-clickable while editing." msgstr "" #: admin/includes/menus/settings.php:298 msgid "Insert Component UI" msgstr "" #: admin/includes/menus/settings.php:299 msgid "UI mechanism to insert components" msgstr "" #: admin/includes/menus/settings.php:301 msgid "Drag and Drop" msgstr "" #: admin/includes/menus/settings.php:304 msgid "Click" msgstr "" #: admin/includes/menus/settings.php:307 msgid "Auto Button on Empty Paragraph. medium.com-like UI." msgstr "" #: admin/includes/menus/settings.php:313 msgid "Popup When Text is Selected" msgstr "" #: admin/includes/menus/settings.php:314 msgid "" "Instead of using the bottom toolbar to format texts, use a popup box to format " "texts." msgstr "" #: admin/includes/menus/settings.php:320 msgid "Component" msgstr "" #: admin/includes/menus/settings.php:324 msgid "Additional Component: Table" msgstr "" #: admin/includes/menus/settings.php:325 msgid "Allow user to add and edit tables." msgstr "" #: admin/includes/menus/settings.php:331 msgid "Additional Component: Paragraph" msgstr "" #: admin/includes/menus/settings.php:332 msgid "Plain HTML Paragraph." msgstr "" #: admin/includes/menus/settings.php:363 msgid "Use Simple Image" msgstr "" #: admin/includes/menus/settings.php:364 msgid "Use Simple Image Component without Extra Options." msgstr "" #: admin/includes/menus/settings.php:371 msgid "Use WP Image Block" msgstr "" #: admin/includes/menus/settings.php:372 msgid "" "Use WP Image Block as the image component. Gutenberg Block Editor needs to be " "enabled." msgstr "" #: admin/includes/menus/settings.php:379 msgid "Post Settings UI" msgstr "" #: admin/includes/menus/settings.php:383 msgid "Disable Post Settings" msgstr "" #: admin/includes/menus/settings.php:384 msgid "" "Check this to disable users from being able to edit post settings from the " "front-end." msgstr "" #: admin/includes/menus/settings.php:389 msgid "Allow Changing Post Date" msgstr "" #: admin/includes/menus/settings.php:390 msgid "Add the date selector to change the post's date to the Post Setting dialog" msgstr "" #: admin/includes/menus/settings.php:395 msgid "Allow Editing Excerpt" msgstr "" #: admin/includes/menus/settings.php:396 msgid "Allow the post's excerpt to be edited in the Post Setting dialog" msgstr "" #: admin/includes/menus/settings.php:401 msgid "Allow Adding New Category" msgstr "" #: admin/includes/menus/settings.php:402 msgid "Add the user to create new, previously non-existing categories for posts." msgstr "" #: admin/includes/menus/settings.php:407 msgid "Do Not Allow \"Pending\" Status" msgstr "" #: admin/includes/menus/settings.php:408 msgid "Remove the Option to Set the Status to Pending." msgstr "" #: admin/includes/menus/settings.php:413 msgid "Remove POST URL Option" msgstr "" #: admin/includes/menus/settings.php:414 msgid "Remove the Option to Set the URL for the Post." msgstr "" #: admin/includes/menus/settings.php:419 msgid "Disable Post Adding" msgstr "" #: admin/includes/menus/settings.php:420 msgid "" "Check this box to disable users from being able to add new posts from the front-" "end." msgstr "" #: admin/includes/menus/settings.php:425 msgid "Support Custom Taxonomy" msgstr "" #: admin/includes/menus/settings.php:426 msgid "Allow editing custom taxonomies." msgstr "" #: admin/includes/menus/settings.php:432 msgid "Misc" msgstr "" #: admin/includes/menus/settings.php:436 msgid "Do Not Show Tour Dialog" msgstr "" #: admin/includes/menus/settings.php:437 msgid "Check this box to disable the tour dialog box for all users." msgstr "" #: admin/includes/menus/settings.php:441 msgid "Placeholder Text for New Post" msgstr "" #: admin/includes/menus/settings.php:442 msgid "Placeholder text to be displayed when a new post is created." msgstr "" #: admin/includes/menus/settings.php:443 includes/process/new_object.php:38 #: public/includes/assets.php:248 msgid "Once upon a time..." msgstr "" #: admin/includes/menus/settings.php:448 msgid "Do Not Allow Shortcode Editing" msgstr "" #: admin/includes/menus/settings.php:449 msgid "Check this box to disable frontend editing of shortcodes." msgstr "" #: admin/includes/menus/settings.php:453 msgid "\"Bold\" Tag" msgstr "" #: admin/includes/menus/settings.php:454 msgid "Choose the HTML tag used for the \"Bold\" style." msgstr "" #: admin/includes/menus/settings.php:459 msgid "\"Italic\" Tag" msgstr "" #: admin/includes/menus/settings.php:460 msgid "Choose the HTML tag used for the \"Italic\" style." msgstr "" #: admin/includes/menus/settings.php:466 msgid "Auto Prefix HTTP to links" msgstr "" #: admin/includes/menus/settings.php:467 msgid "" "When user adds a hyperlink, automatically add http:// if the user does not " "specify it explicitly." msgstr "" #: admin/includes/menus/settings.php:471 msgid "Advanced Options" msgstr "" #: admin/includes/menus/settings.php:472 msgid "Suggested not to turn these options on without consulting the developer." msgstr "" #: admin/includes/menus/settings.php:477 msgid "Disable Aesop Component Conversion" msgstr "" #: admin/includes/menus/settings.php:478 msgid "" "Check this box to disable the conversion process used on Aesop Story Engine " "components." msgstr "" #: admin/includes/menus/settings.php:483 msgid "Enable Auto Save" msgstr "" #: admin/includes/menus/settings.php:484 msgid "Check this box to enable auto save." msgstr "" #: admin/includes/menus/settings.php:489 msgid "Disable Post Saving" msgstr "" #: admin/includes/menus/settings.php:490 msgid "" "By default the editor will update the database with the post or page it is " "being used on. Check this box to disable this. If you check this box, it is " "assumed that you will be using the provided filters to save your own content." msgstr "" #: admin/includes/menus/settings.php:496 msgid "Disable Post Editing" msgstr "" #: admin/includes/menus/settings.php:497 msgid "" "You may use this option if you only want to edit custom fields. Refer here for more information. The custom fields you specify will be still " "editable under the editing mode." msgstr "" #: admin/includes/menus/settings.php:503 msgid "Don't Use REST API to Save" msgstr "" #: admin/includes/menus/settings.php:504 msgid "" "By default the editor will use REST API to save posts. Check this box to use " "custom AJAX calls instead." msgstr "" #: admin/includes/menus/settings.php:510 msgid "Don't Wrap Shortcodes" msgstr "" #: admin/includes/menus/settings.php:511 msgid "" "By default Editus wraps shortcodes so they can be preserved. Disable this " "behavior." msgstr "" #: admin/includes/menus/settings.php:521 msgid "Save Settings" msgstr "" #: admin/includes/menus/welcome.php:48 msgid "Editus" msgstr "" #: admin/includes/menus/welcome.php:49 msgid "Welcome" msgstr "" #: admin/includes/menus/welcome.php:71 msgid "" "We will check the current theme on every site in your network and give you a " "quick status feedback here. You can see the status by visiting the Editus menu " "on each site." msgstr "" #: admin/includes/menus/welcome.php:90 msgid "You're Ready to Rock!" msgstr "" #: admin/includes/menus/welcome.php:92 msgid "Your theme is automatically supported. No additional setup is needed." msgstr "" #: admin/includes/menus/welcome.php:94 msgid "" "Editus will place a small menu on the bottom of your site. While on a single " "post or page, click the \"pen\" icon to go into edit mode. Press escape to get " "out of edit mode." msgstr "" #: admin/includes/menus/welcome.php:117 msgid "Welcome to Editus" msgstr "" #: admin/includes/menus/welcome.php:123 msgid "Help" msgstr "" #: admin/includes/menus/welcome.php:124 msgid "Twitter" msgstr "" #: admin/includes/menus/welcome.php:125 msgid "Facebook" msgstr "" #: admin/includes/menus/welcome.php:158 msgid "Article CSS Class Needed!" msgstr "" #: admin/includes/menus/welcome.php:159 msgid "Before using Editus," msgstr "" #: admin/includes/menus/welcome.php:159 msgid "enter and save" msgstr "" #: admin/includes/menus/welcome.php:159 msgid "" "the CSS class of the container that holds your post and page content. You can " "use a tool like inspector in " "Chrome or Firefox to find this CSS class, or " msgstr "" #: admin/includes/menus/welcome.php:159 msgid "email us." msgstr "" #: admin/includes/menus/welcome.php:159 msgid "with a link to a public URL with the theme and we'll find it for you." msgstr "" #: admin/includes/menus/welcome.php:166 msgid "" "Just a heads up that the WP REST API isn't activated. This is required to list " "the posts and pages on the front-end." msgstr "" #: admin/includes/menus/welcome.php:173 msgid "Just a heads up that " msgstr "" #: admin/includes/menus/welcome.php:174 admin/includes/menus/welcome.php:211 msgid "Aesop Story Engine" msgstr "" #: admin/includes/menus/welcome.php:174 msgid "" "isn't activated. It's not required to use Editus, but you won't get the cool " "drag and drop components without it activated. It's free!" msgstr "" #: admin/includes/menus/welcome.php:180 msgid "WP Side Comments Compatibility Warning!" msgstr "" #: admin/includes/menus/welcome.php:181 msgid "" "Since Editus saves the HTML of a post, this may cause undesired issues. We're " "working to resolve incompatibilities faster than a jack rabbit in a hot greasy " "griddle in the middle of August." msgstr "" #: admin/includes/menus/welcome.php:187 msgid "License Key Not Activated" msgstr "" #: admin/includes/menus/welcome.php:188 msgid "" "Just a heads up, your license key isn't activated. Enter your license key into " "the License tab on the left in order to receive plugin update notifications." msgstr "" #: admin/includes/menus/welcome.php:192 msgid "License Key Invalid" msgstr "" #: admin/includes/menus/welcome.php:193 msgid "The license key that you entered is " msgstr "" #: admin/includes/menus/welcome.php:193 msgid "invalid" msgstr "" #: admin/includes/menus/welcome.php:193 msgid ". It may have been entered incorreclty, or may have expired." msgstr "" #: admin/includes/menus/welcome.php:231 #, php-format msgid "This plugin requires the following plugin: %1$s." msgid_plural "This plugin requires the following plugins: %1$s." msgstr[0] "" msgstr[1] "" #: admin/includes/menus/welcome.php:232 #, php-format msgid "This plugin recommends the following plugin: %1$s." msgid_plural "This plugin recommends the following plugins: %1$s." msgstr[0] "" msgstr[1] "" #: admin/includes/menus/welcome.php:233 #, php-format msgid "" "Sorry, but you do not have the correct permissions to install the %s plugin. " "Contact the administrator of this site for help on getting the plugin installed." msgid_plural "" "Sorry, but you do not have the correct permissions to install the %s plugins. " "Contact the administrator of this site for help on getting the plugins " "installed." msgstr[0] "" msgstr[1] "" #: admin/includes/menus/welcome.php:236 #, php-format msgid "" "Sorry, but you do not have the correct permissions to activate the %s plugin. " "Contact the administrator of this site for help on getting the plugin activated." msgid_plural "" "Sorry, but you do not have the correct permissions to activate the %s plugins. " "Contact the administrator of this site for help on getting the plugins " "activated." msgstr[0] "" msgstr[1] "" #: admin/includes/menus/welcome.php:237 #, php-format msgid "" "The following plugin needs to be updated to its latest version to ensure " "maximum compatibility with this plugin: %1$s." msgid_plural "" "The following plugins need to be updated to their latest version to ensure " "maximum compatibility with this plugin: %1$s." msgstr[0] "" msgstr[1] "" #: admin/includes/menus/welcome.php:238 #, php-format msgid "" "Sorry, but you do not have the correct permissions to update the %s plugin. " "Contact the administrator of this site for help on getting the plugin updated." msgid_plural "" "Sorry, but you do not have the correct permissions to update the %s plugins. " "Contact the administrator of this site for help on getting the plugins updated." msgstr[0] "" msgstr[1] "" #: admin/includes/menus/welcome.php:243 #, php-format msgid "All plugins installed and activated successfully. %s" msgstr "" #: includes/process/gallery.php:40 msgid "Save and refresh to view gallery." msgstr "" #: includes/process/gallery.php:199 msgid "Delete From Gallery" msgstr "" #: includes/process/gallery.php:200 msgid "Edit Image Caption" msgstr "" #: internal-api/auth.php:67 msgid "Unauthorized action" msgstr "" #: internal-api/auth.php:71 msgid "" "All callback classes used for processing the Editus Internal API must implement " "the lasso\\internal_api\\api_action interface." msgstr "" #: internal-api/auth.php:76 msgid "Nonce invalid" msgstr "" #: internal-api/route.php:30 msgid "Editus API Error." msgstr "" #: internal-api/route.php:66 msgid "Nonce not set." msgstr "" #: lasso.php:130 msgid "Insert Column" msgstr "" #: lasso.php:131 msgid "Insert Row" msgstr "" #: lasso.php:132 msgid "Delete Column" msgstr "" #: lasso.php:133 msgid "Delete Row" msgstr "" #: lasso.php:134 msgid "Delete Table" msgstr "" #: lasso.php:149 lasso.php:159 msgid "HTML Table" msgstr "" #: lasso.php:192 lasso.php:220 msgid "HTML Paragraph" msgstr "" #: public/includes/assets.php:146 public/includes/editor-modules.php:713 #: public/includes/option-engine.php:132 msgid "Save" msgstr "" #: public/includes/assets.php:147 msgid "Please Select Text First." msgstr "" #: public/includes/assets.php:148 public/includes/editor-modules.php:439 #: public/includes/editor-modules.php:706 public/includes/editor-modules.php:788 #: public/includes/editor-modules.php:1329 msgid "Cancel" msgstr "" #: public/includes/assets.php:149 msgid "Exit Editor" msgstr "" #: public/includes/assets.php:150 msgid "Saving..." msgstr "" #: public/includes/assets.php:151 msgid "Saved!" msgstr "" #: public/includes/assets.php:152 msgid "Adding..." msgstr "" #: public/includes/assets.php:153 msgid "Added!" msgstr "" #: public/includes/assets.php:154 msgid "Loading..." msgstr "" #: public/includes/assets.php:155 msgid "Load More" msgstr "" #: public/includes/assets.php:156 public/includes/helpers.php:457 msgid "Close" msgstr "" #: public/includes/assets.php:157 msgid "No more posts found" msgstr "" #: public/includes/assets.php:158 msgid "Fetching failed." msgstr "" #: public/includes/assets.php:159 msgid "Gallery Created!" msgstr "" #: public/includes/assets.php:160 msgid "Gallery Updated!" msgstr "" #: public/includes/assets.php:161 msgid "Just write..." msgstr "" #: public/includes/assets.php:162 msgid "Choose an image" msgstr "" #: public/includes/assets.php:163 msgid "Update Image" msgstr "" #: public/includes/assets.php:164 msgid "Insert Image" msgstr "" #: public/includes/assets.php:165 msgid "Select Image" msgstr "" #: public/includes/assets.php:166 msgid "Remove featured image?" msgstr "" #: public/includes/assets.php:167 msgid "Update Selected Image" msgstr "" #: public/includes/assets.php:168 msgid "Choose images" msgstr "" #: public/includes/assets.php:169 msgid "Edit Image" msgstr "" #: public/includes/assets.php:170 public/includes/editor-modules--gallery.php:28 msgid "Add Images" msgstr "" #: public/includes/assets.php:171 msgid "Add New Gallery" msgstr "" #: public/includes/assets.php:172 msgid "Select Editus Gallery Image" msgstr "" #: public/includes/assets.php:173 msgid "Use Selected Images" msgstr "" #: public/includes/assets.php:174 msgid "Publish Post?" msgstr "" #: public/includes/assets.php:175 msgid "Yes, publish it!" msgstr "" #: public/includes/assets.php:176 msgid "Trash Post?" msgstr "" #: public/includes/assets.php:177 msgid "Yes, trash it!" msgstr "" #: public/includes/assets.php:178 msgid "Oh snap!" msgstr "" #: public/includes/assets.php:179 msgid "O.K. got it!" msgstr "" #: public/includes/assets.php:180 msgid "" "It looks like we are either missing the Article CSS class, or it is configured " "incorrectly. Editus will not function correctly without this CSS class." msgstr "" #: public/includes/assets.php:181 msgid "Update Settings" msgstr "" #: public/includes/assets.php:182 msgid "one more letter" msgstr "" #: public/includes/assets.php:183 msgid "You are currently editing a backup copy of this post." msgstr "" #: public/includes/assets.php:185 msgid "add categories..." msgstr "" #: public/includes/assets.php:186 msgid "add tags..." msgstr "" #: public/includes/assets.php:187 msgid "add taxonomy terms..." msgstr "" #: public/includes/assets.php:188 msgid "Edit Shortcode" msgstr "" #: public/includes/components.php:19 public/includes/editor-modules.php:352 msgid "Quote" msgstr "" #: public/includes/components.php:23 public/includes/editor-modules.php:350 #: public/includes/editor-modules.php:1103 public/includes/editor-modules.php:1154 #: public/includes/editor-modules.php:1218 msgid "Image" msgstr "" #: public/includes/components.php:27 #: public/includes/editor-modules--gallery.php:74 #: public/includes/editor-modules.php:355 msgid "Parallax" msgstr "" #: public/includes/components.php:31 public/includes/editor-modules.php:356 msgid "Audio" msgstr "" #: public/includes/components.php:35 public/includes/editor-modules.php:353 #: public/includes/editor-modules.php:1080 msgid "Content" msgstr "" #: public/includes/components.php:39 public/includes/editor-modules.php:351 msgid "Character" msgstr "" #: public/includes/components.php:43 public/includes/editor-modules.php:361 msgid "Collection" msgstr "" #: public/includes/components.php:47 public/includes/editor-modules.php:360 msgid "Document" msgstr "" #: public/includes/components.php:51 public/includes/editor-modules.php:362 msgid "Gallery" msgstr "" #: public/includes/components.php:55 public/includes/editor-modules.php:354 msgid "Chapter" msgstr "" #: public/includes/components.php:59 public/includes/editor-modules.php:358 msgid "Map" msgstr "" #: public/includes/components.php:63 public/includes/editor-modules.php:359 msgid "Timeline" msgstr "" #: public/includes/components.php:67 public/includes/editor-modules.php:357 msgid "Video" msgstr "" #: public/includes/components.php:71 public/includes/components.php:91 #: public/includes/editor-modules.php:371 public/includes/editor-modules.php:373 msgid "WordPress Image" msgstr "" #: public/includes/components.php:75 msgid "WordPress Image Block" msgstr "" #: public/includes/components.php:79 public/includes/editor-modules.php:375 msgid "WordPress Quote" msgstr "" #: public/includes/components.php:83 public/includes/editor-modules.php:364 msgid "Gallery Pop" msgstr "" #: public/includes/components.php:87 msgid "Events" msgstr "" #: public/includes/editor-modules--gallery.php:19 msgid "Create gallery" msgstr "" #: public/includes/editor-modules--gallery.php:27 msgid "Manage Images" msgstr "" #: public/includes/editor-modules--gallery.php:31 msgid "Rearrange or edit the images in this gallery." msgstr "" #: public/includes/editor-modules--gallery.php:47 msgid "Create a Gallery" msgstr "" #: public/includes/editor-modules--gallery.php:51 msgid "Select images to create a gallery." msgstr "" #: public/includes/editor-modules--gallery.php:52 msgid "Select Images" msgstr "" #: public/includes/editor-modules--gallery.php:56 msgid "Create Gallery" msgstr "" #: public/includes/editor-modules--gallery.php:67 msgid "Gallery Type" msgstr "" #: public/includes/editor-modules--gallery.php:68 msgid "Select the type of gallery." msgstr "" #: public/includes/editor-modules--gallery.php:70 msgid "Grid" msgstr "" #: public/includes/editor-modules--gallery.php:71 msgid "Thumbnail" msgstr "" #: public/includes/editor-modules--gallery.php:73 msgid "Photoset" msgstr "" #: public/includes/editor-modules--gallery.php:84 msgid "Grid Item Width" msgstr "" #: public/includes/editor-modules--gallery.php:85 msgid "" "Adjust the width of the individual grid items, only if using Grid gallery " "style. Default is 400." msgstr "" #: public/includes/editor-modules--gallery.php:95 msgid "Gallery Transition" msgstr "" #: public/includes/editor-modules--gallery.php:96 msgid "Adjust the transition effect for the Thumbnail gallery. Default is slide." msgstr "" #: public/includes/editor-modules--gallery.php:98 msgid "Fade" msgstr "" #: public/includes/editor-modules--gallery.php:99 msgid "Slide" msgstr "" #: public/includes/editor-modules--gallery.php:100 msgid "Dissolve" msgstr "" #: public/includes/editor-modules--gallery.php:105 msgid "Gallery Transition Speed" msgstr "" #: public/includes/editor-modules--gallery.php:106 msgid "Activate slideshow by setting a speed for the transition.5000 = 5 seconds." msgstr "" #: public/includes/editor-modules--gallery.php:112 msgid "Hide Gallery Thumbnails" msgstr "" #: public/includes/editor-modules--gallery.php:121 msgid "Gallery Layout" msgstr "" #: public/includes/editor-modules--gallery.php:122 msgid "" "Let's say you have 4 images in this gallery. If you enter 121 you will have one " "image on the top row, two images on the second row, and one image on the third " "row." msgstr "" #: public/includes/editor-modules--gallery.php:137 msgid "Main Gallery Height" msgstr "" #: public/includes/editor-modules--gallery.php:138 #, php-format msgid "" "Adjust the overall height of the gallery. Acceptable values include 500px or " "50% etc." msgstr "" #: public/includes/editor-modules--gallery.php:148 msgid "Main Gallery Width" msgstr "" #: public/includes/editor-modules--gallery.php:149 #, php-format msgid "" "Adjust the overall width of the gallery. Acceptable values include 500px or " "50% etc." msgstr "" #: public/includes/editor-modules--gallery.php:153 msgid "Gallery Caption" msgstr "" #: public/includes/editor-modules--gallery.php:154 msgid "Add an optional caption for the gallery." msgstr "" #: public/includes/editor-modules.php:60 public/includes/editor-modules.php:437 msgid "Table" msgstr "" #: public/includes/editor-modules.php:137 #: public/includes/underscore-templates.php:23 #: public/includes/underscore-templates.php:41 msgid "Edit Post" msgstr "" #: public/includes/editor-modules.php:140 public/includes/editor-modules.php:164 #: public/includes/editor-modules.php:457 msgid "Post Settings" msgstr "" #: public/includes/editor-modules.php:145 msgid "All Posts" msgstr "" #: public/includes/editor-modules.php:148 public/includes/editor-modules.php:1323 msgid "Revisions" msgstr "" #: public/includes/editor-modules.php:152 msgid "Add Post" msgstr "" #: public/includes/editor-modules.php:163 public/includes/editor-modules.php:456 #: public/includes/underscore-templates.php:25 #: public/includes/underscore-templates.php:43 msgid "Delete Post" msgstr "" #: public/includes/editor-modules.php:167 public/includes/editor-modules.php:459 msgid "Save Post" msgstr "" #: public/includes/editor-modules.php:170 public/includes/editor-modules.php:462 msgid "Publish Post" msgstr "" #: public/includes/editor-modules.php:170 msgid "Submit For Review" msgstr "" #: public/includes/editor-modules.php:249 public/includes/editor-modules.php:342 msgid "Bold" msgstr "" #: public/includes/editor-modules.php:250 public/includes/editor-modules.php:343 msgid "Underline" msgstr "" #: public/includes/editor-modules.php:251 public/includes/editor-modules.php:344 msgid "Italicize" msgstr "" #: public/includes/editor-modules.php:252 public/includes/editor-modules.php:345 msgid "Strikethrough" msgstr "" #: public/includes/editor-modules.php:255 public/includes/editor-modules.php:384 #: public/includes/editor-modules.php:431 msgid "H2 Heading" msgstr "" #: public/includes/editor-modules.php:256 public/includes/editor-modules.php:385 #: public/includes/editor-modules.php:432 msgid "H3 Heading" msgstr "" #: public/includes/editor-modules.php:262 public/includes/editor-modules.php:391 msgid "H4 Heading" msgstr "" #: public/includes/editor-modules.php:263 public/includes/editor-modules.php:392 msgid "H5 Heading" msgstr "" #: public/includes/editor-modules.php:264 public/includes/editor-modules.php:393 msgid "H6 Heading" msgstr "" #: public/includes/editor-modules.php:268 public/includes/editor-modules.php:397 msgid "Set Color for Selected Text" msgstr "" #: public/includes/editor-modules.php:269 public/includes/editor-modules.php:398 msgid "Choose Color" msgstr "" #: public/includes/editor-modules.php:273 public/includes/editor-modules.php:402 #: public/includes/editor-modules.php:434 msgid "Ordered List" msgstr "" #: public/includes/editor-modules.php:274 public/includes/editor-modules.php:403 #: public/includes/editor-modules.php:435 msgid "Unordered List" msgstr "" #: public/includes/editor-modules.php:278 public/includes/editor-modules.php:407 msgid "Anchor Link" msgstr "" #: public/includes/editor-modules.php:280 public/includes/editor-modules.php:409 msgid "http://url.com" msgstr "" #: public/includes/editor-modules.php:281 public/includes/editor-modules.php:410 msgid "Create Link" msgstr "" #: public/includes/editor-modules.php:283 public/includes/editor-modules.php:412 msgid "Open in a New Tab" msgstr "" #: public/includes/editor-modules.php:347 msgid "Insert Component" msgstr "" #: public/includes/editor-modules.php:367 msgid "Event" msgstr "" #: public/includes/editor-modules.php:376 msgid "WordPress Video" msgstr "" #: public/includes/editor-modules.php:419 public/includes/editor-modules.php:440 msgid "Insert HTML or Code" msgstr "" #: public/includes/editor-modules.php:421 public/includes/editor-modules.php:424 msgid "Enter HTML to insert" msgstr "" #: public/includes/editor-modules.php:425 msgid "You can also use Shortcodes" msgstr "" #: public/includes/editor-modules.php:426 msgid "" "You can also enter a URL to embed, such as Youtube, Vimeo and Twitter URLs." msgstr "" #: public/includes/editor-modules.php:440 msgid "Insert" msgstr "" #: public/includes/editor-modules.php:446 msgid "Text Left Align" msgstr "" #: public/includes/editor-modules.php:447 msgid "Text Center Align" msgstr "" #: public/includes/editor-modules.php:448 msgid "Text Right Align" msgstr "" #: public/includes/editor-modules.php:492 public/includes/editor-modules.php:890 #: public/includes/editor-modules.php:908 public/includes/editor-modules.php:927 msgid "Move" msgstr "" #: public/includes/editor-modules.php:494 public/includes/editor-modules.php:896 #: public/includes/editor-modules.php:910 public/includes/editor-modules.php:929 msgid "Clone" msgstr "" #: public/includes/editor-modules.php:495 public/includes/editor-modules.php:897 #: public/includes/editor-modules.php:911 public/includes/editor-modules.php:930 msgid "Delete" msgstr "" #: public/includes/editor-modules.php:517 msgid "Replace Image" msgstr "" #: public/includes/editor-modules.php:518 msgid "Delete Image" msgstr "" #: public/includes/editor-modules.php:519 msgid "save" msgstr "" #: public/includes/editor-modules.php:593 msgid "Featured Image" msgstr "" #: public/includes/editor-modules.php:593 msgid "Change the featured image for this post." msgstr "" #: public/includes/editor-modules.php:597 msgid "Change Featured Image" msgstr "" #: public/includes/editor-modules.php:598 msgid "Delete Featured Image" msgstr "" #: public/includes/editor-modules.php:614 msgid "Change the status of the post to draft or publish." msgstr "" #: public/includes/editor-modules.php:616 msgid "Draft" msgstr "" #: public/includes/editor-modules.php:618 msgid "Pending" msgstr "" #: public/includes/editor-modules.php:620 msgid "Publish" msgstr "" #: public/includes/editor-modules.php:630 msgid "Post URL" msgstr "" #: public/includes/editor-modules.php:630 msgid "Change the URL (slug) of this post." msgstr "" #: public/includes/editor-modules.php:640 msgid "Categories" msgstr "" #: public/includes/editor-modules.php:640 msgid "Type a category name and press enter." msgstr "" #: public/includes/editor-modules.php:645 msgid "Tags" msgstr "" #: public/includes/editor-modules.php:645 msgid "Type a tag name and press enter." msgstr "" #: public/includes/editor-modules.php:653 msgid "Custom Taxonomy" msgstr "" #: public/includes/editor-modules.php:653 msgid "Choose custom taxonomy." msgstr "" #: public/includes/editor-modules.php:670 msgid "Excerpt" msgstr "" #: public/includes/editor-modules.php:670 msgid "Edit excerpt" msgstr "" #: public/includes/editor-modules.php:679 msgid "Post Date" msgstr "" #: public/includes/editor-modules.php:681 msgid "Set to Now" msgstr "" #: public/includes/editor-modules.php:762 msgid "New post title" msgstr "" #: public/includes/editor-modules.php:762 msgid "Specify title for new post, then save to edit." msgstr "" #: public/includes/editor-modules.php:763 msgid "Type Your Title Here" msgstr "" #: public/includes/editor-modules.php:800 msgid "Create" msgstr "" #: public/includes/editor-modules.php:839 msgid "results found" msgstr "" #: public/includes/editor-modules.php:952 msgid "Save Locations" msgstr "" #: public/includes/editor-modules.php:970 msgid "Save this post and refesh the page to see these changes." msgstr "" #: public/includes/editor-modules.php:1109 public/includes/editor-modules.php:1224 #: public/includes/editor-modules.php:1289 msgid "Image URL" msgstr "" #: public/includes/editor-modules.php:1110 public/includes/editor-modules.php:1225 #: public/includes/editor-modules.php:1290 msgid "" "URL for the image. Click Select Media to open the WordPress Media " "Library." msgstr "" #: public/includes/editor-modules.php:1117 public/includes/editor-modules.php:1232 msgid "Center" msgstr "" #: public/includes/editor-modules.php:1121 public/includes/editor-modules.php:1236 msgid "Left" msgstr "" #: public/includes/editor-modules.php:1125 public/includes/editor-modules.php:1240 msgid "Right" msgstr "" #: public/includes/editor-modules.php:1129 public/includes/editor-modules.php:1244 msgid "Alignment" msgstr "" #: public/includes/editor-modules.php:1136 msgid "Image Width" msgstr "" #: public/includes/editor-modules.php:1137 msgid "" "Width of the image. You can enter the size in pixels or percentage such as " "40% or 500px." msgstr "" #: public/includes/editor-modules.php:1142 msgid "Image Height" msgstr "" #: public/includes/editor-modules.php:1143 msgid "" "Used only for the Panorama mode. Can be set using pixel values such as " "500px. If unspecified, the original height would be used. " msgstr "" #: public/includes/editor-modules.php:1150 msgid "None" msgstr "" #: public/includes/editor-modules.php:1158 msgid "URL" msgstr "" #: public/includes/editor-modules.php:1162 msgid "Link" msgstr "" #: public/includes/editor-modules.php:1163 msgid "Click leads to:" msgstr "" #: public/includes/editor-modules.php:1169 msgid "URL Link" msgstr "" #: public/includes/editor-modules.php:1170 msgid "URL link" msgstr "" #: public/includes/editor-modules.php:1175 public/includes/editor-modules.php:1250 msgid "Image ALT" msgstr "" #: public/includes/editor-modules.php:1176 public/includes/editor-modules.php:1251 msgid "ALT tag used for the image. Primarily used for SEO purposes." msgstr "" #: public/includes/editor-modules.php:1182 public/includes/editor-modules.php:1256 msgid "Caption" msgstr "" #: public/includes/editor-modules.php:1183 public/includes/editor-modules.php:1257 msgid "Optional caption for the image." msgstr "" #: public/includes/editor-modules.php:1188 msgid "An image." msgstr "" #: public/includes/editor-modules.php:1262 msgid "Link URL" msgstr "" #: public/includes/editor-modules.php:1263 msgid "Optional URL to link." msgstr "" #: public/includes/editor-modules.php:1268 msgid "A WP Image Block." msgstr "" #: public/includes/editor-modules.php:1283 msgid "Cover" msgstr "" #: public/includes/editor-modules.php:1294 msgid "A WP Cover Block." msgstr "" #: public/includes/editor-modules.php:1323 msgid "Use the slider to view the revision live on the page." msgstr "" #: public/includes/editor-modules.php:1330 msgid "Select" msgstr "" #: public/includes/helpers.php:449 msgid "No posts to show" msgstr "" #: public/includes/helpers.php:455 msgid "No revisions found" msgstr "" #: public/includes/lasso.php:292 msgid "Post being edited by " msgstr "" #: public/includes/tour.php:67 msgid "Don't show this again" msgstr "" #: public/includes/tour.php:71 msgid "Okay, got it!" msgstr "" #: public/includes/tour.php:96 msgid "" "Access posts by clicking the list icon. Create a new post by clicking the new " "post icon." msgstr "" #: public/includes/tour.php:99 msgid "" "While on a single post, edit by clicking the Pen icon. Access post settings " "with the settings icon. Press escape to exit any modal." msgstr "" #: public/includes/tour.php:102 msgid "" "Highlight a piece of text, and click on a formatting option to style it. Click " "the Disk icon or CMD-S to save. Click the orange \"X\" button to exit the " "editor." msgstr "" #: public/includes/tour.php:105 msgid "" "Story components can be added by clicking the plus icon, and dragging any " "component from the component tray into the story." msgstr "" ================================================ FILE: lasso.php ================================================ , Nick Haskins * @link http://edituswp.com * @copyright 2015-2021 Aesopinteractive * * Plugin Name: Editus * Plugin URI: http://edituswp.com * Description: Front-end editor and story builder. * Version: 1.7.0 * Author: Aesopinteractive * Author URI: http://aesopinteractive.com * Text Domain: lasso * Domain Path: /languages */ // If this file is called directly, abort. if ( ! defined( 'WPINC' ) ) { die; } // Set some constants define( 'LASSO_VERSION', '1.7.0' ); define( 'LASSO_DIR', plugin_dir_path( __FILE__ ) ); define( 'LASSO_URL', plugins_url( '', __FILE__ ) ); define( 'LASSO_FILE', __FILE__ ); /** * Load plugin if PHP version is 5.4 or later. */ if ( version_compare( PHP_VERSION, '5.4.0', '>=' ) ) { include_once( LASSO_DIR . '/bootstrap.php' ); } else { add_action('admin_head', 'lasso_fail_notice'); function lasso_fail_notice(){ printf('

    Editus requires PHP 5.4 or higher.

    '); } } add_filter('register_post_type_args', 'lasso_show_in_rest', 10, 2); function lasso_show_in_rest($args, $post_type){ $allowed_post_types = lasso_editor_get_option( 'allowed_post_types', 'lasso_editor', array( ) ); $allowed_post_types = apply_filters( 'lasso_allowed_post_types', $allowed_post_types ); if (in_array( $post_type,$allowed_post_types)) { $args['show_in_rest'] = true; if ($post_type != 'post' && $post_type != 'page') { $args['rest_base'] = $post_type; } } return $args; } function lasso_editor_get_option( $option, $section, $default = '' ) { if ( empty( $option ) ) return; if ( function_exists( 'is_multisite' ) && is_multisite() ) { $options = get_site_option( $section ); } else { $options = get_option( $section ); } if ( isset( $options[$option] ) ) { return $options[$option]; } return $default; } register_meta('user', 'lasso_hide_tour', array( "type" => "string", "show_in_rest" => true // this is the key part )); // Gutenberg if( function_exists( 'is_gutenberg_page' ) ) { function add_raw_to_post( $response, $post, $request ) { $response_data = $response->get_data(); if ( is_array( $response_data['content'] )) { $response_data['content']['raw'] = $post->post_content ; $response->set_data( $response_data ); } return $response; } add_filter( "rest_prepare_post", 'add_raw_to_post', 10, 3 ); } //table codes to be added class editus_table { public function __construct(){ $add_table = lasso_editor_get_option('add_table', 'lasso_editor', false); if ($add_table) { add_action('wp_enqueue_scripts', array($this,'scripts')); } } function scripts() { add_action('lasso_editor_controls_after_outside', array($this,'editus_table_edit_menu')); add_filter('lasso_components',array($this,'editus_components_add_table'),10,1); add_action( 'lasso_toolbar_components', array($this,'editus_toolbar_components_add_table'), 10 ); wp_enqueue_style( 'editus-table-style', LASSO_URL. '/public/assets/css/editus-table-edit-public.css', LASSO_VERSION, true ); wp_enqueue_script( 'editus_table', LASSO_URL. '/public/assets/js/editus-table-edit-public.js', array( 'jquery' ), LASSO_VERSION, true ); } function editus_table_edit_menu() { ?>
    • Cell 1Cell 2
      Cell 3Cell 4


      '; } function editus_components_add_table( $array ){ $custom = array( 'htmltable' => array( 'name' => __('HTML Table','lasso'), 'content' => self::editus_html_table(), ) ); return array_merge( $array, $custom ); } function editus_toolbar_components_add_table( ) { ?>
    • array( 'name' => __('HTML Paragraph','lasso'), 'content' => self::editus_html_paragraph(), ) ); return array_merge( $array, $custom ); } function editus_html_paragraph() { return '


      '; } function editus_paragraph_style() { ?>
    • .ps-scrollbar-x-rail,.ps-container.ps-active-y>.ps-scrollbar-y-rail{display:block}.ps-container>.ps-scrollbar-x-rail{display:none;position:absolute;opacity:0;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;-o-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;bottom:3px;height:8px}.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x{position:absolute;background-color:#32373c;-webkit-transition:background-color .2s linear;-moz-transition:background-color .2s linear;-o-transition:background-color .2s linear;transition:background-color .2s linear;bottom:0;height:8px}.ps-container>.ps-scrollbar-x-rail.in-scrolling{background-color:transparent;opacity:.9;-ms-filter:"alpha(Opacity=90)";filter:alpha(opacity=90)}.ps-container>.ps-scrollbar-y-rail{display:none;position:absolute;opacity:0;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;-o-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;right:3px;width:8px}.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y{position:absolute;background-color:#32373c;-webkit-transition:background-color .2s linear;-moz-transition:background-color .2s linear;-o-transition:background-color .2s linear;transition:background-color .2s linear;right:0;width:8px}.ps-container>.ps-scrollbar-y-rail.in-scrolling{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail,.ps-container:hover>.ps-scrollbar-y-rail{opacity:.6;filter:alpha(opacity=60)}.ps-container:hover>.ps-scrollbar-x-rail.in-scrolling,.ps-container:hover>.ps-scrollbar-y-rail.in-scrolling{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail:hover{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x{background-color:#999}.ps-container:hover>.ps-scrollbar-y-rail:hover{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y{background-color:#999}.lasso-sidebar-open{overflow:hidden}.lasso-sidebar-open .lasso-buttoninsert-wrap,.lasso-sidebar-open #lasso--sidebar{right:0}#lasso--sidebar{z-index:9999;position:fixed;right:-285px;top:0;bottom:0;width:285px;-webkit-transition:right .25s ease;-moz-transition:right .25s ease;transition:right .25s ease}#lasso--sidebar *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#lasso--sidebar label,#lasso--sidebar p{color:#e2e2e2;background:#23282d}#lasso--sidebar code{color:#e2e2e2;background:#23282d}.admin-bar #lasso--sidebar{top:32px}.admin-bar #lasso--component__settings form{padding-bottom:102px}.lasso--sidebar__inner{height:100%;font-family:Arial;font-size:14px;background:#23282d;border-left:4px solid #353c44;color:#e2e2e2;text-shadow:0 1px 1px rgba(0,0,0,.4);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-box-shadow:inset 9px 0 9px -9px #000;box-shadow:inset 9px 0 9px -9px #000}.lasso--sidebar__inner #lasso--sidebar__close{color:#007aab}.lasso--sidebar__inner #lasso--component__settings{overflow:hidden;position:relative}#lasso--sidebar__drag{height:100px;width:50px;background:red;top:50%;bottom:0;position:absolute}ul.lasso-component--controls{color:#e2e2e2;border:1px solid #181b1f;background-image:-webkit-linear-gradient(top,#353c44 0,#23282d 100%);background-image:-o-linear-gradient(top,#353c44 0,#23282d 100%);background-image:linear-gradient(to bottom,#353c44 0,#23282d 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff353c44', endColorstr='#ff23282d', GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);position:absolute;margin:0;padding:0;line-height:1;height:26px;width:121px;top:4px;text-align:center;margin:0 auto;border-radius:2px;opacity:0;filter:alpha(opacity=0);-webkit-transition:opacity .4s ease;-moz-transition:opacity .4s ease;transition:opacity .4s ease;z-index:105;padding-left:0}ul.lasso-component--controls *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.lasso-component--controls:before,ul.lasso-component--controls:after{content:" ";display:table}ul.lasso-component--controls:after{clear:both}ul.lasso-component--controls.editus-center{left:0;right:0}ul.lasso-component--controls.editus-right{right:0}ul.lasso-component--controls li{float:left;list-style-type:none;line-height:1;margin:0;width:29.51219512px;height:24px;border-right:1px solid #23282d;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,.4)}ul.lasso-component--controls li:before{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;position:relative;top:1px;font-size:15px}ul.lasso-component--controls li:first-child:hover{border-bottom-left-radius:2px;border-top-left-radius:2px}ul.lasso-component--controls li:hover{cursor:pointer;background:#39424a}ul.lasso-component--controls li:active{-webkit-box-shadow:inset 0 0 6px -2px rgba(0,0,0,.66);box-shadow:inset 0 0 6px -2px rgba(0,0,0,.66)}ul.lasso-component--controls li:last-child{border-right:0}ul.lasso-component--controls li:last-child:hover{border-top-right-radius:2px;border-bottom-right-radius:2px}ul.lasso-component--controls li.lasso-drag{cursor:move}ul.lasso-component--controls li.lasso-drag:hover{cursor:move}ul.lasso-component--controls li.lasso-drag:before{content:'\e600'}ul.lasso-component--controls li.lasso-settings:before{content:'\e994'}ul.lasso-component--controls li.lasso-clone:before{content:'\e92c'}ul.lasso-component--controls li.lasso-delete:before{content:'\e9ad'}.lasso-editing .aesop-component:hover .lasso-component--controls,.lasso-editing .wp-block-cover:hover .lasso-component--controls{left:4px;opacity:1;filter:alpha(opacity=100)}.aesop-timeline-stop .lasso-component--controls li{line-height:16px}.aesop-image-component[data-align=right]:hover .lasso-component--controls,.aesop-image-component[data-align=left]:hover .lasso-component--controls{margin:13px 0 0 4px}.aesop-image-component[data-align=right]:hover .lasso-component--controls{left:auto}.lasso-component{position:relative}.editus_shortcode_p{position:relative}.editus_shortcode{color:#e2e2e2;border:1px solid #181b1f;background-image:-webkit-linear-gradient(top,#353c44 0,#23282d 100%);background-image:-o-linear-gradient(top,#353c44 0,#23282d 100%);background-image:linear-gradient(to bottom,#353c44 0,#23282d 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff353c44', endColorstr='#ff23282d', GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-transition:opacity .4s ease;-moz-transition:opacity .4s ease;transition:opacity .4s ease;margin:auto;text-align:center;width:200px;z-index:105;position:absolute;left:0;right:0;top:0;opacity:.5;border-radius:4px}.editus_shortcode_p:hover .editus_shortcode{opacity:1}@media (max-width:768){.editus_shortcode_p .editus_shortcode{opacity:1}}#lasso--component__settings form{margin:0;position:relative;padding-bottom:70px}#lasso--component__settings label,#lasso--component__settings .lasso-option-desc{display:block;line-height:1.3}#lasso--component__settings h3,#lasso--component__settings label{font-weight:700;margin-bottom:3px;font-size:14px}#lasso--component__settings .lasso-option-desc{margin-bottom:5px;font-size:11.25px}#lasso--component__settings input[type=text],#lasso--component__settings input[type=text_small],#lasso--component__settings input[type=media_upload],#lasso--component__settings textarea,#lasso--component__settings select{background:#f8f8f8;width:100%;height:30px;border:1px solid #181b1f;border-radius:4px;line-height:1.8;padding:0 6px;color:#444;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);font-size:14px}#lasso--component__settings input[type=text]:focus,#lasso--component__settings input[type=text_small]:focus,#lasso--component__settings input[type=media_upload]:focus,#lasso--component__settings textarea:focus,#lasso--component__settings select:focus{box-shadow:none;outline:0;border:1px solid #007aab}#lasso--component__settings input[type=color]{border-radius:3px;border:1px solid #181b1f;padding:0 2px;height:30px;display:block}#lasso--component__settings input[type=color]:active,#lasso--component__settings input[type=color]:focus{box-shadow:none;outline:0;border:1px solid #007aab}#lasso--component__settings select{height:30px;box-shadow:none}#lasso--component__settings textarea{overflow:auto;margin:0;line-height:1.15;padding:6px;height:auto}#lasso--component__settings input[type=media_upload]{height:30px}#lasso--component__settings input[type=submit],#lasso--component__settings .lasso-generator-cancel{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:0;display:inline-block;font-family:Arial;color:#fff;font-size:17px;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none;font-size:15px}#lasso--component__settings input[type=submit]:active,#lasso--component__settings .lasso-generator-cancel:active,#lasso--component__settings input[type=submit]:focus,#lasso--component__settings .lasso-generator-cancel:focus{outline:0}#lasso--component__settings input[type=submit]:hover,#lasso--component__settings .lasso-generator-cancel:hover{text-decoration:none;color:#fff;background:#005678}#lasso--component__settings input[type=submit]:active,#lasso--component__settings .lasso-generator-cancel:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--component__settings .lasso-option-button{position:absolute;bottom:21px;right:21px;background-color:#4b5661;border-color:#2c3238;-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.25);box-shadow:0 1px 1px rgba(0,0,0,.25)}#lasso--component__settings .lasso-option-button:hover{text-decoration:none;background:#3e474f}#lasso--component__settings .lasso-option-button:active,#lasso--component__settings .lasso-option-button:focus{outline:0;text-decoration:none;border-color:#21252a;background:#353c44;transition:none;-webkit-box-shadow:inset 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px rgba(0,0,0,.4)}#lasso--component__settings #lasso-upload-img{height:28px;padding:8px;border-top-right-radius:3px;border-bottom-right-radius:3px;font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#lasso--component__settings #lasso-upload-img:before{content:'\e9c6';position:relative;color:#f8f8f8}#lasso--component__settings .lasso-generator-cancel{background:0 0;color:#d9534f;position:relative;top:-1px}#lasso--component__settings .lasso-generator-cancel:hover{color:#db5b57;background:0 0;text-decoration:none}#lasso--component__settings .lasso-generator-cancel:active{color:#d74b47;box-shadow:none}.lasso-option{position:relative;border-bottom:1px solid #181b1f;margin:0;padding:15px 20px 20px;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.05);box-shadow:0 1px 1px rgba(255,255,255,.05);-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease}.lasso-option:before,.lasso-option:after{content:" ";display:table}.lasso-option:after{clear:both}.lasso-option:hover{background:rgba(53,60,68,.5)}.lasso-buttoninsert-wrap{display:none;margin:0 auto;position:fixed;text-align:right;padding:20px;bottom:0;width:281px;height:70px;background:#353c44;right:-289px;z-index:1;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:right .25s ease;-moz-transition:right .25s ease;transition:right .25s ease;-webkit-box-shadow:0 -10px 10px -10px #000;box-shadow:0 -10px 10px -10px #000}.lasso-buttoninsert-wrap:before,.lasso-buttoninsert-wrap:after{content:" ";display:table}.lasso-buttoninsert-wrap:after{clear:both}#lasso-generator-insert{text-align:center;float:right;display:block;margin:0 15px;padding:6px 10px;border-radius:2px;background:#007aab;border:1px solid #006892;color:#fff}#lasso-generator-insert:hover{text-decoration:none;background:#005678}#lasso-generator-insert:active,#lasso-generator-insert:focus{text-decoration:none;outline:0}#lasso-generator-insert:active{background:#00435e;-webkit-box-shadow:inset 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px rgba(0,0,0,.4)}#lasso-generator-insert.saved{background:#4da34d}.lasso-c-comp-text{position:absolute;right:-10000px;opacity:0;filter:alpha(opacity=0);height:0}#lasso--gallery__images{min-height:65px;position:relative}#lasso--gallery__images .lasso-icon-spinner6{position:relative;left:135px;top:18px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;font-size:16px}.editor-btn-secondary{background:#32373c;border:1px solid #181b1f;color:#e2e2e2;font-size:17px;line-height:1.8;padding:2px 12px 1px;text-decoration:none;display:inline-block;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.editor-btn-secondary:active,.editor-btn-secondary:visited{color:#e2e2e2}.editor-btn-secondary:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}.editor-btn-secondary:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.editor-btn-secondary.lasso--btn-loading:before{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}#ase-gallery-images{margin:0 -7px;border-radius:4px;padding:2px;-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease}#ase-gallery-images:before,#ase-gallery-images:after{content:" ";display:table}#ase-gallery-images:after{clear:both}#ase-gallery-images .ui-state-highlight{height:1.5em;line-height:1.2em}.ase-gallery-image{position:relative;float:left;margin:4px;-webkit-transition:transform .1s ease;-moz-transition:transform .1s ease;transition:transform .1s ease;list-style:none}.ase-gallery-image i{top:3px;position:absolute;z-index:1;color:#fff;font-size:16px;text-shadow:0 1px 1px rgba(0,0,0,.5);opacity:.6;filter:alpha(opacity=60);-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease}.ase-gallery-image i:hover{cursor:pointer;opacity:1;filter:alpha(opacity=100);-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}.ase-gallery-image i:active{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);box-shadow:none}.ase-gallery-image .dashicons-edit{left:3px}.ase-gallery-image .dashicons-no-alt{right:2px}.ase-gallery-image img{max-width:54px;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.ase-gallery-image.ui-sortable-helper{-ms-transform:rotate(7deg);-webkit-transform:rotate(7deg);transform:rotate(7deg)}.ase-gallery-image:hover{cursor:move}.ase-gallery-image:hover img{opacity:.66;filter:alpha(opacity=66)}.ase-gallery-opts--edit-gallery:hover #ase-gallery-images{background:#181b1f;-webkit-box-shadow:inset 0 -1px 1px rgba(255,255,255,.1);box-shadow:inset 0 -1px 1px rgba(255,255,255,.1)}.lasso-editor-tiny-btn{font-size:10px;background:#181b1f;color:rgba(226,226,226,.8);border-radius:100%;font-weight:400;height:18px;width:18px;line-height:20px;text-align:center;text-shadow:1px 1px rgba(0,0,0,.1)}.lasso-editor-tiny-btn:focus,.lasso-editor-tiny-btn:active,.lasso-editor-tiny-btn:hover{outline:0;color:rgba(226,226,226,.8);text-decoration:none}.lasso-editor-tiny-btn:hover{color:rgba(226,226,226,.8);background:rgba(0,122,171,.8)}.lasso-editor-tiny-btn:active{color:rgba(226,226,226,.8);background:#007aab}#ase-gallery-add-image{position:absolute;right:12px;font-size:9px}.ase-gallery-drop-zone{border:1px solid #23282d;background:#353c44;color:#363636;width:54px;height:54px;float:left;margin:4px;border-radius:2px}#lasso--component__settings .ase-gallery-layout-label{font-size:12px}.ase-gallery-opts--type{position:relative}.ase-gallery-opts--type h3{margin:0}.ase-gallery-opts--type input[type=radio]{position:absolute;opacity:0;z-index:-1}.ase-gallery-opts--type .ase-gallery-layout-label{position:relative;float:left;height:68px;width:78px;overflow:hidden;text-align:center;background:#353c44;padding:5px;box-sizing:border-box;border:1px solid #181b1f;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease;opacity:.3;filter:alpha(opacity=30);margin-right:2px;font-weight:400}.ase-gallery-opts--type .ase-gallery-layout-label:last-of-type{margin-right:0!important}.ase-gallery-opts--type .ase-gallery-layout-label:after{content:'';background-image:url(../img/layout-sprite.png);background-size:84%;position:absolute;height:42px;display:block;left:0;right:0;bottom:0}.ase-gallery-opts--type .ase-gallery-layout-label:hover{opacity:1;filter:alpha(opacity=100);cursor:pointer}.ase-gallery-opts--type .ase-gallery-layout-label:active{background:#2c3238;-webkit-box-shadow:inset 0 0 6px -1px rgba(0,0,0,.5);box-shadow:inset 0 0 6px -1px rgba(0,0,0,.5)}.ase-gallery-opts--type .selected{-webkit-box-shadow:inset 0 0 12px -2px rgba(0,0,0,.5);box-shadow:inset 0 0 12px -2px rgba(0,0,0,.5);opacity:1;filter:alpha(opacity=100)}.ase-gallery-opts--type label:first-of-type:after{background-position:5px -9px}.ase-gallery-opts--type label:nth-of-type(2):after{background-position:5px -52px}.ase-gallery-opts--type label:nth-of-type(3):after{background-position:5px -99px}.ase-gallery-opts--type label:nth-of-type(4):after{background-position:5px -145px}.ase-gallery-opts--type label:nth-of-type(5):after{background-position:5px -191px}.ase-gallery-opts--type label:last-of-type:after{background-position:5px -235px}.ase-gallery-opts{-webkit-transition:opacity .25s ease;-moz-transition:opacity .25s ease;transition:opacity .25s ease}.lasso--empty-component{height:0;opacity:0;filter:alpha(opacity=0);text-align:center;color:#444;font-family:Arial;font-size:20px;-webkit-transition:all .2s linear;-moz-transition:all .2s linear;transition:all .2s linear}.lasso--empty-component span{position:relative;top:2px}.lasso-editing .lasso--empty-component+.aesop-map-component .lasso-component--controls,.lasso-editing .aesop-gallery-component.empty-gallery .lasso-component--controls{opacity:1;filter:alpha(opacity=100);left:0}.lasso-editing .lasso--empty-component{height:150px;padding-top:75px;opacity:1;filter:alpha(opacity=100)}#lasso--component__settings.gallery-no-images .ase-gallery-opts:not(.ase-gallery-opts--create-gallery){display:none}#lasso--component-settings-form.creating-gallery .lasso-option.lasso-gallery-id{display:none}#lasso--component-settings-form.has-galleries .ase-gallery-opts--create-gallery{display:none}#lasso--component-settings-form.hide-all-fields .ase-gallery-opts{opacity:0;filter:alpha(opacity=0)}#lasso--map-form{position:relative}#lasso--map-form .lasso--map-form__submit{position:absolute;top:10px;right:10px;z-index:1000;background:#007aab;border:1px solid #0073a1;padding:8px 12px;font-size:14px;line-height:1.2;font-family:Arial;text-shadow:1px 1px rgba(0,0,0,.1);-webkit-box-shadow:0 0 5px -1px rgba(0,0,0,.4);box-shadow:0 0 5px -1px rgba(0,0,0,.4)}#lasso--map-form .lasso--map-form__submit:active,#lasso--map-form .lasso--map-form__submit:focus{outline:0}#lasso--map-form .lasso--map-form__submit:hover{background:#005678;border:1px solid #004e6e}#lasso--map-form .lasso--map-form__submit:active{box-shadow:none}#lasso--map-form{margin-top:10px}#lasso--map-form .leaflet-popup-content-wrapper,#lasso--map-form .leaflet-popup-tip{border-radius:4px}#lasso--map-form .leaflet-popup-content-wrapper input,#lasso--map-form .leaflet-popup-tip input{font-size:14px;border-radius:0;padding:3px 5px;width:200px;display:inline-block;line-height:1}#lasso--map-form .leaflet-popup-content{margin:10px}#lasso--map-form .leaflet-popup-close-button{position:absolute;left:-10000px;height:0}#lasso--map-form .marker-update-button,#lasso--map-form .marker-delete-button{border-radius:0;color:#fff;box-shadow:none;border:0;border-radius:3px;display:inline-block;height:25px;width:25px;vertical-align:top;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;text-align:center}#lasso--map-form .marker-update-button:hover,#lasso--map-form .marker-delete-button:hover{cursor:pointer}#lasso--map-form .marker-update-button:active,#lasso--map-form .marker-delete-button:active{outline:0;focus:none;box-shadow:none}#lasso--map-form .marker-update-button:before,#lasso--map-form .marker-delete-button:before{position:relative;text-align:center}#lasso--map-form .marker-update-button{background:#007aab}#lasso--map-form .marker-update-button:hover{background:#00648c}#lasso--map-form .marker-update-button:active{background:#005678}#lasso--map-form .marker-update-button:before{top:1px;left:-1px;font-size:24px}#lasso--map-form .marker-delete-button{background:#d9534f}#lasso--map-form .marker-delete-button:hover{background:#d43a36}#lasso--map-form .marker-delete-button:active{background:#c9302c}#lasso--map-form .marker-delete-button:before{font-size:17px;top:1px;left:1px}.aesop-map-component .lasso-component--controls{width:91px;z-index:9999}.aesop-map-component .lasso-component--controls .lasso-clone{display:none}.aesop-sticky-map #lasso--map-form .lasso-component--controls{position:fixed;z-index:9999;width:61px}.aesop-sticky-map #lasso--map-form .lasso-component--controls .lasso-drag{display:none}.aesop-sticky-map.aesop-sticky-map-left #lasso--map-form .lasso-component--controls{left:183px;right:auto}.aesop-sticky-map.aesop-sticky-map-right #lasso--map-form .lasso-component--controls{right:183px;left:auto}#lasso--featImgControls{position:relative;z-index:1;left:0;right:0;text-align:center;top:5px;width:30px;height:26px;padding:0;margin:0 auto;font-size:15px;border-radius:2px;line-height:0;background-image:-webkit-linear-gradient(top,#353c44 0,#23282d 100%);background-image:-o-linear-gradient(top,#353c44 0,#23282d 100%);background-image:linear-gradient(to bottom,#353c44 0,#23282d 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff353c44', endColorstr='#ff23282d', GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}#lasso--featImgControls.lasso--featImg--has-thumb{width:60px;padding:0}#lasso--featImgControls.lasso--featImg--has-thumb #lasso--featImgDelete{opacity:1;filter:alpha(opacity=100)}#lasso--featImgControls li{float:left;list-style-type:none;line-height:0;margin-left:0;width:30px;height:26px;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,.4)}#lasso--featImgControls li i{font-style:normal;position:relative;top:5px}#lasso--featImgControls li:before{position:relative;top:3px;font-size:15px}#lasso--featImgControls li:hover{cursor:pointer;background:#39424a}#lasso--featImgControls li:active{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.4);box-shadow:inset 0 1px 1px rgba(0,0,0,.4)}#lasso--featImgControls .lasso--featImg--controlHidden{position:absolute;left:-1000px;height:0;opacity:0;filter:alpha(opacity=0)}#lasso--featImgControls #lasso--featImgSave{position:absolute;left:-1000px;height:0;opacity:0;filter:alpha(opacity=0)}#lasso--featImgControls #lasso--featImgDelete{opacity:0;filter:alpha(opacity=0)}#lasso--featImgControls a{color:#fff;display:block}#lasso--featImgControls a:hover{text-decoration:none}.lasso--wpquote,.lasso--wpimg__wrap{position:relative}.lasso--wpquote:hover{opacity:1;filter:alpha(opacity=100);left:0}.lasso--wpimg__wrap:hover .lasso-component--controls,.lasso-component:hover .lasso-component--controls,.wp-block-image:hover .lasso-component--controls{opacity:1;filter:alpha(opacity=100)}.wp-block-image:hover .lasso-component--controls{position:relative}.lasso--wpquote .lasso-component--controls #lasso-component--settings__trigger{position:absolute;left:-10000px;height:0;opacity:0;filter:alpha(opacity=0);display:none}.sweet-overlay{background-color:rgba(0,0,0,.4);position:fixed;left:0;right:0;top:0;bottom:0;display:none;z-index:1000}.sweet-alert{background-color:#1f2327;font-family:Arial;width:478px;padding:17px;border-radius:5px;text-align:center;position:fixed;left:50%;top:50%;margin-left:-256px;margin-top:-200px;overflow:hidden;display:none;z-index:100002;-webkit-box-shadow:0 0 10px 1px rgba(0,0,0,.5);box-shadow:0 0 10px 1px rgba(0,0,0,.5)}@media all and (max-width:540px){.sweet-alert{width:auto;margin-left:0;margin-right:0;left:15px;right:15px}}.sweet-alert h2{color:#e2e2e2;font-size:30px;text-align:center;font-weight:600;text-transform:none;position:relative;margin:25px 0;padding:0;line-height:40px;display:block;font-family:inherit}.sweet-alert p{color:#e2e2e2;font-size:16px;text-align:center;font-weight:300;position:relative;text-align:inherit;float:none;margin:0;padding:0;line-height:normal}.sweet-alert p~button{margin-bottom:20px}.sweet-alert button{background-color:#007aab;color:#fff;border:0;box-shadow:none;font-size:17px;font-family:Arial;font-weight:500;border-radius:5px;padding:10px 32px;margin:26px 5px 0;cursor:pointer}.sweet-alert button:focus{outline:0;box-shadow:0 0 2px rgba(128,179,235,.5),inset 0 0 0 1px rgba(0,0,0,.05)}.sweet-alert button:hover{background-color:#a1d9f2}.sweet-alert button:active{background-color:#81ccee}.sweet-alert button.cancel{background:0 0;color:#d9534f}.sweet-alert button.cancel:hover{background:0 0}.sweet-alert button.cancel:active{background:0 0}.sweet-alert button.cancel:focus{box-shadow:rgba(197,205,211,.8) 0 0 2px,rgba(0,0,0,.0470588) 0 0 0 1px inset!important}.sweet-alert button::-moz-focus-inner{border:0}.sweet-alert .icon{width:80px;height:80px;border:4px solid gray;border-radius:50%;margin:20px auto;padding:0;position:relative;box-sizing:content-box}.sweet-alert .icon.error{border-color:#d9534f}.sweet-alert .icon.error .x-mark{position:relative;display:block}.sweet-alert .icon.error .line{position:absolute;height:5px;width:47px;background-color:#d9534f;display:block;top:37px;border-radius:2px}.sweet-alert .icon.error .line.left{-webkit-transform:rotate(45deg);transform:rotate(45deg);left:17px}.sweet-alert .icon.error .line.right{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);right:16px}.sweet-alert .icon.warning{border-color:#d9534f}.sweet-alert .icon.warning .body{position:absolute;width:5px;height:47px;left:50%;top:10px;border-radius:2px;margin-left:-2px;background-color:#d9534f}.sweet-alert .icon.warning .dot{position:absolute;width:7px;height:7px;border-radius:50%;margin-left:-3px;left:50%;bottom:10px;background-color:#d9534f}.sweet-alert .icon.info{border-color:#007aab}.sweet-alert .icon.info::before{content:"";position:absolute;width:5px;height:29px;left:50%;bottom:17px;border-radius:2px;margin-left:-2px;background-color:#007aab}.sweet-alert .icon.info::after{content:"";position:absolute;width:7px;height:7px;border-radius:50%;margin-left:-3px;top:19px;background-color:#007aab}.sweet-alert .icon.success{border-color:#A5DC86}.sweet-alert .icon.success::before,.sweet-alert .icon.success::after{content:'';border-radius:50%;position:absolute;width:60px;height:120px;background:#fff;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.sweet-alert .icon.success::before{border-radius:120px 0 0 120px;top:-7px;left:-33px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:60px 60px;transform-origin:60px 60px}.sweet-alert .icon.success::after{border-radius:0 120px 120px 0;top:-11px;left:30px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:0 60px;transform-origin:0 60px}.sweet-alert .icon.success .placeholder{width:80px;height:80px;border:4px solid rgba(165,220,134,.2);border-radius:50%;box-sizing:content-box;position:absolute;left:-4px;top:-4px;z-index:2}.sweet-alert .icon.success .fix{width:5px;height:90px;background-color:#fff;position:absolute;left:28px;top:8px;z-index:1;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .icon.success .line{height:5px;background-color:#A5DC86;display:block;border-radius:2px;position:absolute;z-index:2}.sweet-alert .icon.success .line.tip{width:25px;left:14px;top:46px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.sweet-alert .icon.success .line.long{width:47px;right:8px;top:38px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .icon.custom{background-size:contain;border-radius:0;border:0;background-position:center center;background-repeat:no-repeat}.sweet-alert #shortcode_edit{width:100%;height:200px;color:#000;font-size:small;font-family:"Lucida Console","Courier New",monospace}.sweet-alert[data-has-cancel-button=false] button{box-shadow:none!important}@-webkit-keyframes showSweetAlert{0%{transform:scale(0.7);-webkit-transform:scale(0.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-moz-keyframes showSweetAlert{0%{transform:scale(0.7);-webkit-transform:scale(0.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes showSweetAlert{0%{transform:scale(0.7);-webkit-transform:scale(0.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-webkit-keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(0.5);-webkit-transform:scale(0.5)}}@-moz-keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(0.5);-webkit-transform:scale(0.5)}}@keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(0.5);-webkit-transform:scale(0.5)}}.showSweetAlert{-webkit-animation:showSweetAlert .2s;-moz-animation:showSweetAlert .2s;animation:showSweetAlert .2s}.hideSweetAlert{-webkit-animation:hideSweetAlert .2s;-moz-animation:hideSweetAlert .2s;animation:hideSweetAlert .2s}.animateSuccessTip{-webkit-animation:animateSuccessTip .75s;-moz-animation:animateSuccessTip .75s;animation:animateSuccessTip .75s}.animateSuccessLong{-webkit-animation:animateSuccessLong .75s;-moz-animation:animateSuccessLong .75s;animation:animateSuccessLong .75s}.icon.success.animate::after{-webkit-animation:rotatePlaceholder 4.25s ease-in;-moz-animation:rotatePlaceholder 4.25s ease-in;animation:rotatePlaceholder 4.25s ease-in}.lasso-util--help{position:relative;cursor:pointer;color:#007aab;display:inline-block;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease;opacity:.75;filter:alpha(opacity=75)}.lasso-util--help:hover{text-decoration:none;opacity:1;filter:alpha(opacity=100)}.lasso-util--help:before,.lasso-util--help:after{position:absolute;visibility:hidden;opacity:0;filter:alpha(opacity=0);-webkit-transition:opacity .2s ease-in-out,visibility .2s ease-in-out,-webkit-transform .2s cubic-bezier(0.71,1.7,.77,1.24);-moz-transition:opacity .2s ease-in-out,visibility .2s ease-in-out,-moz-transform .2s cubic-bezier(0.71,1.7,.77,1.24);transition:opacity .2s ease-in-out,visibility .2s ease-in-out,transform .2s cubic-bezier(0.71,1.7,.77,1.24);-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translate3d(0,0,0);pointer-events:none}.lasso-util--help:hover:before,.lasso-util--help:hover:after,.lasso-util--help:focus:before,.lasso-util--help:focus:after{visibility:visible;opacity:1;filter:alpha(opacity=100)}.lasso-util--help:before{z-index:10001;border:6px solid transparent;background:0 0;content:""}.lasso-util--help:after{z-index:1000;padding:8px;width:160px;background-color:rgba(0,122,171,.95);color:#e2e2e2;font-family:Arial;content:attr(data-tooltip);font-size:12px;line-height:1.2;border-radius:2px}.lasso-util--help:before,.lasso-util--help:after,.lasso-util--help-top:before,.lasso-util--help-top:after{bottom:100%;left:50%}.lasso-util--help:before,.lasso-util--help-top:before{margin-left:-6px;margin-bottom:-12px;border-top-color:rgba(0,122,171,.95)}.lasso-util--help:after,.lasso-util--help-top:after{margin-left:-80px}.lasso-util--help:hover:before,.lasso-util--help:hover:after,.lasso-util--help:focus:before,.lasso-util--help:focus:after,.lasso-util--help-top:hover:before,.lasso-util--help-top:hover:after,.lasso-util--help-top:focus:before,.lasso-util--help-top:focus:after{-webkit-transform:translateY(-12px);-moz-transform:translateY(-12px);transform:translateY(-12px)}.lasso-util--help-left:before,.lasso-util--help-left:after{right:100%;bottom:50%;left:auto}.lasso-util--help-left:before{margin-left:0;margin-right:-12px;margin-bottom:0;border-top-color:transparent;border-left-color:rgba(0,122,171,.95)}.lasso-util--help-left:hover:before,.lasso-util--help-left:hover:after,.lasso-util--help-left:focus:before,.lasso-util--help-left:focus:after{-webkit-transform:translateX(-12px);-moz-transform:translateX(-12px);transform:translateX(-12px)}.lasso-util--help-bottom:before,.lasso-util--help-bottom:after{top:100%;bottom:auto;left:50%}.lasso-util--help-bottom:before{margin-top:-12px;margin-bottom:0;border-top-color:transparent;border-bottom-color:rgba(0,122,171,.95)}.lasso-util--help-bottom:hover:before,.lasso-util--help-bottom:hover:after,.lasso-util--help-bottom:focus:before,.lasso-util--help-bottom:focus:after{-webkit-transform:translateY(12px);-moz-transform:translateY(12px);transform:translateY(12px)}.lasso-util--help-right:before,.lasso-util--help-right:after{bottom:50%;left:100%}.lasso-util--help-right:before{margin-bottom:0;margin-left:-12px;border-top-color:transparent;border-right-color:rgba(0,122,171,.95)}.lasso-util--help-right:hover:before,.lasso-util--help-right:hover:after,.lasso-util--help-right:focus:before,.lasso-util--help-right:focus:after{-webkit-transform:translateX(12px);-moz-transform:translateX(12px);transform:translateX(12px)}.lasso-util--help-left:before,.lasso-util--help-right:before{top:3px}.lasso-util--help-left:after,.lasso-util--help-right:after{margin-left:0;margin-bottom:-16px}.story-tags-option .tagit,.story-categories-option .tagit,.story-custom-taxonomy-option .tagit{padding:4px 0 0;overflow:auto;margin-left:inherit;margin-right:inherit;border-radius:3px;list-style:none}.story-tags-option .tagit li,.story-categories-option .tagit li,.story-custom-taxonomy-option .tagit li{float:left}.story-tags-option .tagit li.tagit-choice,.story-categories-option .tagit li.tagit-choice,.story-custom-taxonomy-option .tagit li.tagit-choice{position:relative;margin:2px;display:inline;padding:4px 8px 4px 18px;font-family:Arial;font-size:12px;line-height:16px;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:2px;background:rgba(50,55,60,.75)}.story-tags-option .tagit li .tagit-close,.story-categories-option .tagit li .tagit-close,.story-custom-taxonomy-option .tagit li .tagit-close{cursor:pointer;position:absolute;left:7px;color:#fff;top:5px}.story-tags-option .tagit li .tagit-close:hover,.story-categories-option .tagit li .tagit-close:hover,.story-custom-taxonomy-option .tagit li .tagit-close:hover{text-decoration:none;color:#fff}.story-tags-option .tagit li.tagit-new,.story-categories-option .tagit li.tagit-new,.story-custom-taxonomy-option .tagit li.tagit-new{position:relative;top:-6px}.story-tags-option .tagit li input[type=text],.story-categories-option .tagit li input[type=text],.story-custom-taxonomy-option .tagit li input[type=text]{box-shadow:none;border:0;border-radius:0;margin:0;padding:0 0 0 4px;width:inherit;background-color:#fff!important;color:#000!important;outline:0;font-size:12px;line-height:24px;display:inline-block;margin:2px 5px 2px 0;color:rgba(255,255,255,.5)}.story-tags-option input.tagit-hidden-field,.story-categories-option input.tagit-hidden-field,.story-custom-taxonomy-option input.tagit-hidden-field{display:none}.story-tags-option ul.tagit li.tagit-choice a.tagit-label,.story-categories-option ul.tagit li.tagit-choice a.tagit-label,.story-custom-taxonomy-option ul.tagit li.tagit-choice a.tagit-label{cursor:pointer;text-decoration:none}.story-categories-option{border-bottom:0;box-shadow:none;margin-bottom:0}.story-tags-option .tagit li.tagit-choice{position:relative;margin:2px 2px 2px 15px;padding:4px 8px 4px 12px;border-top-left-radius:0;border-bottom-left-radius:0}.story-tags-option .tagit li.tagit-choice:before{content:'';position:absolute;width:0;height:0;border-top:12px solid transparent;border-bottom:12px solid transparent;border-right:14px solid #32373c;left:-14px;top:0}.story-tags-option .tagit li.tagit-choice .tagit-close{left:0}.lasso-modal-open .ui-autocomplete{position:absolute;top:100%;left:0;z-index:100002;float:left;display:none;min-width:160px;padding:4px;margin:2px 0 0;list-style:none;color:#fff;background-color:#32373c;border-radius:3px;box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.lasso-modal-open .ui-autocomplete .ui-menu-item{display:block;padding:1px 2px;clear:both;font-weight:400;line-height:18px;white-space:nowrap;font-family:Arial;font-size:14px;background-color:#23282d}.lasso-modal-open .ui-autocomplete .ui-menu-item a{background-color:#23282d;color:#fff}.lasso-modal-open .ui-autocomplete .ui-menu-item:hover,.lasso-modal-open .ui-autocomplete .ui-menu-item.ui-state-active{cursor:pointer}.lasso-modal-open .ui-autocomplete.tagit-autocomplete{overflow-y:scroll;max-height:310px}.lasso--tour__modal .lasso--postsettings__footer:before,.lasso--tour__modal .lasso--postsettings__footer:after{content:" ";display:table}.lasso--tour__modal .lasso--postsettings__footer:after{clear:both}.lasso--tour__modal .lasso--modal__inner{position:relative}.lasso--tour__modal .lasso--postsettings__option{border-bottom:0;box-shadow:none;padding-bottom:0;margin-bottom:0;float:left;top:4px;position:relative;opacity:.85;filter:alpha(opacity=85)}.lasso--tour__modal .lasso--postsettings__option label{padding-left:23px;font-size:14px;font-weight:400;color:#fff}.lasso--tour__modal .lasso--postsettings__option .control-indicator{width:14px;height:14px;top:0}.lasso--tour__modal #lasso--tour__slides{position:relative;overflow:auto;display:none}.lasso--tour__modal ul{margin:0;padding:0;list-style:none}.lasso--tour__modal ul:before,.lasso--tour__modal ul:after{content:" ";display:table}.lasso--tour__modal ul:after{clear:both}.lasso--tour__modal ul li{float:left}.lasso--tour__modal li img{background:#0d0e10;padding:6px;border-radius:3px;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.1);box-shadow:0 1px 1px rgba(255,255,255,.1)}.lasso--tour__modal li p{font-family:Arial;font-size:16px;line-height:1.25;margin:15px auto 28px;padding-right:4px;padding-left:4px}.lasso--tour__modal .dots{position:absolute;left:0;right:0;bottom:-10px;text-align:center;width:100%;margin:0;height:30px}.lasso--tour__modal .dots li{display:inline-block;width:14px;height:14px;line-height:16px;margin:0 3px;text-indent:-999em;border:1px solid #0d0e10;background:rgba(0,122,171,.75);border-radius:100%;cursor:pointer;opacity:.4;filter:alpha(opacity=40);-webkit-transition:background .5s,opacity .5s;-moz-transition:background .5s,opacity .5s;transition:background .5s,opacity .5s;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.1);box-shadow:0 1px 1px rgba(255,255,255,.1)}.lasso--tour__modal .dots li.active{background:#fff;opacity:1}.lasso--tour__modal input[type=submit]{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:0;display:inline-block;font-family:Arial;color:#fff;font-size:17px;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none}.lasso--tour__modal input[type=submit]:active,.lasso--tour__modal input[type=submit]:focus{outline:0}.lasso--tour__modal input[type=submit]:hover{text-decoration:none;color:#fff;background:#005678}.lasso--tour__modal input[type=submit]:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--loading{height:auto;left:0;top:0;right:0;width:100%}.lasso--loader{height:40px;width:40px;margin:10px auto;top:48%;position:relative;-webkit-animation:rotation .6s infinite linear;-moz-animation:rotation .6s infinite linear;-o-animation:rotation .6s infinite linear;animation:rotation .6s infinite linear;border-left:3px solid rgba(96,106,116,.2);border-right:3px solid rgba(96,106,116,.2);border-bottom:3px solid rgba(96,106,116,.2);border-top:3px solid #606a74;border-radius:100%}@-webkit-keyframes rotation{from{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes rotation{from{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@-o-keyframes rotation{from{-o-transform:rotate(0deg)}to{-o-transform:rotate(359deg)}}@keyframes rotation{from{transform:rotate(0deg)}to{transform:rotate(359deg)}}.lasso--modal{top:10vh}.lasso--modal.lasso--modal__full{width:100%;max-width:800px}.lasso--modal.lasso--modal__full .lasso--modal__inner{display:block;padding:36px}.lasso--modal.lasso--modal__full .lasso--modal__inner:before,.lasso--modal.lasso--modal__full .lasso--modal__inner:after{content:" ";display:table}.lasso--modal.lasso--modal__full .lasso--modal__inner:after{clear:both}#lasso--all-posts__modal #lasso--loading{position:absolute;height:90%}ul.lasso--post-object-list,ul.lasso--post-list{text-align:left;list-style:none;margin:0;padding:0}ul.lasso--post-object-list li,ul.lasso--post-list li{display:block;position:relative;width:100%;list-style-type:none;margin-bottom:7px;font-size:14px;font-family:Arial;font-weight:700}ul.lasso--post-object-list{width:100px;float:left;height:100%}ul.lasso--post-object-list li{line-height:25px;margin-bottom:0;font-family:Arial;font-weight:400;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}ul.lasso--post-object-list li:not(.active){opacity:.45;filter:alpha(opacity=45)}ul.lasso--post-object-list li:hover{cursor:pointer;opacity:1;filter:alpha(opacity=100)}.lasso--post-filtering{padding:0 18px;width:calc(100% - 100px);height:42px;float:right}.lasso--post-filtering:before,.lasso--post-filtering:after{content:" ";display:table}.lasso--post-filtering:after{clear:both}.lasso--post-filtering .lasso--search__results,.lasso--post-filtering .lasso--search{float:left}.lasso--post-filtering .lasso--search__results{opacity:0;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;transition:opacity .2s ease;width:60%;font-size:15px}.lasso--post-filtering .lasso--search__results span{font-weight:700;margin-right:4px}.lasso--post-filtering .lasso--search{width:40%;overflow:hidden;position:relative}.lasso--post-filtering .lasso--search #lasso--search__toggle,.lasso--post-filtering .lasso--search input{-webkit-transition:right .15s linear;-moz-transition:right .15s linear;transition:right .15s linear}.lasso--post-filtering .lasso--search #lasso--search__toggle{position:relative;top:7.5px;right:-209px}.lasso--post-filtering .lasso--search #lasso--search__toggle:before{opacity:.5;filter:alpha(opacity=50);-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.lasso--post-filtering .lasso--search #lasso--search__toggle:hover{cursor:pointer}.lasso--post-filtering .lasso--search #lasso--search__toggle:hover:before{opacity:.9;filter:alpha(opacity=90)}.lasso--post-filtering .lasso--search input{float:right;width:194px;right:-194px;background-color:#f8f8f8!important;padding:2px 8px;background:#f8f8f8;border:1px solid #181b1f;color:#444;font-size:14px;z-index:0;position:relative;padding-left:6px;height:36px;border-radius:4px;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);height:32px}.lasso--post-filtering .lasso--search input:focus{outline:0;border:1px solid #007aab;border-radius:2px}.lasso--post-filtering .lasso--search input:focus{box-shadow:none}.lasso--post-filtering .lasso--search.lasso--search__visible #lasso--search__toggle{right:-15px}.lasso--post-filtering .lasso--search.lasso--search__visible #lasso--search__toggle:before{opacity:.9;filter:alpha(opacity=90)}.lasso--post-filtering .lasso--search.lasso--search__visible #lasso--search__toggle:hover:before{opacity:.5;filter:alpha(opacity=50)}.lasso--post-filtering .lasso--search.lasso--search__visible input{right:0}#lasso--helper{position:absolute;right:4px;top:4px;font-size:12px;padding:2px 6px;background:#32373c;color:#fff;border-radius:2px;font-family:Arial}#lasso--clear-search{position:absolute;right:7px;top:7px;color:#c9c9c9;z-index:1}#lasso--clear-search:hover{color:#bcbcbc;cursor:pointer}.lasso--empty-state{max-width:200px;text-align:center;color:#737679;margin:0 auto;top:40%;position:relative}.lasso--empty-state .lasso--empty-state-icon{font-size:50px}.lasso--empty-state p{margin-bottom:0;font-family:Arial;font-size:90%;font-weight:700}.lasso--empty-state p+a{margin-top:10px}ul.lasso--post-list{float:left;padding:0 18px;width:calc(100% - 100px);overflow:hidden;position:relative;height:520px;border-left:1px solid #181b1f;-webkit-box-shadow:inset 1px 0 1px -1px rgba(255,255,255,.15);box-shadow:inset 1px 0 1px -1px rgba(255,255,255,.15)}ul.lasso--post-list li{overflow:hidden;line-height:50px}ul.lasso--post-list .lasso--post-list__item{color:#c9c9c9;display:block;padding:0 15px;background:rgba(50,55,60,.75);text-decoration:none;border-radius:4px;-webkit-transition:all .15s ease;-moz-transition:all .15s ease;transition:all .15s ease;font-family:Arial;font-weight:400;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ul.lasso--post-list .lasso--post-list__item:before{content:'';height:8px;width:8px;border-radius:100%;margin-right:8px;display:inline-block}ul.lasso--post-list .lasso--post-list__item.draft:before{background:#f0ad4e}ul.lasso--post-list .lasso--post-list__item.publish:before{background:#4da34d}ul.lasso--post-list .lasso--post-list__item.pending:before{background:#007aab}ul.lasso--post-list .lasso--post-list__item:hover{background:#32373c;text-decoration:none;width:calc(100% - 115px)}ul.lasso--post-list .lasso--post-list__item:hover .lasso--post-list__controls{right:0}ul.lasso--post-list .lasso--post-list__item:active{outline:0;background:#32373c;text-decoration:none;-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.5);box-shadow:inset 1px 1px 2px rgba(0,0,0,.5)}ul.lasso--post-list .lasso--post-list__item:focus{outline:0}ul.lasso--post-list .lasso--post-list__item.no-delete:hover{width:calc(100% - 57.5px)}.lasso--post-list__controls{position:absolute;right:0;top:0;width:115px;text-align:right;right:-115px;height:50px;-webkit-transition:right .15s ease;-moz-transition:right .15s ease;transition:right .15s ease}.lasso--post-list__controls span{color:#626262;display:inline-block;width:50px;height:50px;background:#32373c;border-radius:4px;position:relative}.lasso--post-list__controls span:after{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;font-size:18px;position:absolute;z-index:2;top:16px;left:16px}.lasso--post-list__controls span:hover{color:#626262;background:rgba(50,55,60,.5)}.lasso--post-list__controls span:active{background:#32373c;text-decoration:none;-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.5);box-shadow:inset 1px 1px 2px rgba(0,0,0,.5)}.lasso--post-list__controls #lasso--post__edit{margin-right:3px}.lasso--post-list__controls #lasso--post__edit:hover{color:#e2e2e2;background:#007aab}.lasso--post-list__controls #lasso--post__edit:after{content:'\e908'}.lasso--post-list__controls #lasso--post__delete:hover{color:#e2e2e2;background:#d9534f}.lasso--post-list__controls #lasso--post__delete:after{content:'\e9ad'}#lasso--load-more,#lasso--close-modal-posts{background:#32373c;border:1px solid #181b1f;color:#e2e2e2;font-size:17px;line-height:1.8;padding:2px 12px 1px;text-decoration:none;display:inline-block;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease;font-size:15px;text-transform:uppercase;line-height:2;margin-top:10px;opacity:.66;filter:alpha(opacity=66)}#lasso--load-more:active,#lasso--close-modal-posts:active,#lasso--load-more:visited,#lasso--close-modal-posts:visited{color:#e2e2e2}#lasso--load-more:hover,#lasso--close-modal-posts:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}#lasso--load-more:active,#lasso--close-modal-posts:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--load-more.lasso--btn-loading:before,#lasso--close-modal-posts.lasso--btn-loading:before{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}#lasso--load-more:active,#lasso--close-modal-posts:active,#lasso--load-more:visited,#lasso--close-modal-posts:visited{color:#e2e2e2}#lasso--load-more:hover,#lasso--close-modal-posts:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}#lasso--load-more:active,#lasso--close-modal-posts:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--load-more.lasso--btn-loading:before,#lasso--close-modal-posts.lasso--btn-loading:before{font-family:icomoon-editus;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}.editus-firstp:empty:before{content:attr(placeholder);color:grey;font-style:italic}#lasso--revision__modal{-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}#lasso--revision__modal .lasso--slider_wrap{padding:0 16px;margin-top:18px}#lasso--revision__modal .lasso--btn-group .lasso--btn-secondary{opacity:.7;filter:alpha(opacity=70);-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}#lasso--revision__modal .lasso--btn-group .lasso--btn-secondary:hover{opacity:1;filter:alpha(opacity=100)}#lasso--revision__modal .lasso-icon-move{position:absolute;top:15px;right:15px;color:#747474;font-size:14px}#lasso--revision__modal .lasso-icon-move:hover{cursor:move}#lasso--revision-list{margin:0;padding:0;list-style:none;text-align:center;margin-bottom:10px;width:110%;left:-5%;position:relative;top:-3px}#lasso--revision-list:before,#lasso--revision-list:after{content:" ";display:table}#lasso--revision-list:after{clear:both}#lasso--revision-list li{padding:12px 0 0;display:inline-block;font-family:Arial;font-size:11px;color:#c9c9c9;text-transform:uppercase;line-height:13px;margin:0 auto;position:relative}#lasso--revision-list li span{color:#c9c9c9}#lasso--revision-list li:first-child{margin-left:0}#lasso--revision-list li:last-child{margin-right:0}#lasso--revision-list li:before{content:'';height:5px;border-right:1px solid #747474;width:1px;position:absolute;top:0;left:0;right:0;text-align:center;margin:0 auto}#lasso--revision-list[data-count="6"] li{width:16.666666%}#lasso--revision-list[data-count="6"] li[data-revision="0"]{left:2px}#lasso--revision-list[data-count="6"] li[data-revision="1"]{left:2px}#lasso--revision-list[data-count="6"] li[data-revision="5"]{right:-1px}#lasso--revision-list[data-count="6"] li[data-revision="6"]{right:6px}#lasso--revision-list[data-count="5"] li{width:20%}#lasso--revision-list[data-count="5"] li[data-revision="0"]{left:-4px}#lasso--revision-list[data-count="5"] li[data-revision="1"]{left:-2px}#lasso--revision-list[data-count="5"] li[data-revision="2"]{left:0}#lasso--revision-list[data-count="5"] li[data-revision="3"]{right:-2px}#lasso--revision-list[data-count="5"] li[data-revision="4"]{right:-4px}#lasso--revision-list[data-count="4"] li{width:25%}#lasso--revision-list[data-count="4"] li[data-revision="0"]{left:-15px}#lasso--revision-list[data-count="4"] li[data-revision="1"]{left:-4px}#lasso--revision-list[data-count="4"] li[data-revision="2"]{right:-4px}#lasso--revision-list[data-count="4"] li[data-revision="3"]{right:-15px}#lasso--revision-list[data-count="3"] li{width:33.333%}#lasso--revision-list[data-count="3"] li[data-revision="0"]{left:-29px}#lasso--revision-list[data-count="3"] li[data-revision="1"]{left:0}#lasso--revision-list[data-count="3"] li[data-revision="2"]{right:-29px}#lasso--revision-list[data-count="2"] li{width:50%}#lasso--revision-list[data-count="2"] li[data-revision="0"]{left:-60px}#lasso--revision-list[data-count="2"] li[data-revision="1"]{right:-60px}.os-ios .lasso-component--controls{opacity:1;filter:alpha(opacity=100);left:0}@media (max-width:600px){.lasso-editing .lasso--toolbar_wrap.ase-not-active,.lasso-editing .lasso--toolbar_wrap.toolbar-extended,.lasso-editing .lasso--toolbar_wrap.ase-not-active.toolbar-extended,.lasso-editing .lasso--toolbar_wrap{border-radius:0;width:100%;left:0;right:0;-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0);height:auto;bottom:auto}.lasso-editing .lasso--controls__right{z-index:1000;top:auto;right:0}.lasso-editing .lasso--controls__right a{background:0 0}.lasso-editing .lasso--controls__right #lasso--save:before{top:3px}.lasso-editing #lasso-toolbar--link.link--drop-down,.lasso-editing #lasso-toolbar--html.html--drop-down{position:static}.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap,.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--link__wrap,.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--html__wrap,.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap{left:0;right:0;top:auto;bottom:50px;width:90%}.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after,.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--link__wrap:after,.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--html__wrap:after,.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after{margin:0;top:-6px;border-top:0;border-bottom:6px solid #39424a}.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after{left:142px}.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after{left:175px}.lasso-editing #lasso-toolbar--components.toolbar--drop-down{position:static}.lasso-editing #lasso-toolbar--components.toolbar--drop-down ul{top:44px;left:0;right:0;width:100%}.lasso-editing #lasso-toolbar--components.toolbar--drop-down ul:after{left:206px;margin:0;top:-6px;border-top:0;border-bottom:6px solid #39424a}.lasso-editing .toolbar-extended #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after{left:222px}.lasso-editing .toolbar-extended #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after{left:255px}.lasso-editing .toolbar-extended #lasso-toolbar--components.toolbar--drop-down ul:after{left:288px}#lasso--all-posts__modal ul.lasso--post-list,#lasso--all-posts__modal ul.lasso--post-object-list{float:none;width:100%;display:block}#lasso--all-posts__modal ul.lasso--post-object-list{margin-bottom:20px;padding-bottom:10px;border-bottom:1px solid #181b1f;-webkit-box-shadow:0 1px 1px -1px rgba(255,255,255,.15);box-shadow:0 1px 1px -1px rgba(255,255,255,.15)}#lasso--all-posts__modal ul.lasso--post-object-list li{display:inline-block;width:auto;margin-right:20px;font-size:90%}#lasso--all-posts__modal ul.lasso--post-list{padding-left:0;border:0;box-shadow:none}.lasso--modal .lasso--modal__inner,.lasso--modal.lasso--modal__full .lasso--modal__inner{border-radius:0;padding:10px}}.lasso-mobile #lasso--exit{float:none}@media (min-width:601px){.lasso-mobile .toolbar--drop-up ul:after{margin:0;top:-9px;border-top:0;border-bottom:6px solid #39424a}.lasso-mobile #lasso-toolbar--html__wrap:after,.lasso-mobile #lasso-toolbar--link__wrap:after{margin:0;top:-9px;border-top:0;border-bottom:6px solid #39424a}.lasso-mobile.lasso--toolbar_wrap{width:100%}} ================================================ FILE: public/assets/css/style.css ================================================ .lasso--animate__spin{-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}.not-visible{opacity:0;filter:alpha(opacity=0);display:none;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;transition:opacity .2s ease}@font-face{font-family:icomoon;src:url(../../../public/assets/fonts/icomoon.eot?ua4grz);src:url(../../../public/assets/fonts/icomoon.eot?#iefixua4grz) format('embedded-opentype'),url(../../../public/assets/fonts/icomoon.woff?ua4grz) format('woff'),url(../../../public/assets/fonts/icomoon.ttf?ua4grz) format('truetype'),url(../../../public/assets/fonts/icomoon.svg?ua4grz#icomoon) format('svg');font-weight:400;font-style:normal}[class*=" lasso-icon-"],[class^=lasso-icon-]{font-family:icomoon;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lasso-icon-move:before{content:"\e600"}.lasso-icon-pen:before{content:"\e908"}.lasso-icon-image:before{content:"\e90d"}.lasso-icon-images:before{content:"\e90e"}.lasso-icon-camera:before{content:"\e90f"}.lasso-icon-headphones:before{content:"\e910"}.lasso-icon-film:before{content:"\e913"}.lasso-icon-book:before{content:"\e91f"}.lasso-icon-books:before{content:"\e920"}.lasso-icon-file-text2:before{content:"\e926"}.lasso-icon-location:before{content:"\e947"}.lasso-icon-clock:before{content:"\e94e"}.lasso-icon-user:before{content:"\e971"}.lasso-icon-quotes-left:before{content:"\e977"}.lasso-icon-plus:before{content:"\ea0a"}.lasso-icon-bold:before{content:"\ea62"}.lasso-icon-underline:before{content:"\ea63"}.lasso-icon-italic:before{content:"\ea64"}.lasso-icon-strikethrough:before{content:"\ea65"}.lasso-icon-pagebreak:before{content:"\ea6e"}.lasso-icon-paragraph-center:before{content:"\ea78"}.lasso-icon-spinner6:before{content:"\e97f"}.lasso-icon-upload2:before{content:"\e9c6"}.lasso-icon-cross:before{content:"\ea0f"}.lasso-icon-bin2:before{content:"\e9ad"}.lasso-icon-copy:before{content:"\e92c"}.lasso-icon-disk:before{content:"\e601"}.lasso-icon-embed:before{content:"\ea7f"}.lasso-icon-blog:before{content:"\e909"}.lasso-icon-pencil:before{content:"\e905"}.lasso-icon-gear:before{content:'\e994'}.lasso-icon-link:before{content:'\e9cb'}.lasso-icon-help:before{content:"\e602"}.lasso-icon-tools:before{content:"\f031"}.lasso-icon-layout:before{content:"\e603"}.lasso-icon-list:before{content:"\e9ba"}.lasso-icon-file-add:before{content:"\e603"}.lasso-icon-check:before{content:'\ea10'}.lasso-icon-history:before{content:"\e94d"}.lasso-editing .aesop-content-comp-wrap,.lasso-editing .aesop-image-component-image,.lasso-editing .aesop-video-container{-webkit-transition:all .25s linear;-moz-transition:all .25s linear;transition:all .25s linear}.lassoShowAnimate{-webkit-animation:lassoShowAnimate .2s;-moz-animation:lassoShowAnimate .2s;animation:lassoShowAnimate .2s}.lassoHideAnimate{-webkit-animation:lassoHideAnimate .2s;-moz-animation:lassoHideAnimate .2s;animation:lassoHideAnimate .2s}@-webkit-keyframes lassoShowAnimate{0%{transform:scale(.7);-webkit-transform:scale(.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-moz-keyframes lassoShowAnimate{0%{transform:scale(.7);-webkit-transform:scale(.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes lassoShowAnimate{0%{transform:scale(.7);-webkit-transform:scale(.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-webkit-keyframes lassoHideAnimate{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}@-moz-keyframes lassoHideAnimate{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}@keyframes lassoHideAnimate{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}.aesop-component{position:relative}.screen-reader-text,.screen-reader-text span,.ui-helper-hidden-accessible{position:absolute;margin:-1px;padding:0;height:1px;width:1px;overflow:hidden;clip:rect(0 0 0 0);border:0}[contenteditable=true]:focus{outline:0}.lasso-title-saved{-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease;background:rgba(255,255,255,.1)}.lasso-drop-zone{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;height:75px;background:rgba(0,0,0,.03);border:1px dashed rgba(0,0,0,.2);list-style-type:none;width:700px;margin:0 auto 25px;border-radius:3px}.lasso-drop-zone:hover{background:rgba(0,0,0,.03)}.lasso-drag-holder{height:75px!important;background:#d7d7d7;text-align:center;width:60px;font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lasso-drag-holder.lasso-toolbar--component__image:before,.lasso-drag-holder.lasso-toolbar--component__wpimg:before{content:"\e90f"}.lasso-drag-holder.lasso-toolbar--component__character:before{content:"\e971"}.lasso-drag-holder.lasso-toolbar--component__quote:before,.lasso-drag-holder.lasso-toolbar--component__wpquote:before{content:"\e977"}.lasso-drag-holder.lasso-toolbar--component__content:before{content:"\ea78"}.lasso-drag-holder.lasso-toolbar--component__chapter:before{content:"\e91f"}.lasso-drag-holder.lasso-toolbar--component__parallax:before{content:"\ea6e"}.lasso-drag-holder.lasso-toolbar--component__audio:before{content:"\e910"}.lasso-drag-holder.lasso-toolbar--component__video:before,.lasso-drag-holder.lasso-toolbar--component__wpvideo:before{content:"\e913"}.lasso-drag-holder.lasso-toolbar--component__map:before{content:"\e947"}.lasso-drag-holder.lasso-toolbar--component__timeline:before{content:"\e94e"}.lasso-drag-holder.lasso-toolbar--component__document:before{content:"\e926"}.lasso-drag-holder.lasso-toolbar--component__collection:before{content:"\e920"}.lasso-drag-holder.lasso-toolbar--component__gallery:before{content:"\e90e"}.lasso-drag-holder.lasso-toolbar--component__gallerypop:before{content:"\f211";font-family:Dashicons}.lasso-drag-holder:before{position:relative;top:25px;font-size:22px}.lasso-editor{position:relative;min-height:10px}.lasso-editor:focus{outline:0;border:none;box-shadow:none}.lasso-editor p:empty{display:block;height:1em}.lasso-editor .ui-draggable-dragging{list-style-type:none;height:50px;padding:10px;width:60px!important;background:rgba(35,40,45,.5);text-align:center;font-size:22px;border-radius:4px;font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__image:before,.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__wpimg:before{content:"\e90f"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__character:before{content:"\e971"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__quote:before,.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__wpquote:before{content:"\e977"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__content:before{content:"\ea78"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__chapter:before{content:"\e91f"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__parallax:before{content:"\ea6e"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__audio:before{content:"\e910"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__video:before,.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__wpvideo:before{content:"\e913"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__map:before{content:"\e947"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__timeline:before{content:"\e94e"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__document:before{content:"\e926"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__collection:before{content:"\e920"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__gallery:before{content:"\e90e"}.lasso-editor .ui-draggable-dragging.lasso-toolbar--component__gallerypop:before{content:"\f211";font-family:Dashicons}.lasso-editor .ui-draggable-dragging:before{color:#fff;position:relative;top:4px}.lasso-editor-clear{background:0 0!important;border-color:transparent!important}.lasso-editor-paste-hook{position:absolute;opacity:0}.lasso-editor-placeholder{position:absolute}.lasso-editor-placeholder div{opacity:.5;filter:alpha(opacity=50);position:absolute}.lasso-editor-placeholder-rich div{font-style:italic}.lasso-editor-inline,.lasso-editor-inlineRich,.lasso-editor-placeholder-inline div,.lasso-editor-placeholder-inlineRich div{overflow:hidden;white-space:nowrap}.lasso-editor-drag{position:absolute;cursor:move;margin-left:-5px;margin-top:-20px}.lasso-editor-toolbar-hide{overflow:hidden;max-height:0;padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0;transition-property:opacity;-moz-transition-duration:.3s;-webkit-transition-duration:.3s;-o-transition-duration:.3s;transition-duration:.3s;-moz-transition-timing-function:cubic-bezier(0,1,.5,1);-webkit-transition-timing-function:cubic-bezier(0,1,.5,1);-o-transition-timing-function:cubic-bezier(0,1,.5,1);transition-timing-function:cubic-bezier(0,1,.5,1);opacity:0}.lasso-editor-toolbar-show{transition-property:opacity;-moz-transition-duration:.3s;-webkit-transition-duration:.3s;-o-transition-duration:.3s;transition-duration:.3s;-moz-transition-timing-function:ease-in;-webkit-transition-timing-function:ease-in;-o-transition-timing-function:ease-in;transition-timing-function:ease-in;max-height:1000px;opacity:1;width:auto!important}.lasso-editor-toolbar-fixed{position:fixed}.lasso-editor-focused{transition:all 500ms ease-in-out 0s;-moz-box-shadow:0 0 3px 4px rgba(0,0,0,.2);-webkit-box-shadow:0 0 3px 4px rgba(0,0,0,.2);box-shadow:0 0 3px 4px rgba(0,0,0,.2)}#lasso--pagerefresh{padding:15px;background:#4da34d;color:#fff;font-size:14px;line-height:18.2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.lasso--toolbar_wrap{width:auto;left:50%;-webkit-transform:translate(-50%,0);-ms-transform:translate(-50%,0);transform:translate(-50%,0)}.lasso-editor-controls--wrap{color:#e2e2e2;border:1px solid #181b1f;background-image:-webkit-linear-gradient(top,#353c44 0,#23282d 100%);background-image:-o-linear-gradient(top,#353c44 0,#23282d 100%);background-image:linear-gradient(to bottom,#353c44 0,#23282d 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff353c44', endColorstr='#ff23282d', GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);height:39px;font-size:16px;border-radius:4px;position:fixed;text-align:center;bottom:20px;z-index:999}.lasso-editor-controls--wrap *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.lasso-editor-controls{margin:0;padding:0;letter-spacing:0;list-style:none;height:39px;line-height:1}ul.lasso-editor-controls:after,ul.lasso-editor-controls:before{content:" ";display:table}ul.lasso-editor-controls:after{clear:both}ul.lasso-editor-controls li{height:37px;position:relative;float:left;padding:0 8px;border-right:1px solid #23282d;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,.4);line-height:1}ul.lasso-editor-controls li:before{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease;position:relative;top:10px}ul.lasso-editor-controls li:first-child:hover{border-top-left-radius:4px;border-bottom-left-radius:4px}ul.lasso-editor-controls li:last-child{border-right:0}ul.lasso-editor-controls li:last-child:hover{border-top-right-radius:4px;border-bottom-right-radius:4px}ul.lasso-editor-controls li:hover{cursor:pointer;background:#39424a}ul.lasso-editor-controls li:active{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.4);box-shadow:inset 0 1px 1px rgba(0,0,0,.4)}#lasso-toolbar--bold:before{content:'\ea62'}#lasso-toolbar--italic:before{content:'\ea64'}#lasso-toolbar--underline:before{content:'\ea63'}#lasso-toolbar--strike:before{content:'\ea65'}#lasso-toolbar--link:before{content:'\e9cb'}#lasso-toolbar--h2:before{content:'H2';top:9px;font-size:17px;font-weight:700;letter-spacing:.05em}#lasso-toolbar--h3:before{content:'H3';top:9px;font-size:17px;font-weight:700;letter-spacing:.05em}#lasso-toolbar--html:before{content:'\ea7f'}#lasso-toolbar--components:before{content:'\ea0a'}#lasso-toolbar--color-set:before{content:'A';top:5px;font-size:21px;font-weight:700;letter-spacing:.05em}#lasso-toolbar--color-pick:before{content:'\f100';font-family:Dashicons}#lasso-toolbar--left-align:before{content:'\f206';font-family:Dashicons}#lasso-toolbar--center-align:before{content:'\f207';font-family:Dashicons}#lasso-toolbar--right-align:before{content:'\f208';font-family:Dashicons}#lasso-toolbar--html #lasso-toolbar--html__wrap{position:absolute;left:-10000px;opacity:0;filter:alpha(opacity=0)}#lasso-toolbar--html.html--drop-down,#lasso-toolbar--html.html--drop-up{box-shadow:none;background:#39424a}#lasso-toolbar--html.html--drop-down *,#lasso-toolbar--html.html--drop-up *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__wrap{margin:0;padding:4px;opacity:1;filter:alpha(opacity=100);list-style-type:none;width:340px;height:173px;bottom:45px;border-radius:4px;left:-154px;background:#353c44}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__wrap:after{content:'';position:absolute;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #39424a;left:0;right:0;bottom:-6px;text-align:center;margin:0 auto}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:hover,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__wrap:hover{cursor:default}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__inner,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__inner{background:#23282d;color:#e2e2e2;height:130px;overflow:scroll;text-align:left;line-height:1.25;padding:8px;border-radius:2px;font-family:monospace;white-space:pre;font-size:14px;-webkit-box-shadow:inset 0 0 4px 1px rgba(0,0,0,.25);box-shadow:inset 0 0 4px 1px rgba(0,0,0,.25)}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__inner:empty:before,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__inner:empty:before{content:attr(placeholder);color:rgba(226,226,226,.5)}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__inner:hover,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__inner:hover{cursor:text}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__inner:focus,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__inner:focus{outline:0}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer{text-align:right;font-family:Arial;padding:7px 2px 2px;height:35px}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer a,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer a{font-size:14px;font-weight:700;padding:5px 7px 4px;line-height:1;border-radius:2px;display:inline-block;text-decoration:none;color:#fff;text-shadow:0 1px 1px rgba(0,0,0,.4)}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer #lasso-toolbar--html__insert,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer #lasso-toolbar--html__insert{background:#007aab}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer #lasso-toolbar--html__insert:hover,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer #lasso-toolbar--html__insert:hover{background:#006187}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer #lasso-toolbar--html__insert:active,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer #lasso-toolbar--html__insert:active{background:#004764;-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso-toolbar--html.html--drop-down #lasso-toolbar--html__footer .lasso-toolbar--html__cancel,#lasso-toolbar--html.html--drop-up #lasso-toolbar--html__footer .lasso-toolbar--html__cancel{color:#d9534f}ul.lasso-toolbar--html-snips{font-size:12px;line-height:0;float:left;margin:0;list-style:none}ul.lasso-toolbar--html-snips:after,ul.lasso-toolbar--html-snips:before{content:" ";display:table}ul.lasso-toolbar--html-snips:after{clear:both}ul.lasso-toolbar--html-snips li{line-height:0;height:25px;margin-right:4px;background:#23282d;border:1px solid #1f2327;border-radius:4px;-webkit-box-shadow:inset 1px 1px 0 rgba(255,255,255,.05);box-shadow:inset 1px 1px 0 rgba(255,255,255,.05)}ul.lasso-toolbar--html-snips li:before{top:5px}ul.lasso-toolbar--html-snips li:last-child{border-right:1px solid #1f2327}ul.lasso-toolbar--html-snips #lasso-html--h2:before{content:'H2'}ul.lasso-toolbar--html-snips #lasso-html--h3:before{content:'H3'}ul.lasso-toolbar--html-snips #lasso-html--ul:before{content:'UL'}ul.lasso-toolbar--html-snips #lasso-html--ol:before{content:'OL'}#lasso-toolbar--components ul{position:absolute;left:-10000px;opacity:0;filter:alpha(opacity=0)}#lasso-toolbar--components.toolbar--drop-down,#lasso-toolbar--components.toolbar--drop-up{box-shadow:none;background:#39424a}#lasso-toolbar--components.toolbar--drop-down *,#lasso-toolbar--components.toolbar--drop-up *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#lasso-toolbar--components.toolbar--drop-down ul,#lasso-toolbar--components.toolbar--drop-up ul{margin:0;padding:4px;opacity:1;filter:alpha(opacity=100);list-style-type:none;width:304px;height:86px;top:-92px;border-radius:4px;left:-136px;background:#353c44;line-height:0}#lasso-toolbar--components.toolbar--drop-down ul:after,#lasso-toolbar--components.toolbar--drop-up ul:after{content:'';position:absolute;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #39424a;left:0;right:0;bottom:-6px;text-align:center;margin:0 auto}#lasso-toolbar--components.toolbar--drop-down ul li,#lasso-toolbar--components.toolbar--drop-up ul li{line-height:0;text-align:center;position:relative;font-size:20px;text-shadow:0 1px 1px rgba(0,0,0,.4);border-right:none;margin:1px;padding:2px;height:36px;width:40px;background:#2a3036;border-left:1px solid rgba(255,255,255,.1);border-top:1px solid rgba(255,255,255,.1);-webkit-box-shadow:1px 1px 0 rgba(0,0,0,.3);box-shadow:1px 1px 0 rgba(0,0,0,.3)}#lasso-toolbar--components.toolbar--drop-down ul li:before,#lasso-toolbar--components.toolbar--drop-up ul li:before{top:6px}#lasso-toolbar--components.toolbar--drop-down ul li:hover,#lasso-toolbar--components.toolbar--drop-up ul li:hover{cursor:move;background:#23282d;border-radius:0}#lasso-toolbar--components.toolbar--drop-down ul li.active,#lasso-toolbar--components.toolbar--drop-down ul li:active,#lasso-toolbar--components.toolbar--drop-up ul li.active,#lasso-toolbar--components.toolbar--drop-up ul li:active{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.4);box-shadow:inset 0 1px 1px rgba(0,0,0,.4);background:#1a1e22}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__image:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__wpimg:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__image:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__wpimg:before{content:"\e90f"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__character:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__character:before{content:"\e971"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__quote:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__wpquote:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__quote:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__wpquote:before{content:"\e977"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__content:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__content:before{content:"\ea78"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__chapter:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__chapter:before{content:"\e91f"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__parallax:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__parallax:before{content:"\ea6e"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__audio:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__audio:before{content:"\e910"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__video:before,#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__wpvideo:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__video:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__wpvideo:before{content:"\e913"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__map:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__map:before{content:"\e947"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__timeline:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__timeline:before{content:"\e94e"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__document:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__document:before{content:"\e926"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__collection:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__collection:before{content:"\e920"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__gallery:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__gallery:before{content:"\e90e"}#lasso-toolbar--components.toolbar--drop-down ul li.lasso-toolbar--component__gallerypop:before,#lasso-toolbar--components.toolbar--drop-up ul li.lasso-toolbar--component__gallerypop:before{content:"\f211";font-family:Dashicons}#lasso-toolbar--link *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#lasso-toolbar--link #lasso-toolbar--link__wrap{position:absolute;left:-10000px;opacity:0;filter:alpha(opacity=0)}#lasso-toolbar--link.link--drop-down,#lasso-toolbar--link.link--drop-up{box-shadow:none;background:#39424a}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__wrap{margin:0;padding:4px;opacity:1;filter:alpha(opacity=100);list-style-type:none;width:300px;height:70px;bottom:45px;border-radius:4px;left:-134px;background:#353c44}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__wrap:after{content:'';position:absolute;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #39424a;left:0;right:0;bottom:-6px;text-align:center;margin:0 auto}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:hover,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__wrap:hover{cursor:default}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner{background:#23282d;color:#e2e2e2;height:32px;white-space:nowrap;overflow:hidden;text-align:left;line-height:1.25;padding:8px;border-radius:2px;font-family:monospace;font-size:14px;-webkit-box-shadow:inset 0 0 4px 1px rgba(0,0,0,.25);box-shadow:inset 0 0 4px 1px rgba(0,0,0,.25)}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner:empty:before,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner:empty:before{content:attr(placeholder);color:rgba(226,226,226,.5)}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner:after,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner:after{content:'';position:absolute;background:#23282d;border-top-right-radius:2px;border-bottom-right-radius:2px;right:4px;top:4px;height:32px;width:36px}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner:hover,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner:hover{cursor:text}#lasso-toolbar--link.link--drop-down #lasso-toolbar--link__inner:focus,#lasso-toolbar--link.link--drop-up #lasso-toolbar--link__inner:focus{outline:0}#lasso-toolbar--link .lasso-toolbar--link__control{position:absolute;top:9px;right:5px;width:25px;font-family:Arial;font-size:12px;font-weight:700;padding:5px 7px 4px;line-height:1;border-radius:2px;display:inline-block;text-decoration:none;color:#fff;text-shadow:0 1px 1px rgba(0,0,0,.4);background:#007aab}#lasso-toolbar--link .lasso-toolbar--link__control:before{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\ea10'}#lasso-toolbar--link .styled-checkbox{position:absolute;top:45px;left:8px}#lasso-toolbar--link label{position:absolute;top:45px;left:41px;font-family:Arial;color:#fff;font-size:12px}.ase-not-active #lasso-toolbar--components #lasso-toolbar--components__list{width:94px;left:calc(50% - 94px / 2);height:48px;top:-55px}.lasso--controls__center{width:auto;left:50%;-webkit-transform:translate(-50%,0);-ms-transform:translate(-50%,0);transform:translate(-50%,0)}.lasso--controls__center li{list-style-type:none;line-height:0}.lasso--controls__right{position:fixed;right:-10000px;bottom:20px;z-index:999;opacity:0;filter:alpha(opacity=0);-webkit-transition:opacity .3s ease;-moz-transition:opacity .3s ease;transition:opacity .3s ease;text-align:right}.lasso--controls__right a{display:inline-block;vertical-align:bottom;color:#e2e2e2;font-family:Arial;font-style:normal;font-size:20px;padding:0 8px;border-radius:3px;height:39px;width:43px;line-height:38px;text-align:center;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.lasso--controls__right a:active,.lasso--controls__right a:active:before,.lasso--controls__right a:focus,.lasso--controls__right a:focus:before,.lasso--controls__right a:hover{color:#e2e2e2;text-decoration:none}.lasso--controls__right a:before{color:#fff;font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lasso--controls__right a:focus{outline:0}#lasso--edit{background:#353c44;border-top-left-radius:3px;border-bottom-left-radius:3px}#lasso--edit:before{content:'\e908'}#lasso--edit:hover{background:#2e353b}#lasso--post-settings:before{content:'\f031'}#lasso--post-new:before{content:'\e603'}#lasso--post-revisions:before{content:'\e94d'}#lasso--post-all:before{content:'\e9ba';font-size:15px;top:11px}#lasso--save{background:#007aab;font-size:22px}#lasso--save:before{position:relative;top:4px;left:0;height:auto;content:'\e601'}#lasso--save:hover{background:#005678}#lasso--save:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--save.being-saved:before{content:'\e97f';-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}#lasso--save.lasso--saved{background:#4da34d}#lasso--save.lasso--saved:before{top:2px;content:'\ea10'}#lasso--save.lasso--error{background:#d9534f}#lasso--save.lasso--error:before{content:'\ea05'}#lasso--exit{background:#f0ad4e;float:left}#lasso--exit:before{position:relative;top:3px;content:'\ea0f'}#lasso--publish{background:#4da34d}#lasso--publish:before{content:'\e909';position:relative;top:2px}.lasso-editing #lasso--controls .lasso-editor-controls,.lasso-editing #lasso--edit,.lasso-editing #lasso--post-settings{opacity:0;filter:alpha(opacity=0);position:absolute;left:-10000px}.lasso-editing .lasso--controls__right{opacity:1;filter:alpha(opacity=100);right:20px;left:20px}.lasso-editing .wp-audio-shortcode{visibility:visible!important}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.lasso--btn-primary{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:none;display:inline-block;font-family:Arial;color:#fff;font-size:17px;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none}.lasso--btn-primary:active,.lasso--btn-primary:focus{outline:0}.lasso--btn-primary:hover{text-decoration:none;color:#fff;background:#005678}.lasso--btn-primary:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--btn-secondary{background:#32373c;border:1px solid #181b1f;color:#e2e2e2;font-size:17px;line-height:1.8;padding:2px 12px 1px;text-decoration:none;display:inline-block;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.lasso--btn-secondary:active,.lasso--btn-secondary:visited{color:#e2e2e2}.lasso--btn-secondary:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}.lasso--btn-secondary:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--btn-secondary.lasso--btn-loading:before{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}.lasso--post-form label{font-size:14px;line-height:1;margin-bottom:8px;display:block;font-family:Arial}.lasso--post-form label .lasso-icon-help{margin-left:5px;position:relative;top:2px}.lasso--post-form input[type=text]{background-color:#f8f8f8!important;padding:2px 8px 2px 6px;background:0 0;border:1px solid #181b1f;color:#444;font-size:14px;z-index:0;position:relative;height:36px;border-radius:4px;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px 1px rgba(0,0,0,.4)}.lasso--post-form input[type=text]:focus{outline:0;border:1px solid #007aab;border-radius:2px}.lasso--post-form .checkbox_label{display:inline-block}.lasso--post-form .checkbox-control{position:relative;display:inline-block;padding-left:28px;cursor:pointer;top:2px}.lasso--post-form .checkbox-control input{position:absolute;opacity:0;z-index:-1}.lasso--post-form .checkbox-control input:checked~.control-indicator{color:#f8f8f8;background-color:#007aab}.lasso--post-form .checkbox-control input:active~.control-indicator{color:#f8f8f8;background-color:#007aab}.lasso--post-form .control-indicator{position:absolute;top:-1px;left:0;display:block;width:18px;height:18px;line-height:1rem;font-size:65%;color:#f8f8f8;text-align:center;background-color:#f8f8f8;background-size:50% 50%;background-position:center center;background-repeat:no-repeat;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.lasso--post-form .checkbox .control-indicator{border-radius:.25rem}.lasso--post-form .checkbox input:checked~.control-indicator{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTYuNCwxTDUuNywxLjdMMi45LDQuNUwyLjEsMy43TDEuNCwzTDAsNC40bDAuNywwLjdsMS41LDEuNWwwLjcsMC43bDAuNy0wLjdsMy41LTMuNWwwLjctMC43TDYuNCwxTDYuNCwxeiINCgkvPg0KPC9zdmc+DQo=)}.lasso--post-form .radio .control-indicator{border-radius:50%}.lasso--post-form .radio input:checked~.control-indicator{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTQsMUMyLjMsMSwxLDIuMywxLDRzMS4zLDMsMywzczMtMS4zLDMtM1M1LjcsMSw0LDF6Ii8+DQo8L3N2Zz4NCg==)}.lasso--post-form .control-x input:checked~.control-indicator{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iOHB4IiBoZWlnaHQ9IjhweCIgdmlld0JveD0iMCAwIDggOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgOCA4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIGZpbGw9IiNGRkZGRkYiIGQ9Ik0xLjQsMEwwLDEuNGwwLjcsMC43bDEuOCwxLjhMMC43LDUuN0wwLDYuNGwxLjQsMS40bDAuNy0wLjdsMS44LTEuOGwxLjgsMS44bDAuNywwLjdsMS40LTEuNEw3LjEsNS43DQoJTDUuMywzLjlsMS44LTEuOGwwLjctMC43TDYuNCwwTDUuNywwLjdMMy45LDIuNUwyLjEsMC43QzIuMSwwLjcsMS40LDAsMS40LDB6Ii8+DQo8L3N2Zz4NCg==)}.lasso--post-form .control-dash input:checked~.control-indicator{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iOHB4IiBoZWlnaHQ9IjhweCIgdmlld0JveD0iMCAwIDggOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgOCA4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIGZpbGw9IiNGRkZGRkYiIGQ9Ik0wLDN2Mmg4VjNIMHoiLz4NCjwvc3ZnPg0K)}.lasso--post-form .lasso--postsettings-cancel{background:0 0;color:#d9534f;position:relative;top:3px}.lasso--post-form .lasso--postsettings-cancel:hover{color:#d43f3a;text-decoration:none}.lasso--post-form input[type=submit]{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:none;display:inline-block;font-family:Arial;color:#fff;font-size:17px;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none;float:right}.lasso--post-form input[type=submit]:active,.lasso--post-form input[type=submit]:focus{outline:0}.lasso--post-form input[type=submit]:hover{text-decoration:none;color:#fff;background:#005678}.lasso--post-form input[type=submit]:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--btn-group{text-align:center}.lasso--btn-group a{margin:0;display:inline-block}.lasso--btn-group.lasso--btn-group-small a{font-size:14px}.lasso--notice{text-align:center;max-width:500px;padding:10px;color:#fff;font-family:Arial;font-size:14px;margin:10px auto}.lasso--notice.lasso--notice-warning{background:#f0ad4e}.lasso--notice.lasso--notice-info{background:#007aab}.lasso--notice.lasso--notice-error{background:#d9534f}.lasso--notice.lasso--notice-success{background:#4da34d}#lasso--slider{position:relative;text-align:left;background:#32373c;top:5px;height:10px;border-radius:4px;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.2);box-shadow:inset 1px 1px 1px rgba(0,0,0,.2)}#lasso--slider .ui-slider-handle{position:absolute;z-index:2;width:22px;height:22px;cursor:default;-ms-touch-action:none;touch-action:none;background:#007aab;top:-6px;margin-left:-11px;border-radius:100%;-webkit-box-shadow:0 0 7px -1px rgba(0,0,0,.75);box-shadow:0 0 7px -1px rgba(0,0,0,.75)}#lasso--slider .ui-slider-handle:active,#lasso--slider .ui-slider-handle:focus{outline:0}#lasso--slider .ui-slider-handle:active,#lasso--slider .ui-slider-handle:hover{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.5);box-shadow:inset 0 0 6px rgba(0,0,0,.5)}#lasso--slider .ui-slider-handle:hover{border:4px solid #007aab}#lasso--slider .ui-slider-handle:active{border:4px solid #006f9c}#lasso--slider .ui-slider-handle:active,#lasso--slider .ui-slider-handle:focus,#lasso--slider .ui-slider-handle:hover{cursor:move}.lasso--select-wrap{position:relative;display:inline-block;color:#444}.lasso--select-wrap select{display:inline-block;width:100%;margin:0;line-height:30px;color:#e2e2e2;background-color:#32373c;border:0;padding:2px 25px 2px 12px;border-radius:4px;cursor:pointer;outline:0;font-size:15px;-webkit-appearance:none;-moz-appearance:none;appearance:none}.lasso--select-wrap select:focus:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}.lasso--select-wrap:after{position:absolute;top:50%;right:12px;display:inline-block;content:"";width:0;height:0;margin-top:-.15rem;pointer-events:none;border-top:4px solid #e2e2e2;border-right:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid transparent}.lasso--select-wrap select:active{color:#444;background-color:#32373c}.lasso--select-wrap select::-ms-expand{display:none}@-moz-document url-prefix(){select{text-indent:.01px;text-overflow:'';padding-right:1rem}option{background-color:#fff}}.lasso-modal-open{overflow:hidden}#lasso--modal__overlay{z-index:999;position:fixed;left:0;top:0;right:0;bottom:0;background:rgba(255,255,255,.85)}.lasso--modal{z-index:1001;position:fixed;display:table;left:0;right:0;bottom:0;width:100%;max-width:381px;margin:0 auto;font-family:Arial}.lasso--modal *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.lasso--modal__inner{display:table-cell;vertical-align:middle;background:#23282d;border-radius:4px;border:1px solid #0d0e10;padding:18px;-webkit-box-shadow:0 0 10px 1px rgba(0,0,0,.5);box-shadow:0 0 10px 1px rgba(0,0,0,.5);color:#e2e2e2;position:relative}.lasso--modal__inner:after,.lasso--modal__inner:before{content:" ";display:table}.lasso--modal__inner:after{clear:both}#lasso--modal__close{position:absolute;right:20px;top:10px}#lasso--modal__close:hover{cursor:pointer}.lasso--slider_wrap{padding:0 10px;height:18px}.lasso--postsettings__option{padding-bottom:20px;margin-bottom:20px;position:relative;line-height:1;border-bottom:1px solid #0d0e10;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.05);box-shadow:0 1px 1px rgba(255,255,255,.05)}.lasso--postsettings__option.lasso--last-option{border-bottom:none;margin-bottom:0;padding-bottom:0}.lasso--postsettings__option .story-status{margin:12px 0 8px;padding:0 10px;line-height:1}.lasso--postsettings__option .story-status:after,.lasso--postsettings__option .story-status:before{content:" ";display:table}.lasso--postsettings__option .story-status:after{clear:both}.lasso--postsettings__option .story-status li{font-size:14px;float:left;list-style-type:none}.lasso--postsettings__option .story-status.story-status-draft #lasso--status-publish,.lasso--postsettings__option .story-status.story-status-publish #lasso--status-draft{opacity:.3;filter:alpha(opacity=30)}.lasso--postsettings__option .story-status #lasso--status-publish{float:right}.lasso--postsettings__option.story-slug-option .lasso--select-wrap{position:absolute;top:24px;left:1px}.lasso--postsettings__option.story-slug-option .lasso--select-wrap select{font-size:13px;border-radius:1px 0 0 1px}.lasso--postsettings__option.story-slug-option+.lasso--postsettings__footer{padding-top:inherit;padding-to:20px;margin-top:20px}.lasso--postsettings__option+.lasso--postsettings__footer{border-top:none;box-shadow:none;margin-top:0;padding-top:0}.lasso--postsettings__footer{text-align:right;font-size:16px;padding-top:20px;margin-top:22px;border-top:1px solid #0d0e10;-webkit-box-shadow:0 -1px 1px rgba(255,255,255,.05);box-shadow:0 -1px 1px rgba(255,255,255,.05)}.lasso--postsettings__footer a,.lasso--postsettings__footer input{display:inline-block}#lasso--postnew__form .story-slug-option{margin-bottom:0}#lasso--postnew__form .story-slug-option input[type=text]{padding-left:92px}#lasso--postnew__form .story-slug-option #lasso--select-type{height:35px}.lasso--modal__tabs{position:absolute;right:0;top:-36px;padding:0;margin:0;height:36px;list-style:none}.lasso--modal__tabs li{display:inline-block;background:#32373c;font-size:15px;border-top-left-radius:4px;border-top-right-radius:4px;padding:0 10px;margin:0 1px;height:36px;line-height:36px;-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease}.lasso--modal__tabs li.active-tab,.lasso--modal__tabs li:hover{cursor:pointer;background:#23282d}.lasso--modal__tabs li:last-child{margin-right:-1px}.lasso--modal__content #poststuff{min-width:1px}#lasso--post-settings__modal{max-width:600px}.lasso--postsettings__2col:after,.lasso--postsettings__2col:before{content:" ";display:table}.lasso--postsettings__2col:after{clear:both}.lasso--postsettings__2col .lasso--postsettings__left,.lasso--postsettings__2col .lasso--postsettings__right{float:left}.lasso--postsettings__2col .lasso--postsettings__left{width:35%}.lasso--postsettings__2col .lasso--postsettings__left label{font-size:14px;line-height:1;display:block;margin-bottom:15px}.lasso--postsettings__2col .lasso--postsettings__left .lasso-util--help{left:6px;top:2px}.lasso--postsettings__2col .lasso--postsettings__right{width:62%;margin-left:3%}.story-slug-option,.story-tags-option{border-bottom:none;box-shadow:none;padding-bottom:0}.lasso--postsettings__middle{clear:left;padding-top:20px;border-top:1px solid #0d0e10;-webkit-box-shadow:inset 0 1px 1px rgba(255,255,255,.05);box-shadow:inset 0 1px 1px rgba(255,255,255,.05)}.lasso--post-thumb{position:relative}.lasso--post-thumb .lasso--post-thumb__controls{position:absolute;top:10px;left:10px;right:10px;z-index:1}.lasso--post-thumb .lasso--post-thumb__controls i{text-shadow:0 1px 1px rgba(0,0,0,.5);opacity:.6;filter:alpha(opacity=60);-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease}.lasso--post-thumb .lasso--post-thumb__controls i:hover{cursor:pointer;opacity:1;filter:alpha(opacity=100);-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}.lasso--post-thumb .lasso--post-thumb__controls i:active{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);box-shadow:none}.lasso--post-thumb .lasso--post-thumb__controls #lasso--post-thumb__add{font-size:16px;top:2px;margin-right:-4px;position:relative}.lasso--post-thumb .lasso--post-thumb__controls #lasso--save-status{float:right;font-size:16px;position:relative;top:3px;right:3px;color:#4da34d}.lasso--post-thumb img{border:5px solid #32373c;border-radius:4px;width:196px;height:136px}#lasso--postsettings__form.no-thumbnail #lasso--post-thumb__delete{opacity:0;filter:alpha(opacity=0);display:none;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;transition:opacity .2s ease}.ps-container.ps-active-x>.ps-scrollbar-x-rail,.ps-container.ps-active-y>.ps-scrollbar-y-rail{display:block}.ps-container>.ps-scrollbar-x-rail{display:none;position:absolute;opacity:0;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;-o-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;bottom:3px;height:8px}.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x{position:absolute;background-color:#32373c;-webkit-transition:background-color .2s linear;-moz-transition:background-color .2s linear;-o-transition:background-color .2s linear;transition:background-color .2s linear;bottom:0;height:8px}.ps-container>.ps-scrollbar-x-rail.in-scrolling{background-color:transparent;opacity:.9;-ms-filter:"alpha(Opacity=90)";filter:alpha(opacity=90)}.ps-container>.ps-scrollbar-y-rail{display:none;position:absolute;opacity:0;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;-o-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;right:3px;width:8px}.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y{position:absolute;background-color:#32373c;-webkit-transition:background-color .2s linear;-moz-transition:background-color .2s linear;-o-transition:background-color .2s linear;transition:background-color .2s linear;right:0;width:8px}.ps-container>.ps-scrollbar-y-rail.in-scrolling{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail,.ps-container:hover>.ps-scrollbar-y-rail{opacity:.6;filter:alpha(opacity=60)}.ps-container:hover>.ps-scrollbar-x-rail.in-scrolling,.ps-container:hover>.ps-scrollbar-x-rail:hover,.ps-container:hover>.ps-scrollbar-y-rail.in-scrolling{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x{background-color:#999}.ps-container:hover>.ps-scrollbar-y-rail:hover{background-color:transparent;opacity:.9;filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y{background-color:#999}.lasso-sidebar-open{overflow:hidden}.lasso-sidebar-open #lasso--sidebar,.lasso-sidebar-open .lasso-buttoninsert-wrap{right:0}#lasso--sidebar{z-index:9999;position:fixed;right:-285px;top:0;bottom:0;width:285px;-webkit-transition:right .25s ease;-moz-transition:right .25s ease;transition:right .25s ease}#lasso--sidebar *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#lasso--sidebar code,#lasso--sidebar p{color:#e2e2e2;background:#23282d}.admin-bar #lasso--sidebar{top:32px}.admin-bar #lasso--component__settings form{padding-bottom:102px}.lasso--sidebar__inner{height:100%;font-family:Arial;font-size:14px;background:#23282d;border-left:4px solid #353c44;color:#e2e2e2;text-shadow:0 1px 1px rgba(0,0,0,.4);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-box-shadow:inset 9px 0 9px -9px #000;box-shadow:inset 9px 0 9px -9px #000}.lasso--sidebar__inner #lasso--sidebar__close{color:#007aab}.lasso--sidebar__inner #lasso--component__settings{overflow:hidden;position:relative}#lasso--sidebar__drag{height:100px;width:50px;background:red;top:50%;bottom:0;position:absolute}ul.lasso-component--controls{color:#e2e2e2;border:1px solid #181b1f;background-image:-webkit-linear-gradient(top,#353c44 0,#23282d 100%);background-image:-o-linear-gradient(top,#353c44 0,#23282d 100%);background-image:linear-gradient(to bottom,#353c44 0,#23282d 100%);background-repeat:repeat-x;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);position:absolute;padding:0;line-height:1;height:26px;width:121px;top:4px;right:0;left:-10000px;text-align:center;margin:0 auto;border-radius:2px;opacity:0;filter:alpha(opacity=0);-webkit-transition:opacity .4s ease;-moz-transition:opacity .4s ease;transition:opacity .4s ease;z-index:105}ul.lasso-component--controls *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}ul.lasso-component--controls:after,ul.lasso-component--controls:before{content:" ";display:table}ul.lasso-component--controls:after{clear:both}ul.lasso-component--controls li{float:left;list-style-type:none;line-height:1;width:29.51px;height:24px;border-right:1px solid #23282d;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,.4)}ul.lasso-component--controls li:before{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;position:relative;top:1px;font-size:15px}ul.lasso-component--controls li:first-child:hover{border-bottom-left-radius:2px;border-top-left-radius:2px}ul.lasso-component--controls li:hover{cursor:pointer;background:#39424a}ul.lasso-component--controls li:active{-webkit-box-shadow:inset 0 0 6px -2px rgba(0,0,0,.66);box-shadow:inset 0 0 6px -2px rgba(0,0,0,.66)}ul.lasso-component--controls li:last-child{border-right:none}ul.lasso-component--controls li:last-child:hover{border-top-right-radius:2px;border-bottom-right-radius:2px}ul.lasso-component--controls li.lasso-drag,ul.lasso-component--controls li.lasso-drag:hover{cursor:move}ul.lasso-component--controls li.lasso-drag:before{content:'\e600'}ul.lasso-component--controls li.lasso-settings:before{content:'\e994'}ul.lasso-component--controls li.lasso-clone:before{content:'\e92c'}ul.lasso-component--controls li.lasso-delete:before{content:'\e9ad'}.lasso-editing .aesop-component:hover .lasso-component--controls{left:4px;opacity:1;filter:alpha(opacity=100)}.aesop-timeline-stop .lasso-component--controls li{line-height:16px}.aesop-image-component[data-align=right]:hover .lasso-component--controls,.aesop-image-component[data-align=left]:hover .lasso-component--controls{margin:13px 0 0 4px}.aesop-image-component[data-align=right]:hover .lasso-component--controls{left:auto}#lasso--component__settings form{margin:0;position:relative;padding-bottom:70px}#lasso--component__settings .lasso-option-desc,#lasso--component__settings label{display:block;line-height:1.3}#lasso--component__settings h3,#lasso--component__settings label{font-weight:700;margin-bottom:3px;font-size:14px}#lasso--component__settings .lasso-option-desc{margin-bottom:5px;font-size:11.25px}#lasso--component__settings input[type=text],#lasso--component__settings input[type=text_small],#lasso--component__settings input[type=media_upload],#lasso--component__settings select,#lasso--component__settings textarea{background:#f8f8f8;width:100%;height:30px;border:1px solid #181b1f;border-radius:4px;line-height:1.8;padding:0 6px;color:#444;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);font-size:14px}#lasso--component__settings input[type=text]:focus,#lasso--component__settings input[type=text_small]:focus,#lasso--component__settings input[type=media_upload]:focus,#lasso--component__settings select:focus,#lasso--component__settings textarea:focus{box-shadow:none;outline:0;border:1px solid #007aab}#lasso--component__settings input[type=color]{border-radius:3px;border:1px solid #181b1f;padding:0 2px;height:30px;display:block}#lasso--component__settings input[type=color]:active,#lasso--component__settings input[type=color]:focus{box-shadow:none;outline:0;border:1px solid #007aab}#lasso--component__settings select{height:30px;box-shadow:none}#lasso--component__settings textarea{overflow:auto;margin:0;line-height:1.15;padding:6px;height:auto}#lasso--component__settings input[type=media_upload]{height:30px}#lasso--component__settings .lasso-generator-cancel,#lasso--component__settings input[type=submit]{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:none;display:inline-block;font-family:Arial;color:#fff;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none;font-size:15px}#lasso--component__settings .lasso-generator-cancel:active,#lasso--component__settings .lasso-generator-cancel:focus,#lasso--component__settings input[type=submit]:active,#lasso--component__settings input[type=submit]:focus{outline:0}#lasso--component__settings .lasso-generator-cancel:hover,#lasso--component__settings input[type=submit]:hover{text-decoration:none;color:#fff;background:#005678}#lasso--component__settings .lasso-generator-cancel:active,#lasso--component__settings input[type=submit]:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--component__settings .lasso-option-button{position:absolute;bottom:21px;right:21px;background-color:#4b5661;border-color:#2c3238;-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.25);box-shadow:0 1px 1px rgba(0,0,0,.25)}#lasso--component__settings .lasso-option-button:hover{text-decoration:none;background:#3e474f}#lasso--component__settings .lasso-option-button:active,#lasso--component__settings .lasso-option-button:focus{outline:0;text-decoration:none;border-color:#21252a;background:#353c44;transition:none;-webkit-box-shadow:inset 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px rgba(0,0,0,.4)}#lasso--component__settings #lasso-upload-img{height:28px;padding:8px;border-top-right-radius:3px;border-bottom-right-radius:3px;font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#lasso--component__settings #lasso-upload-img:before{content:'\e9c6';position:relative;color:#f8f8f8}#lasso--component__settings .lasso-generator-cancel{background:0 0;color:#d9534f;position:relative;top:-1px}#lasso--component__settings .lasso-generator-cancel:hover{color:#db5b57;background:0 0;text-decoration:none}#lasso--component__settings .lasso-generator-cancel:active{color:#d74b47;box-shadow:none}.lasso-option{position:relative;border-bottom:1px solid #181b1f;margin:0;padding:15px 20px 20px;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.05);box-shadow:0 1px 1px rgba(255,255,255,.05);-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease}.lasso-option:after,.lasso-option:before{content:" ";display:table}.lasso-option:after{clear:both}.lasso-option:hover{background:rgba(53,60,68,.5)}.lasso-buttoninsert-wrap{display:none;margin:0 auto;position:fixed;text-align:right;padding:20px;bottom:0;width:281px;height:70px;background:#353c44;right:-289px;z-index:1;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:right .25s ease;-moz-transition:right .25s ease;transition:right .25s ease;-webkit-box-shadow:0 -10px 10px -10px #000;box-shadow:0 -10px 10px -10px #000}.lasso-buttoninsert-wrap:after,.lasso-buttoninsert-wrap:before{content:" ";display:table}.lasso-buttoninsert-wrap:after{clear:both}#lasso-generator-insert{text-align:center;float:right;display:block;margin:0 15px;padding:6px 10px;border-radius:2px;background:#007aab;border:1px solid #006892;color:#fff}#lasso-generator-insert:hover{text-decoration:none;background:#005678}#lasso-generator-insert:active,#lasso-generator-insert:focus{text-decoration:none;outline:0}#lasso-generator-insert:active{background:#00435e;-webkit-box-shadow:inset 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px rgba(0,0,0,.4)}#lasso-generator-insert.saved{background:#4da34d}.lasso-c-comp-text{position:absolute;right:-10000px;opacity:0;filter:alpha(opacity=0);height:0}#lasso--gallery__images{min-height:65px;position:relative}#lasso--gallery__images .lasso-icon-spinner6{position:relative;left:135px;top:18px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;font-size:16px}.editor-btn-secondary{background:#32373c;border:1px solid #181b1f;color:#e2e2e2;font-size:17px;line-height:1.8;padding:2px 12px 1px;text-decoration:none;display:inline-block;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.editor-btn-secondary:active,.editor-btn-secondary:visited{color:#e2e2e2}.editor-btn-secondary:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}.editor-btn-secondary:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.editor-btn-secondary.lasso--btn-loading:before{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}#ase-gallery-images{margin:0 -7px;border-radius:4px;padding:2px;-webkit-transition:background .15s ease;-moz-transition:background .15s ease;transition:background .15s ease}#ase-gallery-images:after,#ase-gallery-images:before{content:" ";display:table}#ase-gallery-images:after{clear:both}#ase-gallery-images .ui-state-highlight{height:1.5em;line-height:1.2em}.ase-gallery-image{position:relative;float:left;margin:4px;-webkit-transition:transform .1s ease;-moz-transition:transform .1s ease;transition:transform .1s ease;list-style:none}.ase-gallery-image i{top:3px;position:absolute;z-index:1;color:#fff;font-size:16px;text-shadow:0 1px 1px rgba(0,0,0,.5);opacity:.6;filter:alpha(opacity=60);-webkit-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease}.ase-gallery-image i:hover{cursor:pointer;opacity:1;filter:alpha(opacity=100);-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}.ase-gallery-image i:active{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);box-shadow:none}.ase-gallery-image .dashicons-edit{left:3px}.ase-gallery-image .dashicons-no-alt{right:2px}.ase-gallery-image img{max-width:54px;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.ase-gallery-image.ui-sortable-helper{-ms-transform:rotate(7deg);-webkit-transform:rotate(7deg);transform:rotate(7deg)}.ase-gallery-image:hover{cursor:move}.ase-gallery-image:hover img{opacity:.66;filter:alpha(opacity=66)}.ase-gallery-opts--edit-gallery:hover #ase-gallery-images{background:#181b1f;-webkit-box-shadow:inset 0 -1px 1px rgba(255,255,255,.1);box-shadow:inset 0 -1px 1px rgba(255,255,255,.1)}.lasso-editor-tiny-btn{font-size:10px;background:#181b1f;color:rgba(226,226,226,.8);border-radius:100%;font-weight:400;height:18px;width:18px;line-height:20px;text-align:center;text-shadow:1px 1px rgba(0,0,0,.1)}.lasso-editor-tiny-btn:active,.lasso-editor-tiny-btn:focus,.lasso-editor-tiny-btn:hover{outline:0;color:rgba(226,226,226,.8);text-decoration:none}.lasso-editor-tiny-btn:hover{color:rgba(226,226,226,.8);background:rgba(0,122,171,.8)}.lasso-editor-tiny-btn:active{color:rgba(226,226,226,.8);background:#007aab}#ase-gallery-add-image{position:absolute;right:12px;font-size:9px}.ase-gallery-drop-zone{border:1px solid #23282d;background:#353c44;color:#363636;width:54px;height:54px;float:left;margin:4px;border-radius:2px}#lasso--component__settings .ase-gallery-layout-label{font-size:12px}.ase-gallery-opts--type{position:relative}.ase-gallery-opts--type h3{margin:0}.ase-gallery-opts--type input[type=radio]{position:absolute;opacity:0;z-index:-1}.ase-gallery-opts--type .ase-gallery-layout-label{position:relative;float:left;height:68px;width:78px;overflow:hidden;text-align:center;background:#353c44;padding:5px;box-sizing:border-box;border:1px solid #181b1f;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease;opacity:.3;filter:alpha(opacity=30);margin-right:2px;font-weight:400}.ase-gallery-opts--type .ase-gallery-layout-label:last-of-type{margin-right:0!important}.ase-gallery-opts--type .ase-gallery-layout-label:after{content:'';background-image:url(../img/layout-sprite.png);background-size:84%;position:absolute;height:42px;display:block;left:0;right:0;bottom:0}.ase-gallery-opts--type .ase-gallery-layout-label:hover{opacity:1;filter:alpha(opacity=100);cursor:pointer}.ase-gallery-opts--type .ase-gallery-layout-label:active{background:#2c3238;-webkit-box-shadow:inset 0 0 6px -1px rgba(0,0,0,.5);box-shadow:inset 0 0 6px -1px rgba(0,0,0,.5)}.ase-gallery-opts--type .selected{-webkit-box-shadow:inset 0 0 12px -2px rgba(0,0,0,.5);box-shadow:inset 0 0 12px -2px rgba(0,0,0,.5);opacity:1;filter:alpha(opacity=100)}.ase-gallery-opts--type label:first-of-type:after{background-position:5px -9px}.ase-gallery-opts--type label:nth-of-type(2):after{background-position:5px -52px}.ase-gallery-opts--type label:nth-of-type(3):after{background-position:5px -99px}.ase-gallery-opts--type label:nth-of-type(4):after{background-position:5px -145px}.ase-gallery-opts--type label:nth-of-type(5):after{background-position:5px -191px}.ase-gallery-opts--type label:last-of-type:after{background-position:5px -470px}.ase-gallery-opts{-webkit-transition:opacity .25s ease;-moz-transition:opacity .25s ease;transition:opacity .25s ease}.lasso--empty-component{height:0;opacity:0;filter:alpha(opacity=0);text-align:center;color:#444;font-family:Arial;font-size:20px;-webkit-transition:all .2s linear;-moz-transition:all .2s linear;transition:all .2s linear}.lasso--empty-component span{position:relative;top:2px}.lasso-editing .aesop-gallery-component.empty-gallery .lasso-component--controls,.lasso-editing .lasso--empty-component+.aesop-map-component .lasso-component--controls{opacity:1;filter:alpha(opacity=100);left:0}.lasso-editing .lasso--empty-component{height:150px;padding-top:75px;opacity:1;filter:alpha(opacity=100)}#lasso--component__settings.gallery-no-images .ase-gallery-opts:not(.ase-gallery-opts--create-gallery){display:none}#lasso--component-settings-form.creating-gallery .lasso-option.lasso-gallery-id,#lasso--component-settings-form.has-galleries .ase-gallery-opts--create-gallery{display:none}#lasso--component-settings-form.hide-all-fields .ase-gallery-opts{opacity:0;filter:alpha(opacity=0)}#lasso--map-form{position:relative}#lasso--map-form .lasso--map-form__submit{position:absolute;top:10px;right:10px;z-index:100;background:#007aab;border:1px solid #0073a1;padding:8px 12px;font-size:14px;line-height:1.2;font-family:Arial;text-shadow:1px 1px rgba(0,0,0,.1);-webkit-box-shadow:0 0 5px -1px rgba(0,0,0,.4);box-shadow:0 0 5px -1px rgba(0,0,0,.4)}#lasso--map-form .lasso--map-form__submit:active,#lasso--map-form .lasso--map-form__submit:focus{outline:0}#lasso--map-form .lasso--map-form__submit:hover{background:#005678;border:1px solid #004e6e}#lasso--map-form .lasso--map-form__submit:active{box-shadow:none}#lasso--map-form{margin-top:10px}#lasso--map-form .leaflet-popup-content-wrapper,#lasso--map-form .leaflet-popup-tip{border-radius:4px}#lasso--map-form .leaflet-popup-content-wrapper input,#lasso--map-form .leaflet-popup-tip input{font-size:14px;border-radius:0;padding:3px 5px;width:200px;display:inline-block;line-height:1}#lasso--map-form .leaflet-popup-content{margin:10px}#lasso--map-form .leaflet-popup-close-button{position:absolute;left:-10000px;height:0}#lasso--map-form .marker-delete-button,#lasso--map-form .marker-update-button{color:#fff;box-shadow:none;border:none;border-radius:3px;display:inline-block;height:25px;width:25px;vertical-align:top;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;text-align:center}#lasso--map-form .marker-delete-button:hover,#lasso--map-form .marker-update-button:hover{cursor:pointer}#lasso--map-form .marker-delete-button:active,#lasso--map-form .marker-update-button:active{outline:0;focus:none;box-shadow:none}#lasso--map-form .marker-delete-button:before,#lasso--map-form .marker-update-button:before{position:relative;text-align:center}#lasso--map-form .marker-update-button{background:#007aab}#lasso--map-form .marker-update-button:hover{background:#00648c}#lasso--map-form .marker-update-button:active{background:#005678}#lasso--map-form .marker-update-button:before{top:1px;left:-1px;font-size:24px}#lasso--map-form .marker-delete-button{background:#d9534f}#lasso--map-form .marker-delete-button:hover{background:#d43a36}#lasso--map-form .marker-delete-button:active{background:#c9302c}#lasso--map-form .marker-delete-button:before{font-size:17px;top:1px;left:1px}.aesop-map-component .lasso-component--controls{width:91px}.aesop-map-component .lasso-component--controls .lasso-clone{display:none}.aesop-sticky-map #lasso--map-form .lasso-component--controls{position:fixed;z-index:999;width:61px}.aesop-sticky-map #lasso--map-form .lasso-component--controls .lasso-drag{display:none}.aesop-sticky-map.aesop-sticky-map-left #lasso--map-form .lasso-component--controls{left:183px;right:auto}.aesop-sticky-map.aesop-sticky-map-right #lasso--map-form .lasso-component--controls{right:183px;left:auto}#lasso--featImgControls{position:relative;z-index:1;left:0;right:0;text-align:center;top:5px;width:30px;height:26px;padding:0;margin:0 auto;font-size:15px;border-radius:2px;line-height:0;background-image:-webkit-linear-gradient(top,#353c44 0,#23282d 100%);background-image:-o-linear-gradient(top,#353c44 0,#23282d 100%);background-image:linear-gradient(to bottom,#353c44 0,#23282d 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff353c44', endColorstr='#ff23282d', GradientType=0);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}#lasso--featImgControls.lasso--featImg--has-thumb{width:60px}#lasso--featImgControls.lasso--featImg--has-thumb #lasso--featImgDelete{opacity:1;filter:alpha(opacity=100)}#lasso--featImgControls li{float:left;list-style-type:none;line-height:0;width:30px;height:26px;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,.4)}#lasso--featImgControls li i{font-style:normal;position:relative;top:5px}#lasso--featImgControls li:before{position:relative;top:3px;font-size:15px}#lasso--featImgControls li:hover{cursor:pointer;background:#39424a}#lasso--featImgControls li:active{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.4);box-shadow:inset 0 1px 1px rgba(0,0,0,.4)}#lasso--featImgControls #lasso--featImgSave,#lasso--featImgControls .lasso--featImg--controlHidden{position:absolute;left:-1000px;height:0;opacity:0;filter:alpha(opacity=0)}#lasso--featImgControls #lasso--featImgDelete{opacity:0;filter:alpha(opacity=0)}#lasso--featImgControls a{color:#fff;display:block}#lasso--featImgControls a:hover{text-decoration:none}.lasso--wpimg__wrap,.lasso--wpquote{position:relative}.lasso--wpimg__wrap:hover .lasso-component--controls,.lasso--wpquote:hover .lasso-component--controls{opacity:1;filter:alpha(opacity=100);left:0}.lasso--wpquote .lasso-component--controls{width:91px}.lasso--wpquote .lasso-component--controls #lasso-component--settings__trigger{position:absolute;left:-10000px;height:0;opacity:0;filter:alpha(opacity=0);display:none}.sweet-overlay{background-color:rgba(0,0,0,.4);position:fixed;left:0;right:0;top:0;bottom:0;display:none;z-index:1000}.sweet-alert{background-color:#1f2327;font-family:Arial;width:478px;padding:17px;border-radius:5px;text-align:center;position:fixed;left:50%;top:50%;margin-left:-256px;margin-top:-200px;overflow:hidden;display:none;z-index:2000;-webkit-box-shadow:0 0 10px 1px rgba(0,0,0,.5);box-shadow:0 0 10px 1px rgba(0,0,0,.5)}@media all and (max-width:540px){.sweet-alert{width:auto;margin-left:0;margin-right:0;left:15px;right:15px}}.sweet-alert h2{color:#e2e2e2;font-size:30px;text-align:center;font-weight:600;text-transform:none;position:relative;margin:25px 0;padding:0;line-height:40px;display:block;font-family:inherit}.sweet-alert p{color:#e2e2e2;font-size:16px;font-weight:300;position:relative;text-align:inherit;float:none;margin:0;padding:0;line-height:normal}.sweet-alert p~button{margin-bottom:20px}.sweet-alert button{background-color:#007aab;color:#fff;border:none;box-shadow:none;font-size:17px;font-family:Arial;font-weight:500;border-radius:5px;padding:10px 32px;margin:26px 5px 0;cursor:pointer}.sweet-alert button:focus{outline:0;box-shadow:0 0 2px rgba(128,179,235,.5),inset 0 0 0 1px rgba(0,0,0,.05)}.sweet-alert button:hover{background-color:#a1d9f2}.sweet-alert button:active{background-color:#81ccee}.sweet-alert button.cancel{background:0 0;color:#d9534f}.sweet-alert button.cancel:active,.sweet-alert button.cancel:hover{background:0 0}.sweet-alert button.cancel:focus{box-shadow:rgba(197,205,211,.8) 0 0 2px,rgba(0,0,0,.0470588) 0 0 0 1px inset!important}.sweet-alert button::-moz-focus-inner{border:0}.sweet-alert .icon{width:80px;height:80px;border:4px solid gray;border-radius:50%;margin:20px auto;padding:0;position:relative;box-sizing:content-box}.sweet-alert .icon.error{border-color:#d9534f}.sweet-alert .icon.error .x-mark{position:relative;display:block}.sweet-alert .icon.error .line{position:absolute;height:5px;width:47px;background-color:#d9534f;display:block;top:37px;border-radius:2px}.sweet-alert .icon.error .line.left{-webkit-transform:rotate(45deg);transform:rotate(45deg);left:17px}.sweet-alert .icon.error .line.right{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);right:16px}.sweet-alert .icon.warning{border-color:#d9534f}.sweet-alert .icon.warning .body{position:absolute;width:5px;height:47px;left:50%;top:10px;border-radius:2px;margin-left:-2px;background-color:#d9534f}.sweet-alert .icon.warning .dot{position:absolute;width:7px;height:7px;border-radius:50%;margin-left:-3px;left:50%;bottom:10px;background-color:#d9534f}.sweet-alert .icon.info{border-color:#007aab}.sweet-alert .icon.info::before{content:"";position:absolute;width:5px;height:29px;left:50%;bottom:17px;border-radius:2px;margin-left:-2px;background-color:#007aab}.sweet-alert .icon.info::after{content:"";position:absolute;width:7px;height:7px;border-radius:50%;margin-left:-3px;top:19px;background-color:#007aab}.sweet-alert .icon.success{border-color:#A5DC86}.sweet-alert .icon.success::after,.sweet-alert .icon.success::before{content:'';position:absolute;width:60px;height:120px;background:#fff;-webkit-transform:rotate(45deg)}.sweet-alert .icon.success::before{border-radius:120px 0 0 120px;top:-7px;left:-33px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:60px 60px;transform-origin:60px 60px}.sweet-alert .icon.success::after{border-radius:0 120px 120px 0;top:-11px;left:30px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:0 60px;transform-origin:0 60px}.sweet-alert .icon.success .placeholder{width:80px;height:80px;border:4px solid rgba(165,220,134,.2);border-radius:50%;box-sizing:content-box;position:absolute;left:-4px;top:-4px;z-index:2}.sweet-alert .icon.success .fix{width:5px;height:90px;background-color:#fff;position:absolute;left:28px;top:8px;z-index:1;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .icon.success .line{height:5px;background-color:#A5DC86;display:block;border-radius:2px;position:absolute;z-index:2}.sweet-alert .icon.success .line.tip{width:25px;left:14px;top:46px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.sweet-alert .icon.success .line.long{width:47px;right:8px;top:38px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.sweet-alert .icon.custom{background-size:contain;border-radius:0;border:none;background-position:center center;background-repeat:no-repeat}.sweet-alert[data-has-cancel-button=false] button{box-shadow:none!important}@-webkit-keyframes showSweetAlert{0%{transform:scale(.7);-webkit-transform:scale(.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-moz-keyframes showSweetAlert{0%{transform:scale(.7);-webkit-transform:scale(.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes showSweetAlert{0%{transform:scale(.7);-webkit-transform:scale(.7)}100%{transform:scale(1);-webkit-transform:scale(1)}}@-webkit-keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}@-moz-keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}@keyframes hideSweetAlert{0%{transform:scale(1);-webkit-transform:scale(1)}100%{transform:scale(.5);-webkit-transform:scale(.5)}}.showSweetAlert{-webkit-animation:showSweetAlert .2s;-moz-animation:showSweetAlert .2s;animation:showSweetAlert .2s}.hideSweetAlert{-webkit-animation:hideSweetAlert .2s;-moz-animation:hideSweetAlert .2s;animation:hideSweetAlert .2s}.animateSuccessTip{-webkit-animation:animateSuccessTip .75s;-moz-animation:animateSuccessTip .75s;animation:animateSuccessTip .75s}.animateSuccessLong{-webkit-animation:animateSuccessLong .75s;-moz-animation:animateSuccessLong .75s;animation:animateSuccessLong .75s}.icon.success.animate::after{-webkit-animation:rotatePlaceholder 4.25s ease-in;-moz-animation:rotatePlaceholder 4.25s ease-in;animation:rotatePlaceholder 4.25s ease-in}.lasso-util--help{position:relative;cursor:pointer;color:#007aab;display:inline-block;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease;opacity:.75;filter:alpha(opacity=75)}.lasso-util--help:hover{text-decoration:none;opacity:1;filter:alpha(opacity=100)}.lasso-util--help:after,.lasso-util--help:before{position:absolute;visibility:hidden;opacity:0;filter:alpha(opacity=0);-webkit-transition:opacity .2s ease-in-out,visibility .2s ease-in-out,-webkit-transform .2s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .2s ease-in-out,visibility .2s ease-in-out,-moz-transform .2s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .2s ease-in-out,visibility .2s ease-in-out,transform .2s cubic-bezier(.71,1.7,.77,1.24);-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translate3d(0,0,0);pointer-events:none}.lasso-util--help:focus:after,.lasso-util--help:focus:before,.lasso-util--help:hover:after,.lasso-util--help:hover:before{visibility:visible;opacity:1;filter:alpha(opacity=100)}.lasso-util--help:before{z-index:1001;border:6px solid transparent;background:0 0;content:""}.lasso-util--help:after{z-index:1000;padding:8px;width:160px;background-color:rgba(0,122,171,.95);color:#e2e2e2;font-family:Arial;content:attr(data-tooltip);font-size:12px;line-height:1.2;border-radius:2px}.lasso-util--help-top:after,.lasso-util--help-top:before,.lasso-util--help:after,.lasso-util--help:before{bottom:100%;left:50%}.lasso-util--help-top:before,.lasso-util--help:before{margin-left:-6px;margin-bottom:-12px;border-top-color:rgba(0,122,171,.95)}.lasso-util--help-top:after,.lasso-util--help:after{margin-left:-80px}.lasso-util--help-top:focus:after,.lasso-util--help-top:focus:before,.lasso-util--help-top:hover:after,.lasso-util--help-top:hover:before,.lasso-util--help:focus:after,.lasso-util--help:focus:before,.lasso-util--help:hover:after,.lasso-util--help:hover:before{-webkit-transform:translateY(-12px);-moz-transform:translateY(-12px);transform:translateY(-12px)}.lasso-util--help-left:after,.lasso-util--help-left:before{right:100%;bottom:50%;left:auto}.lasso-util--help-left:before{margin-left:0;margin-right:-12px;margin-bottom:0;border-top-color:transparent;border-left-color:rgba(0,122,171,.95)}.lasso-util--help-left:focus:after,.lasso-util--help-left:focus:before,.lasso-util--help-left:hover:after,.lasso-util--help-left:hover:before{-webkit-transform:translateX(-12px);-moz-transform:translateX(-12px);transform:translateX(-12px)}.lasso-util--help-bottom:after,.lasso-util--help-bottom:before{top:100%;bottom:auto;left:50%}.lasso-util--help-bottom:before{margin-top:-12px;margin-bottom:0;border-top-color:transparent;border-bottom-color:rgba(0,122,171,.95)}.lasso-util--help-bottom:focus:after,.lasso-util--help-bottom:focus:before,.lasso-util--help-bottom:hover:after,.lasso-util--help-bottom:hover:before{-webkit-transform:translateY(12px);-moz-transform:translateY(12px);transform:translateY(12px)}.lasso-util--help-right:after,.lasso-util--help-right:before{bottom:50%;left:100%}.lasso-util--help-right:before{margin-bottom:0;margin-left:-12px;border-top-color:transparent;border-right-color:rgba(0,122,171,.95)}.lasso-util--help-right:focus:after,.lasso-util--help-right:focus:before,.lasso-util--help-right:hover:after,.lasso-util--help-right:hover:before{-webkit-transform:translateX(12px);-moz-transform:translateX(12px);transform:translateX(12px)}.lasso-util--help-left:before,.lasso-util--help-right:before{top:3px}.lasso-util--help-left:after,.lasso-util--help-right:after{margin-left:0;margin-bottom:-16px}.story-categories-option .tagit,.story-tags-option .tagit{padding:4px 0 0;overflow:auto;margin-left:inherit;margin-right:inherit;border-radius:3px;list-style:none}.story-categories-option .tagit li,.story-tags-option .tagit li{float:left}.story-categories-option .tagit li.tagit-choice,.story-tags-option .tagit li.tagit-choice{position:relative;margin:2px;display:inline;padding:4px 8px 4px 18px;font-family:Arial;font-size:12px;line-height:16px;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:2px;background:#32373c}.story-categories-option .tagit li .tagit-close,.story-tags-option .tagit li .tagit-close{cursor:pointer;position:absolute;left:7px;color:#fff;top:5px}.story-categories-option .tagit li .tagit-close:hover,.story-tags-option .tagit li .tagit-close:hover{text-decoration:none;color:#fff}.story-categories-option .tagit li.tagit-new,.story-tags-option .tagit li.tagit-new{position:relative;top:-6px}.story-categories-option .tagit li input[type=text],.story-tags-option .tagit li input[type=text]{box-shadow:none;border:none;border-radius:0;padding:0 0 0 4px;width:inherit;background-color:inherit;outline:0;font-size:12px;line-height:24px;display:inline-block;margin:2px 5px 2px 0;color:rgba(255,255,255,.5)}.story-categories-option input.tagit-hidden-field,.story-tags-option input.tagit-hidden-field{display:none}.story-categories-option ul.tagit li.tagit-choice a.tagit-label,.story-tags-option ul.tagit li.tagit-choice a.tagit-label{cursor:pointer;text-decoration:none}.story-categories-option{border-bottom:none;box-shadow:none;margin-bottom:0}.story-tags-option .tagit li.tagit-choice{position:relative;margin:2px 2px 2px 15px;padding:4px 8px 4px 12px;border-top-left-radius:0;border-bottom-left-radius:0}.story-tags-option .tagit li.tagit-choice:before{content:'';position:absolute;width:0;height:0;border-top:12px solid transparent;border-bottom:12px solid transparent;border-right:14px solid #32373c;left:-14px;top:0}.story-tags-option .tagit li.tagit-choice .tagit-close{left:0}.lasso-modal-open .ui-autocomplete{position:absolute;top:100%;left:0;z-index:9999;float:left;display:none;min-width:160px;padding:4px;margin:2px 0 0;list-style:none;color:#fff;background-color:#32373c;border-radius:3px;box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.lasso-modal-open .ui-autocomplete .ui-menu-item{display:block;padding:1px 2px;clear:both;font-weight:400;line-height:18px;color:#fff;white-space:nowrap;font-family:Arial;font-size:14px}.lasso-modal-open .ui-autocomplete .ui-menu-item.ui-state-active,.lasso-modal-open .ui-autocomplete .ui-menu-item:hover{cursor:pointer;background:#222529}.lasso--tour__modal .lasso--postsettings__footer:after,.lasso--tour__modal .lasso--postsettings__footer:before{content:" ";display:table}.lasso--tour__modal .lasso--postsettings__footer:after{clear:both}.lasso--tour__modal .lasso--modal__inner{position:relative}.lasso--tour__modal .lasso--postsettings__option{border-bottom:none;box-shadow:none;padding-bottom:0;margin-bottom:0;float:left;top:4px;position:relative;opacity:.85;filter:alpha(opacity=85)}.lasso--tour__modal .lasso--postsettings__option label{padding-left:23px;font-size:14px;font-weight:400}.lasso--tour__modal .lasso--postsettings__option .control-indicator{width:14px;height:14px;top:0}.lasso--tour__modal #lasso--tour__slides{position:relative;overflow:auto;display:none}.lasso--tour__modal ul{margin:0;padding:0;list-style:none}.lasso--tour__modal ul:after,.lasso--tour__modal ul:before{content:" ";display:table}.lasso--tour__modal ul:after{clear:both}.lasso--tour__modal ul li{float:left}.lasso--tour__modal li img{background:#0d0e10;padding:6px;border-radius:3px;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.1);box-shadow:0 1px 1px rgba(255,255,255,.1)}.lasso--tour__modal li p{font-family:Arial;font-size:16px;line-height:1.25;margin:15px auto 28px;padding-right:4px;padding-left:4px}.lasso--tour__modal .dots{position:absolute;left:0;right:0;bottom:-10px;text-align:center;width:100%;margin:0}.lasso--tour__modal .dots li{display:inline-block;width:14px;height:14px;line-height:16px;margin:0 3px;text-indent:-999em;border:1px solid #0d0e10;background:#32373c;border-radius:100%;cursor:pointer;opacity:.4;filter:alpha(opacity=40);-webkit-transition:background .5s,opacity .5s;-moz-transition:background .5s,opacity .5s;transition:background .5s,opacity .5s;-webkit-box-shadow:0 1px 1px rgba(255,255,255,.1);box-shadow:0 1px 1px rgba(255,255,255,.1)}.lasso--tour__modal .dots li.active{background:rgba(0,122,171,.75);opacity:1}.lasso--tour__modal input[type=submit]{text-align:center;margin:0 0 0 15px;border-radius:2px;background:#007aab;border:none;display:inline-block;font-family:Arial;color:#fff;font-size:17px;line-height:1.8;padding:2px 12px 1px;-webkit-appearance:none}.lasso--tour__modal input[type=submit]:active,.lasso--tour__modal input[type=submit]:focus{outline:0}.lasso--tour__modal input[type=submit]:hover{text-decoration:none;color:#fff;background:#005678}.lasso--tour__modal input[type=submit]:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}.lasso--loading{height:auto;left:0;top:0;right:0;width:100%}.lasso--loader{height:40px;width:40px;margin:10px auto;top:48%;position:relative;-webkit-animation:rotation .6s infinite linear;-moz-animation:rotation .6s infinite linear;-o-animation:rotation .6s infinite linear;animation:rotation .6s infinite linear;border-left:3px solid rgba(96,106,116,.2);border-right:3px solid rgba(96,106,116,.2);border-bottom:3px solid rgba(96,106,116,.2);border-top:3px solid #606a74;border-radius:100%}@-webkit-keyframes rotation{from{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes rotation{from{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@-o-keyframes rotation{from{-o-transform:rotate(0deg)}to{-o-transform:rotate(359deg)}}@keyframes rotation{from{transform:rotate(0deg)}to{transform:rotate(359deg)}}.lasso--modal{top:10vh}.lasso--modal.lasso--modal__full{width:100%;max-width:800px}.lasso--modal.lasso--modal__full .lasso--modal__inner{display:block;padding:36px}.lasso--modal.lasso--modal__full .lasso--modal__inner:after,.lasso--modal.lasso--modal__full .lasso--modal__inner:before{content:" ";display:table}.lasso--modal.lasso--modal__full .lasso--modal__inner:after{clear:both}#lasso--all-posts__modal #lasso--loading{position:absolute;height:90%}ul.lasso--post-list,ul.lasso--post-object-list{text-align:left;list-style:none;margin:0;padding:0}ul.lasso--post-list li,ul.lasso--post-object-list li{display:block;position:relative;width:100%;list-style-type:none;margin-bottom:7px;font-size:14px;font-family:Arial;font-weight:700}ul.lasso--post-object-list{width:100px;float:left;height:100%}ul.lasso--post-object-list li{line-height:25px;margin-bottom:0;font-family:Arial;font-weight:400;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}ul.lasso--post-object-list li:not(.active){opacity:.45;filter:alpha(opacity=45)}ul.lasso--post-object-list li:hover{cursor:pointer;opacity:1;filter:alpha(opacity=100)}.lasso--post-filtering{padding:0 18px;width:calc(100% - 100px);height:42px;float:right}.lasso--post-filtering:after,.lasso--post-filtering:before{content:" ";display:table}.lasso--post-filtering:after{clear:both}.lasso--post-filtering .lasso--search,.lasso--post-filtering .lasso--search__results{float:left}.lasso--post-filtering .lasso--search__results{opacity:0;-webkit-transition:opacity .2s ease;-moz-transition:opacity .2s ease;transition:opacity .2s ease;width:60%;font-size:15px}.lasso--post-filtering .lasso--search__results span{font-weight:700;margin-right:4px}.lasso--post-filtering .lasso--search{width:40%;overflow:hidden;position:relative}.lasso--post-filtering .lasso--search #lasso--search__toggle,.lasso--post-filtering .lasso--search input{-webkit-transition:right .15s linear;-moz-transition:right .15s linear;transition:right .15s linear}.lasso--post-filtering .lasso--search #lasso--search__toggle{position:relative;top:7.5px;right:-209px}.lasso--post-filtering .lasso--search #lasso--search__toggle:before{opacity:.5;filter:alpha(opacity=50);-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}.lasso--post-filtering .lasso--search #lasso--search__toggle:hover{cursor:pointer}.lasso--post-filtering .lasso--search #lasso--search__toggle:hover:before{opacity:.9;filter:alpha(opacity=90)}.lasso--post-filtering .lasso--search input{float:right;width:194px;right:-194px;background-color:#f8f8f8!important;padding:2px 8px 2px 6px;background:0 0;border:1px solid #181b1f;color:#444;font-size:14px;z-index:0;position:relative;border-radius:4px;-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);box-shadow:inset 1px 1px 1px rgba(0,0,0,.4);height:32px}.lasso--post-filtering .lasso--search input:focus{outline:0;border:1px solid #007aab;border-radius:2px;box-shadow:none}.lasso--post-filtering .lasso--search.lasso--search__visible #lasso--search__toggle{right:-15px}.lasso--post-filtering .lasso--search.lasso--search__visible #lasso--search__toggle:before{opacity:.9;filter:alpha(opacity=90)}.lasso--post-filtering .lasso--search.lasso--search__visible #lasso--search__toggle:hover:before{opacity:.5;filter:alpha(opacity=50)}.lasso--post-filtering .lasso--search.lasso--search__visible input{right:0}#lasso--helper{position:absolute;right:4px;top:4px;font-size:12px;padding:2px 6px;background:#32373c;color:#fff;border-radius:2px;font-family:Arial}#lasso--clear-search{position:absolute;right:7px;top:7px;color:#c9c9c9;z-index:1}#lasso--clear-search:hover{color:#bcbcbc;cursor:pointer}.lasso--empty-state{max-width:200px;text-align:center;color:#737679;margin:0 auto;top:40%;position:relative}.lasso--empty-state .lasso--empty-state-icon{font-size:50px}.lasso--empty-state p{margin-bottom:0;font-family:Arial;font-size:90%;font-weight:700}.lasso--empty-state p+a{margin-top:10px}ul.lasso--post-list{float:left;padding:0 18px;width:calc(100% - 100px);overflow:hidden;position:relative;height:520px;border-left:1px solid #181b1f;-webkit-box-shadow:inset 1px 0 1px -1px rgba(255,255,255,.15);box-shadow:inset 1px 0 1px -1px rgba(255,255,255,.15)}ul.lasso--post-list li{overflow:hidden;line-height:50px}ul.lasso--post-list .lasso--post-list__item{color:#c9c9c9;display:block;padding:0 15px;background:rgba(50,55,60,.88);text-decoration:none;border-radius:4px;-webkit-transition:all .15s ease;-moz-transition:all .15s ease;transition:all .15s ease;font-family:Arial;font-weight:400;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}ul.lasso--post-list .lasso--post-list__item:before{content:'';height:8px;width:8px;border-radius:100%;margin-right:8px;display:inline-block}ul.lasso--post-list .lasso--post-list__item.draft:before{background:#f0ad4e}ul.lasso--post-list .lasso--post-list__item.publish:before{background:#4da34d}ul.lasso--post-list .lasso--post-list__item.pending:before{background:#007aab}ul.lasso--post-list .lasso--post-list__item:hover{background:#32373c;text-decoration:none;width:calc(100% - 115px)}ul.lasso--post-list .lasso--post-list__item:hover .lasso--post-list__controls{right:0}ul.lasso--post-list .lasso--post-list__item:active{outline:0;background:#32373c;text-decoration:none;-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.5);box-shadow:inset 1px 1px 2px rgba(0,0,0,.5)}ul.lasso--post-list .lasso--post-list__item:focus{outline:0}ul.lasso--post-list .lasso--post-list__item.no-delete:hover{width:calc(100% - 57.5px)}.lasso--post-list__controls{position:absolute;top:0;width:115px;text-align:right;right:-115px;height:50px;-webkit-transition:right .15s ease;-moz-transition:right .15s ease;transition:right .15s ease}.lasso--post-list__controls span{color:#626262;display:inline-block;width:50px;height:50px;background:#32373c;border-radius:4px;position:relative}.lasso--post-list__controls span:after{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;font-size:18px;position:absolute;z-index:2;top:16px;left:16px}.lasso--post-list__controls span:hover{color:#626262;background:rgba(50,55,60,.5)}.lasso--post-list__controls span:active{background:#32373c;text-decoration:none;-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.5);box-shadow:inset 1px 1px 2px rgba(0,0,0,.5)}.lasso--post-list__controls #lasso--post__edit{margin-right:3px}.lasso--post-list__controls #lasso--post__edit:hover{color:#e2e2e2;background:#007aab}.lasso--post-list__controls #lasso--post__edit:after{content:'\e908'}.lasso--post-list__controls #lasso--post__delete:hover{color:#e2e2e2;background:#d9534f}.lasso--post-list__controls #lasso--post__delete:after{content:'\e9ad'}#lasso--load-more{background:#32373c;border:1px solid #181b1f;color:#e2e2e2;padding:2px 12px 1px;text-decoration:none;display:inline-block;border-radius:2px;-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease;font-size:15px;text-transform:uppercase;line-height:2;margin-top:10px;opacity:.66;filter:alpha(opacity=66)}#lasso--load-more:active,#lasso--load-more:visited{color:#e2e2e2}#lasso--load-more:hover{opacity:1;filter:alpha(opacity=100);color:#e2e2e2;text-decoration:none}#lasso--load-more:active{-webkit-box-shadow:inset 1px 1px 2px rgba(0,0,0,.4);box-shadow:inset 1px 1px 2px rgba(0,0,0,.4)}#lasso--load-more.lasso--btn-loading:before{font-family:icomoon;display:inline-block;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:'\e97f';margin-right:10px;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear}#lasso--revision__modal{-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}#lasso--revision__modal .lasso--slider_wrap{padding:0 16px;margin-top:18px}#lasso--revision__modal .lasso--btn-group .lasso--btn-secondary{opacity:.7;filter:alpha(opacity=70);-webkit-transition:opacity .15s ease;-moz-transition:opacity .15s ease;transition:opacity .15s ease}#lasso--revision__modal .lasso--btn-group .lasso--btn-secondary:hover{opacity:1;filter:alpha(opacity=100)}#lasso--revision__modal .lasso-icon-move{position:absolute;top:15px;right:15px;color:#747474;font-size:14px}#lasso--revision__modal .lasso-icon-move:hover{cursor:move}#lasso--revision-list{margin:0 0 10px;padding:0;list-style:none;text-align:center;width:110%;left:-5%;position:relative;top:-3px}#lasso--revision-list:after,#lasso--revision-list:before{content:" ";display:table}#lasso--revision-list:after{clear:both}#lasso--revision-list li{padding:12px 0 0;display:inline-block;font-family:Arial;font-size:11px;color:#c9c9c9;text-transform:uppercase;line-height:13px;margin:0 auto;position:relative}#lasso--revision-list li span{color:#c9c9c9}#lasso--revision-list li:first-child{margin-left:0}#lasso--revision-list li:last-child{margin-right:0}#lasso--revision-list li:before{content:'';height:5px;border-right:1px solid #747474;width:1px;position:absolute;top:0;left:0;right:0;text-align:center;margin:0 auto}#lasso--revision-list[data-count="6"] li{width:16.666666%}#lasso--revision-list[data-count="6"] li[data-revision="0"],#lasso--revision-list[data-count="6"] li[data-revision="1"]{left:2px}#lasso--revision-list[data-count="6"] li[data-revision="5"]{right:-1px}#lasso--revision-list[data-count="6"] li[data-revision="6"]{right:6px}#lasso--revision-list[data-count="5"] li{width:20%}#lasso--revision-list[data-count="5"] li[data-revision="0"]{left:-4px}#lasso--revision-list[data-count="5"] li[data-revision="1"]{left:-2px}#lasso--revision-list[data-count="5"] li[data-revision="2"]{left:0}#lasso--revision-list[data-count="5"] li[data-revision="3"]{right:-2px}#lasso--revision-list[data-count="5"] li[data-revision="4"]{right:-4px}#lasso--revision-list[data-count="4"] li{width:25%}#lasso--revision-list[data-count="4"] li[data-revision="0"]{left:-15px}#lasso--revision-list[data-count="4"] li[data-revision="1"]{left:-4px}#lasso--revision-list[data-count="4"] li[data-revision="2"]{right:-4px}#lasso--revision-list[data-count="4"] li[data-revision="3"]{right:-15px}#lasso--revision-list[data-count="3"] li{width:33.333%}#lasso--revision-list[data-count="3"] li[data-revision="0"]{left:-29px}#lasso--revision-list[data-count="3"] li[data-revision="1"]{left:0}#lasso--revision-list[data-count="3"] li[data-revision="2"]{right:-29px}#lasso--revision-list[data-count="2"] li{width:50%}#lasso--revision-list[data-count="2"] li[data-revision="0"]{left:-60px}#lasso--revision-list[data-count="2"] li[data-revision="1"]{right:-60px}.os-ios .lasso-component--controls{opacity:1;filter:alpha(opacity=100);left:0}@media (max-width:600px){.lasso-editing .lasso--toolbar_wrap,.lasso-editing .lasso--toolbar_wrap.ase-not-active,.lasso-editing .lasso--toolbar_wrap.ase-not-active.toolbar-extended,.lasso-editing .lasso--toolbar_wrap.toolbar-extended{border-radius:0;top:0;width:100%;left:0;right:0;-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0);height:auto;bottom:auto}.lasso-editing .lasso--controls__right{z-index:1000;top:auto;right:0}.lasso-editing .lasso--controls__right #lasso--save,.lasso-editing .lasso--controls__right a{background:0 0}.lasso-editing .lasso--controls__right #lasso--save:before{color:#007aab;top:3px}.lasso-editing #lasso-toolbar--html.html--drop-down,.lasso-editing #lasso-toolbar--link.link--drop-down{position:static}.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap,.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--link__wrap,.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--html__wrap,.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap{left:0;right:0;top:44px;bottom:auto;width:90%}.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after,.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--link__wrap:after,.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--html__wrap:after,.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after{margin:0;top:-6px;border-top:none;border-bottom:6px solid #39424a}.lasso-editing #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after{left:142px}.lasso-editing #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after{left:175px}.lasso-editing #lasso-toolbar--components.toolbar--drop-down{position:static}.lasso-editing #lasso-toolbar--components.toolbar--drop-down ul{top:44px;left:0;right:0;width:100%}.lasso-editing #lasso-toolbar--components.toolbar--drop-down ul:after{left:206px;margin:0;top:-6px;border-top:none;border-bottom:6px solid #39424a}.lasso-editing .toolbar-extended #lasso-toolbar--link.link--drop-down #lasso-toolbar--link__wrap:after{left:222px}.lasso-editing .toolbar-extended #lasso-toolbar--html.html--drop-down #lasso-toolbar--html__wrap:after{left:255px}.lasso-editing .toolbar-extended #lasso-toolbar--components.toolbar--drop-down ul:after{left:288px}#lasso--all-posts__modal ul.lasso--post-list,#lasso--all-posts__modal ul.lasso--post-object-list{float:none;width:100%;display:block}#lasso--all-posts__modal ul.lasso--post-object-list{margin-bottom:20px;padding-bottom:10px;border-bottom:1px solid #181b1f;-webkit-box-shadow:0 1px 1px -1px rgba(255,255,255,.15);box-shadow:0 1px 1px -1px rgba(255,255,255,.15)}#lasso--all-posts__modal ul.lasso--post-object-list li{display:inline-block;width:auto;margin-right:20px;font-size:90%}#lasso--all-posts__modal ul.lasso--post-list{padding-left:0;border:none;box-shadow:none}.lasso--modal{display:block}.lasso--modal .lasso--modal__inner,.lasso--modal.lasso--modal__full .lasso--modal__inner{border-radius:0;padding:10px}}@media (min-width:601px){.lasso-mobile #lasso-toolbar--html__wrap:after,.lasso-mobile #lasso-toolbar--link__wrap:after,.lasso-mobile .toolbar--drop-up ul:after{margin:0;top:-9px;border-top:none;border-bottom:6px solid #39424a}} ================================================ FILE: public/assets/js/editus-table-edit-public.js ================================================ jQuery(document).ready(function($){ 'use strict'; if (typeof lasso_editor !== 'undefined') { // JAVASCRIPT (jQuery) var enable = false; var table; var tableWidth; var col; var row; if (lasso_editor.enterEditorHookArray) { lasso_editor.enterEditorHookArray.push(whenEnterEditor); } else { lasso_editor.enterEditorHookArray = [whenEnterEditor]; } if (lasso_editor.exitEditorHookArray) { lasso_editor.exitEditorHookArray.push(whenExitEditor); } else { lasso_editor.exitEditorHookArray = [whenExitEditor]; } // Trigger action when the contexmenu is about to be shown $(document).bind("contextmenu", function (event) { if (enable && (event.target.nodeName =="TH" || event.target.nodeName =="TD" )) { // Avoid the real one event.preventDefault(); var cell = event.target; table = cell.parentNode.parentNode; tableWidth = $(table).find("tr:first td").length; col = $(cell).parent().children().index($(cell)); row = $(cell).parent().parent().children().index($(cell).parent()); if (!tableWidth) { tableWidth = $(table).find("tr:first th").length; } // Show contextmenu $(".editus-table-menu").finish().toggle(100). // In the right position (the mouse) css({ top: event.pageY + "px", left: event.pageX + "px" }); // If the menu element is clicked $(".editus-table-menu li").on('click',function(){ // This is the triggered action name if (!table) return; switch($(this).attr("data-action")) { // A case for each action. Your actions here case "insertcol": addColumn(col); break; case "insertrow": addRow(row); break; case "delcol": deleteColumn(col); break; case "delrow": deleteRow(row); break; case "deltable": deleteTable(); break; } articleMedium.makeUndoable(); table = 0; // Hide it AFTER the action was triggered $(".custom-menu").hide(100); }); } }); // If the document is clicked somewhere $(document).bind("mousedown", function (e) { // If the clicked element is not the menu if (!$(e.target).parents(".editus-table-menu").length > 0) { // Hide it $(".editus-table-menu").hide(100); } }); function addColumn(n) { $(table).find('tr').each(function(){ //$("tr").each(function() { $(this).find('th').eq(n).after('new cell added'); $(this).find('td').eq(n).after('new cell added'); }); tableWidth = $(table).find("tr:first td").length; } function addRow(n) { var str = ''; for (var i =0; i15) { this.commands.shift(); } else { this.stackPosition++; } this.changed(); }, undo: function() { this.commands[this.stackPosition].undo(); this.stackPosition--; //this.commands.pop(); this.changed(); }, canUndo: function() { return this.stackPosition >= 0; }, redo: function() { this.stackPosition++; this.commands[this.stackPosition].redo(); this.changed(); }, canRedo: function() { return this.stackPosition < this.commands.length - 1; }, save: function() { this.savePosition = this.stackPosition; this.changed(); }, dirty: function() { return (this.stackPosition != this.savePosition) || lasso_editor.dirtyByComponent; }, _clearRedo: function() { // TODO there's probably a more efficient way for this this.commands = this.commands.slice(0, this.stackPosition + 1); }, changed: function() { // do nothing, override } }); Undo.Command = function(name) { this.name = name; } var up = new Error("override me!"); extend(Undo.Command.prototype, { execute: function() { throw up; }, undo: function() { throw up; }, redo: function() { this.execute(); } }); Undo.Command.extend = function(protoProps) { var child = inherits(this, protoProps); child.extend = Undo.Command.extend; return child; }; }).call(this); /** * Rangy, a cross-browser JavaScript range and selection library * http://code.google.com/p/rangy/ * * Copyright 2014, Tim Down * Licensed under the MIT license. * Version: 1.3.0-alpha.20140827 * Build date: 27 August 2014 */ (function(factory, root) { if (typeof define == "function" && define.amd) { // AMD. Register as an anonymous module. define(factory); } else if (typeof module != "undefined" && typeof exports == "object") { // Node/CommonJS style module.exports = factory(); } else { // No AMD or CommonJS support so we place Rangy in (probably) the global variable root.rangy = factory(); } })(function() { var OBJECT = "object", FUNCTION = "function", UNDEFINED = "undefined"; // Minimal set of properties required for DOM Level 2 Range compliance. Comparison constants such as START_TO_START // are omitted because ranges in KHTML do not have them but otherwise work perfectly well. See issue 113. var domRangeProperties = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed", "commonAncestorContainer"]; // Minimal set of methods required for DOM Level 2 Range compliance var domRangeMethods = ["setStart", "setStartBefore", "setStartAfter", "setEnd", "setEndBefore", "setEndAfter", "collapse", "selectNode", "selectNodeContents", "compareBoundaryPoints", "deleteContents", "extractContents", "cloneContents", "insertNode", "surroundContents", "cloneRange", "toString", "detach"]; var textRangeProperties = ["boundingHeight", "boundingLeft", "boundingTop", "boundingWidth", "htmlText", "text"]; // Subset of TextRange's full set of methods that we're interested in var textRangeMethods = ["collapse", "compareEndPoints", "duplicate", "moveToElementText", "parentElement", "select", "setEndPoint", "getBoundingClientRect"]; /*----------------------------------------------------------------------------------------------------------------*/ // Trio of functions taken from Peter Michaux's article: // http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting function isHostMethod(o, p) { var t = typeof o[p]; return t == FUNCTION || (!!(t == OBJECT && o[p])) || t == "unknown"; } function isHostObject(o, p) { return !!(typeof o[p] == OBJECT && o[p]); } function isHostProperty(o, p) { return typeof o[p] != UNDEFINED; } // Creates a convenience function to save verbose repeated calls to tests functions function createMultiplePropertyTest(testFunc) { return function(o, props) { var i = props.length; while (i--) { if (!testFunc(o, props[i])) { return false; } } return true; }; } // Next trio of functions are a convenience to save verbose repeated calls to previous two functions var areHostMethods = createMultiplePropertyTest(isHostMethod); var areHostObjects = createMultiplePropertyTest(isHostObject); var areHostProperties = createMultiplePropertyTest(isHostProperty); function isTextRange(range) { return range && areHostMethods(range, textRangeMethods) && areHostProperties(range, textRangeProperties); } function getBody(doc) { return isHostObject(doc, "body") ? doc.body : doc.getElementsByTagName("body")[0]; } var modules = {}; var isBrowser = (typeof window != UNDEFINED && typeof document != UNDEFINED); var util = { isHostMethod: isHostMethod, isHostObject: isHostObject, isHostProperty: isHostProperty, areHostMethods: areHostMethods, areHostObjects: areHostObjects, areHostProperties: areHostProperties, isTextRange: isTextRange, getBody: getBody }; var api = { version: "1.3.0-alpha.20140827", initialized: false, isBrowser: isBrowser, supported: true, util: util, features: {}, modules: modules, config: { alertOnFail: true, alertOnWarn: false, preferTextRange: false, autoInitialize: (typeof rangyAutoInitialize == UNDEFINED) ? true : rangyAutoInitialize } }; function consoleLog(msg) { if (typeof console != UNDEFINED && isHostMethod(console, "log")) { console.log(msg); } } function alertOrLog(msg, shouldAlert) { if (isBrowser && shouldAlert) { alert(msg); } else { consoleLog(msg); } } function fail(reason) { api.initialized = true; api.supported = false; alertOrLog("Rangy is not supported in this environment. Reason: " + reason, api.config.alertOnFail); } api.fail = fail; function warn(msg) { alertOrLog("Rangy warning: " + msg, api.config.alertOnWarn); } api.warn = warn; // Add utility extend() method var extend; if ({}.hasOwnProperty) { util.extend = extend = function(obj, props, deep) { var o, p; for (var i in props) { if (props.hasOwnProperty(i)) { o = obj[i]; p = props[i]; if (deep && o !== null && typeof o == "object" && p !== null && typeof p == "object") { extend(o, p, true); } obj[i] = p; } } // Special case for toString, which does not show up in for...in loops in IE <= 8 if (props.hasOwnProperty("toString")) { obj.toString = props.toString; } return obj; }; util.createOptions = function(optionsParam, defaults) { var options = {}; extend(options, defaults); if (optionsParam) { extend(options, optionsParam, true); } return options; }; } else { fail("hasOwnProperty not supported"); } // Test whether we're in a browser and bail out if not if (!isBrowser) { fail("Rangy can only run in a browser"); } // Test whether Array.prototype.slice can be relied on for NodeLists and use an alternative toArray() if not (function() { var toArray; if (isBrowser) { var el = document.createElement("div"); el.appendChild(document.createElement("span")); var slice = [].slice; try { if (slice.call(el.childNodes, 0)[0].nodeType == 1) { toArray = function(arrayLike) { return slice.call(arrayLike, 0); }; } } catch (e) {} } if (!toArray) { toArray = function(arrayLike) { var arr = []; for (var i = 0, len = arrayLike.length; i < len; ++i) { arr[i] = arrayLike[i]; } return arr; }; } util.toArray = toArray; })(); // Very simple event handler wrapper function that doesn't attempt to solve issues such as "this" handling or // normalization of event properties var addListener; if (isBrowser) { if (isHostMethod(document, "addEventListener")) { addListener = function(obj, eventType, listener) { obj.addEventListener(eventType, listener, false); }; } else if (isHostMethod(document, "attachEvent")) { addListener = function(obj, eventType, listener) { obj.attachEvent("on" + eventType, listener); }; } else { fail("Document does not have required addEventListener or attachEvent method"); } util.addListener = addListener; } var initListeners = []; function getErrorDesc(ex) { return ex.message || ex.description || String(ex); } // Initialization function init() { if (!isBrowser || api.initialized) { return; } var testRange; var implementsDomRange = false, implementsTextRange = false; // First, perform basic feature tests if (isHostMethod(document, "createRange")) { testRange = document.createRange(); if (areHostMethods(testRange, domRangeMethods) && areHostProperties(testRange, domRangeProperties)) { implementsDomRange = true; } } var body = getBody(document); if (!body || body.nodeName.toLowerCase() != "body") { fail("No body element found"); return; } if (body && isHostMethod(body, "createTextRange")) { testRange = body.createTextRange(); if (isTextRange(testRange)) { implementsTextRange = true; } } if (!implementsDomRange && !implementsTextRange) { fail("Neither Range nor TextRange are available"); return; } api.initialized = true; api.features = { implementsDomRange: implementsDomRange, implementsTextRange: implementsTextRange }; // Initialize modules var module, errorMessage; for (var moduleName in modules) { if ( (module = modules[moduleName]) instanceof Module ) { module.init(module, api); } } // Call init listeners for (var i = 0, len = initListeners.length; i < len; ++i) { try { initListeners[i](api); } catch (ex) { errorMessage = "Rangy init listener threw an exception. Continuing. Detail: " + getErrorDesc(ex); consoleLog(errorMessage); } } } // Allow external scripts to initialize this library in case it's loaded after the document has loaded api.init = init; // Execute listener immediately if already initialized api.addInitListener = function(listener) { if (api.initialized) { listener(api); } else { initListeners.push(listener); } }; var shimListeners = []; api.addShimListener = function(listener) { shimListeners.push(listener); }; function shim(win) { win = win || window; init(); // Notify listeners for (var i = 0, len = shimListeners.length; i < len; ++i) { shimListeners[i](win); } } if (isBrowser) { api.shim = api.createMissingNativeApi = shim; } function Module(name, dependencies, initializer) { this.name = name; this.dependencies = dependencies; this.initialized = false; this.supported = false; this.initializer = initializer; } Module.prototype = { init: function() { var requiredModuleNames = this.dependencies || []; for (var i = 0, len = requiredModuleNames.length, requiredModule, moduleName; i < len; ++i) { moduleName = requiredModuleNames[i]; requiredModule = modules[moduleName]; if (!requiredModule || !(requiredModule instanceof Module)) { throw new Error("required module '" + moduleName + "' not found"); } requiredModule.init(); if (!requiredModule.supported) { throw new Error("required module '" + moduleName + "' not supported"); } } // Now run initializer this.initializer(this); }, fail: function(reason) { this.initialized = true; this.supported = false; throw new Error("Module '" + this.name + "' failed to load: " + reason); }, warn: function(msg) { api.warn("Module " + this.name + ": " + msg); }, deprecationNotice: function(deprecated, replacement) { api.warn("DEPRECATED: " + deprecated + " in module " + this.name + "is deprecated. Please use " + replacement + " instead"); }, createError: function(msg) { return new Error("Error in Rangy " + this.name + " module: " + msg); } }; function createModule(name, dependencies, initFunc) { var newModule = new Module(name, dependencies, function(module) { if (!module.initialized) { module.initialized = true; try { initFunc(api, module); module.supported = true; } catch (ex) { var errorMessage = "Module '" + name + "' failed to load: " + getErrorDesc(ex); consoleLog(errorMessage); } } }); modules[name] = newModule; return newModule; } api.createModule = function(name) { // Allow 2 or 3 arguments (second argument is an optional array of dependencies) var initFunc, dependencies; if (arguments.length == 2) { initFunc = arguments[1]; dependencies = []; } else { initFunc = arguments[2]; dependencies = arguments[1]; } var module = createModule(name, dependencies, initFunc); // Initialize the module immediately if the core is already initialized if (api.initialized && api.supported) { module.init(); } }; api.createCoreModule = function(name, dependencies, initFunc) { createModule(name, dependencies, initFunc); }; /*----------------------------------------------------------------------------------------------------------------*/ // Ensure rangy.rangePrototype and rangy.selectionPrototype are available immediately function RangePrototype() {} api.RangePrototype = RangePrototype; api.rangePrototype = new RangePrototype(); function SelectionPrototype() {} api.selectionPrototype = new SelectionPrototype(); /*----------------------------------------------------------------------------------------------------------------*/ // DOM utility methods used by Rangy api.createCoreModule("DomUtil", [], function(api, module) { var UNDEF = "undefined"; var util = api.util; // Perform feature tests if (!util.areHostMethods(document, ["createDocumentFragment", "createElement", "createTextNode"])) { module.fail("document missing a Node creation method"); } if (!util.isHostMethod(document, "getElementsByTagName")) { module.fail("document missing getElementsByTagName method"); } var el = document.createElement("div"); if (!util.areHostMethods(el, ["insertBefore", "appendChild", "cloneNode"] || !util.areHostObjects(el, ["previousSibling", "nextSibling", "childNodes", "parentNode"]))) { module.fail("Incomplete Element implementation"); } // innerHTML is required for Range's createContextualFragment method if (!util.isHostProperty(el, "innerHTML")) { module.fail("Element is missing innerHTML property"); } var textNode = document.createTextNode("test"); if (!util.areHostMethods(textNode, ["splitText", "deleteData", "insertData", "appendData", "cloneNode"] || !util.areHostObjects(el, ["previousSibling", "nextSibling", "childNodes", "parentNode"]) || !util.areHostProperties(textNode, ["data"]))) { module.fail("Incomplete Text Node implementation"); } /*----------------------------------------------------------------------------------------------------------------*/ // Removed use of indexOf because of a bizarre bug in Opera that is thrown in one of the Acid3 tests. I haven't been // able to replicate it outside of the test. The bug is that indexOf returns -1 when called on an Array that // contains just the document as a single element and the value searched for is the document. var arrayContains = /*Array.prototype.indexOf ? function(arr, val) { return arr.indexOf(val) > -1; }:*/ function(arr, val) { var i = arr.length; while (i--) { if (arr[i] === val) { return true; } } return false; }; // Opera 11 puts HTML elements in the null namespace, it seems, and IE 7 has undefined namespaceURI function isHtmlNamespace(node) { var ns; return typeof node.namespaceURI == UNDEF || ((ns = node.namespaceURI) === null || ns == "http://www.w3.org/1999/xhtml"); } function parentElement(node) { var parent = node.parentNode; return (parent.nodeType == 1) ? parent : null; } function getNodeIndex(node) { var i = 0; while( (node = node.previousSibling) ) { ++i; } return i; } function getNodeLength(node) { switch (node.nodeType) { case 7: case 10: return 0; case 3: case 8: return node.length; default: return node.childNodes.length; } } function getCommonAncestor(node1, node2) { var ancestors = [], n; for (n = node1; n; n = n.parentNode) { ancestors.push(n); } for (n = node2; n; n = n.parentNode) { if (arrayContains(ancestors, n)) { return n; } } return null; } function isAncestorOf(ancestor, descendant, selfIsAncestor) { var n = selfIsAncestor ? descendant : descendant.parentNode; while (n) { if (n === ancestor) { return true; } else { n = n.parentNode; } } return false; } function isOrIsAncestorOf(ancestor, descendant) { return isAncestorOf(ancestor, descendant, true); } function getClosestAncestorIn(node, ancestor, selfIsAncestor) { var p, n = selfIsAncestor ? node : node.parentNode; while (n) { p = n.parentNode; if (p === ancestor) { return n; } n = p; } return null; } function isCharacterDataNode(node) { var t = node.nodeType; return t == 3 || t == 4 || t == 8 ; // Text, CDataSection or Comment } function isTextOrCommentNode(node) { if (!node) { return false; } var t = node.nodeType; return t == 3 || t == 8 ; // Text or Comment } function insertAfter(node, precedingNode) { var nextNode = precedingNode.nextSibling, parent = precedingNode.parentNode; if (nextNode) { parent.insertBefore(node, nextNode); } else { parent.appendChild(node); } return node; } // Note that we cannot use splitText() because it is bugridden in IE 9. function splitDataNode(node, index, positionsToPreserve) { var newNode = node.cloneNode(false); newNode.deleteData(0, index); node.deleteData(index, node.length - index); insertAfter(newNode, node); // Preserve positions if (positionsToPreserve) { for (var i = 0, position; position = positionsToPreserve[i++]; ) { // Handle case where position was inside the portion of node after the split point if (position.node == node && position.offset > index) { position.node = newNode; position.offset -= index; } // Handle the case where the position is a node offset within node's parent else if (position.node == node.parentNode && position.offset > getNodeIndex(node)) { ++position.offset; } } } return newNode; } function getDocument(node) { if (node.nodeType == 9) { return node; } else if (typeof node.ownerDocument != UNDEF) { return node.ownerDocument; } else if (typeof node.document != UNDEF) { return node.document; } else if (node.parentNode) { return getDocument(node.parentNode); } else { throw module.createError("getDocument: no document found for node"); } } function getWindow(node) { var doc = getDocument(node); if (typeof doc.defaultView != UNDEF) { return doc.defaultView; } else if (typeof doc.parentWindow != UNDEF) { return doc.parentWindow; } else { throw module.createError("Cannot get a window object for node"); } } function getIframeDocument(iframeEl) { if (typeof iframeEl.contentDocument != UNDEF) { return iframeEl.contentDocument; } else if (typeof iframeEl.contentWindow != UNDEF) { return iframeEl.contentWindow.document; } else { throw module.createError("getIframeDocument: No Document object found for iframe element"); } } function getIframeWindow(iframeEl) { if (typeof iframeEl.contentWindow != UNDEF) { return iframeEl.contentWindow; } else if (typeof iframeEl.contentDocument != UNDEF) { return iframeEl.contentDocument.defaultView; } else { throw module.createError("getIframeWindow: No Window object found for iframe element"); } } // This looks bad. Is it worth it? function isWindow(obj) { return obj && util.isHostMethod(obj, "setTimeout") && util.isHostObject(obj, "document"); } function getContentDocument(obj, module, methodName) { var doc; if (!obj) { doc = document; } // Test if a DOM node has been passed and obtain a document object for it if so else if (util.isHostProperty(obj, "nodeType")) { doc = (obj.nodeType == 1 && obj.tagName.toLowerCase() == "iframe") ? getIframeDocument(obj) : getDocument(obj); } // Test if the doc parameter appears to be a Window object else if (isWindow(obj)) { doc = obj.document; } if (!doc) { throw module.createError(methodName + "(): Parameter must be a Window object or DOM node"); } return doc; } function getRootContainer(node) { var parent; while ( (parent = node.parentNode) ) { node = parent; } return node; } function comparePoints(nodeA, offsetA, nodeB, offsetB) { // See http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Comparing var nodeC, root, childA, childB, n; if (nodeA == nodeB) { // Case 1: nodes are the same return offsetA === offsetB ? 0 : (offsetA < offsetB) ? -1 : 1; } else if ( (nodeC = getClosestAncestorIn(nodeB, nodeA, true)) ) { // Case 2: node C (container B or an ancestor) is a child node of A return offsetA <= getNodeIndex(nodeC) ? -1 : 1; } else if ( (nodeC = getClosestAncestorIn(nodeA, nodeB, true)) ) { // Case 3: node C (container A or an ancestor) is a child node of B return getNodeIndex(nodeC) < offsetB ? -1 : 1; } else { root = getCommonAncestor(nodeA, nodeB); if (!root) { throw new Error("comparePoints error: nodes have no common ancestor"); } // Case 4: containers are siblings or descendants of siblings childA = (nodeA === root) ? root : getClosestAncestorIn(nodeA, root, true); childB = (nodeB === root) ? root : getClosestAncestorIn(nodeB, root, true); if (childA === childB) { // This shouldn't be possible throw module.createError("comparePoints got to case 4 and childA and childB are the same!"); } else { n = root.firstChild; while (n) { if (n === childA) { return -1; } else if (n === childB) { return 1; } n = n.nextSibling; } } } } /*----------------------------------------------------------------------------------------------------------------*/ // Test for IE's crash (IE 6/7) or exception (IE >= 8) when a reference to garbage-collected text node is queried var crashyTextNodes = false; function isBrokenNode(node) { var n; try { n = node.parentNode; return false; } catch (e) { return true; } } (function() { var el = document.createElement("b"); el.innerHTML = "1"; var textNode = el.firstChild; el.innerHTML = "
      "; crashyTextNodes = isBrokenNode(textNode); api.features.crashyTextNodes = crashyTextNodes; })(); /*----------------------------------------------------------------------------------------------------------------*/ function inspectNode(node) { if (!node) { return "[No node]"; } if (crashyTextNodes && isBrokenNode(node)) { return "[Broken node]"; } if (isCharacterDataNode(node)) { return '"' + node.data + '"'; } if (node.nodeType == 1) { var idAttr = node.id ? ' id="' + node.id + '"' : ""; return "<" + node.nodeName + idAttr + ">[index:" + getNodeIndex(node) + ",length:" + node.childNodes.length + "][" + (node.innerHTML || "[innerHTML not supported]").slice(0, 25) + "]"; } return node.nodeName; } function fragmentFromNodeChildren(node) { var fragment = getDocument(node).createDocumentFragment(), child; while ( (child = node.firstChild) ) { fragment.appendChild(child); } return fragment; } var getComputedStyleProperty; if (typeof window.getComputedStyle != UNDEF) { getComputedStyleProperty = function(el, propName) { return getWindow(el).getComputedStyle(el, null)[propName]; }; } else if (typeof document.documentElement.currentStyle != UNDEF) { getComputedStyleProperty = function(el, propName) { return el.currentStyle[propName]; }; } else { module.fail("No means of obtaining computed style properties found"); } function NodeIterator(root) { this.root = root; this._next = root; } NodeIterator.prototype = { _current: null, hasNext: function() { return !!this._next; }, next: function() { var n = this._current = this._next; var child, next; if (this._current) { child = n.firstChild; if (child) { this._next = child; } else { next = null; while ((n !== this.root) && !(next = n.nextSibling)) { n = n.parentNode; } this._next = next; } } return this._current; }, detach: function() { this._current = this._next = this.root = null; } }; function createIterator(root) { return new NodeIterator(root); } function DomPosition(node, offset) { this.node = node; this.offset = offset; } DomPosition.prototype = { equals: function(pos) { return !!pos && this.node === pos.node && this.offset == pos.offset; }, inspect: function() { return "[DomPosition(" + inspectNode(this.node) + ":" + this.offset + ")]"; }, toString: function() { return this.inspect(); } }; function DOMException(codeName) { this.code = this[codeName]; this.codeName = codeName; this.message = "DOMException: " + this.codeName; } DOMException.prototype = { INDEX_SIZE_ERR: 1, HIERARCHY_REQUEST_ERR: 3, WRONG_DOCUMENT_ERR: 4, NO_MODIFICATION_ALLOWED_ERR: 7, NOT_FOUND_ERR: 8, NOT_SUPPORTED_ERR: 9, INVALID_STATE_ERR: 11, INVALID_NODE_TYPE_ERR: 24 }; DOMException.prototype.toString = function() { return this.message; }; api.dom = { arrayContains: arrayContains, isHtmlNamespace: isHtmlNamespace, parentElement: parentElement, getNodeIndex: getNodeIndex, getNodeLength: getNodeLength, getCommonAncestor: getCommonAncestor, isAncestorOf: isAncestorOf, isOrIsAncestorOf: isOrIsAncestorOf, getClosestAncestorIn: getClosestAncestorIn, isCharacterDataNode: isCharacterDataNode, isTextOrCommentNode: isTextOrCommentNode, insertAfter: insertAfter, splitDataNode: splitDataNode, getDocument: getDocument, getWindow: getWindow, getIframeWindow: getIframeWindow, getIframeDocument: getIframeDocument, getBody: util.getBody, isWindow: isWindow, getContentDocument: getContentDocument, getRootContainer: getRootContainer, comparePoints: comparePoints, isBrokenNode: isBrokenNode, inspectNode: inspectNode, getComputedStyleProperty: getComputedStyleProperty, fragmentFromNodeChildren: fragmentFromNodeChildren, createIterator: createIterator, DomPosition: DomPosition }; api.DOMException = DOMException; }); /*----------------------------------------------------------------------------------------------------------------*/ // Pure JavaScript implementation of DOM Range api.createCoreModule("DomRange", ["DomUtil"], function(api, module) { var dom = api.dom; var util = api.util; var DomPosition = dom.DomPosition; var DOMException = api.DOMException; var isCharacterDataNode = dom.isCharacterDataNode; var getNodeIndex = dom.getNodeIndex; var isOrIsAncestorOf = dom.isOrIsAncestorOf; var getDocument = dom.getDocument; var comparePoints = dom.comparePoints; var splitDataNode = dom.splitDataNode; var getClosestAncestorIn = dom.getClosestAncestorIn; var getNodeLength = dom.getNodeLength; var arrayContains = dom.arrayContains; var getRootContainer = dom.getRootContainer; var crashyTextNodes = api.features.crashyTextNodes; /*----------------------------------------------------------------------------------------------------------------*/ // Utility functions function isNonTextPartiallySelected(node, range) { return (node.nodeType != 3) && (isOrIsAncestorOf(node, range.startContainer) || isOrIsAncestorOf(node, range.endContainer)); } function getRangeDocument(range) { return range.document || getDocument(range.startContainer); } function getBoundaryBeforeNode(node) { return new DomPosition(node.parentNode, getNodeIndex(node)); } function getBoundaryAfterNode(node) { return new DomPosition(node.parentNode, getNodeIndex(node) + 1); } function insertNodeAtPosition(node, n, o) { var firstNodeInserted = node.nodeType == 11 ? node.firstChild : node; if (isCharacterDataNode(n)) { if (o == n.length) { dom.insertAfter(node, n); } else { n.parentNode.insertBefore(node, o == 0 ? n : splitDataNode(n, o)); } } else if (o >= n.childNodes.length) { n.appendChild(node); } else { n.insertBefore(node, n.childNodes[o]); } return firstNodeInserted; } function rangesIntersect(rangeA, rangeB, touchingIsIntersecting) { assertRangeValid(rangeA); assertRangeValid(rangeB); if (getRangeDocument(rangeB) != getRangeDocument(rangeA)) { throw new DOMException("WRONG_DOCUMENT_ERR"); } var startComparison = comparePoints(rangeA.startContainer, rangeA.startOffset, rangeB.endContainer, rangeB.endOffset), endComparison = comparePoints(rangeA.endContainer, rangeA.endOffset, rangeB.startContainer, rangeB.startOffset); return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0; } function cloneSubtree(iterator) { var partiallySelected; for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) { partiallySelected = iterator.isPartiallySelectedSubtree(); node = node.cloneNode(!partiallySelected); if (partiallySelected) { subIterator = iterator.getSubtreeIterator(); node.appendChild(cloneSubtree(subIterator)); subIterator.detach(); } if (node.nodeType == 10) { // DocumentType throw new DOMException("HIERARCHY_REQUEST_ERR"); } frag.appendChild(node); } return frag; } function iterateSubtree(rangeIterator, func, iteratorState) { var it, n; iteratorState = iteratorState || { stop: false }; for (var node, subRangeIterator; node = rangeIterator.next(); ) { if (rangeIterator.isPartiallySelectedSubtree()) { if (func(node) === false) { iteratorState.stop = true; return; } else { // The node is partially selected by the Range, so we can use a new RangeIterator on the portion of // the node selected by the Range. subRangeIterator = rangeIterator.getSubtreeIterator(); iterateSubtree(subRangeIterator, func, iteratorState); subRangeIterator.detach(); if (iteratorState.stop) { return; } } } else { // The whole node is selected, so we can use efficient DOM iteration to iterate over the node and its // descendants it = dom.createIterator(node); while ( (n = it.next()) ) { if (func(n) === false) { iteratorState.stop = true; return; } } } } } function deleteSubtree(iterator) { var subIterator; while (iterator.next()) { if (iterator.isPartiallySelectedSubtree()) { subIterator = iterator.getSubtreeIterator(); deleteSubtree(subIterator); subIterator.detach(); } else { iterator.remove(); } } } function extractSubtree(iterator) { for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) { if (iterator.isPartiallySelectedSubtree()) { node = node.cloneNode(false); subIterator = iterator.getSubtreeIterator(); node.appendChild(extractSubtree(subIterator)); subIterator.detach(); } else { iterator.remove(); } if (node.nodeType == 10) { // DocumentType throw new DOMException("HIERARCHY_REQUEST_ERR"); } frag.appendChild(node); } return frag; } function getNodesInRange(range, nodeTypes, filter) { var filterNodeTypes = !!(nodeTypes && nodeTypes.length), regex; var filterExists = !!filter; if (filterNodeTypes) { regex = new RegExp("^(" + nodeTypes.join("|") + ")$"); } var nodes = []; iterateSubtree(new RangeIterator(range, false), function(node) { if (filterNodeTypes && !regex.test(node.nodeType)) { return; } if (filterExists && !filter(node)) { return; } // Don't include a boundary container if it is a character data node and the range does not contain any // of its character data. See issue 190. var sc = range.startContainer; if (node == sc && isCharacterDataNode(sc) && range.startOffset == sc.length) { return; } var ec = range.endContainer; if (node == ec && isCharacterDataNode(ec) && range.endOffset == 0) { return; } nodes.push(node); }); return nodes; } function inspect(range) { var name = (typeof range.getName == "undefined") ? "Range" : range.getName(); return "[" + name + "(" + dom.inspectNode(range.startContainer) + ":" + range.startOffset + ", " + dom.inspectNode(range.endContainer) + ":" + range.endOffset + ")]"; } /*----------------------------------------------------------------------------------------------------------------*/ // RangeIterator code partially borrows from IERange by Tim Ryan (http://github.com/timcameronryan/IERange) function RangeIterator(range, clonePartiallySelectedTextNodes) { this.range = range; this.clonePartiallySelectedTextNodes = clonePartiallySelectedTextNodes; if (!range.collapsed) { this.sc = range.startContainer; this.so = range.startOffset; this.ec = range.endContainer; this.eo = range.endOffset; var root = range.commonAncestorContainer; if (this.sc === this.ec && isCharacterDataNode(this.sc)) { this.isSingleCharacterDataNode = true; this._first = this._last = this._next = this.sc; } else { this._first = this._next = (this.sc === root && !isCharacterDataNode(this.sc)) ? this.sc.childNodes[this.so] : getClosestAncestorIn(this.sc, root, true); this._last = (this.ec === root && !isCharacterDataNode(this.ec)) ? this.ec.childNodes[this.eo - 1] : getClosestAncestorIn(this.ec, root, true); } } } RangeIterator.prototype = { _current: null, _next: null, _first: null, _last: null, isSingleCharacterDataNode: false, reset: function() { this._current = null; this._next = this._first; }, hasNext: function() { return !!this._next; }, next: function() { // Move to next node var current = this._current = this._next; if (current) { this._next = (current !== this._last) ? current.nextSibling : null; // Check for partially selected text nodes if (isCharacterDataNode(current) && this.clonePartiallySelectedTextNodes) { if (current === this.ec) { (current = current.cloneNode(true)).deleteData(this.eo, current.length - this.eo); } if (this._current === this.sc) { (current = current.cloneNode(true)).deleteData(0, this.so); } } } return current; }, remove: function() { var current = this._current, start, end; if (isCharacterDataNode(current) && (current === this.sc || current === this.ec)) { start = (current === this.sc) ? this.so : 0; end = (current === this.ec) ? this.eo : current.length; if (start != end) { current.deleteData(start, end - start); } } else { if (current.parentNode) { current.parentNode.removeChild(current); } else { } } }, // Checks if the current node is partially selected isPartiallySelectedSubtree: function() { var current = this._current; return isNonTextPartiallySelected(current, this.range); }, getSubtreeIterator: function() { var subRange; if (this.isSingleCharacterDataNode) { subRange = this.range.cloneRange(); subRange.collapse(false); } else { subRange = new Range(getRangeDocument(this.range)); var current = this._current; var startContainer = current, startOffset = 0, endContainer = current, endOffset = getNodeLength(current); if (isOrIsAncestorOf(current, this.sc)) { startContainer = this.sc; startOffset = this.so; } if (isOrIsAncestorOf(current, this.ec)) { endContainer = this.ec; endOffset = this.eo; } updateBoundaries(subRange, startContainer, startOffset, endContainer, endOffset); } return new RangeIterator(subRange, this.clonePartiallySelectedTextNodes); }, detach: function() { this.range = this._current = this._next = this._first = this._last = this.sc = this.so = this.ec = this.eo = null; } }; /*----------------------------------------------------------------------------------------------------------------*/ var beforeAfterNodeTypes = [1, 3, 4, 5, 7, 8, 10]; var rootContainerNodeTypes = [2, 9, 11]; var readonlyNodeTypes = [5, 6, 10, 12]; var insertableNodeTypes = [1, 3, 4, 5, 7, 8, 10, 11]; var surroundNodeTypes = [1, 3, 4, 5, 7, 8]; function createAncestorFinder(nodeTypes) { return function(node, selfIsAncestor) { var t, n = selfIsAncestor ? node : node.parentNode; while (n) { t = n.nodeType; if (arrayContains(nodeTypes, t)) { return n; } n = n.parentNode; } return null; }; } var getDocumentOrFragmentContainer = createAncestorFinder( [9, 11] ); var getReadonlyAncestor = createAncestorFinder(readonlyNodeTypes); var getDocTypeNotationEntityAncestor = createAncestorFinder( [6, 10, 12] ); function assertNoDocTypeNotationEntityAncestor(node, allowSelf) { if (getDocTypeNotationEntityAncestor(node, allowSelf)) { throw new DOMException("INVALID_NODE_TYPE_ERR"); } } function assertValidNodeType(node, invalidTypes) { if (!arrayContains(invalidTypes, node.nodeType)) { throw new DOMException("INVALID_NODE_TYPE_ERR"); } } function assertValidOffset(node, offset) { if (offset < 0 || offset > (isCharacterDataNode(node) ? node.length : node.childNodes.length)) { throw new DOMException("INDEX_SIZE_ERR"); } } function assertSameDocumentOrFragment(node1, node2) { if (getDocumentOrFragmentContainer(node1, true) !== getDocumentOrFragmentContainer(node2, true)) { throw new DOMException("WRONG_DOCUMENT_ERR"); } } function assertNodeNotReadOnly(node) { if (getReadonlyAncestor(node, true)) { throw new DOMException("NO_MODIFICATION_ALLOWED_ERR"); } } function assertNode(node, codeName) { if (!node) { throw new DOMException(codeName); } } function isOrphan(node) { return (crashyTextNodes && dom.isBrokenNode(node)) || !arrayContains(rootContainerNodeTypes, node.nodeType) && !getDocumentOrFragmentContainer(node, true); } function isValidOffset(node, offset) { return offset <= (isCharacterDataNode(node) ? node.length : node.childNodes.length); } function isRangeValid(range) { return (!!range.startContainer && !!range.endContainer && !isOrphan(range.startContainer) && !isOrphan(range.endContainer) && isValidOffset(range.startContainer, range.startOffset) && isValidOffset(range.endContainer, range.endOffset)); } function assertRangeValid(range) { if (!isRangeValid(range)) { throw new Error("Range error: Range is no longer valid after DOM mutation (" + range.inspect() + ")"); } } /*----------------------------------------------------------------------------------------------------------------*/ // Test the browser's innerHTML support to decide how to implement createContextualFragment var styleEl = document.createElement("style"); var htmlParsingConforms = false; try { styleEl.innerHTML = "x"; htmlParsingConforms = (styleEl.firstChild.nodeType == 3); // Opera incorrectly creates an element node } catch (e) { // IE 6 and 7 throw } api.features.htmlParsingConforms = htmlParsingConforms; var createContextualFragment = htmlParsingConforms ? // Implementation as per HTML parsing spec, trusting in the browser's implementation of innerHTML. See // discussion and base code for this implementation at issue 67. // Spec: http://html5.org/specs/dom-parsing.html#extensions-to-the-range-interface // Thanks to Aleks Williams. function(fragmentStr) { // "Let node the context object's start's node." var node = this.startContainer; var doc = getDocument(node); // "If the context object's start's node is null, raise an INVALID_STATE_ERR // exception and abort these steps." if (!node) { throw new DOMException("INVALID_STATE_ERR"); } // "Let element be as follows, depending on node's interface:" // Document, Document Fragment: null var el = null; // "Element: node" if (node.nodeType == 1) { el = node; // "Text, Comment: node's parentElement" } else if (isCharacterDataNode(node)) { el = dom.parentElement(node); } // "If either element is null or element's ownerDocument is an HTML document // and element's local name is "html" and element's namespace is the HTML // namespace" if (el === null || ( el.nodeName == "HTML" && dom.isHtmlNamespace(getDocument(el).documentElement) && dom.isHtmlNamespace(el) )) { // "let element be a new Element with "body" as its local name and the HTML // namespace as its namespace."" el = doc.createElement("body"); } else { el = el.cloneNode(false); } // "If the node's document is an HTML document: Invoke the HTML fragment parsing algorithm." // "If the node's document is an XML document: Invoke the XML fragment parsing algorithm." // "In either case, the algorithm must be invoked with fragment as the input // and element as the context element." el.innerHTML = fragmentStr; // "If this raises an exception, then abort these steps. Otherwise, let new // children be the nodes returned." // "Let fragment be a new DocumentFragment." // "Append all new children to fragment." // "Return fragment." return dom.fragmentFromNodeChildren(el); } : // In this case, innerHTML cannot be trusted, so fall back to a simpler, non-conformant implementation that // previous versions of Rangy used (with the exception of using a body element rather than a div) function(fragmentStr) { var doc = getRangeDocument(this); var el = doc.createElement("body"); el.innerHTML = fragmentStr; return dom.fragmentFromNodeChildren(el); }; function splitRangeBoundaries(range, positionsToPreserve) { assertRangeValid(range); var sc = range.startContainer, so = range.startOffset, ec = range.endContainer, eo = range.endOffset; var startEndSame = (sc === ec); if (isCharacterDataNode(ec) && eo > 0 && eo < ec.length) { splitDataNode(ec, eo, positionsToPreserve); } if (isCharacterDataNode(sc) && so > 0 && so < sc.length) { sc = splitDataNode(sc, so, positionsToPreserve); if (startEndSame) { eo -= so; ec = sc; } else if (ec == sc.parentNode && eo >= getNodeIndex(sc)) { eo++; } so = 0; } range.setStartAndEnd(sc, so, ec, eo); } function rangeToHtml(range) { assertRangeValid(range); var container = range.commonAncestorContainer.parentNode.cloneNode(false); container.appendChild( range.cloneContents() ); return container.innerHTML; } /*----------------------------------------------------------------------------------------------------------------*/ var rangeProperties = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed", "commonAncestorContainer"]; var s2s = 0, s2e = 1, e2e = 2, e2s = 3; var n_b = 0, n_a = 1, n_b_a = 2, n_i = 3; util.extend(api.rangePrototype, { compareBoundaryPoints: function(how, range) { assertRangeValid(this); assertSameDocumentOrFragment(this.startContainer, range.startContainer); var nodeA, offsetA, nodeB, offsetB; var prefixA = (how == e2s || how == s2s) ? "start" : "end"; var prefixB = (how == s2e || how == s2s) ? "start" : "end"; nodeA = this[prefixA + "Container"]; offsetA = this[prefixA + "Offset"]; nodeB = range[prefixB + "Container"]; offsetB = range[prefixB + "Offset"]; return comparePoints(nodeA, offsetA, nodeB, offsetB); }, insertNode: function(node) { assertRangeValid(this); assertValidNodeType(node, insertableNodeTypes); assertNodeNotReadOnly(this.startContainer); if (isOrIsAncestorOf(node, this.startContainer)) { throw new DOMException("HIERARCHY_REQUEST_ERR"); } // No check for whether the container of the start of the Range is of a type that does not allow // children of the type of node: the browser's DOM implementation should do this for us when we attempt // to add the node var firstNodeInserted = insertNodeAtPosition(node, this.startContainer, this.startOffset); this.setStartBefore(firstNodeInserted); }, cloneContents: function() { assertRangeValid(this); var clone, frag; if (this.collapsed) { return getRangeDocument(this).createDocumentFragment(); } else { if (this.startContainer === this.endContainer && isCharacterDataNode(this.startContainer)) { clone = this.startContainer.cloneNode(true); clone.data = clone.data.slice(this.startOffset, this.endOffset); frag = getRangeDocument(this).createDocumentFragment(); frag.appendChild(clone); return frag; } else { var iterator = new RangeIterator(this, true); clone = cloneSubtree(iterator); iterator.detach(); } return clone; } }, canSurroundContents: function() { assertRangeValid(this); assertNodeNotReadOnly(this.startContainer); assertNodeNotReadOnly(this.endContainer); // Check if the contents can be surrounded. Specifically, this means whether the range partially selects // no non-text nodes. var iterator = new RangeIterator(this, true); var boundariesInvalid = (iterator._first && (isNonTextPartiallySelected(iterator._first, this)) || (iterator._last && isNonTextPartiallySelected(iterator._last, this))); iterator.detach(); return !boundariesInvalid; }, surroundContents: function(node) { assertValidNodeType(node, surroundNodeTypes); if (!this.canSurroundContents()) { throw new DOMException("INVALID_STATE_ERR"); } // Extract the contents var content = this.extractContents(); // Clear the children of the node if (node.hasChildNodes()) { while (node.lastChild) { node.removeChild(node.lastChild); } } // Insert the new node and add the extracted contents insertNodeAtPosition(node, this.startContainer, this.startOffset); node.appendChild(content); this.selectNode(node); }, cloneRange: function() { assertRangeValid(this); var range = new Range(getRangeDocument(this)); var i = rangeProperties.length, prop; while (i--) { prop = rangeProperties[i]; range[prop] = this[prop]; } return range; }, toString: function() { assertRangeValid(this); var sc = this.startContainer; if (sc === this.endContainer && isCharacterDataNode(sc)) { return (sc.nodeType == 3 || sc.nodeType == 4) ? sc.data.slice(this.startOffset, this.endOffset) : ""; } else { var textParts = [], iterator = new RangeIterator(this, true); iterateSubtree(iterator, function(node) { // Accept only text or CDATA nodes, not comments if (node.nodeType == 3 || node.nodeType == 4) { textParts.push(node.data); } }); iterator.detach(); return textParts.join(""); } }, // The methods below are all non-standard. The following batch were introduced by Mozilla but have since // been removed from Mozilla. compareNode: function(node) { assertRangeValid(this); var parent = node.parentNode; var nodeIndex = getNodeIndex(node); if (!parent) { throw new DOMException("NOT_FOUND_ERR"); } var startComparison = this.comparePoint(parent, nodeIndex), endComparison = this.comparePoint(parent, nodeIndex + 1); if (startComparison < 0) { // Node starts before return (endComparison > 0) ? n_b_a : n_b; } else { return (endComparison > 0) ? n_a : n_i; } }, comparePoint: function(node, offset) { assertRangeValid(this); assertNode(node, "HIERARCHY_REQUEST_ERR"); assertSameDocumentOrFragment(node, this.startContainer); if (comparePoints(node, offset, this.startContainer, this.startOffset) < 0) { return -1; } else if (comparePoints(node, offset, this.endContainer, this.endOffset) > 0) { return 1; } return 0; }, createContextualFragment: createContextualFragment, toHtml: function() { return rangeToHtml(this); }, // touchingIsIntersecting determines whether this method considers a node that borders a range intersects // with it (as in WebKit) or not (as in Gecko pre-1.9, and the default) intersectsNode: function(node, touchingIsIntersecting) { assertRangeValid(this); assertNode(node, "NOT_FOUND_ERR"); if (getDocument(node) !== getRangeDocument(this)) { return false; } var parent = node.parentNode, offset = getNodeIndex(node); assertNode(parent, "NOT_FOUND_ERR"); var startComparison = comparePoints(parent, offset, this.endContainer, this.endOffset), endComparison = comparePoints(parent, offset + 1, this.startContainer, this.startOffset); return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0; }, isPointInRange: function(node, offset) { assertRangeValid(this); assertNode(node, "HIERARCHY_REQUEST_ERR"); assertSameDocumentOrFragment(node, this.startContainer); return (comparePoints(node, offset, this.startContainer, this.startOffset) >= 0) && (comparePoints(node, offset, this.endContainer, this.endOffset) <= 0); }, // The methods below are non-standard and invented by me. // Sharing a boundary start-to-end or end-to-start does not count as intersection. intersectsRange: function(range) { return rangesIntersect(this, range, false); }, // Sharing a boundary start-to-end or end-to-start does count as intersection. intersectsOrTouchesRange: function(range) { return rangesIntersect(this, range, true); }, intersection: function(range) { if (this.intersectsRange(range)) { var startComparison = comparePoints(this.startContainer, this.startOffset, range.startContainer, range.startOffset), endComparison = comparePoints(this.endContainer, this.endOffset, range.endContainer, range.endOffset); var intersectionRange = this.cloneRange(); if (startComparison == -1) { intersectionRange.setStart(range.startContainer, range.startOffset); } if (endComparison == 1) { intersectionRange.setEnd(range.endContainer, range.endOffset); } return intersectionRange; } return null; }, union: function(range) { if (this.intersectsOrTouchesRange(range)) { var unionRange = this.cloneRange(); if (comparePoints(range.startContainer, range.startOffset, this.startContainer, this.startOffset) == -1) { unionRange.setStart(range.startContainer, range.startOffset); } if (comparePoints(range.endContainer, range.endOffset, this.endContainer, this.endOffset) == 1) { unionRange.setEnd(range.endContainer, range.endOffset); } return unionRange; } else { throw new DOMException("Ranges do not intersect"); } }, containsNode: function(node, allowPartial) { if (allowPartial) { return this.intersectsNode(node, false); } else { return this.compareNode(node) == n_i; } }, containsNodeContents: function(node) { return this.comparePoint(node, 0) >= 0 && this.comparePoint(node, getNodeLength(node)) <= 0; }, containsRange: function(range) { var intersection = this.intersection(range); return intersection !== null && range.equals(intersection); }, containsNodeText: function(node) { var nodeRange = this.cloneRange(); nodeRange.selectNode(node); var textNodes = nodeRange.getNodes([3]); if (textNodes.length > 0) { nodeRange.setStart(textNodes[0], 0); var lastTextNode = textNodes.pop(); nodeRange.setEnd(lastTextNode, lastTextNode.length); return this.containsRange(nodeRange); } else { return this.containsNodeContents(node); } }, getNodes: function(nodeTypes, filter) { assertRangeValid(this); return getNodesInRange(this, nodeTypes, filter); }, getDocument: function() { return getRangeDocument(this); }, collapseBefore: function(node) { this.setEndBefore(node); this.collapse(false); }, collapseAfter: function(node) { this.setStartAfter(node); this.collapse(true); }, getBookmark: function(containerNode) { var doc = getRangeDocument(this); var preSelectionRange = api.createRange(doc); containerNode = containerNode || dom.getBody(doc); preSelectionRange.selectNodeContents(containerNode); var range = this.intersection(preSelectionRange); var start = 0, end = 0; if (range) { preSelectionRange.setEnd(range.startContainer, range.startOffset); start = preSelectionRange.toString().length; end = start + range.toString().length; } return { start: start, end: end, containerNode: containerNode }; }, moveToBookmark: function(bookmark) { var containerNode = bookmark.containerNode; var charIndex = 0; this.setStart(containerNode, 0); this.collapse(true); var nodeStack = [containerNode], node, foundStart = false, stop = false; var nextCharIndex, i, childNodes; while (!stop && (node = nodeStack.pop())) { if (node.nodeType == 3) { nextCharIndex = charIndex + node.length; if (!foundStart && bookmark.start >= charIndex && bookmark.start <= nextCharIndex) { this.setStart(node, bookmark.start - charIndex); foundStart = true; } if (foundStart && bookmark.end >= charIndex && bookmark.end <= nextCharIndex) { this.setEnd(node, bookmark.end - charIndex); stop = true; } charIndex = nextCharIndex; } else { childNodes = node.childNodes; i = childNodes.length; while (i--) { nodeStack.push(childNodes[i]); } } } }, getName: function() { return "DomRange"; }, equals: function(range) { return Range.rangesEqual(this, range); }, isValid: function() { return isRangeValid(this); }, inspect: function() { return inspect(this); }, detach: function() { // In DOM4, detach() is now a no-op. } }); function copyComparisonConstantsToObject(obj) { obj.START_TO_START = s2s; obj.START_TO_END = s2e; obj.END_TO_END = e2e; obj.END_TO_START = e2s; obj.NODE_BEFORE = n_b; obj.NODE_AFTER = n_a; obj.NODE_BEFORE_AND_AFTER = n_b_a; obj.NODE_INSIDE = n_i; } function copyComparisonConstants(constructor) { copyComparisonConstantsToObject(constructor); copyComparisonConstantsToObject(constructor.prototype); } function createRangeContentRemover(remover, boundaryUpdater) { return function() { assertRangeValid(this); var sc = this.startContainer, so = this.startOffset, root = this.commonAncestorContainer; var iterator = new RangeIterator(this, true); // Work out where to position the range after content removal var node, boundary; if (sc !== root) { node = getClosestAncestorIn(sc, root, true); boundary = getBoundaryAfterNode(node); sc = boundary.node; so = boundary.offset; } // Check none of the range is read-only iterateSubtree(iterator, assertNodeNotReadOnly); iterator.reset(); // Remove the content var returnValue = remover(iterator); iterator.detach(); // Move to the new position boundaryUpdater(this, sc, so, sc, so); return returnValue; }; } function createPrototypeRange(constructor, boundaryUpdater) { function createBeforeAfterNodeSetter(isBefore, isStart) { return function(node) { assertValidNodeType(node, beforeAfterNodeTypes); assertValidNodeType(getRootContainer(node), rootContainerNodeTypes); var boundary = (isBefore ? getBoundaryBeforeNode : getBoundaryAfterNode)(node); (isStart ? setRangeStart : setRangeEnd)(this, boundary.node, boundary.offset); }; } function setRangeStart(range, node, offset) { var ec = range.endContainer, eo = range.endOffset; if (node !== range.startContainer || offset !== range.startOffset) { // Check the root containers of the range and the new boundary, and also check whether the new boundary // is after the current end. In either case, collapse the range to the new position if (getRootContainer(node) != getRootContainer(ec) || comparePoints(node, offset, ec, eo) == 1) { ec = node; eo = offset; } boundaryUpdater(range, node, offset, ec, eo); } } function setRangeEnd(range, node, offset) { var sc = range.startContainer, so = range.startOffset; if (node !== range.endContainer || offset !== range.endOffset) { // Check the root containers of the range and the new boundary, and also check whether the new boundary // is after the current end. In either case, collapse the range to the new position if (getRootContainer(node) != getRootContainer(sc) || comparePoints(node, offset, sc, so) == -1) { sc = node; so = offset; } boundaryUpdater(range, sc, so, node, offset); } } // Set up inheritance var F = function() {}; F.prototype = api.rangePrototype; constructor.prototype = new F(); util.extend(constructor.prototype, { setStart: function(node, offset) { assertNoDocTypeNotationEntityAncestor(node, true); assertValidOffset(node, offset); setRangeStart(this, node, offset); }, setEnd: function(node, offset) { assertNoDocTypeNotationEntityAncestor(node, true); assertValidOffset(node, offset); setRangeEnd(this, node, offset); }, /** * Convenience method to set a range's start and end boundaries. Overloaded as follows: * - Two parameters (node, offset) creates a collapsed range at that position * - Three parameters (node, startOffset, endOffset) creates a range contained with node starting at * startOffset and ending at endOffset * - Four parameters (startNode, startOffset, endNode, endOffset) creates a range starting at startOffset in * startNode and ending at endOffset in endNode */ setStartAndEnd: function() { var args = arguments; var sc = args[0], so = args[1], ec = sc, eo = so; switch (args.length) { case 3: eo = args[2]; break; case 4: ec = args[2]; eo = args[3]; break; } boundaryUpdater(this, sc, so, ec, eo); }, setBoundary: function(node, offset, isStart) { this["set" + (isStart ? "Start" : "End")](node, offset); }, setStartBefore: createBeforeAfterNodeSetter(true, true), setStartAfter: createBeforeAfterNodeSetter(false, true), setEndBefore: createBeforeAfterNodeSetter(true, false), setEndAfter: createBeforeAfterNodeSetter(false, false), collapse: function(isStart) { assertRangeValid(this); if (isStart) { boundaryUpdater(this, this.startContainer, this.startOffset, this.startContainer, this.startOffset); } else { boundaryUpdater(this, this.endContainer, this.endOffset, this.endContainer, this.endOffset); } }, selectNodeContents: function(node) { assertNoDocTypeNotationEntityAncestor(node, true); boundaryUpdater(this, node, 0, node, getNodeLength(node)); }, selectNode: function(node) { assertNoDocTypeNotationEntityAncestor(node, false); assertValidNodeType(node, beforeAfterNodeTypes); var start = getBoundaryBeforeNode(node), end = getBoundaryAfterNode(node); boundaryUpdater(this, start.node, start.offset, end.node, end.offset); }, extractContents: createRangeContentRemover(extractSubtree, boundaryUpdater), deleteContents: createRangeContentRemover(deleteSubtree, boundaryUpdater), canSurroundContents: function() { assertRangeValid(this); assertNodeNotReadOnly(this.startContainer); assertNodeNotReadOnly(this.endContainer); // Check if the contents can be surrounded. Specifically, this means whether the range partially selects // no non-text nodes. var iterator = new RangeIterator(this, true); var boundariesInvalid = (iterator._first && isNonTextPartiallySelected(iterator._first, this) || (iterator._last && isNonTextPartiallySelected(iterator._last, this))); iterator.detach(); return !boundariesInvalid; }, splitBoundaries: function() { splitRangeBoundaries(this); }, splitBoundariesPreservingPositions: function(positionsToPreserve) { splitRangeBoundaries(this, positionsToPreserve); }, normalizeBoundaries: function() { assertRangeValid(this); var sc = this.startContainer, so = this.startOffset, ec = this.endContainer, eo = this.endOffset; var mergeForward = function(node) { var sibling = node.nextSibling; if (sibling && sibling.nodeType == node.nodeType) { ec = node; eo = node.length; node.appendData(sibling.data); sibling.parentNode.removeChild(sibling); } }; var mergeBackward = function(node) { var sibling = node.previousSibling; if (sibling && sibling.nodeType == node.nodeType) { sc = node; var nodeLength = node.length; so = sibling.length; node.insertData(0, sibling.data); sibling.parentNode.removeChild(sibling); if (sc == ec) { eo += so; ec = sc; } else if (ec == node.parentNode) { var nodeIndex = getNodeIndex(node); if (eo == nodeIndex) { ec = node; eo = nodeLength; } else if (eo > nodeIndex) { eo--; } } } }; var normalizeStart = true; if (isCharacterDataNode(ec)) { if (ec.length == eo) { mergeForward(ec); } } else { if (eo > 0) { var endNode = ec.childNodes[eo - 1]; if (endNode && isCharacterDataNode(endNode)) { mergeForward(endNode); } } normalizeStart = !this.collapsed; } if (normalizeStart) { if (isCharacterDataNode(sc)) { if (so == 0) { mergeBackward(sc); } } else { if (so < sc.childNodes.length) { var startNode = sc.childNodes[so]; if (startNode && isCharacterDataNode(startNode)) { mergeBackward(startNode); } } } } else { sc = ec; so = eo; } boundaryUpdater(this, sc, so, ec, eo); }, collapseToPoint: function(node, offset) { assertNoDocTypeNotationEntityAncestor(node, true); assertValidOffset(node, offset); this.setStartAndEnd(node, offset); } }); copyComparisonConstants(constructor); } /*----------------------------------------------------------------------------------------------------------------*/ // Updates commonAncestorContainer and collapsed after boundary change function updateCollapsedAndCommonAncestor(range) { range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset); range.commonAncestorContainer = range.collapsed ? range.startContainer : dom.getCommonAncestor(range.startContainer, range.endContainer); } function updateBoundaries(range, startContainer, startOffset, endContainer, endOffset) { range.startContainer = startContainer; range.startOffset = startOffset; range.endContainer = endContainer; range.endOffset = endOffset; range.document = dom.getDocument(startContainer); updateCollapsedAndCommonAncestor(range); } function Range(doc) { this.startContainer = doc; this.startOffset = 0; this.endContainer = doc; this.endOffset = 0; this.document = doc; updateCollapsedAndCommonAncestor(this); } createPrototypeRange(Range, updateBoundaries); util.extend(Range, { rangeProperties: rangeProperties, RangeIterator: RangeIterator, copyComparisonConstants: copyComparisonConstants, createPrototypeRange: createPrototypeRange, inspect: inspect, toHtml: rangeToHtml, getRangeDocument: getRangeDocument, rangesEqual: function(r1, r2) { return r1.startContainer === r2.startContainer && r1.startOffset === r2.startOffset && r1.endContainer === r2.endContainer && r1.endOffset === r2.endOffset; } }); api.DomRange = Range; }); /*----------------------------------------------------------------------------------------------------------------*/ // Wrappers for the browser's native DOM Range and/or TextRange implementation api.createCoreModule("WrappedRange", ["DomRange"], function(api, module) { var WrappedRange, WrappedTextRange; var dom = api.dom; var util = api.util; var DomPosition = dom.DomPosition; var DomRange = api.DomRange; var getBody = dom.getBody; var getContentDocument = dom.getContentDocument; var isCharacterDataNode = dom.isCharacterDataNode; /*----------------------------------------------------------------------------------------------------------------*/ if (api.features.implementsDomRange) { // This is a wrapper around the browser's native DOM Range. It has two aims: // - Provide workarounds for specific browser bugs // - provide convenient extensions, which are inherited from Rangy's DomRange (function() { var rangeProto; var rangeProperties = DomRange.rangeProperties; function updateRangeProperties(range) { var i = rangeProperties.length, prop; while (i--) { prop = rangeProperties[i]; range[prop] = range.nativeRange[prop]; } // Fix for broken collapsed property in IE 9. range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset); } function updateNativeRange(range, startContainer, startOffset, endContainer, endOffset) { var startMoved = (range.startContainer !== startContainer || range.startOffset != startOffset); var endMoved = (range.endContainer !== endContainer || range.endOffset != endOffset); var nativeRangeDifferent = !range.equals(range.nativeRange); // Always set both boundaries for the benefit of IE9 (see issue 35) if (startMoved || endMoved || nativeRangeDifferent) { range.setEnd(endContainer, endOffset); range.setStart(startContainer, startOffset); } } var createBeforeAfterNodeSetter; WrappedRange = function(range) { if (!range) { throw module.createError("WrappedRange: Range must be specified"); } this.nativeRange = range; updateRangeProperties(this); }; DomRange.createPrototypeRange(WrappedRange, updateNativeRange); rangeProto = WrappedRange.prototype; rangeProto.selectNode = function(node) { this.nativeRange.selectNode(node); updateRangeProperties(this); }; rangeProto.cloneContents = function() { return this.nativeRange.cloneContents(); }; // Due to a long-standing Firefox bug that I have not been able to find a reliable way to detect, // insertNode() is never delegated to the native range. rangeProto.surroundContents = function(node) { this.nativeRange.surroundContents(node); updateRangeProperties(this); }; rangeProto.collapse = function(isStart) { this.nativeRange.collapse(isStart); updateRangeProperties(this); }; rangeProto.cloneRange = function() { return new WrappedRange(this.nativeRange.cloneRange()); }; rangeProto.refresh = function() { updateRangeProperties(this); }; rangeProto.toString = function() { return this.nativeRange.toString(); }; // Create test range and node for feature detection var testTextNode = document.createTextNode("test"); getBody(document).appendChild(testTextNode); var range = document.createRange(); /*--------------------------------------------------------------------------------------------------------*/ // Test for Firefox 2 bug that prevents moving the start of a Range to a point after its current end and // correct for it range.setStart(testTextNode, 0); range.setEnd(testTextNode, 0); try { range.setStart(testTextNode, 1); rangeProto.setStart = function(node, offset) { this.nativeRange.setStart(node, offset); updateRangeProperties(this); }; rangeProto.setEnd = function(node, offset) { this.nativeRange.setEnd(node, offset); updateRangeProperties(this); }; createBeforeAfterNodeSetter = function(name) { return function(node) { this.nativeRange[name](node); updateRangeProperties(this); }; }; } catch(ex) { rangeProto.setStart = function(node, offset) { try { this.nativeRange.setStart(node, offset); } catch (ex) { this.nativeRange.setEnd(node, offset); this.nativeRange.setStart(node, offset); } updateRangeProperties(this); }; rangeProto.setEnd = function(node, offset) { try { this.nativeRange.setEnd(node, offset); } catch (ex) { this.nativeRange.setStart(node, offset); this.nativeRange.setEnd(node, offset); } updateRangeProperties(this); }; createBeforeAfterNodeSetter = function(name, oppositeName) { return function(node) { try { this.nativeRange[name](node); } catch (ex) { this.nativeRange[oppositeName](node); this.nativeRange[name](node); } updateRangeProperties(this); }; }; } rangeProto.setStartBefore = createBeforeAfterNodeSetter("setStartBefore", "setEndBefore"); rangeProto.setStartAfter = createBeforeAfterNodeSetter("setStartAfter", "setEndAfter"); rangeProto.setEndBefore = createBeforeAfterNodeSetter("setEndBefore", "setStartBefore"); rangeProto.setEndAfter = createBeforeAfterNodeSetter("setEndAfter", "setStartAfter"); /*--------------------------------------------------------------------------------------------------------*/ // Always use DOM4-compliant selectNodeContents implementation: it's simpler and less code than testing // whether the native implementation can be trusted rangeProto.selectNodeContents = function(node) { this.setStartAndEnd(node, 0, dom.getNodeLength(node)); }; /*--------------------------------------------------------------------------------------------------------*/ // Test for and correct WebKit bug that has the behaviour of compareBoundaryPoints round the wrong way for // constants START_TO_END and END_TO_START: https://bugs.webkit.org/show_bug.cgi?id=20738 range.selectNodeContents(testTextNode); range.setEnd(testTextNode, 3); var range2 = document.createRange(); range2.selectNodeContents(testTextNode); range2.setEnd(testTextNode, 4); range2.setStart(testTextNode, 2); if (range.compareBoundaryPoints(range.START_TO_END, range2) == -1 && range.compareBoundaryPoints(range.END_TO_START, range2) == 1) { // This is the wrong way round, so correct for it rangeProto.compareBoundaryPoints = function(type, range) { range = range.nativeRange || range; if (type == range.START_TO_END) { type = range.END_TO_START; } else if (type == range.END_TO_START) { type = range.START_TO_END; } return this.nativeRange.compareBoundaryPoints(type, range); }; } else { rangeProto.compareBoundaryPoints = function(type, range) { return this.nativeRange.compareBoundaryPoints(type, range.nativeRange || range); }; } /*--------------------------------------------------------------------------------------------------------*/ // Test for IE deleteContents() and extractContents() bug and correct it. See issue 107. var el = document.createElement("div"); el.innerHTML = "123"; var textNode = el.firstChild; var body = getBody(document); body.appendChild(el); range.setStart(textNode, 1); range.setEnd(textNode, 2); range.deleteContents(); if (textNode.data == "13") { // Behaviour is correct per DOM4 Range so wrap the browser's implementation of deleteContents() and // extractContents() rangeProto.deleteContents = function() { this.nativeRange.deleteContents(); updateRangeProperties(this); }; rangeProto.extractContents = function() { var frag = this.nativeRange.extractContents(); updateRangeProperties(this); return frag; }; } else { } body.removeChild(el); body = null; /*--------------------------------------------------------------------------------------------------------*/ // Test for existence of createContextualFragment and delegate to it if it exists if (util.isHostMethod(range, "createContextualFragment")) { rangeProto.createContextualFragment = function(fragmentStr) { return this.nativeRange.createContextualFragment(fragmentStr); }; } /*--------------------------------------------------------------------------------------------------------*/ // Clean up getBody(document).removeChild(testTextNode); rangeProto.getName = function() { return "WrappedRange"; }; api.WrappedRange = WrappedRange; api.createNativeRange = function(doc) { doc = getContentDocument(doc, module, "createNativeRange"); return doc.createRange(); }; })(); } if (api.features.implementsTextRange) { /* This is a workaround for a bug where IE returns the wrong container element from the TextRange's parentElement() method. For example, in the following (where pipes denote the selection boundaries):
      • | a
      • b |
      var range = document.selection.createRange(); alert(range.parentElement().id); // Should alert "ul" but alerts "b" This method returns the common ancestor node of the following: - the parentElement() of the textRange - the parentElement() of the textRange after calling collapse(true) - the parentElement() of the textRange after calling collapse(false) */ var getTextRangeContainerElement = function(textRange) { var parentEl = textRange.parentElement(); var range = textRange.duplicate(); range.collapse(true); var startEl = range.parentElement(); range = textRange.duplicate(); range.collapse(false); var endEl = range.parentElement(); var startEndContainer = (startEl == endEl) ? startEl : dom.getCommonAncestor(startEl, endEl); return startEndContainer == parentEl ? startEndContainer : dom.getCommonAncestor(parentEl, startEndContainer); }; var textRangeIsCollapsed = function(textRange) { return textRange.compareEndPoints("StartToEnd", textRange) == 0; }; // Gets the boundary of a TextRange expressed as a node and an offset within that node. This function started // out as an improved version of code found in Tim Cameron Ryan's IERange (http://code.google.com/p/ierange/) // but has grown, fixing problems with line breaks in preformatted text, adding workaround for IE TextRange // bugs, handling for inputs and images, plus optimizations. var getTextRangeBoundaryPosition = function(textRange, wholeRangeContainerElement, isStart, isCollapsed, startInfo) { var workingRange = textRange.duplicate(); workingRange.collapse(isStart); var containerElement = workingRange.parentElement(); // Sometimes collapsing a TextRange that's at the start of a text node can move it into the previous node, so // check for that if (!dom.isOrIsAncestorOf(wholeRangeContainerElement, containerElement)) { containerElement = wholeRangeContainerElement; } // Deal with nodes that cannot "contain rich HTML markup". In practice, this means form inputs, images and // similar. See http://msdn.microsoft.com/en-us/library/aa703950%28VS.85%29.aspx if (!containerElement.canHaveHTML) { var pos = new DomPosition(containerElement.parentNode, dom.getNodeIndex(containerElement)); return { boundaryPosition: pos, nodeInfo: { nodeIndex: pos.offset, containerElement: pos.node } }; } var workingNode = dom.getDocument(containerElement).createElement("span"); // Workaround for HTML5 Shiv's insane violation of document.createElement(). See Rangy issue 104 and HTML5 // Shiv issue 64: https://github.com/aFarkas/html5shiv/issues/64 if (workingNode.parentNode) { workingNode.parentNode.removeChild(workingNode); } var comparison, workingComparisonType = isStart ? "StartToStart" : "StartToEnd"; var previousNode, nextNode, boundaryPosition, boundaryNode; var start = (startInfo && startInfo.containerElement == containerElement) ? startInfo.nodeIndex : 0; var childNodeCount = containerElement.childNodes.length; var end = childNodeCount; // Check end first. Code within the loop assumes that the endth child node of the container is definitely // after the range boundary. var nodeIndex = end; while (true) { if (nodeIndex == childNodeCount) { containerElement.appendChild(workingNode); } else { containerElement.insertBefore(workingNode, containerElement.childNodes[nodeIndex]); } workingRange.moveToElementText(workingNode); comparison = workingRange.compareEndPoints(workingComparisonType, textRange); if (comparison == 0 || start == end) { break; } else if (comparison == -1) { if (end == start + 1) { // We know the endth child node is after the range boundary, so we must be done. break; } else { start = nodeIndex; } } else { end = (end == start + 1) ? start : nodeIndex; } nodeIndex = Math.floor((start + end) / 2); containerElement.removeChild(workingNode); } // We've now reached or gone past the boundary of the text range we're interested in // so have identified the node we want boundaryNode = workingNode.nextSibling; if (comparison == -1 && boundaryNode && isCharacterDataNode(boundaryNode)) { // This is a character data node (text, comment, cdata). The working range is collapsed at the start of // the node containing the text range's boundary, so we move the end of the working range to the // boundary point and measure the length of its text to get the boundary's offset within the node. workingRange.setEndPoint(isStart ? "EndToStart" : "EndToEnd", textRange); var offset; if (/[\r\n]/.test(boundaryNode.data)) { /* For the particular case of a boundary within a text node containing rendered line breaks (within a
       element, for example), we need a slightly complicated approach to get the boundary's offset in
                              IE. The facts:
                              
                              - Each line break is represented as \r in the text node's data/nodeValue properties
                              - Each line break is represented as \r\n in the TextRange's 'text' property
                              - The 'text' property of the TextRange does not contain trailing line breaks
                              
                              To get round the problem presented by the final fact above, we can use the fact that TextRange's
                              moveStart() and moveEnd() methods return the actual number of characters moved, which is not
                              necessarily the same as the number of characters it was instructed to move. The simplest approach is
                              to use this to store the characters moved when moving both the start and end of the range to the
                              start of the document body and subtracting the start offset from the end offset (the
                              "move-negative-gazillion" method). However, this is extremely slow when the document is large and
                              the range is near the end of it. Clearly doing the mirror image (i.e. moving the range boundaries to
                              the end of the document) has the same problem.
                              
                              Another approach that works is to use moveStart() to move the start boundary of the range up to the
                              end boundary one character at a time and incrementing a counter with the value returned by the
                              moveStart() call. However, the check for whether the start boundary has reached the end boundary is
                              expensive, so this method is slow (although unlike "move-negative-gazillion" is largely unaffected
                              by the location of the range within the document).
                              
                              The approach used below is a hybrid of the two methods above. It uses the fact that a string
                              containing the TextRange's 'text' property with each \r\n converted to a single \r character cannot
                              be longer than the text of the TextRange, so the start of the range is moved that length initially
                              and then a character at a time to make up for any trailing line breaks not contained in the 'text'
                              property. This has good performance in most situations compared to the previous two methods.
                              */
                              var tempRange = workingRange.duplicate();
                              var rangeLength = tempRange.text.replace(/\r\n/g, "\r").length;
      
                              offset = tempRange.moveStart("character", rangeLength);
                              while ( (comparison = tempRange.compareEndPoints("StartToEnd", tempRange)) == -1) {
                                  offset++;
                                  tempRange.moveStart("character", 1);
                              }
                          } else {
                              offset = workingRange.text.length;
                          }
                          boundaryPosition = new DomPosition(boundaryNode, offset);
                      } else {
      
                          // If the boundary immediately follows a character data node and this is the end boundary, we should favour
                          // a position within that, and likewise for a start boundary preceding a character data node
                          previousNode = (isCollapsed || !isStart) && workingNode.previousSibling;
                          nextNode = (isCollapsed || isStart) && workingNode.nextSibling;
                          if (nextNode && isCharacterDataNode(nextNode)) {
                              boundaryPosition = new DomPosition(nextNode, 0);
                          } else if (previousNode && isCharacterDataNode(previousNode)) {
                              boundaryPosition = new DomPosition(previousNode, previousNode.data.length);
                          } else {
                              boundaryPosition = new DomPosition(containerElement, dom.getNodeIndex(workingNode));
                          }
                      }
      
                      // Clean up
                      workingNode.parentNode.removeChild(workingNode);
      
                      return {
                          boundaryPosition: boundaryPosition,
                          nodeInfo: {
                              nodeIndex: nodeIndex,
                              containerElement: containerElement
                          }
                      };
                  };
      
                  // Returns a TextRange representing the boundary of a TextRange expressed as a node and an offset within that
                  // node. This function started out as an optimized version of code found in Tim Cameron Ryan's IERange
                  // (http://code.google.com/p/ierange/)
                  var createBoundaryTextRange = function(boundaryPosition, isStart) {
                      var boundaryNode, boundaryParent, boundaryOffset = boundaryPosition.offset;
                      var doc = dom.getDocument(boundaryPosition.node);
                      var workingNode, childNodes, workingRange = getBody(doc).createTextRange();
                      var nodeIsDataNode = isCharacterDataNode(boundaryPosition.node);
      
                      if (nodeIsDataNode) {
                          boundaryNode = boundaryPosition.node;
                          boundaryParent = boundaryNode.parentNode;
                      } else {
                          childNodes = boundaryPosition.node.childNodes;
                          boundaryNode = (boundaryOffset < childNodes.length) ? childNodes[boundaryOffset] : null;
                          boundaryParent = boundaryPosition.node;
                      }
      
                      // Position the range immediately before the node containing the boundary
                      workingNode = doc.createElement("span");
      
                      // Making the working element non-empty element persuades IE to consider the TextRange boundary to be within
                      // the element rather than immediately before or after it
                      workingNode.innerHTML = "&#feff;";
      
                      // insertBefore is supposed to work like appendChild if the second parameter is null. However, a bug report
                      // for IERange suggests that it can crash the browser: http://code.google.com/p/ierange/issues/detail?id=12
                      if (boundaryNode) {
                          boundaryParent.insertBefore(workingNode, boundaryNode);
                      } else {
                          boundaryParent.appendChild(workingNode);
                      }
      
                      workingRange.moveToElementText(workingNode);
                      workingRange.collapse(!isStart);
      
                      // Clean up
                      boundaryParent.removeChild(workingNode);
      
                      // Move the working range to the text offset, if required
                      if (nodeIsDataNode) {
                          workingRange[isStart ? "moveStart" : "moveEnd"]("character", boundaryOffset);
                      }
      
                      return workingRange;
                  };
      
                  /*------------------------------------------------------------------------------------------------------------*/
      
                  // This is a wrapper around a TextRange, providing full DOM Range functionality using rangy's DomRange as a
                  // prototype
      
                  WrappedTextRange = function(textRange) {
                      this.textRange = textRange;
                      this.refresh();
                  };
      
                  WrappedTextRange.prototype = new DomRange(document);
      
                  WrappedTextRange.prototype.refresh = function() {
                      var start, end, startBoundary;
      
                      // TextRange's parentElement() method cannot be trusted. getTextRangeContainerElement() works around that.
                      var rangeContainerElement = getTextRangeContainerElement(this.textRange);
      
                      if (textRangeIsCollapsed(this.textRange)) {
                          end = start = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true,
                              true).boundaryPosition;
                      } else {
                          startBoundary = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true, false);
                          start = startBoundary.boundaryPosition;
      
                          // An optimization used here is that if the start and end boundaries have the same parent element, the
                          // search scope for the end boundary can be limited to exclude the portion of the element that precedes
                          // the start boundary
                          end = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, false, false,
                              startBoundary.nodeInfo).boundaryPosition;
                      }
      
                      this.setStart(start.node, start.offset);
                      this.setEnd(end.node, end.offset);
                  };
      
                  WrappedTextRange.prototype.getName = function() {
                      return "WrappedTextRange";
                  };
      
                  DomRange.copyComparisonConstants(WrappedTextRange);
      
                  var rangeToTextRange = function(range) {
                      if (range.collapsed) {
                          return createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);
                      } else {
                          var startRange = createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);
                          var endRange = createBoundaryTextRange(new DomPosition(range.endContainer, range.endOffset), false);
                          var textRange = getBody( DomRange.getRangeDocument(range) ).createTextRange();
                          textRange.setEndPoint("StartToStart", startRange);
                          textRange.setEndPoint("EndToEnd", endRange);
                          return textRange;
                      }
                  };
      
                  WrappedTextRange.rangeToTextRange = rangeToTextRange;
      
                  WrappedTextRange.prototype.toTextRange = function() {
                      return rangeToTextRange(this);
                  };
      
                  api.WrappedTextRange = WrappedTextRange;
      
                  // IE 9 and above have both implementations and Rangy makes both available. The next few lines sets which
                  // implementation to use by default.
                  if (!api.features.implementsDomRange || api.config.preferTextRange) {
                      // Add WrappedTextRange as the Range property of the global object to allow expression like Range.END_TO_END to work
                      var globalObj = (function(f) { return f("return this;")(); })(Function);
                      if (typeof globalObj.Range == "undefined") {
                          globalObj.Range = WrappedTextRange;
                      }
      
                      api.createNativeRange = function(doc) {
                          doc = getContentDocument(doc, module, "createNativeRange");
                          return getBody(doc).createTextRange();
                      };
      
                      api.WrappedRange = WrappedTextRange;
                  }
              }
      
              api.createRange = function(doc) {
                  doc = getContentDocument(doc, module, "createRange");
                  return new api.WrappedRange(api.createNativeRange(doc));
              };
      
              api.createRangyRange = function(doc) {
                  doc = getContentDocument(doc, module, "createRangyRange");
                  return new DomRange(doc);
              };
      
              api.createIframeRange = function(iframeEl) {
                  module.deprecationNotice("createIframeRange()", "createRange(iframeEl)");
                  return api.createRange(iframeEl);
              };
      
              api.createIframeRangyRange = function(iframeEl) {
                  module.deprecationNotice("createIframeRangyRange()", "createRangyRange(iframeEl)");
                  return api.createRangyRange(iframeEl);
              };
      
              api.addShimListener(function(win) {
                  var doc = win.document;
                  if (typeof doc.createRange == "undefined") {
                      doc.createRange = function() {
                          return api.createRange(doc);
                      };
                  }
                  doc = win = null;
              });
          });
      
          /*----------------------------------------------------------------------------------------------------------------*/
      
          // This module creates a selection object wrapper that conforms as closely as possible to the Selection specification
          // in the HTML Editing spec (http://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#selections)
          api.createCoreModule("WrappedSelection", ["DomRange", "WrappedRange"], function(api, module) {
              api.config.checkSelectionRanges = true;
      
              var BOOLEAN = "boolean";
              var NUMBER = "number";
              var dom = api.dom;
              var util = api.util;
              var isHostMethod = util.isHostMethod;
              var DomRange = api.DomRange;
              var WrappedRange = api.WrappedRange;
              var DOMException = api.DOMException;
              var DomPosition = dom.DomPosition;
              var getNativeSelection;
              var selectionIsCollapsed;
              var features = api.features;
              var CONTROL = "Control";
              var getDocument = dom.getDocument;
              var getBody = dom.getBody;
              var rangesEqual = DomRange.rangesEqual;
      
      
              // Utility function to support direction parameters in the API that may be a string ("backward" or "forward") or a
              // Boolean (true for backwards).
              function isDirectionBackward(dir) {
                  return (typeof dir == "string") ? /^backward(s)?$/i.test(dir) : !!dir;
              }
      
              function getWindow(win, methodName) {
                  if (!win) {
                      return window;
                  } else if (dom.isWindow(win)) {
                      return win;
                  } else if (win instanceof WrappedSelection) {
                      return win.win;
                  } else {
                      var doc = dom.getContentDocument(win, module, methodName);
                      return dom.getWindow(doc);
                  }
              }
      
              function getWinSelection(winParam) {
                  return getWindow(winParam, "getWinSelection").getSelection();
              }
      
              function getDocSelection(winParam) {
                  return getWindow(winParam, "getDocSelection").document.selection;
              }
              
              function winSelectionIsBackward(sel) {
                  var backward = false;
                  if (sel.anchorNode) {
                      backward = (dom.comparePoints(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset) == 1);
                  }
                  return backward;
              }
      
              // Test for the Range/TextRange and Selection features required
              // Test for ability to retrieve selection
              var implementsWinGetSelection = isHostMethod(window, "getSelection"),
                  implementsDocSelection = util.isHostObject(document, "selection");
      
              features.implementsWinGetSelection = implementsWinGetSelection;
              features.implementsDocSelection = implementsDocSelection;
      
              var useDocumentSelection = implementsDocSelection && (!implementsWinGetSelection || api.config.preferTextRange);
      
              if (useDocumentSelection) {
                  getNativeSelection = getDocSelection;
                  api.isSelectionValid = function(winParam) {
                      var doc = getWindow(winParam, "isSelectionValid").document, nativeSel = doc.selection;
      
                      // Check whether the selection TextRange is actually contained within the correct document
                      return (nativeSel.type != "None" || getDocument(nativeSel.createRange().parentElement()) == doc);
                  };
              } else if (implementsWinGetSelection) {
                  getNativeSelection = getWinSelection;
                  api.isSelectionValid = function() {
                      return true;
                  };
              } else {
                  module.fail("Neither document.selection or window.getSelection() detected.");
              }
      
              api.getNativeSelection = getNativeSelection;
      
              var testSelection = getNativeSelection();
              var testRange = api.createNativeRange(document);
              var body = getBody(document);
      
              // Obtaining a range from a selection
              var selectionHasAnchorAndFocus = util.areHostProperties(testSelection,
                  ["anchorNode", "focusNode", "anchorOffset", "focusOffset"]);
      
              features.selectionHasAnchorAndFocus = selectionHasAnchorAndFocus;
      
              // Test for existence of native selection extend() method
              var selectionHasExtend = isHostMethod(testSelection, "extend");
              features.selectionHasExtend = selectionHasExtend;
              
              // Test if rangeCount exists
              var selectionHasRangeCount = (typeof testSelection.rangeCount == NUMBER);
              features.selectionHasRangeCount = selectionHasRangeCount;
      
              var selectionSupportsMultipleRanges = false;
              var collapsedNonEditableSelectionsSupported = true;
      
              var addRangeBackwardToNative = selectionHasExtend ?
                  function(nativeSelection, range) {
                      var doc = DomRange.getRangeDocument(range);
                      var endRange = api.createRange(doc);
                      endRange.collapseToPoint(range.endContainer, range.endOffset);
                      nativeSelection.addRange(getNativeRange(endRange));
                      nativeSelection.extend(range.startContainer, range.startOffset);
                  } : null;
      
              if (util.areHostMethods(testSelection, ["addRange", "getRangeAt", "removeAllRanges"]) &&
                      typeof testSelection.rangeCount == NUMBER && features.implementsDomRange) {
      
                  (function() {
                      // Previously an iframe was used but this caused problems in some circumstances in IE, so tests are
                      // performed on the current document's selection. See issue 109.
      
                      // Note also that if a selection previously existed, it is wiped by these tests. This should usually be fine
                      // because initialization usually happens when the document loads, but could be a problem for a script that
                      // loads and initializes Rangy later. If anyone complains, code could be added to save and restore the
                      // selection.
                      var sel = window.getSelection();
                      if (sel) {
                          // Store the current selection
                          var originalSelectionRangeCount = sel.rangeCount;
                          var selectionHasMultipleRanges = (originalSelectionRangeCount > 1);
                          var originalSelectionRanges = [];
                          var originalSelectionBackward = winSelectionIsBackward(sel); 
                          for (var i = 0; i < originalSelectionRangeCount; ++i) {
                              originalSelectionRanges[i] = sel.getRangeAt(i);
                          }
                          
                          // Create some test elements
                          var body = getBody(document);
                          var testEl = body.appendChild( document.createElement("div") );
                          testEl.contentEditable = "false";
                          var textNode = testEl.appendChild( document.createTextNode("\u00a0\u00a0\u00a0") );
      
                          // Test whether the native selection will allow a collapsed selection within a non-editable element
                          var r1 = document.createRange();
      
                          r1.setStart(textNode, 1);
                          r1.collapse(true);
                          sel.addRange(r1);
                          collapsedNonEditableSelectionsSupported = (sel.rangeCount == 1);
                          sel.removeAllRanges();
      
                          // Test whether the native selection is capable of supporting multiple ranges.
                          if (!selectionHasMultipleRanges) {
                              // Doing the original feature test here in Chrome 36 (and presumably later versions) prints a
                              // console error of "Discontiguous selection is not supported." that cannot be suppressed. There's
                              // nothing we can do about this while retaining the feature test so we have to resort to a browser
                              // sniff. I'm not happy about it. See
                              // https://code.google.com/p/chromium/issues/detail?id=399791
                              var chromeMatch = window.navigator.appVersion.match(/Chrome\/(.*?) /);
                              if (chromeMatch && parseInt(chromeMatch[1]) >= 36) {
                                  selectionSupportsMultipleRanges = false;
                              } else {
                                  var r2 = r1.cloneRange();
                                  r1.setStart(textNode, 0);
                                  r2.setEnd(textNode, 3);
                                  r2.setStart(textNode, 2);
                                  sel.addRange(r1);
                                  sel.addRange(r2);
                                  selectionSupportsMultipleRanges = (sel.rangeCount == 2);
                              }
                          }
      
                          // Clean up
                          body.removeChild(testEl);
                          sel.removeAllRanges();
      
                          for (i = 0; i < originalSelectionRangeCount; ++i) {
                              if (i == 0 && originalSelectionBackward) {
                                  if (addRangeBackwardToNative) {
                                      addRangeBackwardToNative(sel, originalSelectionRanges[i]);
                                  } else {
                                      api.warn("Rangy initialization: original selection was backwards but selection has been restored forwards because the browser does not support Selection.extend");
                                      sel.addRange(originalSelectionRanges[i]);
                                  }
                              } else {
                                  sel.addRange(originalSelectionRanges[i]);
                              }
                          }
                      }
                  })();
              }
      
              features.selectionSupportsMultipleRanges = selectionSupportsMultipleRanges;
              features.collapsedNonEditableSelectionsSupported = collapsedNonEditableSelectionsSupported;
      
              // ControlRanges
              var implementsControlRange = false, testControlRange;
      
              if (body && isHostMethod(body, "createControlRange")) {
                  testControlRange = body.createControlRange();
                  if (util.areHostProperties(testControlRange, ["item", "add"])) {
                      implementsControlRange = true;
                  }
              }
              features.implementsControlRange = implementsControlRange;
      
              // Selection collapsedness
              if (selectionHasAnchorAndFocus) {
                  selectionIsCollapsed = function(sel) {
                      return sel.anchorNode === sel.focusNode && sel.anchorOffset === sel.focusOffset;
                  };
              } else {
                  selectionIsCollapsed = function(sel) {
                      return sel.rangeCount ? sel.getRangeAt(sel.rangeCount - 1).collapsed : false;
                  };
              }
      
              function updateAnchorAndFocusFromRange(sel, range, backward) {
                  var anchorPrefix = backward ? "end" : "start", focusPrefix = backward ? "start" : "end";
                  sel.anchorNode = range[anchorPrefix + "Container"];
                  sel.anchorOffset = range[anchorPrefix + "Offset"];
                  sel.focusNode = range[focusPrefix + "Container"];
                  sel.focusOffset = range[focusPrefix + "Offset"];
              }
      
              function updateAnchorAndFocusFromNativeSelection(sel) {
                  var nativeSel = sel.nativeSelection;
                  sel.anchorNode = nativeSel.anchorNode;
                  sel.anchorOffset = nativeSel.anchorOffset;
                  sel.focusNode = nativeSel.focusNode;
                  sel.focusOffset = nativeSel.focusOffset;
              }
      
              function updateEmptySelection(sel) {
                  sel.anchorNode = sel.focusNode = null;
                  sel.anchorOffset = sel.focusOffset = 0;
                  sel.rangeCount = 0;
                  sel.isCollapsed = true;
                  sel._ranges.length = 0;
              }
      
              function getNativeRange(range) {
                  var nativeRange;
                  if (range instanceof DomRange) {
                      nativeRange = api.createNativeRange(range.getDocument());
                      nativeRange.setEnd(range.endContainer, range.endOffset);
                      nativeRange.setStart(range.startContainer, range.startOffset);
                  } else if (range instanceof WrappedRange) {
                      nativeRange = range.nativeRange;
                  } else if (features.implementsDomRange && (range instanceof dom.getWindow(range.startContainer).Range)) {
                      nativeRange = range;
                  }
                  return nativeRange;
              }
      
              function rangeContainsSingleElement(rangeNodes) {
                  if (!rangeNodes.length || rangeNodes[0].nodeType != 1) {
                      return false;
                  }
                  for (var i = 1, len = rangeNodes.length; i < len; ++i) {
                      if (!dom.isAncestorOf(rangeNodes[0], rangeNodes[i])) {
                          return false;
                      }
                  }
                  return true;
              }
      
              function getSingleElementFromRange(range) {
                  var nodes = range.getNodes();
                  if (!rangeContainsSingleElement(nodes)) {
                      throw module.createError("getSingleElementFromRange: range " + range.inspect() + " did not consist of a single element");
                  }
                  return nodes[0];
              }
      
              // Simple, quick test which only needs to distinguish between a TextRange and a ControlRange
              function isTextRange(range) {
                  return !!range && typeof range.text != "undefined";
              }
      
              function updateFromTextRange(sel, range) {
                  // Create a Range from the selected TextRange
                  var wrappedRange = new WrappedRange(range);
                  sel._ranges = [wrappedRange];
      
                  updateAnchorAndFocusFromRange(sel, wrappedRange, false);
                  sel.rangeCount = 1;
                  sel.isCollapsed = wrappedRange.collapsed;
              }
      
              function updateControlSelection(sel) {
                  // Update the wrapped selection based on what's now in the native selection
                  sel._ranges.length = 0;
                  if (sel.docSelection.type == "None") {
                      updateEmptySelection(sel);
                  } else {
                      var controlRange = sel.docSelection.createRange();
                      if (isTextRange(controlRange)) {
                          // This case (where the selection type is "Control" and calling createRange() on the selection returns
                          // a TextRange) can happen in IE 9. It happens, for example, when all elements in the selected
                          // ControlRange have been removed from the ControlRange and removed from the document.
                          updateFromTextRange(sel, controlRange);
                      } else {
                          sel.rangeCount = controlRange.length;
                          var range, doc = getDocument(controlRange.item(0));
                          for (var i = 0; i < sel.rangeCount; ++i) {
                              range = api.createRange(doc);
                              range.selectNode(controlRange.item(i));
                              sel._ranges.push(range);
                          }
                          sel.isCollapsed = sel.rangeCount == 1 && sel._ranges[0].collapsed;
                          updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], false);
                      }
                  }
              }
      
              function addRangeToControlSelection(sel, range) {
                  var controlRange = sel.docSelection.createRange();
                  var rangeElement = getSingleElementFromRange(range);
      
                  // Create a new ControlRange containing all the elements in the selected ControlRange plus the element
                  // contained by the supplied range
                  var doc = getDocument(controlRange.item(0));
                  var newControlRange = getBody(doc).createControlRange();
                  for (var i = 0, len = controlRange.length; i < len; ++i) {
                      newControlRange.add(controlRange.item(i));
                  }
                  try {
                      newControlRange.add(rangeElement);
                  } catch (ex) {
                      throw module.createError("addRange(): Element within the specified Range could not be added to control selection (does it have layout?)");
                  }
                  newControlRange.select();
      
                  // Update the wrapped selection based on what's now in the native selection
                  updateControlSelection(sel);
              }
      
              var getSelectionRangeAt;
      
              if (isHostMethod(testSelection, "getRangeAt")) {
                  // try/catch is present because getRangeAt() must have thrown an error in some browser and some situation.
                  // Unfortunately, I didn't write a comment about the specifics and am now scared to take it out. Let that be a
                  // lesson to us all, especially me.
                  getSelectionRangeAt = function(sel, index) {
                      try {
                          return sel.getRangeAt(index);
                      } catch (ex) {
                          return null;
                      }
                  };
              } else if (selectionHasAnchorAndFocus) {
                  getSelectionRangeAt = function(sel) {
                      var doc = getDocument(sel.anchorNode);
                      var range = api.createRange(doc);
                      range.setStartAndEnd(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset);
      
                      // Handle the case when the selection was selected backwards (from the end to the start in the
                      // document)
                      if (range.collapsed !== this.isCollapsed) {
                          range.setStartAndEnd(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset);
                      }
      
                      return range;
                  };
              }
      
              function WrappedSelection(selection, docSelection, win) {
                  this.nativeSelection = selection;
                  this.docSelection = docSelection;
                  this._ranges = [];
                  this.win = win;
                  this.refresh();
              }
      
              WrappedSelection.prototype = api.selectionPrototype;
      
              function deleteProperties(sel) {
                  sel.win = sel.anchorNode = sel.focusNode = sel._ranges = null;
                  sel.rangeCount = sel.anchorOffset = sel.focusOffset = 0;
                  sel.detached = true;
              }
      
              var cachedRangySelections = [];
      
              function actOnCachedSelection(win, action) {
                  var i = cachedRangySelections.length, cached, sel;
                  while (i--) {
                      cached = cachedRangySelections[i];
                      sel = cached.selection;
                      if (action == "deleteAll") {
                          deleteProperties(sel);
                      } else if (cached.win == win) {
                          if (action == "delete") {
                              cachedRangySelections.splice(i, 1);
                              return true;
                          } else {
                              return sel;
                          }
                      }
                  }
                  if (action == "deleteAll") {
                      cachedRangySelections.length = 0;
                  }
                  return null;
              }
      
              var getSelection = function(win) {
                  // Check if the parameter is a Rangy Selection object
                  if (win && win instanceof WrappedSelection) {
                      win.refresh();
                      return win;
                  }
      
                  win = getWindow(win, "getNativeSelection");
      
                  var sel = actOnCachedSelection(win);
                  var nativeSel = getNativeSelection(win), docSel = implementsDocSelection ? getDocSelection(win) : null;
                  if (sel) {
                      sel.nativeSelection = nativeSel;
                      sel.docSelection = docSel;
                      sel.refresh();
                  } else {
                      sel = new WrappedSelection(nativeSel, docSel, win);
                      cachedRangySelections.push( { win: win, selection: sel } );
                  }
                  return sel;
              };
      
              api.getSelection = getSelection;
      
              api.getIframeSelection = function(iframeEl) {
                  module.deprecationNotice("getIframeSelection()", "getSelection(iframeEl)");
                  return api.getSelection(dom.getIframeWindow(iframeEl));
              };
      
              var selProto = WrappedSelection.prototype;
      
              function createControlSelection(sel, ranges) {
                  // Ensure that the selection becomes of type "Control"
                  var doc = getDocument(ranges[0].startContainer);
                  var controlRange = getBody(doc).createControlRange();
                  for (var i = 0, el, len = ranges.length; i < len; ++i) {
                      el = getSingleElementFromRange(ranges[i]);
                      try {
                          controlRange.add(el);
                      } catch (ex) {
                          throw module.createError("setRanges(): Element within one of the specified Ranges could not be added to control selection (does it have layout?)");
                      }
                  }
                  controlRange.select();
      
                  // Update the wrapped selection based on what's now in the native selection
                  updateControlSelection(sel);
              }
      
              // Selecting a range
              if (!useDocumentSelection && selectionHasAnchorAndFocus && util.areHostMethods(testSelection, ["removeAllRanges", "addRange"])) {
                  selProto.removeAllRanges = function() {
                      this.nativeSelection.removeAllRanges();
                      updateEmptySelection(this);
                  };
      
                  var addRangeBackward = function(sel, range) {
                      addRangeBackwardToNative(sel.nativeSelection, range);
                      sel.refresh();
                  };
      
                  if (selectionHasRangeCount) {
                      selProto.addRange = function(range, direction) {
                          if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {
                              addRangeToControlSelection(this, range);
                          } else {
                              if (isDirectionBackward(direction) && selectionHasExtend) {
                                  addRangeBackward(this, range);
                              } else {
                                  var previousRangeCount;
                                  if (selectionSupportsMultipleRanges) {
                                      previousRangeCount = this.rangeCount;
                                  } else {
                                      this.removeAllRanges();
                                      previousRangeCount = 0;
                                  }
                                  // Clone the native range so that changing the selected range does not affect the selection.
                                  // This is contrary to the spec but is the only way to achieve consistency between browsers. See
                                  // issue 80.
                                  var clonedNativeRange = getNativeRange(range).cloneRange();
                                  try {
                                      this.nativeSelection.addRange(clonedNativeRange);
                                  } catch (ex) {
                                  }
      
                                  // Check whether adding the range was successful
                                  this.rangeCount = this.nativeSelection.rangeCount;
      
                                  if (this.rangeCount == previousRangeCount + 1) {
                                      // The range was added successfully
      
                                      // Check whether the range that we added to the selection is reflected in the last range extracted from
                                      // the selection
                                      if (api.config.checkSelectionRanges) {
                                          var nativeRange = getSelectionRangeAt(this.nativeSelection, this.rangeCount - 1);
                                          if (nativeRange && !rangesEqual(nativeRange, range)) {
                                              // Happens in WebKit with, for example, a selection placed at the start of a text node
                                              range = new WrappedRange(nativeRange);
                                          }
                                      }
                                      this._ranges[this.rangeCount - 1] = range;
                                      updateAnchorAndFocusFromRange(this, range, selectionIsBackward(this.nativeSelection));
                                      this.isCollapsed = selectionIsCollapsed(this);
                                  } else {
                                      // The range was not added successfully. The simplest thing is to refresh
                                      this.refresh();
                                  }
                              }
                          }
                      };
                  } else {
                      selProto.addRange = function(range, direction) {
                          if (isDirectionBackward(direction) && selectionHasExtend) {
                              addRangeBackward(this, range);
                          } else {
                              this.nativeSelection.addRange(getNativeRange(range));
                              this.refresh();
                          }
                      };
                  }
      
                  selProto.setRanges = function(ranges) {
                      if (implementsControlRange && implementsDocSelection && ranges.length > 1) {
                          createControlSelection(this, ranges);
                      } else {
                          this.removeAllRanges();
                          for (var i = 0, len = ranges.length; i < len; ++i) {
                              this.addRange(ranges[i]);
                          }
                      }
                  };
              } else if (isHostMethod(testSelection, "empty") && isHostMethod(testRange, "select") &&
                         implementsControlRange && useDocumentSelection) {
      
                  selProto.removeAllRanges = function() {
                      // Added try/catch as fix for issue #21
                      try {
                          this.docSelection.empty();
      
                          // Check for empty() not working (issue #24)
                          if (this.docSelection.type != "None") {
                              // Work around failure to empty a control selection by instead selecting a TextRange and then
                              // calling empty()
                              var doc;
                              if (this.anchorNode) {
                                  doc = getDocument(this.anchorNode);
                              } else if (this.docSelection.type == CONTROL) {
                                  var controlRange = this.docSelection.createRange();
                                  if (controlRange.length) {
                                      doc = getDocument( controlRange.item(0) );
                                  }
                              }
                              if (doc) {
                                  var textRange = getBody(doc).createTextRange();
                                  textRange.select();
                                  this.docSelection.empty();
                              }
                          }
                      } catch(ex) {}
                      updateEmptySelection(this);
                  };
      
                  selProto.addRange = function(range) {
                      if (this.docSelection.type == CONTROL) {
                          addRangeToControlSelection(this, range);
                      } else {
                          api.WrappedTextRange.rangeToTextRange(range).select();
                          this._ranges[0] = range;
                          this.rangeCount = 1;
                          this.isCollapsed = this._ranges[0].collapsed;
                          updateAnchorAndFocusFromRange(this, range, false);
                      }
                  };
      
                  selProto.setRanges = function(ranges) {
                      this.removeAllRanges();
                      var rangeCount = ranges.length;
                      if (rangeCount > 1) {
                          createControlSelection(this, ranges);
                      } else if (rangeCount) {
                          this.addRange(ranges[0]);
                      }
                  };
              } else {
                  module.fail("No means of selecting a Range or TextRange was found");
                  return false;
              }
      
              selProto.getRangeAt = function(index) {
                  if (index < 0 || index >= this.rangeCount) {
                      throw new DOMException("INDEX_SIZE_ERR");
                  } else {
                      // Clone the range to preserve selection-range independence. See issue 80.
                      return this._ranges[index].cloneRange();
                  }
              };
      
              var refreshSelection;
      
              if (useDocumentSelection) {
                  refreshSelection = function(sel) {
                      var range;
                      if (api.isSelectionValid(sel.win)) {
                          range = sel.docSelection.createRange();
                      } else {
                          range = getBody(sel.win.document).createTextRange();
                          range.collapse(true);
                      }
      
                      if (sel.docSelection.type == CONTROL) {
                          updateControlSelection(sel);
                      } else if (isTextRange(range)) {
                          updateFromTextRange(sel, range);
                      } else {
                          updateEmptySelection(sel);
                      }
                  };
              } else if (isHostMethod(testSelection, "getRangeAt") && typeof testSelection.rangeCount == NUMBER) {
                  refreshSelection = function(sel) {
                      if (implementsControlRange && implementsDocSelection && sel.docSelection.type == CONTROL) {
                          updateControlSelection(sel);
                      } else {
                          sel._ranges.length = sel.rangeCount = sel.nativeSelection.rangeCount;
                          if (sel.rangeCount) {
                              for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                                  sel._ranges[i] = new api.WrappedRange(sel.nativeSelection.getRangeAt(i));
                              }
                              updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], selectionIsBackward(sel.nativeSelection));
                              sel.isCollapsed = selectionIsCollapsed(sel);
                          } else {
                              updateEmptySelection(sel);
                          }
                      }
                  };
              } else if (selectionHasAnchorAndFocus && typeof testSelection.isCollapsed == BOOLEAN && typeof testRange.collapsed == BOOLEAN && features.implementsDomRange) {
                  refreshSelection = function(sel) {
                      var range, nativeSel = sel.nativeSelection;
                      if (nativeSel.anchorNode) {
                          range = getSelectionRangeAt(nativeSel, 0);
                          sel._ranges = [range];
                          sel.rangeCount = 1;
                          updateAnchorAndFocusFromNativeSelection(sel);
                          sel.isCollapsed = selectionIsCollapsed(sel);
                      } else {
                          updateEmptySelection(sel);
                      }
                  };
              } else {
                  module.fail("No means of obtaining a Range or TextRange from the user's selection was found");
                  return false;
              }
      
              selProto.refresh = function(checkForChanges) {
                  var oldRanges = checkForChanges ? this._ranges.slice(0) : null;
                  var oldAnchorNode = this.anchorNode, oldAnchorOffset = this.anchorOffset;
      
                  refreshSelection(this);
                  if (checkForChanges) {
                      // Check the range count first
                      var i = oldRanges.length;
                      if (i != this._ranges.length) {
                          return true;
                      }
      
                      // Now check the direction. Checking the anchor position is the same is enough since we're checking all the
                      // ranges after this
                      if (this.anchorNode != oldAnchorNode || this.anchorOffset != oldAnchorOffset) {
                          return true;
                      }
      
                      // Finally, compare each range in turn
                      while (i--) {
                          if (!rangesEqual(oldRanges[i], this._ranges[i])) {
                              return true;
                          }
                      }
                      return false;
                  }
              };
      
              // Removal of a single range
              var removeRangeManually = function(sel, range) {
                  var ranges = sel.getAllRanges();
                  sel.removeAllRanges();
                  for (var i = 0, len = ranges.length; i < len; ++i) {
                      if (!rangesEqual(range, ranges[i])) {
                          sel.addRange(ranges[i]);
                      }
                  }
                  if (!sel.rangeCount) {
                      updateEmptySelection(sel);
                  }
              };
      
              if (implementsControlRange && implementsDocSelection) {
                  selProto.removeRange = function(range) {
                      if (this.docSelection.type == CONTROL) {
                          var controlRange = this.docSelection.createRange();
                          var rangeElement = getSingleElementFromRange(range);
      
                          // Create a new ControlRange containing all the elements in the selected ControlRange minus the
                          // element contained by the supplied range
                          var doc = getDocument(controlRange.item(0));
                          var newControlRange = getBody(doc).createControlRange();
                          var el, removed = false;
                          for (var i = 0, len = controlRange.length; i < len; ++i) {
                              el = controlRange.item(i);
                              if (el !== rangeElement || removed) {
                                  newControlRange.add(controlRange.item(i));
                              } else {
                                  removed = true;
                              }
                          }
                          newControlRange.select();
      
                          // Update the wrapped selection based on what's now in the native selection
                          updateControlSelection(this);
                      } else {
                          removeRangeManually(this, range);
                      }
                  };
              } else {
                  selProto.removeRange = function(range) {
                      removeRangeManually(this, range);
                  };
              }
      
              // Detecting if a selection is backward
              var selectionIsBackward;
              if (!useDocumentSelection && selectionHasAnchorAndFocus && features.implementsDomRange) {
                  selectionIsBackward = winSelectionIsBackward;
      
                  selProto.isBackward = function() {
                      return selectionIsBackward(this);
                  };
              } else {
                  selectionIsBackward = selProto.isBackward = function() {
                      return false;
                  };
              }
      
              // Create an alias for backwards compatibility. From 1.3, everything is "backward" rather than "backwards"
              selProto.isBackwards = selProto.isBackward;
      
              // Selection stringifier
              // This is conformant to the old HTML5 selections draft spec but differs from WebKit and Mozilla's implementation.
              // The current spec does not yet define this method.
              selProto.toString = function() {
                  var rangeTexts = [];
                  for (var i = 0, len = this.rangeCount; i < len; ++i) {
                      rangeTexts[i] = "" + this._ranges[i];
                  }
                  return rangeTexts.join("");
              };
      
              function assertNodeInSameDocument(sel, node) {
                  if (sel.win.document != getDocument(node)) {
                      throw new DOMException("WRONG_DOCUMENT_ERR");
                  }
              }
      
              // No current browser conforms fully to the spec for this method, so Rangy's own method is always used
              selProto.collapse = function(node, offset) {
                  assertNodeInSameDocument(this, node);
                  var range = api.createRange(node);
                  range.collapseToPoint(node, offset);
                  this.setSingleRange(range);
                  this.isCollapsed = true;
              };
      
              selProto.collapseToStart = function() {
                  if (this.rangeCount) {
                      var range = this._ranges[0];
                      this.collapse(range.startContainer, range.startOffset);
                  } else {
                      throw new DOMException("INVALID_STATE_ERR");
                  }
              };
      
              selProto.collapseToEnd = function() {
                  if (this.rangeCount) {
                      var range = this._ranges[this.rangeCount - 1];
                      this.collapse(range.endContainer, range.endOffset);
                  } else {
                      throw new DOMException("INVALID_STATE_ERR");
                  }
              };
      
              // The spec is very specific on how selectAllChildren should be implemented so the native implementation is
              // never used by Rangy.
              selProto.selectAllChildren = function(node) {
                  assertNodeInSameDocument(this, node);
                  var range = api.createRange(node);
                  range.selectNodeContents(node);
                  this.setSingleRange(range);
              };
      
              selProto.deleteFromDocument = function() {
                  // Sepcial behaviour required for IE's control selections
                  if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {
                      var controlRange = this.docSelection.createRange();
                      var element;
                      while (controlRange.length) {
                          element = controlRange.item(0);
                          controlRange.remove(element);
                          element.parentNode.removeChild(element);
                      }
                      this.refresh();
                  } else if (this.rangeCount) {
                      var ranges = this.getAllRanges();
                      if (ranges.length) {
                          this.removeAllRanges();
                          for (var i = 0, len = ranges.length; i < len; ++i) {
                              ranges[i].deleteContents();
                          }
                          // The spec says nothing about what the selection should contain after calling deleteContents on each
                          // range. Firefox moves the selection to where the final selected range was, so we emulate that
                          this.addRange(ranges[len - 1]);
                      }
                  }
              };
      
              // The following are non-standard extensions
              selProto.eachRange = function(func, returnValue) {
                  for (var i = 0, len = this._ranges.length; i < len; ++i) {
                      if ( func( this.getRangeAt(i) ) ) {
                          return returnValue;
                      }
                  }
              };
      
              selProto.getAllRanges = function() {
                  var ranges = [];
                  this.eachRange(function(range) {
                      ranges.push(range);
                  });
                  return ranges;
              };
      
              selProto.setSingleRange = function(range, direction) {
                  this.removeAllRanges();
                  this.addRange(range, direction);
              };
      
              selProto.callMethodOnEachRange = function(methodName, params) {
                  var results = [];
                  this.eachRange( function(range) {
                      results.push( range[methodName].apply(range, params) );
                  } );
                  return results;
              };
              
              function createStartOrEndSetter(isStart) {
                  return function(node, offset) {
                      var range;
                      if (this.rangeCount) {
                          range = this.getRangeAt(0);
                          range["set" + (isStart ? "Start" : "End")](node, offset);
                      } else {
                          range = api.createRange(this.win.document);
                          range.setStartAndEnd(node, offset);
                      }
                      this.setSingleRange(range, this.isBackward());
                  };
              }
      
              selProto.setStart = createStartOrEndSetter(true);
              selProto.setEnd = createStartOrEndSetter(false);
              
              // Add select() method to Range prototype. Any existing selection will be removed.
              api.rangePrototype.select = function(direction) {
                  getSelection( this.getDocument() ).setSingleRange(this, direction);
              };
      
              selProto.changeEachRange = function(func) {
                  var ranges = [];
                  var backward = this.isBackward();
      
                  this.eachRange(function(range) {
                      func(range);
                      ranges.push(range);
                  });
      
                  this.removeAllRanges();
                  if (backward && ranges.length == 1) {
                      this.addRange(ranges[0], "backward");
                  } else {
                      this.setRanges(ranges);
                  }
              };
      
              selProto.containsNode = function(node, allowPartial) {
                  return this.eachRange( function(range) {
                      return range.containsNode(node, allowPartial);
                  }, true ) || false;
              };
      
              selProto.getBookmark = function(containerNode) {
                  return {
                      backward: this.isBackward(),
                      rangeBookmarks: this.callMethodOnEachRange("getBookmark", [containerNode])
                  };
              };
      
              selProto.moveToBookmark = function(bookmark) {
                  var selRanges = [];
                  for (var i = 0, rangeBookmark, range; rangeBookmark = bookmark.rangeBookmarks[i++]; ) {
                      range = api.createRange(this.win);
                      range.moveToBookmark(rangeBookmark);
                      selRanges.push(range);
                  }
                  if (bookmark.backward) {
                      this.setSingleRange(selRanges[0], "backward");
                  } else {
                      this.setRanges(selRanges);
                  }
              };
      
              selProto.toHtml = function() {
                  var rangeHtmls = [];
                  this.eachRange(function(range) {
                      rangeHtmls.push( DomRange.toHtml(range) );
                  });
                  return rangeHtmls.join("");
              };
      
              if (features.implementsTextRange) {
                  selProto.getNativeTextRange = function() {
                      var sel, textRange;
                      if ( (sel = this.docSelection) ) {
                          var range = sel.createRange();
                          if (isTextRange(range)) {
                              return range;
                          } else {
                              throw module.createError("getNativeTextRange: selection is a control selection"); 
                          }
                      } else if (this.rangeCount > 0) {
                          return api.WrappedTextRange.rangeToTextRange( this.getRangeAt(0) );
                      } else {
                          throw module.createError("getNativeTextRange: selection contains no range");
                      }
                  };
              }
      
              function inspect(sel) {
                  var rangeInspects = [];
                  var anchor = new DomPosition(sel.anchorNode, sel.anchorOffset);
                  var focus = new DomPosition(sel.focusNode, sel.focusOffset);
                  var name = (typeof sel.getName == "function") ? sel.getName() : "Selection";
      
                  if (typeof sel.rangeCount != "undefined") {
                      for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                          rangeInspects[i] = DomRange.inspect(sel.getRangeAt(i));
                      }
                  }
                  return "[" + name + "(Ranges: " + rangeInspects.join(", ") +
                          ")(anchor: " + anchor.inspect() + ", focus: " + focus.inspect() + "]";
              }
      
              selProto.getName = function() {
                  return "WrappedSelection";
              };
      
              selProto.inspect = function() {
                  return inspect(this);
              };
      
              selProto.detach = function() {
                  actOnCachedSelection(this.win, "delete");
                  deleteProperties(this);
              };
      
              WrappedSelection.detachAll = function() {
                  actOnCachedSelection(null, "deleteAll");
              };
      
              WrappedSelection.inspect = inspect;
              WrappedSelection.isDirectionBackward = isDirectionBackward;
      
              api.Selection = WrappedSelection;
      
              api.selectionPrototype = selProto;
      
              api.addShimListener(function(win) {
                  if (typeof win.getSelection == "undefined") {
                      win.getSelection = function() {
                          return getSelection(win);
                      };
                  }
                  win = null;
              });
          });
          
      
          /*----------------------------------------------------------------------------------------------------------------*/
      
          // Wait for document to load before initializing
          var docReady = false;
      
          var loadHandler = function(e) {
              if (!docReady) {
                  docReady = true;
                  if (!api.initialized && api.config.autoInitialize) {
                      init();
                  }
              }
          };
      
          if (isBrowser) {
              // Test whether the document has already been loaded and initialize immediately if so
              if (/^(?:complete|interactive)$/.test(document.readyState)) {
                  loadHandler();
              } else {
                  if (isHostMethod(document, "addEventListener")) {
                      document.addEventListener("DOMContentLoaded", loadHandler, false);
                  }
      
                  // Add a fallback in case the DOMContentLoaded event isn't supported
                  addListener(window, "load", loadHandler);
              }
          }
      
          return api;
      }, /* build:replaceWithGlobalObject */this/* build:replaceWithGlobalObjectEnd */);
      /**
       * Class Applier module for Rangy.
       * Adds, removes and toggles classes on Ranges and Selections
       *
       * Part of Rangy, a cross-browser JavaScript range and selection library
       * http://code.google.com/p/rangy/
       *
       * Depends on Rangy core.
       *
       * Copyright 2014, Tim Down
       * Licensed under the MIT license.
       * Version: 1.3.0-alpha.20140827
       * Build date: 27 August 2014
       */
      (function(factory, root) {
          if (typeof define == "function" && define.amd) {
              // AMD. Register as an anonymous module with a dependency on Rangy.
              define(["./rangy-core"], factory);
          } else if (typeof module != "undefined" && typeof exports == "object") {
              // Node/CommonJS style
              module.exports = factory( require("rangy") );
          } else {
              // No AMD or CommonJS support so we use the rangy property of root (probably the global variable)
              factory(root.rangy);
          }
      })(function(rangy) {
          rangy.createModule("ClassApplier", ["WrappedSelection"], function(api, module) {
              var dom = api.dom;
              var DomPosition = dom.DomPosition;
              var contains = dom.arrayContains;
              var isHtmlNamespace = dom.isHtmlNamespace;
      
      
              var defaultTagName = "span";
      
              function each(obj, func) {
                  for (var i in obj) {
                      if (obj.hasOwnProperty(i)) {
                          if (func(i, obj[i]) === false) {
                              return false;
                          }
                      }
                  }
                  return true;
              }
              
              function trim(str) {
                  return str.replace(/^\s\s*/, "").replace(/\s\s*$/, "");
              }
      
              function hasClass(el, className) {
                  return el.className && new RegExp("(?:^|\\s)" + className + "(?:\\s|$)").test(el.className);
              }
      
              function addClass(el, className) {
                  if (el.className) {
                      if (!hasClass(el, className)) {
                          el.className += " " + className;
                      }
                  } else {
                      el.className = className;
                  }
              }
      
              var removeClass = (function() {
                  function replacer(matched, whiteSpaceBefore, whiteSpaceAfter) {
                      return (whiteSpaceBefore && whiteSpaceAfter) ? " " : "";
                  }
      
                  return function(el, className) {
                      if (el.className) {
                          el.className = el.className.replace(new RegExp("(^|\\s)" + className + "(\\s|$)"), replacer);
                      }
                  };
              })();
      
              function sortClassName(className) {
                  return className && className.split(/\s+/).sort().join(" ");
              }
      
              function getSortedClassName(el) {
                  return sortClassName(el.className);
              }
      
              function haveSameClasses(el1, el2) {
                  return getSortedClassName(el1) == getSortedClassName(el2);
              }
      
              function movePosition(position, oldParent, oldIndex, newParent, newIndex) {
                  var posNode = position.node, posOffset = position.offset;
                  var newNode = posNode, newOffset = posOffset;
      
                  if (posNode == newParent && posOffset > newIndex) {
                      ++newOffset;
                  }
      
                  if (posNode == oldParent && (posOffset == oldIndex  || posOffset == oldIndex + 1)) {
                      newNode = newParent;
                      newOffset += newIndex - oldIndex;
                  }
      
                  if (posNode == oldParent && posOffset > oldIndex + 1) {
                      --newOffset;
                  }
      
                  position.node = newNode;
                  position.offset = newOffset;
              }
              
              function movePositionWhenRemovingNode(position, parentNode, index) {
                  if (position.node == parentNode && position.offset > index) {
                      --position.offset;
                  }
              }
      
              function movePreservingPositions(node, newParent, newIndex, positionsToPreserve) {
                  // For convenience, allow newIndex to be -1 to mean "insert at the end".
                  if (newIndex == -1) {
                      newIndex = newParent.childNodes.length;
                  }
      
                  var oldParent = node.parentNode;
                  var oldIndex = dom.getNodeIndex(node);
      
                  for (var i = 0, position; position = positionsToPreserve[i++]; ) {
                      movePosition(position, oldParent, oldIndex, newParent, newIndex);
                  }
      
                  // Now actually move the node.
                  if (newParent.childNodes.length == newIndex) {
                      newParent.appendChild(node);
                  } else {
                      newParent.insertBefore(node, newParent.childNodes[newIndex]);
                  }
              }
              
              function removePreservingPositions(node, positionsToPreserve) {
      
                  var oldParent = node.parentNode;
                  var oldIndex = dom.getNodeIndex(node);
      
                  for (var i = 0, position; position = positionsToPreserve[i++]; ) {
                      movePositionWhenRemovingNode(position, oldParent, oldIndex);
                  }
      
                  node.parentNode.removeChild(node);
              }
      
              function moveChildrenPreservingPositions(node, newParent, newIndex, removeNode, positionsToPreserve) {
                  var child, children = [];
                  while ( (child = node.firstChild) ) {
                      movePreservingPositions(child, newParent, newIndex++, positionsToPreserve);
                      children.push(child);
                  }
                  if (removeNode) {
                      removePreservingPositions(node, positionsToPreserve);
                  }
                  return children;
              }
      
              function replaceWithOwnChildrenPreservingPositions(element, positionsToPreserve) {
                  return moveChildrenPreservingPositions(element, element.parentNode, dom.getNodeIndex(element), true, positionsToPreserve);
              }
      
              function rangeSelectsAnyText(range, textNode) {
                  var textNodeRange = range.cloneRange();
                  textNodeRange.selectNodeContents(textNode);
      
                  var intersectionRange = textNodeRange.intersection(range);
                  var text = intersectionRange ? intersectionRange.toString() : "";
      
                  return text != "";
              }
      
              function getEffectiveTextNodes(range) {
                  var nodes = range.getNodes([3]);
                  
                  // Optimization as per issue 145
                  
                  // Remove non-intersecting text nodes from the start of the range
                  var start = 0, node;
                  while ( (node = nodes[start]) && !rangeSelectsAnyText(range, node) ) {
                      ++start;
                  }
      
                  // Remove non-intersecting text nodes from the start of the range
                  var end = nodes.length - 1;
                  while ( (node = nodes[end]) && !rangeSelectsAnyText(range, node) ) {
                      --end;
                  }
                  
                  return nodes.slice(start, end + 1);
              }
      
              function elementsHaveSameNonClassAttributes(el1, el2) {
                  if (el1.attributes.length != el2.attributes.length) return false;
                  for (var i = 0, len = el1.attributes.length, attr1, attr2, name; i < len; ++i) {
                      attr1 = el1.attributes[i];
                      name = attr1.name;
                      if (name != "class") {
                          attr2 = el2.attributes.getNamedItem(name);
                          if ( (attr1 === null) != (attr2 === null) ) return false;
                          if (attr1.specified != attr2.specified) return false;
                          if (attr1.specified && attr1.nodeValue !== attr2.nodeValue) return false;
                      }
                  }
                  return true;
              }
      
              function elementHasNonClassAttributes(el, exceptions) {
                  for (var i = 0, len = el.attributes.length, attrName; i < len; ++i) {
                      attrName = el.attributes[i].name;
                      if ( !(exceptions && contains(exceptions, attrName)) && el.attributes[i].specified && attrName != "class") {
                          return true;
                      }
                  }
                  return false;
              }
      
              function elementHasProperties(el, props) {
                  return each(props, function(p, propValue) {
                      if (typeof propValue == "object") {
                          if (!elementHasProperties(el[p], propValue)) {
                              return false;
                          }
                      } else if (el[p] !== propValue) {
                          return false;
                      }
                  });
              }
      
              var getComputedStyleProperty = dom.getComputedStyleProperty;
              var isEditableElement = (function() {
                  var testEl = document.createElement("div");
                  return typeof testEl.isContentEditable == "boolean" ?
                      function (node) {
                          return node && node.nodeType == 1 && node.isContentEditable;
                      } :
                      function (node) {
                          if (!node || node.nodeType != 1 || node.contentEditable == "false") {
                              return false;
                          }
                          return node.contentEditable == "true" || isEditableElement(node.parentNode);
                      };
              })();
      
              function isEditingHost(node) {
                  var parent;
                  return node && node.nodeType == 1 &&
                      (( (parent = node.parentNode) && parent.nodeType == 9 && parent.designMode == "on") ||
                      (isEditableElement(node) && !isEditableElement(node.parentNode)));
              }
      
              function isEditable(node) {
                  return (isEditableElement(node) || (node.nodeType != 1 && isEditableElement(node.parentNode))) && !isEditingHost(node);
              }
      
              var inlineDisplayRegex = /^inline(-block|-table)?$/i;
      
              function isNonInlineElement(node) {
                  return node && node.nodeType == 1 && !inlineDisplayRegex.test(getComputedStyleProperty(node, "display"));
              }
      
              // White space characters as defined by HTML 4 (http://www.w3.org/TR/html401/struct/text.html)
              var htmlNonWhiteSpaceRegex = /[^\r\n\t\f \u200B]/;
      
              function isUnrenderedWhiteSpaceNode(node) {
                  if (node.data.length == 0) {
                      return true;
                  }
                  if (htmlNonWhiteSpaceRegex.test(node.data)) {
                      return false;
                  }
                  var cssWhiteSpace = getComputedStyleProperty(node.parentNode, "whiteSpace");
                  switch (cssWhiteSpace) {
                      case "pre":
                      case "pre-wrap":
                      case "-moz-pre-wrap":
                          return false;
                      case "pre-line":
                          if (/[\r\n]/.test(node.data)) {
                              return false;
                          }
                  }
      
                  // We now have a whitespace-only text node that may be rendered depending on its context. If it is adjacent to a
                  // non-inline element, it will not be rendered. This seems to be a good enough definition.
                  return isNonInlineElement(node.previousSibling) || isNonInlineElement(node.nextSibling);
              }
      
              function getRangeBoundaries(ranges) {
                  var positions = [], i, range;
                  for (i = 0; range = ranges[i++]; ) {
                      positions.push(
                          new DomPosition(range.startContainer, range.startOffset),
                          new DomPosition(range.endContainer, range.endOffset)
                      );
                  }
                  return positions;
              }
      
              function updateRangesFromBoundaries(ranges, positions) {
                  for (var i = 0, range, start, end, len = ranges.length; i < len; ++i) {
                      range = ranges[i];
                      start = positions[i * 2];
                      end = positions[i * 2 + 1];
                      range.setStartAndEnd(start.node, start.offset, end.node, end.offset);
                  }
              }
      
              function isSplitPoint(node, offset) {
                  if (dom.isCharacterDataNode(node)) {
                      if (offset == 0) {
                          return !!node.previousSibling;
                      } else if (offset == node.length) {
                          return !!node.nextSibling;
                      } else {
                          return true;
                      }
                  }
      
                  return offset > 0 && offset < node.childNodes.length;
              }
      
              function splitNodeAt(node, descendantNode, descendantOffset, positionsToPreserve) {
                  var newNode, parentNode;
                  var splitAtStart = (descendantOffset == 0);
      
                  if (dom.isAncestorOf(descendantNode, node)) {
                      return node;
                  }
      
                  if (dom.isCharacterDataNode(descendantNode)) {
                      var descendantIndex = dom.getNodeIndex(descendantNode);
                      if (descendantOffset == 0) {
                          descendantOffset = descendantIndex;
                      } else if (descendantOffset == descendantNode.length) {
                          descendantOffset = descendantIndex + 1;
                      } else {
                          throw module.createError("splitNodeAt() should not be called with offset in the middle of a data node (" +
                              descendantOffset + " in " + descendantNode.data);
                      }
                      descendantNode = descendantNode.parentNode;
                  }
      
                  if (isSplitPoint(descendantNode, descendantOffset)) {
                      // descendantNode is now guaranteed not to be a text or other character node
                      newNode = descendantNode.cloneNode(false);
                      parentNode = descendantNode.parentNode;
                      if (newNode.id) {
                          newNode.removeAttribute("id");
                      }
                      var child, newChildIndex = 0;
      
                      while ( (child = descendantNode.childNodes[descendantOffset]) ) {
                          movePreservingPositions(child, newNode, newChildIndex++, positionsToPreserve);
                      }
                      movePreservingPositions(newNode, parentNode, dom.getNodeIndex(descendantNode) + 1, positionsToPreserve);
                      return (descendantNode == node) ? newNode : splitNodeAt(node, parentNode, dom.getNodeIndex(newNode), positionsToPreserve);
                  } else if (node != descendantNode) {
                      newNode = descendantNode.parentNode;
      
                      // Work out a new split point in the parent node
                      var newNodeIndex = dom.getNodeIndex(descendantNode);
      
                      if (!splitAtStart) {
                          newNodeIndex++;
                      }
                      return splitNodeAt(node, newNode, newNodeIndex, positionsToPreserve);
                  }
                  return node;
              }
      
              function areElementsMergeable(el1, el2) {
                  return el1.namespaceURI == el2.namespaceURI &&
                      el1.tagName.toLowerCase() == el2.tagName.toLowerCase() &&
                      haveSameClasses(el1, el2) &&
                      elementsHaveSameNonClassAttributes(el1, el2) &&
                      getComputedStyleProperty(el1, "display") == "inline" &&
                      getComputedStyleProperty(el2, "display") == "inline";
              }
      
              function createAdjacentMergeableTextNodeGetter(forward) {
                  var siblingPropName = forward ? "nextSibling" : "previousSibling";
      
                  return function(textNode, checkParentElement) {
                      var el = textNode.parentNode;
                      var adjacentNode = textNode[siblingPropName];
                      if (adjacentNode) {
                          // Can merge if the node's previous/next sibling is a text node
                          if (adjacentNode && adjacentNode.nodeType == 3) {
                              return adjacentNode;
                          }
                      } else if (checkParentElement) {
                          // Compare text node parent element with its sibling
                          adjacentNode = el[siblingPropName];
                          if (adjacentNode && adjacentNode.nodeType == 1 && areElementsMergeable(el, adjacentNode)) {
                              var adjacentNodeChild = adjacentNode[forward ? "firstChild" : "lastChild"];
                              if (adjacentNodeChild && adjacentNodeChild.nodeType == 3) {
                                  return adjacentNodeChild;
                              }
                          }
                      }
                      return null;
                  };
              }
      
              var getPreviousMergeableTextNode = createAdjacentMergeableTextNodeGetter(false),
                  getNextMergeableTextNode = createAdjacentMergeableTextNodeGetter(true);
      
          
              function Merge(firstNode) {
                  this.isElementMerge = (firstNode.nodeType == 1);
                  this.textNodes = [];
                  var firstTextNode = this.isElementMerge ? firstNode.lastChild : firstNode;
                  if (firstTextNode) {
                      this.textNodes[0] = firstTextNode;
                  }
              }
      
              Merge.prototype = {
                  doMerge: function(positionsToPreserve) {
                      var textNodes = this.textNodes;
                      var firstTextNode = textNodes[0];
                      if (textNodes.length > 1) {
                          var firstTextNodeIndex = dom.getNodeIndex(firstTextNode);
                          var textParts = [], combinedTextLength = 0, textNode, parent;
                          for (var i = 0, len = textNodes.length, j, position; i < len; ++i) {
                              textNode = textNodes[i];
                              parent = textNode.parentNode;
                              if (i > 0) {
                                  parent.removeChild(textNode);
                                  if (!parent.hasChildNodes()) {
                                      parent.parentNode.removeChild(parent);
                                  }
                                  if (positionsToPreserve) {
                                      for (j = 0; position = positionsToPreserve[j++]; ) {
                                          // Handle case where position is inside the text node being merged into a preceding node
                                          if (position.node == textNode) {
                                              position.node = firstTextNode;
                                              position.offset += combinedTextLength;
                                          }
                                          // Handle case where both text nodes precede the position within the same parent node
                                          if (position.node == parent && position.offset > firstTextNodeIndex) {
                                              --position.offset;
                                              if (position.offset == firstTextNodeIndex + 1 && i < len - 1) {
                                                  position.node = firstTextNode;
                                                  position.offset = combinedTextLength;
                                              }
                                          }
                                      }
                                  }
                              }
                              textParts[i] = textNode.data;
                              combinedTextLength += textNode.data.length;
                          }
                          firstTextNode.data = textParts.join("");
                      }
                      return firstTextNode.data;
                  },
      
                  getLength: function() {
                      var i = this.textNodes.length, len = 0;
                      while (i--) {
                          len += this.textNodes[i].length;
                      }
                      return len;
                  },
      
                  toString: function() {
                      var textParts = [];
                      for (var i = 0, len = this.textNodes.length; i < len; ++i) {
                          textParts[i] = "'" + this.textNodes[i].data + "'";
                      }
                      return "[Merge(" + textParts.join(",") + ")]";
                  }
              };
      
              var optionProperties = ["elementTagName", "ignoreWhiteSpace", "applyToEditableOnly", "useExistingElements",
                  "removeEmptyElements", "onElementCreate"];
      
              // TODO: Populate this with every attribute name that corresponds to a property with a different name. Really??
              var attrNamesForProperties = {};
      
              function ClassApplier(className, options, tagNames) {
                  var normalize, i, len, propName, applier = this;
                  applier.cssClass = applier.className = className; // cssClass property is for backward compatibility
      
                  var elementPropertiesFromOptions = null, elementAttributes = {};
      
                  // Initialize from options object
                  if (typeof options == "object" && options !== null) {
                      tagNames = options.tagNames;
                      elementPropertiesFromOptions = options.elementProperties;
                      elementAttributes = options.elementAttributes;
      
                      for (i = 0; propName = optionProperties[i++]; ) {
                          if (options.hasOwnProperty(propName)) {
                              applier[propName] = options[propName];
                          }
                      }
                      normalize = options.normalize;
                  } else {
                      normalize = options;
                  }
      
                  // Backward compatibility: the second parameter can also be a Boolean indicating to normalize after unapplying
                  applier.normalize = (typeof normalize == "undefined") ? true : normalize;
      
                  // Initialize element properties and attribute exceptions
                  applier.attrExceptions = [];
                  var el = document.createElement(applier.elementTagName);
                  applier.elementProperties = applier.copyPropertiesToElement(elementPropertiesFromOptions, el, true);
                  each(elementAttributes, function(attrName) {
                      applier.attrExceptions.push(attrName);
                  });
                  applier.elementAttributes = elementAttributes;
      
                  applier.elementSortedClassName = applier.elementProperties.hasOwnProperty("className") ?
                      applier.elementProperties.className : className;
      
                  // Initialize tag names
                  applier.applyToAnyTagName = false;
                  var type = typeof tagNames;
                  if (type == "string") {
                      if (tagNames == "*") {
                          applier.applyToAnyTagName = true;
                      } else {
                          applier.tagNames = trim(tagNames.toLowerCase()).split(/\s*,\s*/);
                      }
                  } else if (type == "object" && typeof tagNames.length == "number") {
                      applier.tagNames = [];
                      for (i = 0, len = tagNames.length; i < len; ++i) {
                          if (tagNames[i] == "*") {
                              applier.applyToAnyTagName = true;
                          } else {
                              applier.tagNames.push(tagNames[i].toLowerCase());
                          }
                      }
                  } else {
                      applier.tagNames = [applier.elementTagName];
                  }
              }
      
              ClassApplier.prototype = {
                  elementTagName: defaultTagName,
                  elementProperties: {},
                  elementAttributes: {},
                  ignoreWhiteSpace: true,
                  applyToEditableOnly: false,
                  useExistingElements: true,
                  removeEmptyElements: true,
                  onElementCreate: null,
      
                  copyPropertiesToElement: function(props, el, createCopy) {
                      var s, elStyle, elProps = {}, elPropsStyle, propValue, elPropValue, attrName;
      
                      for (var p in props) {
                          if (props.hasOwnProperty(p)) {
                              propValue = props[p];
                              elPropValue = el[p];
      
                              // Special case for class. The copied properties object has the applier's CSS class as well as its
                              // own to simplify checks when removing styling elements
                              if (p == "className") {
                                  addClass(el, propValue);
                                  addClass(el, this.className);
                                  el[p] = sortClassName(el[p]);
                                  if (createCopy) {
                                      elProps[p] = el[p];
                                  }
                              }
      
                              // Special case for style
                              else if (p == "style") {
                                  elStyle = elPropValue;
                                  if (createCopy) {
                                      elProps[p] = elPropsStyle = {};
                                  }
                                  for (s in props[p]) {
                                      elStyle[s] = propValue[s];
                                      if (createCopy) {
                                          elPropsStyle[s] = elStyle[s];
                                      }
                                  }
                                  this.attrExceptions.push(p);
                              } else {
                                  el[p] = propValue;
                                  // Copy the property back from the dummy element so that later comparisons to check whether
                                  // elements may be removed are checking against the right value. For example, the href property
                                  // of an element returns a fully qualified URL even if it was previously assigned a relative
                                  // URL.
                                  if (createCopy) {
                                      elProps[p] = el[p];
      
                                      // Not all properties map to identically-named attributes
                                      attrName = attrNamesForProperties.hasOwnProperty(p) ? attrNamesForProperties[p] : p;
                                      this.attrExceptions.push(attrName);
                                  }
                              }
                          }
                      }
      
                      return createCopy ? elProps : "";
                  },
                  
                  copyAttributesToElement: function(attrs, el) {
                      for (var attrName in attrs) {
                          if (attrs.hasOwnProperty(attrName)) {
                              el.setAttribute(attrName, attrs[attrName]);
                          }
                      }
                  },
      
                  hasClass: function(node) {
                      return node.nodeType == 1 &&
                          contains(this.tagNames, node.tagName.toLowerCase()) &&
                          hasClass(node, this.className);
                  },
      
                  getSelfOrAncestorWithClass: function(node) {
                      while (node) {
                          if (this.hasClass(node)) {
                              return node;
                          }
                          node = node.parentNode;
                      }
                      return null;
                  },
      
                  isModifiable: function(node) {
                      return !this.applyToEditableOnly || isEditable(node);
                  },
      
                  // White space adjacent to an unwrappable node can be ignored for wrapping
                  isIgnorableWhiteSpaceNode: function(node) {
                      return this.ignoreWhiteSpace && node && node.nodeType == 3 && isUnrenderedWhiteSpaceNode(node);
                  },
      
                  // Normalizes nodes after applying a CSS class to a Range.
                  postApply: function(textNodes, range, positionsToPreserve, isUndo) {
                      var firstNode = textNodes[0], lastNode = textNodes[textNodes.length - 1];
      
                      var merges = [], currentMerge;
      
                      var rangeStartNode = firstNode, rangeEndNode = lastNode;
                      var rangeStartOffset = 0, rangeEndOffset = lastNode.length;
      
                      var textNode, precedingTextNode;
      
                      // Check for every required merge and create a Merge object for each
                      for (var i = 0, len = textNodes.length; i < len; ++i) {
                          textNode = textNodes[i];
                          precedingTextNode = getPreviousMergeableTextNode(textNode, !isUndo);
                          if (precedingTextNode) {
                              if (!currentMerge) {
                                  currentMerge = new Merge(precedingTextNode);
                                  merges.push(currentMerge);
                              }
                              currentMerge.textNodes.push(textNode);
                              if (textNode === firstNode) {
                                  rangeStartNode = currentMerge.textNodes[0];
                                  rangeStartOffset = rangeStartNode.length;
                              }
                              if (textNode === lastNode) {
                                  rangeEndNode = currentMerge.textNodes[0];
                                  rangeEndOffset = currentMerge.getLength();
                              }
                          } else {
                              currentMerge = null;
                          }
                      }
      
                      // Test whether the first node after the range needs merging
                      var nextTextNode = getNextMergeableTextNode(lastNode, !isUndo);
      
                      if (nextTextNode) {
                          if (!currentMerge) {
                              currentMerge = new Merge(lastNode);
                              merges.push(currentMerge);
                          }
                          currentMerge.textNodes.push(nextTextNode);
                      }
      
                      // Apply the merges
                      if (merges.length) {
                          for (i = 0, len = merges.length; i < len; ++i) {
                              merges[i].doMerge(positionsToPreserve);
                          }
      
                          // Set the range boundaries
                          range.setStartAndEnd(rangeStartNode, rangeStartOffset, rangeEndNode, rangeEndOffset);
                      }
                  },
      
                  createContainer: function(doc) {
                      var el = doc.createElement(this.elementTagName);
                      this.copyPropertiesToElement(this.elementProperties, el, false);
                      this.copyAttributesToElement(this.elementAttributes, el);
                      addClass(el, this.className);
                      if (this.onElementCreate) {
                          this.onElementCreate(el, this);
                      }
                      return el;
                  },
      
                  applyToTextNode: function(textNode, positionsToPreserve) {
                      var parent = textNode.parentNode;
                      if (parent.childNodes.length == 1 &&
                              this.useExistingElements &&
                              isHtmlNamespace(parent) &&
                              contains(this.tagNames, parent.tagName.toLowerCase()) &&
                              elementHasProperties(parent, this.elementProperties)) {
      
                          addClass(parent, this.className);
                      } else {
                          var el = this.createContainer(dom.getDocument(textNode));
                          textNode.parentNode.insertBefore(el, textNode);
                          el.appendChild(textNode);
                      }
                  },
      
                  isRemovable: function(el) {
                      return isHtmlNamespace(el) &&
                          el.tagName.toLowerCase() == this.elementTagName &&
                          getSortedClassName(el) == this.elementSortedClassName &&
                          elementHasProperties(el, this.elementProperties) &&
                          !elementHasNonClassAttributes(el, this.attrExceptions) &&
                          this.isModifiable(el);
                  },
      
                  isEmptyContainer: function(el) {
                      var childNodeCount = el.childNodes.length;
                      return el.nodeType == 1 &&
                          this.isRemovable(el) &&
                          (childNodeCount == 0 || (childNodeCount == 1 && this.isEmptyContainer(el.firstChild)));
                  },
                  
                  removeEmptyContainers: function(range) {
                      var applier = this;
                      var nodesToRemove = range.getNodes([1], function(el) {
                          return applier.isEmptyContainer(el);
                      });
                      
                      var rangesToPreserve = [range];
                      var positionsToPreserve = getRangeBoundaries(rangesToPreserve);
                      
                      for (var i = 0, node; node = nodesToRemove[i++]; ) {
                          removePreservingPositions(node, positionsToPreserve);
                      }
      
                      // Update the range from the preserved boundary positions
                      updateRangesFromBoundaries(rangesToPreserve, positionsToPreserve);
                  },
      
                  undoToTextNode: function(textNode, range, ancestorWithClass, positionsToPreserve) {
                      if (!range.containsNode(ancestorWithClass)) {
                          // Split out the portion of the ancestor from which we can remove the CSS class
                          //var parent = ancestorWithClass.parentNode, index = dom.getNodeIndex(ancestorWithClass);
                          var ancestorRange = range.cloneRange();
                          ancestorRange.selectNode(ancestorWithClass);
                          if (ancestorRange.isPointInRange(range.endContainer, range.endOffset)) {
                              splitNodeAt(ancestorWithClass, range.endContainer, range.endOffset, positionsToPreserve);
                              range.setEndAfter(ancestorWithClass);
                          }
                          if (ancestorRange.isPointInRange(range.startContainer, range.startOffset)) {
                              ancestorWithClass = splitNodeAt(ancestorWithClass, range.startContainer, range.startOffset, positionsToPreserve);
                          }
                      }
                      if (this.isRemovable(ancestorWithClass)) {
                          replaceWithOwnChildrenPreservingPositions(ancestorWithClass, positionsToPreserve);
                      } else {
                          removeClass(ancestorWithClass, this.className);
                      }
                  },
      
                  applyToRange: function(range, rangesToPreserve) {
                      rangesToPreserve = rangesToPreserve || [];
      
                      // Create an array of range boundaries to preserve
                      var positionsToPreserve = getRangeBoundaries(rangesToPreserve || []);
                      
                      range.splitBoundariesPreservingPositions(positionsToPreserve);
      
                      // Tidy up the DOM by removing empty containers 
                      if (this.removeEmptyElements) {
                          this.removeEmptyContainers(range);
                      }
      
                      var textNodes = getEffectiveTextNodes(range);
      
                      if (textNodes.length) {
                          for (var i = 0, textNode; textNode = textNodes[i++]; ) {
                              if (!this.isIgnorableWhiteSpaceNode(textNode) && !this.getSelfOrAncestorWithClass(textNode) &&
                                      this.isModifiable(textNode)) {
                                  this.applyToTextNode(textNode, positionsToPreserve);
                              }
                          }
                          textNode = textNodes[textNodes.length - 1];
                          range.setStartAndEnd(textNodes[0], 0, textNode, textNode.length);
                          if (this.normalize) {
                              this.postApply(textNodes, range, positionsToPreserve, false);
                          }
      
                          // Update the ranges from the preserved boundary positions
                          updateRangesFromBoundaries(rangesToPreserve, positionsToPreserve);
                      }
                  },
      
                  applyToRanges: function(ranges) {
      
                      var i = ranges.length;
                      while (i--) {
                          this.applyToRange(ranges[i], ranges);
                      }
      
      
                      return ranges;
                  },
      
                  applyToSelection: function(win) {
                      var sel = api.getSelection(win);
                      sel.setRanges( this.applyToRanges(sel.getAllRanges()) );
                  },
      
                  undoToRange: function(range, rangesToPreserve) {
                      // Create an array of range boundaries to preserve
                      rangesToPreserve = rangesToPreserve || [];
                      var positionsToPreserve = getRangeBoundaries(rangesToPreserve);
      
      
                      range.splitBoundariesPreservingPositions(positionsToPreserve);
      
                      // Tidy up the DOM by removing empty containers 
                      if (this.removeEmptyElements) {
                          this.removeEmptyContainers(range, positionsToPreserve);
                      }
      
                      var textNodes = getEffectiveTextNodes(range);
                      var textNode, ancestorWithClass;
                      var lastTextNode = textNodes[textNodes.length - 1];
      
                      if (textNodes.length) {
                          for (var i = 0, len = textNodes.length; i < len; ++i) {
                              textNode = textNodes[i];
                              ancestorWithClass = this.getSelfOrAncestorWithClass(textNode);
                              if (ancestorWithClass && this.isModifiable(textNode)) {
                                  this.undoToTextNode(textNode, range, ancestorWithClass, positionsToPreserve);
                              }
      
                              // Ensure the range is still valid
                              range.setStartAndEnd(textNodes[0], 0, lastTextNode, lastTextNode.length);
                          }
      
      
                          if (this.normalize) {
                              this.postApply(textNodes, range, positionsToPreserve, true);
                          }
      
                          // Update the ranges from the preserved boundary positions
                          updateRangesFromBoundaries(rangesToPreserve, positionsToPreserve);
                      }
                  },
      
                  undoToRanges: function(ranges) {
                      // Get ranges returned in document order
                      var i = ranges.length;
      
                      while (i--) {
                          this.undoToRange(ranges[i], ranges);
                      }
      
                      return ranges;
                  },
      
                  undoToSelection: function(win) {
                      var sel = api.getSelection(win);
                      var ranges = api.getSelection(win).getAllRanges();
                      this.undoToRanges(ranges);
                      sel.setRanges(ranges);
                  },
      
          /*
                  getTextSelectedByRange: function(textNode, range) {
                      var textRange = range.cloneRange();
                      textRange.selectNodeContents(textNode);
      
                      var intersectionRange = textRange.intersection(range);
                      var text = intersectionRange ? intersectionRange.toString() : "";
                      textRange.detach();
      
                      return text;
                  },
          */
      
                  isAppliedToRange: function(range) {
                      if (range.collapsed || range.toString() == "") {
                          return !!this.getSelfOrAncestorWithClass(range.commonAncestorContainer);
                      } else {
                          var textNodes = range.getNodes( [3] );
                          if (textNodes.length)
                          for (var i = 0, textNode; textNode = textNodes[i++]; ) {
                              if (!this.isIgnorableWhiteSpaceNode(textNode) && rangeSelectsAnyText(range, textNode) &&
                                      this.isModifiable(textNode) && !this.getSelfOrAncestorWithClass(textNode)) {
                                  return false;
                              }
                          }
                          return true;
                      }
                  },
      
                  isAppliedToRanges: function(ranges) {
                      var i = ranges.length;
                      if (i == 0) {
                          return false;
                      }
                      while (i--) {
                          if (!this.isAppliedToRange(ranges[i])) {
                              return false;
                          }
                      }
                      return true;
                  },
      
                  isAppliedToSelection: function(win) {
                      var sel = api.getSelection(win);
                      return this.isAppliedToRanges(sel.getAllRanges());
                  },
      
                  toggleRange: function(range) {
                      if (this.isAppliedToRange(range)) {
                          this.undoToRange(range);
                      } else {
                          this.applyToRange(range);
                      }
                  },
      
          /*
                  toggleRanges: function(ranges) {
                      if (this.isAppliedToRanges(ranges)) {
                          this.undoToRanges(ranges);
                      } else {
                          this.applyToRanges(ranges);
                      }
                  },
          */
      
                  toggleSelection: function(win) {
                      if (this.isAppliedToSelection(win)) {
                          this.undoToSelection(win);
                      } else {
                          this.applyToSelection(win);
                      }
                  },
                  
                  getElementsWithClassIntersectingRange: function(range) {
                      var elements = [];
                      var applier = this;
                      range.getNodes([3], function(textNode) {
                          var el = applier.getSelfOrAncestorWithClass(textNode);
                          if (el && !contains(elements, el)) {
                              elements.push(el);
                          }
                      });
                      return elements;
                  },
      
          /*
                  getElementsWithClassIntersectingSelection: function(win) {
                      var sel = api.getSelection(win);
                      var elements = [];
                      var applier = this;
                      sel.eachRange(function(range) {
                          var rangeElements = applier.getElementsWithClassIntersectingRange(range);
                          for (var i = 0, el; el = rangeElements[i++]; ) {
                              if (!contains(elements, el)) {
                                  elements.push(el);
                              }
                          }
                      });
                      return elements;
                  },
          */
      
                  detach: function() {}
              };
      
              function createClassApplier(className, options, tagNames) {
                  return new ClassApplier(className, options, tagNames);
              }
      
              ClassApplier.util = {
                  hasClass: hasClass,
                  addClass: addClass,
                  removeClass: removeClass,
                  hasSameClasses: haveSameClasses,
                  replaceWithOwnChildren: replaceWithOwnChildrenPreservingPositions,
                  elementsHaveSameNonClassAttributes: elementsHaveSameNonClassAttributes,
                  elementHasNonClassAttributes: elementHasNonClassAttributes,
                  splitNodeAt: splitNodeAt,
                  isEditableElement: isEditableElement,
                  isEditingHost: isEditingHost,
                  isEditable: isEditable
              };
      
              api.CssClassApplier = api.ClassApplier = ClassApplier;
              api.createCssClassApplier = api.createClassApplier = createClassApplier;
          });
          
      }, this);
      /*
       * Medium.js
       *
       * Copyright 2013, Jacob Kelley - http://jakiestfu.com/
       * Released under the MIT Licence
       * http://opensource.org/licenses/MIT
       *
       * Github:  http://github.com/jakiestfu/Medium.js/
       * Version: 1.0
       */
      
      (function (w, d) {
      	'use strict';
      	
      	// check if the selection contains noneditable element
      	function checkNonEditable(e, selRange) {
      		var i =0;
      		var nodes = selRange.cloneContents().querySelectorAll("[contenteditable='false']");
      		for (i =0; i< nodes.length; i++) {
      			if (nodes[i].tagName !="A") {
      				e.preventDefault();
      				return true;
      			}
      		}
      		return false;
      	}
      	
      	function checkBackspaceForNoEditable(elem)
      	{
      		var elem = elem.previousElementSibling;
      		while (elem) {
      		   if ((elem.contentEditable == "false" || elem.readonly == "true" || elem.classList.contains('lasso-undeletable')) && elem.tagName !="A") {
      			   return true;
      		   }
      		   if (elem.innerHTML.includes("/g ;
      			    var cont = re.exec(this.innerHTML);
      							
      				$(this).next().append( '
      '+lasso_editor.strings.editShortcode+'
      ' ); $(this).next().addClass("editus_shortcode_p"); if (cont) $(this).next().find('.editus_shortcode')[0].dataset.shortcode = cont[1]; }); } $(document).on('click','.editus_shortcode', function(e){ var $this = $(this); var s = $(window).scrollTop(); swal({ title: lasso_editor.strings.editShortcode, text: "", showCancelButton: true, confirmButtonColor: "#d9534f", confirmButtonText: "Modify", closeOnConfirm: true, obj: this }, function(){ var val = $('textarea#shortcode_edit').val(); var data = { action: 'editus_do_shortcode', code: val, ID: lasso_editor.postid }; jQuery.post(lasso_editor.ajaxurl2, data, function(response) { restoreSelection(window.selRange); if( response && response.includes("EDITUS_OTHER_SHORTCODE_END")){ $this.parent().prev().remove(); //$this.next().remove(); $this.parent().replaceWith( response.replace("","") ); processShortcodes(); } else { alert("Shortcode processing failed"); } $(window).scrollTop(s); }); }); }) function taghelper(tag) { articleMedium.element.contentEditable = true; article.highlight(); articleMedium.invokeElement(tag); articleMedium.makeUndoable(); return false; } $('[id="lasso-toolbar--bold"]').on('mousedown', function(e) { return taghelper(lasso_editor.boldTag); }); $('[id="lasso-toolbar--underline"]').on('mousedown', function(e) { return taghelper('u'); }); $('[id="lasso-toolbar--italic"]').on('mousedown', function(e) { return taghelper(lasso_editor.iTag); }); $('[id="lasso-toolbar--strike"]').on('mousedown', function(e) { return taghelper('strike'); }); $(document).on('keydown', function ( e ) { // remove formatting when the use pushes ctrl+space if ((e.metaKey || e.ctrlKey) && ( e.which == 32) ) { document.execCommand('removeFormat'); document.execCommand('formatBlock', false, 'p') } }); function heading_helper(heading) { articleMedium.element.contentEditable = true; article.highlight(); articleMedium.invokeElement(heading); //reg = '/

      ([^<>]*)<\/h2>/i'; reg = new RegExp('<'+heading+' class="lasso-'+heading+'">([^<>]*)<\\/'+heading+'>', 'i');; // the following code breaks the paragraphs before and after heading $(articleMedium.element).html(function(index,html){ //return html.replace(/

      ([^<>]*)<\/h2>/i,'

      <'+heading+'>$1

      '); return html.replace(reg,'

      <'+heading+'>$1

      '); }); articleMedium.makeUndoable(); return false; } document.getElementById('lasso-toolbar--link').onmousedown = function() { var article = document.getElementById(lasso_editor.editor); article.highlight(); window.selRange = saveSelection(); }; document.getElementById('lasso-toolbar--html').onmousedown = function() { var article = document.getElementById(lasso_editor.editor); article.highlight(); window.selRange = saveSelection(); if( typeof window.selRange === 'undefined' || null == window.selRange ) { window.selRange = saveSelection(); } }; if ( toolbarHeading ) { document.getElementById('lasso-toolbar--h2').onmousedown = function() { return heading_helper('h2'); }; document.getElementById('lasso-toolbar--h3').onmousedown = function() { return heading_helper('h3'); }; } if ( lasso_editor.toolbarHeadingsH4 ) { document.getElementById('lasso-toolbar--h4').onmousedown = function() { return heading_helper('h4'); }; document.getElementById('lasso-toolbar--h5').onmousedown = function() { return heading_helper('h5'); }; document.getElementById('lasso-toolbar--h6').onmousedown = function() { return heading_helper('h6'); }; } document.getElementById('lasso-toolbar--link__create').onmousedown = function() { articleMedium.element.contentEditable = true; article.highlight(); restoreSelection(window.selRange); var html = ''+window.selRange+''; } else { html = html+' href="'+ target +'">'+window.selRange+''; } } articleMedium.insertHtml(html); var container = window.selRange.startContainer.parentNode, containerTag = container.localName; if ( containerTag == 'a' ) { var containerObject = $(window.selRange.startContainer.parentNode); containerObject.replaceWith(containerObject[0].innerHTML); } window.selRange = null; // close modal drag $('#lasso-toolbar--link').removeClass('link--drop-up link--drop-down'); articleMedium.makeUndoable(); return false; }; // process shortcode using AJAX service and insert the result function do_shortcode_ajax(content) { var data = { action: 'editus_do_shortcode', code: content, ID: lasso_editor.postid }; jQuery.post(lasso_editor.ajaxurl2, data, function(response) { restoreSelection(window.selRange); if( response ){ return insert_html(response); } else { return insert_html(content); } }); } function insert_html(htmlContent, contentishtml) { var html = contentishtml; if (contentishtml == undefined) { html = true; } try { var container = window.selRange.startContainer; var containerTag = container.localName; var containerObject = $(container); var htmlCopy = htmlContent; if (html) { //htmlContent is html, not an object htmlContent = $(htmlContent); htmlContent.attr('contenteditable','true'); } else { htmlCopy = htmlContent[0].outerHTML; } // handle 3 specific scenarios dealing with

      's // note: might need climb up dom tree depending on nesting use case if (containerTag == 'p') { var innerText = container.innerText.replace(/(\r\n|\n|\r)/gm,""); if (!html) { // currently we come here only if when inserting components /*htmlContent.insertAfter( containerObject ); if (innerText =="") { // empty p tag containerObject.remove(); }*/ // decided to change the behavior Now the component is inserted before the empty paragraph htmlContent.insertBefore( containerObject ); if (innerText =="") { articleMedium.cursor.caretToBeginning(container); } } else { articleMedium.insertHtml( htmlCopy ); } } else { // within a p tag container = container.parentNode; containerTag = container.localName; if( containerTag == 'p') { //if (string.indexOf(<) !== -1; //htmlContent.insertAfter( containerObject ); articleMedium.insertHtml( htmlCopy ); } else { // let's just go ahead and paste it on location articleMedium.insertHtml( '

      '+htmlCopy+'

      ' ); } } //window.selRange = null; // close modal drag $('#lasso-toolbar--html').removeClass('html--drop-up'); articleMedium.makeUndoable(); lasso_editor.addComponentButton(); return htmlContent; } catch (e) { alert(e.message); } } function isURL(str) { var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name and extension '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address '(\\:\\d+)?'+ // port '(\\/[-a-z\\d%@_.~+&:]*)*'+ // path '(\\?[;&a-z\\d%@_.,~+&:=-]*)?'+ // query string '(\\#[-a-z\\d_]*)?$','i'); // fragment locator return pattern.test(str); } document.getElementById('lasso-toolbar--html__insert').onmousedown = function() { articleMedium.element.contentEditable = true; restoreSelection(window.selRange); var htmlContent = $('#lasso-toolbar--html__inner').text(); if (htmlContent.indexOf("]") != -1) { do_shortcode_ajax(htmlContent); return false; } else if (isURL(htmlContent)) { do_shortcode_ajax("[embed]"+htmlContent+"[/embed]"); return false; } else { return insert_html(htmlContent); } }; if (lasso_editor.enableAutoSave) { lasso_editor.intervalID = window.setInterval(autoSave, 60000); } function autoSave() { if (localStorage.getItem( 'lasso_backup_'+postid ) || lasso_editor.dirtyByComponent) { $('.lasso--controls__right #lasso--save').trigger('click'); } } function clearTimer() { if (lasso_editor.intervalID) { window.clearInterval(lasso_editor.intervalID); lasso_editor.intervalID = 0; } if (lasso_editor.lockIntervalID) { window.clearInterval(lasso_editor.lockIntervalID); lasso_editor.lockIntervalID = 0; //unlock post var data = { action: 'editus_unlock_post', postid: lasso_editor.postid }; jQuery.post(lasso_editor.ajaxurl2, data, function(response) { }); } } ///////////////// /// EXIT EDITOR /////////////////// function exitEditor(){ clearTimer(); if ($('body').hasClass('lasso-sidebar-open')) { //e.preventDefault(); $('body').removeClass('lasso-sidebar-open'); $('#lasso--component__settings').perfectScrollbar('destroy'); return; } $('body').removeClass('lasso-sidebar-open lasso-editing'); $('.lasso--toolbar_wrap,#lasso--sidebar,#lasso--featImgControls,.lasso-component--controls,#lasso--exit,#lasso-side-comp-button,.lasso--text-popup,.editus_shortcode').fadeOut().remove(); $('#lasso--edit').css('opacity',1); $('.lasso--controls__right').css('opacity',0); $(post_container).attr('id',''); // unwrap wp images /*$('.lasso--wpimg__wrap').each(function(){ $(this).children().unwrap() });*/ // unwrap map from hits drag holder $('#lasso--map-form').each(function(){ var $this = $(this) $this.find('.lasso-component--controls, .lasso--map-form__footer ').remove() $this.children().unwrap() }); $(titleClass).attr('contenteditable', false); $(articleMedium.element).find("*").removeAttr('contenteditable'); articleMedium.destroy(); // ways to inject codes into the exitEditor if (lasso_editor.exitEditorHookArray) { $(lasso_editor.exitEditorHookArray).each(function(key, val){ val(); }); } } lasso_editor.exitEditor = exitEditor; // on escape key exit $(document).keyup(function(e) { if ( 27 == e.keyCode ) { if ($('#lasso-toolbar--link').hasClass('link--drop-up')) { $('#lasso-toolbar--link').removeClass('link--drop-up'); } else if ($('#lasso-toolbar--html').hasClass('html--drop-up')) { $('#lasso-toolbar--html').removeClass('html--drop-up'); } else { exitEditor() } } }); // on utility class exit //$('#lasso--exit').live('click',function(e){ jQuery(document).on('click','#lasso--exit', function(e){ e.preventDefault(); //previously we just called exitEditor(), now the following reloads the page if there is an unsaved change if (articleMedium.dirty) { clearTimer(); location.reload(); } else { exitEditor(); } }) // on control s save $(document).keydown(function(e) { if ((e.which == '115' || e.which == '83' ) && (e.ctrlKey || e.metaKey)){ e.preventDefault(); $('.lasso-editing #lasso--save').trigger('click') return false; } return true; }); /////////// // INITIALIZE TIMELINE ////////// lasso_editor.timelineGoTime = function(){ // if there's no toolbar present if ( !$('.aesop-timeline').length > 0 ) { $('body').append('
      ').addClass('has-timeline'); } if ( !$('.aesop-timeline .scroll-nav').length > 0 ) { $('.aesop-entry-content').scrollNav({ sections: '.aesop-timeline-stop', arrowKeys: true, insertTarget: '.aesop-timeline', insertLocation: 'appendTo', showTopLink: false, showHeadline: false, scrollOffset: 0, }); $('.aesop-timeline-stop').each(function(){ $(this).append( lassoDragHandle ); }); } $('.aesop-timeline-stop').each(function(){ var label = $(this).attr('data-title'); $(this).text(label); if ( $(this).find('.lasso-component--controls').length == 0 ) { $(this).append( lassoDragHandle ); } }); } /////////// // INITIALIZE VIDEO /////////// var videoGoTime = function(){ $('.aesop-video-component').fitVids() } var start_point = mapStart ? mapStart : [29.76, -95.38] , start_zoom = mapZoom ? mapZoom : 12 , mapTileProvider = lasso_editor.mapTileProvider; /////////// // INITIALIZE MAPS /////////// var mapsGoTime = function(){ var lat = start_point.lat ? start_point.lat : 29.76 , lng = start_point.lng ? start_point.lng : -95.38; var map = L.map('aesop-map-component',{ scrollWheelZoom: false, zoom: start_zoom, center: [lat, lng] }); setMapCenter(start_point[0],start_point[1]); jQuery('#lasso-map-address').geocomplete().bind('geocode:result', function(event, result){ var lat = result.geometry.location.k; var lng = result.geometry.location.B; map.panTo(new L.LatLng(lat,lng)); setMapCenter(lat,lng); }); L.tileLayer(mapTileProvider, { maxZoom: 20//start_zoom }).addTo(map); mapLocations.forEach(function(location) { createMapMarker([location['lat'],location['lng']],location['title']).addTo(map); createMarkerField( marker._leaflet_id, encodeMarkerData(location['lat'], location['lng'], location['title']) ); }); // adding a new marker map.on('click', onMapClick); map.on('dragend', onMapDrag); map.on('zoomend', onMapZoom); function setMapCenter(k, B) { var ldata = encodeLocationData(k,B); jQuery('input[name="ase-map-component-start-point"]').remove(); jQuery('.lasso--map-form__footer').append(''); jQuery('#lasso-map-address').val(k + ', ' + B); } function setMapZoom(z) { jQuery('input[name="ase-map-component-zoom"]').remove(); jQuery('.lasso--map-form__footer').append(''); } function onMarkerDrag(e) { updateMarkerField(e.target); } function onMapDrag(e) { var mapCenter = e.target.getCenter() setMapCenter(rnd(mapCenter.lat),rnd(mapCenter.lng)); } function onMapZoom(e) { setMapZoom(e.target.getZoom()); } function rnd(n) { return Math.round(n * 100) / 100 } function onMapClick(e) { var geojsonFeature = { "type": "Feature", "properties": {}, "geometry": { "type": "Point", "coordinates": [e.latlng.lat, e.latlng.lng] } } var marker; L.geoJson(geojsonFeature, { pointToLayer: function(feature, latlng){ marker = L.marker(e.latlng, { title: 'Resource Location', alt: 'Resource Location', riseOnHover: true, draggable: true, }).bindPopup("\ \ \ \ "); marker.on('popupopen', onPopupOpen); marker.on('dragend', onMarkerDrag); return marker; } }).addTo(map); createMarkerField( marker._leaflet_id, encodeMarkerData(e.latlng.lat, e.latlng.lng, 'Location Title') ); } // open popup function onPopupOpen() { var tempMarker = this; // To remove marker on click of delete button in the popup of marker jQuery('.marker-delete-button:visible').click(function () { jQuery('input[data-marker="' + tempMarker._leaflet_id + '"]').remove(); map.removeLayer(tempMarker); }); // Update the title of the location jQuery('.marker-update-button:visible').click(function (t) { var title = t.target.previousElementSibling.value; var tdata = encodeMarkerData(tempMarker._latlng.lat, tempMarker._latlng.lng, title); jQuery('input[data-marker="' + tempMarker._leaflet_id + '"]').val(tdata); tempMarker.options.title = title; tempMarker.closePopup(); tempMarker.bindPopup("\ \ \ \ "); }); } // create map marker function createMapMarker(latlng, title) { marker = L.marker(latlng, { title: title, alt: title, riseOnHover: true, draggable: true, }).bindPopup("\ \ \ \ "); marker.on('popupopen', onPopupOpen); marker.on('dragend', onMarkerDrag); return marker; } function getAllMarkers() { var allMarkersObjArray = []; // for marker objects var allMarkersGeoJsonArray = []; // for readable geoJson markers jQuery.each(map._layers, function (ml) { if (map._layers[ml].feature) { allMarkersObjArray.push(this) allMarkersGeoJsonArray.push(JSON.stringify(this.toGeoJSON())) } }) } // let's create a hidden form element for the marker function createMarkerField(mid, mdata) { jQuery('.lasso--map-form__footer').append(''); } function updateMarkerField(m) { var tdata = encodeMarkerData(m._latlng.lat, m._latlng.lng, m.options.title); jQuery('input[data-marker="' + m._leaflet_id + '"]').val(tdata); } // encode the information into a string function encodeMarkerData(mlat, mlng, mtitle) { return encodeURIComponent(JSON.stringify({lat: mlat, lng: mlng, title: mtitle})); } // encode location into a string function encodeLocationData(mlat, mlng) { return encodeURIComponent(JSON.stringify({lat: mlat, lng: mlng})); } // decode the information function decodeMarkerData(mdata) { return decodeURIComponent(JSON.parse(mdata)); } } // the code to enable map editing after reload. if ($( ".aesop-map-component" ).length) { $( ".aesop-map-component" ).replaceWith(setComponent("map")); mapsGoTime(); } function setComponent(type) { // if an image is dragged in var comp =""; if (!components[type] || !components[type]['content']) return null; if ( 'wpimg' == type && lasso_editor.oldWPimg) { comp = $(components[type]['content']).prepend( wpImgEdit ); // else it's likely an aesop component } else if ( 'htmlparagraph' != type && 'htmltable' != type) { comp = $(components[type]['content']) .prepend( lassoDragHandle ) .attr({ 'data-component-type': type }); } else { comp = $(components[type]['content']); } return comp; } function postComponent(comp,type) { // set some figures to uneditable $("figure.wp-block-image, figure.lasso--wpimg__wrap").attr('contenteditable',false).attr('readonly',true); // TODO: if a stock wordpress image is dragged in if ('timeline_stop' == type ) { lasso_editor.timelineGoTime() } if ('video' == type ) { videoGoTime() } $('#lasso-side-comp-button').remove(); if ( 'map' == type ) { mapsGoTime(); } else { $(comp).find('.lasso-settings').trigger('click'); } } function imgDialog( ){ var that = this; // Create the media frame. var lasso_file_frame = wp.media.frames.file_frame = wp.media({ title: 'Select Image', button: { text: 'Insert Image', }, multiple: false // Set to true to allow multiple files to be selected }); // When an image is selected, run a callback. lasso_file_frame.on( 'select', function() { var attachment = lasso_file_frame.state().get('selection').first().toJSON(); $(that).parent().data('imgid',''+attachment.id); if ($(that).parent().find('img').length > 0) { $(that).parent().find('img').attr('src', attachment.url ); } else {i $(that).parent().css({ 'background-image': 'url('+ attachment.url +')' }); } // set some figures to uneditable $("figure.wp-block-image, figure.lasso--wpimg__wrap").attr('contenteditable',false).attr('readonly',true); }); // Finally, open the modal lasso_file_frame.open(); }; ///////////////// /// DRAG DROP /////////////////// // recent change: when a new component is dropped, the setting window is opened automatically $('#'+editor).sortable({ opacity: 0.65, placeholder:'lasso-drop-zone', handle: '.lasso-drag', cursor:'move', tolerance:'pointer', refreshPositions: true, helper: function( e, ui ) { // get the curent target and add the type class to the drag event var item = ui['context'], type = $(item).attr('data-component-type'); return $('
      '); }, beforeStop: function (event, ui) { draggedItem = ui.item }, receive: function (event,ui) { // close modal drag $('#lasso-toolbar--components').removeClass('toolbar--drop-up'); articleMedium.makeUndoable(); // get the item and type var item = draggedItem['context']; if (!item) item = draggedItem; var type = $(item).attr('data-type'); // item2 will be the content tthat gets inserted. It also has edit controls // if coming from draggable replace with our content and prepend toolbar if ( origin == 'draggable' ) { // check if it's inserted at the end var newIndex = $(this).data("ui-sortable").currentItem.index(); var sortable_len = $(this).data("ui-sortable").items.length; var last = false; if (newIndex>= (sortable_len-1)) { last = true; } var item2 = setComponent(type); if (last) { item2.append('


      '); } $(item).replaceWith( item2); postComponent(item2,type); } } }); lasso_editor.addComponentButton = function() { // this function checks the current selected element and adds the component button if appropriate if (!lasso_editor.buttonOnEmptyP) { // if this feature is not turned on, return return; } window.selRange = saveSelection(); if (!window.selRange) return; var container = window.selRange.startContainer, containerTag; if ($(container).attr('id') == "lasso--content") { container = $(container).children()[0]; } $('#lasso-side-comp-button').remove(); containerTag = container.localName; parentTag = $(container).parent().prop("tagName"); if ($(container).parent().attr('id') != "lasso--content") { if (parentTag == 'figure' || parentTag == 'div' || $(container).parent().parent().attr('id') != "lasso--content") { return; } } if ( containerTag == 'p' || ((containerTag=='b' || containerTag=='em' || containerTag=='i' || containerTag=='strike' || containerTag=='span') && $(container).parent().text() == "")) { var innerText = container.innerText.replace(/(\r\n|\n|\r)/gm,""); if (innerText != "") { //this paragraph is not empty, return return; } var top_ = container.offsetTop-10; var left_ = container.offsetLeft-30; if ($(container).parent().attr('id') != "lasso--content") { $(container).parent().empty(); } var button = $('
      '); button.css({top:top_,left:left_}); $("#lasso--content").append(button); if (button.offset().left<0) { button.offset({left:0}); } } } // the following codes decide which UI triggers drag-drop and which UI triggers click-insert // If we are only using drag-drop then clickToInsertElement would be empty var clickToInsertElement = '#lasso-side-comp-button #lasso-toolbar--components__list li'; if (lasso_editor.clickToInsert) { clickToInsertElement = '#lasso-toolbar--components__list li' } else { $('#lasso-toolbar--components #lasso-toolbar--components__list li').draggable({ axis:'y', helper:'clone', cursor: 'move', connectToSortable: '#'+editor, start: function(ui) { // add an origin so sortable can detect where comign from origin = 'draggable'; // get the curent target and add the type class to the drag event var item = ui.currentTarget, type = $(item).attr('data-type'); $(this).addClass(type); } }); } jQuery(document).on('mousedown', clickToInsertElement, function(){ var type = $(this).attr('data-type'); var item = setComponent(type); restoreSelection(window.selRange); $('#lasso-side-comp-button').remove(); if ($('#'+editor).children().length==1 && $('#'+editor).find('.editus-firstp').length ==1) { $('.editus-firstp').replaceWith(item); } else { var t = insert_html(item, false); } postComponent(item,type); lasso_editor.addComponentButton(); }); // replace the content if the content is empty if ( $('#'+editor).children().length && $('#'+editor).children().prop("tagName") == "P" && $('#'+editor).children().text() == "") { $('#'+editor).html(lasso_editor.newObjectContent); $('#'+editor).children().focus(); lasso_editor.addComponentButton(); } lasso_editor.hidePopup = function(){ $(".lasso--text-popup").hide(); } lasso_editor.checkForPopup = function() { if (!lasso_editor.toolbarPopup) return; s = window.getSelection(); oRange = s.getRangeAt(0); //get the text range if (!oRange.collapsed ) { oRect = oRange.getBoundingClientRect(); ; oRect2 = document.getElementById(editor).getBoundingClientRect(); oRect3 = document.body.getBoundingClientRect(); var t2 = $('body').offset().top; //var t2 = document.body.offsetTop.getBoundingClientRect().top; var left = ((oRect.right+oRect.left) - $(".lasso--text-popup").width())/2; if (left <= 0) left = 0; var t = oRect.bottom-document.body.getBoundingClientRect().top; $(".lasso--text-popup").css("left",left); $(".lasso--text-popup").css("top",t+t2); $(".lasso--text-popup").css("display","table"); $(".lasso--text-popup").css("position","absolute"); } else { lasso_editor.hidePopup(); } }; $('#'+editor).on('mouseup',function() { lasso_editor.checkForPopup(); }); $('#'+editor).focusout(function() { lasso_editor.hidePopup(); }); // ways to inject codes into the enterEditor if (lasso_editor.enterEditorHookArray2) { $(lasso_editor.enterEditorHookArray2).each(function(key, val){ val(); }); } }); if (lasso_editor.skipToEdit) { $('#lasso--edit').trigger('click'); lasso_editor.skipToEdit = false; } if (lasso_editor.setupHookArray) { $(lasso_editor.setupHookArray).each(function(key, val){ val(); }); } }); (function( $ ) { $(document).ready(function(){ ///////////////// /// MODAL LOGIC /////////////////// // method to destroy the modal var destroyModal = function(){ $('body').removeClass('lasso-modal-open'); $('#lasso--post-settings__modal, #lasso--modal__overlay').remove(); } jQuery(document).on('click', '.lasso--postsettings__option', function(e){ if ($(e.target).hasClass('tagit')) { // close the modal window if the user clicks on empty spaces // destroy posts modal destroyModal(); } }); // modal click //$('#lasso--post-settings').live('click',function(e){ jQuery(document).on('click','#lasso--post-settings, #lasso--post-settings2',function(e){ e.preventDefault(); // add a body class $('body').toggleClass('lasso-modal-open'); // append teh modal markup ( lasso_editor_component_modal() ) $('body').append(lasso_editor.component_modal); ///////////////// /// UI SLIDER INIT AND METHODS /////////////////// var statusReturn = function( value ) { var out; if ( 100 == value ) { out = 'draft'; } else if ( 150 == value ) { out = 'pending'; } else if ( 200 == value ) { out = 'publish'; } else if ( 'draft' == value ) { out = 100; } else if ( 'pending' == value ) { out = 150; } else if ( 'publish' == value ) { out = 200; } return out; } // init slider $('#lasso--slider').slider({ value:statusReturn(lasso_editor.post_status), min: 100, max: 200, step: lasso_editor.supportPendingStatus ? 50 : 100, animate:'fast', slide: function( event, ui ) { $('input[name="status"]').val( statusReturn(ui.value) ); $('.lasso--postsettings__footer').slideDown() if ( 100 == ui.value ) { $('.story-status').removeClass('story-status-publish').addClass('story-status-draft') } else if ( 200 == ui.value ) { $('.story-status').removeClass('story-status-draft').addClass('story-status-publish') } } }); $('input[name="status"]').val( statusReturn( $( "#lasso--slider" ).slider('value') ) ); /*// if any changes happen then show the footer $('.lasso--modal__trigger-footer').on('keyup',function(){ $('.lasso--postsettings__footer').slideDown() });*/ // categories var cats = $('#lasso--cat-select') , tags = $('#lasso--tag-select') , custom = $('#lasso--custom-taxo-input') cats.tagit({ //fieldName:'itemName[fieldName][]', placeholderText: lasso_editor.strings.catsPlaceholder, //'add categories...', availableTags: lasso_editor.postCategories, allowSpaces: true }); cats.on('change',function(event){ $('.lasso--postsettings__footer').slideDown() }) tags.tagit({ //fieldName:'itemName[fieldName][]', placeholderText: lasso_editor.strings.tagsPlaceholder,//'add tags...', availableTags: lasso_editor.postTags, allowSpaces: true }); tags.on('change',function(event){ $('.lasso--postsettings__footer').slideDown() }) if( $('.editus_custom_date').length ) { $('.editus_custom_date').datepicker({}); } if (lasso_editor.supCustTaxo) { var selTaxo = $('#lasso--custom-taxo-select').val(); custom.val(lasso_editor.postCusTaxonomies[selTaxo]); custom.tagit({ placeholderText: lasso_editor.strings.catsPlaceholder,//'add tags...', availableTags: lasso_editor.extCusTaxonomies[selTaxo], allowSpaces: true }); $('#lasso--custom-taxo-select').on('change', function() { lasso_editor.postCusTaxonomies[selTaxo] = custom.val(); custom.tagit("destroy"); custom.val(lasso_editor.postCusTaxonomies[$(this).val()]); custom.tagit({ placeholderText: lasso_editor.strings.taxoPlaceholder, //'add categories...', availableTags: lasso_editor.extCusTaxonomies[$(this).val()], allowSpaces: true }); selTaxo = $(this).val(); }); } modalResizer() }); // destroy modal if clicking close or overlay //$('#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel').live('click',function(e){ jQuery(document).on('click', '#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel', function(e){ e.preventDefault(); destroyModal(); }); ///////////////// /// EXIT SETTINGS /////////////////// $(document).keyup(function(e) { if ( 27 == e.keyCode ) { destroyModal(); } }); ///////////// // SAVE SETTINGS ////////////// var form; //$('#lasso--postsettings__form').live('submit', function(e) { //$('#lasso--postsettings__form').live('submit', function(e) { jQuery(document).on('submit','#lasso--postsettings__form',function(e) { e.preventDefault(); if ($('#lasso--custom-field-form').length ==0 || $('#lasso--custom-field-form').children().length == 0 ) { $('#lasso--save').removeClass('lasso-publish-post'); $('#lasso--save').trigger('click'); } var $this = $(this); /* //alternate way of setting categories, disabled for now var cats = []; $('input[name="categories"]').each(function () { if (this.checked) { cats.push(this.id);} }); if (cats.length>0) { $('input[name="story_cats"]').val(cats.join(',')); }*/ if (lasso_editor.supCustTaxo) { var selTaxo = $('#lasso--custom-taxo-select').val(); lasso_editor.postCusTaxonomies[selTaxo] = $('#lasso--custom-taxo-input').val(); $(this).find("input[name=story_custom_taxonomies]" ).val(JSON.stringify(lasso_editor.postCusTaxonomies)); } $(this).find('input[type="submit"]').val(lasso_editor.strings.saving); var data2 = $this.serialize(); ///////////// // DO THE SAVE ///////////// var data = { action: 'editus_set_post_setting', postid: lasso_editor.postid, data: data2 }; $.post( lasso_editor.ajaxurl2, data, function(response) { if( true == response.success ) { $('input[type="submit"]').addClass('saved'); $('input[type="submit"]').val(lasso_editor.strings.saved); window.onbeforeunload = null; if ($('#lasso--custom-field-form').length && $('#lasso--custom-field-form').children().length) { $('#lasso--custom-field-form').trigger('submit'); setTimeout(function() { window.location.replace(response.data['link']); }, 1000); } else { // changing the setting can potentially change the URL of the post. In that case we need to // reload the post window.location.replace(response.data['link']); } } else { alert('error:'+response); console.log(response) } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); ///////////// // ADDON TABS ////////////// $(document).on('click', '.lasso--modal__tabs li', function(e){ e.preventDefault() var $this = $(this) , name = $this.data('addon-name') , rem = 'not-visible' , add = 'visible' $('.lasso--modal__tabs li').removeClass('active-tab') $this.addClass('active-tab') $('.lasso--modal__content').removeClass( add ).addClass( rem ) $this.closest('.lasso--modal__inner').find('div[data-addon-content="'+name+'"]').removeClass( rem ).addClass( add ) modalResizer() }) }); })( jQuery ); (function( $ ) { $(document).ready(function(){ // helper to dstry the sidebar var destroySidebar = function(){ $('body').removeClass('lasso-sidebar-open'); } // close the sidebar when clicking outside of it $('body').on('click', '#'+lasso_editor.editor, function(){ //lets not for now //destroySidebar() }); // helper to set the height of the settings panel var settingsHeight = function(){ var settings = $('#lasso--component__settings'); settings.height( $(window).height() ); $(window).resize(function(){ settings.height( $(window).height() ); //$('#lasso--component__settings').perfectScrollbar('update'); }); } var component, data; ///////////// // OPEN COMPONENT SETTINGS //////////// $(document).on('click','.lasso-component--settings__trigger',function(){ var settings = $('#lasso--component__settings') var click = $(this) // let's set our globals if ( $(this).parent().parent().hasClass('aesop-map-component') ) { component = $(this).parent().parent().find('.aesop-component'); } else { component = $(this).closest('.aesop-component,.lasso-component,.wp-block-image,.wp-block-cover'); } data = component.data(); if (!data) { return;} // let's force globalize this until we refactor the js window.component = component; window.componentClone = component.clone(); if (data['componentType'] == 'wpimg') { if ($(component).find('figure.lasso-component').length) { data = $(component).find('figure.lasso-component').data();//'.wp-image.lasso-component').data(); } else if ($(component).find('img').length) { data['img'] =$(component).find('img').attr('src'); } } if (data['componentType'] == 'wpimg-block') { if ($(component).find('img').length) { var $img = $(component).find('img'); data['img'] =$img.attr('src'); data['alt'] =$img.attr('alt'); var c = $img.attr('class'); var $fig = $(component).find('figure'); if ($fig.hasClass('alignright')) { data['align']='right'; } else if ($fig.hasClass('aligncenter')) { data['align']='center'; } else if ($fig.hasClass('alignleft')) { data['align']='left'; } if (c && c.indexOf('wp-image-') == 0) { data['id'] = c.substr(9); } if ($(component).find('figcaption').length) { data['caption'] = $(component).find('figcaption').text(); } if ($(component).find('a').length) { data['link'] = $(component).find('a').attr("href"); } } } if (data['componentType'] == 'wpcover-block') { if ($(component).find('img').length) { var $img = $(component).find('img'); data['img'] =$img.attr('src'); } } if (data['componentType'] =='wpquote') { return;} if (!lasso_editor.component_options) return; // special case for hero gallery if ( $(this).parent().parent().hasClass('aesop-hero-gallery-wrapper') ) { jQuery.extend(data, $(component).find(".fotorama").data()); } // add a body class $('body').toggleClass('lasso-sidebar-open'); settings.find('input[name="unique"]').val( data['unique'] ); // set up settings panel settingsHeight(); settings.html( lasso_editor.component_options[data.componentType] ); // add the type as a value in a hidden field in settings settings.find('.component_type').val( data.componentType ); // fade in save controls $('.lasso-buttoninsert-wrap').fadeIn(600); // initialize scrolbar settings.perfectScrollbar('destroy'); settings.perfectScrollbar(); // map the settings from the data attributes on components into appropriate settings in settings panel settings.find('.lasso-option').each(function(){ var option = $(this).data('option'); var field = $(this).find('.lasso-generator-attr'); // if it's a gallery data attribute map the cehcekd attribute to the right place // @todo - account for map stuff if ( 'gallery-type' == option ) { // this function is repeated on process-gallery-opts line 4 var value_check = function( value ){ if ( 'grid' == value ) { $('.ase-gallery-opts--thumb').fadeOut(); $('.ase-gallery-opts--photoset').fadeOut(); $('.ase-gallery-opts--hero').fadeOut(); $('.ase-gallery-opts--grid').fadeIn(); } else { $('.ase-gallery-opts--grid').fadeOut(); } if ( 'thumbnail' == value ) { $('.ase-gallery-opts--grid').fadeOut(); $('.ase-gallery-opts--photoset').fadeOut(); $('.ase-gallery-opts--hero').fadeOut(); $('.ase-gallery-opts--thumb').fadeIn(); } else { $('.ase-gallery-opts--thumb').fadeOut(); } if ( 'photoset' == value ) { $('.ase-gallery-opts--grid').fadeOut(); $('.ase-gallery-opts--thumb').fadeOut(); $('.ase-gallery-opts--hero').fadeOut(); $('.ase-gallery-opts--photoset').fadeIn(); } else { $('.ase-gallery-opts--photoset').fadeOut(); } if ( 'hero' == value ) { $('.ase-gallery-opts--grid').fadeOut(); $('.ase-gallery-opts--thumb').fadeOut(); $('.ase-gallery-opts--photoset').fadeOut(); $('.ase-gallery-opts--hero').fadeIn(); } else { $('.ase-gallery-opts--hero').fadeOut(); } } $(field).each(function(){ if ( $(this).val() == data.galleryType ) { $(this).parent().addClass('selected') $(this).prop('checked',true); value_check( $(this).val() ); // add the type to a hidden field $('#ase_gallery_type').val( $(this).val() ) } }); } else { $( field[0] ).val(data[option]); } }); //////////// // SMOOTH SLIDE TO COMPONENT - @since 0.9.5 /////////// // if its a content component if ( component.hasClass('aesop-content-component') ) { var target = component.find('.aesop-content-comp-wrap').attr('id') , item = $('#'+target) } else { var item = $('#'+component.attr('id') ) } if (item.length) { //$('html, body').animate({ scrollTop: item.offset().top - 50 }, 400); } ///////////// // GET GALLERY IMAGES IF ITS A GALLERY ///////////// //if ( $(this).parent().parent().hasClass('empty-gallery') ) { //settings.addClass('gallery-no-images') //} if ( $(this).parent().parent().hasClass('aesop-gallery-component') ) { var $this = $(this) , ajaxurl = lasso_editor.ajaxurl , form = $('#lasso--component-settings-form.gallery') , nonce = lasso_editor.getGallImgNonce , gall_id = data['id'] var data = { action: 'process_gallery_get-images', post_id: gall_id, nonce: nonce }; // post ajax response with data $.post( ajaxurl, data, function(response) { $('#lasso--gallery__images').html( response.data.html ); ///////////// // CALL SORTABLE ON RECIEVED IMAGES ///////////// var gallery = $('#ase-gallery-images'); gallery.ready(function(){ gallery.sortable({ containment: 'parent', cursor: 'move', opacity: 0.8, placeholder: 'ase-gallery-drop-zone', forcePlaceholderSize:true, update: function(){ var imageArray = $(this).sortable('toArray'); $('#ase_gallery_ids').val( imageArray ); }, create: function(){ var imageArray = $(this).sortable('toArray'); $('#ase_gallery_ids').val( imageArray ); } }); }); }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); });; } }).on('click', '#lasso-upload-img', function( e ){ e.preventDefault(); className = e.currentTarget.parentElement.className; var type = $('input[name="component_type"]').val() // If the media frame already exists, reopen it. if ( typeof lasso_file_frame != 'undefined' ) { lasso_file_frame.close(); } // Create the media frame. lasso_file_frame = wp.media.frames.file_frame = wp.media({ title: 'Select Image', button: { text: 'Insert Image', }, multiple: false // Set to true to allow multiple files to be selected }); // When an image is selected, run a callback. lasso_file_frame.on( 'select', function() { var attachment = lasso_file_frame.state().get('selection').first().toJSON(); $('.aesop-generator-attr-media_upload').prop('value',attachment.url); ///////////// // START LIVE IMAGE EDITING COMPONENTS // @todo - this was going to be taken care of in above but it seems we have to bind this to the file upload here? //////////// if ( 'parallax' == type ) { component.find('.aesop-parallax-sc-img').prop('src', attachment.url ) } else if ( 'quote' == type ) { component.css({ 'background-image': 'url('+ attachment.url +')' }); } else if ( 'image' == type ) { $("#aesop-generator-attr-img").val(attachment.url); component.find('.aesop-image-component-image > img').prop('src', attachment.url); // new addition for panorama images component.find('.paver__pano').css({'background-image': 'url('+ attachment.url +')'}); } else if ( 'character' == type ) { component.find('.aesop-character-avatar').prop('src', attachment.url) } else if ( 'chapter' == type ) { component.find('.aesop-article-chapter').css({ 'background-image': 'url('+ attachment.url +')' }); }else if ( 'wpimg' == type ) { var img = window.component.find('img'); if (img.length>0) { img.prop('src', attachment.url ); img.prop("srcset",""); } } else if ( 'wpimg-block' == type ) { var img = window.component.find('img'); if (img.length >0) { img.prop('src', attachment.url ); img.prop("srcset",""); if (attachment.id) { img.removeClass(); img.addClass("wp-image-"+attachment.id); window.component.data( 'id', ""+attachment.id); } } } else if ( 'wpcover-block' == type ) { var img = window.component.find('img'); if (img.length >0) { img.prop('src', attachment.url ); img.prop("srcset",""); img.removeClass(); img.addClass("wp-block-cover__image-background"); if (attachment.id) { img.addClass("wp-image-"+attachment.id); } } else { window.component.css('background-image', "url("+attachment.url+")"); } } ///////////// // EDN LIVE IMAGE EDITING COMPONENTS //////////// }); // Finally, open the modal lasso_file_frame.open(); }); // destroy panel if clicking close or overlay //$('#lasso--sidebar__close').live('click',function(e){ // cancel jQuery(document).on('click','#lasso--sidebar__close',function(e){ e.preventDefault(); window.component.replaceWith(window.componentClone); //restore the state before editing destroySidebar(); $('#lasso--component__settings').perfectScrollbar('destroy'); }); }); })( jQuery ); (function( $ ) { $(document).ready(function(){ ///////////// // LIVE EDITING COMPONENTS // @todo - this is hella dirty and needs to be cleaned up // @todo - move this mess to it's own file //////////// $(document).on('click', '.lasso-component--settings__trigger', function(){ var settings = $('#lasso--component__settings') // QUOTE LIVE EDIT /////////////////// //settings.find('#aesop-generator-attr-background').live('change',function(){ settings.find('#aesop-generator-attr-background').on('change',function(){ component.css({'background-color': $(this).val()}); }); //settings.find('#aesop-generator-attr-text').live('change',function(){ settings.find('#aesop-generator-attr-text').on('change',function(){ component.css({'color': $(this).val()}); }); settings.find('#aesop-generator-attr-quote').on('keyup',function(){ component.find('blockquote span').text( $(this).val() ); }); settings.find('#aesop-generator-attr-cite').on('keyup',function(){ var t = component.find('blockquote cite'); if ( 0 == t.length ) { component.find('blockquote').append( ''+$(this).val()+'' ); } else { component.find('blockquote cite').text( $(this).val() ); } }); settings.find('.aesop-quote-width > #aesop-generator-attr-width').on('keyup',function(){ component.css('width', $(this).val() ); }); settings.find('.aesop-quote-type #aesop-generator-attr-type').on('change',function(){ var value = $(this).val() if ( 'pull' == value ) { component.css('background-color','transparent') } component.removeClass('aesop-quote-type-block aesop-quote-type-pull') component.addClass('aesop-quote-type-'+$(this).val()+' ') }); settings.find('.aesop-quote-align #aesop-generator-attr-align').on('change',function(){ var value = $(this).val() if ( 'left' == value ) { component.removeClass('aesop-component-align-right aesop-component-align-center') component.find('blockquote').removeClass('aesop-component-align-right aesop-component-align-center') } else if ( 'right' == value ) { component.removeClass('aesop-component-align-left aesop-component-align-center') component.find('blockquote').removeClass('aesop-component-align-left aesop-component-align-center') } else if ( 'center' == value ) { component.removeClass('aesop-component-align-left aesop-component-align-right') component.find('blockquote').removeClass('aesop-component-align-left aesop-component-align-right') } component.addClass('aesop-component-align-'+$(this).val()+' ') component.find('blockquote').addClass('aesop-component-align-'+$(this).val()+' ') }); // PARALLAX LIVE EDIT /////////////////// settings.find('.aesop-parallax-caption > #aesop-generator-attr-caption').on('keyup',function(){ var t = component.find('.aesop-parallax-sc-caption-wrap') if ( 0 == t.length ) { component.find('img').after( '
      '+$(this).val()+'
      ' ); } else { component.find('.aesop-parallax-sc-caption-wrap').text( $(this).val() ); } }) settings.find('.aesop-parallax-captionposition > #aesop-generator-attr-captionposition').on('change',function(){ var value = $(this).val() if ( 'bottom-left' == value ) { component.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-right top-left top-right') } else if ( 'bottom-right' == value ) { component.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-left top-left top-right') } else if ( 'top-left' == value ) { component.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-right top-right bottom-left') } else if ( 'top-right' == value ) { component.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-right bottom-left top-left') } component.find('.aesop-parallax-sc-caption-wrap').addClass( value ); }) // IMAGE LIVE EDIT /////////////////// settings.find('.aesop-image-caption > #aesop-generator-attr-caption').on('keyup',function(){ var t = component.find('.aesop-image-component-caption'); if ( 0 == t.length ) { component.find('img').after( '

      '+$(this).val()+'

      ' ); } else { component.find('.aesop-image-component-caption').text( $(this).val() ); } }) settings.find('.aesop-image-imgwidth > #aesop-generator-attr-imgwidth').on('keyup',function(){ component.find('.aesop-image-component-image').css('max-width', $(this).val() ); }) settings.find('.aesop-image-align > #aesop-generator-attr-align').on('change',function(){ var value = $(this).val() if ( 'left' == value ) { component.find('.aesop-image-component-image').removeClass('aesop-component-align-right aesop-component-align-center') } else if ( 'right' == value ) { component.find('.aesop-image-component-image').removeClass('aesop-component-align-left aesop-component-align-center') } else if ( 'center' == value ) { component.find('.aesop-image-component-image').removeClass('aesop-component-align-left aesop-component-align-right') } component.find('.aesop-image-component-image').addClass('aesop-component-align-'+$(this).val()+' ') }) settings.find('.aesop-image-captionposition > #aesop-generator-attr-captionposition').on('change',function(){ var value = $(this).val(); if ( 'left' == value ) { component.find('.aesop-image-component-image').removeClass('aesop-image-component-caption-right aesop-image-component-caption-center') } else if ( 'right' == value ) { component.find('.aesop-image-component-image').removeClass('aesop-image-component-caption-left aesop-image-component-caption-center') } else if ( 'center' == value ) { component.find('.aesop-image-component-image').removeClass('aesop-image-component-caption-left aesop-image-component-caption-right') } component.find('.lasso-image-component-image').addClass('lasso-image-component-caption-'+value+' '); }); settings.find('.aesop-image-offset > #aesop-generator-attr-offset').on('keyup',function(){ var value = $(this).val(); if ( component.find('.aesop-image-component-image').hasClass('aesop-component-align-left') ) { component.find('.aesop-image-component-image').css('margin-left', $(this).val() ); } else { component.find('.aesop-image-component-image').css('margin-right', $(this).val() ); } }); // CHARACTER LIVE EDIT /////////////////// settings.find('.aesop-character-name > #aesop-generator-attr-name').on('keyup',function(){ component.find('.aesop-character-title').text( $(this).val() ); }) settings.find('.aesop-character-caption > #aesop-generator-attr-caption').on('keyup',function(){ component.find('.aesop-character-cap').text( $(this).val() ); }) settings.find('.aesop-character-align > #aesop-generator-attr-align').on('change',function(){ var value = $(this).val() if ( 'left' == value ) { component.removeClass('aesop-component-align-right aesop-component-align-center'); } else if ( 'center' == value ) { component.removeClass('aesop-component-align-left aesop-component-align-right'); } component.addClass('aesop-component-align-'+$(this).val()+' '); }); // CHAPTER LIVE EDIT /////////////////// settings.find('.aesop-chapter-title > #aesop-generator-attr-title').on('keyup',function(){ component.find('.aesop-cover-title span').text( $(this).val() ); }) settings.find('.aesop-chapter-subtitle > #aesop-generator-attr-subtitle').on('keyup',function(){ component.find('.aesop-cover-title small').text( $(this).val() ); }) // VIDEO LIVE EDITOR ///////////////////// //settings.find('.lasso-video-src > #aesop-generator-attr-src').live('change blur',function(){ settings.find('.aesop-video-src > #aesop-generator-attr-src').on('change blur',function(){ val = $(this).val() if ( 'vimeo' == val ) { component.find('iframe').attr('src', '//player.vimeo.com/video/'+val+' ') initVideoProvider( settings, component, 'vimeo' ); } else if ( 'youtube' == val ) { component.find('iframe').attr('src', '//www.youtube.com/embed/'+val+'?rel=0&wmode=transparent') initVideoProvider( settings, component, 'youtube' ); } }); settings.find('.aesop-video-id > #aesop-generator-attr-id').on('keyup',function(){ t = $('.aesop-video-src > #aesop-generator-attr-src').val(); val = $(this).val(); if ( 'vimeo' == t ) { component.find('iframe').attr('src', '//player.vimeo.com/video/'+val+' ') } else if ( 'youtube' == t ) { component.find('iframe').attr('src', '//www.youtube.com/embed/'+val+'?rel=0&wmode=transparent') } }); settings.find('.aesop-video-width > #aesop-generator-attr-width').on('keyup',function(){ component.find('.aesop-video-container').css('max-width', $(this).val() ); }); // CONTENT COMPONENT LIVE EDIT ///// //settings.find('.lasso-content-background > #aesop-generator-attr-background').live('change',function(){ settings.find('.lasso-content-background > #aesop-generator-attr-background').on('change',function(){ component.find('.aesop-content-comp-wrap').css({'background-color': $(this).val()}); }); //settings.find('.lasso-content-color > #aesop-generator-attr-color').live('change',function(){ settings.find('.aesop-content-color > #aesop-generator-attr-color').on('change',function(){ component.find('.aesop-content-comp-wrap').css({'color': $(this).val()}); }); //settings.find('.lasso-content-height > #aesop-generator-attr-height').live('keyup',function(){ settings.find('.aesop-content-height > #aesop-generator-attr-height').on('keyup',function(){ val = $(this).val() component.find('.aesop-content-comp-wrap').css({'min-height': $(this).val()}); }); //settings.find('.lasso-content-columns > #aesop-generator-attr-columns').live('change',function(){ settings.find('.aesop-content-columns > #aesop-generator-attr-columns').on('change',function(){ val = $(this).val() if ( '1' == val ) { component.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-2 aesop-content-comp-columns-3 aesop-content-comp-columns-4').addClass('aesop-content-comp-columns-1') } else if ( '2' == val ) { component.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-1 aesop-content-comp-columns-3 aesop-content-comp-columns-4').addClass('aesop-content-comp-columns-2') } else if ( '3' == val ) { component.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-1 aesop-content-comp-columns-2 aesop-content-comp-columns-4').addClass('aesop-content-comp-columns-3') } else if ( '4' == val ) { component.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-1 aesop-content-comp-columns-2 aesop-content-comp-columns-3').addClass('aesop-content-comp-columns-4') } }); }); /** * * Swap the video player with the correct id * @param object the global settings for this component * @param object the component we're editing * @param type string the type of video (vimeo, youtube) * @since 0.9.7 */ function initVideoProvider( settings, component, type ){ //settings.find('.lasso-video-id > #aesop-generator-attr-id').live('change',function(){ settings.find('.lasso-video-id > #aesop-generator-attr-id').on('change',function(){ video_id = $(this).val() if ( 'vimeo' == type ) { component.find('iframe').attr('src', '//player.vimeo.com/video/'+video_id+' ') } else if ( 'youtube' == type ) { component.find('iframe').attr('src', '//www.youtube.com/embed/'+video_id+'?rel=0&wmode=transparent') } }) } }); })( jQuery ); jQuery(function( $ ) { function saveSelection() { if (window.getSelection) { sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { return sel.getRangeAt(0); } } else if (document.selection && document.selection.createRange) { return document.selection.createRange(); } return null; } function restoreSelection(range) { if (range) { if (window.getSelection) { sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } else if (document.selection && range.select) { range.select(); } } else { if (window.getSelection) { sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { window.selRange = sel.getRangeAt(0); } } } } lasso_editor.checkSelection = function (saveSel) { /*var saveSel = saveSelection; if (saveSel == undefined) { saveSel = false; } */ if (saveSel == true) { window.selRange = saveSelection(); } if (!window.selRange || window.selRange.collapsed) { swal({ title:"", text: lasso_editor.strings.selectText, closeOnConfirm: true }); return false; } return true; } var ifSmallWidth = function(){ return 600 <= $(window).width() ? true : false; } var dropClass = function() { return "up";//ifSmallWidth() ? 'up' : 'down'; } ///////////// /// DROP UP ///////////// $(document).on('click', '#lasso-toolbar--components', function(e){ $(this).toggleClass('toolbar--drop-'+dropClass() ); // show and hide the component list var dropUp = $(this).find('ul'); if ($(this).hasClass( 'toolbar--drop-'+dropClass() )) { $(dropUp).show(); } else { $(dropUp).hide(); } var components = $(dropUp).find("li").length; if (components<7) { $(dropUp).css('width',''+(components*42+8)+'px'); $(dropUp).css('left','-'+((components*42+8)/2-20)+'px'); } restoreSelection(window.selRange); $('#lasso-toolbar--html').removeClass('html--drop-'+dropClass() ); $('#lasso-toolbar--link').removeClass('link--drop-'+dropClass() ); if( !lasso_editor.isMobile) { // get the height of the list of components var dropUpHeight = $(dropUp).height(), caretSpacing = 15; // this is the height of the caret // and adjust the drop up position as necessary if ( true == ifSmallWidth() ) { $(dropUp).css({ dropUp: dropUpHeight, top: -(dropUpHeight + caretSpacing) }); } } else { /*$(dropUp).css({ dropUp: dropUpHeight, top: 40 });*/ } }); // if we the side component button feature is on if (lasso_editor.buttonOnEmptyP) { jQuery(document).on('click', '#lasso--content p', function(e){ //if the user click on a paragraph if ($(this).find("#lasso-side-comp-button").length == 0) { lasso_editor.addComponentButton(); } }); } jQuery(document).on('mousedown', '#lasso-side-comp-button', function(){ // side component button handler window.selRange = saveSelection(); $(this).toggleClass('toolbar--side' ); // show and hide the component list var drop = $('#lasso-side-comp-button #lasso-toolbar--components__list'); if (drop.length ==0) { drop = $('#lasso-toolbar--components__list').clone(); $(this).append(drop); } if ($(this).hasClass( 'toolbar--side')) { $(drop).show(); } else { $(drop).hide(); } $('#lasso-toolbar--html').removeClass('html--drop-'+dropClass() ); $('#lasso-toolbar--link').removeClass('link--drop-'+dropClass() ); $(drop).css({ left: '30px', top:'0px' }); if ($(this).find("li").length<7) { $(this).find("ul").css('column-count',''+$(this).find("ul li").length); $(this).find("ul").css('width','auto'); } }); ///////////// /// HTML DROP UP ///////////// //$('#lasso-toolbar--html').live('mousedown',function(){ /*jQuery(document).on('mousedown', '#lasso-toolbar--html,#lasso-toolbar--components,#lasso-toolbar--link', function(){ if( ! $(this).hasClass('html--drop-'+dropClass() ) ) { var article = document.getElementById(lasso_editor.editor); article.highlight(); window.selRange = saveSelection(); if( typeof window.selRange === 'undefined' || null == window.selRange ) { window.selRange = saveSelection(); } } });*/ //$('#lasso-toolbar--html__inner').live('focusout',function(){ jQuery(document).on('focusout', '#lasso-toolbar--html__inner', function(){ restoreSelection(window.selRange); }); //$('#lasso-toolbar--html__inner').live('focus',function(){ jQuery(document).on('focus', '#lasso-toolbar--html__inner', function(){ var savedSelect = saveSelection(); if ( savedSelect && $(savedSelect.commonAncestorContainer).parents('#lasso--content').length != 0 ) { window.selRange = saveSelection(); } }); $(document).on('click', '#lasso-toolbar--html', function(e){ $(this).toggleClass('html--drop-'+dropClass() ); $('#lasso-toolbar--components').removeClass('toolbar--drop-'+dropClass() ); $('#lasso-toolbar--link').removeClass('link--drop-'+dropClass() ); // prevent dropup from closing //$('#lasso-toolbar--html__wrap').live('click',function(){ jQuery(document).on('click', '#lasso-toolbar--html__wrap', function(){ return false; }); $(this).find('#lasso-toolbar--html__inner').focus(); }); //$('.lasso-toolbar--html__cancel').live('click',function(){ jQuery(document).on('click', '.lasso-toolbar--html__cancel', function(){ $(this).closest('li').removeClass('html--drop-'+dropClass() ); }); ////////////////// // HTML FORMATTING IN HTML DROP UP MENU ////////////////// var htmlItemInsert = function(markup){ return $('#lasso-toolbar--html__inner').text(markup); } //$('#lasso-html--h2').live('click',function(e){ jQuery(document).on('click', '#lasso-html--h2', function(e){ e.preventDefault(); htmlItemInsert('

      H2 Heading

      '); }); //$('#lasso-html--h3').live('click',function(e){ jQuery(document).on('click', '#lasso-html--h3', function(e){ e.preventDefault(); htmlItemInsert('

      H3 Heading

      '); }); //$('#lasso-html--ul').live('click',function(e){ jQuery(document).on('click', '#lasso-html--ul', function(e){ e.preventDefault(); htmlItemInsert('
      • Item
      '); }); //$('#lasso-html--ol').live('click',function(e){ jQuery(document).on('click', '#lasso-html--ol', function(e){ e.preventDefault(); htmlItemInsert('
      1. Item
      '); }); jQuery(document).on('click', '#lasso-html--table', function(e){ e.preventDefault(); htmlItemInsert(lasso_editor.tableCode);//'
      Cell 1Cell 2
      Cell 3Cell 4
      '); }); //////////// /// LINK DROP UIP //////////// //$('#lasso-toolbar--link').live('mousedown',function(){ jQuery(document).on('mousedown', '#lasso-toolbar--link', function(){ $('#lasso-toolbar--components').removeClass('toolbar--drop-'+dropClass() ); $('#lasso-toolbar--html').removeClass('html--drop-'+dropClass() ); }); //$('#lasso-toolbar--link__inner').live('focusout',function(){ jQuery(document).on('focusout', '#lasso-toolbar--link__inner', function(){ restoreSelection(window.selRange); }); //$('#lasso-toolbar--link__inner').live('focus',function(){ jQuery(document).on('focus', '#lasso-toolbar--link__inner', function(){ var savedSelect = saveSelection(); if ( savedSelect && $(savedSelect.commonAncestorContainer).parents('#lasso--content').length != 0 ) { window.selRange = saveSelection(); } }); $(document).on('click', '#lasso-toolbar--link', function(e){ // exit if nothing is selected if (!lasso_editor.checkSelection()) return false; $(this).toggleClass('link--drop-'+dropClass()); $('#aesop-toolbar--link_newtab').unbind('mousedown').mousedown(function() { $(this).prop("checked", !$(this).prop("checked")); return; }); // prevent dropup from closing jQuery(document).on('click', '#lasso-toolbar--link__wrap', function(){ return false; }); $(this).find('#lasso-toolbar--link__inner').focus(); if (window.selRange.startContainer.parentNode.tagName == 'A') { $('#lasso-toolbar--link__inner').text(window.selRange.startContainer.parentNode.href); } }); // RESTORING LINK SELECTION //$('.lasso-editing .lasso-link').live('click',function(e){ jQuery(document).on('click', '.lasso-editing .lasso-link', function(e){ e.preventDefault(); // prevent dropup from closing //$('#lasso-toolbar--link__wrap').live('click',function(){ jQuery(document).on('click', '#lasso-toolbar--link__wrap', function(){ return false; }); var link = $(this).attr('href'); $('#lasso-toolbar--link').addClass('link--drop-'+dropClass()); $('#lasso-toolbar--link__inner').text(link); }); ///////////// /// DELETING ///////////// //$('.lasso-delete').live('click',function(e) { jQuery(document).on('click', '.lasso-delete', function(e){ e.preventDefault(); var $this = $(this); swal({ title: "Delete this component?", type: "warning", text: false, showCancelButton: true, confirmButtonColor: "#d9534f", confirmButtonText: "Yes, delete it!", closeOnConfirm: true }, function(){ // remove component $this.closest('.aesop-component').remove(); // remove wp image if its a wp image $this.closest('.lasso-component').remove(); if ($this.parent().parent().hasClass('wp-block-image')) { //$this.closest('.wp-block-image').remove(); $this.parent().parent().remove(); } }); }); ///////////// /// CLONING ///////////// //$('.lasso-clone').live('click',function(e) { jQuery(document).on('click', '.lasso-clone', function(e){ // sore reference to this var $this = $(this); e.preventDefault(); $this.closest('.aesop-component').clone().insertAfter( $(this).parent().parent() ).hide().fadeIn() $this.closest('.lasso-component').clone().insertAfter( $(this).parent().parent() ).hide().fadeIn() }); }); jQuery(document).ready(function($){ var ajaxurl = lasso_editor.ajaxurl, save = $('.lasso--controls__right a'), editor = lasso_editor.editor, postid = lasso_editor.postid, oldHtml = $('#'+editor).html(), warnNoSave = 'You have unsaved changes!'; // Set to true when we want to reload the current page without a warning message noWarningReload = false; /////////////////////// // 1. IF UNSAVED CHANGES STORE IN LOCAL STORAGE // @todo - need to account for component on the page this only accounts for text /////////////////////// //$('#'+editor).live('change',function(){ jQuery(document).on('change', '#'+editor, function(){ var $this = $(this), newHtml = $this.html(); if ( oldHtml !== newHtml ) { localStorage.setItem( 'lasso_backup_'+postid , newHtml ); } }); /////////////////////// // 2. WARN THE USER IF THEY TRY TO NAVIGATE AWAY WITH UNSAVED CHANGES /////////////////////// window.onbeforeunload = function () { if ( localStorage.getItem( 'lasso_backup_'+postid ) && lasso_editor.userCanEdit ) { return warnNoSave; $('#lasso--save').css('opacity',1); } } // but also clear the unsaved changes if the user does navigate away window.onunload = function () { if ( localStorage.getItem( 'lasso_backup_'+postid ) && lasso_editor.userCanEdit ) { localStorage.clear(); } } /*function process_html(html, do_shortcodify) { // take care of twitter widget html = process_twitter(html); // remove objects to ignore if they are not removed already if (lasso_editor.showIgnoredItems ) { var $temp = $('
      ').html( html ); $temp.find(lasso_editor.objectsNoSave).remove(); $temp.find(lasso_editor.supportedNoSave).remove(); html = $temp.html(); } // remove extra classes { var $temp = $('
      ').html( html ); $temp.find("a").removeClass("lasso-link"); $temp.find("span").removeClass("lasso-span"); $temp.find("h2").removeClass("lasso-h2"); $temp.find("h3").removeClass("lasso-h3"); $temp.find(".lasso-noclass").removeClass("lasso-noclass"); $temp.find(".lasso-undeletable").removeClass("lasso-undeletable"); $temp.find(".lasso-component--controls, .aesop-events-edit").remove(); $temp.find('*[class=""]').removeAttr('class'); html = $temp.html(); } // remove all contenteditable attr html = removeEditable(html); // if custom fields if (lasso_editor.customFields) { saveCustomFields(html); } // shortcode ultimate html = shortcodify_su(html); // shortcode aesop html = do_shortcodify ? shortcodify(html) : html; // restore other shortcodes to the original shortcodes html = replace_rendered_shortcodes( html ); // avia editor if (lasso_editor.aviaEditor) { html = shortcodify_avia(html); } // WordPress Block if (lasso_editor.hasGutenberg) { html = process_gutenberg(html); } // if multi page if (lasso_editor.multipages != "-1") { var res = lasso_editor.post_content.split(""); var html2 = ""; res[parseInt(lasso_editor.multipages)] = html; html = res.join(""); } // any user supplied filters if (lasso_editor.filterArray) { $(lasso_editor.filterArray).each(function(key, val){ html = val(html ); }); } return html }*/ /////////////////////// // 3. SAVE OR PUBLISH OBJECT /////////////////////// //$('.lasso--controls__right a:not(#lasso--exit)').live('click',function(e) { //jQuery(document).on('click', '.lasso--controls__right a:not(#lasso--exit)', function(e){ //jQuery('.lasso--controls__right a:not(#lasso--exit)').on('click', function(e){ jQuery(document).on('click','#lasso--save, #lasso--publish', function(e){ var warnNoSave = null; e.preventDefault(); // sore reference to this var $this = $(this); // unwrap wp images /*$(".lasso--wpimg__wrap").each(function(){ //if ( !$(this).hasClass('wp-caption') ) { // $(this).children().unwrap() //} $('.lasso-component--controls').remove(); }); // unwrap custom components $('.lasso-component').each(function(){ $('.lasso-component--controls').remove(); });*/ // unwrap map from hits drag holder $('#lasso--map-form').each(function(){ var $this = $(this) $this.find('.lasso-component--controls, .lasso--map-form__footer ').remove() $this.children().unwrap() }); // if tehre are any scrollnav sections we need to break them open so the editor doesnt save the html $('.scroll-nav__section').each(function(){ $(this).children().unwrap(); }) // remove any notices $('#lasso--notice').remove(); //remove any comp buttons $('#lasso-side-comp-button').remove(); $('.lasso--text-popup').remove(); // let user know someting is happening on click $(this).addClass('being-saved'); // get the html from our div var html = $('#'+editor).html(), postid = lasso_editor.postid; if (!html) return; html = process_html(html, $this.hasClass('shortcodify-enabled')); // gather the data var data = { action: ($this.hasClass('lasso-publish-post') && lasso_editor.can_publish) ? 'process_save_publish-content' : 'process_save_content', author: lasso_editor.author, content: html, post_id: postid, nonce: lasso_editor.nonce }; // intercept if publish to confirm if ( $this.hasClass('lasso-publish-post') ) { if (lasso_editor.publishHandler) { // custom publish handler lasso_editor.publishHandler(data); } else { swal({ title: lasso_editor.strings.publishPost, type: "info", text: false, showCancelButton: true, confirmButtonColor: "#5bc0de", confirmButtonText: lasso_editor.strings.publishYes, closeOnConfirm: true }, function(){ runSavePublish(true) }); } } else { runSavePublish(false) } function process_html(html, do_shortcodify) { // take care of twitter widget html = process_twitter(html); // remove objects to ignore if they are not removed already if (lasso_editor.showIgnoredItems ) { var $temp = $('
      ').html( html ); $temp.find(lasso_editor.objectsNoSave).remove(); $temp.find(lasso_editor.supportedNoSave).remove(); html = $temp.html(); } // remove extra classes { var $temp = $('
      ').html( html ); $temp.find("a").removeClass("lasso-link"); $temp.find("span").removeClass("lasso-span"); $temp.find("h2").removeClass("lasso-h2"); $temp.find("h3").removeClass("lasso-h3"); $temp.find(".lasso-noclass").removeClass("lasso-noclass"); $temp.find(".editus-firstp").removeClass("editus-firstp"); $temp.find(".lasso-undeletable").removeClass("lasso-undeletable"); $temp.find(".lasso-component--controls, .aesop-events-edit").remove(); $temp.find('*[class=""]').removeAttr('class'); //process $temp.find("span#more-"+lasso_editor.postid).replaceWith( "" ); html = $temp.html(); } // remove all contenteditable attr html = removeEditable(html); // if custom fields if (lasso_editor.customFields) { saveCustomFields(html); } // WordPress Block if (lasso_editor.hasGutenberg) { const reg = /]*>

      ","-->"); html = process_gutenberg(html); } //shortcodes { // shortcode ultimate //html = shortcodify_su(html); // restore other shortcodes to the original shortcodes html = replace_rendered_shortcodes( html ); // shortcode aesop html = do_shortcodify ? shortcodify(html) : html; // avia editor if (lasso_editor.aviaEditor) { html = shortcodify_avia(html); } } // if multi page if (lasso_editor.multipages != "-1") { var res = lasso_editor.post_content.split(""); var html2 = ""; res[parseInt(lasso_editor.multipages)] = html; html = res.join(""); } // any user supplied filters if (lasso_editor.filterArray) { $(lasso_editor.filterArray).each(function(key, val){ html = val(html ); }); } return html } function removeComment(content) { return content.replace(//g, ""); } function removeEditable(content) { return content.replace(/contenteditable="(false|true)"/g, ""); } // gather the custom field data and save to lasso_editor.cftosave function saveCustomFields(content) { var data ={}; var customFields = lasso_editor.customFields; for (var key in customFields) { var selector =''; var html = false; var isimgurl = false; if (typeof(lasso_editor.customFields[key]) == 'object') { selector = customFields[key]['selector']; html = customFields[key]['html']; isimgurl = customFields[key]['imgurl']; } else { selector =customFields[key]; } var arr = $(document).find(selector); if (arr.length) { if (html) { data[key] = arr[0].innerHTML.replace(/[\n\r]/g, '');; } else if (isimgurl) { data[key] = $(arr[0]).attr('src'); } else { data[key] = arr[0].innerText;//.replace(/[\n\r]/g, ''); } } } lasso_editor.cftosave = data; } /** * Turn content html into shortcodes * @param {[type]} content [description] * @param {[type]} selector [description] * @return {[type]} [description] */ function shortcodify(content,selector){ // Convert the html into a series of jQuery objects var j = $.parseHTML(content); var processed = ''; if (j == null) { return content; } // Iterate through the array of dom objects for (var i = 0; i < j.length; i++) { var component = $(j[i]); // If it's not a component, move along if ( !component.hasClass('aesop-component') ) { if(component.find('.aesop-component').length !== 0) { // if there is an aesop component in a child, recursively process it var comp_content = component.html(); comp_content = shortcodify(comp_content); component.html(comp_content); processed += component.clone().wrap('

      ').parent().html();; } else // Let's test what kind of object it is if ( component.context && component.context.nodeType == 3 ) { // Text only object without dom processed += j[i].data; } else if ( (component.context && component.context.nodeType == 8) || j[i].nodeType==8) { processed += ''; } else { // DOM object if (j[i].outerHTML) { processed += j[i].outerHTML; } else if (j[i].data){ processed += j[i].data; } } continue; } var data = component.data(); var params = ''; // It's a component, let's check to make sure it's defined properly if ( data.hasOwnProperty('componentType') ) { if (data.componentType =="wpimg") continue; for ( var index in data ) { // Don't accept componentType as a param if ( !data.hasOwnProperty(index) || index == 'componentType' ) { continue; } // Build the params string out of the data attributes params += " " + index + '="' + data[index] + '"'; } var sc = '[aesop_' + data.componentType + params + ']'; // Let's check to see if it's a "full" shortcode var inner = component.find('.aesop-component-content-data'); if ( inner.length != 0 ) { sc += inner[0].innerHTML + "[/aesop_" + data.componentType + "]"; } processed += sc; } } return processed; } function process_twitter(html) { // if twitter widget doesn't exist return if (!html) return null; if (html.indexOf("twitterwidget") ==-1) return html; var t = $('#'+editor).clone(); var t1 = t.find('twitterwidget'); var t2 = $('#'+editor).find('twitterwidget'); var i; for (i = 0; i').html(t2[i].shadowRoot.innerHTML).find('.EmbeddedTweet').data('click-to-open-target'); $(t1[i]).replaceWith(t5); } var html2 = t.html(); return html2; } //shortcode ultimates function shortcodify_su(content,selector){ // Convert the html into a series of jQuery objects var j = $.parseHTML(content); var processed = ''; // Iterate through the array of dom objects for (var i = 0; i < j.length; i++) { var component = $(j[i]); // If it's not a component, move along if ( !component.hasClass('su-box') && !component.hasClass('su-note') && !component.hasClass('su-document') && !component.hasClass('su-spoiler')) { // Let's test what kind of object it is if ( component.context.nodeType == 3 ) { // Text only object without dom processed += j[i].data; } else if ( component.context.nodeType == 8 ) { processed += ''; } else { // DOM object processed += j[i].outerHTML; } continue; } if ( component.hasClass('su-box')) { var box_title = component.find('.su-box-title')[0].innerHTML; var box_content = component.find('.su-box-content')[0].innerHTML; var box_color = component.find('.su-box-title')[0].style.backgroundColor; var sc = '[su_box title="'+box_title+'"'+' box_color="' +box_color+'"]' + box_content+'[/su_box]'; processed += sc; } else if ( component.hasClass('su-note')) { var note_content = component.find('.su-note-inner')[0].innerHTML; note_content = shortcodify_su(note_content); var note_color = component.find('.su-note-inner')[0].style.backgroundColor; var text_color = component.find('.su-note-inner')[0].style.color; var sc = '[su_note note_color="'+ note_color + '" text_color="'+text_color +'"]' + note_content+'[/su_note]'; processed += sc; } else if ( component.hasClass('su-document')) { var ifr = component.find('iframe.su-document')[0]; var url = getParameterByName("url",ifr.src); var width = ifr.width; var height = ifr.height; var sc = '[su_document url="'+ url + '" width="'+ width +'" height="' + height+'"]'; processed += sc; } else if ( component.hasClass('su-spoiler')) { var spoiler_content = component.find('.su-spoiler-content')[0].innerHTML; spoiler_content = shortcodify_su(spoiler_content); var title = component.find('.su-spoiler-title')[0].textContent; var sc = '[su_spoiler title="'+ title + '" style="fancy" open="no"]' + spoiler_content+'[/su_spoiler]'; processed += sc; } } return processed; } function process_gutenberg(content){ // Convert the html into a series of jQuery objects var k = $.parseHTML(content); var processed = ''; if (k == null) { return content; } j = $('

      ').append($(k).clone()); //ul $(j).find("ul").before('' ).after(''); $(j).find("ol").before('' ).after(''); // columns $(j).find(".wp-block-column").each( function(index ) { var data = {}; if ($(this).hasClass('is-vertically-aligned-center')) { data["verticalAlignment"]= "center"; } if ($(this).css("flex-basis")!= "") { data["width"] = $(this).css("flex-basis"); } blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); $(j).find(".wp-block-columns").each( function(index ) { var data = {}; if ($(this).hasClass('are-vertically-aligned-center')) { data["verticalAlignment"]= "center"; } blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); //paragraph $(j).find("p").each( function(index ) { var data = {}; if ($(this).hasClass('has-text-align-center')) { data["align"]= "center"; } blockCode = ""; $(this).before(blockCode).after("" ); }); //gallery $(j).find(".wp-block-gallery").each( function(index ) { debugger; var data = {}; if ($(this).hasClass('aligncenter')) { data["align"]= "center"; } var classes = $(this).attr('class').split(" "); for (i = 0; i < classes.length; ++i) { if (classes[i].indexOf('columns-') == 0) { data["columns"] = parseInt(classes[i].substr(8)); } } var ids = []; $(this).find("img").each( function(index ) { ids[index] = $(this).data('id'); }); data["ids"]= ids; if ($(this).find("a").length ==0) { data["linkTo"] = "none"; } else { data["linkTo"] = "file"; } blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); //heading $(j).find("h1").before('' ); $(j).find("h2").before('' ); $(j).find("h3").before('' ); $(j).find("h4").before('' ); $(j).find("h5").before('' ); $(j).find("h1,h2,h3,h4,h5").after("" ); //table $(j).find(".wp-block-table").before("" ).after("" ); //button $(j).find(".wp-block-button").before("" ); $(j).find(".wp-block-button").after("" ); $(j).find(".wp-block-buttons").each( function(index ) { var blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); //group $(j).find(".wp-block-group").each( function(index ) { var data = {}; if ($(this).hasClass('alignfull')) { data["align"]= "full"; } var blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); // spacer $(j).find(".wp-block-spacer").before("" ).after("" ); // separator $(j).find(".wp-block-separator").before("" ).after("" ); // image $(j).find(".wp-block-image").each( function(index ) { $(this).removeAttr('data-component-type'); var data = {}; if ($(this).find("img").length == 0) { return; } var blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); // cover $(j).find(".wp-block-cover").each( function(index ) { $(this).removeAttr('data-component-type'); var blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); //aesop components $(j).find(".aesop-component").each( function(index ) { var d = $(this).data(); if (d['componentType'] == 'timeline_stop') d['componentType'] = 'timeline'; var blockCode = ""; $(this).before(blockCode); $(this).remove(); }); var html = $(j).html(); html = html.replace(" {} -->"," -->"); return html; } //shortcode avia layout editor function shortcodify_avia(content,selector){ // Convert the html into a series of jQuery objects var j = $.parseHTML(content); var processed = ''; // Iterate through the array of dom objects for (var i = 0; i < j.length; i++) { var component = $(j[i]); // If it's not a component, move along if ( !component.hasClass('av_textblock_section') && !component.hasClass('av_toggle_section') && !component.hasClass('togglecontainer')) { // Let's test what kind of object it is if ( component.context.nodeType == 3 ) { // Text only object without dom processed += j[i].data; } else if ( component.context.nodeType == 8 ) { processed += ''; } else { // DOM object processed += j[i].outerHTML; } continue; } if ( component.hasClass('av_textblock_section')) { var box_text = component.find('.avia_textblock')[0].innerHTML; var sc = '[av_textblock]' + box_text+'[/av_textblock]'; processed += sc; } else if ( component.hasClass('togglecontainer')) { var content = component[0].innerHTML; var mode ="accordion"; content = shortcodify_avia(content); if (component[0].hasClass('enable_toggles')) { mode = "toggle"; } var sc = "[av_toggle_container mode='"+mode+"']" + content+'[/av_toggle_container]'; processed += sc; } else if ( component.hasClass('av_toggle_section')) { var toggle_title = component.find('.toggler')[0].innerText; var toggle_content = component.find('.toggle_content')[0].innerHTML; var sc = '[av_toggle title="'+toggle_title+'"]' + toggle_content+'[/av_toggle]'; processed += sc; } } return processed; } function replace_rendered_shortcodes( content ) { // also remove scripts content = content.replace(/.*<\/script>/g, " "); if ( content.indexOf('--EDITUS_OTHER_SHORTCODE_START|' ) == -1) { return content; } /*var k = $.parseHTML(content); if (k != null) { j = $('
      ').append($(k).clone()); $(j).find('.editus_shortcode').each(function(){ var oldComment = this.previousElementSibling.innerHTML; var re = //g.exec(oldComment) ; var cont = this.dataset.shortcode; if (cont && re && re.size>1) { this.previousElementSibling.innerHTML = oldComment.replace(re[1], cont); }; }); content = $(j).html(); }*/ var re = /([\s\S]*?)/g ; if (lasso_editor.hasGutenberg) { content = content.replace(re,'$1'); } else { content = content.replace(re,'$1'); } return content; } // Save post using REST API V2 function savePublishREST(postid, title, subtitle, content_, type_,status_,forcePublish){ var data = { content: content_, status: status_ }; if (lasso_editor.aviaEditor) { data['content'] =""; data['metadata'] = { '_aviaLayoutBuilderCleanData': content_}; } //custom fields to save if (lasso_editor.cftosave) { if (!data['metadata']) { data['metadata']= lasso_editor.cftosave; } else { Object.assign(data['metadata'], lasso_editor.cftosave); } } var type; if (type_=="post") { type = "posts"; } else if (type_=="page"){ type = "pages"; } else { type = type_; } if (title.length>0) { data['title'] = title; } if (subtitle.length>0) { data['metadata'] = { '_subtitle': subtitle}; } if (lasso_editor.disableSavePost == 'on') { delete data['content']; } $.ajax({ method: "POST", url: lasso_editor.rest_root + 'wp/v2/'+type+'/'+postid, data: data, beforeSend: function ( xhr ) { xhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce ); }, success : function( response ) { saveSuccess(); if (forcePublish) { var data = { action: 'editus_publish_post', postid: lasso_editor.postid } $.post( lasso_editor.ajaxurl2, data); } }, error : function (xhr, exception) { console.log( xhr ); alert("AJAX Error: "+xhr.responseText ); $('#lasso--save').removeClass('being-saved').addClass('lasso--error'); } }); } // code to run when post saving is successful function saveSuccess() { // change button class to saved $('#lasso--save').removeClass('being-saved').addClass('lasso--saved'); // if this is being published then remove the publish button afterwards if ( $this.hasClass('lasso-publish-post') ) { $this.remove(); } // wait a bit then remvoe the button class so they can save again setTimeout(function(){ $('#lasso--save').removeClass('lasso--saved'); if ( $this.hasClass('lasso-publish-post') ) { location.reload() } },1200); // then remove this copy from local stoarge localStorage.removeItem( 'lasso_backup_'+postid ); lasso_editor.dirtyByComponent = false; articleMedium.dirty = false; if (lasso_editor.saveSuccessHookArray) { $(lasso_editor.saveSuccessHookArray).each(function(key, val){ val(); }); } } // make the actual ajax call to save or publish function runSavePublish(forcePublish){ if (lasso_editor.saveusingrest) { // get the status of the post (published/draft) var status_ = $('.lasso--controls__right').data( "status" ); var title=""; if ($(lasso_editor.titleClass).length>0) { title = $(lasso_editor.titleClass)[0].innerText; } var subtitle=""; if ($(lasso_editor.subtitleClass).length>0) { subtitle = $(lasso_editor.subtitleClass)[0].innerText; } if (forcePublish) { status_ = "publish"; if (!lasso_editor.can_publish) { status_ = "pending"; } } savePublishREST(lasso_editor.postid, title, subtitle, data.content, $('.lasso--controls__right').data( "posttype" ), status_, forcePublish); return; } $.post( ajaxurl, data, function(response) { if( true == response.success ) { saveSuccess(); } else { $('#lasso--save').removeClass('being-saved').addClass('lasso--error'); } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); $('#lasso--save').removeClass('being-saved').addClass('lasso--error'); }); } }); jQuery(document).on('click','#lasso--post-delete', function(e){ e.preventDefault(); var $this = $(this); swal({ title: lasso_editor.strings.deletePost, type: "error", text: false, showCancelButton: true, confirmButtonColor: "#d9534f", confirmButtonText: lasso_editor.strings.deleteYes, closeOnConfirm: true }, function(){ var data = { action: 'editus_delete_post', postid: lasso_editor.postid, nonce: lasso_editor.deletePost } $.post( lasso_editor.ajaxurl2, data, function(response) { //load home page after deleting the post window.location.assign(lasso_editor.siteUrl); }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); }); }); function EditusFormatAJAXErrorMessage(jqXHR, exception) { if (jqXHR.status === 0) { return ('AJAX Error: Not connected.\nPlease verify your network connection.'); } else if (jqXHR.status == 404) { return ('AJAX Error: The requested page not found. [404]'); } else if (jqXHR.status == 500) { return ('AJAX Error: Internal Server Error [500].'); } else if (exception === 'parsererror') { return ('AJAX Error: Requested JSON parse failed.'); } else if (exception === 'timeout') { return ('AJAX Error: Time out error.'); } else if (exception === 'abort') { return ('AJAX Error: Ajax request aborted.'); } else { return ('AJAX Error: Uncaught Error.\n' + jqXHR.responseText); } } (function( $ ) { 'use strict'; ///////////// // NEW GALLERY CREATE //////////// //$('#lasso--gallery__create').live('click',function(e){ jQuery(document).on('click','#lasso--gallery__create',function(e){ e.preventDefault(); $(this).closest('form').addClass('creating-gallery'); $('.ase-gallery-opts--create-gallery2').fadeIn(); $('.ase-gallery-opts--edit-gallery').fadeOut(1); $('#ase-gallery-images li').remove(); $('#lasso--gallery__create').remove(); $('.ase-gallery-opts--edit-gallery').text(lasso_editor.strings.addNewGallery); $('.ase-gallery-opts--edit-gallery .lasso-option-desc').text('Select new images to create a gallery with.'); }); ///////////// // NEW GALLERY UPLOAD //////////// var file_frame; var gallery = $('#ase-gallery-images'); //$(document).on('click', '#lasso--gallery__selectImages', function( e ){ jQuery(document).on('click','#lasso--gallery__selectImages',function( e ){ e.preventDefault(); // If the media frame already exists, reopen it. if ( file_frame ) { file_frame.open(); return; } // Create the media frame. file_frame = wp.media.frames.file_frame = wp.media({ title: lasso_editor.strings.chooseImages, button: { text: lasso_editor.strings.addImages, }, multiple: true // Set to true to allow multiple files to be selected }); // When an image is selected, run a callback. file_frame.on( 'select', function() { var attachments = file_frame.state().get('selection'); if (!attachments) { return; } // loop through and insert the new items attachments.each( function( attachment ) { var id = attachment.id; var url = attachment.attributes.sizes.thumbnail.url; ase_insert_gallery_item(id, url); }); // insert the new ids from new gallery var ids = attachments.map( function( attachment ) { var attachment = attachment.toJSON(); return attachment.id; }).join(','); // populate gallery input with ids $('#ase_gallery_ids').val( ids ); // show the save button $('.has-galleries > #lasso--gallery__save').fadeIn(); // remove the select images button $('#lasso--gallery__selectImages').remove(); }); // Finally, open the modal file_frame.open(); }); ////////// // NEW GALLERY SWAP ////////// //$('.lasso-gallery-id #aesop-generator-attr-id').live('change',function(){ jQuery(document).on('change','.aesop-gallery-id #aesop-generator-attr-id',function(){ editus_gallery_swap($(this).val()); var data2 = { action: 'process_gallery_get-images', post_id: $(this).val(), nonce: lasso_editor.getGallImgNonce }; // post ajax response with data $.post( lasso_editor.ajaxurl, data2, function(response) { $('#lasso--gallery__images').html( response.data.html ); ///////////// // CALL SORTABLE ON RECIEVED IMAGES ///////////// var gallery = $('#ase-gallery-images'); gallery.ready(function(){ gallery.sortable({ containment: 'parent', cursor: 'move', opacity: 0.8, placeholder: 'ase-gallery-drop-zone', forcePlaceholderSize:true, update: function(){ var imageArray = $(this).sortable('toArray'); $('#ase_gallery_ids').val( imageArray ); }, create: function(){ var imageArray = $(this).sortable('toArray'); $('#ase_gallery_ids').val( imageArray ); } }); window.component.find('.lasso-component--settings__trigger').trigger('click'); }); }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); function editus_gallery_swap(galleryID){ var data = { componentType: 'gallery', id: galleryID }; window.get_aesop_component_ajax(data); } /////////// // EDIT GALLERY // the sortsble instat is in settingspanel.js /////////// // deleting gallery items $(document).on('click', '.ase-gallery-image > i.dashicons-no-alt', function(){ $(this).parent().remove(); gallery.sortable('refresh'); ase_encode_gallery_items(); }); function ase_string_encode(gData){ return encodeURIComponent(JSON.stringify(gData)); } function ase_string_decode(gData){ return JSON.parse(decodeURIComponent(gData)); } function ase_encode_gallery_items(){ gallery = $('#lasso--gallery__images #ase-gallery-images'); if (gallery.length) { var imageArray = gallery.sortable('toArray'); $('#ase_gallery_ids').val( imageArray ); } } // inserting gallery items function ase_insert_gallery_item(id, url){ var item_html = ""; $('#ase-gallery-images').append( item_html ); gallery.sortable('refresh'); ase_encode_gallery_items(); } // adding additiona images to existing gallery var clicked_button = false; $(document).on('click', '#ase-gallery-add-image', function (event) { event.preventDefault(); var selected_img; clicked_button = $(this); if(wp.media.frames.ase_frame) { wp.media.frames.ase_frame.open(); return; } wp.media.frames.ase_frame = wp.media({ title: lasso_editor.strings.selectGallery, multiple: true, library: { type: 'image' }, button: { text: lasso_editor.strings.useSelectedImages } }); var ase_media_set_image = function() { var selection = wp.media.frames.ase_frame.state().get('selection'); if (!selection) { return; } selection.each(function(attachment) { var id = attachment.id; var url = attachment.attributes.sizes.thumbnail.url; ase_insert_gallery_item(id, url); }); }; wp.media.frames.ase_frame.on('select', ase_media_set_image); wp.media.frames.ase_frame.open(); }); // editing a single image function ase_edit_gallery_item(id, url, editable){ var item_html = ""; $(editable).replaceWith( item_html ); gallery.sortable('refresh'); ase_encode_gallery_items(); } // edit single image var ase_media_edit_init = function() { var clicked_button; $(document).on('click', '.ase-gallery-image > i.dashicons-edit', function(event){ event.preventDefault(); var selected_img; clicked_button = $(this); if(wp.media.frames.ase_edit_frame) { wp.media.frames.ase_edit_frame.open(); return; } wp.revisions wp.media.frames.ase_edit_frame = wp.media({ title: lasso_editor.strings.editImage, multiple: false, library: { type: 'image' }, button: { text: lasso_editor.strings.updateSelectedImg } }); var ase_media_edit_image = function() { var selection = wp.media.frames.ase_edit_frame.state().get('selection'); if (!selection) { return; } // iterate through selected elements selection.each(function(attachment) { var id = attachment.id; var url = attachment.attributes.sizes.thumbnail.url; ase_edit_gallery_item(id, url, clicked_button.parent()); }); }; // image selection event wp.media.frames.ase_edit_frame.on('select', ase_media_edit_image); wp.media.frames.ase_edit_frame.on('open',function(){ var selection = wp.media.frames.ase_edit_frame.state().get('selection'); var attachment = wp.media.attachment( clicked_button.parent().attr('id') ); attachment.fetch(); selection.add( attachment ? [ attachment ] : [] ); }); wp.media.frames.ase_edit_frame.open(); }); }; //ase_media_init('#ase-gallery-add-image', 'i'); ase_media_edit_init(); ase_encode_gallery_items(); })( jQuery ); (function( $ ) { $(document).ready(function($){ // this function is repeated on settings-panel.js var value_check = function( value ){ if ( 'grid' == value ) { $('.ase-gallery-opts--thumb').fadeOut(); $('.ase-gallery-opts--photoset').fadeOut(); $('.ase-gallery-opts--hero').fadeOut(); $('.ase-gallery-opts--grid').fadeIn(); } else { $('.ase-gallery-opts--grid').fadeOut(); } if ( 'thumbnail' == value ) { $('.ase-gallery-opts--grid').fadeOut(); $('.ase-gallery-opts--photoset').fadeOut(); $('.ase-gallery-opts--hero').fadeOut(); $('.ase-gallery-opts--thumb').fadeIn(); } else { $('.ase-gallery-opts--thumb').fadeOut(); } if ( 'photoset' == value ) { $('.ase-gallery-opts--grid').fadeOut(); $('.ase-gallery-opts--thumb').fadeOut(); $('.ase-gallery-opts--hero').fadeOut(); $('.ase-gallery-opts--photoset').fadeIn(); } else { $('.ase-gallery-opts--photoset').fadeOut(); } if ( 'hero' == value ) { $('.ase-gallery-opts--grid').fadeOut(); $('.ase-gallery-opts--thumb').fadeOut(); $('.ase-gallery-opts--photoset').fadeOut(); $('.ase-gallery-opts--hero').fadeIn(); } else { $('.ase-gallery-opts--hero').fadeOut(); } } $('.ase-gallery-type-radio').each(function(){ if ( $(this).is(':checked') ) { $(this).parent().addClass('selected'); var value = $(this).val(); value_check(value); } }); //$('.ase-gallery-layout-label').live('click',function(){ jQuery(document).on('click','.ase-gallery-layout-label', function(){ $('.ase-gallery-layout-label').removeClass('selected'); $(this).addClass('selected'); var value = $(this).find('input').val(); value_check(value); // add the type to a hidden field $('#ase_gallery_type').val( value ) }); }) })( jQuery ); (function( $ ) { var form; //$('#lasso--map-form').live('submit', function(e) { jQuery(document).on('submit','#lasso--map-form',function(e) { e.preventDefault(); var $this = $(this); $(this).find('input[type="submit"]').val('Saving...').addClass('being-saved'); var data = $this.serialize(); ///////////// // DO TEH SAVE ///////////// $.post( lasso_editor.ajaxurl, data, function(response) { if ( true == response.success ) { $this.find('input[type="submit"]').val('Saved'); $this.removeClass('being-saved').addClass('lasso--saved'); setTimeout(function(){ $this.find('input[type="submit"]').val('Save Locations').removeClass('lasso-saved'); },1200); } else { $this.removeClass('being-saved').addClass('lasso--error'); } }); }); })( jQuery ); (function( $ ) { 'use strict'; //$( '#lasso--featImgSave a' ).live('click', function(e) { jQuery(document).on('click', '#lasso--featImgSave a', function(e){ e.preventDefault(); var $this = $(this) , saveStatus = $('#lasso--save-status') var data = { action: 'editus_featured_img', postid: lasso_editor.postid, image_id: $this.data('featimg-id'), nonce: lasso_editor.featImgNonce } saveStatus.removeClass('not-visible').addClass('visible lasso--animate__spin'); $.post( lasso_editor.ajaxurl2, data, function(response) { if ( response ) { console.log('response') $('#lasso--featImgSave').css('opacity',0); //setTimeout(function(){ // saveStatus.removeClass('lasso--animate__spin lasso-icon-check').addClass('lasso-icon-spinner6 not-visible') //},500); } saveStatus.removeClass('lasso--animate__spin lasso-icon-spinner6').addClass('lasso-icon-check'); }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); saveStatus.removeClass('lasso--animate__spin lasso-icon-spinner6').addClass('lasso-icon-check'); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); ///////////// // FILE UPLOAD //////////// var file_frame; var className; $(document).on('click', '#lasso--featImgUpload > a', function( e ){ e.preventDefault(); className = e.currentTarget.parentElement.className; var save = $('#lasso--featImgSave a') // If the media frame already exists, reopen it. if ( file_frame ) { file_frame.open(); return; } // Create the media frame. file_frame = wp.media.frames.file_frame = wp.media({ title: lasso_editor.strings.chooseImage, button: { text: lasso_editor.strings.updateImage, }, multiple: false // Set to true to allow multiple files to be selected }); // When an image is selected, run a callback. file_frame.on( 'select', function() { var attachment = file_frame.state().get('selection').first().toJSON(); $('body').addClass('lasso--post-thumb-applied'); $('article').removeClass('no-post-thumbnail').addClass('has-post-thumbnail'); if ( $(lasso_editor.featImgClass).is( "img" ) ) { $(lasso_editor.featImgClass).prop("src",attachment.url); $(lasso_editor.featImgClass).prop("srcset",""); } else { $(lasso_editor.featImgClass).css({ 'background-image': 'url('+attachment.url+')' }); } save.attr('data-featimg-id',attachment.id).trigger('click'); $('.no-post-cover-note').remove(); }); // Finally, open the modal file_frame.open(); }); //////////// // FEAT IMAGE DELETE //////////// $(document).on('click', '#lasso--featImgDelete > a', function( e ){ e.preventDefault(); var $this = $(this); var data = { action: 'editus_del_featured_img', postid: lasso_editor.postid, nonce: lasso_editor.featImgNonce } swal({ title: lasso_editor.strings.removeFeatImg, type: "warning", text: false, showCancelButton: true, confirmButtonColor: "#d9534f", confirmButtonText: lasso_editor.strings.deleteYes, closeOnConfirm: true }, function(){ $.post( lasso_editor.ajaxurl2, data, function(response) { if ( "" == response ) { // add a body class so we can do whatever with $('body').addClass('lasso--post-thumb-removed'); $('article').removeClass('has-post-thumbnail').addClass('no-post-thumbnail'); // add the hidden class to control shell to allow for delete button $('#lasso--featImgDelete').addClass('lasso--featImg--controlHidden'); $this.closest('ul').removeClass('lasso--featImg--has-thumb'); // remove the attr src - just a real-time update if ( $(lasso_editor.featImgClass).is( "img" ) ) { $(lasso_editor.featImgClass).attr("src",""); } else { $(lasso_editor.featImgClass).css({ 'background-image': 'url()' }); } } }); }); }); //////////// // FEAT IMAGE FROM SETTINGS - @since 0.9.4 //////////// var featimg_frame; $(document).on('click', '#lasso--post-thumb__add', function( e ){ e.preventDefault(); var $this = $(this) , save = $('#lasso--featImgSave a') // If the media frame already exists, reopen it. if ( featimg_frame ) { featimg_frame.open(); return; } // Create the media frame. featimg_frame = wp.media.frames.featimg_frame = wp.media({ title: lasso_editor.strings.chooseImage, button: { text: lasso_editor.strings.updateImage, }, multiple: false // Set to true to allow multiple files to be selected }); // When an image is selected, run a callback. featimg_frame.on( 'select', function() { var attachment = featimg_frame.state().get('selection').first().toJSON(); var pic = $this.closest('.lasso--post-thumb').find('img'); pic.attr('src', attachment.url ); save.attr('data-featimg-id',attachment.id).trigger('click'); $('#lasso--postsettings__form').removeClass('no-thumbnail').addClass('has-thumbnail'); pic.removeAttr("srcset"); noWarningReload = true; }); // Finally, open the modal featimg_frame.open(); }).on('click', '#lasso--post-thumb__delete', function( e ){ e.preventDefault(); var $this = $(this); var data = { action: 'editus_del_featured_img', postid: lasso_editor.postid, nonce: lasso_editor.featImgNonce } swal({ title: lasso_editor.strings.removeFeatImg, type: "warning", text: false, showCancelButton: true, confirmButtonColor: "#d9534f", confirmButtonText: lasso_editor.strings.deleteYes, closeOnConfirm: true }, function(){ $.post( lasso_editor.ajaxurl2, data, function(response) { if ( "" == response ) { var defaultImg = $this.closest('.lasso--post-thumb').data('default-thumb'); $this.closest('.lasso--postsettings__left').find('img').attr('src', defaultImg ); $this.closest('.lasso--postsettings__left').find('img').removeAttr("srcset"); $('#lasso--postsettings__form').removeClass('has-thumbnail').addClass('no-thumbnail') noWarningReload = true; } }); }); }); })( jQuery ); (function( $ ) { var form; // get updated aesop componets through ajax calls (global function) window.get_aesop_component_ajax = function(cdata) { var data = { action: 'get_aesop_component', code: 'aesop_'+cdata['componentType'] }; for ( var index in cdata ) { // Don't accept componentType as a param if ( !cdata.hasOwnProperty(index) || index == 'componentType' || index =='sortableItem') { continue; } data[index] = cdata[index]; } jQuery.post(lasso_editor.ajaxurl2, data, function(response) { if( response ){ response = response.replace(/\\'/g, "'"); var $a = $(response); window.component.replaceWith($a); window.component = $a; if ($('.fotorama').length){ $('.fotorama').fotorama(); } if ($('.aesop-gallery-photoset').length){ $(window).trigger( 'load' ); } lasso_editor.wrapImg(); $('.aesop-component').each(function(){ if ($(this).css("height")=="0px") { $(this).css("height","auto"); } // if there's no toolbar present if ( !$(this).find('.lasso-component--toolbar').length > 0 ) { // if this is a map then we need to first wrap it so that we can drag the map around if ( $(this).hasClass('aesop-map-component') ) { var $this = $(this) // so wrap it with a aesop-compoentn aesop-map-component div // @todo - note once a map is inserted it can't be edited after saving again. a user has to delete the existin map and add a new map // to //$this.wrap('
      ').before( lassoDragHandle ).after( lassoMapForm ); $this.wrap('
      ').before( lassoDragHandle ); } else { $(this).append( lasso_editor.handle ); } } }); if ('video' == cdata['componentType']) { $('.aesop-video-component').fitVids(); } if ('gallery' == cdata['componentType']) { get_aesop_options('gallery'); } if ('gallery_pop' == cdata['componentType']) { get_aesop_options('gallery_pop'); } if ('timeline_stop' == cdata['componentType']) { lasso_editor.timelineGoTime(); } // set some figures to uneditable $("figure.wp-block-image, figure.lasso--wpimg__wrap").attr('contenteditable',false).attr('readonly',true); lasso_editor.dirtyByComponent = true; } else { alert("error"); } }); } //reload aesop component options function get_aesop_options(comp) { var data = { action: 'editus_get_ase_options', component: comp }; jQuery.post(lasso_editor.ajaxurl2, data, function(response) { if( response ){ lasso_editor.component_options[comp] = response; } else { alert("error"); } }); } //$('#lasso--component-settings-form').live('submit', function(e) { //jQuery(document).on('submit', '#lasso--component-settings-form', function(e){ jQuery(document).on('submit', '#aesop-generator-settings', function(e){ e.preventDefault(); e.stopImmediatePropagation(); // store some atts var $component = window.component , cdata = $component.data() , saveInsert = $('#lasso-generator-insert') , form = $('#lasso--component-settings-form') , $this = $(this); // let people know something is happening saveInsert.val(lasso_editor.strings.saving); // send the new settings to the component and update it's data attributes $this.find('.lasso-generator-attr').each(function(){ var optionName = $(this).closest('.lasso-option').data('option'); // save even if the entry is blank //if ( '' !== $(this).val() ) { //$component.attr( 'data-' + optionName, $(this).val() ); $component.prop( 'data-' + optionName, $(this).val() ); $component.data(optionName, $(this).val() ); //} }); // return the data attributes as field for the sortable item var cleanFields = function( cdata ){ delete cdata['sortableItem']; return cdata; } /** * * Build a sequence that saves, adds a class, and removs the sidebar * @param stall bool should we stall on save? typically used for all but the gallery component which runs an ajax call * @param timeout int how long should we timeout before removing the settings sidebar * @param gallery bool is this a gallery creation? otherwise let's mod the label */ var saveSequence = function( stall, timeout, gallery ){ // add a saved class then change the save label to saved var saveActions = function(gallery){ saveInsert.addClass('saved'); if ( true == gallery ) { saveInsert.val(lasso_editor.strings.galleryCreated); } else { saveInsert.val(lasso_editor.strings.saved); } } if ( true == stall ) { setTimeout( function(){ saveActions(); }, 500 ); } else if ( true == gallery ) { //form.addClass('hide-all-fields').prepend('
      Gallery Created! Save your post and refresh the page to access this new gallery.
      ') setTimeout( function(){ saveActions(true); }, 500 ); } else { saveActions(); } setTimeout( function(){ $('body').removeClass('lasso-sidebar-open'); }, timeout ); articleMedium.makeUndoable(); lasso_editor.dirtyByComponent = true; } // make an ajax call to deal with gallery saving or creating only if it's a gallery if ( 'gallery' == cdata['componentType'] ) { var data = { action: $('.ase-gallery-opts--create-gallery2').is(":visible") ? 'editus_create_gallery' : 'editus_update_gallery', postid: cdata['id'], unique: cdata['unique'], fields: cleanFields(cdata), gallery_type: $('#ase_gallery_type').val(), gallery_ids: $('#ase_gallery_ids').val(), nonce: $('#lasso-generator-nonce').val() } if ($('.ase-gallery-opts--create-gallery2').is(":visible")) { data['edgallerytitle'] = document.getElementById("lasso--gallery__galleryname").value; } $.post( lasso_editor.ajaxurl2, data, function(response) { retData = JSON.parse(response); if ( 'gallery-created' == retData["message"] ) { saveSequence( false, 1000, true ); // load the new gallery cdata['id'] = retData["id"]; } else if ( 'gallery-updated' == retData["message"] ) { saveSequence( false, 1000 ); form.before(lasso_editor.refreshRequired); } else { alert( 'error' ); } window.get_aesop_component_ajax(cdata); }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); } else { saveSequence( true, 1200 ); } if ( 'image' == cdata['componentType'] || 'quote' == cdata['componentType'] || 'parallax' == cdata['componentType'] || 'chapter' == cdata['componentType'] || 'video' == cdata['componentType'] || 'character' == cdata['componentType'] || 'collection' == cdata['componentType'] || 'audio' == cdata['componentType']) { window.get_aesop_component_ajax(cdata); } else if ('content' == cdata['componentType']) { var inner = component.find('.aesop-component-content-data'); if ( inner.length != 0 ) { cdata['content_data'] = inner[0].innerHTML; } window.get_aesop_component_ajax(cdata); } /*else if ('events' == cdata['componentType']) { //aesop events alert("Save and Reload the page to see the update."); }*/ else { window.get_aesop_component_ajax(cdata); } }); })( jQuery ); (function( $ ) { $(document).ready(function(){ // method to destroy the modal var destroyModal = function(){ $('body').removeClass('lasso-modal-open' ); $('.lasso--modal, #lasso--modal__overlay').remove(); if (noWarningReload) { location.reload(); } } // modal click //$('#lasso--post-new').live('click',function(e){ jQuery(document).on('click','#lasso--post-new',function(e){ e.preventDefault(); // add a body class $('body').toggleClass('lasso-modal-open'); // append teh modal markup ( lasso_editor_component_modal() ) $('body').append(lasso_editor.newPostModal); // if any changes happen then show the footer $('.lasso--modal__trigger-footer').on('keyup',function(){ $('.lasso--postsettings__footer #lasso--postsettings-create').slideDown() }); modalResizer() }); // destroy modal if clicking close or overlay //$('#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel').live('click',function(e){ jQuery(document).on('click','#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel',function(e){ e.preventDefault(); destroyModal(); }); jQuery(document).on('click', '#lasso--postsettings-setnow', function(e){ $('.editus_custom_date').datepicker( "setDate", new Date().setTime(Date.now()) ); }); ///////////////// /// EXIT SETTINGS /////////////////// $(document).keyup(function(e) { if ( 27 == e.keyCode ) { destroyModal(); } }); ///////////// // MAKE NEW POST OBJECT ////////////// var form; //$('#lasso--postnew__form').live('submit', function(e) { jQuery(document).on('submit', '#lasso--postnew__form', function(e){ e.preventDefault(); var $this = $(this); $(this).find('input[type="submit"]').val(lasso_editor.strings.adding); if (lasso_editor.saveusingrest) { // Use REST API var data2 = $this.serializeArray().reduce(function(obj, item) { obj[item.name] = item.value; return obj; }, {}); newPostREST(data2.story_title, data2.object,lasso_editor.newObjectContent); } else { var data = $this.serialize(); ///////////// // DO TEH SAVE ///////////// $.post( lasso_editor.ajaxurl, data, function(response) { if ( true == response.success ) { $('input[type="submit"]').addClass('saved'); $('input[type="submit"]').val(lasso_editor.strings.added); window.location.replace(response.link+'&preview=true'); } else { alert('error'); } }); } }); }); function newPostREST(title_, type_,content_){ var data = { title: title_, content: content_, status: "draft" }; if (lasso_editor.currCat !== null) { data.categories = $.map( lasso_editor.currCat, function( a ) { return a.term_id; }); } var type; if (type_=="post") { type = "posts"; } else if (type_=="page"){ type = "pages"; } else { type = type_; } $.ajax({ method: "POST", url: lasso_editor.rest_root + 'wp/v2/'+type, data: data, beforeSend: function ( xhr ) { xhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce ); }, success : function( response ) { $('input[type="submit"]').addClass('saved'); $('input[type="submit"]').val(lasso_editor.strings.added); window.location.replace(response.link+'&preview=true'); }, error : function (xhr, exception) { alert("AJAX Error: "+xhr.responseText ); } }); } ///////////// // POST OBJECT CHANGE - since 0.9.5 ///////////// //$('#lasso--select-type').live('change',function() { jQuery(document).on('change', '#lasso--select-type', function(){ var val = $(this).val() $('input[name="object"]').val( val ) $(this).closest('.story-slug-option').find('label span:not(.lasso-util--help)').text( val ) }); })( jQuery ); (function( $ ) { $(document).ready(function(){ ///////////// // SAVE TITLE ///////////// $(lasso_editor.titleClass).on('blur', function() { var target = $(this); var data = { action: 'process_title-update_post', postid: lasso_editor.postid, title: $.trim( target.text() ), nonce: lasso_editor.titleNonce } ///////////// // UPDATE THE TITLE ///////////// $.post( lasso_editor.ajaxurl, data, function(response) { if ( true == response.success ) { var saveClass = 'lasso-title-saved'; target.addClass(saveClass); setTimeout(function(){ target.removeClass(saveClass); },500); } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); }); })( jQuery ); (function( $ ) { $(document).ready(function(){ // get the attachment id from teh class wp-image-XXX, where XXX is the id of the attached iamge // this oly works if the image was inserted from within the wordpress post editor var ase_edit_frame; var className; $(document).on('click', '.lasso--wpimg-edit',function(e){ e.preventDefault(); if ($(this).parent().parent().find('img').length==0) { return; } var id =''; var selected_img , clicked = $(this) , cls = $(this).parent().next('img').attr('class'); if (cls) { id = cls.match(/\d+/); } className = e.currentTarget.parentElement.className; // create frame ase_edit_frame = wp.media.frames.ase_edit_frame = wp.media({ title: lasso_editor.strings.selectImage, button: { text: lasso_editor.strings.insertImage, }, multiple: false // Set to true to allow multiple files to be selected }); // open frame ase_edit_frame.on('open',function(){ var selection = ase_edit_frame.state().get('selection'); if (id) { var attachment = wp.media.attachment( id ); attachment.fetch(); selection.add( attachment ? [ attachment ] : [] ); } }); // update image on select ase_edit_frame.on( 'select', function() { // here after simple wpimg image select var attachment = ase_edit_frame.state().get('selection').first().toJSON() , imageURL = undefined === attachment.sizes.large ? attachment.sizes.full.url : attachment.sizes.large.url $(clicked).parent().parent().find('img').prop({ 'src': imageURL, 'srcset' :"", 'alt': attachment.alt, 'class': 'aligncenter size-large wp-image-'+attachment.id+'' }); //$("html").scrollTop(lasso_editor.scrollTop); $('#lasso-side-comp-button,.lasso--text-popup').remove(); // set some figures to uneditable $("figure.wp-block-image, figure.lasso--wpimg__wrap").attr('contenteditable',false).attr('readonly',true); }); lasso_editor.scrollTop = $(window).scrollTop(); // Finally, open the modal ase_edit_frame.open(); }) }); })( jQuery ); (function( $ ) { $(document).on('submit', '#lasso--custom-field-form', function(e) { e.preventDefault(); $('#lasso--save').trigger('click'); var $this = $(this) , submit = $this.find('input[type="submit"]') , strings = lasso_editor.strings , data = $this.serialize(); submit.val( strings.saving ); $.post( lasso_editor.ajaxurl, data, function(response) { if( true == response.success ) { submit.val( strings.saved ).addClass('saved'); /*console.log(response) setTimeout(function(){ submit.removeClass('saved'); submit.val( strings.save ); },1000);*/ location.reload(); } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); })( jQuery ); (function( $ ) { // dyanmically center modals vertically based on size of modal jQuery(document).ready(function($){ modalResizer = function(){ var modal = $('.lasso--modal') , mHeight = modal.height() , wHeight = $(window).height() , eHeight = $('.lasso--modal').hasClass('lasso--tour__modal') ? 0 : 30 // this is the height of the submit button that is hidden utnil the user changes a setting modal.css({ 'top' : (wHeight - mHeight - eHeight) / 2 }) } $('.lasso--modal').imagesLoaded( function() { modalResizer(); }) jQuery(window).resize(function(){ modalResizer(); }); }); })( jQuery ); (function( $, Backbone, _, WP_API_Settings, undefined ) { var contentTemplate = $('#lasso-tmpl--post' ) , postTemplate = _.template( contentTemplate.html() ) //, posts = new wp.api.collections.Posts() //, pages = new wp.api.collections.Pages() , postAll = $('#lasso--post-all') , postList = '#lasso--post-list' , loadingText = lasso_editor.strings.loading , loadMoreText = lasso_editor.strings.loadMore , noPostsText = lasso_editor.strings.noPostsFound , fetchFailText = lasso_editor.strings.fetchFail , body = $('body') , noPostsMessage = '
    • '+noPostsText+'
    • ' , fetchFailMessage = '
    • '+fetchFailText+'
    • ' , noResultsDiv = lasso_editor.noResultsDiv , loader = '
      ' , moreButton = ''+loadMoreText+'' , closeButton = ''+lasso_editor.strings.close+'' , clear = '' , clearItem = '#lasso--clear-search' , hideClass = 'lasso--hide' , showClass = 'lasso--show' , helper = '#lasso--helper' , page = 1 , lastType = 'posts' , collection = false , initial = true , totalPages = null , api = WP_API_Settings.root , timer // infinite load options var options = { data: { page: page, filter: { post_status: ['publish','draft','pending'] } } } ////////////////// // DESTROY LOADER ///////////////// function destroyLoader(){ $('#lasso--loading').remove() } ///////////////// // INITIALIZE SCROLL ///////////////// function initScroll() { $(postList).perfectScrollbar({ suppressScrollX: true }); } // set links clickable //$("a").attr('contenteditable',false); function fetchError(xhr){ $( '#lasso--loading' ).remove(); try { var data = JSON.parse(xhr.responseText); if (data['code'] == 'rest_post_invalid_page_number' ) { $( '#lasso--load-more' ).remove(); $( postList ).append( noPostsMessage ); } else { // show some info $( postList ).append( fetchFailMessage + '
      '+JSON.stringify(xhr).replace(/&/g,'&').replace(//g,'>')+'
      ' ); } } catch (e){ $( postList ).append( fetchFailMessage); } } ////////////////// // FETCH POSTS HELPER FUNCTION ///////////////// function fetchPosts( type ){ var capable = lasso_editor.edit_others_posts; lastType = type; if ( 'pages' == type ) { capable = lasso_editor.edit_others_pages; } /*else if ( 'posts' == type ) { //collection = new wp.api.collections.Posts( options ); } else { // this is a working, alternate way to get collection of custom post type /*var customPost = wp.api.models.Post.extend({ urlRoot: WP_API_Settings.root + 'wp/v2/'+type, defaults: { type: type } }); var customCollection = wp.api.collections.Posts.extend({ url: WP_API_Settings.root + 'wp/v2/'+type, model: customPost }); collection = new customCollection;* }*/ if (type=='posts') { options = capable ? setOptionsPost( type, page ) : setOptionsPost( type, page, lasso_editor.author ); collection = new wp.api.collections.Posts( ); collection.fetch( options ).done( function() { //remove more button $( '#lasso--load-more,#lasso--close-modal-posts' ).remove(); // if we have more posts then load them if ( collection.length > 0 ) { var setContainer = $( '
      ' ); if (lasso_editor.restapi2) { collection.each( function ( model ) { //post.link title status id setContainer.append( postTemplate( { post: model.attributes, link_: model.attributes._links.self[0].href, settings: WP_API_Settings } ) ); } ); } else { collection.each( function ( model ) { setContainer.append( postTemplate( { post: model.attributes, settings: WP_API_Settings } ) ); } ); } // append to the post container $(postList).append( setContainer ); //put back more button $(postList).append( moreButton ); $(postList).append( closeButton ); // show search filtering $('.lasso--post-filtering').removeClass('not-visible').addClass('visible') $( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading'); // re-init scroll initScroll() }else{ $( postList ).append( noPostsMessage ); setTimeout(function(){ $('#lasso--end-posts').fadeOut('slow') }, 1000) } // destroy the spinny loader destroyLoader(); }).fail(function(xhr, err) { fetchError(xhr); }); } else { /*var author = capable ? lasso_editor.author : -1; var parms = getParams( true, page, author ); jQuery.ajax({ method: "GET", url: WP_API_Settings.root+'wp/v2/'+type+parms,//'?status[]=draft&author[]='+lasso_editor.author, //dataType: "json", beforeSend: function(xhr){ xhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce ); }, success : function( data ) { dispPosts(data, type); parms = getParams( false, page, author ); jQuery.ajax({ method: "GET", url: WP_API_Settings.root+'wp/v2/'+type+parms, //dataType: "json", beforeSend: function(xhr){ xhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce ); }, success : function( data ) { dispPosts(data, type); }, done: function(data) { }, error: function(xhr, err) { $( '#lasso--loading' ).remove(); //alert(xhr.responseText); //fetchError(xhr); } }); }, done: function(data) { }, error: function(xhr, err) { $( '#lasso--loading' ).remove(); //alert(xhr.responseText); //fetchError(xhr); parms = getParams( false, page, lasso_editor.author ); jQuery.ajax({ method: "GET", url: WP_API_Settings.root+'wp/v2/'+type+parms, //dataType: "json", beforeSend: function(xhr){ xhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce ); }, success : function( data ) { dispPosts(data, type); }, done: function(data) { }, error: function(xhr, err) { $( '#lasso--loading' ).remove(); //alert(xhr.responseText); //fetchError(xhr); } }); } });*/ options = capable ? setOptions( type, page ) : setOptions( type, page, lasso_editor.author ); jQuery.getJSON(WP_API_Settings.root+'wp/v2/'+type,options, function(data) { $( '#lasso--load-more' ).remove(); if ( data.length > 0 ) { var setContainer = $( '
      ' ); jQuery.each( data, function( i, val ) { setContainer.append( postTemplate( { post: val, link_: val.link, settings: WP_API_Settings } ) ); }); // append to the post container $(postList).append( setContainer ); //put back more button if (data.length>=7 ) { $(postList).append( moreButton ); $( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading'); } // show search filtering $('.lasso--post-filtering').removeClass('not-visible').addClass('visible'); // re-init scroll initScroll() } else { $( postList ).append( noPostsMessage ); setTimeout(function(){ $('#lasso--end-posts').fadeOut('slow') }, 1000) } destroyLoader(); }) .fail(function(xhr, err) { fetchError(xhr); }); } } function dispPosts(data, type) { $( '#lasso--load-more' ).remove(); if ( data.length > 0 ) { var setContainer = $( '
      ' ); jQuery.each( data, function( i, val ) { setContainer.append( postTemplate( { post: val, link_: val.link, settings: WP_API_Settings } ) ); }); // append to the post container $(postList).append( setContainer ); //put back more button if (data.length>=7 ) { $(postList).append( moreButton ); $( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading'); } // show search filtering $('.lasso--post-filtering').removeClass('not-visible').addClass('visible'); // re-init scroll initScroll() } else { //$( postList ).append( noPostsMessage ); setTimeout(function(){ $('#lafesso--end-posts').fadeOut('slow') }, 1000) } destroyLoader(); } function getParams( draft, page, author ) { var params = '?page='+page; if (author != -1) { params += '&author[]='+author; } if (draft) { params += '&status[]=draft'; } return params; } /** * Helper function to reset options * * @param type post type * @param page page * * @returns {{data: {page: *, filter: {post_type: *, post_status: string[]}}}} */ function setOptions( type, page, author ) { if (!author) { return { page: page, type: type, //status: 'draft', per_page: 7, //filter: { //post_status: ['publish','draft','pending'], // posts_per_page: 7, //author: author //} }; } return { page: page, type: type, author: author, //status: ['publish','draft','pending'], per_page: 7, /*filter: { post_status: ['publish','draft','pending'], posts_per_page: 7, author: author }*/ } } function setOptionsPost( type, page, author ) { return options = { data: { page: page, type: type, author: author, status:['publish','draft','pending'], per_page: 7, filter: { post_status: ['publish','draft','pending'], posts_per_page: 7, author: author } } } } ////////////////// // OPEN INITIAL POSTS ///////////////// $( postAll ).on('click',function(e){ e.preventDefault(); // add a body class body.toggleClass('lasso-modal-open'); // append teh modal markup ( lasso_editor_component_modal() ) body.append( lasso_editor.allPostModal ); // get the intial posts fetchPosts('posts'); modalResizer(); }); /** * Load more click event */ $( body ).on('click', '#lasso--load-more', function(e){ e.preventDefault(); type = $( this ).attr( 'data-post-type' ); $(this).addClass('lasso--btn-loading').text( loadingText ); if (lastType == type) { page++; } else { page = 1; } lastType = type; fetchPosts( type ); }).on('click','#lasso--close-modal-posts',function(e){ e.preventDefault(); destroyModal(); }).on('click', '.lasso--show-objects', function(e){ e.preventDefault(); $('.lasso--show-objects').removeClass('active'); $(this).addClass('active'); $('#lasso--post-list').empty(); type = $(this).data('post-type'); page = 1; totalPages = null; $( '#lasso--load-more' ).attr( 'data-post-type', type); $(postList).prepend( loader ); fetchPosts( type ); }).on('click', '#lasso--post__delete', function(e){ e.preventDefault(); var $this = $(this); swal({ title: lasso_editor.strings.deletePost, type: "error", text: false, showCancelButton: true, confirmButtonColor: "#d9534f", confirmButtonText: lasso_editor.strings.deleteYes, closeOnConfirm: true }, function(){ var data = { action: 'editus_delete_post', postid: $this.closest('a').data('postid'), nonce: lasso_editor.deletePost } $.post( lasso_editor.ajaxurl2, data, function(response) { if ( "" == response ) { $this.closest('li').fadeOut().remove() } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); }).on('keyup','#lasso--search-field',function( e ){ // live search - @since 0.9.5 // clear the previous timer clearTimeout(timer) var key = e.which , that = this , val = $.trim( $(this).val() ) , valEqual = val == $(that).val() , notEmpty = '' !== val , type = $('.active.lasso--show-objects').data('post-type') , url = api+'/'+type+'s?filter[s]='+val+'&filter[posts_per_page]=50' , input = '#lasso--search-field' , results = $('#lasso--results-found') , helperText = lasso_editor.strings.helperText , helperSpan = ''+helperText+'' // 800ms delay so we dont exectute excessively timer = setTimeout(function() { // don't proceed if the value is empty or not equal to itself if ( !valEqual && !notEmpty ) return false; // what if the user only types two characters? if ( val.length == 2 && !$(helper).length ) { destroyClose() $(input).after( helperSpan ) } // if we have more than 3 characters and if value is teh same if ( val.length >= 3 || val.length >= 3 && 13 == key ) { // append loading indicator $(postList).prepend( loader ); // remove any helpers $( helper ).fadeOut().remove(); // remove the cose destroyClose(); //http://localhost/wordpress/wp-json/wp/v2/posts?search=test%205 var page = 1; var capable = lasso_editor.edit_others_posts; if (type=='posts') { options = capable ? setOptionsPost( type, page ) : setOptionsPost( type, page, lasso_editor.author ); options.data['search']=val; collection = new wp.api.collections.Posts( ); collection.fetch( options ).done( function() { $(postList).children().remove(); //remove more button $( '#lasso--load-more,#lasso--close-modal-posts' ).remove(); // if we have more posts then load them if ( collection.length > 0 ) { var setContainer = $( '
      ' ); if (lasso_editor.restapi2) { collection.each( function ( model ) { //post.link title status id setContainer.append( postTemplate( { post: model.attributes, link_: model.attributes._links.self[0].href, settings: WP_API_Settings } ) ); } ); } else { collection.each( function ( model ) { setContainer.append( postTemplate( { post: model.attributes, settings: WP_API_Settings } ) ); } ); } // append to the post container $(postList).append( setContainer ); //put back more button $(postList).append( moreButton ); $(postList).append( closeButton ); // show search filtering $('.lasso--post-filtering').removeClass('not-visible').addClass('visible') $( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading'); // re-init scroll initScroll() }else{ $( postList ).append( noPostsMessage ); setTimeout(function(){ $('#lasso--end-posts').fadeOut('slow') }, 1000) } // destroy the spinny loader destroyLoader(); }).fail(function(xhr, err) { fetchError(xhr); }); } else { options = capable ? setOptions( type, page ) : setOptions( type, page, lasso_editor.author ); options['search']=val; jQuery.getJSON(WP_API_Settings.root+'wp/v2/'+type,options, function(data) { $( '#lasso--load-more' ).remove(); $(postList).children().remove(); if ( data.length > 0 ) { var setContainer = $( '
      ' ); jQuery.each( data, function( i, val ) { setContainer.append( postTemplate( { post: val, link_: val.link, settings: WP_API_Settings } ) ); }); // append to the post container $(postList).append( setContainer ); //put back more button if (data.length>=7 ) { $(postList).append( moreButton ); $( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading'); } // show search filtering $('.lasso--post-filtering').removeClass('not-visible').addClass('visible'); // re-init scroll initScroll() } else { $( postList ).append( noPostsMessage ); setTimeout(function(){ $('#lasso--end-posts').fadeOut('slow') }, 1000) } destroyLoader(); }) .fail(function(xhr, err) { fetchError(xhr); }); } } }, 600); }).on('click','#lasso--search__toggle', function( e ) { // open close search e.preventDefault() var input = $('#lasso--search-field') // toggle visible class $('.lasso--search').toggleClass( 'lasso--search__visible' ) // focus on input input.focus() // if the search isnt visible and not empty then destroy the search if ( !$(this).parent().hasClass('lasso--search__visible') && input.val() !== '' ) { destroySearch('post') } }).on('click', clearItem, function(e){ e.preventDefault(); destroySearch('post'); }); /** * Utility function destroy search close */ function destroyClose(){ $( clearItem ).remove(); } /** * Helper fucntion to destroy the search * @param type string the type of post to fetch (post or page) * @since 0.9.5 */ function destroySearch( type ){ // remove teh children $(postList).children().remove() // fetch initial posts fetchPosts( type ) // clear previous seach term $( '#lasso--search-field' ).val('').focusout() // weird bug with focusout not wokring // hide searh results $('#lasso--results-found').parent().css('opacity',0) // remove helper if any $( helper ).remove(); // remove close destroyClose() } jQuery(document).on('click', '#lasso--post-list', function(e){ if (e.target.id === 'lasso--post-list') { // close modal if the user clicks on empty spaces // destroy posts modal $('#lasso--all-posts__modal').remove(); $( '#lasso--modal__overlay' ).remove(); $('body').remove('#lasso--modal__overlay'); } }); })( jQuery, Backbone, _, WP_API_Settings ); (function( $ ) { $(document).ready(function(){ destroyModal = function(){ $('body').removeClass('lasso-modal-open'); $('#lasso--tour__modal,#lasso--all-posts__modal,#lasso--modal__overlay').remove(); } //$('#lasso--tour__modal input[type="submit"]').live('click', function(e) { jQuery(document).on('click', '#lasso--tour__modal input[type="submit"]', function(e){ e.preventDefault(); var target = $(this); if ( !$('#hide_tour').is(':checked') ) { destroyModal() } else { if (lasso_editor.saveusingrest) { var data = { action: 'process_tour_hide', nonce: $(this).data('nonce') } $.post( lasso_editor.ajaxurl, data, function(response) { if ( true == response.success ) { destroyModal(); } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); } else { var data = { action: 'process_tour_hide', nonce: $(this).data('nonce') } $.post( lasso_editor.ajaxurl, data, function(response) { if ( true == response.success ) { destroyModal(); } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); } } }); }); })( jQuery ); (function( $ ) { jQuery(document).ready(function($){ if ( $( "#lasso--tour__slides" ).length ) { $('body').addClass('lasso-modal-open'); $('.lasso--loading').remove(); $('#lasso--tour__slides').hide().fadeIn() $('#lasso--tour__slides').unslider({ dots: true, delay:7000 }); } }); })( jQuery ); (function( $ ) { $(document).ready(function(){ var vars = lasso_editor , revisions , revision_id = 0 , next , previous , total revisionList = $('#lasso--revision-list'); // method to destroy the modal var destroyModal = function(){ $('body').removeClass('lasso-modal-open'); $('#lasso--revision__modal').remove(); $('#lasso--post-revisions').show(); }; // destroy loader function destroyLoader(){ $('#lasso--loading').remove(); } //Update title/post content for a revision var restoreRevision = function( revision_id ) { if( revision_id in revisions ){ revision = revisions[ revision_id ]; $( vars.titleClass ).html( revision.post_title ); $( vars.article_object ).html( revision.post_content ); $('body').attr('data-revision', revision_id ); } }; // modal click $('#lasso--post-revisions').on('click',function(e){ e.preventDefault(); // preent double clicking and opening $(this).hide(); // append revision modal $('body').append(vars.revisionModal); innerModal = $('#lasso--revision__modal .lasso--modal__inner'); // make the modal draggable innerModal.draggable({ cursor:'move', opacity:0.8 }); data = { action : 'process_revision_get', postid : vars.postid, nonce : vars.nonce }; $.post( vars.ajaxurl, data, function(response) { // do we have a response if ( true == response.success ) { revisionList = $('#lasso--revision-list'); slider = $('#lasso--slider'); lassoHide = $('#lasso--hide'); // remove any count classes removeRevisionCount(); // desroy the loader destroyLoader(); // show the button and slider lassoHide.show(); // if we have revisions if ( 'object' == typeof response.data && response.data.length ) { revisions = response.data; var total = revisions.length == 1 ? 1 : revisions.length -1; if ( revisions.length !== 1 ) { $.each( revisions, function( i, post ) { revisionList.append( '
    • ' + post.modified_time + '
    • ' ) }); // init slider and restore on slide slider.slider({ min: 0, max: total, animate:'fast', value: 0, zindex:999, slide: function( event, ui ) { restoreRevision( ui.value ) } }); // restore revision and sync slider on click $('.lasso--jump-revision').on('click',function(e){ e.preventDefault(); var val = $(this).data('revision'); slider.slider( 'value', val ); restoreRevision( val ); }) revisionList.attr('data-count', total + 1 ) // because we start at 0 } else { lassoHide.hide(); innerModal.append( vars.noRevisionsDiv ); } $('body').addClass('lasso--revision-count-'+revisions.length ); maybeRestoreCurrent(); modalResizer(); }else{ $('#lasso--hide').hide() innerModal.append( vars.noRevisionsDiv ); modalResizer(); } } else { alert('error'); } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); modalResizer(); }); // select a revision and start editing $(document).on('click', '#lasso--select-revision', function(e){ e.preventDefault(); destroyModal(); $('#lasso--edit').trigger('click'); addBackupNotice(); }).on('click','#lasso--close-modal',function(e){ e.preventDefault(); destroyModal(); }); ///////////////// /// EXIT SETTINGS /////////////////// $(document).keyup(function(e) { if ( 27 == e.keyCode ) { destroyModal(); } }); // restore teh current revision but only if a user is editing one function maybeRestoreCurrent(){ if( $('body').data('revision') ) { slider.slider('value', $('body').data('revision') ) } } // add a backup notice if we're editing a backukp function addBackupNotice(){ if ( !$('#lasso--notice').length ) { $(vars.article_object).before('
      '+vars.strings.editingBackup+'
      '); } } // remove/reset revisino count function removeRevisionCount(){ $('body').removeClass (function (index, css) { return (css.match (/(^|\s)lasso--revision-count-\S+/g) || []).join(' '); }); } }); })( jQuery ); ================================================ FILE: public/assets/js/source/all-posts.js ================================================ (function( $, Backbone, _, WP_API_Settings, undefined ) { var contentTemplate = $('#lasso-tmpl--post' ) , postTemplate = _.template( contentTemplate.html() ) //, posts = new wp.api.collections.Posts() //, pages = new wp.api.collections.Pages() , postAll = $('#lasso--post-all') , postList = '#lasso--post-list' , loadingText = lasso_editor.strings.loading , loadMoreText = lasso_editor.strings.loadMore , noPostsText = lasso_editor.strings.noPostsFound , fetchFailText = lasso_editor.strings.fetchFail , body = $('body') , noPostsMessage = '
    • '+noPostsText+'
    • ' , fetchFailMessage = '
    • '+fetchFailText+'
    • ' , noResultsDiv = lasso_editor.noResultsDiv , loader = '
      ' , moreButton = ''+loadMoreText+'' , closeButton = ''+lasso_editor.strings.close+'' , clear = '' , clearItem = '#lasso--clear-search' , hideClass = 'lasso--hide' , showClass = 'lasso--show' , helper = '#lasso--helper' , page = 1 , lastType = 'posts' , collection = false , initial = true , totalPages = null , api = WP_API_Settings.root , timer // infinite load options var options = { data: { page: page, filter: { post_status: ['publish','draft','pending'] } } } ////////////////// // DESTROY LOADER ///////////////// function destroyLoader(){ $('#lasso--loading').remove() } ///////////////// // INITIALIZE SCROLL ///////////////// function initScroll() { $(postList).perfectScrollbar({ suppressScrollX: true }); } // set links clickable //$("a").attr('contenteditable',false); function fetchError(xhr){ $( '#lasso--loading' ).remove(); try { var data = JSON.parse(xhr.responseText); if (data['code'] == 'rest_post_invalid_page_number' ) { $( '#lasso--load-more' ).remove(); $( postList ).append( noPostsMessage ); } else { // show some info $( postList ).append( fetchFailMessage + '
      '+JSON.stringify(xhr).replace(/&/g,'&').replace(//g,'>')+'
      ' ); } } catch (e){ $( postList ).append( fetchFailMessage); } } ////////////////// // FETCH POSTS HELPER FUNCTION ///////////////// function fetchPosts( type ){ var capable = lasso_editor.edit_others_posts; lastType = type; if ( 'pages' == type ) { capable = lasso_editor.edit_others_pages; } /*else if ( 'posts' == type ) { //collection = new wp.api.collections.Posts( options ); } else { // this is a working, alternate way to get collection of custom post type /*var customPost = wp.api.models.Post.extend({ urlRoot: WP_API_Settings.root + 'wp/v2/'+type, defaults: { type: type } }); var customCollection = wp.api.collections.Posts.extend({ url: WP_API_Settings.root + 'wp/v2/'+type, model: customPost }); collection = new customCollection;* }*/ if (type=='posts') { options = capable ? setOptionsPost( type, page ) : setOptionsPost( type, page, lasso_editor.author ); collection = new wp.api.collections.Posts( ); collection.fetch( options ).done( function() { //remove more button $( '#lasso--load-more,#lasso--close-modal-posts' ).remove(); // if we have more posts then load them if ( collection.length > 0 ) { var setContainer = $( '
      ' ); if (lasso_editor.restapi2) { collection.each( function ( model ) { //post.link title status id setContainer.append( postTemplate( { post: model.attributes, link_: model.attributes._links.self[0].href, settings: WP_API_Settings } ) ); } ); } else { collection.each( function ( model ) { setContainer.append( postTemplate( { post: model.attributes, settings: WP_API_Settings } ) ); } ); } // append to the post container $(postList).append( setContainer ); //put back more button $(postList).append( moreButton ); $(postList).append( closeButton ); // show search filtering $('.lasso--post-filtering').removeClass('not-visible').addClass('visible') $( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading'); // re-init scroll initScroll() }else{ $( postList ).append( noPostsMessage ); setTimeout(function(){ $('#lasso--end-posts').fadeOut('slow') }, 1000) } // destroy the spinny loader destroyLoader(); }).fail(function(xhr, err) { fetchError(xhr); }); } else { /*var author = capable ? lasso_editor.author : -1; var parms = getParams( true, page, author ); jQuery.ajax({ method: "GET", url: WP_API_Settings.root+'wp/v2/'+type+parms,//'?status[]=draft&author[]='+lasso_editor.author, //dataType: "json", beforeSend: function(xhr){ xhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce ); }, success : function( data ) { dispPosts(data, type); parms = getParams( false, page, author ); jQuery.ajax({ method: "GET", url: WP_API_Settings.root+'wp/v2/'+type+parms, //dataType: "json", beforeSend: function(xhr){ xhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce ); }, success : function( data ) { dispPosts(data, type); }, done: function(data) { }, error: function(xhr, err) { $( '#lasso--loading' ).remove(); //alert(xhr.responseText); //fetchError(xhr); } }); }, done: function(data) { }, error: function(xhr, err) { $( '#lasso--loading' ).remove(); //alert(xhr.responseText); //fetchError(xhr); parms = getParams( false, page, lasso_editor.author ); jQuery.ajax({ method: "GET", url: WP_API_Settings.root+'wp/v2/'+type+parms, //dataType: "json", beforeSend: function(xhr){ xhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce ); }, success : function( data ) { dispPosts(data, type); }, done: function(data) { }, error: function(xhr, err) { $( '#lasso--loading' ).remove(); //alert(xhr.responseText); //fetchError(xhr); } }); } });*/ options = capable ? setOptions( type, page ) : setOptions( type, page, lasso_editor.author ); jQuery.getJSON(WP_API_Settings.root+'wp/v2/'+type,options, function(data) { $( '#lasso--load-more' ).remove(); if ( data.length > 0 ) { var setContainer = $( '
      ' ); jQuery.each( data, function( i, val ) { setContainer.append( postTemplate( { post: val, link_: val.link, settings: WP_API_Settings } ) ); }); // append to the post container $(postList).append( setContainer ); //put back more button if (data.length>=7 ) { $(postList).append( moreButton ); $( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading'); } // show search filtering $('.lasso--post-filtering').removeClass('not-visible').addClass('visible'); // re-init scroll initScroll() } else { $( postList ).append( noPostsMessage ); setTimeout(function(){ $('#lasso--end-posts').fadeOut('slow') }, 1000) } destroyLoader(); }) .fail(function(xhr, err) { fetchError(xhr); }); } } function dispPosts(data, type) { $( '#lasso--load-more' ).remove(); if ( data.length > 0 ) { var setContainer = $( '
      ' ); jQuery.each( data, function( i, val ) { setContainer.append( postTemplate( { post: val, link_: val.link, settings: WP_API_Settings } ) ); }); // append to the post container $(postList).append( setContainer ); //put back more button if (data.length>=7 ) { $(postList).append( moreButton ); $( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading'); } // show search filtering $('.lasso--post-filtering').removeClass('not-visible').addClass('visible'); // re-init scroll initScroll() } else { //$( postList ).append( noPostsMessage ); setTimeout(function(){ $('#lafesso--end-posts').fadeOut('slow') }, 1000) } destroyLoader(); } function getParams( draft, page, author ) { var params = '?page='+page; if (author != -1) { params += '&author[]='+author; } if (draft) { params += '&status[]=draft'; } return params; } /** * Helper function to reset options * * @param type post type * @param page page * * @returns {{data: {page: *, filter: {post_type: *, post_status: string[]}}}} */ function setOptions( type, page, author ) { if (!author) { return { page: page, type: type, //status: 'draft', per_page: 7, //filter: { //post_status: ['publish','draft','pending'], // posts_per_page: 7, //author: author //} }; } return { page: page, type: type, author: author, //status: ['publish','draft','pending'], per_page: 7, /*filter: { post_status: ['publish','draft','pending'], posts_per_page: 7, author: author }*/ } } function setOptionsPost( type, page, author ) { return options = { data: { page: page, type: type, author: author, status:['publish','draft','pending'], per_page: 7, filter: { post_status: ['publish','draft','pending'], posts_per_page: 7, author: author } } } } ////////////////// // OPEN INITIAL POSTS ///////////////// $( postAll ).on('click',function(e){ e.preventDefault(); // add a body class body.toggleClass('lasso-modal-open'); // append teh modal markup ( lasso_editor_component_modal() ) body.append( lasso_editor.allPostModal ); // get the intial posts fetchPosts('posts'); modalResizer(); }); /** * Load more click event */ $( body ).on('click', '#lasso--load-more', function(e){ e.preventDefault(); type = $( this ).attr( 'data-post-type' ); $(this).addClass('lasso--btn-loading').text( loadingText ); if (lastType == type) { page++; } else { page = 1; } lastType = type; fetchPosts( type ); }).on('click','#lasso--close-modal-posts',function(e){ e.preventDefault(); destroyModal(); }).on('click', '.lasso--show-objects', function(e){ e.preventDefault(); $('.lasso--show-objects').removeClass('active'); $(this).addClass('active'); $('#lasso--post-list').empty(); type = $(this).data('post-type'); page = 1; totalPages = null; $( '#lasso--load-more' ).attr( 'data-post-type', type); $(postList).prepend( loader ); fetchPosts( type ); }).on('click', '#lasso--post__delete', function(e){ e.preventDefault(); var $this = $(this); swal({ title: lasso_editor.strings.deletePost, type: "error", text: false, showCancelButton: true, confirmButtonColor: "#d9534f", confirmButtonText: lasso_editor.strings.deleteYes, closeOnConfirm: true }, function(){ var data = { action: 'editus_delete_post', postid: $this.closest('a').data('postid'), nonce: lasso_editor.deletePost } $.post( lasso_editor.ajaxurl2, data, function(response) { if ( "" == response ) { $this.closest('li').fadeOut().remove() } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); }).on('keyup','#lasso--search-field',function( e ){ // live search - @since 0.9.5 // clear the previous timer clearTimeout(timer) var key = e.which , that = this , val = $.trim( $(this).val() ) , valEqual = val == $(that).val() , notEmpty = '' !== val , type = $('.active.lasso--show-objects').data('post-type') , url = api+'/'+type+'s?filter[s]='+val+'&filter[posts_per_page]=50' , input = '#lasso--search-field' , results = $('#lasso--results-found') , helperText = lasso_editor.strings.helperText , helperSpan = ''+helperText+'' // 800ms delay so we dont exectute excessively timer = setTimeout(function() { // don't proceed if the value is empty or not equal to itself if ( !valEqual && !notEmpty ) return false; // what if the user only types two characters? if ( val.length == 2 && !$(helper).length ) { destroyClose() $(input).after( helperSpan ) } // if we have more than 3 characters and if value is teh same if ( val.length >= 3 || val.length >= 3 && 13 == key ) { // append loading indicator $(postList).prepend( loader ); // remove any helpers $( helper ).fadeOut().remove(); // remove the cose destroyClose(); //http://localhost/wordpress/wp-json/wp/v2/posts?search=test%205 var page = 1; var capable = lasso_editor.edit_others_posts; if (type=='posts') { options = capable ? setOptionsPost( type, page ) : setOptionsPost( type, page, lasso_editor.author ); options.data['search']=val; collection = new wp.api.collections.Posts( ); collection.fetch( options ).done( function() { $(postList).children().remove(); //remove more button $( '#lasso--load-more,#lasso--close-modal-posts' ).remove(); // if we have more posts then load them if ( collection.length > 0 ) { var setContainer = $( '
      ' ); if (lasso_editor.restapi2) { collection.each( function ( model ) { //post.link title status id setContainer.append( postTemplate( { post: model.attributes, link_: model.attributes._links.self[0].href, settings: WP_API_Settings } ) ); } ); } else { collection.each( function ( model ) { setContainer.append( postTemplate( { post: model.attributes, settings: WP_API_Settings } ) ); } ); } // append to the post container $(postList).append( setContainer ); //put back more button $(postList).append( moreButton ); $(postList).append( closeButton ); // show search filtering $('.lasso--post-filtering').removeClass('not-visible').addClass('visible') $( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading'); // re-init scroll initScroll() }else{ $( postList ).append( noPostsMessage ); setTimeout(function(){ $('#lasso--end-posts').fadeOut('slow') }, 1000) } // destroy the spinny loader destroyLoader(); }).fail(function(xhr, err) { fetchError(xhr); }); } else { options = capable ? setOptions( type, page ) : setOptions( type, page, lasso_editor.author ); options['search']=val; jQuery.getJSON(WP_API_Settings.root+'wp/v2/'+type,options, function(data) { $( '#lasso--load-more' ).remove(); $(postList).children().remove(); if ( data.length > 0 ) { var setContainer = $( '
      ' ); jQuery.each( data, function( i, val ) { setContainer.append( postTemplate( { post: val, link_: val.link, settings: WP_API_Settings } ) ); }); // append to the post container $(postList).append( setContainer ); //put back more button if (data.length>=7 ) { $(postList).append( moreButton ); $( '#lasso--load-more' ).attr( 'data-post-type', type ).removeClass('lasso--btn-loading'); } // show search filtering $('.lasso--post-filtering').removeClass('not-visible').addClass('visible'); // re-init scroll initScroll() } else { $( postList ).append( noPostsMessage ); setTimeout(function(){ $('#lasso--end-posts').fadeOut('slow') }, 1000) } destroyLoader(); }) .fail(function(xhr, err) { fetchError(xhr); }); } } }, 600); }).on('click','#lasso--search__toggle', function( e ) { // open close search e.preventDefault() var input = $('#lasso--search-field') // toggle visible class $('.lasso--search').toggleClass( 'lasso--search__visible' ) // focus on input input.focus() // if the search isnt visible and not empty then destroy the search if ( !$(this).parent().hasClass('lasso--search__visible') && input.val() !== '' ) { destroySearch('post') } }).on('click', clearItem, function(e){ e.preventDefault(); destroySearch('post'); }); /** * Utility function destroy search close */ function destroyClose(){ $( clearItem ).remove(); } /** * Helper fucntion to destroy the search * @param type string the type of post to fetch (post or page) * @since 0.9.5 */ function destroySearch( type ){ // remove teh children $(postList).children().remove() // fetch initial posts fetchPosts( type ) // clear previous seach term $( '#lasso--search-field' ).val('').focusout() // weird bug with focusout not wokring // hide searh results $('#lasso--results-found').parent().css('opacity',0) // remove helper if any $( helper ).remove(); // remove close destroyClose() } jQuery(document).on('click', '#lasso--post-list', function(e){ if (e.target.id === 'lasso--post-list') { // close modal if the user clicks on empty spaces // destroy posts modal $('#lasso--all-posts__modal').remove(); $( '#lasso--modal__overlay' ).remove(); $('body').remove('#lasso--modal__overlay'); } }); })( jQuery, Backbone, _, WP_API_Settings ); ================================================ FILE: public/assets/js/source/enter-editor.js ================================================ jQuery(document).ready(function($){ var editor = lasso_editor.editor, strings = lasso_editor.strings, settingsLink = lasso_editor.settingsLink, post_container = lasso_editor.article_object, toolbar = lasso_editor.toolbar, toolbarPopup = lasso_editor.toolbarPopup, toolbarHeading = lasso_editor.toolbarHeadings, panel = lasso_editor.component_sidebar, postid = lasso_editor.postid, modal = lasso_editor.component_modal, components = lasso_editor.components, featImgClass = lasso_editor.featImgClass, featImgNonce = lasso_editor.featImgNonce, titleClass = lasso_editor.titleClass, uploadControls = lasso_editor.featImgControls, wpImgEdit = lasso_editor.wpImgEdit, lassoDragHandle = lasso_editor.handle, lassoMapForm = lasso_editor.mapFormFooter, mapLocations = lasso_editor.mapLocations, mapZoom = lasso_editor.mapZoom, mapStart = lasso_editor.mapStart, objectsNoSave = lasso_editor.objectsNoSave, objectsNonEditable = lasso_editor.objectsNonEditable, supportedNoSave = lasso_editor.supportedNoSave function restoreSelection(range) { if (range) { if (window.getSelection) { var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } else if (document.selection && range.select) { range.select(); } } } function saveSelection() { if (window.getSelection) { article.highlight(); sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { return sel.getRangeAt(0); } } else if (document.selection && document.selection.createRange) { return document.selection.createRange(); } return null; } /* function to disable selection. Not used for now jQuery.fn.extend({ disableSelection : function() { return this.each(function() { this.onselectstart = function() { return false; }; this.unselectable = "on"; jQuery(this).css('user-select', 'none'); jQuery(this).css('-o-user-select', 'none'); jQuery(this).css('-moz-user-select', 'none'); jQuery(this).css('-khtml-user-select', 'none'); jQuery(this).css('-webkit-user-select', 'none'); }); } });*/ $('#lasso--edit').click(function(e){ if ($(post_container).length ==0 ){ // try one more time, support for shapely theme var contClasses = [".shapely-content",".entry-content",".aesop-entry-content",".novella-entry-content",".post-content", ".entry-content-wrapper",".post_content",".gp-entry-content"]; for (var i = 0; i < contClasses.length; i++) { if ($(contClasses[i]).length >0 ){ post_container = contClasses[i]; break; } } if ($(post_container).length ==0 ){ // if we can't find the article class, warn them and exit swal({ title: strings.warning, type: 'info', text: strings.missingClass, showCancelButton: true, cancelButtonText: strings.cancelText, confirmButtonColor: '#007aab', confirmButtonText: strings.missingConfirm, closeOnConfirm: false }, function(){ location.replace(settingsLink); }); return; } } lasso_editor.article_object = post_container; // ways to inject codes into the enterEditor if (lasso_editor.enterEditorHookArray) { $(lasso_editor.enterEditorHookArray).each(function(key, val){ val(); }); } // lock the post for editing var data = { action: 'editus_lock_post', postid: lasso_editor.postid }; lasso_editor.dontlock = false; jQuery.post(lasso_editor.ajaxurl2, data, function(response) { if( response ){ if (response.trim()=="true") { lasso_editor.dontlock = true; } else { swal({ title:"Lock Post Fail", text: response, closeOnConfirm: true }); exitEditor(); } } else { alert("Error locking the post for editing"); exitEditor(); } }); //keep locking periodically if (!lasso_editor.dontlock) { lasso_editor.lockIntervalID = window.setInterval(lockPost, 120000); } function lockPost() { var data = { action: 'editus_lock_post', postid: lasso_editor.postid }; jQuery.post(lasso_editor.ajaxurl2, data, function(response) { /*if( response ){ if (response!="true") { alert(response); exitEditor(); } } else { alert("Error locking the post for edit"); exitEditor(); }*/ }); } e.preventDefault(); // add body class editing $('body').toggleClass('lasso-editing'); //append editor id to post container $(post_container).prop('id', editor); // append toolbar $(toolbar).hide().appendTo('body').fadeIn(300); // fade in controls if previous exacped $('.lasso--controls__right').css('opacity',1); // set edtior to editable $('#'+editor).attr('contenteditable',true); // add settings panel $('body').append(panel); // append upload bar to featured image if present if ( $( featImgClass ).length > 0 ) { if ( $(lasso_editor.featImgClass).is( "img" ) ) { $(featImgClass).parent().append( uploadControls ); } else { $(featImgClass).append( uploadControls ); } } // append contenteditable to title if set if ( $(titleClass).length > 0 ) { $(titleClass).attr('contenteditable', true); } else { // try one more time with .entry-title var titleClasses = [".entry-title-primary",".entry-title",".novella-entry-title"]; for (var i = 0; i < titleClasses.length; i++) { if ( $(titleClasses[i]).length > 0 ) { lasso_editor.titleClass = titleClass = titleClasses[i]; $(titleClass).attr('contenteditable', true); break; }; } } lasso_editor.subtitleClass=""; var subtitleClasses = [".entry-subtitle",".novella-entry-subtitle"]; for (var i = 0; i < subtitleClasses.length; i++) { if ( $(subtitleClasses[i]).length > 0 ) { lasso_editor.subtitleClass = subtitleClasses[i]; $(subtitleClasses[i]).attr('contenteditable', true); break; }; } // if tehre are any scrollnav sections we need to break them open so that we can drag compnents around in them $('.scroll-nav__section').each(function(){ $(this).children().unwrap(); }) // add an exit editor button $('.lasso--controls__right ').prepend(''); // append the toolbar to any components that dont have them // @todo - this likely needs to be changed to a lasso- namespaced item which then needs to be updated in Aesop Story Engine $('.aesop-component').each(function(){ // if there's no toolbar present if ( !$('.lasso-component--toolbar').length > 0 ) { // if this is a map then we need to first wrap it so that we can drag the map around if ( $(this).hasClass('aesop-map-component') ) { var $this = $(this) // so wrap it with a aesop-compoentn aesop-map-component div // @todo - note once a map is inserted it can't be edited after saving again. a user has to delete the existin map and add a new map // to //$this.wrap('').before( lassoDragHandle ).after( lassoMapForm ); $this.wrap('
      ').before( lassoDragHandle ); } else { $(this).append( lassoDragHandle ); } } }); lasso_editor.wrapImg = function () { // find images inserted from within the wordpress backend post editor and // wrap them in a div, then append an edit button for editing the image /*$("[class*='wp-image-']").each(function(){ var $this = $(this) if ( !$('.lasso--wpimg-edit').length > 0 ) { if ( $this.parent().hasClass('wp-caption') ) { $this.parent().addClass('lasso--wpimg__wrap') } else { $this.wrap('
      ') } $this.parent().data( $this.data() ); var s =$this.attr('src'); if (s) { $this.parent().data({componentType:"wpimg", img: $this.attr('src')}); } } });*/ //$('.lasso-component:not(.lasso--wpimg__wrap)').each(function(){ $('.lasso-component').each(function(){ var $this = $(this) if ( $(this).find('.lasso-component--controls').length == 0 ) { if (!lasso_editor.oldWPimg) { $(this).prepend( lassoDragHandle ); var img = $(this).find('img')[0]; var ctrl = $this.find('.lasso-component--controls')[0]; if ($(img).hasClass('alignnone') || $(img).hasClass('alignleft')) { $(ctrl).removeClass('editus-center'); } if ($(img).hasClass('alignright')) { $(ctrl).removeClass('editus-center'); $(ctrl).addClass('editus-right'); } } else { if ( $this.parent().hasClass('wp-caption') ) { $this.parent().addClass('lasso--wpimg__wrap') }/* else if ( !$this.parent().hasClass('lasso--wpimg__wrap') ) { $this.wrap('
      ') }*/ $this.parent().prepend(lasso_editor.wpImgEdit); } } }) //wp image block $('.wp-block-image').each(function(){ var $this = $(this) if ( $(this).find('.lasso-component--controls').length == 0 ) { $this.prepend(lasso_editor.wpImgBlockEdit); $this.attr('data-component-type','wpimg-block'); } }) //wp cover block $('.wp-block-cover').each(function(){ var $this = $(this) if ( $(this).find('.lasso-component--controls').length == 0 ) { $this.prepend(lasso_editor.wpImgBlockEdit); $this.find(".lasso-clone,.lasso-delete").remove(); $this.find(".lasso-component--controls").width('61px'); $this.attr('data-component-type','wpcover-block'); } }) } lasso_editor.wrapImg(); ///////////////// /// /// CONTENT EDITABLE / TOOLBAR /// /// - attributes and tags are set to null to allow any markup and block level items to be passed through /// this means that medium.js is only providing us with a helper API to invoke certain markup and to /// insert HTML. It's important to realize that the_content filter together with wpautop is responsible /// for automatically making new paragraph elements on enter /// /////////////////// article = document.getElementById(editor), articleMedium = new Medium({ element: article, mode: Medium.richMode, attributes: null, tags: null, placeholder:lasso_editor.strings.justWrite, pasteAsText: true, cssClasses: { editor: 'lasso-editor', pasteHook: 'lasso-editor-paste-hook', placeholder: 'lasso-editor-placeholder', clear: 'lasso-editor-clear' } }); $(objectsNonEditable).attr('contenteditable',false); $(objectsNonEditable).attr('readonly',true); // set some figures uneditable $("figure.wp-block-image, figure.lasso--wpimg__wrap").attr('contenteditable',false).attr('readonly',true); // remove any additional markup so we dont save it as HTML if (objectsNoSave.length) { objectsNoSave = objectsNoSave+","+supportedNoSave; } else { objectsNoSave = supportedNoSave; } lasso_editor.objectsNoSave = objectsNoSave; if ($(objectsNonEditable).length || (lasso_editor.showIgnoredItems && ($(objectsNoSave).length)|| $(supportedNoSave).length )) { lasso_editor.readOnlyExists = true; } else { lasso_editor.readOnlyExists = false; } if (!lasso_editor.showIgnoredItems) { $(objectsNoSave).remove(); $(supportedNoSave).remove(); } else { $(objectsNoSave).attr('contenteditable',false); $(objectsNoSave).attr('readonly',true); } // detect avia editor lasso_editor.aviaEditor = ($('.av_toggle_section,.av_textblock_section').length>0); // set links clickable if (!lasso_editor.linksEditable) { $("a").attr('contenteditable',false); } if (lasso_editor.disableEditPost) { //set everything uneditable $( "[contenteditable]" ).attr('contenteditable',false); } // custom fields if (lasso_editor.customFields) { var joined = []; for (var key in lasso_editor.customFields) { var imgControls = ''; if (typeof(lasso_editor.customFields[key]) == 'object') { var selector = lasso_editor.customFields[key]['selector']; joined.push(selector); if (lasso_editor.customFields[key]['imgurl']) { if ($(selector).find('.editus-custosm-image-control').length == 0) { $(selector).parent().parent().append( imgControls ); $(selector).parent().parent().css("position", "relative"); $(selector).parent().parent().find('.editus-custom-image-control').mousedown(imgDialog); } } } else { joined.push(lasso_editor.customFields[key]); } } lasso_editor.cfselector = joined.join(','); $(lasso_editor.cfselector).attr('contenteditable',true); if (lasso_editor.undeletableExists = ($(lasso_editor.cfselector).length>0)) { $(lasso_editor.cfselector).addClass('lasso-undeletable'); } } //$(objectsNonEditable).disableSelection(); // this forces the default new element in content editable to be a paragraph element if // it has no previous element to depart from // ref http://stackoverflow.com/a/15482748 document.execCommand('defaultParagraphSeparator', false, 'p'); // cursor to the beginning if (articleMedium.element.firstChild == null) { var node = document.createElement("p"); var textnode = document.createTextNode(" "); // Create a text node node.appendChild(textnode); articleMedium.element.appendChild(node); } articleMedium.cursor.caretToBeginning(articleMedium.element.firstChild); article.highlight = function() { if (document.activeElement !== article) { //articleMedium.select(); article.focus(); } else { return false; } }; if (lasso_editor.toolbarPopup) { $(lasso_editor.toolbarPopup).hide().appendTo('body'); } //color if (lasso_editor.showColor) { var cv = "#ff0000"; // red is the default color $( '#lasso-toolbar--color-pick' ).iris(); $( '#lasso-toolbar--color-pick' ).iris('color', '#f00'); $('head').append(''); $(window).mousedown(function() { //Hide the color picker if visible $("#lasso-toolbar--color-pick").iris('hide'); }); function rgb2hex(rgb) { rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); function hex(x) { return ("0" + parseInt(x).toString(16)).slice(-2); } return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]); } if (!lasso_editor.isMobile) { $(".iris-picker").css({position:'absolute', top:-180}); } $("#lasso-toolbar--color-pick").iris({ palettes: true, change: function(event, ui) { // event = standard jQuery event, produced by whichever control was changed. // ui = standard jQuery UI object, with a color member containing a Color.js object // change the color $('style#editus-colorpick').remove(); cv = ui.color.toString(); $('head').append(''); } }); $('#lasso-toolbar--color-pick').on('mousedown', function(event) { if (event.target.id == 'lasso-toolbar--color-pick') { $("#lasso-toolbar--color-pick").iris('toggle'); } event.stopPropagation(); }); $('#lasso-toolbar--color-set').on('mousedown', function() { $("#lasso-toolbar--color-pick").iris('hide'); articleMedium.element.contentEditable = true; // exit if nothing is selected if (!lasso_editor.checkSelection(true)) return false; //var colorVar = rgb2hex($('#lasso-toolbar--color-pick').css("color")); articleMedium.invokeElement('span', { style: 'color:' + cv + ';'}); //unselect if (window.getSelection) { if (window.getSelection().empty) { // Chrome window.getSelection().empty(); } else if (window.getSelection().removeAllRanges) { // Firefox window.getSelection().removeAllRanges(); } } else if (document.selection) { // IE? document.selection.empty(); } $(".lasso--text-popup").hide(); articleMedium.makeUndoable(); return false; }); } // color end //alignement if (lasso_editor.showAlignment) { function alignHelper(align) { var focusedElements = articleMedium.html.textElementsAtCaret(); if (focusedElements) { for (i = 0; i < focusedElements.length; i++) { focusedElements[i].style.textAlign = align; } } articleMedium.makeUndoable(); return false; } $('#lasso-toolbar--right-align').mousedown(function() { return alignHelper("right"); }); $('#lasso-toolbar--left-align').mousedown(function() { return alignHelper("left"); }); $('#lasso-toolbar--center-align').mousedown(function() { return alignHelper("center"); }); } //end alignment $('#lasso-toolbar--ul').mousedown(function() { makeList("ul"); }); $('#lasso-toolbar--ol').mousedown(function() { makeList("ol"); }); function makeList(list_type) { var list = $("<"+list_type+"/>"); var focusedElements = articleMedium.html.textElementsAtCaret(); if (focusedElements) { for (i = 0; i < focusedElements.length; i++) { list.append("
    • " + focusedElements[i].innerHTML + "
    • "); if (i>0) { focusedElements[i].parentNode.removeChild(focusedElements[i]); } } $(focusedElements[0]).replaceWith(list[0]); } articleMedium.makeUndoable(); article.highlight(); //setCursor($(focusedElements[0])); //articleMedium.cursor.caretToBeginning(articleMedium.element.firstChild); } if (!lasso_editor.disableEditSC) { processShortcodes(); } function processShortcodes() { $(article).children().filter(function(){ return this.innerHTML.includes("EDITUS_OTHER_SHORTCODE_START"); }).each(function(i, e){ var re = //g ; var cont = re.exec(this.innerHTML); $(this).next().append( '
      '+lasso_editor.strings.editShortcode+'
      ' ); $(this).next().addClass("editus_shortcode_p"); if (cont) $(this).next().find('.editus_shortcode')[0].dataset.shortcode = cont[1]; }); } $(document).on('click','.editus_shortcode', function(e){ var $this = $(this); var s = $(window).scrollTop(); swal({ title: lasso_editor.strings.editShortcode, text: "", showCancelButton: true, confirmButtonColor: "#d9534f", confirmButtonText: "Modify", closeOnConfirm: true, obj: this }, function(){ var val = $('textarea#shortcode_edit').val(); var data = { action: 'editus_do_shortcode', code: val, ID: lasso_editor.postid }; jQuery.post(lasso_editor.ajaxurl2, data, function(response) { restoreSelection(window.selRange); if( response && response.includes("EDITUS_OTHER_SHORTCODE_END")){ $this.parent().prev().remove(); //$this.next().remove(); $this.parent().replaceWith( response.replace("","") ); processShortcodes(); } else { alert("Shortcode processing failed"); } $(window).scrollTop(s); }); }); }) function taghelper(tag) { articleMedium.element.contentEditable = true; article.highlight(); articleMedium.invokeElement(tag); articleMedium.makeUndoable(); return false; } $('[id="lasso-toolbar--bold"]').on('mousedown', function(e) { return taghelper(lasso_editor.boldTag); }); $('[id="lasso-toolbar--underline"]').on('mousedown', function(e) { return taghelper('u'); }); $('[id="lasso-toolbar--italic"]').on('mousedown', function(e) { return taghelper(lasso_editor.iTag); }); $('[id="lasso-toolbar--strike"]').on('mousedown', function(e) { return taghelper('strike'); }); $(document).on('keydown', function ( e ) { // remove formatting when the use pushes ctrl+space if ((e.metaKey || e.ctrlKey) && ( e.which == 32) ) { document.execCommand('removeFormat'); document.execCommand('formatBlock', false, 'p') } }); function heading_helper(heading) { articleMedium.element.contentEditable = true; article.highlight(); articleMedium.invokeElement(heading); //reg = '/

      ([^<>]*)<\/h2>/i'; reg = new RegExp('<'+heading+' class="lasso-'+heading+'">([^<>]*)<\\/'+heading+'>', 'i');; // the following code breaks the paragraphs before and after heading $(articleMedium.element).html(function(index,html){ //return html.replace(/

      ([^<>]*)<\/h2>/i,'

      <'+heading+'>$1

      '); return html.replace(reg,'

      <'+heading+'>$1

      '); }); articleMedium.makeUndoable(); return false; } document.getElementById('lasso-toolbar--link').onmousedown = function() { var article = document.getElementById(lasso_editor.editor); article.highlight(); window.selRange = saveSelection(); }; document.getElementById('lasso-toolbar--html').onmousedown = function() { var article = document.getElementById(lasso_editor.editor); article.highlight(); window.selRange = saveSelection(); if( typeof window.selRange === 'undefined' || null == window.selRange ) { window.selRange = saveSelection(); } }; if ( toolbarHeading ) { document.getElementById('lasso-toolbar--h2').onmousedown = function() { return heading_helper('h2'); }; document.getElementById('lasso-toolbar--h3').onmousedown = function() { return heading_helper('h3'); }; } if ( lasso_editor.toolbarHeadingsH4 ) { document.getElementById('lasso-toolbar--h4').onmousedown = function() { return heading_helper('h4'); }; document.getElementById('lasso-toolbar--h5').onmousedown = function() { return heading_helper('h5'); }; document.getElementById('lasso-toolbar--h6').onmousedown = function() { return heading_helper('h6'); }; } document.getElementById('lasso-toolbar--link__create').onmousedown = function() { articleMedium.element.contentEditable = true; article.highlight(); restoreSelection(window.selRange); var html = ''+window.selRange+''; } else { html = html+' href="'+ target +'">'+window.selRange+''; } } articleMedium.insertHtml(html); var container = window.selRange.startContainer.parentNode, containerTag = container.localName; if ( containerTag == 'a' ) { var containerObject = $(window.selRange.startContainer.parentNode); containerObject.replaceWith(containerObject[0].innerHTML); } window.selRange = null; // close modal drag $('#lasso-toolbar--link').removeClass('link--drop-up link--drop-down'); articleMedium.makeUndoable(); return false; }; // process shortcode using AJAX service and insert the result function do_shortcode_ajax(content) { var data = { action: 'editus_do_shortcode', code: content, ID: lasso_editor.postid }; jQuery.post(lasso_editor.ajaxurl2, data, function(response) { restoreSelection(window.selRange); if( response ){ return insert_html(response); } else { return insert_html(content); } }); } function insert_html(htmlContent, contentishtml) { var html = contentishtml; if (contentishtml == undefined) { html = true; } try { var container = window.selRange.startContainer; var containerTag = container.localName; var containerObject = $(container); var htmlCopy = htmlContent; if (html) { //htmlContent is html, not an object htmlContent = $(htmlContent); htmlContent.attr('contenteditable','true'); } else { htmlCopy = htmlContent[0].outerHTML; } // handle 3 specific scenarios dealing with

      's // note: might need climb up dom tree depending on nesting use case if (containerTag == 'p') { var innerText = container.innerText.replace(/(\r\n|\n|\r)/gm,""); if (!html) { // currently we come here only if when inserting components /*htmlContent.insertAfter( containerObject ); if (innerText =="") { // empty p tag containerObject.remove(); }*/ // decided to change the behavior Now the component is inserted before the empty paragraph htmlContent.insertBefore( containerObject ); if (innerText =="") { articleMedium.cursor.caretToBeginning(container); } } else { articleMedium.insertHtml( htmlCopy ); } } else { // within a p tag container = container.parentNode; containerTag = container.localName; if( containerTag == 'p') { //if (string.indexOf(<) !== -1; //htmlContent.insertAfter( containerObject ); articleMedium.insertHtml( htmlCopy ); } else { // let's just go ahead and paste it on location articleMedium.insertHtml( '

      '+htmlCopy+'

      ' ); } } //window.selRange = null; // close modal drag $('#lasso-toolbar--html').removeClass('html--drop-up'); articleMedium.makeUndoable(); lasso_editor.addComponentButton(); return htmlContent; } catch (e) { alert(e.message); } } function isURL(str) { var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name and extension '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address '(\\:\\d+)?'+ // port '(\\/[-a-z\\d%@_.~+&:]*)*'+ // path '(\\?[;&a-z\\d%@_.,~+&:=-]*)?'+ // query string '(\\#[-a-z\\d_]*)?$','i'); // fragment locator return pattern.test(str); } document.getElementById('lasso-toolbar--html__insert').onmousedown = function() { articleMedium.element.contentEditable = true; restoreSelection(window.selRange); var htmlContent = $('#lasso-toolbar--html__inner').text(); if (htmlContent.indexOf("]") != -1) { do_shortcode_ajax(htmlContent); return false; } else if (isURL(htmlContent)) { do_shortcode_ajax("[embed]"+htmlContent+"[/embed]"); return false; } else { return insert_html(htmlContent); } }; if (lasso_editor.enableAutoSave) { lasso_editor.intervalID = window.setInterval(autoSave, 60000); } function autoSave() { if (localStorage.getItem( 'lasso_backup_'+postid ) || lasso_editor.dirtyByComponent) { $('.lasso--controls__right #lasso--save').trigger('click'); } } function clearTimer() { if (lasso_editor.intervalID) { window.clearInterval(lasso_editor.intervalID); lasso_editor.intervalID = 0; } if (lasso_editor.lockIntervalID) { window.clearInterval(lasso_editor.lockIntervalID); lasso_editor.lockIntervalID = 0; //unlock post var data = { action: 'editus_unlock_post', postid: lasso_editor.postid }; jQuery.post(lasso_editor.ajaxurl2, data, function(response) { }); } } ///////////////// /// EXIT EDITOR /////////////////// function exitEditor(){ clearTimer(); if ($('body').hasClass('lasso-sidebar-open')) { //e.preventDefault(); $('body').removeClass('lasso-sidebar-open'); $('#lasso--component__settings').perfectScrollbar('destroy'); return; } $('body').removeClass('lasso-sidebar-open lasso-editing'); $('.lasso--toolbar_wrap,#lasso--sidebar,#lasso--featImgControls,.lasso-component--controls,#lasso--exit,#lasso-side-comp-button,.lasso--text-popup,.editus_shortcode').fadeOut().remove(); $('#lasso--edit').css('opacity',1); $('.lasso--controls__right').css('opacity',0); $(post_container).attr('id',''); // unwrap wp images /*$('.lasso--wpimg__wrap').each(function(){ $(this).children().unwrap() });*/ // unwrap map from hits drag holder $('#lasso--map-form').each(function(){ var $this = $(this) $this.find('.lasso-component--controls, .lasso--map-form__footer ').remove() $this.children().unwrap() }); $(titleClass).attr('contenteditable', false); $(articleMedium.element).find("*").removeAttr('contenteditable'); articleMedium.destroy(); // ways to inject codes into the exitEditor if (lasso_editor.exitEditorHookArray) { $(lasso_editor.exitEditorHookArray).each(function(key, val){ val(); }); } } lasso_editor.exitEditor = exitEditor; // on escape key exit $(document).keyup(function(e) { if ( 27 == e.keyCode ) { if ($('#lasso-toolbar--link').hasClass('link--drop-up')) { $('#lasso-toolbar--link').removeClass('link--drop-up'); } else if ($('#lasso-toolbar--html').hasClass('html--drop-up')) { $('#lasso-toolbar--html').removeClass('html--drop-up'); } else { exitEditor() } } }); // on utility class exit //$('#lasso--exit').live('click',function(e){ jQuery(document).on('click','#lasso--exit', function(e){ e.preventDefault(); //previously we just called exitEditor(), now the following reloads the page if there is an unsaved change if (articleMedium.dirty) { clearTimer(); location.reload(); } else { exitEditor(); } }) // on control s save $(document).keydown(function(e) { if ((e.which == '115' || e.which == '83' ) && (e.ctrlKey || e.metaKey)){ e.preventDefault(); $('.lasso-editing #lasso--save').trigger('click') return false; } return true; }); /////////// // INITIALIZE TIMELINE ////////// lasso_editor.timelineGoTime = function(){ // if there's no toolbar present if ( !$('.aesop-timeline').length > 0 ) { $('body').append('
      ').addClass('has-timeline'); } if ( !$('.aesop-timeline .scroll-nav').length > 0 ) { $('.aesop-entry-content').scrollNav({ sections: '.aesop-timeline-stop', arrowKeys: true, insertTarget: '.aesop-timeline', insertLocation: 'appendTo', showTopLink: false, showHeadline: false, scrollOffset: 0, }); $('.aesop-timeline-stop').each(function(){ $(this).append( lassoDragHandle ); }); } $('.aesop-timeline-stop').each(function(){ var label = $(this).attr('data-title'); $(this).text(label); if ( $(this).find('.lasso-component--controls').length == 0 ) { $(this).append( lassoDragHandle ); } }); } /////////// // INITIALIZE VIDEO /////////// var videoGoTime = function(){ $('.aesop-video-component').fitVids() } var start_point = mapStart ? mapStart : [29.76, -95.38] , start_zoom = mapZoom ? mapZoom : 12 , mapTileProvider = lasso_editor.mapTileProvider; /////////// // INITIALIZE MAPS /////////// var mapsGoTime = function(){ var lat = start_point.lat ? start_point.lat : 29.76 , lng = start_point.lng ? start_point.lng : -95.38; var map = L.map('aesop-map-component',{ scrollWheelZoom: false, zoom: start_zoom, center: [lat, lng] }); setMapCenter(start_point[0],start_point[1]); jQuery('#lasso-map-address').geocomplete().bind('geocode:result', function(event, result){ var lat = result.geometry.location.k; var lng = result.geometry.location.B; map.panTo(new L.LatLng(lat,lng)); setMapCenter(lat,lng); }); L.tileLayer(mapTileProvider, { maxZoom: 20//start_zoom }).addTo(map); mapLocations.forEach(function(location) { createMapMarker([location['lat'],location['lng']],location['title']).addTo(map); createMarkerField( marker._leaflet_id, encodeMarkerData(location['lat'], location['lng'], location['title']) ); }); // adding a new marker map.on('click', onMapClick); map.on('dragend', onMapDrag); map.on('zoomend', onMapZoom); function setMapCenter(k, B) { var ldata = encodeLocationData(k,B); jQuery('input[name="ase-map-component-start-point"]').remove(); jQuery('.lasso--map-form__footer').append(''); jQuery('#lasso-map-address').val(k + ', ' + B); } function setMapZoom(z) { jQuery('input[name="ase-map-component-zoom"]').remove(); jQuery('.lasso--map-form__footer').append(''); } function onMarkerDrag(e) { updateMarkerField(e.target); } function onMapDrag(e) { var mapCenter = e.target.getCenter() setMapCenter(rnd(mapCenter.lat),rnd(mapCenter.lng)); } function onMapZoom(e) { setMapZoom(e.target.getZoom()); } function rnd(n) { return Math.round(n * 100) / 100 } function onMapClick(e) { var geojsonFeature = { "type": "Feature", "properties": {}, "geometry": { "type": "Point", "coordinates": [e.latlng.lat, e.latlng.lng] } } var marker; L.geoJson(geojsonFeature, { pointToLayer: function(feature, latlng){ marker = L.marker(e.latlng, { title: 'Resource Location', alt: 'Resource Location', riseOnHover: true, draggable: true, }).bindPopup("\ \ \ \ "); marker.on('popupopen', onPopupOpen); marker.on('dragend', onMarkerDrag); return marker; } }).addTo(map); createMarkerField( marker._leaflet_id, encodeMarkerData(e.latlng.lat, e.latlng.lng, 'Location Title') ); } // open popup function onPopupOpen() { var tempMarker = this; // To remove marker on click of delete button in the popup of marker jQuery('.marker-delete-button:visible').click(function () { jQuery('input[data-marker="' + tempMarker._leaflet_id + '"]').remove(); map.removeLayer(tempMarker); }); // Update the title of the location jQuery('.marker-update-button:visible').click(function (t) { var title = t.target.previousElementSibling.value; var tdata = encodeMarkerData(tempMarker._latlng.lat, tempMarker._latlng.lng, title); jQuery('input[data-marker="' + tempMarker._leaflet_id + '"]').val(tdata); tempMarker.options.title = title; tempMarker.closePopup(); tempMarker.bindPopup("\ \ \ \ "); }); } // create map marker function createMapMarker(latlng, title) { marker = L.marker(latlng, { title: title, alt: title, riseOnHover: true, draggable: true, }).bindPopup("\ \ \ \ "); marker.on('popupopen', onPopupOpen); marker.on('dragend', onMarkerDrag); return marker; } function getAllMarkers() { var allMarkersObjArray = []; // for marker objects var allMarkersGeoJsonArray = []; // for readable geoJson markers jQuery.each(map._layers, function (ml) { if (map._layers[ml].feature) { allMarkersObjArray.push(this) allMarkersGeoJsonArray.push(JSON.stringify(this.toGeoJSON())) } }) } // let's create a hidden form element for the marker function createMarkerField(mid, mdata) { jQuery('.lasso--map-form__footer').append(''); } function updateMarkerField(m) { var tdata = encodeMarkerData(m._latlng.lat, m._latlng.lng, m.options.title); jQuery('input[data-marker="' + m._leaflet_id + '"]').val(tdata); } // encode the information into a string function encodeMarkerData(mlat, mlng, mtitle) { return encodeURIComponent(JSON.stringify({lat: mlat, lng: mlng, title: mtitle})); } // encode location into a string function encodeLocationData(mlat, mlng) { return encodeURIComponent(JSON.stringify({lat: mlat, lng: mlng})); } // decode the information function decodeMarkerData(mdata) { return decodeURIComponent(JSON.parse(mdata)); } } // the code to enable map editing after reload. if ($( ".aesop-map-component" ).length) { $( ".aesop-map-component" ).replaceWith(setComponent("map")); mapsGoTime(); } function setComponent(type) { // if an image is dragged in var comp =""; if (!components[type] || !components[type]['content']) return null; if ( 'wpimg' == type && lasso_editor.oldWPimg) { comp = $(components[type]['content']).prepend( wpImgEdit ); // else it's likely an aesop component } else if ( 'htmlparagraph' != type && 'htmltable' != type) { comp = $(components[type]['content']) .prepend( lassoDragHandle ) .attr({ 'data-component-type': type }); } else { comp = $(components[type]['content']); } return comp; } function postComponent(comp,type) { // set some figures to uneditable $("figure.wp-block-image, figure.lasso--wpimg__wrap").attr('contenteditable',false).attr('readonly',true); // TODO: if a stock wordpress image is dragged in if ('timeline_stop' == type ) { lasso_editor.timelineGoTime() } if ('video' == type ) { videoGoTime() } $('#lasso-side-comp-button').remove(); if ( 'map' == type ) { mapsGoTime(); } else { $(comp).find('.lasso-settings').trigger('click'); } } function imgDialog( ){ var that = this; // Create the media frame. var lasso_file_frame = wp.media.frames.file_frame = wp.media({ title: 'Select Image', button: { text: 'Insert Image', }, multiple: false // Set to true to allow multiple files to be selected }); // When an image is selected, run a callback. lasso_file_frame.on( 'select', function() { var attachment = lasso_file_frame.state().get('selection').first().toJSON(); $(that).parent().data('imgid',''+attachment.id); if ($(that).parent().find('img').length > 0) { $(that).parent().find('img').attr('src', attachment.url ); } else {i $(that).parent().css({ 'background-image': 'url('+ attachment.url +')' }); } // set some figures to uneditable $("figure.wp-block-image, figure.lasso--wpimg__wrap").attr('contenteditable',false).attr('readonly',true); }); // Finally, open the modal lasso_file_frame.open(); }; ///////////////// /// DRAG DROP /////////////////// // recent change: when a new component is dropped, the setting window is opened automatically $('#'+editor).sortable({ opacity: 0.65, placeholder:'lasso-drop-zone', handle: '.lasso-drag', cursor:'move', tolerance:'pointer', refreshPositions: true, helper: function( e, ui ) { // get the curent target and add the type class to the drag event var item = ui['context'], type = $(item).attr('data-component-type'); return $('
      '); }, beforeStop: function (event, ui) { draggedItem = ui.item }, receive: function (event,ui) { // close modal drag $('#lasso-toolbar--components').removeClass('toolbar--drop-up'); articleMedium.makeUndoable(); // get the item and type var item = draggedItem['context']; if (!item) item = draggedItem; var type = $(item).attr('data-type'); // item2 will be the content tthat gets inserted. It also has edit controls // if coming from draggable replace with our content and prepend toolbar if ( origin == 'draggable' ) { // check if it's inserted at the end var newIndex = $(this).data("ui-sortable").currentItem.index(); var sortable_len = $(this).data("ui-sortable").items.length; var last = false; if (newIndex>= (sortable_len-1)) { last = true; } var item2 = setComponent(type); if (last) { item2.append('


      '); } $(item).replaceWith( item2); postComponent(item2,type); } } }); lasso_editor.addComponentButton = function() { // this function checks the current selected element and adds the component button if appropriate if (!lasso_editor.buttonOnEmptyP) { // if this feature is not turned on, return return; } window.selRange = saveSelection(); if (!window.selRange) return; var container = window.selRange.startContainer, containerTag; if ($(container).attr('id') == "lasso--content") { container = $(container).children()[0]; } $('#lasso-side-comp-button').remove(); containerTag = container.localName; parentTag = $(container).parent().prop("tagName"); if ($(container).parent().attr('id') != "lasso--content") { if (parentTag == 'figure' || parentTag == 'div' || $(container).parent().parent().attr('id') != "lasso--content") { return; } } if ( containerTag == 'p' || ((containerTag=='b' || containerTag=='em' || containerTag=='i' || containerTag=='strike' || containerTag=='span') && $(container).parent().text() == "")) { var innerText = container.innerText.replace(/(\r\n|\n|\r)/gm,""); if (innerText != "") { //this paragraph is not empty, return return; } var top_ = container.offsetTop-10; var left_ = container.offsetLeft-30; if ($(container).parent().attr('id') != "lasso--content") { $(container).parent().empty(); } var button = $('
      '); button.css({top:top_,left:left_}); $("#lasso--content").append(button); if (button.offset().left<0) { button.offset({left:0}); } } } // the following codes decide which UI triggers drag-drop and which UI triggers click-insert // If we are only using drag-drop then clickToInsertElement would be empty var clickToInsertElement = '#lasso-side-comp-button #lasso-toolbar--components__list li'; if (lasso_editor.clickToInsert) { clickToInsertElement = '#lasso-toolbar--components__list li' } else { $('#lasso-toolbar--components #lasso-toolbar--components__list li').draggable({ axis:'y', helper:'clone', cursor: 'move', connectToSortable: '#'+editor, start: function(ui) { // add an origin so sortable can detect where comign from origin = 'draggable'; // get the curent target and add the type class to the drag event var item = ui.currentTarget, type = $(item).attr('data-type'); $(this).addClass(type); } }); } jQuery(document).on('mousedown', clickToInsertElement, function(){ var type = $(this).attr('data-type'); var item = setComponent(type); restoreSelection(window.selRange); $('#lasso-side-comp-button').remove(); if ($('#'+editor).children().length==1 && $('#'+editor).find('.editus-firstp').length ==1) { $('.editus-firstp').replaceWith(item); } else { var t = insert_html(item, false); } postComponent(item,type); lasso_editor.addComponentButton(); }); // replace the content if the content is empty if ( $('#'+editor).children().length && $('#'+editor).children().prop("tagName") == "P" && $('#'+editor).children().text() == "") { $('#'+editor).html(lasso_editor.newObjectContent); $('#'+editor).children().focus(); lasso_editor.addComponentButton(); } lasso_editor.hidePopup = function(){ $(".lasso--text-popup").hide(); } lasso_editor.checkForPopup = function() { if (!lasso_editor.toolbarPopup) return; s = window.getSelection(); oRange = s.getRangeAt(0); //get the text range if (!oRange.collapsed ) { oRect = oRange.getBoundingClientRect(); ; oRect2 = document.getElementById(editor).getBoundingClientRect(); oRect3 = document.body.getBoundingClientRect(); var t2 = $('body').offset().top; //var t2 = document.body.offsetTop.getBoundingClientRect().top; var left = ((oRect.right+oRect.left) - $(".lasso--text-popup").width())/2; if (left <= 0) left = 0; var t = oRect.bottom-document.body.getBoundingClientRect().top; $(".lasso--text-popup").css("left",left); $(".lasso--text-popup").css("top",t+t2); $(".lasso--text-popup").css("display","table"); $(".lasso--text-popup").css("position","absolute"); } else { lasso_editor.hidePopup(); } }; $('#'+editor).on('mouseup',function() { lasso_editor.checkForPopup(); }); $('#'+editor).focusout(function() { lasso_editor.hidePopup(); }); // ways to inject codes into the enterEditor if (lasso_editor.enterEditorHookArray2) { $(lasso_editor.enterEditorHookArray2).each(function(key, val){ val(); }); } }); if (lasso_editor.skipToEdit) { $('#lasso--edit').trigger('click'); lasso_editor.skipToEdit = false; } if (lasso_editor.setupHookArray) { $(lasso_editor.setupHookArray).each(function(key, val){ val(); }); } }); ================================================ FILE: public/assets/js/source/modal-sizing.js ================================================ (function( $ ) { // dyanmically center modals vertically based on size of modal jQuery(document).ready(function($){ modalResizer = function(){ var modal = $('.lasso--modal') , mHeight = modal.height() , wHeight = $(window).height() , eHeight = $('.lasso--modal').hasClass('lasso--tour__modal') ? 0 : 30 // this is the height of the submit button that is hidden utnil the user changes a setting modal.css({ 'top' : (wHeight - mHeight - eHeight) / 2 }) } $('.lasso--modal').imagesLoaded( function() { modalResizer(); }) jQuery(window).resize(function(){ modalResizer(); }); }); })( jQuery ); ================================================ FILE: public/assets/js/source/post-settings.js ================================================ (function( $ ) { $(document).ready(function(){ ///////////////// /// MODAL LOGIC /////////////////// // method to destroy the modal var destroyModal = function(){ $('body').removeClass('lasso-modal-open'); $('#lasso--post-settings__modal, #lasso--modal__overlay').remove(); } jQuery(document).on('click', '.lasso--postsettings__option', function(e){ if ($(e.target).hasClass('tagit')) { // close the modal window if the user clicks on empty spaces // destroy posts modal destroyModal(); } }); // modal click //$('#lasso--post-settings').live('click',function(e){ jQuery(document).on('click','#lasso--post-settings, #lasso--post-settings2',function(e){ e.preventDefault(); // add a body class $('body').toggleClass('lasso-modal-open'); // append teh modal markup ( lasso_editor_component_modal() ) $('body').append(lasso_editor.component_modal); ///////////////// /// UI SLIDER INIT AND METHODS /////////////////// var statusReturn = function( value ) { var out; if ( 100 == value ) { out = 'draft'; } else if ( 150 == value ) { out = 'pending'; } else if ( 200 == value ) { out = 'publish'; } else if ( 'draft' == value ) { out = 100; } else if ( 'pending' == value ) { out = 150; } else if ( 'publish' == value ) { out = 200; } return out; } // init slider $('#lasso--slider').slider({ value:statusReturn(lasso_editor.post_status), min: 100, max: 200, step: lasso_editor.supportPendingStatus ? 50 : 100, animate:'fast', slide: function( event, ui ) { $('input[name="status"]').val( statusReturn(ui.value) ); $('.lasso--postsettings__footer').slideDown() if ( 100 == ui.value ) { $('.story-status').removeClass('story-status-publish').addClass('story-status-draft') } else if ( 200 == ui.value ) { $('.story-status').removeClass('story-status-draft').addClass('story-status-publish') } } }); $('input[name="status"]').val( statusReturn( $( "#lasso--slider" ).slider('value') ) ); /*// if any changes happen then show the footer $('.lasso--modal__trigger-footer').on('keyup',function(){ $('.lasso--postsettings__footer').slideDown() });*/ // categories var cats = $('#lasso--cat-select') , tags = $('#lasso--tag-select') , custom = $('#lasso--custom-taxo-input') cats.tagit({ //fieldName:'itemName[fieldName][]', placeholderText: lasso_editor.strings.catsPlaceholder, //'add categories...', availableTags: lasso_editor.postCategories, allowSpaces: true }); cats.on('change',function(event){ $('.lasso--postsettings__footer').slideDown() }) tags.tagit({ //fieldName:'itemName[fieldName][]', placeholderText: lasso_editor.strings.tagsPlaceholder,//'add tags...', availableTags: lasso_editor.postTags, allowSpaces: true }); tags.on('change',function(event){ $('.lasso--postsettings__footer').slideDown() }) if( $('.editus_custom_date').length ) { $('.editus_custom_date').datepicker({}); } if (lasso_editor.supCustTaxo) { var selTaxo = $('#lasso--custom-taxo-select').val(); custom.val(lasso_editor.postCusTaxonomies[selTaxo]); custom.tagit({ placeholderText: lasso_editor.strings.catsPlaceholder,//'add tags...', availableTags: lasso_editor.extCusTaxonomies[selTaxo], allowSpaces: true }); $('#lasso--custom-taxo-select').on('change', function() { lasso_editor.postCusTaxonomies[selTaxo] = custom.val(); custom.tagit("destroy"); custom.val(lasso_editor.postCusTaxonomies[$(this).val()]); custom.tagit({ placeholderText: lasso_editor.strings.taxoPlaceholder, //'add categories...', availableTags: lasso_editor.extCusTaxonomies[$(this).val()], allowSpaces: true }); selTaxo = $(this).val(); }); } modalResizer() }); // destroy modal if clicking close or overlay //$('#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel').live('click',function(e){ jQuery(document).on('click', '#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel', function(e){ e.preventDefault(); destroyModal(); }); ///////////////// /// EXIT SETTINGS /////////////////// $(document).keyup(function(e) { if ( 27 == e.keyCode ) { destroyModal(); } }); ///////////// // SAVE SETTINGS ////////////// var form; //$('#lasso--postsettings__form').live('submit', function(e) { //$('#lasso--postsettings__form').live('submit', function(e) { jQuery(document).on('submit','#lasso--postsettings__form',function(e) { e.preventDefault(); if ($('#lasso--custom-field-form').length ==0 || $('#lasso--custom-field-form').children().length == 0 ) { $('#lasso--save').removeClass('lasso-publish-post'); $('#lasso--save').trigger('click'); } var $this = $(this); /* //alternate way of setting categories, disabled for now var cats = []; $('input[name="categories"]').each(function () { if (this.checked) { cats.push(this.id);} }); if (cats.length>0) { $('input[name="story_cats"]').val(cats.join(',')); }*/ if (lasso_editor.supCustTaxo) { var selTaxo = $('#lasso--custom-taxo-select').val(); lasso_editor.postCusTaxonomies[selTaxo] = $('#lasso--custom-taxo-input').val(); $(this).find("input[name=story_custom_taxonomies]" ).val(JSON.stringify(lasso_editor.postCusTaxonomies)); } $(this).find('input[type="submit"]').val(lasso_editor.strings.saving); var data2 = $this.serialize(); ///////////// // DO THE SAVE ///////////// var data = { action: 'editus_set_post_setting', postid: lasso_editor.postid, data: data2 }; $.post( lasso_editor.ajaxurl2, data, function(response) { if( true == response.success ) { $('input[type="submit"]').addClass('saved'); $('input[type="submit"]').val(lasso_editor.strings.saved); window.onbeforeunload = null; if ($('#lasso--custom-field-form').length && $('#lasso--custom-field-form').children().length) { $('#lasso--custom-field-form').trigger('submit'); setTimeout(function() { window.location.replace(response.data['link']); }, 1000); } else { // changing the setting can potentially change the URL of the post. In that case we need to // reload the post window.location.replace(response.data['link']); } } else { alert('error:'+response); console.log(response) } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); ///////////// // ADDON TABS ////////////// $(document).on('click', '.lasso--modal__tabs li', function(e){ e.preventDefault() var $this = $(this) , name = $this.data('addon-name') , rem = 'not-visible' , add = 'visible' $('.lasso--modal__tabs li').removeClass('active-tab') $this.addClass('active-tab') $('.lasso--modal__content').removeClass( add ).addClass( rem ) $this.closest('.lasso--modal__inner').find('div[data-addon-content="'+name+'"]').removeClass( rem ).addClass( add ) modalResizer() }) }); })( jQuery ); ================================================ FILE: public/assets/js/source/process-gallery-opts.js ================================================ (function( $ ) { $(document).ready(function($){ // this function is repeated on settings-panel.js var value_check = function( value ){ if ( 'grid' == value ) { $('.ase-gallery-opts--thumb').fadeOut(); $('.ase-gallery-opts--photoset').fadeOut(); $('.ase-gallery-opts--hero').fadeOut(); $('.ase-gallery-opts--grid').fadeIn(); } else { $('.ase-gallery-opts--grid').fadeOut(); } if ( 'thumbnail' == value ) { $('.ase-gallery-opts--grid').fadeOut(); $('.ase-gallery-opts--photoset').fadeOut(); $('.ase-gallery-opts--hero').fadeOut(); $('.ase-gallery-opts--thumb').fadeIn(); } else { $('.ase-gallery-opts--thumb').fadeOut(); } if ( 'photoset' == value ) { $('.ase-gallery-opts--grid').fadeOut(); $('.ase-gallery-opts--thumb').fadeOut(); $('.ase-gallery-opts--hero').fadeOut(); $('.ase-gallery-opts--photoset').fadeIn(); } else { $('.ase-gallery-opts--photoset').fadeOut(); } if ( 'hero' == value ) { $('.ase-gallery-opts--grid').fadeOut(); $('.ase-gallery-opts--thumb').fadeOut(); $('.ase-gallery-opts--photoset').fadeOut(); $('.ase-gallery-opts--hero').fadeIn(); } else { $('.ase-gallery-opts--hero').fadeOut(); } } $('.ase-gallery-type-radio').each(function(){ if ( $(this).is(':checked') ) { $(this).parent().addClass('selected'); var value = $(this).val(); value_check(value); } }); //$('.ase-gallery-layout-label').live('click',function(){ jQuery(document).on('click','.ase-gallery-layout-label', function(){ $('.ase-gallery-layout-label').removeClass('selected'); $(this).addClass('selected'); var value = $(this).find('input').val(); value_check(value); // add the type to a hidden field $('#ase_gallery_type').val( value ) }); }) })( jQuery ); ================================================ FILE: public/assets/js/source/process-gallery.js ================================================ (function( $ ) { 'use strict'; ///////////// // NEW GALLERY CREATE //////////// //$('#lasso--gallery__create').live('click',function(e){ jQuery(document).on('click','#lasso--gallery__create',function(e){ e.preventDefault(); $(this).closest('form').addClass('creating-gallery'); $('.ase-gallery-opts--create-gallery2').fadeIn(); $('.ase-gallery-opts--edit-gallery').fadeOut(1); $('#ase-gallery-images li').remove(); $('#lasso--gallery__create').remove(); $('.ase-gallery-opts--edit-gallery').text(lasso_editor.strings.addNewGallery); $('.ase-gallery-opts--edit-gallery .lasso-option-desc').text('Select new images to create a gallery with.'); }); ///////////// // NEW GALLERY UPLOAD //////////// var file_frame; var gallery = $('#ase-gallery-images'); //$(document).on('click', '#lasso--gallery__selectImages', function( e ){ jQuery(document).on('click','#lasso--gallery__selectImages',function( e ){ e.preventDefault(); // If the media frame already exists, reopen it. if ( file_frame ) { file_frame.open(); return; } // Create the media frame. file_frame = wp.media.frames.file_frame = wp.media({ title: lasso_editor.strings.chooseImages, button: { text: lasso_editor.strings.addImages, }, multiple: true // Set to true to allow multiple files to be selected }); // When an image is selected, run a callback. file_frame.on( 'select', function() { var attachments = file_frame.state().get('selection'); if (!attachments) { return; } // loop through and insert the new items attachments.each( function( attachment ) { var id = attachment.id; var url = attachment.attributes.sizes.thumbnail.url; ase_insert_gallery_item(id, url); }); // insert the new ids from new gallery var ids = attachments.map( function( attachment ) { var attachment = attachment.toJSON(); return attachment.id; }).join(','); // populate gallery input with ids $('#ase_gallery_ids').val( ids ); // show the save button $('.has-galleries > #lasso--gallery__save').fadeIn(); // remove the select images button $('#lasso--gallery__selectImages').remove(); }); // Finally, open the modal file_frame.open(); }); ////////// // NEW GALLERY SWAP ////////// //$('.lasso-gallery-id #aesop-generator-attr-id').live('change',function(){ jQuery(document).on('change','.aesop-gallery-id #aesop-generator-attr-id',function(){ editus_gallery_swap($(this).val()); var data2 = { action: 'process_gallery_get-images', post_id: $(this).val(), nonce: lasso_editor.getGallImgNonce }; // post ajax response with data $.post( lasso_editor.ajaxurl, data2, function(response) { $('#lasso--gallery__images').html( response.data.html ); ///////////// // CALL SORTABLE ON RECIEVED IMAGES ///////////// var gallery = $('#ase-gallery-images'); gallery.ready(function(){ gallery.sortable({ containment: 'parent', cursor: 'move', opacity: 0.8, placeholder: 'ase-gallery-drop-zone', forcePlaceholderSize:true, update: function(){ var imageArray = $(this).sortable('toArray'); $('#ase_gallery_ids').val( imageArray ); }, create: function(){ var imageArray = $(this).sortable('toArray'); $('#ase_gallery_ids').val( imageArray ); } }); window.component.find('.lasso-component--settings__trigger').trigger('click'); }); }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); function editus_gallery_swap(galleryID){ var data = { componentType: 'gallery', id: galleryID }; window.get_aesop_component_ajax(data); } /////////// // EDIT GALLERY // the sortsble instat is in settingspanel.js /////////// // deleting gallery items $(document).on('click', '.ase-gallery-image > i.dashicons-no-alt', function(){ $(this).parent().remove(); gallery.sortable('refresh'); ase_encode_gallery_items(); }); function ase_string_encode(gData){ return encodeURIComponent(JSON.stringify(gData)); } function ase_string_decode(gData){ return JSON.parse(decodeURIComponent(gData)); } function ase_encode_gallery_items(){ gallery = $('#lasso--gallery__images #ase-gallery-images'); if (gallery.length) { var imageArray = gallery.sortable('toArray'); $('#ase_gallery_ids').val( imageArray ); } } // inserting gallery items function ase_insert_gallery_item(id, url){ var item_html = ""; $('#ase-gallery-images').append( item_html ); gallery.sortable('refresh'); ase_encode_gallery_items(); } // adding additiona images to existing gallery var clicked_button = false; $(document).on('click', '#ase-gallery-add-image', function (event) { event.preventDefault(); var selected_img; clicked_button = $(this); if(wp.media.frames.ase_frame) { wp.media.frames.ase_frame.open(); return; } wp.media.frames.ase_frame = wp.media({ title: lasso_editor.strings.selectGallery, multiple: true, library: { type: 'image' }, button: { text: lasso_editor.strings.useSelectedImages } }); var ase_media_set_image = function() { var selection = wp.media.frames.ase_frame.state().get('selection'); if (!selection) { return; } selection.each(function(attachment) { var id = attachment.id; var url = attachment.attributes.sizes.thumbnail.url; ase_insert_gallery_item(id, url); }); }; wp.media.frames.ase_frame.on('select', ase_media_set_image); wp.media.frames.ase_frame.open(); }); // editing a single image function ase_edit_gallery_item(id, url, editable){ var item_html = ""; $(editable).replaceWith( item_html ); gallery.sortable('refresh'); ase_encode_gallery_items(); } // edit single image var ase_media_edit_init = function() { var clicked_button; $(document).on('click', '.ase-gallery-image > i.dashicons-edit', function(event){ event.preventDefault(); var selected_img; clicked_button = $(this); if(wp.media.frames.ase_edit_frame) { wp.media.frames.ase_edit_frame.open(); return; } wp.revisions wp.media.frames.ase_edit_frame = wp.media({ title: lasso_editor.strings.editImage, multiple: false, library: { type: 'image' }, button: { text: lasso_editor.strings.updateSelectedImg } }); var ase_media_edit_image = function() { var selection = wp.media.frames.ase_edit_frame.state().get('selection'); if (!selection) { return; } // iterate through selected elements selection.each(function(attachment) { var id = attachment.id; var url = attachment.attributes.sizes.thumbnail.url; ase_edit_gallery_item(id, url, clicked_button.parent()); }); }; // image selection event wp.media.frames.ase_edit_frame.on('select', ase_media_edit_image); wp.media.frames.ase_edit_frame.on('open',function(){ var selection = wp.media.frames.ase_edit_frame.state().get('selection'); var attachment = wp.media.attachment( clicked_button.parent().attr('id') ); attachment.fetch(); selection.add( attachment ? [ attachment ] : [] ); }); wp.media.frames.ase_edit_frame.open(); }); }; //ase_media_init('#ase-gallery-add-image', 'i'); ase_media_edit_init(); ase_encode_gallery_items(); })( jQuery ); ================================================ FILE: public/assets/js/source/process-image-upload.js ================================================ (function( $ ) { 'use strict'; //$( '#lasso--featImgSave a' ).live('click', function(e) { jQuery(document).on('click', '#lasso--featImgSave a', function(e){ e.preventDefault(); var $this = $(this) , saveStatus = $('#lasso--save-status') var data = { action: 'editus_featured_img', postid: lasso_editor.postid, image_id: $this.data('featimg-id'), nonce: lasso_editor.featImgNonce } saveStatus.removeClass('not-visible').addClass('visible lasso--animate__spin'); $.post( lasso_editor.ajaxurl2, data, function(response) { if ( response ) { console.log('response') $('#lasso--featImgSave').css('opacity',0); //setTimeout(function(){ // saveStatus.removeClass('lasso--animate__spin lasso-icon-check').addClass('lasso-icon-spinner6 not-visible') //},500); } saveStatus.removeClass('lasso--animate__spin lasso-icon-spinner6').addClass('lasso-icon-check'); }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); saveStatus.removeClass('lasso--animate__spin lasso-icon-spinner6').addClass('lasso-icon-check'); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); ///////////// // FILE UPLOAD //////////// var file_frame; var className; $(document).on('click', '#lasso--featImgUpload > a', function( e ){ e.preventDefault(); className = e.currentTarget.parentElement.className; var save = $('#lasso--featImgSave a') // If the media frame already exists, reopen it. if ( file_frame ) { file_frame.open(); return; } // Create the media frame. file_frame = wp.media.frames.file_frame = wp.media({ title: lasso_editor.strings.chooseImage, button: { text: lasso_editor.strings.updateImage, }, multiple: false // Set to true to allow multiple files to be selected }); // When an image is selected, run a callback. file_frame.on( 'select', function() { var attachment = file_frame.state().get('selection').first().toJSON(); $('body').addClass('lasso--post-thumb-applied'); $('article').removeClass('no-post-thumbnail').addClass('has-post-thumbnail'); if ( $(lasso_editor.featImgClass).is( "img" ) ) { $(lasso_editor.featImgClass).prop("src",attachment.url); $(lasso_editor.featImgClass).prop("srcset",""); } else { $(lasso_editor.featImgClass).css({ 'background-image': 'url('+attachment.url+')' }); } save.attr('data-featimg-id',attachment.id).trigger('click'); $('.no-post-cover-note').remove(); }); // Finally, open the modal file_frame.open(); }); //////////// // FEAT IMAGE DELETE //////////// $(document).on('click', '#lasso--featImgDelete > a', function( e ){ e.preventDefault(); var $this = $(this); var data = { action: 'editus_del_featured_img', postid: lasso_editor.postid, nonce: lasso_editor.featImgNonce } swal({ title: lasso_editor.strings.removeFeatImg, type: "warning", text: false, showCancelButton: true, confirmButtonColor: "#d9534f", confirmButtonText: lasso_editor.strings.deleteYes, closeOnConfirm: true }, function(){ $.post( lasso_editor.ajaxurl2, data, function(response) { if ( "" == response ) { // add a body class so we can do whatever with $('body').addClass('lasso--post-thumb-removed'); $('article').removeClass('has-post-thumbnail').addClass('no-post-thumbnail'); // add the hidden class to control shell to allow for delete button $('#lasso--featImgDelete').addClass('lasso--featImg--controlHidden'); $this.closest('ul').removeClass('lasso--featImg--has-thumb'); // remove the attr src - just a real-time update if ( $(lasso_editor.featImgClass).is( "img" ) ) { $(lasso_editor.featImgClass).attr("src",""); } else { $(lasso_editor.featImgClass).css({ 'background-image': 'url()' }); } } }); }); }); //////////// // FEAT IMAGE FROM SETTINGS - @since 0.9.4 //////////// var featimg_frame; $(document).on('click', '#lasso--post-thumb__add', function( e ){ e.preventDefault(); var $this = $(this) , save = $('#lasso--featImgSave a') // If the media frame already exists, reopen it. if ( featimg_frame ) { featimg_frame.open(); return; } // Create the media frame. featimg_frame = wp.media.frames.featimg_frame = wp.media({ title: lasso_editor.strings.chooseImage, button: { text: lasso_editor.strings.updateImage, }, multiple: false // Set to true to allow multiple files to be selected }); // When an image is selected, run a callback. featimg_frame.on( 'select', function() { var attachment = featimg_frame.state().get('selection').first().toJSON(); var pic = $this.closest('.lasso--post-thumb').find('img'); pic.attr('src', attachment.url ); save.attr('data-featimg-id',attachment.id).trigger('click'); $('#lasso--postsettings__form').removeClass('no-thumbnail').addClass('has-thumbnail'); pic.removeAttr("srcset"); noWarningReload = true; }); // Finally, open the modal featimg_frame.open(); }).on('click', '#lasso--post-thumb__delete', function( e ){ e.preventDefault(); var $this = $(this); var data = { action: 'editus_del_featured_img', postid: lasso_editor.postid, nonce: lasso_editor.featImgNonce } swal({ title: lasso_editor.strings.removeFeatImg, type: "warning", text: false, showCancelButton: true, confirmButtonColor: "#d9534f", confirmButtonText: lasso_editor.strings.deleteYes, closeOnConfirm: true }, function(){ $.post( lasso_editor.ajaxurl2, data, function(response) { if ( "" == response ) { var defaultImg = $this.closest('.lasso--post-thumb').data('default-thumb'); $this.closest('.lasso--postsettings__left').find('img').attr('src', defaultImg ); $this.closest('.lasso--postsettings__left').find('img').removeAttr("srcset"); $('#lasso--postsettings__form').removeClass('has-thumbnail').addClass('no-thumbnail') noWarningReload = true; } }); }); }); })( jQuery ); ================================================ FILE: public/assets/js/source/process-map.js ================================================ (function( $ ) { var form; //$('#lasso--map-form').live('submit', function(e) { jQuery(document).on('submit','#lasso--map-form',function(e) { e.preventDefault(); var $this = $(this); $(this).find('input[type="submit"]').val('Saving...').addClass('being-saved'); var data = $this.serialize(); ///////////// // DO TEH SAVE ///////////// $.post( lasso_editor.ajaxurl, data, function(response) { if ( true == response.success ) { $this.find('input[type="submit"]').val('Saved'); $this.removeClass('being-saved').addClass('lasso--saved'); setTimeout(function(){ $this.find('input[type="submit"]').val('Save Locations').removeClass('lasso-saved'); },1200); } else { $this.removeClass('being-saved').addClass('lasso--error'); } }); }); })( jQuery ); ================================================ FILE: public/assets/js/source/process-new-post.js ================================================ (function( $ ) { $(document).ready(function(){ // method to destroy the modal var destroyModal = function(){ $('body').removeClass('lasso-modal-open' ); $('.lasso--modal, #lasso--modal__overlay').remove(); if (noWarningReload) { location.reload(); } } // modal click //$('#lasso--post-new').live('click',function(e){ jQuery(document).on('click','#lasso--post-new',function(e){ e.preventDefault(); // add a body class $('body').toggleClass('lasso-modal-open'); // append teh modal markup ( lasso_editor_component_modal() ) $('body').append(lasso_editor.newPostModal); // if any changes happen then show the footer $('.lasso--modal__trigger-footer').on('keyup',function(){ $('.lasso--postsettings__footer #lasso--postsettings-create').slideDown() }); modalResizer() }); // destroy modal if clicking close or overlay //$('#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel').live('click',function(e){ jQuery(document).on('click','#lasso--modal__close, #lasso--modal__overlay, .lasso--postsettings-cancel',function(e){ e.preventDefault(); destroyModal(); }); jQuery(document).on('click', '#lasso--postsettings-setnow', function(e){ $('.editus_custom_date').datepicker( "setDate", new Date().setTime(Date.now()) ); }); ///////////////// /// EXIT SETTINGS /////////////////// $(document).keyup(function(e) { if ( 27 == e.keyCode ) { destroyModal(); } }); ///////////// // MAKE NEW POST OBJECT ////////////// var form; //$('#lasso--postnew__form').live('submit', function(e) { jQuery(document).on('submit', '#lasso--postnew__form', function(e){ e.preventDefault(); var $this = $(this); $(this).find('input[type="submit"]').val(lasso_editor.strings.adding); if (lasso_editor.saveusingrest) { // Use REST API var data2 = $this.serializeArray().reduce(function(obj, item) { obj[item.name] = item.value; return obj; }, {}); newPostREST(data2.story_title, data2.object,lasso_editor.newObjectContent); } else { var data = $this.serialize(); ///////////// // DO TEH SAVE ///////////// $.post( lasso_editor.ajaxurl, data, function(response) { if ( true == response.success ) { $('input[type="submit"]').addClass('saved'); $('input[type="submit"]').val(lasso_editor.strings.added); window.location.replace(response.link+'&preview=true'); } else { alert('error'); } }); } }); }); function newPostREST(title_, type_,content_){ var data = { title: title_, content: content_, status: "draft" }; if (lasso_editor.currCat !== null) { data.categories = $.map( lasso_editor.currCat, function( a ) { return a.term_id; }); } var type; if (type_=="post") { type = "posts"; } else if (type_=="page"){ type = "pages"; } else { type = type_; } $.ajax({ method: "POST", url: lasso_editor.rest_root + 'wp/v2/'+type, data: data, beforeSend: function ( xhr ) { xhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce ); }, success : function( response ) { $('input[type="submit"]').addClass('saved'); $('input[type="submit"]').val(lasso_editor.strings.added); window.location.replace(response.link+'&preview=true'); }, error : function (xhr, exception) { alert("AJAX Error: "+xhr.responseText ); } }); } ///////////// // POST OBJECT CHANGE - since 0.9.5 ///////////// //$('#lasso--select-type').live('change',function() { jQuery(document).on('change', '#lasso--select-type', function(){ var val = $(this).val() $('input[name="object"]').val( val ) $(this).closest('.story-slug-option').find('label span:not(.lasso-util--help)').text( val ) }); })( jQuery ); ================================================ FILE: public/assets/js/source/process-save-component.js ================================================ (function( $ ) { var form; // get updated aesop componets through ajax calls (global function) window.get_aesop_component_ajax = function(cdata) { var data = { action: 'get_aesop_component', code: 'aesop_'+cdata['componentType'] }; for ( var index in cdata ) { // Don't accept componentType as a param if ( !cdata.hasOwnProperty(index) || index == 'componentType' || index =='sortableItem') { continue; } data[index] = cdata[index]; } jQuery.post(lasso_editor.ajaxurl2, data, function(response) { if( response ){ response = response.replace(/\\'/g, "'"); var $a = $(response); window.component.replaceWith($a); window.component = $a; if ($('.fotorama').length){ $('.fotorama').fotorama(); } if ($('.aesop-gallery-photoset').length){ $(window).trigger( 'load' ); } lasso_editor.wrapImg(); $('.aesop-component').each(function(){ if ($(this).css("height")=="0px") { $(this).css("height","auto"); } // if there's no toolbar present if ( !$(this).find('.lasso-component--toolbar').length > 0 ) { // if this is a map then we need to first wrap it so that we can drag the map around if ( $(this).hasClass('aesop-map-component') ) { var $this = $(this) // so wrap it with a aesop-compoentn aesop-map-component div // @todo - note once a map is inserted it can't be edited after saving again. a user has to delete the existin map and add a new map // to //$this.wrap('').before( lassoDragHandle ).after( lassoMapForm ); $this.wrap('
      ').before( lassoDragHandle ); } else { $(this).append( lasso_editor.handle ); } } }); if ('video' == cdata['componentType']) { $('.aesop-video-component').fitVids(); } if ('gallery' == cdata['componentType']) { get_aesop_options('gallery'); } if ('gallery_pop' == cdata['componentType']) { get_aesop_options('gallery_pop'); } if ('timeline_stop' == cdata['componentType']) { lasso_editor.timelineGoTime(); } // set some figures to uneditable $("figure.wp-block-image, figure.lasso--wpimg__wrap").attr('contenteditable',false).attr('readonly',true); lasso_editor.dirtyByComponent = true; } else { alert("error"); } }); } //reload aesop component options function get_aesop_options(comp) { var data = { action: 'editus_get_ase_options', component: comp }; jQuery.post(lasso_editor.ajaxurl2, data, function(response) { if( response ){ lasso_editor.component_options[comp] = response; } else { alert("error"); } }); } //$('#lasso--component-settings-form').live('submit', function(e) { //jQuery(document).on('submit', '#lasso--component-settings-form', function(e){ jQuery(document).on('submit', '#aesop-generator-settings', function(e){ e.preventDefault(); e.stopImmediatePropagation(); // store some atts var $component = window.component , cdata = $component.data() , saveInsert = $('#lasso-generator-insert') , form = $('#lasso--component-settings-form') , $this = $(this); // let people know something is happening saveInsert.val(lasso_editor.strings.saving); // send the new settings to the component and update it's data attributes $this.find('.lasso-generator-attr').each(function(){ var optionName = $(this).closest('.lasso-option').data('option'); // save even if the entry is blank //if ( '' !== $(this).val() ) { //$component.attr( 'data-' + optionName, $(this).val() ); $component.prop( 'data-' + optionName, $(this).val() ); $component.data(optionName, $(this).val() ); //} }); // return the data attributes as field for the sortable item var cleanFields = function( cdata ){ delete cdata['sortableItem']; return cdata; } /** * * Build a sequence that saves, adds a class, and removs the sidebar * @param stall bool should we stall on save? typically used for all but the gallery component which runs an ajax call * @param timeout int how long should we timeout before removing the settings sidebar * @param gallery bool is this a gallery creation? otherwise let's mod the label */ var saveSequence = function( stall, timeout, gallery ){ // add a saved class then change the save label to saved var saveActions = function(gallery){ saveInsert.addClass('saved'); if ( true == gallery ) { saveInsert.val(lasso_editor.strings.galleryCreated); } else { saveInsert.val(lasso_editor.strings.saved); } } if ( true == stall ) { setTimeout( function(){ saveActions(); }, 500 ); } else if ( true == gallery ) { //form.addClass('hide-all-fields').prepend('
      Gallery Created! Save your post and refresh the page to access this new gallery.
      ') setTimeout( function(){ saveActions(true); }, 500 ); } else { saveActions(); } setTimeout( function(){ $('body').removeClass('lasso-sidebar-open'); }, timeout ); articleMedium.makeUndoable(); lasso_editor.dirtyByComponent = true; } // make an ajax call to deal with gallery saving or creating only if it's a gallery if ( 'gallery' == cdata['componentType'] ) { var data = { action: $('.ase-gallery-opts--create-gallery2').is(":visible") ? 'editus_create_gallery' : 'editus_update_gallery', postid: cdata['id'], unique: cdata['unique'], fields: cleanFields(cdata), gallery_type: $('#ase_gallery_type').val(), gallery_ids: $('#ase_gallery_ids').val(), nonce: $('#lasso-generator-nonce').val() } if ($('.ase-gallery-opts--create-gallery2').is(":visible")) { data['edgallerytitle'] = document.getElementById("lasso--gallery__galleryname").value; } $.post( lasso_editor.ajaxurl2, data, function(response) { retData = JSON.parse(response); if ( 'gallery-created' == retData["message"] ) { saveSequence( false, 1000, true ); // load the new gallery cdata['id'] = retData["id"]; } else if ( 'gallery-updated' == retData["message"] ) { saveSequence( false, 1000 ); form.before(lasso_editor.refreshRequired); } else { alert( 'error' ); } window.get_aesop_component_ajax(cdata); }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); } else { saveSequence( true, 1200 ); } if ( 'image' == cdata['componentType'] || 'quote' == cdata['componentType'] || 'parallax' == cdata['componentType'] || 'chapter' == cdata['componentType'] || 'video' == cdata['componentType'] || 'character' == cdata['componentType'] || 'collection' == cdata['componentType'] || 'audio' == cdata['componentType']) { window.get_aesop_component_ajax(cdata); } else if ('content' == cdata['componentType']) { var inner = component.find('.aesop-component-content-data'); if ( inner.length != 0 ) { cdata['content_data'] = inner[0].innerHTML; } window.get_aesop_component_ajax(cdata); } /*else if ('events' == cdata['componentType']) { //aesop events alert("Save and Reload the page to see the update."); }*/ else { window.get_aesop_component_ajax(cdata); } }); })( jQuery ); ================================================ FILE: public/assets/js/source/process-save-meta.js ================================================ (function( $ ) { $(document).on('submit', '#lasso--custom-field-form', function(e) { e.preventDefault(); $('#lasso--save').trigger('click'); var $this = $(this) , submit = $this.find('input[type="submit"]') , strings = lasso_editor.strings , data = $this.serialize(); submit.val( strings.saving ); $.post( lasso_editor.ajaxurl, data, function(response) { if( true == response.success ) { submit.val( strings.saved ).addClass('saved'); /*console.log(response) setTimeout(function(){ submit.removeClass('saved'); submit.val( strings.save ); },1000);*/ location.reload(); } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); })( jQuery ); ================================================ FILE: public/assets/js/source/process-save-title.js ================================================ (function( $ ) { $(document).ready(function(){ ///////////// // SAVE TITLE ///////////// $(lasso_editor.titleClass).on('blur', function() { var target = $(this); var data = { action: 'process_title-update_post', postid: lasso_editor.postid, title: $.trim( target.text() ), nonce: lasso_editor.titleNonce } ///////////// // UPDATE THE TITLE ///////////// $.post( lasso_editor.ajaxurl, data, function(response) { if ( true == response.success ) { var saveClass = 'lasso-title-saved'; target.addClass(saveClass); setTimeout(function(){ target.removeClass(saveClass); },500); } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); }); })( jQuery ); ================================================ FILE: public/assets/js/source/process-save.js ================================================ jQuery(document).ready(function($){ var ajaxurl = lasso_editor.ajaxurl, save = $('.lasso--controls__right a'), editor = lasso_editor.editor, postid = lasso_editor.postid, oldHtml = $('#'+editor).html(), warnNoSave = 'You have unsaved changes!'; // Set to true when we want to reload the current page without a warning message noWarningReload = false; /////////////////////// // 1. IF UNSAVED CHANGES STORE IN LOCAL STORAGE // @todo - need to account for component on the page this only accounts for text /////////////////////// //$('#'+editor).live('change',function(){ jQuery(document).on('change', '#'+editor, function(){ var $this = $(this), newHtml = $this.html(); if ( oldHtml !== newHtml ) { localStorage.setItem( 'lasso_backup_'+postid , newHtml ); } }); /////////////////////// // 2. WARN THE USER IF THEY TRY TO NAVIGATE AWAY WITH UNSAVED CHANGES /////////////////////// window.onbeforeunload = function () { if ( localStorage.getItem( 'lasso_backup_'+postid ) && lasso_editor.userCanEdit ) { return warnNoSave; $('#lasso--save').css('opacity',1); } } // but also clear the unsaved changes if the user does navigate away window.onunload = function () { if ( localStorage.getItem( 'lasso_backup_'+postid ) && lasso_editor.userCanEdit ) { localStorage.clear(); } } /*function process_html(html, do_shortcodify) { // take care of twitter widget html = process_twitter(html); // remove objects to ignore if they are not removed already if (lasso_editor.showIgnoredItems ) { var $temp = $('
      ').html( html ); $temp.find(lasso_editor.objectsNoSave).remove(); $temp.find(lasso_editor.supportedNoSave).remove(); html = $temp.html(); } // remove extra classes { var $temp = $('
      ').html( html ); $temp.find("a").removeClass("lasso-link"); $temp.find("span").removeClass("lasso-span"); $temp.find("h2").removeClass("lasso-h2"); $temp.find("h3").removeClass("lasso-h3"); $temp.find(".lasso-noclass").removeClass("lasso-noclass"); $temp.find(".lasso-undeletable").removeClass("lasso-undeletable"); $temp.find(".lasso-component--controls, .aesop-events-edit").remove(); $temp.find('*[class=""]').removeAttr('class'); html = $temp.html(); } // remove all contenteditable attr html = removeEditable(html); // if custom fields if (lasso_editor.customFields) { saveCustomFields(html); } // shortcode ultimate html = shortcodify_su(html); // shortcode aesop html = do_shortcodify ? shortcodify(html) : html; // restore other shortcodes to the original shortcodes html = replace_rendered_shortcodes( html ); // avia editor if (lasso_editor.aviaEditor) { html = shortcodify_avia(html); } // WordPress Block if (lasso_editor.hasGutenberg) { html = process_gutenberg(html); } // if multi page if (lasso_editor.multipages != "-1") { var res = lasso_editor.post_content.split(""); var html2 = ""; res[parseInt(lasso_editor.multipages)] = html; html = res.join(""); } // any user supplied filters if (lasso_editor.filterArray) { $(lasso_editor.filterArray).each(function(key, val){ html = val(html ); }); } return html }*/ /////////////////////// // 3. SAVE OR PUBLISH OBJECT /////////////////////// //$('.lasso--controls__right a:not(#lasso--exit)').live('click',function(e) { //jQuery(document).on('click', '.lasso--controls__right a:not(#lasso--exit)', function(e){ //jQuery('.lasso--controls__right a:not(#lasso--exit)').on('click', function(e){ jQuery(document).on('click','#lasso--save, #lasso--publish', function(e){ var warnNoSave = null; e.preventDefault(); // sore reference to this var $this = $(this); // unwrap wp images /*$(".lasso--wpimg__wrap").each(function(){ //if ( !$(this).hasClass('wp-caption') ) { // $(this).children().unwrap() //} $('.lasso-component--controls').remove(); }); // unwrap custom components $('.lasso-component').each(function(){ $('.lasso-component--controls').remove(); });*/ // unwrap map from hits drag holder $('#lasso--map-form').each(function(){ var $this = $(this) $this.find('.lasso-component--controls, .lasso--map-form__footer ').remove() $this.children().unwrap() }); // if tehre are any scrollnav sections we need to break them open so the editor doesnt save the html $('.scroll-nav__section').each(function(){ $(this).children().unwrap(); }) // remove any notices $('#lasso--notice').remove(); //remove any comp buttons $('#lasso-side-comp-button').remove(); $('.lasso--text-popup').remove(); // let user know someting is happening on click $(this).addClass('being-saved'); // get the html from our div var html = $('#'+editor).html(), postid = lasso_editor.postid; if (!html) return; html = process_html(html, $this.hasClass('shortcodify-enabled')); // gather the data var data = { action: ($this.hasClass('lasso-publish-post') && lasso_editor.can_publish) ? 'process_save_publish-content' : 'process_save_content', author: lasso_editor.author, content: html, post_id: postid, nonce: lasso_editor.nonce }; // intercept if publish to confirm if ( $this.hasClass('lasso-publish-post') ) { if (lasso_editor.publishHandler) { // custom publish handler lasso_editor.publishHandler(data); } else { swal({ title: lasso_editor.strings.publishPost, type: "info", text: false, showCancelButton: true, confirmButtonColor: "#5bc0de", confirmButtonText: lasso_editor.strings.publishYes, closeOnConfirm: true }, function(){ runSavePublish(true) }); } } else { runSavePublish(false) } function process_html(html, do_shortcodify) { // take care of twitter widget html = process_twitter(html); // remove objects to ignore if they are not removed already if (lasso_editor.showIgnoredItems ) { var $temp = $('
      ').html( html ); $temp.find(lasso_editor.objectsNoSave).remove(); $temp.find(lasso_editor.supportedNoSave).remove(); html = $temp.html(); } // remove extra classes { var $temp = $('
      ').html( html ); $temp.find("a").removeClass("lasso-link"); $temp.find("span").removeClass("lasso-span"); $temp.find("h2").removeClass("lasso-h2"); $temp.find("h3").removeClass("lasso-h3"); $temp.find(".lasso-noclass").removeClass("lasso-noclass"); $temp.find(".editus-firstp").removeClass("editus-firstp"); $temp.find(".lasso-undeletable").removeClass("lasso-undeletable"); $temp.find(".lasso-component--controls, .aesop-events-edit").remove(); $temp.find('*[class=""]').removeAttr('class'); //process $temp.find("span#more-"+lasso_editor.postid).replaceWith( "" ); html = $temp.html(); } // remove all contenteditable attr html = removeEditable(html); // if custom fields if (lasso_editor.customFields) { saveCustomFields(html); } // WordPress Block if (lasso_editor.hasGutenberg) { const reg = /]*>

      ","-->"); html = process_gutenberg(html); } //shortcodes { // shortcode ultimate //html = shortcodify_su(html); // restore other shortcodes to the original shortcodes html = replace_rendered_shortcodes( html ); // shortcode aesop html = do_shortcodify ? shortcodify(html) : html; // avia editor if (lasso_editor.aviaEditor) { html = shortcodify_avia(html); } } // if multi page if (lasso_editor.multipages != "-1") { var res = lasso_editor.post_content.split(""); var html2 = ""; res[parseInt(lasso_editor.multipages)] = html; html = res.join(""); } // any user supplied filters if (lasso_editor.filterArray) { $(lasso_editor.filterArray).each(function(key, val){ html = val(html ); }); } return html } function removeComment(content) { return content.replace(//g, ""); } function removeEditable(content) { return content.replace(/contenteditable="(false|true)"/g, ""); } // gather the custom field data and save to lasso_editor.cftosave function saveCustomFields(content) { var data ={}; var customFields = lasso_editor.customFields; for (var key in customFields) { var selector =''; var html = false; var isimgurl = false; if (typeof(lasso_editor.customFields[key]) == 'object') { selector = customFields[key]['selector']; html = customFields[key]['html']; isimgurl = customFields[key]['imgurl']; } else { selector =customFields[key]; } var arr = $(document).find(selector); if (arr.length) { if (html) { data[key] = arr[0].innerHTML.replace(/[\n\r]/g, '');; } else if (isimgurl) { data[key] = $(arr[0]).attr('src'); } else { data[key] = arr[0].innerText;//.replace(/[\n\r]/g, ''); } } } lasso_editor.cftosave = data; } /** * Turn content html into shortcodes * @param {[type]} content [description] * @param {[type]} selector [description] * @return {[type]} [description] */ function shortcodify(content,selector){ // Convert the html into a series of jQuery objects var j = $.parseHTML(content); var processed = ''; if (j == null) { return content; } // Iterate through the array of dom objects for (var i = 0; i < j.length; i++) { var component = $(j[i]); // If it's not a component, move along if ( !component.hasClass('aesop-component') ) { if(component.find('.aesop-component').length !== 0) { // if there is an aesop component in a child, recursively process it var comp_content = component.html(); comp_content = shortcodify(comp_content); component.html(comp_content); processed += component.clone().wrap('

      ').parent().html();; } else // Let's test what kind of object it is if ( component.context && component.context.nodeType == 3 ) { // Text only object without dom processed += j[i].data; } else if ( (component.context && component.context.nodeType == 8) || j[i].nodeType==8) { processed += ''; } else { // DOM object if (j[i].outerHTML) { processed += j[i].outerHTML; } else if (j[i].data){ processed += j[i].data; } } continue; } var data = component.data(); var params = ''; // It's a component, let's check to make sure it's defined properly if ( data.hasOwnProperty('componentType') ) { if (data.componentType =="wpimg") continue; for ( var index in data ) { // Don't accept componentType as a param if ( !data.hasOwnProperty(index) || index == 'componentType' ) { continue; } // Build the params string out of the data attributes params += " " + index + '="' + data[index] + '"'; } var sc = '[aesop_' + data.componentType + params + ']'; // Let's check to see if it's a "full" shortcode var inner = component.find('.aesop-component-content-data'); if ( inner.length != 0 ) { sc += inner[0].innerHTML + "[/aesop_" + data.componentType + "]"; } processed += sc; } } return processed; } function process_twitter(html) { // if twitter widget doesn't exist return if (!html) return null; if (html.indexOf("twitterwidget") ==-1) return html; var t = $('#'+editor).clone(); var t1 = t.find('twitterwidget'); var t2 = $('#'+editor).find('twitterwidget'); var i; for (i = 0; i

      ').html(t2[i].shadowRoot.innerHTML).find('.EmbeddedTweet').data('click-to-open-target'); $(t1[i]).replaceWith(t5); } var html2 = t.html(); return html2; } //shortcode ultimates function shortcodify_su(content,selector){ // Convert the html into a series of jQuery objects var j = $.parseHTML(content); var processed = ''; // Iterate through the array of dom objects for (var i = 0; i < j.length; i++) { var component = $(j[i]); // If it's not a component, move along if ( !component.hasClass('su-box') && !component.hasClass('su-note') && !component.hasClass('su-document') && !component.hasClass('su-spoiler')) { // Let's test what kind of object it is if ( component.context.nodeType == 3 ) { // Text only object without dom processed += j[i].data; } else if ( component.context.nodeType == 8 ) { processed += ''; } else { // DOM object processed += j[i].outerHTML; } continue; } if ( component.hasClass('su-box')) { var box_title = component.find('.su-box-title')[0].innerHTML; var box_content = component.find('.su-box-content')[0].innerHTML; var box_color = component.find('.su-box-title')[0].style.backgroundColor; var sc = '[su_box title="'+box_title+'"'+' box_color="' +box_color+'"]' + box_content+'[/su_box]'; processed += sc; } else if ( component.hasClass('su-note')) { var note_content = component.find('.su-note-inner')[0].innerHTML; note_content = shortcodify_su(note_content); var note_color = component.find('.su-note-inner')[0].style.backgroundColor; var text_color = component.find('.su-note-inner')[0].style.color; var sc = '[su_note note_color="'+ note_color + '" text_color="'+text_color +'"]' + note_content+'[/su_note]'; processed += sc; } else if ( component.hasClass('su-document')) { var ifr = component.find('iframe.su-document')[0]; var url = getParameterByName("url",ifr.src); var width = ifr.width; var height = ifr.height; var sc = '[su_document url="'+ url + '" width="'+ width +'" height="' + height+'"]'; processed += sc; } else if ( component.hasClass('su-spoiler')) { var spoiler_content = component.find('.su-spoiler-content')[0].innerHTML; spoiler_content = shortcodify_su(spoiler_content); var title = component.find('.su-spoiler-title')[0].textContent; var sc = '[su_spoiler title="'+ title + '" style="fancy" open="no"]' + spoiler_content+'[/su_spoiler]'; processed += sc; } } return processed; } function process_gutenberg(content){ // Convert the html into a series of jQuery objects var k = $.parseHTML(content); var processed = ''; if (k == null) { return content; } j = $('
      ').append($(k).clone()); //ul $(j).find("ul").before('' ).after(''); $(j).find("ol").before('' ).after(''); // columns $(j).find(".wp-block-column").each( function(index ) { var data = {}; if ($(this).hasClass('is-vertically-aligned-center')) { data["verticalAlignment"]= "center"; } if ($(this).css("flex-basis")!= "") { data["width"] = $(this).css("flex-basis"); } blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); $(j).find(".wp-block-columns").each( function(index ) { var data = {}; if ($(this).hasClass('are-vertically-aligned-center')) { data["verticalAlignment"]= "center"; } blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); //paragraph $(j).find("p").each( function(index ) { var data = {}; if ($(this).hasClass('has-text-align-center')) { data["align"]= "center"; } blockCode = ""; $(this).before(blockCode).after("" ); }); //gallery $(j).find(".wp-block-gallery").each( function(index ) { debugger; var data = {}; if ($(this).hasClass('aligncenter')) { data["align"]= "center"; } var classes = $(this).attr('class').split(" "); for (i = 0; i < classes.length; ++i) { if (classes[i].indexOf('columns-') == 0) { data["columns"] = parseInt(classes[i].substr(8)); } } var ids = []; $(this).find("img").each( function(index ) { ids[index] = $(this).data('id'); }); data["ids"]= ids; if ($(this).find("a").length ==0) { data["linkTo"] = "none"; } else { data["linkTo"] = "file"; } blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); //heading $(j).find("h1").before('' ); $(j).find("h2").before('' ); $(j).find("h3").before('' ); $(j).find("h4").before('' ); $(j).find("h5").before('' ); $(j).find("h1,h2,h3,h4,h5").after("" ); //table $(j).find(".wp-block-table").before("" ).after("" ); //button $(j).find(".wp-block-button").before("" ); $(j).find(".wp-block-button").after("" ); $(j).find(".wp-block-buttons").each( function(index ) { var blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); //group $(j).find(".wp-block-group").each( function(index ) { var data = {}; if ($(this).hasClass('alignfull')) { data["align"]= "full"; } var blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); // spacer $(j).find(".wp-block-spacer").before("" ).after("" ); // separator $(j).find(".wp-block-separator").before("" ).after("" ); // image $(j).find(".wp-block-image").each( function(index ) { $(this).removeAttr('data-component-type'); var data = {}; if ($(this).find("img").length == 0) { return; } var blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); // cover $(j).find(".wp-block-cover").each( function(index ) { $(this).removeAttr('data-component-type'); var blockCode = ""; $(this).before(blockCode); $(this).after("" ); }); //aesop components $(j).find(".aesop-component").each( function(index ) { var d = $(this).data(); if (d['componentType'] == 'timeline_stop') d['componentType'] = 'timeline'; var blockCode = ""; $(this).before(blockCode); $(this).remove(); }); var html = $(j).html(); html = html.replace(" {} -->"," -->"); return html; } //shortcode avia layout editor function shortcodify_avia(content,selector){ // Convert the html into a series of jQuery objects var j = $.parseHTML(content); var processed = ''; // Iterate through the array of dom objects for (var i = 0; i < j.length; i++) { var component = $(j[i]); // If it's not a component, move along if ( !component.hasClass('av_textblock_section') && !component.hasClass('av_toggle_section') && !component.hasClass('togglecontainer')) { // Let's test what kind of object it is if ( component.context.nodeType == 3 ) { // Text only object without dom processed += j[i].data; } else if ( component.context.nodeType == 8 ) { processed += ''; } else { // DOM object processed += j[i].outerHTML; } continue; } if ( component.hasClass('av_textblock_section')) { var box_text = component.find('.avia_textblock')[0].innerHTML; var sc = '[av_textblock]' + box_text+'[/av_textblock]'; processed += sc; } else if ( component.hasClass('togglecontainer')) { var content = component[0].innerHTML; var mode ="accordion"; content = shortcodify_avia(content); if (component[0].hasClass('enable_toggles')) { mode = "toggle"; } var sc = "[av_toggle_container mode='"+mode+"']" + content+'[/av_toggle_container]'; processed += sc; } else if ( component.hasClass('av_toggle_section')) { var toggle_title = component.find('.toggler')[0].innerText; var toggle_content = component.find('.toggle_content')[0].innerHTML; var sc = '[av_toggle title="'+toggle_title+'"]' + toggle_content+'[/av_toggle]'; processed += sc; } } return processed; } function replace_rendered_shortcodes( content ) { // also remove scripts content = content.replace(/.*<\/script>/g, " "); if ( content.indexOf('--EDITUS_OTHER_SHORTCODE_START|' ) == -1) { return content; } /*var k = $.parseHTML(content); if (k != null) { j = $('
      ').append($(k).clone()); $(j).find('.editus_shortcode').each(function(){ var oldComment = this.previousElementSibling.innerHTML; var re = //g.exec(oldComment) ; var cont = this.dataset.shortcode; if (cont && re && re.size>1) { this.previousElementSibling.innerHTML = oldComment.replace(re[1], cont); }; }); content = $(j).html(); }*/ var re = /([\s\S]*?)/g ; if (lasso_editor.hasGutenberg) { content = content.replace(re,'$1'); } else { content = content.replace(re,'$1'); } return content; } // Save post using REST API V2 function savePublishREST(postid, title, subtitle, content_, type_,status_,forcePublish){ var data = { content: content_, status: status_ }; if (lasso_editor.aviaEditor) { data['content'] =""; data['metadata'] = { '_aviaLayoutBuilderCleanData': content_}; } //custom fields to save if (lasso_editor.cftosave) { if (!data['metadata']) { data['metadata']= lasso_editor.cftosave; } else { Object.assign(data['metadata'], lasso_editor.cftosave); } } var type; if (type_=="post") { type = "posts"; } else if (type_=="page"){ type = "pages"; } else { type = type_; } if (title.length>0) { data['title'] = title; } if (subtitle.length>0) { data['metadata'] = { '_subtitle': subtitle}; } if (lasso_editor.disableSavePost == 'on') { delete data['content']; } $.ajax({ method: "POST", url: lasso_editor.rest_root + 'wp/v2/'+type+'/'+postid, data: data, beforeSend: function ( xhr ) { xhr.setRequestHeader( 'X-WP-Nonce', lasso_editor.rest_nonce ); }, success : function( response ) { saveSuccess(); if (forcePublish) { var data = { action: 'editus_publish_post', postid: lasso_editor.postid } $.post( lasso_editor.ajaxurl2, data); } }, error : function (xhr, exception) { console.log( xhr ); alert("AJAX Error: "+xhr.responseText ); $('#lasso--save').removeClass('being-saved').addClass('lasso--error'); } }); } // code to run when post saving is successful function saveSuccess() { // change button class to saved $('#lasso--save').removeClass('being-saved').addClass('lasso--saved'); // if this is being published then remove the publish button afterwards if ( $this.hasClass('lasso-publish-post') ) { $this.remove(); } // wait a bit then remvoe the button class so they can save again setTimeout(function(){ $('#lasso--save').removeClass('lasso--saved'); if ( $this.hasClass('lasso-publish-post') ) { location.reload() } },1200); // then remove this copy from local stoarge localStorage.removeItem( 'lasso_backup_'+postid ); lasso_editor.dirtyByComponent = false; articleMedium.dirty = false; if (lasso_editor.saveSuccessHookArray) { $(lasso_editor.saveSuccessHookArray).each(function(key, val){ val(); }); } } // make the actual ajax call to save or publish function runSavePublish(forcePublish){ if (lasso_editor.saveusingrest) { // get the status of the post (published/draft) var status_ = $('.lasso--controls__right').data( "status" ); var title=""; if ($(lasso_editor.titleClass).length>0) { title = $(lasso_editor.titleClass)[0].innerText; } var subtitle=""; if ($(lasso_editor.subtitleClass).length>0) { subtitle = $(lasso_editor.subtitleClass)[0].innerText; } if (forcePublish) { status_ = "publish"; if (!lasso_editor.can_publish) { status_ = "pending"; } } savePublishREST(lasso_editor.postid, title, subtitle, data.content, $('.lasso--controls__right').data( "posttype" ), status_, forcePublish); return; } $.post( ajaxurl, data, function(response) { if( true == response.success ) { saveSuccess(); } else { $('#lasso--save').removeClass('being-saved').addClass('lasso--error'); } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); $('#lasso--save').removeClass('being-saved').addClass('lasso--error'); }); } }); jQuery(document).on('click','#lasso--post-delete', function(e){ e.preventDefault(); var $this = $(this); swal({ title: lasso_editor.strings.deletePost, type: "error", text: false, showCancelButton: true, confirmButtonColor: "#d9534f", confirmButtonText: lasso_editor.strings.deleteYes, closeOnConfirm: true }, function(){ var data = { action: 'editus_delete_post', postid: lasso_editor.postid, nonce: lasso_editor.deletePost } $.post( lasso_editor.ajaxurl2, data, function(response) { //load home page after deleting the post window.location.assign(lasso_editor.siteUrl); }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); }); }); }); function EditusFormatAJAXErrorMessage(jqXHR, exception) { if (jqXHR.status === 0) { return ('AJAX Error: Not connected.\nPlease verify your network connection.'); } else if (jqXHR.status == 404) { return ('AJAX Error: The requested page not found. [404]'); } else if (jqXHR.status == 500) { return ('AJAX Error: Internal Server Error [500].'); } else if (exception === 'parsererror') { return ('AJAX Error: Requested JSON parse failed.'); } else if (exception === 'timeout') { return ('AJAX Error: Time out error.'); } else if (exception === 'abort') { return ('AJAX Error: Ajax request aborted.'); } else { return ('AJAX Error: Uncaught Error.\n' + jqXHR.responseText); } } ================================================ FILE: public/assets/js/source/process-wpimg.js ================================================ (function( $ ) { $(document).ready(function(){ // get the attachment id from teh class wp-image-XXX, where XXX is the id of the attached iamge // this oly works if the image was inserted from within the wordpress post editor var ase_edit_frame; var className; $(document).on('click', '.lasso--wpimg-edit',function(e){ e.preventDefault(); if ($(this).parent().parent().find('img').length==0) { return; } var id =''; var selected_img , clicked = $(this) , cls = $(this).parent().next('img').attr('class'); if (cls) { id = cls.match(/\d+/); } className = e.currentTarget.parentElement.className; // create frame ase_edit_frame = wp.media.frames.ase_edit_frame = wp.media({ title: lasso_editor.strings.selectImage, button: { text: lasso_editor.strings.insertImage, }, multiple: false // Set to true to allow multiple files to be selected }); // open frame ase_edit_frame.on('open',function(){ var selection = ase_edit_frame.state().get('selection'); if (id) { var attachment = wp.media.attachment( id ); attachment.fetch(); selection.add( attachment ? [ attachment ] : [] ); } }); // update image on select ase_edit_frame.on( 'select', function() { // here after simple wpimg image select var attachment = ase_edit_frame.state().get('selection').first().toJSON() , imageURL = undefined === attachment.sizes.large ? attachment.sizes.full.url : attachment.sizes.large.url $(clicked).parent().parent().find('img').prop({ 'src': imageURL, 'srcset' :"", 'alt': attachment.alt, 'class': 'aligncenter size-large wp-image-'+attachment.id+'' }); //$("html").scrollTop(lasso_editor.scrollTop); $('#lasso-side-comp-button,.lasso--text-popup').remove(); // set some figures to uneditable $("figure.wp-block-image, figure.lasso--wpimg__wrap").attr('contenteditable',false).attr('readonly',true); }); lasso_editor.scrollTop = $(window).scrollTop(); // Finally, open the modal ase_edit_frame.open(); }) }); })( jQuery ); ================================================ FILE: public/assets/js/source/revisions.js ================================================ (function( $ ) { $(document).ready(function(){ var vars = lasso_editor , revisions , revision_id = 0 , next , previous , total revisionList = $('#lasso--revision-list'); // method to destroy the modal var destroyModal = function(){ $('body').removeClass('lasso-modal-open'); $('#lasso--revision__modal').remove(); $('#lasso--post-revisions').show(); }; // destroy loader function destroyLoader(){ $('#lasso--loading').remove(); } //Update title/post content for a revision var restoreRevision = function( revision_id ) { if( revision_id in revisions ){ revision = revisions[ revision_id ]; $( vars.titleClass ).html( revision.post_title ); $( vars.article_object ).html( revision.post_content ); $('body').attr('data-revision', revision_id ); } }; // modal click $('#lasso--post-revisions').on('click',function(e){ e.preventDefault(); // preent double clicking and opening $(this).hide(); // append revision modal $('body').append(vars.revisionModal); innerModal = $('#lasso--revision__modal .lasso--modal__inner'); // make the modal draggable innerModal.draggable({ cursor:'move', opacity:0.8 }); data = { action : 'process_revision_get', postid : vars.postid, nonce : vars.nonce }; $.post( vars.ajaxurl, data, function(response) { // do we have a response if ( true == response.success ) { revisionList = $('#lasso--revision-list'); slider = $('#lasso--slider'); lassoHide = $('#lasso--hide'); // remove any count classes removeRevisionCount(); // desroy the loader destroyLoader(); // show the button and slider lassoHide.show(); // if we have revisions if ( 'object' == typeof response.data && response.data.length ) { revisions = response.data; var total = revisions.length == 1 ? 1 : revisions.length -1; if ( revisions.length !== 1 ) { $.each( revisions, function( i, post ) { revisionList.append( '
    • ' + post.modified_time + '
    • ' ) }); // init slider and restore on slide slider.slider({ min: 0, max: total, animate:'fast', value: 0, zindex:999, slide: function( event, ui ) { restoreRevision( ui.value ) } }); // restore revision and sync slider on click $('.lasso--jump-revision').on('click',function(e){ e.preventDefault(); var val = $(this).data('revision'); slider.slider( 'value', val ); restoreRevision( val ); }) revisionList.attr('data-count', total + 1 ) // because we start at 0 } else { lassoHide.hide(); innerModal.append( vars.noRevisionsDiv ); } $('body').addClass('lasso--revision-count-'+revisions.length ); maybeRestoreCurrent(); modalResizer(); }else{ $('#lasso--hide').hide() innerModal.append( vars.noRevisionsDiv ); modalResizer(); } } else { alert('error'); } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); modalResizer(); }); // select a revision and start editing $(document).on('click', '#lasso--select-revision', function(e){ e.preventDefault(); destroyModal(); $('#lasso--edit').trigger('click'); addBackupNotice(); }).on('click','#lasso--close-modal',function(e){ e.preventDefault(); destroyModal(); }); ///////////////// /// EXIT SETTINGS /////////////////// $(document).keyup(function(e) { if ( 27 == e.keyCode ) { destroyModal(); } }); // restore teh current revision but only if a user is editing one function maybeRestoreCurrent(){ if( $('body').data('revision') ) { slider.slider('value', $('body').data('revision') ) } } // add a backup notice if we're editing a backukp function addBackupNotice(){ if ( !$('#lasso--notice').length ) { $(vars.article_object).before('
      '+vars.strings.editingBackup+'
      '); } } // remove/reset revisino count function removeRevisionCount(){ $('body').removeClass (function (index, css) { return (css.match (/(^|\s)lasso--revision-count-\S+/g) || []).join(' '); }); } }); })( jQuery ); ================================================ FILE: public/assets/js/source/settings-live-editing.js ================================================ (function( $ ) { $(document).ready(function(){ ///////////// // LIVE EDITING COMPONENTS // @todo - this is hella dirty and needs to be cleaned up // @todo - move this mess to it's own file //////////// $(document).on('click', '.lasso-component--settings__trigger', function(){ var settings = $('#lasso--component__settings') // QUOTE LIVE EDIT /////////////////// //settings.find('#aesop-generator-attr-background').live('change',function(){ settings.find('#aesop-generator-attr-background').on('change',function(){ component.css({'background-color': $(this).val()}); }); //settings.find('#aesop-generator-attr-text').live('change',function(){ settings.find('#aesop-generator-attr-text').on('change',function(){ component.css({'color': $(this).val()}); }); settings.find('#aesop-generator-attr-quote').on('keyup',function(){ component.find('blockquote span').text( $(this).val() ); }); settings.find('#aesop-generator-attr-cite').on('keyup',function(){ var t = component.find('blockquote cite'); if ( 0 == t.length ) { component.find('blockquote').append( ''+$(this).val()+'' ); } else { component.find('blockquote cite').text( $(this).val() ); } }); settings.find('.aesop-quote-width > #aesop-generator-attr-width').on('keyup',function(){ component.css('width', $(this).val() ); }); settings.find('.aesop-quote-type #aesop-generator-attr-type').on('change',function(){ var value = $(this).val() if ( 'pull' == value ) { component.css('background-color','transparent') } component.removeClass('aesop-quote-type-block aesop-quote-type-pull') component.addClass('aesop-quote-type-'+$(this).val()+' ') }); settings.find('.aesop-quote-align #aesop-generator-attr-align').on('change',function(){ var value = $(this).val() if ( 'left' == value ) { component.removeClass('aesop-component-align-right aesop-component-align-center') component.find('blockquote').removeClass('aesop-component-align-right aesop-component-align-center') } else if ( 'right' == value ) { component.removeClass('aesop-component-align-left aesop-component-align-center') component.find('blockquote').removeClass('aesop-component-align-left aesop-component-align-center') } else if ( 'center' == value ) { component.removeClass('aesop-component-align-left aesop-component-align-right') component.find('blockquote').removeClass('aesop-component-align-left aesop-component-align-right') } component.addClass('aesop-component-align-'+$(this).val()+' ') component.find('blockquote').addClass('aesop-component-align-'+$(this).val()+' ') }); // PARALLAX LIVE EDIT /////////////////// settings.find('.aesop-parallax-caption > #aesop-generator-attr-caption').on('keyup',function(){ var t = component.find('.aesop-parallax-sc-caption-wrap') if ( 0 == t.length ) { component.find('img').after( '
      '+$(this).val()+'
      ' ); } else { component.find('.aesop-parallax-sc-caption-wrap').text( $(this).val() ); } }) settings.find('.aesop-parallax-captionposition > #aesop-generator-attr-captionposition').on('change',function(){ var value = $(this).val() if ( 'bottom-left' == value ) { component.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-right top-left top-right') } else if ( 'bottom-right' == value ) { component.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-left top-left top-right') } else if ( 'top-left' == value ) { component.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-right top-right bottom-left') } else if ( 'top-right' == value ) { component.find('.aesop-parallax-sc-caption-wrap').removeClass('bottom-right bottom-left top-left') } component.find('.aesop-parallax-sc-caption-wrap').addClass( value ); }) // IMAGE LIVE EDIT /////////////////// settings.find('.aesop-image-caption > #aesop-generator-attr-caption').on('keyup',function(){ var t = component.find('.aesop-image-component-caption'); if ( 0 == t.length ) { component.find('img').after( '

      '+$(this).val()+'

      ' ); } else { component.find('.aesop-image-component-caption').text( $(this).val() ); } }) settings.find('.aesop-image-imgwidth > #aesop-generator-attr-imgwidth').on('keyup',function(){ component.find('.aesop-image-component-image').css('max-width', $(this).val() ); }) settings.find('.aesop-image-align > #aesop-generator-attr-align').on('change',function(){ var value = $(this).val() if ( 'left' == value ) { component.find('.aesop-image-component-image').removeClass('aesop-component-align-right aesop-component-align-center') } else if ( 'right' == value ) { component.find('.aesop-image-component-image').removeClass('aesop-component-align-left aesop-component-align-center') } else if ( 'center' == value ) { component.find('.aesop-image-component-image').removeClass('aesop-component-align-left aesop-component-align-right') } component.find('.aesop-image-component-image').addClass('aesop-component-align-'+$(this).val()+' ') }) settings.find('.aesop-image-captionposition > #aesop-generator-attr-captionposition').on('change',function(){ var value = $(this).val(); if ( 'left' == value ) { component.find('.aesop-image-component-image').removeClass('aesop-image-component-caption-right aesop-image-component-caption-center') } else if ( 'right' == value ) { component.find('.aesop-image-component-image').removeClass('aesop-image-component-caption-left aesop-image-component-caption-center') } else if ( 'center' == value ) { component.find('.aesop-image-component-image').removeClass('aesop-image-component-caption-left aesop-image-component-caption-right') } component.find('.lasso-image-component-image').addClass('lasso-image-component-caption-'+value+' '); }); settings.find('.aesop-image-offset > #aesop-generator-attr-offset').on('keyup',function(){ var value = $(this).val(); if ( component.find('.aesop-image-component-image').hasClass('aesop-component-align-left') ) { component.find('.aesop-image-component-image').css('margin-left', $(this).val() ); } else { component.find('.aesop-image-component-image').css('margin-right', $(this).val() ); } }); // CHARACTER LIVE EDIT /////////////////// settings.find('.aesop-character-name > #aesop-generator-attr-name').on('keyup',function(){ component.find('.aesop-character-title').text( $(this).val() ); }) settings.find('.aesop-character-caption > #aesop-generator-attr-caption').on('keyup',function(){ component.find('.aesop-character-cap').text( $(this).val() ); }) settings.find('.aesop-character-align > #aesop-generator-attr-align').on('change',function(){ var value = $(this).val() if ( 'left' == value ) { component.removeClass('aesop-component-align-right aesop-component-align-center'); } else if ( 'center' == value ) { component.removeClass('aesop-component-align-left aesop-component-align-right'); } component.addClass('aesop-component-align-'+$(this).val()+' '); }); // CHAPTER LIVE EDIT /////////////////// settings.find('.aesop-chapter-title > #aesop-generator-attr-title').on('keyup',function(){ component.find('.aesop-cover-title span').text( $(this).val() ); }) settings.find('.aesop-chapter-subtitle > #aesop-generator-attr-subtitle').on('keyup',function(){ component.find('.aesop-cover-title small').text( $(this).val() ); }) // VIDEO LIVE EDITOR ///////////////////// //settings.find('.lasso-video-src > #aesop-generator-attr-src').live('change blur',function(){ settings.find('.aesop-video-src > #aesop-generator-attr-src').on('change blur',function(){ val = $(this).val() if ( 'vimeo' == val ) { component.find('iframe').attr('src', '//player.vimeo.com/video/'+val+' ') initVideoProvider( settings, component, 'vimeo' ); } else if ( 'youtube' == val ) { component.find('iframe').attr('src', '//www.youtube.com/embed/'+val+'?rel=0&wmode=transparent') initVideoProvider( settings, component, 'youtube' ); } }); settings.find('.aesop-video-id > #aesop-generator-attr-id').on('keyup',function(){ t = $('.aesop-video-src > #aesop-generator-attr-src').val(); val = $(this).val(); if ( 'vimeo' == t ) { component.find('iframe').attr('src', '//player.vimeo.com/video/'+val+' ') } else if ( 'youtube' == t ) { component.find('iframe').attr('src', '//www.youtube.com/embed/'+val+'?rel=0&wmode=transparent') } }); settings.find('.aesop-video-width > #aesop-generator-attr-width').on('keyup',function(){ component.find('.aesop-video-container').css('max-width', $(this).val() ); }); // CONTENT COMPONENT LIVE EDIT ///// //settings.find('.lasso-content-background > #aesop-generator-attr-background').live('change',function(){ settings.find('.lasso-content-background > #aesop-generator-attr-background').on('change',function(){ component.find('.aesop-content-comp-wrap').css({'background-color': $(this).val()}); }); //settings.find('.lasso-content-color > #aesop-generator-attr-color').live('change',function(){ settings.find('.aesop-content-color > #aesop-generator-attr-color').on('change',function(){ component.find('.aesop-content-comp-wrap').css({'color': $(this).val()}); }); //settings.find('.lasso-content-height > #aesop-generator-attr-height').live('keyup',function(){ settings.find('.aesop-content-height > #aesop-generator-attr-height').on('keyup',function(){ val = $(this).val() component.find('.aesop-content-comp-wrap').css({'min-height': $(this).val()}); }); //settings.find('.lasso-content-columns > #aesop-generator-attr-columns').live('change',function(){ settings.find('.aesop-content-columns > #aesop-generator-attr-columns').on('change',function(){ val = $(this).val() if ( '1' == val ) { component.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-2 aesop-content-comp-columns-3 aesop-content-comp-columns-4').addClass('aesop-content-comp-columns-1') } else if ( '2' == val ) { component.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-1 aesop-content-comp-columns-3 aesop-content-comp-columns-4').addClass('aesop-content-comp-columns-2') } else if ( '3' == val ) { component.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-1 aesop-content-comp-columns-2 aesop-content-comp-columns-4').addClass('aesop-content-comp-columns-3') } else if ( '4' == val ) { component.find('.aesop-content-comp-wrap').removeClass('aesop-content-comp-columns-1 aesop-content-comp-columns-2 aesop-content-comp-columns-3').addClass('aesop-content-comp-columns-4') } }); }); /** * * Swap the video player with the correct id * @param object the global settings for this component * @param object the component we're editing * @param type string the type of video (vimeo, youtube) * @since 0.9.7 */ function initVideoProvider( settings, component, type ){ //settings.find('.lasso-video-id > #aesop-generator-attr-id').live('change',function(){ settings.find('.lasso-video-id > #aesop-generator-attr-id').on('change',function(){ video_id = $(this).val() if ( 'vimeo' == type ) { component.find('iframe').attr('src', '//player.vimeo.com/video/'+video_id+' ') } else if ( 'youtube' == type ) { component.find('iframe').attr('src', '//www.youtube.com/embed/'+video_id+'?rel=0&wmode=transparent') } }) } }); })( jQuery ); ================================================ FILE: public/assets/js/source/settings-panel.js ================================================ (function( $ ) { $(document).ready(function(){ // helper to dstry the sidebar var destroySidebar = function(){ $('body').removeClass('lasso-sidebar-open'); } // close the sidebar when clicking outside of it $('body').on('click', '#'+lasso_editor.editor, function(){ //lets not for now //destroySidebar() }); // helper to set the height of the settings panel var settingsHeight = function(){ var settings = $('#lasso--component__settings'); settings.height( $(window).height() ); $(window).resize(function(){ settings.height( $(window).height() ); //$('#lasso--component__settings').perfectScrollbar('update'); }); } var component, data; ///////////// // OPEN COMPONENT SETTINGS //////////// $(document).on('click','.lasso-component--settings__trigger',function(){ var settings = $('#lasso--component__settings') var click = $(this) // let's set our globals if ( $(this).parent().parent().hasClass('aesop-map-component') ) { component = $(this).parent().parent().find('.aesop-component'); } else { component = $(this).closest('.aesop-component,.lasso-component,.wp-block-image,.wp-block-cover'); } data = component.data(); if (!data) { return;} // let's force globalize this until we refactor the js window.component = component; window.componentClone = component.clone(); if (data['componentType'] == 'wpimg') { if ($(component).find('figure.lasso-component').length) { data = $(component).find('figure.lasso-component').data();//'.wp-image.lasso-component').data(); } else if ($(component).find('img').length) { data['img'] =$(component).find('img').attr('src'); } } if (data['componentType'] == 'wpimg-block') { if ($(component).find('img').length) { var $img = $(component).find('img'); data['img'] =$img.attr('src'); data['alt'] =$img.attr('alt'); var c = $img.attr('class'); var $fig = $(component).find('figure'); if ($fig.hasClass('alignright')) { data['align']='right'; } else if ($fig.hasClass('aligncenter')) { data['align']='center'; } else if ($fig.hasClass('alignleft')) { data['align']='left'; } if (c && c.indexOf('wp-image-') == 0) { data['id'] = c.substr(9); } if ($(component).find('figcaption').length) { data['caption'] = $(component).find('figcaption').text(); } if ($(component).find('a').length) { data['link'] = $(component).find('a').attr("href"); } } } if (data['componentType'] == 'wpcover-block') { if ($(component).find('img').length) { var $img = $(component).find('img'); data['img'] =$img.attr('src'); } } if (data['componentType'] =='wpquote') { return;} if (!lasso_editor.component_options) return; // special case for hero gallery if ( $(this).parent().parent().hasClass('aesop-hero-gallery-wrapper') ) { jQuery.extend(data, $(component).find(".fotorama").data()); } // add a body class $('body').toggleClass('lasso-sidebar-open'); settings.find('input[name="unique"]').val( data['unique'] ); // set up settings panel settingsHeight(); settings.html( lasso_editor.component_options[data.componentType] ); // add the type as a value in a hidden field in settings settings.find('.component_type').val( data.componentType ); // fade in save controls $('.lasso-buttoninsert-wrap').fadeIn(600); // initialize scrolbar settings.perfectScrollbar('destroy'); settings.perfectScrollbar(); // map the settings from the data attributes on components into appropriate settings in settings panel settings.find('.lasso-option').each(function(){ var option = $(this).data('option'); var field = $(this).find('.lasso-generator-attr'); // if it's a gallery data attribute map the cehcekd attribute to the right place // @todo - account for map stuff if ( 'gallery-type' == option ) { // this function is repeated on process-gallery-opts line 4 var value_check = function( value ){ if ( 'grid' == value ) { $('.ase-gallery-opts--thumb').fadeOut(); $('.ase-gallery-opts--photoset').fadeOut(); $('.ase-gallery-opts--hero').fadeOut(); $('.ase-gallery-opts--grid').fadeIn(); } else { $('.ase-gallery-opts--grid').fadeOut(); } if ( 'thumbnail' == value ) { $('.ase-gallery-opts--grid').fadeOut(); $('.ase-gallery-opts--photoset').fadeOut(); $('.ase-gallery-opts--hero').fadeOut(); $('.ase-gallery-opts--thumb').fadeIn(); } else { $('.ase-gallery-opts--thumb').fadeOut(); } if ( 'photoset' == value ) { $('.ase-gallery-opts--grid').fadeOut(); $('.ase-gallery-opts--thumb').fadeOut(); $('.ase-gallery-opts--hero').fadeOut(); $('.ase-gallery-opts--photoset').fadeIn(); } else { $('.ase-gallery-opts--photoset').fadeOut(); } if ( 'hero' == value ) { $('.ase-gallery-opts--grid').fadeOut(); $('.ase-gallery-opts--thumb').fadeOut(); $('.ase-gallery-opts--photoset').fadeOut(); $('.ase-gallery-opts--hero').fadeIn(); } else { $('.ase-gallery-opts--hero').fadeOut(); } } $(field).each(function(){ if ( $(this).val() == data.galleryType ) { $(this).parent().addClass('selected') $(this).prop('checked',true); value_check( $(this).val() ); // add the type to a hidden field $('#ase_gallery_type').val( $(this).val() ) } }); } else { $( field[0] ).val(data[option]); } }); //////////// // SMOOTH SLIDE TO COMPONENT - @since 0.9.5 /////////// // if its a content component if ( component.hasClass('aesop-content-component') ) { var target = component.find('.aesop-content-comp-wrap').attr('id') , item = $('#'+target) } else { var item = $('#'+component.attr('id') ) } if (item.length) { //$('html, body').animate({ scrollTop: item.offset().top - 50 }, 400); } ///////////// // GET GALLERY IMAGES IF ITS A GALLERY ///////////// //if ( $(this).parent().parent().hasClass('empty-gallery') ) { //settings.addClass('gallery-no-images') //} if ( $(this).parent().parent().hasClass('aesop-gallery-component') ) { var $this = $(this) , ajaxurl = lasso_editor.ajaxurl , form = $('#lasso--component-settings-form.gallery') , nonce = lasso_editor.getGallImgNonce , gall_id = data['id'] var data = { action: 'process_gallery_get-images', post_id: gall_id, nonce: nonce }; // post ajax response with data $.post( ajaxurl, data, function(response) { $('#lasso--gallery__images').html( response.data.html ); ///////////// // CALL SORTABLE ON RECIEVED IMAGES ///////////// var gallery = $('#ase-gallery-images'); gallery.ready(function(){ gallery.sortable({ containment: 'parent', cursor: 'move', opacity: 0.8, placeholder: 'ase-gallery-drop-zone', forcePlaceholderSize:true, update: function(){ var imageArray = $(this).sortable('toArray'); $('#ase_gallery_ids').val( imageArray ); }, create: function(){ var imageArray = $(this).sortable('toArray'); $('#ase_gallery_ids').val( imageArray ); } }); }); }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); });; } }).on('click', '#lasso-upload-img', function( e ){ e.preventDefault(); className = e.currentTarget.parentElement.className; var type = $('input[name="component_type"]').val() // If the media frame already exists, reopen it. if ( typeof lasso_file_frame != 'undefined' ) { lasso_file_frame.close(); } // Create the media frame. lasso_file_frame = wp.media.frames.file_frame = wp.media({ title: 'Select Image', button: { text: 'Insert Image', }, multiple: false // Set to true to allow multiple files to be selected }); // When an image is selected, run a callback. lasso_file_frame.on( 'select', function() { var attachment = lasso_file_frame.state().get('selection').first().toJSON(); $('.aesop-generator-attr-media_upload').prop('value',attachment.url); ///////////// // START LIVE IMAGE EDITING COMPONENTS // @todo - this was going to be taken care of in above but it seems we have to bind this to the file upload here? //////////// if ( 'parallax' == type ) { component.find('.aesop-parallax-sc-img').prop('src', attachment.url ) } else if ( 'quote' == type ) { component.css({ 'background-image': 'url('+ attachment.url +')' }); } else if ( 'image' == type ) { $("#aesop-generator-attr-img").val(attachment.url); component.find('.aesop-image-component-image > img').prop('src', attachment.url); // new addition for panorama images component.find('.paver__pano').css({'background-image': 'url('+ attachment.url +')'}); } else if ( 'character' == type ) { component.find('.aesop-character-avatar').prop('src', attachment.url) } else if ( 'chapter' == type ) { component.find('.aesop-article-chapter').css({ 'background-image': 'url('+ attachment.url +')' }); }else if ( 'wpimg' == type ) { var img = window.component.find('img'); if (img.length>0) { img.prop('src', attachment.url ); img.prop("srcset",""); } } else if ( 'wpimg-block' == type ) { var img = window.component.find('img'); if (img.length >0) { img.prop('src', attachment.url ); img.prop("srcset",""); if (attachment.id) { img.removeClass(); img.addClass("wp-image-"+attachment.id); window.component.data( 'id', ""+attachment.id); } } } else if ( 'wpcover-block' == type ) { var img = window.component.find('img'); if (img.length >0) { img.prop('src', attachment.url ); img.prop("srcset",""); img.removeClass(); img.addClass("wp-block-cover__image-background"); if (attachment.id) { img.addClass("wp-image-"+attachment.id); } } else { window.component.css('background-image', "url("+attachment.url+")"); } } ///////////// // EDN LIVE IMAGE EDITING COMPONENTS //////////// }); // Finally, open the modal lasso_file_frame.open(); }); // destroy panel if clicking close or overlay //$('#lasso--sidebar__close').live('click',function(e){ // cancel jQuery(document).on('click','#lasso--sidebar__close',function(e){ e.preventDefault(); window.component.replaceWith(window.componentClone); //restore the state before editing destroySidebar(); $('#lasso--component__settings').perfectScrollbar('destroy'); }); }); })( jQuery ); ================================================ FILE: public/assets/js/source/toolbar.js ================================================ jQuery(function( $ ) { function saveSelection() { if (window.getSelection) { sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { return sel.getRangeAt(0); } } else if (document.selection && document.selection.createRange) { return document.selection.createRange(); } return null; } function restoreSelection(range) { if (range) { if (window.getSelection) { sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } else if (document.selection && range.select) { range.select(); } } else { if (window.getSelection) { sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { window.selRange = sel.getRangeAt(0); } } } } lasso_editor.checkSelection = function (saveSel) { /*var saveSel = saveSelection; if (saveSel == undefined) { saveSel = false; } */ if (saveSel == true) { window.selRange = saveSelection(); } if (!window.selRange || window.selRange.collapsed) { swal({ title:"", text: lasso_editor.strings.selectText, closeOnConfirm: true }); return false; } return true; } var ifSmallWidth = function(){ return 600 <= $(window).width() ? true : false; } var dropClass = function() { return "up";//ifSmallWidth() ? 'up' : 'down'; } ///////////// /// DROP UP ///////////// $(document).on('click', '#lasso-toolbar--components', function(e){ $(this).toggleClass('toolbar--drop-'+dropClass() ); // show and hide the component list var dropUp = $(this).find('ul'); if ($(this).hasClass( 'toolbar--drop-'+dropClass() )) { $(dropUp).show(); } else { $(dropUp).hide(); } var components = $(dropUp).find("li").length; if (components<7) { $(dropUp).css('width',''+(components*42+8)+'px'); $(dropUp).css('left','-'+((components*42+8)/2-20)+'px'); } restoreSelection(window.selRange); $('#lasso-toolbar--html').removeClass('html--drop-'+dropClass() ); $('#lasso-toolbar--link').removeClass('link--drop-'+dropClass() ); if( !lasso_editor.isMobile) { // get the height of the list of components var dropUpHeight = $(dropUp).height(), caretSpacing = 15; // this is the height of the caret // and adjust the drop up position as necessary if ( true == ifSmallWidth() ) { $(dropUp).css({ dropUp: dropUpHeight, top: -(dropUpHeight + caretSpacing) }); } } else { /*$(dropUp).css({ dropUp: dropUpHeight, top: 40 });*/ } }); // if we the side component button feature is on if (lasso_editor.buttonOnEmptyP) { jQuery(document).on('click', '#lasso--content p', function(e){ //if the user click on a paragraph if ($(this).find("#lasso-side-comp-button").length == 0) { lasso_editor.addComponentButton(); } }); } jQuery(document).on('mousedown', '#lasso-side-comp-button', function(){ // side component button handler window.selRange = saveSelection(); $(this).toggleClass('toolbar--side' ); // show and hide the component list var drop = $('#lasso-side-comp-button #lasso-toolbar--components__list'); if (drop.length ==0) { drop = $('#lasso-toolbar--components__list').clone(); $(this).append(drop); } if ($(this).hasClass( 'toolbar--side')) { $(drop).show(); } else { $(drop).hide(); } $('#lasso-toolbar--html').removeClass('html--drop-'+dropClass() ); $('#lasso-toolbar--link').removeClass('link--drop-'+dropClass() ); $(drop).css({ left: '30px', top:'0px' }); if ($(this).find("li").length<7) { $(this).find("ul").css('column-count',''+$(this).find("ul li").length); $(this).find("ul").css('width','auto'); } }); ///////////// /// HTML DROP UP ///////////// //$('#lasso-toolbar--html').live('mousedown',function(){ /*jQuery(document).on('mousedown', '#lasso-toolbar--html,#lasso-toolbar--components,#lasso-toolbar--link', function(){ if( ! $(this).hasClass('html--drop-'+dropClass() ) ) { var article = document.getElementById(lasso_editor.editor); article.highlight(); window.selRange = saveSelection(); if( typeof window.selRange === 'undefined' || null == window.selRange ) { window.selRange = saveSelection(); } } });*/ //$('#lasso-toolbar--html__inner').live('focusout',function(){ jQuery(document).on('focusout', '#lasso-toolbar--html__inner', function(){ restoreSelection(window.selRange); }); //$('#lasso-toolbar--html__inner').live('focus',function(){ jQuery(document).on('focus', '#lasso-toolbar--html__inner', function(){ var savedSelect = saveSelection(); if ( savedSelect && $(savedSelect.commonAncestorContainer).parents('#lasso--content').length != 0 ) { window.selRange = saveSelection(); } }); $(document).on('click', '#lasso-toolbar--html', function(e){ $(this).toggleClass('html--drop-'+dropClass() ); $('#lasso-toolbar--components').removeClass('toolbar--drop-'+dropClass() ); $('#lasso-toolbar--link').removeClass('link--drop-'+dropClass() ); // prevent dropup from closing //$('#lasso-toolbar--html__wrap').live('click',function(){ jQuery(document).on('click', '#lasso-toolbar--html__wrap', function(){ return false; }); $(this).find('#lasso-toolbar--html__inner').focus(); }); //$('.lasso-toolbar--html__cancel').live('click',function(){ jQuery(document).on('click', '.lasso-toolbar--html__cancel', function(){ $(this).closest('li').removeClass('html--drop-'+dropClass() ); }); ////////////////// // HTML FORMATTING IN HTML DROP UP MENU ////////////////// var htmlItemInsert = function(markup){ return $('#lasso-toolbar--html__inner').text(markup); } //$('#lasso-html--h2').live('click',function(e){ jQuery(document).on('click', '#lasso-html--h2', function(e){ e.preventDefault(); htmlItemInsert('

      H2 Heading

      '); }); //$('#lasso-html--h3').live('click',function(e){ jQuery(document).on('click', '#lasso-html--h3', function(e){ e.preventDefault(); htmlItemInsert('

      H3 Heading

      '); }); //$('#lasso-html--ul').live('click',function(e){ jQuery(document).on('click', '#lasso-html--ul', function(e){ e.preventDefault(); htmlItemInsert('
      • Item
      '); }); //$('#lasso-html--ol').live('click',function(e){ jQuery(document).on('click', '#lasso-html--ol', function(e){ e.preventDefault(); htmlItemInsert('
      1. Item
      '); }); jQuery(document).on('click', '#lasso-html--table', function(e){ e.preventDefault(); htmlItemInsert(lasso_editor.tableCode);//'
      Cell 1Cell 2
      Cell 3Cell 4
      '); }); //////////// /// LINK DROP UIP //////////// //$('#lasso-toolbar--link').live('mousedown',function(){ jQuery(document).on('mousedown', '#lasso-toolbar--link', function(){ $('#lasso-toolbar--components').removeClass('toolbar--drop-'+dropClass() ); $('#lasso-toolbar--html').removeClass('html--drop-'+dropClass() ); }); //$('#lasso-toolbar--link__inner').live('focusout',function(){ jQuery(document).on('focusout', '#lasso-toolbar--link__inner', function(){ restoreSelection(window.selRange); }); //$('#lasso-toolbar--link__inner').live('focus',function(){ jQuery(document).on('focus', '#lasso-toolbar--link__inner', function(){ var savedSelect = saveSelection(); if ( savedSelect && $(savedSelect.commonAncestorContainer).parents('#lasso--content').length != 0 ) { window.selRange = saveSelection(); } }); $(document).on('click', '#lasso-toolbar--link', function(e){ // exit if nothing is selected if (!lasso_editor.checkSelection()) return false; $(this).toggleClass('link--drop-'+dropClass()); $('#aesop-toolbar--link_newtab').unbind('mousedown').mousedown(function() { $(this).prop("checked", !$(this).prop("checked")); return; }); // prevent dropup from closing jQuery(document).on('click', '#lasso-toolbar--link__wrap', function(){ return false; }); $(this).find('#lasso-toolbar--link__inner').focus(); if (window.selRange.startContainer.parentNode.tagName == 'A') { $('#lasso-toolbar--link__inner').text(window.selRange.startContainer.parentNode.href); } }); // RESTORING LINK SELECTION //$('.lasso-editing .lasso-link').live('click',function(e){ jQuery(document).on('click', '.lasso-editing .lasso-link', function(e){ e.preventDefault(); // prevent dropup from closing //$('#lasso-toolbar--link__wrap').live('click',function(){ jQuery(document).on('click', '#lasso-toolbar--link__wrap', function(){ return false; }); var link = $(this).attr('href'); $('#lasso-toolbar--link').addClass('link--drop-'+dropClass()); $('#lasso-toolbar--link__inner').text(link); }); ///////////// /// DELETING ///////////// //$('.lasso-delete').live('click',function(e) { jQuery(document).on('click', '.lasso-delete', function(e){ e.preventDefault(); var $this = $(this); swal({ title: "Delete this component?", type: "warning", text: false, showCancelButton: true, confirmButtonColor: "#d9534f", confirmButtonText: "Yes, delete it!", closeOnConfirm: true }, function(){ // remove component $this.closest('.aesop-component').remove(); // remove wp image if its a wp image $this.closest('.lasso-component').remove(); if ($this.parent().parent().hasClass('wp-block-image')) { //$this.closest('.wp-block-image').remove(); $this.parent().parent().remove(); } }); }); ///////////// /// CLONING ///////////// //$('.lasso-clone').live('click',function(e) { jQuery(document).on('click', '.lasso-clone', function(e){ // sore reference to this var $this = $(this); e.preventDefault(); $this.closest('.aesop-component').clone().insertAfter( $(this).parent().parent() ).hide().fadeIn() $this.closest('.lasso-component').clone().insertAfter( $(this).parent().parent() ).hide().fadeIn() }); }); ================================================ FILE: public/assets/js/source/tour.js ================================================ (function( $ ) { $(document).ready(function(){ destroyModal = function(){ $('body').removeClass('lasso-modal-open'); $('#lasso--tour__modal,#lasso--all-posts__modal,#lasso--modal__overlay').remove(); } //$('#lasso--tour__modal input[type="submit"]').live('click', function(e) { jQuery(document).on('click', '#lasso--tour__modal input[type="submit"]', function(e){ e.preventDefault(); var target = $(this); if ( !$('#hide_tour').is(':checked') ) { destroyModal() } else { if (lasso_editor.saveusingrest) { var data = { action: 'process_tour_hide', nonce: $(this).data('nonce') } $.post( lasso_editor.ajaxurl, data, function(response) { if ( true == response.success ) { destroyModal(); } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); } else { var data = { action: 'process_tour_hide', nonce: $(this).data('nonce') } $.post( lasso_editor.ajaxurl, data, function(response) { if ( true == response.success ) { destroyModal(); } }).fail(function(xhr, err) { var responseTitle= $(xhr.responseText).filter('title').get(0); alert($(responseTitle).text() + "\n" + EditusFormatAJAXErrorMessage(xhr, err) ); }); } } }); }); })( jQuery ); (function( $ ) { jQuery(document).ready(function($){ if ( $( "#lasso--tour__slides" ).length ) { $('body').addClass('lasso-modal-open'); $('.lasso--loading').remove(); $('#lasso--tour__slides').hide().fadeIn() $('#lasso--tour__slides').unslider({ dots: true, delay:7000 }); } }); })( jQuery ); ================================================ FILE: public/assets/js/source/util--color-picker.js ================================================ //color picker (function(global) { // @todo: bind in as a build step, so css is readable var basicCSS = '.vanilla-color-picker { display: inline-block; position: absolute; padding: 5px; background-color: #fff; box-shadow: 1px 1px 2px 1px rgba(0,0,0,0.3) } .vanilla-color-picker-single-color { display: inline-block; width: 20px; height: 20px; margin: 1px; border-radius: 2px; z-index: 100 }'; function singleColorTpl(color, index, picked) { var pickedClass = picked ? "vanilla-color-picker-single-color-picked" : ''; return '
      '; } var DEFAULT_COLORS = ['red', 'yellow', 'green']; function addBasicStyling() { if (document.getElementById('vanilla-color-picker-style')) { return; } var style = document.createElement('style'); style.setAttribute('type', 'text/css'); style.setAttribute('id', 'vanilla-color-picker-style'); style.innerHTML = basicCSS; var firstInHead = global.document.head.children[0]; if (firstInHead) { global.document.head.insertBefore(style, firstInHead); } else { global.document.head.appendChild(style); } } function MessageMediator() { this.subscribers = {}; this.on = function(eventName, callback) { this.subscribers[eventName] = this.subscribers[eventName] || []; this.subscribers[eventName].push(callback); return this; }; this.emit = function(eventName) { var arguments_ = arguments; (this.subscribers[eventName] || []).forEach(function(callback) { callback.apply(null, Array.prototype.splice.call(arguments_, 1)); }); }; } function SinglePicker(elem, colors, className) { MessageMediator.apply(this); this.targetElem = elem; this.elem = null; var this_ = this; this._initialize = function() { this._createPickerElement(); this._positionPickerElement(); this._addEventListeners(); }; this.destroy = function() { try { this.elem.parentNode.removeChild(this.elem); } catch (e) { // http://stackoverflow.com/a/22934552 } }; this._positionPickerElement = function() { var left = this.targetElem.offsetLeft; var top = this.targetElem.offsetTop; var height = this.targetElem.offsetHeight; this.elem.style.left = left + 'px'; this.elem.style.top = (top - this.elem.offsetHeight-5) + 'px'; //this.elem.style.bottom = (this.targetElem.offsetBottom) + 'px'; }; this._onFocusLost = function() { setTimeout(function() { if (this_.elem.contains(document.activeElement)) { // because blur is not propagating document.activeElement.addEventListener('blur', this_._onFocusLost); } else { this_.emit('lostFocus'); } }, 1); }; this._createPickerElement = function() { this.elem = document.createElement('div'); this.elem.classList.add('vanilla-color-picker'); if (className) { this.elem.classList.add(className); } var currentlyChosenColorIndex = colors.indexOf(this.targetElem.dataset.vanillaPickerColor); for (var i = 0; i < colors.length; i++) { this.elem.innerHTML += singleColorTpl(colors[i], i + 1, i == currentlyChosenColorIndex); } this.targetElem.parentNode.appendChild(this.elem); this.elem.setAttribute('tabindex', 1); var toFocus = currentlyChosenColorIndex > -1 ? currentlyChosenColorIndex : 0; this.elem.children[toFocus].focus(); this.elem.children[toFocus].addEventListener('blur', this_._onFocusLost); }; this._addEventListeners = function() { var _this = this; this.elem.addEventListener('click', function(e) { if (e.target.classList.contains('vanilla-color-picker-single-color')) { _this.emit('colorChosen', e.target.dataset.color); } }); this.elem.addEventListener('keydown', function(e) { var ENTER = 13; var ESC = 27; var keyCode = e.which || e.keyCode; if (keyCode == ENTER) { _this.emit('colorChosen', e.target.dataset.color); } if(keyCode == ESC) { _this.emit('lostFocus'); } }); }; this._initialize(); } function PickerHolder(elem) { MessageMediator.apply(this); // an alias for more intuitivity this.set = this.emit; this.colors = DEFAULT_COLORS; this.className = ''; this.elem = elem; this.currentPicker = null; var this_ = this; this._initialize = function() { this._addEventListeners(); }; this._addEventListeners = function() { this.elem.addEventListener('click', this.openPicker); this.elem.addEventListener('focus', this.openPicker); this.on('customColors', function(colors) { if (!(colors instanceof Array)) { throw new Error('Colors must be an array'); } this_.colors = colors; }); this.on('defaultColor', function(color) { if (!this_.elem.dataset.vanillaPickerColor) { this_._updateElemState(color); this_.emit('colorChosen', color, this_.elem); } }); this.on('className', function(className) { this_.className = className; }); }; this._updateElemState = function(color) { this.elem.dataset.vanillaPickerColor = color; this.elem.value = color; }; this.destroyPicker = function() { if (!this_.currentPicker){ return; } this_.currentPicker.destroy(); this_.currentPicker = null; this_.emit('pickerClosed'); }; this.openPicker = function() { if (this_.currentPicker) { return; } this_.currentPicker = new SinglePicker(this_.elem, this_.colors, this_.className); this_.currentPicker.on('colorChosen', function(color) { this_._updateElemState(color); this_.destroyPicker(); this_.emit('colorChosen', color, this_.elem); }); this_.currentPicker.on('lostFocus', function() { this_.destroyPicker(); }); this_.emit('pickerCreated'); }; this._initialize(); } function vanillaColorPicker(element, options) { // @todo: move from here addBasicStyling(); return new PickerHolder(element, options); } if (global.define && global.define.amd) { define([], function() { return vanillaColorPicker; }); } else { global.vanillaColorPicker = vanillaColorPicker; } })(this || window); ================================================ FILE: public/assets/js/source/util--content-editable.js ================================================ /* * Medium.js * * Copyright 2013, Jacob Kelley - http://jakiestfu.com/ * Released under the MIT Licence * http://opensource.org/licenses/MIT * * Github: http://github.com/jakiestfu/Medium.js/ * Version: 1.0 */ (function (w, d) { 'use strict'; // check if the selection contains noneditable element function checkNonEditable(e, selRange) { var i =0; var nodes = selRange.cloneContents().querySelectorAll("[contenteditable='false']"); for (i =0; i< nodes.length; i++) { if (nodes[i].tagName !="A") { e.preventDefault(); return true; } } return false; } function checkBackspaceForNoEditable(elem) { var elem = elem.previousElementSibling; while (elem) { if ((elem.contentEditable == "false" || elem.readonly == "true" || elem.classList.contains('lasso-undeletable')) && elem.tagName !="A") { return true; } if (elem.innerHTML.includes(""); if (!$pos) return -1; global $wp; $url = home_url( $wp->request ); $index = intval(basename($url)) == 0 ? 0 : intval(basename($url))-1; return $index; } public function scripts(){ global $post; if ( lasso_user_can('edit_posts') /* uncomment this line to disable Editus on Gutenberg posts*/ /* && !( function_exists( 'has_blocks' ) && has_blocks( $post->post_content) && !is_home()) */ ) { /** Returns the time offset from UTC */ function get_UTC_offset() { $timezone_string = get_option( 'timezone_string' ); if (empty( $timezone_string ) ) { return get_option('gmt_offset')*3600; } $origin_dtz = new \DateTimeZone($timezone_string); $origin_dt = new \DateTime("now", $origin_dtz); $offset = $origin_dtz->getOffset($origin_dt); return $offset; } wp_enqueue_style('lasso-style', LASSO_URL.'/public/assets/css/lasso.css', LASSO_VERSION, true); //don't load autocomplete if it's a stockholm theme $themename = wp_get_theme()->get('Name'); if ($themename !='Stockholm' ) { wp_enqueue_script('jquery-ui-autocomplete'); } wp_enqueue_script('jquery-ui-draggable'); wp_enqueue_script('jquery-ui-sortable'); wp_enqueue_script('jquery-ui-slider'); // media uploader wp_enqueue_media(); // url for json api $home_url = function_exists('json_get_url_prefix') ? json_get_url_prefix() : false; $article_object = lasso_editor_get_option('article_class','lasso_editor'); $article_object = empty( $article_object ) && lasso_get_supported_theme_class() ? lasso_get_supported_theme_class() : $article_object; $featImgClass = lasso_editor_get_option('featimg_class','lasso_editor'); if (empty( $featImgClass )) { $featImgClass = lasso_get_supported_theme_featured_image_class(); } $titleClass = lasso_editor_get_option('title_class','lasso_editor'); if (empty( $titleClass )) { $titleClass = lasso_get_supported_theme_title_class(); } $toolbar_headings = lasso_editor_get_option('toolbar_headings', 'lasso_editor'); $toolbar_headings_h4 = lasso_editor_get_option('toolbar_headings_h4', 'lasso_editor'); $objectsNoSave = lasso_editor_get_option('dont_save', 'lasso_editor'); $objectsNonEditable = lasso_editor_get_option('non_editable', 'lasso_editor'); $disableRESTSave = lasso_editor_get_option('save_using_rest_disabled', 'lasso_editor'); $save_to_post_disabled = lasso_editor_get_option( 'post_save_disabled', 'lasso_editor' ); $edit_post_disabled = lasso_editor_get_option( 'post_edit_disabled', 'lasso_editor' ); $bold_tag = lasso_editor_get_option('bold_tag', 'lasso_editor','b'); $i_tag = lasso_editor_get_option('i_tag', 'lasso_editor','i'); $use_old_wpimg = lasso_editor_get_option('use_old_wpimg', 'lasso_editor','off'); $use_wpimgblock = false; $text_select_popup = lasso_editor_get_option('text_select_popup', 'lasso_editor', false); $link_prefix_http = lasso_editor_get_option('link_prefix_http', 'lasso_editor', 'off'); $inherit_categories = lasso_editor_get_option('inherit_categories', 'lasso_editor', 'off'); //text alignement $show_align = lasso_editor_get_option('toolbar_show_alignment', 'lasso_editor'); //make links editable under the editing mode $links_editable = lasso_editor_get_option('links_editable', 'lasso_editor'); //color $show_color = lasso_editor_get_option('toolbar_show_color', 'lasso_editor'); // allow change date for post $allow_change_date = lasso_editor_get_option('allow_change_date', 'lasso_editor'); //disable shortcode editing $disable_shortcode_editing = lasso_editor_get_option('disable_shortcode_editing', 'lasso_editor'); // support custom taxonomy $support_custom_taxonomy = lasso_editor_get_option('support_custom_taxonomy', 'lasso_editor'); if ($show_color) { //color picker wp_enqueue_style( 'wp-color-picker' ); wp_enqueue_script( 'iris', admin_url( 'js/iris.min.js' ), array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), false, 1 ); } // click to insert components, not drag and drop $insert_comp_ui = lasso_editor_get_option('insert_comp_ui', 'lasso_editor'); // do we support pending status $no_pending_status = lasso_editor_get_option('no_pending_status', 'lasso_editor'); // custom fields $custom_fields = apply_filters( 'editus_custom_fields', null ); // post id reference $postid = get_the_ID(); $tz_offset = get_UTC_offset(); $post_date = get_the_time('U', $postid); $time = (time()+$tz_offset); $delta = $time - $post_date; $strings = array( 'save' => __('Save','lasso'), 'selectText' => __('Please Select Text First.','lasso'), 'cancel' => __('Cancel','lasso'), 'exiteditor' => __('Exit Editor','lasso'), 'saving' => __('Saving...','lasso'), 'saved' => __('Saved!','lasso'), 'adding' => __('Adding...','lasso'), 'added' => __('Added!','lasso'), 'loading' => __('Loading...','lasso'), 'loadMore' => __('Load More','lasso'), 'close' => __('Close','lasso'), 'noPostsFound' => __('No more posts found','lasso'), 'fetchFail' => __('Fetching failed.','lasso'), 'galleryCreated' => __('Gallery Created!','lasso'), 'galleryUpdated' => __('Gallery Updated!','lasso'), 'justWrite' => __('Just write...','lasso'), 'chooseImage' => __('Choose an image','lasso'), 'updateImage' => __('Update Image','lasso'), 'insertImage' => __('Insert Image','lasso'), 'selectImage' => __('Select Image','lasso'), 'removeFeatImg' => __('Remove featured image?','lasso'), 'updateSelectedImg' => __('Update Selected Image','lasso'), 'chooseImages' => __('Choose images','lasso'), 'editImage' => __('Edit Image','lasso'), 'addImages' => __('Add Images','lasso'), 'addNewGallery' => __('Add New Gallery','lasso'), 'selectGallery' => __('Select Editus Gallery Image','lasso'), 'useSelectedImages' => __('Use Selected Images','lasso'), 'publishPost' => __('Publish Post?','lasso'), 'publishYes' => __('Yes, publish it!','lasso'), 'deletePost' => __('Trash Post?','lasso'), 'deleteYes' => __('Yes, trash it!','lasso'), 'warning' => __('Oh snap!','laso'), 'cancelText' => __('O.K. got it!','lasso'), 'missingClass' => __('It looks like we are either missing the Article CSS class, or it is configured incorrectly. Editus will not function correctly without this CSS class.','lasso'), 'missingConfirm' => __('Update Settings', 'lasso'), 'helperText' => __('one more letter','lasso'), 'editingBackup' => __('You are currently editing a backup copy of this post.'), 'catsPlaceholder' => __('add categories...'), 'tagsPlaceholder' => __('add tags...'), 'taxoPlaceholder' => __('add taxonomy terms...'), 'editShortcode' => __('Edit Shortcode'), ); $api_url = trailingslashit( home_url() ) . 'lasso-internal-api'; $gallery_class = new gallery(); $gallery_nonce_action = $gallery_class->nonce_action; $gallery_nonce = wp_create_nonce( $gallery_nonce_action ); if ($allow_change_date) { $permalink = get_site_url().'/?p='.$postid; } else { $permalink = get_permalink($postid); } // rest api $rest_nonce = ''; $rest_root = site_url().'/?rest_route=/'; if (function_exists('rest_url')) { //$rest_root = esc_url_raw( rest_url()); $rest_nonce = wp_create_nonce( 'wp_rest' ); $settings = array( 'root' => $rest_root, 'nonce' => $rest_nonce ); wp_enqueue_script( 'wp-api', '', array( 'jquery', 'underscore', 'backbone' ), LASSO_VERSION, true ); wp_localize_script( 'wp-api', 'wpApiSettings', $settings ); wp_localize_script( 'wp-api', 'WP_API_Settings', $settings ); if ( class_exists( 'WP_REST_Controller' )) { // we are using REST API V2 $using_restapiv2 = true; } } //excerpt $post_excerpt = ""; $post_excerpt = wp_strip_all_tags($post->post_excerpt,true); //find if this is multi page. -1 if not $multipage = self::is_multipage(); $post_content = ""; //pass post_content if we need to process multipage. In future we may need to pass this for other purposes //if ($multipage != -1) { $post_content = $post->post_content; //} //get custom taxonomy $custom_taxonomies = array_diff(get_object_taxonomies( get_post_type( $postid ), 'names' ), ['category','post_tag','post_format']); $post_taxo_arr = array(); foreach ($custom_taxonomies as $taxonomy) { $post_taxo_arr[$taxonomy] = lasso_get_post_objects( $postid, $taxonomy ); } $existing_taxo_arr = array(); foreach ($custom_taxonomies as $taxonomy) { $existing_taxo_arr[$taxonomy] = lasso_get_objects( $taxonomy ); } $new_post_text = lasso_editor_get_option( 'new_post_text', 'lasso_editor' ); $new_post_text = !empty($new_post_text) ? $new_post_text : wp_strip_all_tags(apply_filters( 'lasso_new_object_content', __( 'Once upon a time...','lasso'))); wp_reset_query(); $cat_new_post = ($inherit_categories =='on' && !is_home() && !is_page()) ? get_the_category() : null; // localized objects $objects = array( 'ajaxurl' => esc_url( $api_url ), 'ajaxurl2' => esc_url( admin_url( 'admin-ajax.php' )), 'siteUrl' => site_url(), 'rest_root' => $rest_root, 'rest_nonce' => $rest_nonce, 'editor' => 'lasso--content', // ID of editable content (without #) DONT CHANGE 'article_object' => $article_object, 'featImgClass' => $featImgClass, 'titleClass' => $titleClass, 'strings' => $strings, 'settingsLink' => function_exists('is_multisite') && is_multisite() ? network_admin_url( 'settings.php?page=lasso-editor' ) : admin_url( 'admin.php?page=lasso-editor-settings' ), 'post_status' => get_post_status( $postid ), 'postid' => $postid, 'permalink' => $permalink, 'edit_others_pages' => current_user_can('edit_others_pages') ? true : false, 'edit_others_posts' => current_user_can('edit_others_posts') ? true : false, 'userCanEdit' => current_user_can('edit_post', $postid ), 'can_publish' => is_page() ? current_user_can('publish_pages') : current_user_can('publish_posts'), //'can_publish_posts' => current_user_can('publish_posts'), //'can_publish_pages' => current_user_can('publish_pages'), 'author' => is_user_logged_in() ? get_current_user_ID() : false, 'nonce' => wp_create_nonce('lasso_editor'), 'handle' => lasso_editor_settings_toolbar(), 'toolbar' => lasso_editor_text_toolbar(), 'toolbarPopup' => $text_select_popup ? lasso_editor_selected_text_toolbar(): false, 'toolbarHeadings' => $toolbar_headings, 'toolbarHeadingsH4' => $toolbar_headings_h4, 'component_modal' => lasso_editor_component_modal(), 'component_sidebar' => lasso_editor_component_sidebar(), 'components' => lasso_editor_components(), 'wpImgEdit' => lasso_editor_wpimg_edit(), 'wpImgBlockEdit' => lasso_editor_wpimg_block_edit(), 'wpVideoEdit' => lasso_editor_wpvideo_edit(), 'featImgControls' => lasso_editor_image_controls(), 'featImgNonce' => $gallery_nonce, 'getGallImgNonce' => $gallery_nonce, 'createGallNonce' => $gallery_nonce, 'swapGallNonce' => $gallery_nonce, 'titleNonce' => wp_create_nonce('lasso_update_title'), 'wpImgNonce' => wp_create_nonce('lasso_update_wpimg'), 'deletePost' => wp_create_nonce('lasso_delete_post'), 'searchPosts' => wp_create_nonce('lasso_search_posts'), 'component_options' => lasso_editor_options_blob(), 'newPostModal' => lasso_editor_newpost_modal(), 'allPostModal' => lasso_editor_allpost_modal(), 'mapFormFooter' => lasso_map_form_footer(), 'refreshRequired' => lasso_editor_refresh_message(), 'objectsNoSave' => $objectsNoSave, 'objectsNonEditable' => $objectsNonEditable, 'supportedNoSave' => lasso_supported_no_save(), 'postCategories' => lasso_get_objects('category'), 'postTags' => lasso_get_objects('tag'), 'postCusTaxonomies' => $post_taxo_arr, 'extCusTaxonomies' => $existing_taxo_arr, 'noResultsDiv' => lasso_editor_empty_results(), 'noRevisionsDiv' => lasso_editor_empty_results('revision'), 'mapTileProvider' => function_exists('aesop_map_tile_provider') ? aesop_map_tile_provider( $postid ) : false, 'mapLocations' => get_post_meta( $postid, 'ase_map_component_locations' ), 'mapStart' => get_post_meta( $postid, 'ase_map_component_start_point', true ), 'mapZoom' => get_post_meta( $postid, 'ase_map_component_zoom', true ), 'revisionModal' => lasso_editor_revision_modal(), 'isMobile' => wp_is_mobile(), 'enableAutoSave' => lasso_editor_get_option( 'enable_autosave', 'lasso_editor' ), 'showColor' => $show_color, 'showAlignment' => $show_align, 'showIgnoredItems' => lasso_editor_get_option('show_ignored_items', 'lasso_editor'), 'restapi2' => $using_restapiv2, 'saveusingrest' => $using_restapiv2 && !$disableRESTSave, 'newObjectContent' => '

      ', 'disableSavePost' => $save_to_post_disabled, 'disableEditPost' => $edit_post_disabled, 'disableEditSC' => $disable_shortcode_editing, 'boldTag' => $bold_tag, 'iTag' => $i_tag, 'customFields' => $custom_fields, 'clickToInsert' => ($insert_comp_ui =='click'), 'buttonOnEmptyP' => ($insert_comp_ui =='mediumcom'), // auto show a button to insert components on an empty paragraph 'rtl' => is_rtl(), 'skipToEdit' =>( $delta < 10 && $delta >=0 ), // if it's a new post, skip to edit mode 'linksEditable' => $links_editable, 'supportPendingStatus' => !$no_pending_status, 'tableCode' => apply_filters( 'lasso_table_html_code','
      Cell 1Cell 2
      Cell 3Cell 4

      '), 'hasGutenberg' => (function_exists( 'has_blocks' ) && has_blocks( $post->post_content)) || self::gutenberg_active(),//, 'multipages'=> $multipage, 'post_content'=>$post_content, 'post_excerpt'=>$post_excerpt, 'supCustTaxo' => $support_custom_taxonomy == 'on', 'oldWPimg'=> $use_old_wpimg =='on', 'useWPImgBlk'=> $use_wpimgblock, 'prefixHTTP'=> $link_prefix_http =='on', 'currCat'=> $cat_new_post ); // wp api if (!$using_restapiv2) { // enqueue REST API V1 wp_enqueue_script( 'wp-api-js', LASSO_URL.'/public/assets/js/source/util--wp-api.js', array( 'jquery', 'underscore', 'backbone' ), LASSO_VERSION, true ); $settings = array( 'root' => home_url( $home_url ), 'nonce' => wp_create_nonce( 'wp_json' ) ); wp_localize_script( 'wp-api-js', 'WP_API_Settings', $settings ); } if ($allow_change_date) { wp_enqueue_script('jquery-ui-datepicker'); wp_register_style('jquery-ui', '//ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css'); wp_enqueue_style('jquery-ui'); } $postfix = ( defined( 'SCRIPT_DEBUG' ) && true === SCRIPT_DEBUG ) ? '' : '.min'; if ($show_color) { wp_enqueue_script('lasso', LASSO_URL. "/public/assets/js/lasso{$postfix}.js", array('jquery', 'wp-api','iris'), LASSO_VERSION, true); } else { wp_enqueue_script('lasso', LASSO_URL. "/public/assets/js/lasso{$postfix}.js", array('jquery', 'wp-api'), LASSO_VERSION, true); } wp_localize_script('lasso', 'lasso_editor', apply_filters('lasso_localized_objects', $objects ) ); } } function gutenberg_active() { // Gutenberg plugin is installed and activated. $gutenberg = ! ( false === has_filter( 'replace_editor', 'gutenberg_init' ) ); // Block editor since 5.0. $block_editor = version_compare( $GLOBALS['wp_version'], '5.0-beta', '>' ); if ( ! $gutenberg && ! $block_editor ) { return false; } if ( self::is_classic_editor_plugin_active() ) { $editor_option = get_option( 'classic-editor-replace' ); $block_editor_active = array( 'no-replace', 'block' ); return in_array( $editor_option, $block_editor_active, true ); } return true; } /** * Check if Classic Editor plugin is active. * * @return bool */ function is_classic_editor_plugin_active() { if ( ! function_exists( 'is_plugin_active' ) ) { include_once ABSPATH . 'wp-admin/includes/plugin.php'; } if ( is_plugin_active( 'classic-editor/classic-editor.php' ) ) { return true; } return false; } } ================================================ FILE: public/includes/components.php ================================================ array( 'name' => __('Quote','lasso'), 'content' => lasso_quote_component(), ), 'image' => array( 'name' => __('Image','lasso'), 'content' => lasso_image_component(), ), 'parallax' => array( 'name' => __('Parallax','lasso'), 'content' => lasso_parallax_component(), ), 'audio' => array( 'name' => __('Audio','lasso'), 'content' => lasso_audio_component(), ), 'content' => array( 'name' => __('Content','lasso'), 'content' => lasso_content_component(), ), 'character' => array( 'name' => __('Character','lasso'), 'content' => lasso_character_component(), ), 'collection' => array( 'name' => __('Collection','lasso'), 'content' => lasso_collections_component(), ), 'document' => array( 'name' => __('Document','lasso'), 'content' => lasso_document_component(), ), 'gallery' => array( 'name' => __('Gallery','lasso'), 'content' => lasso_gallery_component(), ), 'chapter' => array( 'name' => __('Chapter','lasso'), 'content' => lasso_heading_component(), ), 'map' => array( 'name' => __('Map','lasso'), 'content' => lasso_map_component(), ), 'timeline_stop' => array( 'name' => __('Timeline','lasso'), 'content' => lasso_timeline_component(), ), 'video' => array( 'name' => __('Video','lasso'), 'content' => lasso_video_component(), ), 'wpimg' => array( 'name' => __('WordPress Image','lasso'), 'content' => lasso_wp_image(), ), 'wpimg-block' => array( 'name' => __('WordPress Image Block','lasso'), 'content' => lasso_wp_image_block(), ), 'wpquote' => array( 'name' => __('WordPress Quote','lasso'), 'content' => lasso_wp_quote(), ), 'gallery_pop' => array( 'name' => __('Gallery Pop','lasso'), 'content' => lasso_gallery_pop_component(), ), 'events' => array( 'name' => __('Events','lasso'), 'content' => lasso_event_component(), ), 'wpvideo' => array( 'name' => __('WordPress Image','lasso'), 'content' => lasso_wp_video(), ), ); return apply_filters( 'lasso_components', $array ); } /** * Here each of the components content is being registered and retrieved above * * Notes: - these functions are pluggable * - custom modules must have data-component-type="whatever" * - custom modules must have all options as data-attributes if utilizing settings panel * * 1. Quote * 2. Image * 3. Parallax * 4. Audio * 5. Content * 6. Character * 7. Collections * 8. Document * 9. Gallery * 10. Heading * 11. Map * 12. Timeline * 13. Video */ // 1 if ( !function_exists( 'lasso_quote_component' ) ): function lasso_quote_component() { return do_shortcode( '[aesop_quote quote="The Universe is made of stories, not of atoms."]' ); } endif; // 2 if ( !function_exists( 'lasso_image_component' ) ): function lasso_image_component() { return do_shortcode( '[aesop_image img="'.LASSO_URL.'/public/assets/img/empty-img.png" align="center" imgwidth="100%"]' ); } endif; // 3 if ( !function_exists( 'lasso_parallax_component' ) ): function lasso_parallax_component() { return do_shortcode( '[aesop_parallax img="'.LASSO_URL.'/public/assets/img/empty-img.png"]' ); } endif; // 4 if ( !function_exists( 'lasso_audio_component' ) ): function lasso_audio_component() { return do_shortcode( '[aesop_audio src="http://users.skynet.be/fa046054/home/P22/track06.mp3"]' ); } endif; // 5 if ( !function_exists( 'lasso_content_component' ) ): function lasso_content_component() { return do_shortcode( '[aesop_content]Start typing here...[/aesop_content]' ); } endif; // 6 if ( !function_exists( 'lasso_character_component' ) ): function lasso_character_component() { return do_shortcode( '[aesop_character img="'.LASSO_URL.'/public/assets/img/empty-img.png" name="Joes Apartment" width="150px"]' ); } endif; // 7 if ( !function_exists( 'lasso_collections_component' ) ): function lasso_collections_component() { return do_shortcode( '[aesop_collection]' ); } endif; // 8 if ( !function_exists( 'lasso_document_component' ) ): function lasso_document_component() { return do_shortcode( '[aesop_document src="'.LASSO_URL.'/public/assets/img/empty-img.png" ]' ); } endif; // 9 if ( !function_exists( 'lasso_gallery_component' ) ): function lasso_gallery_component() { return do_shortcode( '[aesop_gallery]' ); } endif; // 10 if ( !function_exists( 'lasso_heading_component' ) ): function lasso_heading_component() { return do_shortcode( '[aesop_chapter title="Chapter One" img="'.LASSO_URL.'/public/assets/img/empty-img.png" full="on"]' ); } endif; // 11 if ( !function_exists( 'lasso_map_component' ) ): function lasso_map_component() { return ' '.lasso_map_form_footer().' '.do_shortcode( '[aesop_map sticky="off"]' ).' '; } endif; // 12 if ( !function_exists( 'lasso_timeline_component' ) ): function lasso_timeline_component() { return do_shortcode( '[aesop_timeline_stop num="2014" title="Title"]' ); } endif; // 13 if ( !function_exists( 'lasso_video_component' ) ): function lasso_video_component() { return do_shortcode( '[aesop_video src="vimeo" id="59940289" width="100%" align="center"]' ); } endif; // 14 - since 0.9.1 if ( !function_exists('lasso_wp_image') ): function lasso_wp_image(){ $use_old_wpimg = lasso_editor_get_option('use_old_wpimg', 'lasso_editor','off'); $use_wp_block_image = lasso_editor_get_option('use_wp_block_image', 'lasso_editor','off'); if ($use_wp_block_image == 'on') { return '


      '; } else if ($use_old_wpimg != 'on') { return '


      '; } else { return '


      '; } } endif; // 15 - since 0.9.2 if ( !function_exists('lasso_wp_quote') ): function lasso_wp_quote(){ return '

      The universe is made of stories.


      '; } endif; // 16 gallery pop added but not fully supported as of 0.9.9.11 if ( !function_exists( 'lasso_gallery_pop_component' ) ): function lasso_gallery_pop_component() { return do_shortcode( '[aesop_gallery_pop]' ); } endif; // 17 - work in progress if ( !function_exists( 'lasso_event_component' ) ): function lasso_event_component() { $id = editus_get_one_id('aesop_events'); return '

      Aesop Event: After setting the event, save and reload the page.

      '; } endif; // 18 - work in progress if ( !function_exists('lasso_wp_video') ): function lasso_wp_video(){ return '
      '; } endif; if ( !function_exists('lasso_wp_image_block') ): function lasso_wp_image_block(){ return '


      '; } endif; // helper function to retrieve one id for default option function editus_get_one_id($type) { $args = array( 'posts_per_page' => 1, 'post_type' => $type ); $posts = get_posts( $args ); if ( $posts ) { foreach ( $posts as $post ) { return $post->ID; } } return -1; } ================================================ FILE: public/includes/editor-modules--gallery.php ================================================
        >
      >
        >
      • >
        >
      post_excerpt; ?>
      ">
      labels; $labels->name = 'Articles'; ob_start(); // post status $status = get_post_status( get_the_ID() ); // let users add custom css classes $custom_classes = apply_filters( 'lasso_modal_all_post_classes', '' ); ?>
        $label ) { if (array_key_exists($name, $rest_bases)) { printf( '
      • %3s
      • ', esc_attr( $first), esc_attr( $rest_bases[$name] ), esc_attr( $label ) ); } $first = ''; } } do_action('lasso_modal_post_objects');?>
        $shortcode ) { $return = ''; // Shortcode has atts if ( count( $shortcode['atts'] ) && $shortcode['atts'] ) { foreach ( $shortcode['atts'] as $attr_name => $attr_info ) { $prefix = isset( $attr_info['prefix'] ) ? sprintf( '%s', $attr_info['prefix'] ) : null; $return .= '
        '; $return .= '

        '; $return .= ''; $return .= ''.$attr_info['tip'].''; // Select if ( isset( $attr_info['values'] ) ) { $return .= ''; } else { $attr_field_type = isset( $attr_info['type'] ) ? $attr_info['type'] : 'text'; // image upload if ( 'media_upload' == $attr_info['type'] ) { $return .= ''; $return .= ''; } elseif ( 'color' == $attr_info['type'] ) { $return .= ''; } elseif ( 'text_area' == $attr_info['type'] ) { $return .= ''.$prefix.''; } else { $return .= ''.$prefix.''; } } $return .= '

        '; } } /////////////////////////// // START GALLERY AND MAP FRONT END STUFFS /////////////////////////// if ( isset( $shortcode['front'] ) && true == $shortcode['front'] ) { if ( 'gallery' == $shortcode['front_type'] ) { $return .= lasso_gallery_editor_module(); } } /////////////////////////// // END GALLERY AND MAP FRONT END STUFFS /////////////////////////// // Single shortcode (not closed) if ( 'single' == $shortcode['type'] ) { $return .= ''; } else { $return .= '

        '; } $return .= '

        Cancel

        '; $return .= ''; $return .= ''; $return .= ''; $return .= '
        '; // extra JS codes if (isset($shortcode['codes'])) { $return .= $shortcode['codes']; } $blob[$slug] = $return; } return $blob; } function add_wpimg_options( $shortcodes ) { $custom = array( 'wpimg' => array( 'name' => __( 'Image', 'lasso' ), 'type' => 'single', 'atts' => array( 'img' => array( 'type' => 'media_upload', 'default' => '', 'desc' => __( 'Image URL', 'lasso' ), 'tip' => __( 'URL for the image. Click Select Media to open the WordPress Media Library.', 'aesop-core' ) ), 'align' => array( 'type' => 'select', 'values' => array( array( 'value' => 'center', 'name' => __( 'Center', 'aesop-core' ) ), array( 'value' => 'left', 'name' => __( 'Left', 'aesop-core' ) ), array( 'value' => 'right', 'name' => __( 'Right', 'aesop-core' ) ), ), 'default' => 'center', 'desc' => __( 'Alignment', 'lasso' ), 'tip'=>'' ), 'imgwidth' => array( 'type' => 'text_small', 'default' => '300px', 'desc' => __( 'Image Width', 'lasso' ), 'tip' => __( 'Width of the image. You can enter the size in pixels or percentage such as 40% or 500px.', 'aesop-core' ) ), 'imgheight' => array( 'type' => 'text_small', 'default' => '', 'desc' => __( 'Image Height', 'lasso' ), 'tip' => __( 'Used only for the Panorama mode. Can be set using pixel values such as 500px. If unspecified, the original height would be used. ', 'aesop-core' ) ), 'linkoption' => array( 'type' => 'select', 'values' => array( array( 'value' => 'none', 'name' => __( 'None', 'aesop-core' ) ), array( 'value' => 'img', 'name' => __( 'Image', 'aesop-core' ) ), array( 'value' => 'url', 'name' => __( 'URL', 'aesop-core' ) ), ), 'default' => 'none', 'desc' => __( 'Link', 'lasso' ), 'tip' => __( 'Click leads to:', 'lasso' ) ), 'link' => array( 'type' => 'text', 'default' => '', 'desc' => __( 'URL Link', 'lasso' ), 'tip' => __( 'URL link', 'lasso' ) ), 'alt' => array( 'type' => 'text', 'default' => '', 'desc' => __( 'Image ALT', 'lasso' ), 'tip' => __( 'ALT tag used for the image. Primarily used for SEO purposes.', 'lasso' ) ), 'caption' => array( 'type' => 'text_area', 'default' => '', 'desc' => __( 'Caption', 'lasso' ), 'tip' => __( 'Optional caption for the image.', 'lasso' ) ), ), 'desc' => __( 'An image.', 'aesop-core' ), 'codes' => '' ) ); return array_merge( $shortcodes, $custom ); } function add_wpimg_block_options( $shortcodes ) { $custom = array( 'wpimg-block' => array( 'name' => __( 'Image', 'lasso' ), 'type' => 'single', 'atts' => array( 'img' => array( 'type' => 'media_upload', 'default' => '', 'desc' => __( 'Image URL', 'lasso' ), 'tip' => __( 'URL for the image. Click Select Media to open the WordPress Media Library.', 'aesop-core' ) ), 'align' => array( 'type' => 'select', 'values' => array( array( 'value' => 'center', 'name' => __( 'Center', 'aesop-core' ) ), array( 'value' => 'left', 'name' => __( 'Left', 'aesop-core' ) ), array( 'value' => 'right', 'name' => __( 'Right', 'aesop-core' ) ), ), 'default' => 'center', 'desc' => __( 'Alignment', 'lasso' ), 'tip'=>'' ), 'alt' => array( 'type' => 'text', 'default' => '', 'desc' => __( 'Image ALT', 'lasso' ), 'tip' => __( 'ALT tag used for the image. Primarily used for SEO purposes.', 'lasso' ) ), 'caption' => array( 'type' => 'text', 'default' => '', 'desc' => __( 'Caption', 'lasso' ), 'tip' => __( 'Optional caption for the image.', 'lasso' ) ), 'link' => array( 'type' => 'text', 'default' => '', 'desc' => __( 'Link URL', 'lasso' ), 'tip' => __( 'Optional URL to link.', 'lasso' ) ), ), 'desc' => __( 'A WP Image Block.', 'aesop-core' ), 'codes' => '' ) ); return array_merge( $shortcodes, $custom ); } function add_wpcover_block_options( $shortcodes ) { $custom = array( 'wpcover-block' => array( 'name' => __( 'Cover', 'lasso' ), 'type' => 'single', 'atts' => array( 'img' => array( 'type' => 'media_upload', 'default' => '', 'desc' => __( 'Image URL', 'lasso' ), 'tip' => __( 'URL for the image. Click Select Media to open the WordPress Media Library.', 'aesop-core' ) ) ), 'desc' => __( 'A WP Cover Block.', 'aesop-core' ), 'codes' => '' ) ); return array_merge( $shortcodes, $custom ); } /** * Revisions modal * * @since 0.9.8 * * @return string */ function lasso_editor_revision_modal() { ob_start(); ?>
        'ai_galleries', 'post_status' => 'publish' ) ); if ( $q->have_posts() ) return true; else return false; } /** * Return a CSS class of an automatically supported theme * * @since 0.8.6 * @return a css class if the theme is supported, false if nothing */ function lasso_get_supported_theme_class() { $name = wp_get_theme()->get('Name'); $slug = lasso_clean_string( $name ); switch ( $slug ) { case 'aesop-story-theme': // aesop $out = '.aesop-entry-content'; break; case 'jorgen': // aesop $out = '.jorgen-entry-content'; break; case 'novella': // aesop $out = '.novella-entry-content'; break; case 'genji': // aesop $out = '.genji-entry-content'; break; case 'kerouac': // aesop $out = '.kerouac-entry-content'; break; case 'zealot': // aesop $out = '.zealot-entry-content'; break; case 'fable': // aesop $out = '.fable--entry-content'; break; case 'canvas': // wootheme..err...Automattic $out = '.entry'; break; case 'kleo': // $out = '.article-content'; break; //case 'exposure': // // $out = '.entry-content'; // break; //case 'lore': // // $out = '.entry-content'; // break; //case 'worldview': // upthemes // $out = '.entry-content'; // break; //case 'genesis': // genesis // $out = '.entry-content'; // break; //case 'camera': // array.is // $out = '.entry-content'; // break; case 'longform': $out = '.entry-content-wrapper'; break; } return apply_filters('lasso_content_class', !empty( $out ) ? $out : false); //return !empty( $out ) ? $out : false; } function lasso_get_supported_theme_title_class() { $name = wp_get_theme()->get('Name'); $slug = lasso_clean_string( $name ); switch ( $slug ) { case 'aesop-story-theme': // aesop $out = '.aesop-entry-title'; break; case 'jorgen': // aesop $out = '.jorgen-entry-title'; break; case 'genji': // aesop $out = '.genji-entry-title'; break; case 'kerouac': // aesop $out = '.kerouac-entry-title'; break; case 'zealot': // aesop $out = '.zealot-entry-title'; break; case 'fable': // aesop $out = '.fable--entry-title'; break; case 'kleo': // $out = '.page-title'; break; case 'longform': // $out = '.entry-title'; break; } return apply_filters('lasso_title_class', !empty( $out ) ? $out : false); } //since 0.9.9.6 function lasso_get_supported_theme_featured_image_class() { $name = wp_get_theme()->get('Name'); $slug = lasso_clean_string( $name ); return apply_filters('lasso_featured_image_class', !empty( $out ) ? $out : false); } /** * Return a string of classes with items that Editus will remove when entering the editor * so that we don't save them as HTML * * @since 0.8.7 * @return string of comma separated classes */ function lasso_supported_no_save(){ return apply_filters('lasso_dont_save', '.lasso--ignore,.sharedaddy,.us_wrapper,.meta,.edit-link,.ssba,.addtoany_share_save_container,.mashsb-container,.heateor_sss_sharing_container,.nc_socialPanel,.jp-relatedposts,.fb-comments,.adsbygoogle,.swp_social_panel,.code-block'); } /** * Generic sanitization, useful for sanitization of arrays. * * @since 0.9.2 * * @param array|object|string $data Data to sanatize. * * @return array|mixed|object|string|void */ function lasso_sanitize_data( $data ) { return \lasso\sanatize::do_sanitize( $data ); } /** * Return a comma delimited list of categories for a specific post object * * @since 0.9.3 * @return string of comma delimited category slugs */ function lasso_get_post_objects( $postid, $taxonomy) { if ( empty( $postid ) ) $postid = get_the_ID(); if ('category' == $taxonomy) { $objects = get_the_category( $postid ); } else if ('tag' == $taxonomy) { $objects = get_the_tags( $postid ); } else { $objects = get_the_terms( $postid, $taxonomy ); } if ( empty( $objects) ) return; $out = ''; foreach( $objects as $object ) { $out .= $object->name.','; } return rtrim($out, ', '); } /** * Return an array of categories for autocomplete * * @since 0.9.3 * @return array all categoiries */ function lasso_get_objects( $taxonomy = 'category' ) { if ('category' == $taxonomy) { $objects = get_categories(array('hide_empty' => 0)); } else if ('tag' == $taxonomy) { $objects = get_tags(array('hide_empty' => 0)); } else { $objects = get_terms( array( 'taxonomy' => $taxonomy, 'hide_empty' => false, )); } if ( empty( $objects) ) return; $out = ""; foreach( $objects as $object ) { $out .= $object->name.','; } return $out; } /** * Get allowed post types for the post chooser modal. * * * @since 0.9.4 */ function lasso_post_types_names() { $post_types = get_post_types( array( 'public' => true, ), 'objects' ); $post_types = array_combine( array_keys( $post_types ), wp_list_pluck( $post_types, 'label' ) ); unset( $post_types[ 'attachment' ] ); /** * Set which post types are allowed * * @since 0.9.4 * * @param array $allowed_post_types Array of names (not labels) of allowed post types. Must be registered. */ $allowed_post_types = lasso_editor_get_option( 'allowed_post_types', 'lasso_editor', array( 'post', 'page') ); $allowed_post_types = apply_filters( 'lasso_allowed_post_types', $allowed_post_types ); if (!current_user_can('edit_pages')) { $allowed_post_types = array_diff($allowed_post_types,array('page')); } foreach( $post_types as $name => $label ) { if ( ! in_array( $name, $allowed_post_types ) ) { unset( $post_types[ $name ] ); } } return $post_types; } function lasso_post_types() { $post_types = get_post_types( array( 'public' => true, ), 'names' ); unset( $post_types[ 'attachment' ] ); /** * Set which post types are allowed * * @since 0.9.4 * * @param array $allowed_post_types Array of names (not labels) of allowed post types. Must be registered. */ $allowed_post_types = lasso_editor_get_option( 'allowed_post_types', 'lasso_editor', array( 'post') ); $allowed_post_types = apply_filters( 'lasso_allowed_post_types', $allowed_post_types ); foreach( $post_types as $name => $label ) { if ( ! in_array( $name, $allowed_post_types ) ) { unset( $post_types[ $name ] ); } } return $post_types; } function lasso_post_types_rest_base() { global $wp_post_types; $post_types = lasso_post_types(); $rest_base = array(); foreach ( $post_types as $post_type) { $rest_base[$post_type] = $wp_post_types[$post_type]->rest_base; } return $rest_base; } //////////////////// // INTERNAL //////////////////// /** * Used internally as a callback to build a tab or content area for modal addons * * @param $tab object * @param $type string tab or content * @uses lasso_modal_addons() * @since 0.9.4 */ function lasso_modal_addons_content( $tab = '', $type ){ $name = lasso_clean_string( $tab['name'] ); if ( 'tab' == $type ) { $out = sprintf( '
      • %s
      • ', $name, $tab['name'] ); } else if ( 'content' == $type ){ $content = isset( $tab['content'] ) && is_callable( $tab['content'] ) ? call_user_func( $tab['content'] ) : false; $options = isset( $tab['options'] ) && is_callable( $tab['options'] ) ? call_user_func( $tab['options'] ) : false; $out = sprintf( '
        %s%s
        ', $name, $content, lasso_option_form( $name, $options ) ); } return $out; } /** * Helper function to clean a string and replace spaces with dash * * @param $string string content * @since 0.9.4 * * @return void|string */ function lasso_clean_string( $string = '' ) { if ( empty( $string ) ) return; return sanitize_text_field( strtolower( preg_replace('/[\s_]/', '-', $string ) ) ); } /** * Helper function to switch - to _ after having. * * This is the evil twin of lasso_clean_string() and may or may not make your data forever unclean. * * @param $string string content * @since 0.9.5 * * @return void|string */ function lasso_unclean_string( $string = '' ) { if ( empty( $string ) ) { return; } return sanitize_text_field( strtolower( str_replace( '-', '_', $string ) ) ); } //////////////////// // PLUGGABLE //////////////////// /** * Check if the user is logged in and has the correctly passed capability * * @param unknown $action string a capability such as edit_posts or publish_posts * @param unknown $postid int the id of the post object to check against * @since 0.9.9.7 added filter 'lasso_user_can_filter' */ if ( !function_exists( 'lasso_user_can' ) ): function lasso_user_can( $action = '', $postid = 0 ) { $result = false; if ( empty( $action ) ) $action = 'edit_posts'; if ( empty( $postid ) && $action != 'edit_posts' && $action != 'publish_posts' && $action != 'delete_posts') $postid = get_the_ID(); if ( is_user_logged_in() && current_user_can( $action, $postid ) ) { // check against post types: $allowed_post_types = lasso_editor_get_option( 'allowed_post_types', 'lasso_editor', array( 'post', 'page') ); if (!current_user_can('edit_pages')) { $allowed_post_types = array_diff($allowed_post_types,array('page')); } if (!empty($allowed_post_types) && !empty($postid)) { $type = get_post_type( $postid ); $allowed_post_types = apply_filters( 'lasso_allowed_post_types', $allowed_post_types ); if ( in_array( $type, $allowed_post_types ) ) { $result = true; } } else { //we are not checking against a post, return true $result = true; } } else { $result = false; } //if ( function_exists( 'is_gutenberg_page' ) && has_blocks() ) return false; return apply_filters( 'lasso_user_can_filter', $result, $action, $postid); } endif; /** * Empty state message thats shown when no data available * * @since 0.9.5 */ if ( !function_exists('lasso_editor_empty_results') ): function lasso_editor_empty_results( $type = 'posts' ){ if ( 'posts' == $type ) { $string = apply_filters('lasso_empty_state_message', __('No posts to show', 'lasso') ); $icon = 'lasso-icon-file-text2'; $button = false; } elseif ( 'revision' == $type ) { $string = apply_filters('lasso_empty_state_message', __('No revisions found', 'lasso') ); $icon = 'lasso-icon-history'; $button = sprintf('%s', __('Close','lasso') ); } return sprintf('

        %s

        %s
        ', $icon, $string, $button ); } endif; ================================================ FILE: public/includes/lasso.php ================================================ * @license GPL-2.0+ * @link http://aesopinteractive.com * @copyright 2015-2017 Aesopinteractive */ namespace lasso_public_facing; /** * * * @package Lasso * @author Nick Haskins */ class lasso { /** * * * @since 0.0.1 * * @var string */ protected $plugin_slug = 'lasso'; /** * Instance of this class. * * @since 0.0.1 * * @var object */ protected static $instance = null; /** * * * @since 0.0.1 */ private function __construct() { require_once LASSO_DIR.'/public/includes/underscore-templates.php'; require_once LASSO_DIR.'/public/includes/editor-modules.php'; require_once LASSO_DIR.'/public/includes/helpers.php'; require_once LASSO_DIR.'/public/includes/editor-modules--gallery.php'; require_once LASSO_DIR.'/public/includes/components.php'; require_once LASSO_DIR.'/public/includes/option-engine.php'; require_once LASSO_DIR.'/public/includes/wrap-shortcodes.php'; // Activate plugin when new blog is added add_action( 'wpmu_new_blog', array( $this, 'activate_new_site' ) ); // Load plugin text domain add_action( 'init', array( $this, 'load_plugin_textdomain' ) ); add_action( 'wp_ajax_get_aesop_component', array( $this, 'get_aesop_component' ) ); add_action( 'wp_ajax_editus_do_shortcode', array( $this, 'editus_do_shortcode' ) ); add_action( 'wp_ajax_editus_do_block', array( $this, 'editus_do_block' ) ); add_action( 'wp_ajax_editus_lock_post', array( $this, 'editus_lock_post' ) ); add_action( 'wp_ajax_editus_unlock_post', array( $this, 'editus_unlock_post' ) ); add_action( 'wp_ajax_editus_hide_tour', array( $this, 'editus_hide_tour' ) ); add_action( 'wp_ajax_editus_set_post_setting', array( $this, 'editus_set_post_setting' ) ); add_action( 'wp_ajax_editus_get_ase_options', array( $this, 'get_ase_options' ) ); add_action( 'wp_ajax_editus_delete_post', array( $this, 'delete_post' ) ); add_action( 'wp_ajax_editus_featured_img', array( $this, 'set_featured_img' ) ); add_action( 'wp_ajax_editus_del_featured_img', array( $this, 'del_featured_img' ) ); add_action( 'wp_ajax_editus_publish_post', array( $this, 'on_publish_post' ) ); add_action( 'wp_ajax_editus_create_gallery', array( $this, 'create_gallery' ) ); add_action( 'wp_ajax_editus_update_gallery', array( $this, 'update_gallery' ) ); // enable saving custom fields through REST API self::enable_metasave('post'); self::enable_metasave('page'); $default_post_types = apply_filters( 'lasso_allowed_post_types', array( 'post', 'page')); $allowed_post_types = lasso_editor_get_option( 'allowed_post_types', 'lasso_editor', $default_post_types); foreach ( $allowed_post_types as $post_type ) { self::enable_metasave($post_type); } //enqueue assets new assets(); } /** * Return the plugin slug. * * @since 0.0.1 * * @return Plugin slug variable. */ public function get_plugin_slug() { return $this->plugin_slug; } /** * Return an instance of this class. * * @since 0.0.1 * * @return object A single instance of this class. */ public static function get_instance() { // If the single instance hasn't been set, set it now. if ( null == self::$instance ) { self::$instance = new self; } return self::$instance; } /** * Fired when the plugin is activated. * * @since 0.0.1 * * @param boolean $network_wide True if WPMU superadmin uses * "Network Activate" action, false if * WPMU is disabled or plugin is * activated on an individual blog. */ public static function activate( $network_wide ) { if ( function_exists( 'is_multisite' ) && is_multisite() ) { if ( $network_wide ) { // Get all blog ids $blog_ids = self::get_blog_ids(); foreach ( $blog_ids as $blog_id ) { switch_to_blog( $blog_id ); self::single_activate(); } restore_current_blog(); } else { self::single_activate(); } } else { self::single_activate(); } } /** * Fired when the plugin is deactivated. * * @since 0.0.1 * * @param boolean $network_wide True if WPMU superadmin uses * "Network Deactivate" action, false if * WPMU is disabled or plugin is * deactivated on an individual blog. */ public static function deactivate( $network_wide ) { if ( function_exists( 'is_multisite' ) && is_multisite() ) { if ( $network_wide ) { // Get all blog ids $blog_ids = self::get_blog_ids(); foreach ( $blog_ids as $blog_id ) { switch_to_blog( $blog_id ); self::single_deactivate(); } restore_current_blog(); } else { self::single_deactivate(); } } else { self::single_deactivate(); } } /** * Fired when a new site is activated with a WPMU environment. * * @since 0.0.1 * * @param int $blog_id ID of the new blog. */ public function activate_new_site( $blog_id ) { if ( 1 !== did_action( 'wpmu_new_blog' ) ) { return; } switch_to_blog( $blog_id ); self::single_activate(); restore_current_blog(); } /** * Get all blog ids of blogs in the current network that are: * - not archived * - not spam * - not deleted * * @since 0.0.1 * * @return array|false The blog ids, false if no matches. */ private static function get_blog_ids() { global $wpdb; // get an array of blog ids $sql = "SELECT blog_id FROM $wpdb->blogs WHERE archived = '0' AND spam = '0' AND deleted = '0'"; return $wpdb->get_col( $sql ); } /** * Fired for each blog when the plugin is activated. * * @since 0.0.1 */ private static function single_activate() { $curr_version = get_option( 'lasso_version' ); // update upgraded from if ( $curr_version ) { update_option( 'lasso_updated_from', $curr_version ); } // update lasso version option update_option( 'lasso_version', LASSO_VERSION ); // set transietn for activation welcome set_transient( '_lasso_welcome_redirect', true, 30 ); } /** * Fired for each blog when the plugin is deactivated. * * @since 0.0.1 */ private static function single_deactivate() { // @TODO: Define deactivation functionality here } /** * Load the plugin text domain for translation. * * @since 1.0.0 */ public function load_plugin_textdomain() { $domain = $this->plugin_slug; $locale = apply_filters( 'plugin_locale', get_locale(), $domain ); $out = load_textdomain( $domain, trailingslashit( LASSO_DIR ). 'languages/' . $domain . '-' . $locale . '.mo' ); } // new ajax function to lock post for editing public function editus_lock_post() { $post_id= $_POST["postid"]; $locked = wp_check_post_lock($post_id); if (!$locked) { wp_set_post_lock($post_id); echo "true"; } else { $user_info = get_userdata($locked); echo _e( 'Post being edited by ', 'lasso' ).$user_info->first_name . " " . $user_info->last_name; } exit; } public function editus_unlock_post() { $post_id= $_POST["postid"]; $locked = wp_check_post_lock($post_id); if (!$locked) { delete_post_meta( $post_id, '_edit_lock'); } echo "true"; exit; } // new ajax function to update tour setting public function editus_hide_tour() { $user_id = get_current_user_ID(); update_user_meta( $user_id, 'lasso_hide_tour', true ); exit; } public function editus_set_post_setting() { $data = array(); parse_str($_POST['data'], $data); if (!wp_verify_nonce( $data[ 'nonce' ], 'lasso-update-post-settings' )) { wp_send_json_error(); exit; } $status = isset( $data['status'] ) ? $data['status'] : false; $postid = isset( $data['postid'] ) ? $data['postid'] : false; $slug = isset( $data['story_slug'] ) ? $data['story_slug'] : false; $excerpt = isset( $data['excerpt'] ) ? $data['excerpt'] : false; $args = array( 'ID' => (int) $postid, 'post_name' => $slug, 'post_status' => $status, 'post_excerpt' => wp_strip_all_tags($excerpt,true) ); wp_update_post( apply_filters( 'lasso_object_status_update_args', $args ) ); // update categories $cats = isset( $data['story_cats'] ) ? $data['story_cats'] : false; self::set_post_terms( $postid, $cats, 'category' ); // update tags $tags = isset( $data['story_tags'] ) ? $data['story_tags'] : false; self::set_post_terms( $postid, $tags, 'post_tag' ); // update custom taxonomy $custom_taxonomies = isset( $data['story_custom_taxonomies'] ) ? json_decode($data['story_custom_taxonomies']) : false; foreach ($custom_taxonomies as $x => $x_value) { self::set_post_terms( $postid, $x_value, $x ); } //update date $date = isset( $data['post_date'] ) ? $data['post_date'] : false; self::set_date( $postid, $date ); do_action( 'lasso_post_updated', $postid, $slug, $status, get_current_user_ID() ); $response= array( 'link' => get_permalink($postid). (($status=='publish') ? '' : '&preview=true') ); wp_send_json_success($response); exit; } public static function enable_metasave($type) { register_rest_field( $type, 'metadata', array( 'get_callback' => function ( $data ) { return get_post_meta( $data['id']);//, '', '' ); }, 'update_callback' => function( $data, $post ) { foreach ($data as $key => $value) { update_post_meta($post->ID, $key, $value); } return true; } )); } public function editus_do_shortcode() { $code= $_POST["code"]; $code = str_replace('\"', '"', $code); $code_wrapped = lasso_wrap_shortcodes( $code); $out = do_shortcode($code); if ($out != '') { $out = do_shortcode($code_wrapped); echo $out; exit; } // do_shortcode didn't work. Try again using wp_embed /** @var \WP_Embed $wp_embed */ global $wp_embed; $wp_embed->post_ID = $_POST["ID"]; $out =$wp_embed->run_shortcode( $code_wrapped ); echo $out; exit; } public function editus_do_block() { $code= $_POST["code"]; $out = do_blocks( $code ); echo $out; exit; } public function get_aesop_component() { $code= $_POST["code"]; $atts = array( ); foreach ($_POST as $key => $value) { if ($key !="code" && $key !="action") { $atts[$key] = $value; } } if ($code == "aesop_video") { require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-video.php'); echo aesop_video_shortcode($atts); } else if ($code == "aesop_image") { require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-image.php'); echo aesop_image_shortcode($atts); } else if ($code == "aesop_quote") { require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-quote.php'); echo aesop_quote_shortcode($atts); } else if ($code == "aesop_parallax") { require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-parallax.php'); echo aesop_parallax_shortcode($atts); } else if ($code == "aesop_character") { require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-character.php'); echo aesop_character_shortcode($atts); } else if ($code == "aesop_collection") { require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-collections.php'); echo aesop_collection_shortcode($atts); } else if ($code == "aesop_chapter") { require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-heading.php'); echo aesop_chapter_shortcode($atts); } else if ($code == "aesop_content") { require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-cbox.php'); echo aesop_content_shortcode($atts, $atts['content_data']); } else if ($code == "aesop_gallery") { require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-gallery.php'); echo do_shortcode( '[aesop_gallery id="'.$atts["id"].'"]'); } else if ($code == "aesop_audio") { require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-audio.php'); echo aesop_audio_shortcode($atts); } else if ($code == "aesop_document") { require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-document.php'); echo aesop_document_shortcode($atts); } else if ($code == "aesop_timeline_stop") { require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-timeline.php'); echo aesop_timeline_stop_shortcode($atts); } /*else if ($code == "aesop_content") { require_once( ABSPATH . '/wp-content/plugins/aesop-story-engine/public/includes/components/component-content.php'); echo aesop_content_shortcode($atts); }*/ else if ($code == "aesop_wpimg") { self::wpimg($atts); } else if ($code == "aesop_wpimg-block") { self::wpimg_block($atts); } else { $code = '['.$code.' '; foreach ($atts as $key => $value) { $code = ''.$key.'="'.$value.'" '; } $code = $code.']'; echo do_shortcode($code); } echo '


        '; exit; } public static function wpimg($atts) { echo '
        $value) { echo ' data-'.$key.'="'.$value.'"'; } //echo ' class="wp-image- lasso--wpimg__wrap lasso-component">'; echo ' class="wp-caption lasso-component">'; $hrefset = false; if ($atts['link'] != '' && (!isset($atts['linkoption']) || $atts['linkoption']=="url" )) { echo ''; $hrefset = true; } else if (isset($atts['linkoption']) && $atts['linkoption'] == 'img' ) { echo ''; $hrefset = true; } echo ''. $atts['alt']  .  ''; if ($hrefset) { echo ''; } if ($atts['caption']) { echo '
        '.$atts['caption'].'
        '; } echo '
        '; echo '


        '; return; } public static function wpimg_block($atts) { $imgextra = ''; if (!empty($atts['id'])) { $imgextra = 'class="wp-image-'.$atts['id'].'"'; } $figclass = 'aligncenter'; if ($atts['align']=="left") { $figclass = 'alignleft'; } else if ($atts['align']=="right") { $figclass = 'alignright'; } else { $figclass = 'aligncenter'; } if ($atts['align']=="left" || $atts['align']=="right") { echo '
        '; echo '
        '; } else { echo '
        '; } if (!empty($atts['link'])) { echo ''; } echo ''. $atts['alt']  . ''; if ($atts['caption']) { echo '
        '.$atts['caption'].'
        '; } if (!empty($atts['link'])) { echo '
        '; } echo '
        '; if ($atts['align']=="left" || $atts['align']=="right") { echo '
        '; } echo '


        '; return; } public function get_ase_options() { $blob = lasso_editor_options_blob(); $code= $_POST["component"]; echo $blob[$code]; exit; } public function delete_post( ) { $postid = isset( $_POST['postid'] ) ? $_POST['postid'] : false; // bail out if the current user can't publish posts if ( !lasso_user_can( 'delete_post', $postid ) ) return; if (!wp_verify_nonce( $_POST[ 'nonce' ], 'lasso_delete_post' )) { wp_send_json_error(); exit; } $args = array( 'ID' => (int) $postid, 'post_status' => 'trash' ); wp_update_post( apply_filters( 'lasso_object_deleted_args', $args ) ); do_action( 'lasso_object_deleted', $postid, get_current_user_ID() ); exit; } /* This function doesn't actually publish post, but should be called when a post is published */ public function on_publish_post( ) { $post_id = isset( $_POST['postid'] ) ? $_POST['postid'] : false; do_action( 'transition_post_status', 'publish', 'draft', get_post( $post_id ) ); exit; } public function set_featured_img( ) { $postid = isset( $_POST['postid'] ) ? $_POST['postid'] : false; $image_id = isset( $_POST['image_id'] ) ? absint( $_POST['image_id'] ) : false; if (!wp_verify_nonce( $_POST[ 'nonce' ], 'lasso_gallery' )) { wp_send_json_error(); exit; } set_post_thumbnail( $postid, $image_id ); do_action( 'lasso_featured_image_set', $postid, $image_id, get_current_user_ID() ); exit; } public function del_featured_img( ) { $postid = isset( $_POST['postid'] ) ? $_POST['postid'] : false; if (!wp_verify_nonce( $_POST[ 'nonce' ], 'lasso_gallery' )) { wp_send_json_error(); exit; } delete_post_thumbnail( $postid ); do_action( 'lasso_featured_image_deleted', $postid, get_current_user_ID() ); exit; } /*public function revision_get( ) { $args = array(); if ( isset( $_POST[ 'limit' ] ) ) { $args[ 'posts_per_page' ] = $data[ 'limit' ]; }else{ $args[ 'posts_per_page' ] = 6; // we start at revision 0 } $revisions = wp_get_post_revisions( $_POST[ 'postid' ], $args ); if ( is_array( $revisions ) && ! empty( $revisions ) ) { self::set_revisions( $data[ 'postid' ], $revisions ); } return self::$revisions; }*/ public function set_post_terms( $postid, $value, $taxonomy ) { if( $value ) { $value = explode( ',', $value ); $allow_new_category = lasso_editor_get_option( 'allow_new_category', 'lasso_editor' ); if ($taxonomy =='category') { // convert from names to category ids $cats = array(); foreach ($value as $cat) { $cat_id = get_cat_ID($cat); if ($cat_id !=0) { $cats [] = $cat_id; } else if ($allow_new_category) { $cats [] = wp_create_category($cat); } } $value = $cats; } $result = wp_set_object_terms( $postid, $value, $taxonomy ); } else { //remove all terms from post $result = wp_set_object_terms( $postid, null, $taxonomy ); } if ( ! is_wp_error( $result ) ) { return true; }else{ return false; } } public function create_gallery( ) { $postid = isset( $_POST['postid'] ) ? $_POST['postid'] : false; if (!wp_verify_nonce( $_POST[ 'nonce' ], 'lasso_gallery' )) { wp_send_json_error(); exit; } if ( ! lasso_user_can( 'publish_posts' ) ) { return false; } $gallery_ids = isset( $_POST['gallery_ids'] ) ? $_POST['gallery_ids'] : false; // bail if no gallery ids if ( empty( $gallery_ids ) ) { return false; } $type = isset( $_POST['gallery_type'] ) ? $_POST['gallery_type'] : false; $edgallerytitle = isset( $_POST['edgallerytitle'] ) ? $_POST['edgallerytitle'] : $postid.'-'.rand(); // insert a new gallery $args = array( 'post_title' => $edgallerytitle , 'post_status' => 'publish', 'post_type' => 'ai_galleries' ); $postid = wp_insert_post( apply_filters( 'lasso_insert_gallery_args', $args ) ); // update gallery ids if ( $gallery_ids ) { update_post_meta( $postid, '_ase_gallery_images', $gallery_ids ); } // update the gallery type if ( !empty( $type ) ) { update_post_meta( $postid, 'aesop_gallery_type', $type ); } do_action( 'lasso_gallery_published', $postid, $gallery_ids, get_current_user_ID() ); echo json_encode( array( 'message' => 'gallery-created', 'id' => $postid) ); exit; } public function update_gallery( ) { $options = isset( $_POST['fields'] ) ? $_POST['fields'] : false; $postid = !empty( $options ) ? (int) $options['id'] : false; $gallery_ids = isset( $_POST['gallery_ids'] ) ? $_POST['gallery_ids'] : false; if ( $_POST[ 'gallery_type' ] ) { $type = $_POST[ 'gallery_type' ]; }elseif ( ! empty( $options ) && $options[ 'galleryType' ] ) { $type = $options[ 'galleryType' ]; }else{ $type = false; } self::save_gallery_options( $postid, $gallery_ids, $options, $type ); echo json_encode( array('message' => 'gallery-updated') ); exit; } public function save_gallery_options( $postid, $gallery_ids, $options, $type = false ) { // gallery width $gallery_width = isset( $options['width'] ) ? $options['width'] : false; // gallery grid item width $item_width = isset( $options['itemwidth'] ) ? $options['itemwidth'] : false; // caption $caption = isset( $options['caption'] ) ? $options['caption'] : false; // gallery transition $transition = isset( $options['transition'] ) ? $options['transition'] : false; // gallery transition speed $transitionSpeed = isset( $options['speed'] ) ? $options['speed'] : false; // gallery hide thumbs $hideThumbs = isset( $options['hideThumbs'] ) ? $options['hideThumbs'] : false; // photoset layout hardwired to on for now $psLayout = isset( $options['pslayout'] ) ? $options['pslayout'] : false; // photoset layout $psLightbox = 'on';//isset( $options['pslightbox'] ) ? $options['pslightbox'] : false; // hero gallery height $gallery_height = isset( $options['height'] ) ? $options['height'] : false; // update gallery ids if ( !empty( $gallery_ids ) ) { update_post_meta( $postid, '_ase_gallery_images', $gallery_ids ); } update_post_meta( $postid, 'aesop_gallery_type', sanitize_text_field( trim( $type ) ) ); update_post_meta( $postid, 'aesop_gallery_width', sanitize_text_field( trim( $gallery_width ) ) ); update_post_meta( $postid, 'aesop_grid_gallery_width', sanitize_text_field( trim( $item_width ) ) ); update_post_meta( $postid, 'aesop_gallery_caption', sanitize_text_field( trim( $caption ) ) ); update_post_meta( $postid, 'aesop_thumb_gallery_transition', sanitize_text_field( trim( $transition ) ) ); update_post_meta( $postid, 'aesop_thumb_gallery_transition_speed', absint( trim( $transitionSpeed ) ) ); update_post_meta( $postid, 'aesop_thumb_gallery_hide_thumbs', sanitize_text_field( trim( $hideThumbs ) ) ); update_post_meta( $postid, 'aesop_photoset_gallery_layout', sanitize_text_field( trim( $psLayout ) ) ); update_post_meta( $postid, 'aesop_photoset_gallery_lightbox', sanitize_text_field( trim( $psLightbox ) ) ); update_post_meta( $postid, 'aesop_hero_gallery_height', sanitize_text_field( trim( $gallery_height ) ) ); //hardwired for now update_post_meta( $postid, 'aesop_hero_gallery_transition_speed', 300 ); } function getEnglishMonthName($foreignMonthName){ setlocale(LC_ALL, 'en_US'); $month_numbers = range(1,12); foreach($month_numbers as $month) $english_months[] = strftime('%B',mktime(0,0,0,$month,1,2011)); setlocale(LC_ALL, get_locale()); foreach($month_numbers as $month) $foreign_months[] = utf8_encode(strftime('%B',mktime(0,0,0,$month,1,2011))); return str_replace($foreign_months, $english_months, $foreignMonthName); } public function set_date( $postid, $value) { if( $value ) { $value = self::getEnglishMonthName($value)." ".date("H:i:s", current_time( 'timestamp', 1 )); wp_update_post( array ( 'ID' => $postid, // ID of the post to update 'post_date' => date( 'Y-m-d H:i:s', strtotime($value) ), 'post_date_gmt' => gmdate( 'Y-m-d H:i:s', strtotime($value) ), ) ); } } } ================================================ FILE: public/includes/option-engine.php ================================================ 'Tab', * 'content' => 'mytestcallback', * 'options' => 'myOptionsCallback' * ); * * return $tabs; * } * function myOptionsCallback(){ * * $options = array( * array( * 'id' => 'title', * 'name' => 'Title', * 'type' => 'text', * 'default' => 'default', * 'desc' => 'Cool' * ), * array( * 'id' => 'another', * 'name' => 'Another', * 'type' => 'textarea', * 'default' => 'default', * 'desc' => 'Awesome' * ) * ); * * return $options; * * } * * @since 0.9.4 */ /** * Get an array of addon data for the settings modal * @since 0.9.4 */ function lasso_get_modal_tabs(){ $tabs = array(); return apply_filters('lasso_modal_tabs', $tabs); } /** * Build a side tabs to fit alongside the post settings modal * This is used by addons to add cool stuff to the settings modal as an additional tab * * @param $type string tab or content * @uses lasso_get_modal_tabs() * @uses lasso_modal_addons_content() * @since 0.9.4 */ function lasso_modal_addons( $type = 'tab' ){ $tabs = lasso_get_modal_tabs(); $out = ''; if ( $tabs ): if ( 'tab' == $type ) { $out = '
          '; $out .= '
        • Editus
        • '; foreach ( $tabs as $tab ) { if ( isset( $tab ) ) { $out .= lasso_modal_addons_content( $tab, $type ); } } $out .= '
        '; } elseif ( 'content' == $type ) { foreach ( $tabs as $tab ) { if ( isset( $tab ) ) { $out .= lasso_modal_addons_content( $tab , $type ); } } } endif; return !empty( $out ) ? $out : false; } /** * Build a post meta options form * * @param $name string the name of this tab being logged * @param $options array an array of option fields in the format below * * array( * 'id' => 'title', * 'name' => 'Title', * 'type' => 'text', * 'default' => 'default', * 'desc' => 'My description' * ) * * @since 0.9.5 * @subpackage lasso_modal_addons_content */ function lasso_option_form( $name = '', $options = array() ){ ob_start(); if ( empty( $name ) || empty( $options ) || !is_array( $options ) ) return; $nonce = wp_create_nonce('lasso-process-post-meta'); $key = sprintf('_lasso_%s_settings', $name ); $out = sprintf('
        ' ); $out .= lasso_option_fields( $name, $options ); $out .='
        '; $out .=''; $out .=''; $out .=''; $out .=''; $out .=''; $out .='
        '; $out .= '
        '; $out .= ""; echo $out; return ob_get_clean(); } /** * Build settings fields for lasso_option_form * * @param $name string the name of this tab being logged * @param $options array an array of option fields in the format above * @since 0.9.5 * @subpackage lasso_modal_addons_content */ function lasso_option_fields( $name = '', $options = array() ){ $out = ''; $before = '
        '; $after = '
        '; if ( empty( $name ) || empty( $options ) ) return; foreach ( (array) $options as $option ) { $type = isset( $option['type'] ) ? $option['type'] : 'text'; $out .= sprintf('%s%s%s', $before, lasso_option_engine_option( $name, $option,$type ), $after ); } return $out; } /** * Build settings inputs for settings fields * * @param $name * @param $option mixed object * @param $type string text, textarea, checkbox, color * @since 5.0 */ function lasso_option_engine_option( $name = '', $option = '', $type = '') { if ( empty( $type ) || empty( $option ) ) return; $id = isset( $option['id'] ) ? $option['id'] : false; //$id = $id ? lasso_clean_string( $id ) : false; $desc = isset( $option['desc'] ) ? $option['desc'] : false; $value = get_post_meta( get_the_id(), $option[ 'id' ], true ); switch ( $type ) { case 'text': $out = sprintf('',$id, esc_html( $desc ), $id, $id, $value ); break; case 'textarea': $out = sprintf('',$id, esc_html( $desc ), $id, $id, $value ); break; case 'imgurl': $out = sprintf('
        ',$id, esc_html( $desc ), $value, $id, $id, $value ); break; case 'checkbox': $out = sprintf('

      '; echo apply_filters( 'lasso_tour_slides', $out ); ?> $content = unescape_invalid_shortcodes( $content ); return $content; } /** * Callback for preg_replace_callback in lasso_wrap_shortcodes. Returns shortcode wrapped in HTML Comments. * * @since 0.9.9 * * @param array $m * * @return string */ function lasso_wrap_shortcode_tag( $m ) { // allow [[foo]] syntax for escaping a tag if ( $m[1] == '[' && $m[6] == ']' ) { return substr( $m[0], 1, - 1 ); } $exception_arr1 = array('aesop_gallery_pop','aesop_character_carousel'); $exception_arr2 = array('su_box', 'su_note', 'su_document', 'su_spoiler','av_textblock','av_toggle_container','av_toggle'); $exception_arr2 = apply_filters('lasso_wrap_shortcode_exceptions',$exception_arr2); if ( strpos( $m[2],'aesop_' ) === 0 ) { // check against the exceptions if (strpos_arr($m[2],$exception_arr1)===false) { return $m[0]; } } if (strpos_arr($m[2],$exception_arr2)!==false) { return $m[0]; } return '' . $m[0] . ''; } /* a helper function */ function strpos_arr($haystack, $needle) { if(!is_array($needle)) $needle = array($needle); foreach($needle as $what) { if(($pos = strpos($haystack, $what))!==false) return $pos; } return false; } ================================================ FILE: uninstall.php ================================================ * @license GPL-2.0+ * @link http://aesopinteractive.com * @copyright 2015 Aesopinteractive LLC */ // If uninstall not called from WordPress, then exit if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) { exit; } delete_option('lasso_license_status'); delete_option('lasso_editor'); delete_option('lasso_updated_from'); delete_option('lasso_version');